diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 8fd8e6760b..c5d7927b1d 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -20,10 +20,10 @@ on: - main jobs: coverage-report: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Go 1.23.8 uses: actions/setup-go@v3 with: diff --git a/.github/workflows/devfile-ci.yaml b/.github/workflows/devfile-ci.yaml index 9ed2e5b644..2741b89ba2 100644 --- a/.github/workflows/devfile-ci.yaml +++ b/.github/workflows/devfile-ci.yaml @@ -25,7 +25,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 diff --git a/.github/workflows/minikube-test-helm.yaml b/.github/workflows/minikube-test-helm.yaml index dd09a99a38..19375c47c1 100644 --- a/.github/workflows/minikube-test-helm.yaml +++ b/.github/workflows/minikube-test-helm.yaml @@ -14,10 +14,10 @@ name: Helm test on: pull_request jobs: helm-on-minikube: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Start minikube cluster id: run-minikube uses: che-incubator/setup-minikube-action@next diff --git a/.github/workflows/minikube-test-operator.yaml b/.github/workflows/minikube-test-operator.yaml index 466ccbc7a7..18d1af1ed7 100644 --- a/.github/workflows/minikube-test-operator.yaml +++ b/.github/workflows/minikube-test-operator.yaml @@ -17,14 +17,14 @@ jobs: strategy: fail-fast: false matrix: - runners: ['ubuntu-22.04', 'ubuntu-22.04-arm'] + runners: ['ubuntu-24.04', 'ubuntu-24.04-arm'] runs-on: ${{ matrix.runners }} steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set arch environment variable run: | - if [[ ${{matrix.runners}} == 'ubuntu-22.04' ]]; then + if [[ ${{matrix.runners}} == 'ubuntu-24.04' ]]; then echo arch="amd64" >> $GITHUB_ENV else echo arch="arm64" >> $GITHUB_ENV diff --git a/.github/workflows/minikube-test-upgrade-stable-to-next.yaml b/.github/workflows/minikube-test-upgrade-stable-to-next.yaml index 0a51b74ed6..fbe671c7ef 100644 --- a/.github/workflows/minikube-test-upgrade-stable-to-next.yaml +++ b/.github/workflows/minikube-test-upgrade-stable-to-next.yaml @@ -17,10 +17,10 @@ on: - main jobs: upgrade-stable-to-next-on-minikube: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Start minikube cluster id: run-minikube uses: che-incubator/setup-minikube-action@next diff --git a/.github/workflows/minikube-test-upgrade-stable-to-stable.yaml b/.github/workflows/minikube-test-upgrade-stable-to-stable.yaml index fd0f6fc5d5..40a7d59f03 100644 --- a/.github/workflows/minikube-test-upgrade-stable-to-stable.yaml +++ b/.github/workflows/minikube-test-upgrade-stable-to-stable.yaml @@ -17,10 +17,10 @@ on: - 7.* jobs: upgrade-stable-to-stable-on-minikube: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Start minikube cluster id: run-minikube uses: che-incubator/setup-minikube-action@next diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 77ad05fc4f..012c70ca0a 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -14,10 +14,10 @@ name: PR check on: pull_request jobs: unit-tests: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Go 1.23.8 uses: actions/setup-go@v3 with: @@ -28,14 +28,14 @@ jobs: strategy: fail-fast: false matrix: - runners: ['ubuntu-22.04', 'ubuntu-22.04-arm'] + runners: ['ubuntu-24.04', 'ubuntu-24.04-arm'] runs-on: ${{matrix.runners}} steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set arch environment variable run: | - if [[ ${{matrix.runners}} == 'ubuntu-22.04' ]]; then + if [[ ${{matrix.runners}} == 'ubuntu-24.04' ]]; then echo arch="amd64" >> $GITHUB_ENV else echo arch="arm64" >> $GITHUB_ENV @@ -43,10 +43,10 @@ jobs: - name: Build image run: docker buildx build --platform linux/${{env.arch}} . source-code-validation: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Go 1.23.8 uses: actions/setup-go@v3 with: @@ -96,12 +96,10 @@ jobs: \( -name '*.sh' -o -name "*.go" -o -name "*.yaml" -o -name "*.yml" \)) LICENSE_TEMPLATE="${GITHUB_WORKSPACE}/hack/license-header.txt" check-license-header -f "${LICENSE_TEMPLATE}" ${FILES_TO_CHECK_LICENSE} - dependencies-md-validation: - runs-on: ubuntu-22.04 + dependencies-validation: + runs-on: ubuntu-24.04 steps: - - name: Checkout source code - uses: actions/checkout@v3 - - name: Validate DEPENDENCIES.md file - uses: che-incubator/dependencies-license-action@0.0.2 - env: - EXCLUDE_DEPS: "github.com/bmizerany/assert, gotest.tools/v3, github.com/dhui/dktest, gotest.tools, github.com/golangplus/testing" + - name: Checkout source code + uses: actions/checkout@v4 + - name: Check dependencies + run: build/scripts/clear-defined-test.sh diff --git a/.github/workflows/release-che-docs.yml b/.github/workflows/release-che-docs.yml index 1c5b4b9d0e..e2607d50ec 100644 --- a/.github/workflows/release-che-docs.yml +++ b/.github/workflows/release-che-docs.yml @@ -32,9 +32,9 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up environment diff --git a/.github/workflows/release-chectl.yml b/.github/workflows/release-chectl.yml index d0c951c324..116557e327 100644 --- a/.github/workflows/release-chectl.yml +++ b/.github/workflows/release-chectl.yml @@ -32,9 +32,9 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up environment diff --git a/.github/workflows/release-community-operator-PRs.yml b/.github/workflows/release-community-operator-PRs.yml index 2c6ac0948d..010a5cd806 100644 --- a/.github/workflows/release-community-operator-PRs.yml +++ b/.github/workflows/release-community-operator-PRs.yml @@ -28,9 +28,9 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up environment @@ -51,9 +51,6 @@ jobs: git config --global user.email "mkuznets@redhat.com" export GITHUB_TOKEN=${{ secrets.CHE_INCUBATOR_BOT_GITHUB_TOKEN }} set -e - OP_SDK_DIR=/opt/operator-sdk - mkdir -p $OP_SDK_DIR - make download-operator-sdk DEST="${OP_SDK_DIR}" export PATH="$PATH:$OP_SDK_DIR" export QUAY_ECLIPSE_CHE_USERNAME=${{ secrets.QUAY_USERNAME }} export QUAY_ECLIPSE_CHE_PASSWORD=${{ secrets.QUAY_PASSWORD }} diff --git a/.github/workflows/release-helm-charts.yaml b/.github/workflows/release-helm-charts.yaml index 066d35435c..15bad6b48d 100644 --- a/.github/workflows/release-helm-charts.yaml +++ b/.github/workflows/release-helm-charts.yaml @@ -28,9 +28,9 @@ on: jobs: release-helm-charts: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/release-next-catalog-and-operator-image.yaml b/.github/workflows/release-next-catalog-and-operator-image.yaml index e530af57a3..31e1898351 100644 --- a/.github/workflows/release-next-catalog-and-operator-image.yaml +++ b/.github/workflows/release-next-catalog-and-operator-image.yaml @@ -26,14 +26,14 @@ jobs: strategy: fail-fast: false matrix: - runners: ['ubuntu-22.04', 'ubuntu-22.04-arm'] + runners: ['ubuntu-24.04', 'ubuntu-24.04-arm'] runs-on: ${{matrix.runners}} steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set arch environment variable run: | - if [[ ${{matrix.runners}} == 'ubuntu-22.04' ]]; then + if [[ ${{matrix.runners}} == 'ubuntu-24.04' ]]; then echo arch="amd64" >> $GITHUB_ENV else echo arch="arm64" >> $GITHUB_ENV @@ -56,11 +56,11 @@ jobs: publish-operator-manifest: name: publish operator image - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: build-operator-image-multiarch steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Login to Quay.io uses: docker/login-action@v2 with: @@ -83,11 +83,11 @@ jobs: docker manifest push quay.io/eclipse/che-operator:next build-catalog: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: publish-operator-manifest steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx @@ -109,11 +109,11 @@ jobs: --catalog-image quay.io/eclipse/eclipse-che-olm-catalog:next build-catalog-with-digest: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: build-catalog steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c49467839a..892e8920b4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,9 +29,9 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Check existing tags @@ -92,10 +92,6 @@ jobs: export GITHUB_TOKEN=${{ secrets.CHE_BOT_GITHUB_TOKEN }} set -e - OP_SDK_DIR=/opt/operator-sdk - mkdir -p $OP_SDK_DIR - make download-operator-sdk DEST="${OP_SDK_DIR}" - go install golang.org/x/tools/cmd/goimports@latest export PATH="$PATH:$OP_SDK_DIR" diff --git a/.github/workflows/resources-check-main.yml b/.github/workflows/resources-check-main.yml index fb542359b4..ed74a4d29d 100644 --- a/.github/workflows/resources-check-main.yml +++ b/.github/workflows/resources-check-main.yml @@ -17,10 +17,10 @@ on: - main jobs: resources-validation: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install yq run: sudo pip install yq - name: Set up Go 1.23.8 @@ -32,10 +32,10 @@ jobs: go install golang.org/x/tools/cmd/goimports@latest ${GITHUB_WORKSPACE}/build/scripts/check-resources.sh bundle-version-validation: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install yq run: sudo pip install yq - name: Set up Go 1.23.8 diff --git a/.github/workflows/try-in-web-ide.yaml b/.github/workflows/try-in-web-ide.yaml index 081111419e..fdfadd0c64 100644 --- a/.github/workflows/try-in-web-ide.yaml +++ b/.github/workflows/try-in-web-ide.yaml @@ -19,7 +19,7 @@ on: jobs: add-web-ide-link: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Web IDE Pull Request Check uses: redhat-actions/try-in-web-ide@v1 diff --git a/.vscode/launch.json b/.vscode/launch.json index cda1c4bea5..ac7fcd06ed 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,7 +14,7 @@ "type": "go", "request": "launch", "mode": "auto", - "program": "${workspaceFolder}/main.go", + "program": "${workspaceFolder}/cmd/main.go", "envFile": "/tmp/che-operator-dev/vscode.env", "cwd": "${workspaceFolder}", }, diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md deleted file mode 100644 index 4643f96c11..0000000000 --- a/DEPENDENCIES.md +++ /dev/null @@ -1,594 +0,0 @@ -# Runtime dependencies - -| Packages | License | Resolved CQs | -|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- |-----------------------------------------------------------------------------------------------------------------------------------------------------| -| [cloud.google.com/go@v0.54.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/a6b88cf34a491498e4c7d15c107a31058693e2cb) | -| [cloud.google.com/go/accessapproval@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/accesscontextmanager@v1.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/aiplatform@v1.45.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/analytics@v0.21.2](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/27275903d1424725810b8265e527aaaf44abde6c) | -| [cloud.google.com/go/apigateway@v1.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/apigeeconnect@v1.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/apigeeregistry@v0.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/apikeys@v0.6.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/c2bf628da9b4f30df75608ffa77c2fb8d6a6cf8d) | -| [cloud.google.com/go/appengine@v1.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/area120@v0.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/artifactregistry@v1.14.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/asset@v1.14.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/assuredworkloads@v1.11.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/automl@v1.13.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/baremetalsolution@v0.5.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/947c9ace8740e40abe0ca79acb894ea333655f88) | -| [cloud.google.com/go/batch@v0.7.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/bd90ad90c1de4495ea270e7d1ba3390a41f88f0a) | -| [cloud.google.com/go/beyondcorp@v0.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/bigquery@v1.4.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/3b768578738982b1bd8612d6747ffaf103fc77fe) | -| [cloud.google.com/go/billing@v1.16.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/binaryauthorization@v1.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/certificatemanager@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/channel@v1.16.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/cloudbuild@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/clouddms@v1.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/cloudtasks@v1.11.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/compute@v1.21.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/f23942bb651d39c6d57bb192280659b32b9758ca) | -| [cloud.google.com/go/compute/metadata@v0.3.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/44b3a7d2be2df066b6625227cf4e4988d35a2cd1) | -| [cloud.google.com/go/contactcenterinsights@v1.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/container@v1.22.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/containeranalysis@v0.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/datacatalog@v1.14.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/dataflow@v0.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/dataform@v0.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/datafusion@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/datalabeling@v0.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/dataplex@v1.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/dataproc@v1.12.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/d1db4b27fd8d31b35f4f5d136b5b7120e130ebe8) | -| [cloud.google.com/go/dataqna@v0.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/datastore@v1.2.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/fd7a73a9ad5b5ce9194a755e1805d4c5ac2d3cfa) | -| [cloud.google.com/go/datastream@v1.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/deploy@v1.11.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/27275903d1424725810b8265e527aaaf44abde6c) | -| [cloud.google.com/go/dialogflow@v1.38.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/27275903d1424725810b8265e527aaaf44abde6c) | -| [cloud.google.com/go/dlp@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/documentai@v1.20.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/domains@v0.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/edgecontainer@v1.1.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/errorreporting@v0.3.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/c9aebae6d9cd8518bc247b7198ed38365577a872) | -| [cloud.google.com/go/essentialcontacts@v1.6.2](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/27275903d1424725810b8265e527aaaf44abde6c) | -| [cloud.google.com/go/eventarc@v1.12.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/filestore@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/firestore@v1.1.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/20091f47d3c522ea545f358dd9ac1cdb326bba6f) | -| [cloud.google.com/go/functions@v1.15.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/gaming@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/gkebackup@v0.4.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/947c9ace8740e40abe0ca79acb894ea333655f88) | -| [cloud.google.com/go/gkeconnect@v0.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/gkehub@v0.14.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/gkemulticloud@v0.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/grafeas@v0.3.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/7a0f6d12486209caebc3a02ade940927fceeb0ac) | -| [cloud.google.com/go/gsuiteaddons@v1.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/iam@v1.1.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/iap@v1.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/ids@v1.4.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/iot@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/kms@v1.12.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/language@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/lifesciences@v0.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/logging@v1.7.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/69705144832c715cf23832602ad9338b911dff9a) | -| [cloud.google.com/go/longrunning@v0.5.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/managedidentities@v1.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/maps@v0.7.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/3c279308301a8276ba79082ea44ad47d5861e8c0) | -| [cloud.google.com/go/mediatranslation@v0.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/memcache@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/metastore@v1.11.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/monitoring@v1.15.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/networkconnectivity@v1.12.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/networkmanagement@v1.8.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/27275903d1424725810b8265e527aaaf44abde6c) | -| [cloud.google.com/go/networksecurity@v0.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/notebooks@v1.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/optimization@v1.4.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/orchestration@v1.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/orgpolicy@v1.11.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/osconfig@v1.12.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/oslogin@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/phishingprotection@v0.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/policytroubleshooter@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/privatecatalog@v0.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/pubsub@v1.2.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/bd0b380acd8968ceb01c20edf7c86433da8bfd1c) | -| [cloud.google.com/go/pubsublite@v1.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/151908ab02a0b22c8e537d1bee00afc7f1465511) | -| [cloud.google.com/go/recaptchaenterprise@v1.3.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/c6780d80be72607afe35db2a3074c47346b68064) | -| [cloud.google.com/go/recaptchaenterprise/v2@v2.7.2](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/recommendationengine@v0.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/recommender@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/redis@v1.13.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/resourcemanager@v1.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/resourcesettings@v1.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/retail@v1.14.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/run@v0.9.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/c2bf628da9b4f30df75608ffa77c2fb8d6a6cf8d) | -| [cloud.google.com/go/scheduler@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/secretmanager@v1.11.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/security@v1.15.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/securitycenter@v1.23.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/27275903d1424725810b8265e527aaaf44abde6c) | -| [cloud.google.com/go/servicecontrol@v1.11.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/3c279308301a8276ba79082ea44ad47d5861e8c0) | -| [cloud.google.com/go/servicedirectory@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/servicemanagement@v1.8.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/3c279308301a8276ba79082ea44ad47d5861e8c0) | -| [cloud.google.com/go/serviceusage@v1.6.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/c2bf628da9b4f30df75608ffa77c2fb8d6a6cf8d) | -| [cloud.google.com/go/shell@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/spanner@v1.2.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/ad7cd32b39df6e142b24ab86b2cda03f21e1d708) | -| [cloud.google.com/go/speech@v1.17.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/storage@v1.5.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/b9ee5c702d0ffe94a091bf06a2267242aa0ecae6) | -| [cloud.google.com/go/storagetransfer@v1.10.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/27275903d1424725810b8265e527aaaf44abde6c) | -| [cloud.google.com/go/talent@v1.6.2](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/texttospeech@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/tpu@v1.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/trace@v1.10.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/translate@v1.8.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/video@v1.17.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/videointelligence@v1.11.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/vision@v1.2.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/56d81f123b5b4491aaf294042340c35ffcb224a7) | -| [cloud.google.com/go/vision/v2@v2.7.2](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/vmmigration@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/vmwareengine@v0.4.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/vpcaccess@v1.7.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/webrisk@v1.9.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/websecurityscanner@v1.6.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [cloud.google.com/go/workflows@v1.11.1](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-cloud-go/cdfd26840ecae6f823b2f7cae293a78c569a0a87) | -| [github.com/Azure/go-autorest@fafe600ec8bd2d9aab6c6486172ccc87df6a5302](https://github.com/azure/go-autorest.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/azure/go-autorest/fafe600ec8bd2d9aab6c6486172ccc87df6a5302) | -| [github.com/Azure/go-autorest/autorest@fafe600ec8bd2d9aab6c6486172ccc87df6a5302](https://github.com/azure/go-autorest.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/azure/go-autorest/fafe600ec8bd2d9aab6c6486172ccc87df6a5302) | -| [github.com/Azure/go-autorest/autorest/adal@fafe600ec8bd2d9aab6c6486172ccc87df6a5302](https://github.com/azure/go-autorest.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/azure/go-autorest/fafe600ec8bd2d9aab6c6486172ccc87df6a5302) | -| [github.com/Azure/go-autorest/autorest/date@fafe600ec8bd2d9aab6c6486172ccc87df6a5302](https://github.com/azure/go-autorest.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/azure/go-autorest/fafe600ec8bd2d9aab6c6486172ccc87df6a5302) | -| [github.com/Azure/go-autorest/autorest/mocks@fafe600ec8bd2d9aab6c6486172ccc87df6a5302](https://github.com/azure/go-autorest.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/azure/go-autorest/fafe600ec8bd2d9aab6c6486172ccc87df6a5302) | -| [github.com/Azure/go-autorest/logger@fafe600ec8bd2d9aab6c6486172ccc87df6a5302](https://github.com/azure/go-autorest.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/azure/go-autorest/fafe600ec8bd2d9aab6c6486172ccc87df6a5302) | -| [github.com/Azure/go-autorest/tracing@fafe600ec8bd2d9aab6c6486172ccc87df6a5302](https://github.com/azure/go-autorest.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/azure/go-autorest/fafe600ec8bd2d9aab6c6486172ccc87df6a5302) | -| [github.com/NYTimes/gziphandler@v1.0.1](https://github.com/nytimes/gziphandler.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/nytimes/gziphandler/2600fb119af974220d3916a5916d6e31176aac1b) | -| [github.com/BurntSushi/toml@v0.3.1](https://github.com/BurntSushi/toml.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/burntsushi/toml/3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005) | -| [github.com/BurntSushi/xgb@27f122750802c950b2c869a5b63dafcf590ced95](https://github.com/BurntSushi/xgb.git) | BSD-3-Clause AND WTFPL | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23291) | -| [sigs.k8s.io/structured-merge-diff@v1.0.2](https://github.com/kubernetes-sigs/structured-merge-diff/releases/tag/v4.1.0.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/sigs.k8s.io/structured-merge-diff/v1.0.2) | -| [sigs.k8s.io/yaml@v1.2.0](https://github.com/kubernetes-sigs/yaml.git) | BSD-3-Clause AND MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23295) | -| [k8s.io/utils@99ec85e7a44867095cdb6487884c9882372c819a](https://github.com/kubernetes/utils.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/k8s.io/utils/v0.0.0-20221128185143-99ec85e7a448) | -| [k8s.io/gengo@0689ccc1d7d65d9dd1bedcc3b0b1ed7df91ba266](https://github.com/kubernetes/gengo.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes/gengo/0689ccc1d7d65d9dd1bedcc3b0b1ed7df91ba266) | -| [github.com/PuerkitoBio/urlesc@5bd2802263f21d8788851d5305584c82a5c75d7e](https://github.com/puerkitobio/urlesc.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/puerkitobio/urlesc/5bd2802263f21d8788851d5305584c82a5c75d7e) | -| [github.com/census-instrumentation/opencensus-proto@v0.2.1](https://github.com/census-instrumentation/opencensus-proto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/census-instrumentation/opencensus-proto/d89fa54de508111353cb0b06403c00569be780d8) | -| [github.com/cncf/udpa/go@e8cd3a4bb307e2c810cffff99f93e96e6d7fee85](https://github.com/cncf/udpa.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/cncf/udpa/e8cd3a4bb307e2c810cffff99f93e96e6d7fee85) | -| [github.com/cncf/xds/go@v0.0.0-20230607035331-e9ce68804cb4](https://github.com/cncf/xds.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/cncf/xds/e9ce68804cb4e64cab5a52e3c8baf840d4ff87b7) | -| [github.com/creack/pty@v1.1.9](https://github.com/creack/pty.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/creack/pty/3a6a957789163cacdfe0e291617a1c8e80612c11) | -| [github.com/davecgh/go-spew@v1.1.1](https://github.com/davecgh/go-spew.git) | ISC | [clearlydefined](https://clearlydefined.io/definitions/git/github/davecgh/go-spew/8991bc29aa16c548c550c7ff78260e27b9ab7c73) | -| [github.com/dgrijalva/jwt-go@v3.2.0](https://github.com/dgrijalva/jwt-go.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/dgrijalva/jwt-go/06ea1031745cb8b3dab3f6a236daf2b0aa468b7e) | -| [github.com/docopt/docopt-go@ee0de3bc6815ee19d4a46c7eb90f829db0e014b1](https://github.com/docopt/docopt.go.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23292) | -| [github.com/emicklei/go-restful@a2fa14558f9a828f859fcad1d5c824437d7d4388](https://github.com/emicklei/go-restful.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23312) | -| [github.com/envoyproxy/go-control-plane@v0.9.4](https://github.com/envoyproxy/go-control-plane/releases/tag/v0.9.4.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/envoyproxy/go-control-plane/ba8e577f987f6676343cac84525b92ed1b2d86fe) | -| [github.com/envoyproxy/protoc-gen-validate@9eff07ddfcb4001aa1aab280648153f46e1a8ddc](https://github.com/envoyproxy/protoc-gen-validate.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23307) | -| [github.com/fsnotify/fsnotify@v1.4.7](https://github.com/fsnotify/fsnotify.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/fsnotify/fsnotify/c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9) | -| [github.com/go-logr/logr@v1.4.1](https://github.com/go-logr/logr.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fgo-logr/logr/v1.4.1) | -| [github.com/go-openapi/jsonpointer@v0.19.3](https://github.com/go-openapi/jsonpointer.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23304) | -| [github.com/go-openapi/jsonreference@v0.19.3](https://github.com/go-openapi/jsonreference.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23303) | -| [github.com/go-openapi/spec@v0.19.3](https://github.com/go-openapi/spec.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23302) | -| [github.com/go-openapi/swag@v0.19.5](https://github.com/go-openapi/swag.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-openapi/swag/c3d0f7896d589f3babb99eea24bbc7de98108e72) | -| [github.com/gogo/protobuf@v1.5.2](https://github.com/gogo/protobuf.git) | BSD-2-Clause AND BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=20958) | -| [github.com/golang/glog@23def4e6c14b4da8ac2ed8007337bc5eb5007998](https://github.com/golang/glog.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/golang/glog/23def4e6c14b4da8ac2ed8007337bc5eb5007998) | -| [github.com/golang/groupcache@8c9f03a8e57eb486e42badaed3fb287da51807ba](https://github.com/golang/groupcache.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/golang/groupcache/8c9f03a8e57eb486e42badaed3fb287da51807ba) | -| [github.com/google/gofuzz@44d81051d367757e1c7c6a5a86423ece9afcf63c](https://github.com/google/gofuzz.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=17584) | -| [github.com/google/martian@c223d6f7955e7c1a66526de1d602257e2e8b9254](https://github.com/google/martian.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/google/martian/c223d6f7955e7c1a66526de1d602257e2e8b9254) | -| [github.com/google/pprof@7dadf64105bba38bab598048e7721cc9d34f7e75](https://github.com/google/pprof.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/google/pprof/7dadf64105bba38bab598048e7721cc9d34f7e75) | -| [github.com/google/renameio@v0.1.0](https://github.com/google/renameio.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/google/renameio/f0e32980c006571efd537032e5f9cd8c1a92819e) | -| [github.com/google/s2a-go@v0.1.4](https://github.com/google/s2a-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/google/s2a-go/bb60477ba7d14d1c916863c80ed8343447ec40c0) | -| [github.com/google/uuid@v1.3.0](https://github.com/google/uuid.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/google/uuid/44b5fee7c49cf3bcdf723f106b36d56ef13ccc88) | -| [github.com/googleapis/enterprise-certificate-proxy@v0.2.3](https://github.com/googleapis/enterprise-certificate-proxy.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/enterprise-certificate-proxy/d0957a96ce28f68cd21ce2742c06237f3fa93fbe) | -| [github.com/googleapis/gax-go/v2@v2.0.5](https://github.com/googleapis/gax-go.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23301) | -| [github.com/googleapis/gnostic@v0.4.2](https://github.com/google/gnostic.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23309) | -| [github.com/gorilla/websocket@v1.4.2](https://github.com/gorilla/websocket.git) | BSD-2-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23308) | -| [k8s.io/kube-openapi@172d655c2280350c77cf05962948fc67ff043492](https://github.com/kubernetes/kube-openapi.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/k8s.io/kube-openapi/v0.0.0-20221012153701-172d655c2280) | -| [github.com/gregjones/httpcache@9cad4c3443a7200dd6400aef47183728de563a38](https://github.com/gregjones/httpcache.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/gregjones/httpcache/9cad4c3443a7200dd6400aef47183728de563a38) | -| [github.com/hashicorp/golang-lru@v0.5.1](https://github.com/hashicorp/golang-lru.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/golang-lru/7087cb70de9f7a8bc0a10c375cb0d2280a8edf9c) | -| [github.com/hpcloud/tail@v1.0.0](https://github.com/hpcloud/tail.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23300) | -| [github.com/imdario/mergo@v0.3.5](https://github.com/imdario/mergo.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/imdario/mergo/9316a62528ac99aaecb4e47eadd6dc8aa6533d58) -| [github.com/json-iterator/go@a1ca0830781e007c66b225121d2cdb3a649421f6](https://github.com/json-iterator/go.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/json-iterator/go/a1ca0830781e007c66b225121d2cdb3a649421f6) | -| [github.com/jstemmer/go-junit-report@v0.9.1](https://github.com/jstemmer/go-junit-report.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/jstemmer/go-junit-report/cc1f095d5cc5eca2844f5c5ea7bb37f6b9bf6cac) | -| [github.com/kisielk/errcheck@v1.2.0](https://github.com/kisielk/errcheck.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/kisielk/errcheck/e14f8d59a22d460d56c5ee92507cd94c78fbf274) -| [github.com/rogpeppe/go-internal@v1.3.0](https://github.com/rogpeppe/go-internal/releases/tag/v1.3.0.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/rogpeppe/go-internal/438578804ca6f31be148c27683afc419ce47c06e) | -| [github.com/sirupsen/logrus@v1.4.2](https://github.com/sirupsen/logrus/releases/tag/v1.4.2.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/sirupsen/logrus/839c75faf7f98a33d445d181f3018b5c3409a45e) | -| [github.com/spf13/afero@v1.2.2](https://github.com/spf13/afero/releases/tag/v1.2.2.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/spf13/afero/588a75ec4f32903aa5e39a2619ba6a4631e28424) | -| [github.com/spf13/pflag@v1.0.5](https://github.com/spf13/pflag/releases/tag/v1.0.5.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/spf13/pflag/2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab) | -| [github.com/stretchr/objx@v0.3.0](https://github.com/stretchr/objx/releases/tag/v0.3.0.git) | BSD-3-Clause, ISC, MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/stretchr/objx/35313a95ee26395aa17d366c71a2ccf788fa69b6) | -| [github.com/stretchr/testify@v1.4.0](https://github.com/stretchr/testify/releases/tag/v1.4.0.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23297) | -| [go.opencensus.io@v0.22.3](https://github.com/census-instrumentation/opencensus-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/census-instrumentation/opencensus-go/d835ff86be02193d324330acdb7d65546b05f814) | -| [google.golang.org/api@v0.20.0](https://github.com/googleapis/google-api-go-client.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/google-api-go-client/c24765c18bb761c90df819dcdfdd62f9a7f6fa22) | -| [google.golang.org/appengine@v1.6.5](https://github.com/golang/appengine.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23310) | -| [google.golang.org/genproto@v0.0.0-20230711160842-782d3b101e98](https://github.com/googleapis/go-genproto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/go-genproto/782d3b101e9819bc4ebd78d669f70714ed23541f) | -| [google.golang.org/genproto/googleapis/api@v0.0.0-20230711160842-782d3b101e98](https://github.com/googleapis/go-genproto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/go-genproto/782d3b101e9819bc4ebd78d669f70714ed23541f) | -| [google.golang.org/genproto/googleapis/rpc@v0.0.0-20230711160842-782d3b101e98](https://github.com/googleapis/go-genproto.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/googleapis/go-genproto/782d3b101e9819bc4ebd78d669f70714ed23541f) | -| [google.golang.org/grpc@v1.58.3](https://github.com/grpc/grpc-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/grpc/grpc-go/bf05b9558c16677e362d231120f8213eb276d406) | -| [google.golang.org/protobuf@v1.34.1](https://github.com/protocolbuffers/protobuf-go.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/protocolbuffers/protobuf-go/4a76e11653e368b9331815e1eb98e0cedc28997f) | -| [gopkg.in/errgo.v2@v2.1.0](https://github.com/go-errgo/errgo/releases/tag/v2.1.0.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-errgo/errgo/f768c5ab0476c50e978b039312180859c10fe8c0) | -| [gopkg.in/fsnotify.v1@v1.4.7](https://github.com/fsnotify/fsnotify/releases/tag/v1.4.7.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/fsnotify/fsnotify/c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9) | -| [gopkg.in/go-playground/assert.v1@v1.2.1](https://github.com/go-playground/assert.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-playground/assert/4f4dfbc7d1c48336cf93399deae81aa9067e88af) | -| [gopkg.in/inf.v0@v0.9.1](https://github.com/go-inf/inf.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-inf/inf/d2d2541c53f18d2a059457998ce2876cc8e67cbf) | -| [gopkg.in/tomb.v1@d5d1b5820637886def9eef33e03a27a9f166942c](https://github.com/go-tomb/tomb.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-tomb/tomb/d5d1b5820637886def9eef33e03a27a9f166942c) | -| [gopkg.in/yaml.v2@v2.4.0](https://github.com/go-yaml/yaml/releases/tag/v2.4.0.git) | Apache-2.0 AND MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23268) | -| [honnef.co/go/tools@81508471876c7902b8ca236ae35f897b1777c65a](https://github.com/dominikh/go-tools.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/dominikh/go-tools/81508471876c7902b8ca236ae35f897b1777c65a) | -| [k8s.io/klog/v2@v2.8.0](https://github.com/kubernetes/klog.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23266) | -| [github.com/golang/mock@v1.5.0](https://github.com/golang/mock.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/golang/mock/a23c5e7c8f7bb73c8ae5d8711815bbd30f3cfac8) | -| [github.com/konsorten/go-windows-terminal-sequences@v1.0.1](https://github.com/konsorten/go-windows-terminal-sequences.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/konsorten/go-windows-terminal-sequences/5c8c8bd35d3832f5d134ae1e1e375b69a4d25242) | -| [github.com/kr/pretty@ead452280cd055b2ae8a7f0db5eb37a878d902f7](https://github.com/kr/pretty.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/kr/pretty/ead452280cd055b2ae8a7f0db5eb37a878d902f7) | -| [github.com/kr/pty@282ce0e5322c82529687d609ee670fac7c7d917c](https://github.com/kr/pty.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/kr/pty/282ce0e5322c82529687d609ee670fac7c7d917c) | -| [github.com/kr/text@v0.2.0](https://github.com/kr/text/releases/tag/v0.2.0.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/kr/text/702c74938df48b97370179f33ce2107bd7ff3b3e) | -| [github.com/mailru/easyjson@8edcc4e51f39ddbd3505a3386aff3f435a7fd028](https://github.com/mailru/easyjson.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mailru/easyjson/8edcc4e51f39ddbd3505a3386aff3f435a7fd028) | -| [github.com/mattn/go-isatty@v0.0.3](https://github.com/mattn/go-isatty.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mattn/go-isatty/0360b2af4f38e8d38c7fce2a9f4e702702d73a39) | -| [github.com/munnerz/goautoneg@a547fc61f48d567d5b4ec6f8aee5573d8efce11d](https://github.com/munnerz/goautoneg/commits/a547fc61f48d567d5b4ec6f8aee5573d8efce11d.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23267) | -| [github.com/onsi/ginkgo@v2.19.0](https://github.com/onsi/ginkgo.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/onsi/ginkgo/28fb5d613e96c8f11ca813e1d467117b50662215) | -| [github.com/onsi/gomega@v1.7.0](https://github.com/onsi/gomega/releases/tag/v1.7.0.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/onsi/gomega/bdebf9e0ece900259084cfa4121b97ce1a540939) | -| [github.com/peterbourgon/diskv@0646ccaebea1ed1539efcab30cae44019090093f](https://github.com/peterbourgon/diskv.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/peterbourgon/diskv/0646ccaebea1ed1539efcab30cae44019090093f) | -| [github.com/pkg/errors@614d223910a179a466c1767a985424175c39b465](https://github.com/pkg/errors.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/pkg/errors/614d223910a179a466c1767a985424175c39b465) | -| [k8s.io/metrics@v0.20.2](https://github.com/kubernetes/metrics.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes/metrics/b55f19c89378bd9539068e205f0ca9d1a323404f) | -| [k8s.io/kubectl@10b66c3fd14bc8d2bb27582d03d75bde30a3c8a3](https://github.com/kubernetes/kubectl.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes/kubectl/10b66c3fd14bc8d2bb27582d03d75bde30a3c8a3) | -| [k8s.io/kube-aggregator@14b8d2d93fcb8a90c47fcd2ceea0035dfd6d381a](https://github.com/kubernetes/kube-aggregator.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes/kube-aggregator/14b8d2d93fcb8a90c47fcd2ceea0035dfd6d381a) | -| [k8s.io/klog@v2.80.1](https://github.com/kubernetes/klog/releases/tag/v1.0.0.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes/klog/cb9292a1800659470ad0587b2fe18a30ce2ece7e) | -| [k8s.io/component-base@v0.26.1](https://github.com/kubernetes/component-base.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/k8s.io/component-base/v0.26.1) | -| [k8s.io/code-generator@f186a36abf5c353b917e3c3189f1c06a38866b84](https://github.com/kubernetes/code-generator.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes/code-generator/f186a36abf5c353b917e3c3189f1c06a38866b84) | -| [helm.sh/helm/v3@0a9a9a88e8afd6e77337a3e2ad744756e191429a](https://github.com/helm/helm.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/helm/helm/0a9a9a88e8afd6e77337a3e2ad744756e191429a) | -| [gomodules.xyz/jsonpatch/v2@v2.0.1](https://github.com/gomodules/jsonpatch.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/gomodules/jsonpatch/e8422f09d27ee2c8cfb2c7f8089eb9eeb0764849) | -| [go.uber.org/multierr@v1.3.0](https://github.com/uber-go/multierr.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/uber-go/multierr/c3fc3d02ec864719d8e25be2d7dde1e35a36aa27) | -| [go.etcd.io/bbolt@a0458a2b35708eef59eb5f620ceb3cd1c01a824d](https://github.com/etcd-io/bbolt.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/etcd-io/bbolt/a0458a2b35708eef59eb5f620ceb3cd1c01a824d) | -| [github.com/yuin/goldmark@7b90f04af43131db79ec320be0bd4744079b346f](https://github.com/yuin/goldmark.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/yuin/goldmark/7b90f04af43131db79ec320be0bd4744079b346f) | -| [github.com/xeipuuv/gojsonschema@v1.2.0](https://github.com/xeipuuv/gojsonschema.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/xeipuuv/gojsonschema/82fcdeb203eb6ab2a67d0a623d9c19e5e5a64927) | -| [github.com/xeipuuv/gojsonreference@bd5ef7bd5415a7ac448318e64f11a24cd21e594b](https://github.com/xeipuuv/gojsonreference.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/xeipuuv/gojsonreference/bd5ef7bd5415a7ac448318e64f11a24cd21e594b) | -| [github.com/xeipuuv/gojsonpointer@4e3ac2762d5f479393488629ee9370b50873b3a6](https://clearlydefined.io/definitions/git/github/xeipuuv/gojsonpointer/4e3ac2762d5f479393488629ee9370b50873b3a6.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/xeipuuv/gojsonpointer/4e3ac2762d5f479393488629ee9370b50873b3a6) | -| [github.com/xdg/stringprep@v1.0.0](https://github.com/xdg/stringprep.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/xdg/stringprep/bd625b8dc1e3b0f57412280ccbcc317f0c69d8db) | -| [github.com/xdg/scram@7eeb5667e42c09cb51bf7b7c28aea8c56767da90](https://github.com/xdg/scram.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/xdg/scram/7eeb5667e42c09cb51bf7b7c28aea8c56767da90) | -| [github.com/xanzy/go-gitlab@v0.15.0](https://github.com/xanzy/go-gitlab.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/xanzy/go-gitlab/8e525d783950ddfc35d109e48af26f4cb70dde4a) | -| [github.com/urfave/cli@v1.20.0](https://github.com/urfave/cli.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/urfave/cli/cfb38830724cc34fedffe9a2a29fb54fa9169cd1) | -| [github.com/tmc/grpc-websocket-proxy@0ad062ec5ee553a48f6dbd280b7a1b5638e8a113](https://github.com/tmc/grpc-websocket-proxy.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/tmc/grpc-websocket-proxy/0ad062ec5ee553a48f6dbd280b7a1b5638e8a113) | -| [github.com/tidwall/pretty@ef453c788d6a371829f4f9967b014b2b81856df5](https://github.com/tidwall/pretty.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/tidwall/pretty/ef453c788d6a371829f4f9967b014b2b81856df5) | -| [github.com/subosito/gotenv@v1.2.0](https://github.com/subosito/gotenv.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/subosito/gotenv/2ef7124db659d49edac6aa459693a15ae36c671a) | -| [github.com/spf13/viper@v1.7.0](https://github.com/spf13/viper.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/spf13/viper/13df72109047b6ae9c907bce81e327265d6d8a9c) | -| [github.com/spf13/jwalterweatherman@v1.1.0](https://github.com/spf13/jwalterweatherman.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/spf13/jwalterweatherman/94f6ae3ed3bceceafa716478c5fbf8d29ca601a1) | -| [github.com/spf13/cobra@67fc4837d267bc9bfd6e47f77783fcc3dffc68de](https://github.com/spf13/cobra.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/spf13/cobra/67fc4837d267bc9bfd6e47f77783fcc3dffc68de) | -| [github.com/spf13/cast@v1.3.0](https://github.com/spf13/cast.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/spf13/cast/8c9545af88b134710ab1cd196795e7f2388358d7) | -| [github.com/soheilhy/cmux@v0.1.4](https://github.com/soheilhy/cmux.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/soheilhy/cmux/e09e9389d85d8492d313d73d1469c029e710623f) | -| [github.com/shurcooL/sanitized_anchor_name@v1.0.0](https://github.com/shurcooL/sanitized_anchor_name.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/shurcool/sanitized_anchor_name/7bfe4c7ecddb3666a94b053b422cdd8f5aaa3615) | -| [github.com/sean-/seed@1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1](https://github.com/seccomp/libseccomp-golang.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/seccomp/libseccomp-golang/1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1) | -| [github.com/satori/go.uuid@v1.2.0](https://github.com/satori/go.uuid.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/satori/go.uuid/f58768cc1a7a7e77a3bd49e98cdd21419399b6a3) | -| [github.com/ryanuber/columnize@9b3edd62028f107d7cabb19353292afd29311a4e](https://github.com/ryanuber/columnize.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/ryanuber/columnize/9b3edd62028f107d7cabb19353292afd29311a4e) | -| [github.com/russross/blackfriday@v1.5.2](https://github.com/russross/blackfriday.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/russross/blackfriday/05f3235734ad95d0016f6a23902f06461fcf567a) | -| [github.com/rogpeppe/fastuuid@6724a57986aff9bff1a1770e9347036def7c89f6](https://github.com/rogpeppe/fastuuid.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/rogpeppe/fastuuid/6724a57986aff9bff1a1770e9347036def7c89f6) | -| [github.com/pquerna/cachecontrol@0dec1b30a0215bb68605dfc568e8855066c9202d](https://github.com/pquerna/cachecontrol.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/pquerna/cachecontrol/0dec1b30a0215bb68605dfc568e8855066c9202d) | -| [github.com/posener/complete@v1.1.1](https://github.com/posener/complete.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/posener/complete/98eb9847f27ba2008d380a32c98be474dea55bdf) -| [github.com/pmezard/go-difflib@v1.0.0](https://github.com/pmezard/go-difflib.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/pmezard/go-difflib/792786c7400a136282c1664665ae0a8db921c6c2) | -| [github.com/pierrec/lz4@6b9367c9ff401dbc54fabce3fb8d972e799b702d](https://github.com/pierrec/lz4.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/pierrec/lz4/6b9367c9ff401dbc54fabce3fb8d972e799b702d) | -| [github.com/pelletier/go-toml@v1.4.0](https://github.com/pelletier/go-toml.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/pelletier/go-toml/728039f679cbcd4f6a54e080d2219a4c4928c546) | -| [github.com/opentracing/opentracing-go@v1.1.0](https://github.com/opentracing/opentracing-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/opentracing/opentracing-go/659c90643e714681897ec2521c60567dd21da733) | -| [github.com/mwitkow/go-conntrack@cc309e4a22231782e8893f3c35ced0967807a33e](https://github.com/mwitkow/go-conntrack.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/mwitkow/go-conntrack/cc309e4a22231782e8893f3c35ced0967807a33e) | -| [github.com/modern-go/reflect2@v1.0.1](https://github.com/modern-go/reflect2.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/modern-go/reflect2/94122c33edd36123c84d5368cfb2b69df93a0ec8) | -| [github.com/modern-go/concurrent@bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94](https://github.com/modern-go/concurrent.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23299) | -| [github.com/mitchellh/reflectwalk@v1.0.1](https://github.com/mitchellh/reflectwalk.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mitchellh/reflectwalk/eecee6c969c02c8cc2ae48e1e269843ae8590796) | -| [github.com/mitchellh/mapstructure@v1.1.2](https://github.com/mitchellh/mapstructure.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mitchellh/mapstructure/3536a929edddb9a5b34bd6861dc4a9647cb459fe) | -| [github.com/mitchellh/hashstructure@v1.0.0](https://github.com/mitchellh/hashstructure.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mitchellh/hashstructure/a38c50148365edc8df43c1580c48fb2b3a1e9cd7) | -| [github.com/mitchellh/gox@v0.4.0](https://github.com/mitchellh/gox.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/mitchellh/gox/c9740af9c6574448fd48eb30a71f964014c7a837) | -| [github.com/mitchellh/go-wordwrap@v1.0.0](https://github.com/mitchellh/go-wordwrap.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mitchellh/go-wordwrap/9e67c67572bc5dd02aef930e2b0ae3c02a4b5a5c) | -| [github.com/mitchellh/go-testing-interface@v1.0.0](https://github.com/mitchellh/go-testing-interface.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mitchellh/go-testing-interface/6d0b8010fcc857872e42fc6c931227569016843c) | -| [github.com/mitchellh/go-homedir@v1.1.0](https://github.com/mitchellh/go-homedir.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mitchellh/go-homedir/af06845cf3004701891bf4fdb884bfe4920b3727) | -| [github.com/mitchellh/copystructure@v1.0.0](https://github.com/mitchellh/copystructure.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mitchellh/copystructure/9a1b6f44e8da0e0e374624fb0a825a231b00c537) | -| [github.com/mitchellh/cli@v1.0.0](https://github.com/mitchellh/cli.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/mitchellh/cli/3d22a244be8aa6fb16ac24af0e195c08b7d973aa) | -| [github.com/matttproud/golang_protobuf_extensions@c182affec369e30f25d3eb8cd8a478dee585ae7d](https://github.com/matttproud/golang_protobuf_extensions.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/matttproud/golang_protobuf_extensions/c182affec369e30f25d3eb8cd8a478dee585ae7d) | -| [github.com/mattn/go-sqlite3@b612a2feea6aa87c6d052d9086572551df06497e](https://github.com/mattn/go-sqlite3.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mattn/go-sqlite3/b612a2feea6aa87c6d052d9086572551df06497e) | -| [github.com/mattn/go-shellwords@39dbbfa24bbc39559b61cae9b20b0e8db0e55525](https://github.com/mattn/go-shellwords.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mattn/go-shellwords/39dbbfa24bbc39559b61cae9b20b0e8db0e55525) | -| [github.com/mattn/go-runewidth@v0.0.9](https://github.com/mattn/go-runewidth.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mattn/go-runewidth/14e809f6d78fcf9f48ff9b70981472b64c05f754) | -| [github.com/mattn/go-colorable@v0.1.7](https://github.com/mattn/go-colorable.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mattn/go-colorable/f6c00982823144337e56cdb71c712eaac151d29c) | -| [github.com/lib/pq@51e2106eed1cea199c802d2a49e91e2491b02056](https://github.com/lib/pq.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/lib/pq/51e2106eed1cea199c802d2a49e91e2491b02056) | -| [github.com/leodido/go-urn@6c96508144d00b380edbc8bda077e27b832d0c7b](https://github.com/leodido/go-urn.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/leodido/go-urn/6c96508144d00b380edbc8bda077e27b832d0c7b) | -| [github.com/kylelemons/godebug@v1.1.0](https://github.com/kylelemons/godebug.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/kylelemons/godebug/9ff306d4fbead574800b66369df5b6144732d58e) | -| [github.com/julienschmidt/httprouter@v1.2.0](https://github.com/julienschmidt/httprouter.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/julienschmidt/httprouter/348b672cd90d8190f8240323e372ecd1e66b59dc) | -| [github.com/jtolds/gls@9a4a02dbe491bef4bab3c24fd9f3087d6c4c6690](https://github.com/jtolio/gls.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/jtolds/gls/9a4a02dbe491bef4bab3c24fd9f3087d6c4c6690) | -| [github.com/jonboulle/clockwork@v0.1.0](https://github.com/jonboulle/clockwork.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/jonboulle/clockwork/2eee05ed794112d45db504eb05aa693efd2b8b09) | -| [github.com/jmoiron/sqlx@v1.2.0](https://github.com/jmoiron/sqlx.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/jmoiron/sqlx/d161d7a76b5661016ad0b085869f77fd410f3e6a) | -| [github.com/jmespath/go-jmespath@0.3.0](https://github.com/jmespath/go-jmespath.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/jmespath/go-jmespath/3f887ed31e21667600265f39fc0df20430b42d62) | -| [github.com/jessevdk/go-flags@v1.4.0](https://github.com/jessevdk/go-flags.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/jessevdk/go-flags/c6ca198ec95c841fdb89fc0de7496fed11ab854e) | -| [github.com/inconshreveable/mousetrap@v1.0.0](https://github.com/inconshreveable/mousetrap.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/inconshreveable/mousetrap/76626ae9c91c4f2a10f34cad8ce83ea42c93bb75) | -| [github.com/huandu/xstrings@v1.2.0](https://github.com/huandu/xstrings.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/huandu/xstrings/f02667b379e2fb5916c3cda2cf31e0eb885d79f8) | -| [github.com/hashicorp/memberlist@v0.1.3](https://github.com/hashicorp/memberlist.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/memberlist/a9da52f0668fc4321ec18e9e28dd8141621a808f) | -| [github.com/hashicorp/mdns@v1.0.0](https://github.com/hashicorp/mdns.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/mdns/c31d3f8e4a0a5b46b118c2fd26d9da36467002c9) | -| [github.com/hashicorp/hcl@v1.0.0](https://github.com/hashicorp/hcl.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/hcl/8cb6e5b959231cc1119e43259c4a608f9c51a241) | -| [github.com/hashicorp/go-uuid@v1.0.1](https://github.com/hashicorp/go-uuid.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/go-uuid/4f571afc59f3043a65f8fe6bf46d887b10a01d43) | -| [github.com/hashicorp/go-syslog@v1.0.0](https://github.com/hashicorp/go-syslog.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/go-syslog/8d1874e3e8d1862b74e0536851e218c4571066a5) | -| [github.com/hashicorp/go-rootcerts@v1.0.1](https://github.com/hashicorp/go-rootcerts/releases/tag/v1.0.1.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/go-rootcerts/df8e78a645e18d56ed7bb9ae10ffb8174ab892e2) | -| [github.com/hashicorp/go-multierror@v1.0.0](https://github.com/hashicorp/go-multierror.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/go-multierror/886a7fbe3eb1c874d46f623bfa70af45f425b3d1) | -| [github.com/hashicorp/go-msgpack@v0.5.5](https://github.com/hashicorp/go-msgpack/releases/tag/v0.5.5.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/go-msgpack/ad60660ecf9c5a1eae0ca32182ed72bab5807961) | -| [github.com/hashicorp/go-immutable-radix@v1.0.0](https://github.com/hashicorp/go-immutable-radix.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/go-immutable-radix/27df80928bb34bb1b0d6d0e01b9e679902e7a6b5) | -| [github.com/hashicorp/go-cleanhttp@v0.5.1](github.com/hashicorp/go-cleanhttp.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/go-cleanhttp/eda1e5db218aad1db63ca4642c8906b26bcf2744) | -| [github.com/hashicorp/errwrap@v1.0.0](https://github.com/hashicorp/errwrap.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/hashicorp/errwrap/8a6fb523712970c966eefc6b39ed2c5e74880354) | -| [github.com/hailocab/go-hostpool@e80d13ce29ede4452c43dea11e79b9bc8a15b478](https://github.com/hailocab/go-hostpool.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/hailocab/go-hostpool/e80d13ce29ede4452c43dea11e79b9bc8a15b478) | -| [github.com/grpc-ecosystem/go-grpc-prometheus@v1.2.0](https://github.com/grpc-ecosystem/go-grpc-prometheus.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/grpc-ecosystem/go-grpc-prometheus/c225b8c3b01faf2899099b768856a9e916e5087b) | -| [github.com/grpc-ecosystem/go-grpc-middleware@v1.1.0](https://github.com/grpc-ecosystem/go-grpc-middleware.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/grpc-ecosystem/go-grpc-middleware/dd15ed025b6054e5253963e355991f3070d4e593) | -| [github.com/gosuri/uitable@v0.0.4](https://github.com/gosuri/uitable.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/gosuri/uitable/764536226c71f9c74a2445394091c2a9ac440a1b) | -| [github.com/gorilla/mux@v1.7.2](https://github.com/gorilla/mux/releases/tag/v1.7.2.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/gorilla/mux/ed099d42384823742bba0bf9a72b53b55c9e2e38) | -| [github.com/gorilla/context@v1.1.1](https://github.com/gorilla/context.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/gorilla/context/08b5f424b9271eedf6f9f0ce86cb9396ed337a42) | -| [github.com/gopherjs/gopherjs@fce0ec30dd00773d3fa974351d04ce2737b5c4d9](https://github.com/gopherjs/gopherjs.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/gopherjs/gopherjs/fce0ec30dd00773d3fa974351d04ce2737b5c4d9) | -| [github.com/google/go-querystring@v1.0.0](https://github.com/google/go-querystring.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/google/go-querystring/44c6ddd0a2342c386950e880b658017258da92fc) | -| [github.com/google/go-github/v18@07716bad7a0c6d4277a5abcab95588925656a762](https://github.com/google/go-github.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/google/go-github/07716bad7a0c6d4277a5abcab95588925656a762) | -| [github.com/google/btree@v1.0.0](https://github.com/google/btree.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/google/btree/4030bb1f1f0c35b30ca7009e9ebd06849dd45306) | -| [github.com/golang/snappy@v0.0.1](https://github.com/golang/snappy.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/golang/snappy/2a8bb927dd31d8daada140a5d09578521ce5c36a) | -| [github.com/golang/protobuf@v1.4.3](https://github.com/golang/protobuf.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/golang/protobuf/4846b58453b3708320bdb524f25cc5a1d9cda4d4) | -| [github.com/golang-migrate/migrate/v4@v4.10.0](https://github.com/golang-migrate/migrate/releases/tag/v4.10.0.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/golang-migrate/migrate/5cc28f061e9d4b893963b8524ada7a7ba3b4e79a) | -| [github.com/gofrs/uuid@v3.2.0](https://github.com/gofrs/uuid/releases/tag/v3.2.0.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/gofrs/uuid/6b08a5c5172ba18946672b49749cde22873dd7c2) | -| [github.com/gobwas/glob@v0.2.3](https://github.com/gobwas/glob.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/gobwas/glob/5ccd90ef52e1e632236f7326478d4faa74f99438) | -| [github.com/gobuffalo/flect@v0.1.0](https://github.com/gobuffalo/flect.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/gobuffalo/flect/d4fc286952bf96d0262a67b482e234613ae36f59) | -| [github.com/go-stack/stack@v1.8.0](https://github.com/go-stack/stack.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-stack/stack/2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a) | -| [github.com/go-sql-driver/mysql@v1.4.1](https://github.com/go-sql-driver/mysql.git) | MPL-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-sql-driver/mysql/72cd26f257d44c1114970e19afddcd812016007e) | -| [github.com/go-playground/universal-translator@v0.16.0](https://github.com/go-playground/universal-translator/releases/tag/v0.16.0.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-playground/universal-translator/b32fa301c9fe55953584134cb6853a13c87ec0a1) | -| [github.com/go-openapi/strfmt@v0.19.5](https://github.com/go-openapi/strfmt/releases/tag/v0.19.5.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-openapi/strfmt/2887e74ed0fe2aea628affe322b19fc3112f98cd) | -| [github.com/go-openapi/errors@v0.19.2](https://github.com/go-openapi/errors.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-openapi/errors/0b2a0a1f89aa2eec2d13e03cd80ab0fdaf01f8ce) | -| [github.com/ghodss/yaml@73d445a93680fa1a78ae23a5839bad48f32ba1ee](https://github.com/ghodss/yaml.git) | BSD-3-Clause, BSD-3-Clause AND MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/ghodss/yaml/73d445a93680fa1a78ae23a5839bad48f32ba1ee) | -| [github.com/globalsign/mgo@72aab81a5dece0687b5fc6323b37521741501e1a](https://github.com/globalsign/mgo.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/globalsign/mgo/72aab81a5dece0687b5fc6323b37521741501e1a) | -| [github.com/exponent-io/jsonpath@d6023ce2651d8eafb5c75bb0c7167536102ec9f5](https://github.com/exponent-io/jsonpath.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/exponent-io/jsonpath/d6023ce2651d8eafb5c75bb0c7167536102ec9f5) | -| [github.com/elazarl/goproxy@947c36da3153ff334e74d9d980de341d25f358ba](https://github.com/elazarl/goproxy.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/elazarl/goproxy/947c36da3153ff334e74d9d980de341d25f358ba) | -| [github.com/edsrzf/mmap-go@188cc3b666ba704534fa4f96e9e61f21f1e1ba7c](https://github.com/edsrzf/mmap-go.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/edsrzf/mmap-go/188cc3b666ba704534fa4f96e9e61f21f1e1ba7c) | -| [github.com/dustin/go-humanize@v1.0.0](https://github.com/dustin/go-humanize.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/dustin/go-humanize/9f541cc9db5d55bce703bd99987c9d5cb8eea45e) | -| [github.com/docker/docker-credential-helpers@v0.6.3](https://github.com/docker/docker-credential-helpers.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/docker/docker-credential-helpers/54f0238b6bf101fc3ad3b34114cb5520beb562f5) | -| [github.com/denisenkom/go-mssqldb@df6d76eb92899e4dfe4db66d53b187c89d34be37](https://github.com/denisenkom/go-mssqldb.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/denisenkom/go-mssqldb/df6d76eb92899e4dfe4db66d53b187c89d34be37) | -| [github.com/deislabs/oras@v0.8.1](https://github.com/oras-project/oras.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/deislabs/oras/237ac925cb6a308a5523cc048292bb53037f6975) | -| [github.com/coreos/bbolt@v1.3.3](https://github.com/etcd-io/bbolt.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/coreos/bbolt/a0458a2b35708eef59eb5f620ceb3cd1c01a824d) | -| [github.com/containerd/go-runc@5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3](https://github.com/containerd/go-runc.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/containerd/go-runc/5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3) | -| [github.com/containerd/fifo@a9fb20d87448d386e6d50b1f2e1fa70dcf0de43c](https://github.com/containerd/fifo.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/containerd/fifo/a9fb20d87448d386e6d50b1f2e1fa70dcf0de43c) | -| [github.com/containerd/console@c12b1e7919c14469339a5d38f2f8ed9b64a9de23](https://github.com/containerd/console.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/containerd/console/c12b1e7919c14469339a5d38f2f8ed9b64a9de23) | -| [github.com/containerd/cgroups@3de5a6bb4823a9b39ab1e1108e3bc58bf8fc76ad](https://github.com/containerd/cgroups.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/containerd/cgroups/3de5a6bb4823a9b39ab1e1108e3bc58bf8fc76ad) | -| [github.com/cockroachdb/datadriven@80d97fb3cbaa752564320702f409fdb2ef3da0ef](https://github.com/cockroachdb/datadriven.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/cockroachdb/datadriven/80d97fb3cbaa752564320702f409fdb2ef3da0ef) | -| [github.com/cespare/xxhash/v2@v2.2.0](https://github.com/cespare/xxhash.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/cespare/xxhash/a76eb16a93c1e30527c073ca831d9048b4b935f6) | -| [github.com/blang/semver/v4@v4.0.0](https://github.com/blang/semver.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/blang/semver/af3461a9cbcf1f3f5889d21b83f5ef63880c33a8) | -| [github.com/blang/semver@v3.5.1](https://github.com/blang/semver.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/blang/semver/2ee87856327ba09384cabd113bc6b5d174e9ec0f) | -| [github.com/bitly/go-simplejson@0c965951289cce37dec52ad1f34200fefc816777](https://github.com/bitly/go-simplejson.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/bitly/go-simplejson/0c965951289cce37dec52ad1f34200fefc816777) | -| [github.com/bitly/go-hostpool@5d3b4dc6ed4701a761ee884fd803b0a0879744f1](https://github.com/bitly/go-hostpool.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/bitly/go-hostpool/5d3b4dc6ed4701a761ee884fd803b0a0879744f1) | -| [github.com/bgentry/speakeasy@v0.1.0](https://github.com/bgentry/speakeasy.git) | Apache-2.0 AND MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/bgentry/speakeasy/4aabc24848ce5fd31929f7d1e4ea74d3709c14cd) | -| [github.com/beorn7/perks@v1.0.1](https://github.com/beorn7/perks.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/beorn7/perks/37c8de3658fcb183f997c4e13e8337516ab753e6) | -| [github.com/aws/aws-sdk-go@v1.36.31](https://github.com/aws/aws-sdk-go/releases/tag/v1.36.31.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/aws/aws-sdk-go/2c7b39c8f2e2430d5e27482b7421dac5884613c2) | -| [github.com/armon/go-radix@7fddfc383310abc091d79a27f116d30cf0424032](https://github.com/armon/go-radix.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/armon/go-radix/7fddfc383310abc091d79a27f116d30cf0424032) | -| [github.com/armon/go-metrics@f0300d1749da6fa982027e449ec0c7a145510c3c](https://github.com/armon/go-metrics.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/armon/go-metrics/f0300d1749da6fa982027e449ec0c7a145510c3c) | -| [github.com/armon/circbuf@bbbad097214e2918d8543d5201d12bfd7bca254d](https://github.com/armon/circbuf.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/armon/circbuf/bbbad097214e2918d8543d5201d12bfd7bca254d) | -| [github.com/antihax/optional@ca021399b1a6796ecb758292c6311ce0b28857fc](https://github.com/antihax/optional.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/antihax/optional/ca021399b1a6796ecb758292c6311ce0b28857fc) | -| [github.com/alecthomas/units@c3de453c63f4bdb4dadffab9805ec00426c505f7](https://github.com/alecthomas/units.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/alecthomas/units/c3de453c63f4bdb4dadffab9805ec00426c505f7) | -| [github.com/PuerkitoBio/purell@v1.1.1](https://github.com/PuerkitoBio/purell.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/puerkitobio/purell/44968752391892e1b0d0b821ee79e9a85fa13049) | -| [github.com/Masterminds/sprig/v3@v3.0.2](https://github.com/Masterminds/sprig/releases/tag/v3.0.2.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/masterminds/sprig/25dce230792b748f794ea878db61fc5419410c9f) | -| [github.com/Masterminds/semver/v3@v3.0.3](https://github.com/Masterminds/semver.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/masterminds/semver/910aa146bd66780c2815d652b92a7fc5331e533c) | -| [github.com/MakeNowJust/heredoc@e9091a26100e9cfb2b6a8f470085bfa541931a91](https://github.com/MakeNowJust/heredoc.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/makenowjust/heredoc/e9091a26100e9cfb2b6a8f470085bfa541931a91) | -| [github.com/Azure/go-ansiterm@d6e3b3328b783f23731bc4d058875b0371ff8109](https://github.com/Azure/go-ansiterm.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/azure/go-ansiterm/d6e3b3328b783f23731bc4d058875b0371ff8109) | -| [github.com/Masterminds/goutils@v1.1.0](https://github.com/Masterminds/goutils.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/masterminds/goutils/41ac8693c5c10a92ea1ff5ac3a7f95646f6123b0) | -| [github.com/Shopify/logrus-bugsnag@577dee27f20dd8f1a529f82210094af593be12bd](https://github.com/Shopify/logrus-bugsnag.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/shopify/logrus-bugsnag/577dee27f20dd8f1a529f82210094af593be12bd) | -| [github.com/kisielk/gotool@v1.0.0](https://github.com/kisielk/gotool.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23269) | -| [github.com/mxk/go-flowrate@cca7078d478f8520f85629ad7c68962d31ed7682](https://github.com/mxk/go-flowrate.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23298) | -| [modernc.org/golex@v1.0.0](https://gitlab.com/cznic/golex/-/tags/v1.0.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23415) | -| [modernc.org/fileutil@v1.0.0](https://gitlab.com/cznic/fileutil/-/tags/v1.0.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23413) | -| [modernc.org/db@v1.0.0](https://gitlab.com/cznic/db/-/tags/v1.0.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23411) | -| [modernc.org/b@v1.0.0](https://gitlab.com/cznic/b/-/tags/v1.0.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23410) | -| [modernc.org/file@v1.0.0](https://gitlab.com/cznic/file/-/tags/v1.0.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23412) | -| [github.com/gofrs/flock@v0.7.1](https://github.com/gofrs/flock.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23396) | -| [github.com/go-openapi/validate@v0.19.2](https://github.com/go-openapi/validate.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23394) | -| [github.com/go-openapi/runtime@v0.19.0](https://github.com/go-openapi/runtime.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23393) | -| [github.com/go-openapi/loads@v0.19.2](https://github.com/go-openapi/loads.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23392) | -| [github.com/go-logfmt/logfmt@v0.5.0](https://github.com/go-logfmt/logfmt.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23391) | -| [go.mongodb.org/mongo-driver@v1.1.0](https://github.com/mongodb/mongo-go-driver.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23449) | -| [github.com/smartystreets/goconvey@v1.6.4](https://github.com/smartystreets/goconvey.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23448) | -| [github.com/shopspring/decimal@cd690d0c9e2447b1ef2a129a6b7b49077da89b8e](https://github.com/shopspring/decimal.git) | MIT AND BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23447) | -| [github.com/phayes/freeport@95f893ade6f232a5f1511d61735d89b1ae2df543](https://github.com/phayes/freeport.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23445) | -| [modernc.org/internal@v1.0.0](https://gitlab.com/cznic/internal/-/tags/v1.0.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23416) | -| [github.com/olekukonko/tablewriter@v0.0.2](https://github.com/olekukonko/tablewriter.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23441) | -| [github.com/morikuni/aec@v1.0.0](https://github.com/morikuni/aec.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23437) | -| [github.com/mitchellh/iochan@v1.0.0](https://github.com/mitchellh/iochan.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23436) | -| [github.com/magiconair/properties@v1.8.1](https://github.com/magiconair/properties.git) | BSD-2-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23435) | -| [github.com/kardianos/osext@2bc1f35cddc0cc527b4bc3dce8578fc2a6c11384](https://github.com/kardianos/osext.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23434) | -| [modernc.org/lldb@v1.0.0](https://gitlab.com/cznic/lldb/-/tags/v1.0.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23420) | -| [modernc.org/mathutil@v1.0.0](https://gitlab.com/cznic/mathutil/-/tags/v1.0.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23421) | -| [modernc.org/sortutil@v1.1.0](https://gitlab.com/cznic/sortutil/-/tags/v1.1.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23424) | -| [modernc.org/zappy@v1.0.0](https://gitlab.com/cznic/zappy/-/tags/v1.0.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23426) | -| [modernc.org/strutil@v1.1.0](https://gitlab.com/cznic/strutil/-/tags/v1.1.0.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23425) | -| [github.com/containerd/containerd@v1.3.3](https://github.com/containerd/containerd.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23376) | -| [github.com/containerd/continuity@d3ef23f19fbb106bb73ffde425d07a9187e30745](https://github.com/containerd/continuity.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23377) | -| [github.com/coreos/go-semver@v0.3.0](https://github.com/coreos/go-semver.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23379) | -| [github.com/cockroachdb/apd@v1.1.0](https://github.com/cockroachdb/apd.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23375) | -| [github.com/coreos/pkg@399ea9e2e55f791b6e3d920860dbecb99c3692f0](https://github.com/coreos/pkg.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23380) | -| [github.com/cpuguy83/go-md2man@v1.0.10](https://github.com/cpuguy83/go-md2man.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23382) | -| [github.com/cyphar/filepath-securejoin@v0.2.2](https://github.com/cyphar/filepath-securejoin.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23383) | -| [github.com/docker/go-connections@v0.4.0](https://github.com/docker/go-connections.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23385) | -| [github.com/docker/go-events@e31b211e4f1cd09aa76fe4ac244571fab96ae47f](https://github.com/docker/go-events.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23386) | -| [github.com/fatih/color@v1.9.0](https://github.com/fatih/color.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23388) | -| [github.com/flynn/go-shlex@3f9db97f856818214da2e1057f8ad84803971cff](https://github.com/flynn-archive/go-shlex.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23390) | -| [github.com/coreos/etcd@v3.3.15](https://github.com/etcd-io/etcd.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23378) | -| [github.com/docker/go-units@v0.4.0](https://github.com/docker/go-units.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23387) | -| [github.com/gorilla/handlers@8a3748addc242fc560bd6d4ff28b0374c010b1b4](https://github.com/gorilla/handlers.git) | BSD-2-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23403) | -| [github.com/grpc-ecosystem/grpc-gateway@v1.9.5](https://github.com/grpc-ecosystem/grpc-gateway.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23404) | -| [gitlab.com/nyarla/go-crypt@d9a5dc2b789bc330075d4b805d9b7c971f2865a1](https://gitlab.com/nyarla/go-crypt.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23408) | -| [modernc.org/ql@v1.0.0](https://gitlab.com/cznic/ql/-/tags/v1.0.0.git) | BSD-3-Clause AND CC-BY-3.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23422) | -| [github.com/hashicorp/go-sockaddr@v1.0.0](https://github.com/hashicorp/go-sockaddr.git) | MPL-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23428) | -| [github.com/hashicorp/go.net@v0.0.1](https://github.com/hashicorp/go.net.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23429) | -| [github.com/Microsoft/go-winio@fc70bd9a86b5562b3b5eb1040e803febee1e90a1](https://github.com/microsoft/go-winio.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23371) | -| [github.com/Microsoft/hcsshim@v0.8.9](https://github.com/microsoft/hcsshim.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23372) | -| [github.com/yvasiyarov/gorelic@v0.0.7](https://github.com/yvasiyarov/gorelic.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/yvasiyarov/gorelic/ba7bf1b45591045ab2a20feca0fa8c22d0698c12) | -| [github.com/tebeka/strftime@v0.1.3](https://github.com/tebeka/strftime.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/tebeka/strftime/1e60d44622e3f9de852e0ae26f5a02ea3354623e) | -| [github.com/yvasiyarov/newrelic_platform_go@9c099fbc30e90de5bb5c5f94aa5fd08f2daeaacd](https://github.com/yvasiyarov/newrelic_platform_go.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/yvasiyarov/newrelic_platform_go/9c099fbc30e90de5bb5c5f94aa5fd08f2daeaacd) | -| [github.com/rs/zerolog@v1.15.0](https://github.com/rs/zerolog.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/rs/zerolog/b806a5ecbe5347ad9ef05121fea8f4acc65fa5fc) | -| [github.com/hashicorp/consul/api@v1.1.0](https://github.com/hashicorp/consul.git) | MPL-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23427) | -| [github.com/otiai10/mint@v1.3.1](https://github.com/otiai10/mint.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/otiai10/mint/bef812dd30a0e7e65435fde5ef6a81277d78ca05) | -| [gopkg.in/square/go-jose.v2@v2.2.2](https://github.com/square/go-jose.git) | Apache-2.0, BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/square/go-jose/e94fb177d3668d35ab39c61cbb2f311550557e83) | -| [rsc.io/letsencrypt@v0.0.3](https://github.com/rsc/letsencrypt.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/rsc/letsencrypt/2cfe43d8f3ba33d75c390b0e1e62e0a5f403605e) | -| [github.com/sclevine/spec@v1.2.0](https://github.com/sclevine/spec.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/sclevine/spec/b518b20aa1af75d314a31c9b3acfeeab7c4cbfb4) | -| [github.com/ClickHouse/clickhouse-go@v1.3.12](https://github.com/clickhouse/clickhouse-go.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23516) | -| [github.com/pbnjay/strptime@5c05b0d668c919165e2c16298c96a3f2ab4564b3](https://github.com/pbnjay/strptime.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23522) | -| [github.com/smartystreets/assertions@b2de0cb4f26d0705483a2f495d89896d0b808573](https://github.com/smartystreets/assertions.git) | Apache-2.0 AND BSD-3-Clause AND MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23521) | -| [github.com/xiang90/probing@43a291ad63a214a207fefbf03c7d9d78b703162b](https://github.com/xiang90/probing.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23518) | -| [github.com/Masterminds/vcs@v1.13.1](https://github.com/Masterminds/vcs.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/masterminds/vcs/f94282d8632a0620f79f0c6ff0e82604e8c5c85b) | -| [github.com/alessio/shellescape@v1.2.2](https://github.com/alessio/shellescape.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/alessio/shellescape/c3b6e53cea4242a4d6a2ee925c4b38c1f80e44e9) | -| [github.com/bugsnag/bugsnag-go@v1.5.3](https://github.com/bugsnag/bugsnag-go.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/bugsnag/bugsnag-go/3b0dbb79d7cc36c982e6ba70ceb76771552434f6) | -| [github.com/bugsnag/panicwrap@v1.2.0](https://github.com/bugsnag/panicwrap.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/bugsnag/panicwrap/4009b2b7c78d820cc4a2e42f035bb557ce4ae45b) | -| [github.com/cockroachdb/cockroach-go@606b3d062051259eca584a3f998d37e39b3b7622](https://github.com/cockroachdb/cockroach-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/cockroachdb/cockroach-go/606b3d062051259eca584a3f998d37e39b3b7622) | -| [github.com/containerd/ttrpc@v1.0.1](https://github.com/containerd/ttrpc.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/containerd/ttrpc/72bb1b21c5b0a4a107f59dd85f6ab58e564b68d6) | -| [github.com/containerd/typeurl@2a93cfde8c20b23de8eb84a5adbc234ddf7a9e8d](https://github.com/containerd/typeurl.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/containerd/typeurl/2a93cfde8c20b23de8eb84a5adbc234ddf7a9e8d) | -| [github.com/coreos/go-oidc@v2.1.0](https://github.com/coreos/go-oidc.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/coreos/go-oidc/2be1c5b8a260760503f66dc0996e102b683b3ac3) | -| [github.com/cznic/mathutil@ca4c9f2c136954238c3158b92de72078c7672ecc](https://github.com/cznic/mathutil.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/cznic/mathutil/ca4c9f2c136954238c3158b92de72078c7672ecc) | -| [github.com/docker/libtrust@aabc10ec26b754e797f9028f4589c5b7bd90dc20](https://github.com/docker/libtrust.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/docker/libtrust/aabc10ec26b754e797f9028f4589c5b7bd90dc20) | -| [github.com/fastly/go-utils@d95a45783239f69a867fec572fb7675bcee07d88](https://github.com/fastly/go-utils.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/fastly/go-utils/d95a45783239f69a867fec572fb7675bcee07d88) | -| [github.com/fatih/camelcase@v1.0.0](https://github.com/fatih/camelcase.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/fatih/camelcase/44e46d280b43ec1531bb25252440e34f1b800b65) | -| [github.com/fvbommel/sortorder@v1.0.1](https://github.com/fvbommel/sortorder.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/fvbommel/sortorder/a1ddee917217bbd0691affdca9c88d24d3f5c27d) | -| [github.com/godbus/dbus@ade71ed3457e1a2d0edc32a59e718cc523e73b21](https://github.com/godbus/dbus.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/godbus/dbus/ade71ed3457e1a2d0edc32a59e718cc523e73b21) | -| [github.com/golangplus/bytes@45c989fe545070ef7c9003cf1998bb195c61731a](https://github.com/golangplus/bytes.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/golangplus/bytes/45c989fe545070ef7c9003cf1998bb195c61731a) | -| [github.com/grpc-ecosystem/grpc-health-probe@v0.3.2](https://github.com/grpc-ecosystem/grpc-health-probe.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/grpc-ecosystem/grpc-health-probe/71ebd03865797e785bdc7ae6fababe548b75188e) | -| [github.com/hokaccha/go-prettyjson@108c894c2c0e4a3236172e3698c14f1e3199548d](https://github.com/hokaccha/go-prettyjson.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/hokaccha/go-prettyjson/108c894c2c0e4a3236172e3698c14f1e3199548d) | -| [github.com/go-air/gini@v1.0.1](https://github.com/go-air/gini.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-air/gini/ab553a98575687dd98cf73371b2fc398f41d10fc) | -| [github.com/itchyny/astgen-go@cf3ea398f64584ef328f8fa3e0281536dbaffa4b](https://github.com/itchyny/astgen-go.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/itchyny/astgen-go/cf3ea398f64584ef328f8fa3e0281536dbaffa4b) | -| [github.com/itchyny/gojq@v0.11.0](https://github.com/itchyny/gojq.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/itchyny/gojq/d33449f4c07af896f91db06c7b64052c92ebe42b) | -| [github.com/jackc/pgmock@13a1b77aafa2641ad31b655a18e8c3605ef55e2d](https://github.com/jackc/pgmock.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/jackc/pgmock/13a1b77aafa2641ad31b655a18e8c3605ef55e2d) | -| [github.com/jehiah/go-strftime@1d33003b386959af197ba96475f198c114627b5e](https://github.com/jehiah/go-strftime.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/jehiah/go-strftime/1d33003b386959af197ba96475f198c114627b5e) | -| [github.com/joefitzgerald/rainbow-reporter@v0.1.0](https://github.com/joefitzgerald/rainbow-reporter.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/joefitzgerald/rainbow-reporter/f35bccf50a5c24f2fca9dc7e131454c60efba904) | -| [github.com/lestrrat-go/strftime@v1.0.1](https://github.com/lestrrat-go/strftime.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/lestrrat-go/strftime/6b63b6de4db1514785520f626319d12516ee6932) | -| [github.com/liggitt/tabwriter@89fcab3d43de07060e4fd4c1547430ed57e87f24](https://github.com/liggitt/tabwriter.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/liggitt/tabwriter/89fcab3d43de07060e4fd4c1547430ed57e87f24) | -| [github.com/lithammer/dedent@v1.1.0](https://github.com/lithammer/dedent.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/lithammer/dedent/8478954c3bc893cf36c5ee7c822266b993a3b3ee) -| [github.com/moby/term@df9cb8a406352e9543f2b7cae1c8579b51b8013e](https://github.com/moby/term.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/moby/term/df9cb8a406352e9543f2b7cae1c8579b51b8013e) | -| [github.com/nakagami/firebirdsql@3c02a58cfed8c5b191d653309705042fcd6c4f9c](https://github.com/nakagami/firebirdsql.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/nakagami/firebirdsql/3c02a58cfed8c5b191d653309705042fcd6c4f9c) | -| [github.com/neo4j-drivers/gobolt@v1.7.4](https://github.com/neo4j-drivers/gobolt.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/neo4j-drivers/gobolt/0b8728e471cbd11fe5ffa3ae65a467886018012e) | -| [github.com/neo4j/neo4j-go-driver@v1.7.4](https://github.com/neo4j/neo4j-go-driver.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/neo4j/neo4j-go-driver/934739616886b903306e1df80aa58047407a1971) | -| [github.com/otiai10/copy@v1.2.0](https://github.com/otiai10/copy.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/otiai10/copy/c5f0361fe546fb0f4f26b13746afc8864ea7f6d9) | -| [github.com/otiai10/curr@v1.0.0](https://github.com/otiai10/curr.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/otiai10/curr/88e2f2cffa0b5f13e90ee963a321bd1b2f715561) | -| [github.com/rs/xid@v1.2.1](https://github.com/rs/xid.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/rs/xid/15d26544def341f036c5f8dca987a4cbe575032c) | -| [github.com/zenazn/goji@v0.9.0](https://github.com/zenazn/goji.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/zenazn/goji/845982030542a0fd9c8e8cbf76a84c7482cb3755) | -| [go.uber.org/tools@2cfd321de3ee5d5f8a5fda2521d1703478334d98](https://github.com/uber-go/tools.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/uber-go/tools/2cfd321de3ee5d5f8a5fda2521d1703478334d98) | -| [google.golang.org/grpc/cmd/protoc-gen-go-grpc@d8193ee9cc3e403ec488bf371c57fe8a63e34890](https://github.com/grpc/grpc-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/grpc/grpc-go/d8193ee9cc3e403ec488bf371c57fe8a63e34890) | -| [gopkg.in/alecthomas/kingpin.v2@v2.2.6](https://github.com/alecthomas/kingpin.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/alecthomas/kingpin/947dcec5ba9c011838740e680966fd7087a71d0d) | -| [gopkg.in/cheggaaa/pb.v1@v1.0.25](https://github.com/cheggaaa/pb.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/cheggaaa/pb/2af8bbdea9e99e83b3ac400d8f6b6d1b8cbbf338) | -| [gopkg.in/gemnasium/logrus-airbrake-hook.v2@v2.1.2](https://github.com/gemnasium/logrus-airbrake-hook.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/gemnasium/logrus-airbrake-hook/e928b033a891c0175fb643d5aa0779e86325eb12) | -| [gopkg.in/go-playground/validator.v9@v9.30.0](https://github.com/go-playground/validator.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-playground/validator/cd1bd581694a11c089aea885a26247c5f783a4cf) | -| [gopkg.in/ini.v1@v1.51.0](https://github.com/go-ini/ini.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-ini/ini/87e589f4917038ae250cff2446db7573f47e97ca) | -| [gopkg.in/natefinch/lumberjack.v2@v2.0.0](https://github.com/natefinch/lumberjack.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/natefinch/lumberjack/7d6a1875575e09256dc552b4c0e450dcd02bd10e) | -| [gopkg.in/op/go-logging.v1@b2cb9fa56473e98db8caba80237377e83fe44db5](https://github.com/op/go-logging.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/op/go-logging/b2cb9fa56473e98db8caba80237377e83fe44db5) | -| [gopkg.in/resty.v1@v1.12.0](https://github.com/go-resty/resty.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-resty/resty/fa5875c0caa5c260ab78acec5a244215a730247f) | -| [gopkg.in/tomb.v2@d5d1b5820637886def9eef33e03a27a9f166942c](https://github.com/go-tomb/tomb.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-tomb/tomb/d5d1b5820637886def9eef33e03a27a9f166942c) | -| [gopkg.in/yaml.v3@v3.0.1](https://github.com/go-yaml/yaml.git) | Apache-2.0, Apache-2.0 AND MIT, MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-yaml/yaml/f6f7691b1fdeb513f56608cd2c32c51f8194bf51) | -| [k8s.io/component-helpers@v0.20.1](https://github.com/kubernetes/component-helpers.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes/component-helpers/fb2b7e6065f426f2dac708ad93518177c879a9ab) | -| [github.com/yvasiyarov/go-metrics@c25f46c4b94079672242ec48a545e7ca9ebe3aec](https://github.com/yvasiyarov/go-metrics.git) | BSD-2-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23519) | -| [github.com/go-bindata/go-bindata/v3@v3.1.3](https://github.com/go-bindata/go-bindata.git) | CC0-1.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23561) | -| [bazil.org/fuse@371fbbdaa8987b715bdd21d6adc4c9b20155f748](https://github.com/bazil/fuse.git) | BSD-3-Clause AND MIT AND BSD-2-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23543) | -| [github.com/jackc/pgtype@a8802b16cc593842f5c69b0f7cfb0de11d5cd3a8](https://github.com/jackc/pgtype.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23576) | -| [github.com/docker/go-metrics@v0.0.1](https://github.com/docker/go-metrics.git) | Apache-2.0 AND CC-BY-SA-4.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23558) | -| [sigs.k8s.io/kind@v0.10.0](https://github.com/kubernetes-sigs/kind.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23596) | -| [gopkg.in/inconshreveable/log15.v2@67afb5ed74ec82fd7ac8f49d27c509ac6f991970](https://github.com/inconshreveable/log15.git) | Apache-2.0 AND BSD-3-Clause AND MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23594) | -| [gopkg.in/airbrake/gobrake.v2@v2.0.9](https://github.com/airbrake/gobrake.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23593) | -| [go.etcd.io/etcd@dd1b699fc4895de8cc23c3cac5a428c37eee384a](https://github.com/etcd-io/etcd.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23592) | -| [github.com/remyoudompheng/bigfft@6a916e37a237384e18eefa3270c09247db1ecf50](https://github.com/remyoudompheng/bigfft.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23591) | -| [github.com/operator-framework/operator-registry@v1.13.6](https://github.com/operator-framework/operator-registry.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23590) | -| [github.com/openshift/api@88b476f987ed90f7b0e1fdc851859c35161b1ff5](https://github.com/openshift/api.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/openshift/api/88b476f987ed90f7b0e1fdc851859c35161b1ff5) | -| [github.com/chai2010/gettext-go@c6fed771bfd517099caf0f7a961671fa8ed08723](https://github.com/chai2010/gettext-go.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23551) | -| [github.com/cloudflare/golz4@ef862a3cdc58a6f1fee4e3af3d44fbe279194cde](https://github.com/cloudflare/golz4.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23552) | -| [github.com/coreos/go-systemd@fd7a80b32e1fc73e890fde45604ed5009dc817a3](https://github.com/coreos/go-systemd.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23553) | -| [github.com/daviddengcn/go-colortext@511bcaf42ccd42c38aba7427b6673277bf19e2a1](https://github.com/daviddengcn/go-colortext.git) | BSD-3-Clause AND MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23554) | -| [github.com/docker/cli@5d0cf8839492eb1af7c611a58d09034d29aa9631](https://github.com/docker/cli.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23556) | -| [github.com/docker/distribution@v2.7.1](https://github.com/distribution/distribution.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23557) | -| [github.com/fsouza/fake-gcs-server@v1.17.0](https://github.com/fsouza/fake-gcs-server.git) | BSD-2-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23559) | -| [github.com/bshuster-repo/logrus-logstash-hook@v1.0.0](https://github.com/bshuster-repo/logrus-logstash-hook.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23549) | -| [github.com/garyburd/redigo@v1.6.0](https://github.com/garyburd/redigo.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23560) | -| [github.com/opencontainers/runc@6cc515888830787a93d82138821f0309ad970640](https://github.com/opencontainers/runc.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23584) | -| [github.com/lestrrat-go/envload@a3eb8ddeffccdbca0eb6dd6cc7c7950c040a6546](https://github.com/lestrrat-go/envload.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23580) | -| [github.com/jackc/puddle@11cab39313c9677f9807fef985e6f44e44ddb2ce](https://github.com/jackc/puddle.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23579) | -| [github.com/golangplus/fmt@2a5d6d7d2995baf7d847b7f16ac0179c6888d37b](https://github.com/golangplus/fmt.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23565) | -| [github.com/jackc/pgx/v4@6972a57421861e041adb04dc7294c0ef40e5b3a6](https://github.com/jackc/pgx.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23578) | -| [github.com/itchyny/go-flags@v1.5.0](https://github.com/itchyny/go-flags.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23567) | -| [github.com/jackc/pgconn@v1.3.2](https://github.com/jackc/pgconn.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23570) | -| [github.com/jackc/pgproto3/v2@v2.0.1](https://github.com/jackc/pgproto3.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23574) | -| [github.com/jackc/pgio@v1.0.0](https://github.com/jackc/pgio.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23571) | -| [github.com/jackc/pgpassfile@v1.0.0](https://github.com/jackc/pgpassfile.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23572) | -| [github.com/bketelsen/crypt@5cbc8cc4026c0c1d3bf9c5d4e5a30398f99c99a9](https://github.com/bketelsen/crypt.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23548) | -| [github.com/bkaradzic/go-lz4@v1.0.0](https://github.com/bkaradzic/go-lz4.git) | BSD-2-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23547) | -| [cloud.google.com/go/spanner@v1.2.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23545) | -| [github.com/goccy/go-yaml@v1.8.1](https://github.com/goccy/go-yaml.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23562) | -| [github.com/gocql/gocql@f6df8288f9b44e66f50c9a59aee53a705c788dbe](https://github.com/gocql/gocql.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23564) | -| [github.com/hashicorp/logutils@v1.0.0](https://github.com/hashicorp/logutils.git) | MPL-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23430) | -| [github.com/hashicorp/serf@v0.8.2](https://github.com/hashicorp/serf.git) | MPL-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23431) | -| [github.com/mikefarah/yq/v3@8846255d1c37457b729108cfa4160b4b678b8003](https://github.com/mikefarah/yq.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23583) | -| [github.com/miekg/dns@v1.0.14](https://github.com/miekg/dns.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23581) | -| [github.com/opencontainers/go-digest@v1.0.0](https://github.com/opencontainers/go-digest.git) | Apache-2.0 AND CC-BY-SA-4.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23442) | -| [github.com/opencontainers/image-spec@775207bd45b6cb8153ce218cc59351799217451f](https://github.com/opencontainers/image-spec.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23443) | -| [github.com/operator-framework/operator-lifecycle-manager@v0.18.1](https://github.com/operator-framework/operator-lifecycle-manager.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23589) | -| [github.com/pascaldekloe/goe@57f6aae5913c64c9bcae5dbdffd33365b5a7f138](https://github.com/pascaldekloe/goe.git) | CC0-1.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23444) | -| [sigs.k8s.io/structured-merge-diff/v3@67a7b8c618745e7c2217ca9aebfff71216e9a6ce](https://github.com/kubernetes-sigs/structured-merge-diff.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23597) | -| [gopkg.in/check.v1@64131543e7896d5bcc6bd5a76287eb75ea96c673](https://github.com/go-check/check.git) | BSD-2-Clause AND BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23345) | -| [cloud.google.com/go/firestore@v1.1.0](https://github.com/googleapis/google-cloud-go.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23544) | -| [github.com/hashicorp/consul/sdk@v0.1.1](https://github.com/hashicorp/consul.git) | MPL-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23566) | -| [github.com/jackc/chunkreader/v2@v2.0.1](https://github.com/jackc/chunkreader.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23569) | -| [github.com/opencontainers/runtime-spec@v1.0.0](https://github.com/opencontainers/runtime-spec.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23585) | -| [github.com/maxbrunsfeld/counterfeiter/v6@v6.2.2](https://github.com/maxbrunsfeld/counterfeiter.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23610) | -| [github.com/evanphx/json-patch/v5@v5.1.0](https://github.com/evanphx/json-patch.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23609) | -| [github.com/fatih/set@v0.2.1](https://github.com/fatih/set.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/fatih/set/2c768e3c5489976167bfc42b5c7c92ca783f4389) | -| [github.com/go-errors/errors@v1.0.1](https://github.com/go-errors/errors.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-errors/errors/a6af135bd4e28680facf08a3d206b454abc877a4) | -| [github.com/go-logr/zapr@v1.2.3](https://github.com/go-logr/zapr.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fgo-logr/zapr/v1.2.3) | -| [github.com/google/go-cmp@v0.5.9](https://github.com/google/go-cmp.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/google/go-cmp/a97318bf6562f2ed2632c5f985db51b1bc5bdcd0) | -| [github.com/prometheus/client_golang@v1.14.0](https://github.com/prometheus/client_golang.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/prometheus/client_golang/254e5468413f19fb75cdad45f5ddc0b8c975188c) | -| [github.com/prometheus/client_model@v0.3.0](https://github.com/prometheus/client_model.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/prometheus/client_model/63fb9822ca3ba7a4ba5184071fb8f2ea000a99ef) | -| [github.com/prometheus/common@v0.26.0](https://github.com/prometheus/common.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/prometheus/common/0ec6a33fff8b8a6950b82f03c4bfabaf61ac4813) | -| [github.com/prometheus/procfs@v0.6.0](https://github.com/prometheus/procfs.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/prometheus/procfs/e971af51d579a49db14657a96eebec39cefb4755) | -| [go.uber.org/atomic@v1.7.0](https://github.com/uber-go/atomic.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/uber-go/atomic/12f27ba2637fa0e13772a4f05fa46a5d18d53182) | -| [go.uber.org/zap@v1.18.1](https://github.com/uber-go/zap.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/uber-go/zap/120b08c8fae5be92bc7323ca78b25cd790e8c37a) | -| [k8s.io/api@v0.26.1](https://github.com/kubernetes/api.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/k8s.io/api/v0.26.1) | -| [k8s.io/apimachinery@v0.26.1](https://github.com/kubernetes/apimachinery.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/k8s.io/apimachinery/v0.26.1) | -| [github.com/benbjohnson/clock@v1.1.0](https://github.com/benbjohnson/clock.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23738) | -| [github.com/evanphx/json-patch@v4.11.0](https://github.com/evanphx/json-patch.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23729) | -| [github.com/go-kit/log@v0.1.0](https://github.com/go-kit/log.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23739) | -| [github.com/jpillora/backoff@v1.0.0](https://github.com/jpillora/backoff.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23731) | -| [github.com/moby/spdystream@v0.2.0](https://github.com/moby/spdystream.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23294) | -| [github.com/operator-framework/api@v0.15.0](https://github.com/operator-framework/api.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23754) | -| [github.com/redhat-cop/operator-utils@v1.1.4](https://github.com/redhat-cop/operator-utils.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23755) | -| [github.com/scylladb/go-set@v1.0.2](https://github.com/scylladb/go-set.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23757) | -| [go.uber.org/goleak@v1.1.10](https://github.com/uber-go/goleak.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23758) | -| [k8s.io/apiextensions-apiserver@v0.26.1](https://github.com/kubernetes/apiextensions-apiserver.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/k8s.io/apiextensions-apiserver/v0.26.1) | -| [k8s.io/apiserver@v0.21.3](https://github.com/kubernetes/apiserver.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23733) | -| [k8s.io/cli-runtime@v0.20.1](https://github.com/kubernetes/cli-runtime.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/k8s.io/cli-runtime/v0.20.1) | -| [k8s.io/client-go@v0.26.1](https://github.com/kubernetes/client-go.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/k8s.io/client-go/v0.26.1) | -| [sigs.k8s.io/apiserver-network-proxy/konnectivity-client@v0.0.19](https://github.com/kubernetes-sigs/apiserver-network-proxy.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23744) | -| [sigs.k8s.io/controller-runtime@v0.14.4](https://github.com/kubernetes-sigs/controller-runtime.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/sigs.k8s.io/controller-runtime/v0.14.4) | -| [sigs.k8s.io/controller-tools@v0.6.0](https://github.com/kubernetes-sigs/controller-tools.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23743) | -| [github.com/alcortesm/tgz@9c5fe88206d7765837fed3732a42ef88fc51f1a1](https://github.com/alcortesm/tgz.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/alcortesm/tgz/9c5fe88206d7765837fed3732a42ef88fc51f1a1) | -| [github.com/armon/go-socks5@e75332964ef517daa070d7c38a9466a0d687e0a5](https://github.com/armon/go-socks5.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/armon/go-socks5/e75332964ef517daa070d7c38a9466a0d687e0a5) | -| [github.com/go-git/gcfg@v1.5.0](https://github.com/go-git/gcfg.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-git/gcfg/22f18f9a74d34e3b1a7d59cfa33043bc50ebe376) | -| [github.com/go-git/go-git/v5@v5.2.0](https://github.com/go-git/go-git.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-git/go-git/97741e72346716fd90e534a1b9bd9f7643cd0c80) | -| [github.com/niemeyer/pretty@a10e7caefd8e0d600cea437f5c3613aeb1553d56](https://github.com/niemeyer/pretty.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/niemeyer/pretty/a10e7caefd8e0d600cea437f5c3613aeb1553d56) | -| [github.com/santhosh-tekuri/jsonschema@v1.2.4](https://github.com/santhosh-tekuri/jsonschema.git) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/santhosh-tekuri/jsonschema/534765aa6277d702a0aaf99c986492dda697d48f) | -| [github.com/xanzy/ssh-agent@v0.2.1](https://github.com/xanzy/ssh-agent.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/xanzy/ssh-agent/6a3e2ff9e7c564f36873c2e36413f634534f1c44) | -| [gopkg.in/warnings.v0@v0.1.2](https://github.com/go-warnings/warnings.git) | BSD-2-Clause | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-warnings/warnings/ec4a0fea49c7b46c2aeb0b51aac55779c607e52b) | -| [github.com/jbenet/go-context@d14ea06fba99483203c19d92cfcd13ebe73135f4](https://github.com/jbenet/go-context.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23645) | -| [github.com/go-git/go-billy/v5@v5.0.0](https://github.com/go-git/go-billy.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23644) | -| [github.com/gliderlabs/ssh@v0.2.2](https://github.com/gliderlabs/ssh.git) | BSD-3-Clause | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23642) | -| [github.com/emirpasic/gods@v1.12.0](https://github.com/emirpasic/gods.git) | BSD-2-Clause AND BSD-3-Clause AND ISC | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23643) | -| [github.com/openshift/client-go@2a6cd50aedd02a8b1573c0de49169a43061cf587](https://github.com/openshift/client-go.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23587) | -| [github.com/kevinburke/ssh_config@01f96b0aa0cdcaa93f9495f89bbc6cb5a992ce6e](https://github.com/kevinburke/ssh_config.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23646) | -| [github.com/asaskevich/govalidator@f61b66f89f4a311bef65f13e575bcf1a2ffadda6](https://github.com/asaskevich/govalidator.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/asaskevich/govalidator/f61b66f89f4a311bef65f13e575bcf1a2ffadda6) | -| [github.com/lucasjones/reggen@37ba4fa293bb40d3e1d805ba3545bfaab688d669](https://github.com/lucasjones/reggen.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23647) | -| [github.com/asaskevich/govalidator@f61b66f89f4a311bef65f13e575bcf1a2ffadda6](https://github.com/asaskevich/govalidator.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/asaskevich/govalidator/f61b66f89f4a311bef65f13e575bcf1a2ffadda6) | -| [github.com/moby/moby@38ab9da0030917f154f4d1b05962d48de149d47c](https://github.com/moby/moby.git) | Apache-2.0 AND BSD-3-Clause AND BSD-2-Clause AND MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23774) | -| [github.com/go-openapi/analysis@v0.19.2](https://github.com/go-openapi/analysis.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23775) | -| [github.com/anmitsu/go-shlex@648efa622239a2f6ff949fed78ee37b48d499ba4](https://github.com/anmitsu/go-shlex.git) | MIT | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23777) | -| [sigs.k8s.io/kustomize@v2.0.3](https://sigs.k8s.io/kustomize.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23778) | -| [github.com/go-git/go-git-fixtures/v4@f56387b50c12de95a311253967bdbdcaf56e4545](https://github.com/go-git/go-git-fixtures.git) | Apache-2.0 | [CQ](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=23779) | -| [golang.org/x/crypto@v0.35.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/exp@956cc1757749645f24cefb2ef2a41b0ec4514cf8](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/image@0694c2d4d067f97ebef574d63a763ee8ab559da7](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/lint@6edffad5e6160f5949cdefc81710b2706fbcd4f6](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/mod@v0.17.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/net@v0.36.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/sync@v0.10.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/sys@v0.28.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/telemetry@v0.0.0-20240228155512-f48c80bd79b2](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/term@v0.27.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/text@v0.21.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/time@v0.3.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/tools@vv0.21.1-0.20240508182429-e35e4ccd0d2d](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/xerrors@v0.0.0-20220907171357-04be3eba64a2](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/oauth2@v0.27.0](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [golang.org/x/mobile@d3739f865fa66d07c1f506505c18aac71a8ead6e](https://cs.opensource.google/go) | BSD-3-Clause | N/A | -| [github.com/devfile/api/v2@v2.2.2](https://github.com/devfile/api.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/devfile/api/a6ec0a38307b63a29fad2eea945cc69bee97a683) | -| [github.com/che-incubator/kubernetes-image-puller-operator@0128446f5af78587c0427a35d693bbb8d24036bc](https://github.com/che-incubator/kubernetes-image-puller-operator.git) | EPL-2.0 | todo | -| [github.com/devfile/devworkspace-operator@v0.35.0](https://github.com/devfile/devworkspace-operator.git) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/devfile/devworkspace-operator/4823c6cf920e33d4d3101a53ef3b98517b3f8349) | -| [github.com/gophercloud/gophercloud@v0.1.0](https://github.com/gophercloud/gophercloud) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fgophercloud/gophercloud/v0.1.0) | -| [gopkg.in/imdario/mergo.v0@v0.3.7](https://github.com/imdario/mergo/) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fimdario/mergo/v0.3.7) | -| [github.com/mikefarah/yq/v2@v2.4.1](https://github.com/mikefarah/yq) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/mikefarah/yq/b8b2c9de6189471c0cdbd459b5b0b49a57844bd4) | -| [github.com/stoewer/go-strcase@v1.2.0](https://github.com/stoewer/go-strcase) | MIT | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fstoewer/go-strcase/v1.2.0) | -| [github.com/emicklei/go-restful/v3@v3.9.0](https://github.com/emicklei/go-restful/) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/emicklei/go-restful/ce871fa2f7069b65c784c9c708da1f00b1f2bd66) | -| [github.com/onsi/ginkgo/v2@v2.6.0](https://github.com/onsi/ginkgo/) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/onsi/ginkgo/6ad4fae4dd614651bdf97d445990536c3d4ce225) | -| [rsc.io/sampler@v1.3.0](https://github.com/rsc/sampler) | BSD-3-Clause | [clearlydefined](https://clearlydefined.io/definitions/go/golang/rsc.io/sampler/v1.3.0) | -| [sigs.k8s.io/structured-merge-diff/v4@v4.2.3](https://github.com/kubernetes-sigs/structured-merge-diff/) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes-sigs/structured-merge-diff/26781d0c10bfdbd7d66b18d8be83985f623df9f8) | -| [github.com/mikefarah/yaml/v2@v2.4.0](https://github.com/mikefarah/yaml/) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/git/github/mikefarah/yaml/7649d4548cb53a614db133b2a8ac1f31859dda8c) | -| [github.com/docker/spdystream@v0.0.0-20160310174837-449fdfce4d96](https://github.com/moby/spdystream) | Apache-2.0 AND CC-BY-SA-4.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fdocker/spdystream/v0.0.0-20160310174837-449fdfce4d96) | -| [rsc.io/quote/v3@v3.1.0](https://github.com/rsc/quote/) | BSD-3-Clause| [clearlydefined](https://clearlydefined.io/definitions/git/github/rsc/quote/0406d7298882187f4c75f75fa85cc808a64bcef1) | -| [sigs.k8s.io/json@v0.0.0-20220713155537-f223a00ba0e2](https://github.com/kubernetes-sigs/json) | Apache-2.0 AND BSD-3-Clause AND NOASSERTION | [clearlydefined](https://clearlydefined.io/definitions/git/github/kubernetes-sigs/json/f223a00ba0e27f539157f69f9c919c204ea7f40b) | -| [github.com/google/gnostic@v0.5.7-v3refs](https://github.com/kubernetes-sigs/json) | Apache-2.0 | [clearlydefined](https://clearlydefined.io/definitions/go/golang/github.com%2Fgoogle/gnostic/v0.5.7-v3refs) | -| [github.com/go-task/slim-sprig@v0.0.0-20230315185526-52ccab3ef572](https://github.com/go-task/slim-sprig.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-task/slim-sprig/52ccab3ef572c7e1a2c258be183f9a9296d60152) | -| [github.com/go-task/slim-sprig/v3@v3.0.0](https://github.com/go-task/slim-sprig.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/go-task/slim-sprig/b05cce61fffa5c6dea6ac8b9a1f12b6e3fb7c894) | -| [github.com/josharian/intern@v1.0.0](https://github.com/josharian/intern.git) | MIT | [clearlydefined](https://clearlydefined.io/definitions/git/github/josharian/intern/8e6ff32b3e7c0b018c43953085fe2ac330fe9acd) | diff --git a/Dockerfile b/Dockerfile index dcd36283a3..5375334e6c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,7 +44,7 @@ COPY go.mod go.mod COPY go.sum go.sum # Copy the go source -COPY main.go main.go +COPY cmd/ cmd/ COPY vendor/ vendor/ COPY api/ api/ COPY config/ config/ @@ -56,7 +56,7 @@ COPY editors-definitions /tmp/editors-definitions # to test FIPS compliance, run https://github.com/openshift/check-payload#scan-a-container-or-operator-image against a built image RUN export ARCH="$(uname -m)" && if [[ ${ARCH} == "x86_64" ]]; then export ARCH="amd64"; elif [[ ${ARCH} == "aarch64" ]]; then export ARCH="arm64"; fi && \ if [[ ${SKIP_TESTS} == "false" ]]; then export MOCK_API=true && go test -mod=vendor -v ./...; fi && \ - GOOS=linux GOARCH=${ARCH} GO111MODULE=on go build -mod=vendor -a -o che-operator main.go + GOOS=linux GOARCH=${ARCH} GO111MODULE=on go build -mod=vendor -a -o che-operator cmd/main.go # https://registry.access.redhat.com/ubi8-minimal FROM registry.access.redhat.com/ubi8-minimal:8.10-1154 diff --git a/Makefile b/Makefile index eb8d921423..1d7618711f 100644 --- a/Makefile +++ b/Makefile @@ -124,18 +124,18 @@ help: ## Display this help. ##@ Development build: generate ## Build Eclipse Che operator binary - go build -o bin/manager main.go + go build -o bin/manager cmd/main.go run: SHELL := /bin/bash run: install-che-operands genenerate-env ## Run Eclipse Che operator source $(BASH_ENV_FILE) - go run ./main.go + go run cmd/main.go debug: SHELL := /bin/bash debug: install-che-operands genenerate-env ## Run and debug Eclipse Che operator source $(BASH_ENV_FILE) # dlv has an issue with 'Ctrl-C' termination, that's why we're doing trick with detach. - dlv debug --listen=:2345 --headless=true --api-version=2 ./main.go -- & + dlv debug --listen=:2345 --headless=true --api-version=2 cmd/main.go -- & DLV_PID=$! wait $${DLV_PID} @@ -366,7 +366,7 @@ install-che-operands: generate manifests download-kustomize download-gateway-res if [[ ! "$$($(K8S_CLI) get checluster eclipse-che -n $(ECLIPSE_CHE_NAMESPACE) || false )" ]]; then [[ $(PLATFORM) == "kubernetes" ]] && $(MAKE) install-certmgr $(MAKE) install-devworkspace CHANNEL="next" - $(KUSTOMIZE) build config/$(PLATFORM) | $(K8S_CLI) apply -f - + $(KUSTOMIZE) build config/$(PLATFORM) | $(K8S_CLI) apply --server-side -f - $(MAKE) wait-pod-running SELECTOR="app.kubernetes.io/component=che-operator" NAMESPACE=$(ECLIPSE_CHE_NAMESPACE) fi @@ -481,7 +481,7 @@ bundle: generate manifests download-kustomize download-operator-sdk ## Generate goimports -w ./api go fmt -x ./api - $(OPERATOR_SDK) bundle validate $${BUNDLE_PATH} --select-optional name=operatorhub --optional-values=k8s-version=1.19 + $(OPERATOR_SDK) bundle validate $${BUNDLE_PATH} --select-optional name="operatorhubv2" --select-optional name="good-practices" --optional-values=k8s-version=1.19 bundle-build: SHELL := /bin/bash bundle-build: download-opm ## Build a bundle image @@ -575,24 +575,19 @@ bundle-version: ## Prints a bundle version for a given channel ##@ Utilities OPM ?= $(shell pwd)/bin/opm +OPM_VERSION ?= "v1.26.2" download-opm: SHELL := /bin/bash download-opm: ## Download opm tool - [[ -z "$(DEST)" ]] && dest=$(OPM) || dest=$(DEST)/opm command -v $(OPM) >/dev/null 2>&1 && exit - OS=$(shell go env GOOS) - ARCH=$(shell go env GOARCH) - OPM_VERSION=$$(yq -r '.opm' $(PROJECT_DIR)/REQUIREMENTS) - - echo "[INFO] Downloading opm version: $${OPM_VERSION}" - - mkdir -p $$(dirname "$${dest}") - curl -sL https://github.com/operator-framework/operator-registry/releases/download/$${OPM_VERSION}/$${OS}-$${ARCH}-opm > $${dest} - chmod +x $${dest} + echo "[INFO] Downloading opm version: $(OPM_VERSION)" + mkdir -p $$(dirname "$(OPM)") + curl -sL https://github.com/operator-framework/operator-registry/releases/download/$(OPM_VERSION)/$$(go env GOOS)-$$(go env GOARCH)-opm > $(OPM) + chmod +x $(OPM) CONTROLLER_GEN = $(shell pwd)/bin/controller-gen download-controller-gen: ## Download controller-gen tool - $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0) + $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.18.0) KUSTOMIZE = $(shell pwd)/bin/kustomize download-kustomize: ## Download kustomize tool @@ -602,20 +597,27 @@ ADD_LICENSE = $(shell pwd)/bin/addlicense download-addlicense: ## Download addlicense tool $(call go-get-tool,$(ADD_LICENSE),github.com/google/addlicense@99ebc9c9db7bceb8623073e894533b978d7b7c8a) +OPERATOR_SDK_VERSION ?= "v1.39.2" OPERATOR_SDK ?= $(shell pwd)/bin/operator-sdk download-operator-sdk: SHELL := /bin/bash download-operator-sdk: ## Downloads operator sdk tool - [[ -z "$(DEST)" ]] && dest=$(OPERATOR_SDK) || dest=$(DEST)/operator-sdk - command -v $${dest} >/dev/null 2>&1 && exit - - OS=$(shell go env GOOS) - ARCH=$(shell go env GOARCH) - OPERATOR_SDK_VERSION=$$(yq -r '."operator-sdk"' $(PROJECT_DIR)/REQUIREMENTS) - - echo "[INFO] Downloading operator-sdk version $${OPERATOR_SDK_VERSION} into $${dest}" - mkdir -p $$(dirname "$${dest}") - curl -sL https://github.com/operator-framework/operator-sdk/releases/download/$${OPERATOR_SDK_VERSION}/operator-sdk_$${OS}_$${ARCH} > $${dest} - chmod +x $${dest} + command -v $(OPERATOR_SDK) >/dev/null 2>&1 && exit + + echo "[INFO] Downloading operator-sdk version $(OPERATOR_SDK_VERSION) into $(OPERATOR_SDK)" + mkdir -p $$(dirname "$(OPERATOR_SDK)") + curl -sL https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk_$$(go env GOOS)_$$(go env GOARCH) > $(OPERATOR_SDK) + chmod +x $(OPERATOR_SDK) + +KUBEBUILDER_VERSION ?= "v4.7.1" +KUBEBUILDER ?= $(shell pwd)/bin/kubebuilder +download-kubebuilder: SHELL := /bin/bash +download-kubebuilder: ## Downloads kubebuilder tool + command -v $(KUBEBUILDER) >/dev/null 2>&1 && exit + + echo "[INFO] Downloading kubebuilder version $(KUBEBUILDER_VERSION) into $(KUBEBUILDER)" + mkdir -p $$(dirname "$(KUBEBUILDER)") + curl -sL https://github.com/kubernetes-sigs/kubebuilder/releases/download/$(KUBEBUILDER_VERSION)/kubebuilder_$$(go env GOOS)_$$(go env GOARCH) > $(KUBEBUILDER) + chmod +x $(KUBEBUILDER) # Check if all required packages are installed validate-requirements: SHELL := /bin/bash diff --git a/PROJECT b/PROJECT index 7b1e635396..a4bc6667f2 100644 --- a/PROJECT +++ b/PROJECT @@ -1,6 +1,10 @@ +# Code generated by tool. DO NOT EDIT. +# This file is used to track the info used to scaffold your project +# and allow the plugins properly work. +# More info: https://book.kubebuilder.io/reference/project-config.html domain: eclipse.che layout: -- go.kubebuilder.io/v3 +- go.kubebuilder.io/v4 plugins: manifests.sdk.operatorframework.io/v2: {} scorecard.sdk.operatorframework.io/v2: {} diff --git a/REQUIREMENTS b/REQUIREMENTS deleted file mode 100644 index 4ddf98bb6f..0000000000 --- a/REQUIREMENTS +++ /dev/null @@ -1,2 +0,0 @@ -operator-sdk: v1.9.2 -opm: v1.26.2 diff --git a/api/v2/checluster_webhook.go b/api/v2/checluster_webhook.go index 9aa52dd100..be2b04c44f 100644 --- a/api/v2/checluster_webhook.go +++ b/api/v2/checluster_webhook.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -18,6 +18,10 @@ import ( "strconv" "strings" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "github.com/devfile/devworkspace-operator/pkg/infrastructure" "k8s.io/utils/pointer" @@ -32,24 +36,43 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook" ) -func (r *CheCluster) SetupWebhookWithManager(mgr ctrl.Manager) error { +var ( + webhookLogger = ctrl.Log.WithName("webhook") +) + +func SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). - For(r). + For(&CheCluster{}). + WithDefaulter(&CheClusterDefaulter{}). + WithValidator(&CheClusterValidator{}). Complete() } -var _ webhook.Defaulter = &CheCluster{} +// Keep empty line after annotation +// +kubebuilder:webhook:path=/mutate-org-eclipse-che-v2-checluster,mutating=true,failurePolicy=fail,sideEffects=None,groups=org.eclipse.che,resources=checlusters,verbs=create;update,versions=v2,name=mchecluster.kb.io,admissionReviewVersions=v1 + +type CheClusterDefaulter struct{} + +var _ webhook.CustomDefaulter = &CheClusterDefaulter{} // Default implements webhook.Defaulter so a webhook will be registered for the type -func (r *CheCluster) Default() { - setContainerBuildConfiguration(r) - setDisableContainerBuildCapabilities(r) +func (r *CheClusterDefaulter) Default(_ context.Context, obj runtime.Object) error { + cheCluster, ok := obj.(*CheCluster) + + if !ok { + return fmt.Errorf("expected an CheCluster object but got %T", obj) + } + + webhookLogger.Info("Defaulting for CheCluster", "name", cheCluster.GetName()) + + r.setContainerBuildConfiguration(cheCluster) + r.setDisableContainerBuildCapabilities(cheCluster) + return nil } -func setDisableContainerBuildCapabilities(cheCluster *CheCluster) { +func (r *CheClusterDefaulter) setDisableContainerBuildCapabilities(cheCluster *CheCluster) { // Container build capabilities can be enabled on OpenShift only if !infrastructure.IsOpenShift() { cheCluster.Spec.DevEnvironments.DisableContainerBuildCapabilities = pointer.Bool(true) @@ -57,40 +80,61 @@ func setDisableContainerBuildCapabilities(cheCluster *CheCluster) { } // Sets ContainerBuildConfiguration if container build capabilities is enabled. -func setContainerBuildConfiguration(cheCluster *CheCluster) { +func (r *CheClusterDefaulter) setContainerBuildConfiguration(cheCluster *CheCluster) { if cheCluster.IsContainerBuildCapabilitiesEnabled() && cheCluster.Spec.DevEnvironments.ContainerBuildConfiguration == nil { cheCluster.Spec.DevEnvironments.ContainerBuildConfiguration = &ContainerBuildConfiguration{} } } -var _ webhook.Validator = &CheCluster{} +// Keep empty line after annotation +// +kubebuilder:webhook:path=/validate-org-eclipse-che-v2-checluster,mutating=false,failurePolicy=fail,sideEffects=None,groups=org.eclipse.che,resources=checlusters,verbs=create;update,versions=v2,name=vchecluster.kb.io,admissionReviewVersions=v1 + +type CheClusterValidator struct{} + +var _ admission.CustomValidator = &CheClusterValidator{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (r *CheCluster) ValidateCreate() error { - if err := ensureSingletonCheCluster(); err != nil { - return err +func (r *CheClusterValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + cheCluster, ok := obj.(*CheCluster) + + if !ok { + return nil, fmt.Errorf("expected an CheCluster object but got %T", obj) + } + + webhookLogger.Info("Validation for CheCluster upon creation", "name", cheCluster.GetName()) + + if err := r.ensureSingletonCheCluster(); err != nil { + return []string{}, err } - return validate(r) + return []string{}, r.validate(cheCluster) } -// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (r *CheCluster) ValidateUpdate(old runtime.Object) error { - return validate(r) +// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type CheCluster. +func (r *CheClusterValidator) ValidateUpdate(_ context.Context, _, newObj runtime.Object) (admission.Warnings, error) { + cheCluster, ok := newObj.(*CheCluster) + + if !ok { + return nil, fmt.Errorf("expected an CheCluster object but got %T", newObj) + } + + webhookLogger.Info("Validation for CheCluster upon update", "name", cheCluster.GetName()) + + return nil, r.validate(cheCluster) } -// ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (r *CheCluster) ValidateDelete() error { - return nil +// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type CheCluster. +func (r *CheClusterValidator) ValidateDelete(_ context.Context, _ runtime.Object) (admission.Warnings, error) { + return nil, nil } -func ensureSingletonCheCluster() error { +func (r *CheClusterValidator) ensureSingletonCheCluster() error { client := k8shelper.New().GetClient() utilruntime.Must(AddToScheme(client.Scheme())) che := &CheClusterList{} err := client.List(context.TODO(), che) if err != nil { - logger.Error(err, "Failed to list CheCluster Custom Resources.") + webhookLogger.Error(err, "Failed to list CheCluster Custom Resources.") } if len(che.Items) != 0 { @@ -100,27 +144,27 @@ func ensureSingletonCheCluster() error { return nil } -func validate(checluster *CheCluster) error { +func (r *CheClusterValidator) validate(checluster *CheCluster) error { for _, github := range checluster.Spec.GitServices.GitHub { - if err := validateOAuthSecret(github.SecretName, "github", github.Endpoint, github.DisableSubdomainIsolation, checluster.Namespace); err != nil { + if err := r.validateOAuthSecret(github.SecretName, "github", github.Endpoint, github.DisableSubdomainIsolation, checluster.Namespace); err != nil { return err } } for _, gitlab := range checluster.Spec.GitServices.GitLab { - if err := validateOAuthSecret(gitlab.SecretName, "gitlab", gitlab.Endpoint, nil, checluster.Namespace); err != nil { + if err := r.validateOAuthSecret(gitlab.SecretName, "gitlab", gitlab.Endpoint, nil, checluster.Namespace); err != nil { return err } } for _, bitbucket := range checluster.Spec.GitServices.BitBucket { - if err := validateOAuthSecret(bitbucket.SecretName, "bitbucket", bitbucket.Endpoint, nil, checluster.Namespace); err != nil { + if err := r.validateOAuthSecret(bitbucket.SecretName, "bitbucket", bitbucket.Endpoint, nil, checluster.Namespace); err != nil { return err } } for _, azure := range checluster.Spec.GitServices.AzureDevOps { - if err := validateOAuthSecret(azure.SecretName, constants.AzureDevOpsOAuth, "", nil, checluster.Namespace); err != nil { + if err := r.validateOAuthSecret(azure.SecretName, constants.AzureDevOpsOAuth, "", nil, checluster.Namespace); err != nil { return err } } @@ -128,7 +172,7 @@ func validate(checluster *CheCluster) error { return nil } -func validateOAuthSecret(secretName string, scmProvider string, serverEndpoint string, disableSubdomainIsolation *bool, namespace string) error { +func (r *CheClusterValidator) validateOAuthSecret(secretName string, scmProvider string, serverEndpoint string, disableSubdomainIsolation *bool, namespace string) error { if secretName == "" { return nil } @@ -142,25 +186,25 @@ func validateOAuthSecret(secretName string, scmProvider string, serverEndpoint s return fmt.Errorf("error reading '%s' secret", err.Error()) } - if err := ensureScmLabelsAndAnnotations(secret, scmProvider, serverEndpoint, disableSubdomainIsolation); err != nil { + if err := r.ensureScmLabelsAndAnnotations(secret, scmProvider, serverEndpoint, disableSubdomainIsolation); err != nil { return err } switch scmProvider { case "github": - if err := validateGitHubOAuthSecretDataKeys(secret); err != nil { + if err := r.validateGitHubOAuthSecretDataKeys(secret); err != nil { return err } case "gitlab": - if err := validateGitLabOAuthSecretDataKeys(secret); err != nil { + if err := r.validateGitLabOAuthSecretDataKeys(secret); err != nil { return err } case "bitbucket": - if err := validateBitBucketOAuthSecretDataKeys(secret); err != nil { + if err := r.validateBitBucketOAuthSecretDataKeys(secret); err != nil { return err } case constants.AzureDevOpsOAuth: - if err := validateAzureDevOpsSecretDataKeys(secret); err != nil { + if err := r.validateAzureDevOpsSecretDataKeys(secret); err != nil { return err } } @@ -168,27 +212,27 @@ func validateOAuthSecret(secretName string, scmProvider string, serverEndpoint s return nil } -func validateAzureDevOpsSecretDataKeys(secret *corev1.Secret) error { +func (r *CheClusterValidator) validateAzureDevOpsSecretDataKeys(secret *corev1.Secret) error { keys2validate := []string{constants.GitHubOAuthConfigClientIdFileName, constants.GitHubOAuthConfigClientSecretFileName} - return validateOAuthSecretDataKeys(secret, keys2validate) + return r.validateOAuthSecretDataKeys(secret, keys2validate) } -func validateGitHubOAuthSecretDataKeys(secret *corev1.Secret) error { +func (r *CheClusterValidator) validateGitHubOAuthSecretDataKeys(secret *corev1.Secret) error { keys2validate := []string{constants.GitHubOAuthConfigClientIdFileName, constants.GitHubOAuthConfigClientSecretFileName} - return validateOAuthSecretDataKeys(secret, keys2validate) + return r.validateOAuthSecretDataKeys(secret, keys2validate) } -func validateGitLabOAuthSecretDataKeys(secret *corev1.Secret) error { +func (r *CheClusterValidator) validateGitLabOAuthSecretDataKeys(secret *corev1.Secret) error { keys2validate := []string{constants.GitLabOAuthConfigClientIdFileName, constants.GitLabOAuthConfigClientSecretFileName} - return validateOAuthSecretDataKeys(secret, keys2validate) + return r.validateOAuthSecretDataKeys(secret, keys2validate) } -func validateBitBucketOAuthSecretDataKeys(secret *corev1.Secret) error { +func (r *CheClusterValidator) validateBitBucketOAuthSecretDataKeys(secret *corev1.Secret) error { oauth1Keys2validate := []string{constants.BitBucketOAuthConfigPrivateKeyFileName, constants.BitBucketOAuthConfigConsumerKeyFileName} - errOauth1Keys := validateOAuthSecretDataKeys(secret, oauth1Keys2validate) + errOauth1Keys := r.validateOAuthSecretDataKeys(secret, oauth1Keys2validate) oauth2Keys2validate := []string{constants.BitBucketOAuthConfigClientIdFileName, constants.BitBucketOAuthConfigClientSecretFileName} - errOauth2Keys := validateOAuthSecretDataKeys(secret, oauth2Keys2validate) + errOauth2Keys := r.validateOAuthSecretDataKeys(secret, oauth2Keys2validate) if errOauth1Keys != nil && errOauth2Keys != nil { return fmt.Errorf("secret must contain either [%s] or [%s] keys", strings.Join(oauth1Keys2validate, ", "), strings.Join(oauth2Keys2validate, ", ")) @@ -197,7 +241,7 @@ func validateBitBucketOAuthSecretDataKeys(secret *corev1.Secret) error { return nil } -func ensureScmLabelsAndAnnotations(secret *corev1.Secret, scmProvider string, serverEndpoint string, disableSubdomainIsolation *bool) error { +func (r *CheClusterValidator) ensureScmLabelsAndAnnotations(secret *corev1.Secret, scmProvider string, serverEndpoint string, disableSubdomainIsolation *bool) error { patch := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ @@ -232,7 +276,7 @@ func ensureScmLabelsAndAnnotations(secret *corev1.Secret, scmProvider string, se return nil } -func validateOAuthSecretDataKeys(secret *corev1.Secret, keys []string) error { +func (r *CheClusterValidator) validateOAuthSecretDataKeys(secret *corev1.Secret, keys []string) error { for _, key := range keys { if len(secret.Data[key]) == 0 { return fmt.Errorf("secret '%s' must contain [%s] keys", secret.Name, strings.Join(keys, ", ")) diff --git a/api/checluster_webhook_test.go b/api/v2/checluster_webhook_test.go similarity index 87% rename from api/checluster_webhook_test.go rename to api/v2/checluster_webhook_test.go index 1339b93987..bf26bd9d2a 100644 --- a/api/checluster_webhook_test.go +++ b/api/v2/checluster_webhook_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -10,13 +10,12 @@ // Red Hat, Inc. - initial API and implementation // -package org +package v2 import ( "context" "testing" - v2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/pkg/common/constants" k8shelper "github.com/eclipse-che/che-operator/pkg/common/k8s-helper" "github.com/stretchr/testify/assert" @@ -69,26 +68,26 @@ func TestValidateScmSecrets(t *testing.T) { _, err = k8sHelper.GetClientset().CoreV1().Secrets("eclipse-che").Create(context.TODO(), bitbucketSecret, metav1.CreateOptions{}) assert.Nil(t, err) - checluster := &v2.CheCluster{ + checluster := &CheCluster{ ObjectMeta: metav1.ObjectMeta{ Name: "eclipse-che", Namespace: "eclipse-che", }, - Spec: v2.CheClusterSpec{ - GitServices: v2.CheClusterGitServices{ - GitHub: []v2.GitHubService{ + Spec: CheClusterSpec{ + GitServices: CheClusterGitServices{ + GitHub: []GitHubService{ { SecretName: "github-scm-secret", Endpoint: "github-endpoint", }, }, - GitLab: []v2.GitLabService{ + GitLab: []GitLabService{ { SecretName: "gitlab-scm-secret", Endpoint: "gitlab-endpoint-checluster", }, }, - BitBucket: []v2.BitBucketService{ + BitBucket: []BitBucketService{ { SecretName: "bitbucket-scm-secret", }, @@ -97,7 +96,9 @@ func TestValidateScmSecrets(t *testing.T) { }, } - err = checluster.ValidateCreate() + cheClusterValidator := CheClusterValidator{} + + _, err = cheClusterValidator.ValidateCreate(context.TODO(), checluster) assert.Nil(t, err) githubSecret, err = k8sHelper.GetClientset().CoreV1().Secrets("eclipse-che").Get(context.TODO(), "github-scm-secret", metav1.GetOptions{}) @@ -123,14 +124,14 @@ func TestValidateScmSecrets(t *testing.T) { } func TestValidateScmSecretsShouldThrowError(t *testing.T) { - checluster := &v2.CheCluster{ + checluster := &CheCluster{ ObjectMeta: metav1.ObjectMeta{ Name: "eclipse-che", Namespace: "eclipse-che", }, - Spec: v2.CheClusterSpec{ - GitServices: v2.CheClusterGitServices{ - GitHub: []v2.GitHubService{ + Spec: CheClusterSpec{ + GitServices: CheClusterGitServices{ + GitHub: []GitHubService{ { SecretName: "github-scm-secret-with-errors", }, @@ -139,7 +140,8 @@ func TestValidateScmSecretsShouldThrowError(t *testing.T) { }, } - err := checluster.ValidateCreate() + cheClusterValidator := CheClusterValidator{} + _, err := cheClusterValidator.ValidateCreate(context.TODO(), checluster) assert.Error(t, err) assert.Equal(t, "secret 'github-scm-secret-with-errors' not found", err.Error()) @@ -154,7 +156,7 @@ func TestValidateScmSecretsShouldThrowError(t *testing.T) { _, err = k8sHelper.GetClientset().CoreV1().Secrets("eclipse-che").Create(context.TODO(), githubSecret, metav1.CreateOptions{}) assert.Nil(t, err) - err = checluster.ValidateCreate() + _, err = cheClusterValidator.ValidateCreate(context.TODO(), checluster) assert.Error(t, err) assert.Equal(t, "secret 'github-scm-secret-with-errors' must contain [id, secret] keys", err.Error()) } diff --git a/api/v2/zz_generated.deepcopy.go b/api/v2/zz_generated.deepcopy.go index 4ec0fc3fba..8597e7136a 100644 --- a/api/v2/zz_generated.deepcopy.go +++ b/api/v2/zz_generated.deepcopy.go @@ -223,6 +223,21 @@ func (in *CheClusterContainerRegistry) DeepCopy() *CheClusterContainerRegistry { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CheClusterDefaulter) DeepCopyInto(out *CheClusterDefaulter) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheClusterDefaulter. +func (in *CheClusterDefaulter) DeepCopy() *CheClusterDefaulter { + if in == nil { + return nil + } + out := new(CheClusterDefaulter) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CheClusterDevEnvironments) DeepCopyInto(out *CheClusterDevEnvironments) { *out = *in @@ -495,6 +510,21 @@ func (in *CheClusterStatus) DeepCopy() *CheClusterStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CheClusterValidator) DeepCopyInto(out *CheClusterValidator) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheClusterValidator. +func (in *CheClusterValidator) DeepCopy() *CheClusterValidator { + if in == nil { + return nil + } + out := new(CheClusterValidator) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CheServer) DeepCopyInto(out *CheServer) { *out = *in diff --git a/build/scripts/clear-defined-test.sh b/build/scripts/clear-defined-test.sh new file mode 100755 index 0000000000..88de887fdd --- /dev/null +++ b/build/scripts/clear-defined-test.sh @@ -0,0 +1,204 @@ +#!/bin/bash +# +# Copyright (c) 2019-2025 Red Hat, Inc. +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Red Hat, Inc. - initial API and implementation +# + +set -e + +# https://www.eclipse.org/legal/licenses/#approved +allowed_licenses=( + "Adobe-Glyph" + "Apache-1.0" + "Apache-1.1" + "Apache-2.0" + "Artistic-2.0" + "BlueOak-1.0.0" + "BSL-1.0" + "BSD-2-Clause" + "BSD-2-Clause-FreeBSD" + "BSD-2-Clause-Views" + "BSD-3-Clause" + "BSD-4-Clause" + "0BSD" + "CDDL-1.0" + "CDDL-1.1" + "CPL-1.0" + "CC-BY-3.0" + "CC-BY-4.0" + "CC-BY-2.5" + "CC-BY-SA-3.0" + "CC-BY-SA-4.0" + "CC0-1.0" + "WTFPL" + "EPL-1.0" + "EPL-2.0" + "EUPL-1.1" + "EUPL-1.2" + "FTL" + "GFDL-1.3" + "LGPL-2.1" + "LGPL-2.1-or-later" + "LGPL-3.0" + "LGPL-3.0-or-later" + "LGPL-2.0" + "LGPL-2.0-or-later" + "IPL-1.0" + "ISC" + "MIT" + "MIT-0" + "MPL-1.1" + "MPL-2.0" + "NTP" + "OpenSSL" + "PHP-3.01" + "PostgreSQL" + "OFL-1.1" + "UNLICENSE" + "Unicode-DFS-2015" + "Unicode-DFS-2016" + "Unicode-TOU" + "UPL-1.0" + "W3C" + "W3C-20150513" + "W3C-19980720" + "X11" + "Zlib" + "ZPL-2.1" +) + +# replaces to have a correct link for clearlydefined.io api request +declare -A replaced_modules=( + # https://github.com/open-telemetry/opentelemetry-go-contrib/commit/bc53d2b4eb4de79471bc54f64a5c3dcefa8720d7# + ["go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0"]="github.com/open-telemetry/opentelemetry-go-contrib v1.35.0" + # https://github.com/open-telemetry/opentelemetry-go-contrib/commit/bc53d2b4eb4de79471bc54f64a5c3dcefa8720d7# + ["go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0"]="github.com/open-telemetry/opentelemetry-go-contrib v1.35.0" + # https://github.com/census-instrumentation/opencensus-go/commits/v0.23.0/ + ["go.opencensus.io v0.23.0"]="census-instrumentation/opencensus-go 49838f207d61097fc0ebb8aeef306913388376ca" +) + +# replaces to have a correct link for clearlydefined.io api request +declare -A replaced_paths=( + ["go.starlark.net"]="github.com/google/starlark-go" + ["gotest.tools"]="github.com/gotestyourself/gotest.tools" +) + +# replaces to have a correct link for clearlydefined.io api request +declare -A replaced_api_suffix=( + ["census-instrumentation/opencensus-go"]="git/github" +) + +declare -A ignored_paths=( + ["github.com/sean-/seed"]="Harvesting in progress" +) + +declare -A ignored_paths_license=( + ["github.com/sean-/seed"]="MIT" +) + + +go list -m -mod=mod all | while read -r module; do + # ignore the first dependency which is the current module + if [[ "$module" == "github.com/eclipse-che/che-operator" ]]; then + continue + fi + + # respect the replace directive in go.mod file + if [[ "${module}" == *"=>"* ]]; then + module="${module#*=> }" + fi + + orig_module="$module" + if [[ -v replaced_modules["$orig_module"] ]]; then + module=${replaced_modules[$orig_module]} + fi + + path=$(echo "$module" | awk '{print $1}') + + if [[ -v ignored_paths["$path"] ]]; then + license="${ignored_paths_license["$path"]}" + reason="${ignored_paths["$path"]}" + + printf "%-7s %-70s %-25s %-10s %s\n" "[WARN]" "$orig_module" "$license" "N/A" "$reason" + + continue + fi + + path=$(echo "$module" | awk '{print $1}') + if [[ -v replaced_paths["$path"] ]]; then + path=${replaced_paths[$path]} + fi + + version=$(echo "$module" | awk '{print $2}') + + api_suffix="go/golang" + if [[ -v replaced_api_suffix["$path"] ]]; then + api_suffix=${replaced_api_suffix[$path]} + fi + + orig_url="https://api.clearlydefined.io/definitions/${api_suffix}/${path}/${version}" + url=$orig_url + + score=$(curl -s "$url" | jq -r '.scores.effective') + + # try a shorter path if the first one returns null + while [[ "$score" == "null" ]] || [[ "$score" == "35" ]]; do + # remove the last part of the path + path="${path%/*}" + old_url=$url + url="https://api.clearlydefined.io/definitions/go/golang/${path}/${version}" + + # if the path is the same as the old one, break to avoid infinite loop + if [[ "$url" == "$old_url" ]]; then + score="N/A" + break + fi + + # get the score again + score=$(curl -s $url | jq -r '.scores.effective') + done + + if [[ $score == "N/A" ]]; then + printf "%-7s %-70s %-25s %-10s %s\n" "[ERROR]" "$orig_module" "N/A" "N/A" "$orig_url" + exit 1 + fi + + + # analyze the license + license=$(curl -s "$url" | jq -r '.licensed.declared') + license="${license%% AND*}" + + license_approved=false + for allowed_license in "${allowed_licenses[@]}"; do + if [[ "$allowed_license" == "$license" ]]; then + license_approved=true + break + fi + done + + if [[ $license_approved == "false" ]]; then + printf "%-7s %-70s %-25s %-10s %s\n" "[ERROR]" "$orig_module" "$license" "$score" "$url" + exit 1 + fi + + # analyze the score + if (( score < 65 )); then + printf "%-7s %-70s %-25s %-10s %s\n" "[ERROR]" "$orig_module" "$license" "$score" "$url" + exit 1 + fi + + result="[OK]" + if (( score < 75 )); then + result="[WARN]" + fi + printf "%-7s %-70s %-25s %-10s %s\n" "$result" "$orig_module" "$license" "$score" "$url" +done + +echo "[INFO] All dependencies are defined correctly." diff --git a/build/scripts/release/make-release.sh b/build/scripts/release/make-release.sh index dac5ae6420..145d322b2d 100755 --- a/build/scripts/release/make-release.sh +++ b/build/scripts/release/make-release.sh @@ -56,10 +56,7 @@ init() { done [ -z "$QUAY_ECLIPSE_CHE_USERNAME" ] && echo "[ERROR] QUAY_ECLIPSE_CHE_USERNAME is not set" && exit 1 [ -z "$QUAY_ECLIPSE_CHE_PASSWORD" ] && echo "[ERROR] QUAY_ECLIPSE_CHE_PASSWORD is not set" && exit 1 - command -v operator-sdk >/dev/null 2>&1 || { echo "[ERROR] operator-sdk is not installed. Abort."; exit 1; } command -v skopeo >/dev/null 2>&1 || { echo "[ERROR] skopeo is not installed. Abort."; exit 1; } - REQUIRED_OPERATOR_SDK=$(yq -r ".\"operator-sdk\"" "${OPERATOR_REPO}/REQUIREMENTS") - [[ $(operator-sdk version) =~ .*${REQUIRED_OPERATOR_SDK}.* ]] || { echo "[ERROR] operator-sdk ${REQUIRED_OPERATOR_SDK} is required. Abort."; exit 1; } } usage () { diff --git a/bundle/next/eclipse-che/bundle.Dockerfile b/bundle/next/eclipse-che/bundle.Dockerfile index 08f92f9530..ba2de6eeeb 100644 --- a/bundle/next/eclipse-che/bundle.Dockerfile +++ b/bundle/next/eclipse-che/bundle.Dockerfile @@ -19,9 +19,9 @@ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ LABEL operators.operatorframework.io.bundle.package.v1=eclipse-che LABEL operators.operatorframework.io.bundle.channels.v1=next LABEL operators.operatorframework.io.bundle.channel.default.v1=next -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.9.0+git +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.39.2 LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 -LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 +LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4 # Labels for testing. LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 diff --git a/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml b/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml index 30c133cf59..cc494051cd 100644 --- a/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml @@ -86,7 +86,7 @@ metadata: categories: Developer Tools certified: "false" containerImage: quay.io/eclipse/che-operator:next - createdAt: "2021-05-11T18:38:31Z" + createdAt: "2025-07-29T14:05:27Z" description: A Kube-native development solution that delivers portable and collaborative developer workspaces. features.operators.openshift.io/cnf: "false" @@ -100,25 +100,30 @@ metadata: features.operators.openshift.io/token-auth-azure: "false" features.operators.openshift.io/token-auth-gcp: "false" operatorframework.io/suggested-namespace: openshift-operators - operators.operatorframework.io/builder: operator-sdk-v1.9.0+git - operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 + operators.operatorframework.io/builder: operator-sdk-v1.39.2 + operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 repository: https://github.com/eclipse-che/che-operator support: Eclipse Foundation labels: operatorframework.io/arch.amd64: supported operatorframework.io/arch.arm64: supported operatorframework.io/os.linux: supported - name: eclipse-che.v7.107.0-912.next + name: eclipse-che.v7.107.0-934.next namespace: placeholder spec: apiservicedefinitions: {} customresourcedefinitions: owned: - description: 'The `CheCluster` custom resource allows defining and managing - Eclipse Che server installation. Based on these settings, the Operator - automatically creates and maintains several ConfigMaps: `che`, `plugin-registry` - that will contain the appropriate environment variables of the various components - of the installation. These generated ConfigMaps must NOT be updated manually.' + Eclipse Che server installation. + + Based on these settings, the Operator automatically creates and maintains + several ConfigMaps: + + `che`, `plugin-registry` that will contain the appropriate environment variables + + of the various components of the installation. These generated ConfigMaps + must NOT be updated manually.' displayName: Eclipse Che instance Specification kind: CheCluster name: checlusters.org.eclipse.che @@ -176,7 +181,9 @@ spec: displayName: Azure path: gitServices.azure - description: 'Kubernetes secret, that contains Base64-encoded Azure DevOps - Service Application ID and Client Secret. See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-microsoft-azure-devops-services' + Service Application ID and Client Secret. + + See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-microsoft-azure-devops-services' displayName: Secret Name path: gitServices.azure[0].secretName x-descriptors: @@ -186,7 +193,10 @@ spec: displayName: Bitbucket path: gitServices.bitbucket - description: 'Kubernetes secret, that contains Base64-encoded Bitbucket - OAuth 1.0 or OAuth 2.0 data. See the following pages for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-1-for-a-bitbucket-server/ + OAuth 1.0 or OAuth 2.0 data. + + See the following pages for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-1-for-a-bitbucket-server/ + and https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-the-bitbucket-cloud/.' displayName: Secret Name path: gitServices.bitbucket[0].secretName @@ -197,8 +207,9 @@ spec: displayName: GitHub path: gitServices.github - description: 'Kubernetes secret, that contains Base64-encoded GitHub OAuth - Client id and GitHub OAuth Client secret. See the following page for - details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-github/.' + Client id and GitHub OAuth Client secret. + + See the following page for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-github/.' displayName: Secret Name path: gitServices.github[0].secretName x-descriptors: @@ -208,7 +219,9 @@ spec: displayName: GitLab path: gitServices.gitlab - description: 'Kubernetes secret, that contains Base64-encoded GitHub Application - id and GitLab Application Client secret. See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-gitlab/.' + id and GitLab Application Client secret. + + See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-gitlab/.' displayName: Secret Name path: gitServices.gitlab[0].secretName x-descriptors: @@ -256,10 +269,13 @@ spec: path: reason x-descriptors: - urn:alm:descriptor:text - - description: The resolved workspace base domain. This is either the copy - of the explicitly defined property of the same name in the spec or, - if it is undefined in the spec and we're running on OpenShift, the automatically - resolved basedomain for routes. + - description: 'The resolved workspace base domain. This is either the copy + of the explicitly defined property of the + + same name in the spec or, if it is undefined in the spec and we''re + running on OpenShift, the automatically + + resolved basedomain for routes.' displayName: Workspace base domain path: workspaceBaseDomain x-descriptors: @@ -323,9 +339,11 @@ spec: - description: DevWorkspace operator configuration displayName: Dev Workspace operator path: devWorkspace - - description: Deploys the DevWorkspace Operator in the cluster. Does nothing - when a matching version of the Operator is already installed. Fails - when a non-matching version of the Operator is already installed. + - description: 'Deploys the DevWorkspace Operator in the cluster. + + Does nothing when a matching version of the Operator is already installed. + + Fails when a non-matching version of the Operator is already installed.' displayName: Enable DevWorkspace operator path: devWorkspace.enable x-descriptors: @@ -339,7 +357,10 @@ spec: displayName: Bitbucket path: gitServices.bitbucket - description: 'Kubernetes secret, that contains Base64-encoded Bitbucket - OAuth 1.0 or OAuth 2.0 data. See the following pages for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-1-for-a-bitbucket-server/ + OAuth 1.0 or OAuth 2.0 data. + + See the following pages for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-1-for-a-bitbucket-server/ + and https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-the-bitbucket-cloud/.' displayName: Secret Name path: gitServices.bitbucket[0].secretName @@ -350,8 +371,9 @@ spec: displayName: GitHub path: gitServices.github - description: 'Kubernetes secret, that contains Base64-encoded GitHub OAuth - Client id and GitHub OAuth Client secret. See the following page for - details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-github/.' + Client id and GitHub OAuth Client secret. + + See the following page for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-github/.' displayName: Secret Name path: gitServices.github[0].secretName x-descriptors: @@ -361,7 +383,9 @@ spec: displayName: GitLab path: gitServices.gitlab - description: 'Kubernetes secret, that contains Base64-encoded GitHub Application - id and GitLab Application Client secret. See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-gitlab/.' + id and GitLab Application Client secret. + + See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-gitlab/.' displayName: Secret Name path: gitServices.gitlab[0].secretName x-descriptors: @@ -381,11 +405,13 @@ spec: the plugin and devfile registries displayName: Che server path: server - - description: Deprecated. The value of this flag is ignored. Defines that - a user is allowed to specify a Kubernetes namespace, or an OpenShift - project, which differs from the default. It's NOT RECOMMENDED to set - to `true` without OpenShift OAuth configured. The OpenShift infrastructure - also uses this property. + - description: 'Deprecated. The value of this flag is ignored. + + Defines that a user is allowed to specify a Kubernetes namespace, or + an OpenShift project, which differs from the default. + + It''s NOT RECOMMENDED to set to `true` without OpenShift OAuth configured. + The OpenShift infrastructure also uses this property.' displayName: Allow User Defined Workspace Namespaces path: server.allowUserDefinedWorkspaceNamespaces x-descriptors: @@ -395,9 +421,11 @@ spec: path: server.devfileRegistryUrl x-descriptors: - urn:alm:descriptor:com.tectonic.ui:hidden - - description: Deprecated. The value of this flag is ignored. The Che Operator - will automatically detect whether the router certificate is self-signed - and propagate it to other components, such as the Che server. + - description: 'Deprecated. The value of this flag is ignored. + + The Che Operator will automatically detect whether the router certificate + is self-signed and propagate it to other components, such as the Che + server.' displayName: Self Signed Cert path: server.selfSignedCert x-descriptors: @@ -880,7 +908,13 @@ spec: - create serviceAccountName: che-operator deployments: - - name: che-operator + - label: + app: che-operator + app.kubernetes.io/component: che-operator + app.kubernetes.io/instance: che + app.kubernetes.io/name: che + app.kubernetes.io/part-of: che.eclipse.org + name: che-operator spec: replicas: 1 selector: @@ -1084,15 +1118,49 @@ spec: minKubeVersion: 1.19.0 provider: name: Eclipse Foundation - version: 7.107.0-912.next + relatedImages: + - image: quay.io/eclipse/che-server:next + name: che-server + - image: quay.io/eclipse/che-dashboard:next + name: dashboard + - image: quay.io/eclipse/che-plugin-registry:next + name: plugin-registry + - image: quay.io/eclipse/che-tls-secret-creator:9f9d4a6 + name: che-tls-secrets-creation-job + - image: quay.io/eclipse/che--traefik:v3.4.0-4cf907247939b5d20bf4eff73abd21cb413c339600dde76dbc94a874b2578a27 + name: single-host-gateway + - image: quay.io/che-incubator/configbump:next + name: single-host-gateway-config-sidecar + - image: quay.io/openshift/origin-oauth-proxy:4.9 + name: gateway-authentication-sidecar + - image: quay.io/openshift/origin-kube-rbac-proxy:4.9 + name: gateway-authorization-sidecar + - image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0 + name: gateway-authentication-sidecar-k8s + - image: quay.io/brancz/kube-rbac-proxy:v0.13.1 + name: gateway-authorization-sidecar-k8s + - image: quay.io/che-incubator/header-rewrite-proxy:latest + name: gateway-header-sidecar + version: 7.107.0-934.next webhookdefinitions: - admissionReviewVersions: - v1 - - v1beta1 + - v2 + containerPort: 443 + conversionCRDs: + - checlusters.org.eclipse.che + deploymentName: che-operator + generateName: ccheclusters.kb.io + sideEffects: None + targetPort: 9443 + type: ConversionWebhook + webhookPath: /convert + - admissionReviewVersions: + - v1 containerPort: 443 deploymentName: che-operator failurePolicy: Fail - generateName: vchecluster.kb.io + generateName: mchecluster.kb.io rules: - apiGroups: - org.eclipse.che @@ -1105,15 +1173,14 @@ spec: - checlusters sideEffects: None targetPort: 9443 - type: ValidatingAdmissionWebhook - webhookPath: /validate-org-eclipse-che-v2-checluster + type: MutatingAdmissionWebhook + webhookPath: /mutate-org-eclipse-che-v2-checluster - admissionReviewVersions: - v1 - - v1beta1 containerPort: 443 deploymentName: che-operator failurePolicy: Fail - generateName: mchecluster.kb.io + generateName: vchecluster.kb.io rules: - apiGroups: - org.eclipse.che @@ -1126,17 +1193,5 @@ spec: - checlusters sideEffects: None targetPort: 9443 - type: MutatingAdmissionWebhook - webhookPath: /mutate-org-eclipse-che-v2-checluster - - admissionReviewVersions: - - v1 - - v2 - containerPort: 443 - conversionCRDs: - - checlusters.org.eclipse.che - deploymentName: che-operator - generateName: ccheclusters.kb.io - sideEffects: None - targetPort: 9443 - type: ConversionWebhook - webhookPath: /convert + type: ValidatingAdmissionWebhook + webhookPath: /validate-org-eclipse-che-v2-checluster diff --git a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml index 57ef49c1c4..69b3b33e3a 100644 --- a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml +++ b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml @@ -14,7 +14,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.18.0 creationTimestamp: null labels: app.kubernetes.io/instance: che @@ -138,10 +138,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -201,10 +204,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -253,10 +259,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -316,10 +325,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -372,10 +384,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -435,10 +450,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -487,10 +505,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -550,10 +571,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -878,10 +902,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -941,10 +968,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -1029,10 +1059,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -1092,10 +1125,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -1411,10 +1447,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -1474,10 +1513,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -1589,10 +1631,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -1652,10 +1697,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -1774,10 +1822,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -1837,10 +1888,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -2012,10 +2066,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -2075,10 +2132,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -2297,7 +2357,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2306,7 +2365,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2320,7 +2378,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -2336,13 +2393,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2351,20 +2405,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2383,27 +2433,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2432,13 +2475,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -2462,7 +2502,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -2529,7 +2568,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -2601,7 +2639,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -2639,7 +2676,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2655,13 +2691,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2670,20 +2703,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2702,27 +2731,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2778,7 +2800,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2794,13 +2815,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2809,20 +2827,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2841,27 +2855,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2903,7 +2910,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -2920,13 +2926,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -3020,13 +3024,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -3074,7 +3075,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -3086,13 +3086,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -3153,7 +3150,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3162,7 +3158,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3176,7 +3171,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -3193,13 +3187,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3207,20 +3198,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3239,27 +3226,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3287,13 +3267,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -3316,7 +3293,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -3358,7 +3334,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -3430,7 +3405,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -3467,7 +3441,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3484,13 +3457,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3498,20 +3468,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3530,27 +3496,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3606,7 +3565,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3623,13 +3581,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3637,20 +3592,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3669,27 +3620,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -4128,10 +4072,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -4196,10 +4143,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -4463,10 +4413,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -4531,10 +4484,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -4764,10 +4720,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -4832,10 +4791,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -5105,10 +5067,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -5173,10 +5138,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -5398,6 +5366,8 @@ spec: description: OpenShift security context constraint to build containers. type: string + required: + - openShiftSecurityContextConstraint type: object defaultComponents: description: |- @@ -5444,7 +5414,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5453,7 +5422,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5467,7 +5435,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -5483,13 +5450,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5498,20 +5462,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5530,27 +5490,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5579,13 +5532,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -5609,7 +5559,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -5676,7 +5625,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -5748,7 +5696,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -5786,7 +5733,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5802,13 +5748,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5817,20 +5760,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5849,27 +5788,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5925,7 +5857,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5941,13 +5872,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5956,20 +5884,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5988,27 +5912,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6050,7 +5967,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -6067,13 +5983,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -6167,13 +6081,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -6221,7 +6132,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -6233,13 +6143,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -6300,7 +6207,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6309,7 +6215,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6323,7 +6228,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -6340,13 +6244,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6354,20 +6255,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6386,27 +6283,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6434,13 +6324,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -6463,7 +6350,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -6505,7 +6391,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -6577,7 +6462,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -6614,7 +6498,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6631,13 +6514,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6645,20 +6525,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6677,27 +6553,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6753,7 +6622,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6770,13 +6638,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6784,20 +6649,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6816,27 +6677,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -7013,7 +6867,6 @@ spec: When set to `false` (the default value), the devEnvironments.security.containerSecurityContext field is ignored, and the following container SecurityContext is applied: - containerSecurityContext: allowPrivilegeEscalation: true capabilities: @@ -7058,10 +6911,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -7121,10 +6977,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or @@ -7323,10 +7182,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -7386,10 +7248,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or @@ -7514,6 +7379,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7527,6 +7416,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7534,6 +7424,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7545,7 +7436,7 @@ spec: procMount: description: |- procMount denotes the type of proc mount to use for the containers. - The default is DefaultProcMount which uses the container runtime defaults for + The default value is Default which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. @@ -7620,14 +7511,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7655,12 +7545,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7676,17 +7563,38 @@ spec: PodSecurityContext used by all workspace-related pods. If set, defined values are merged into the default PodSecurityContext configuration. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- 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: - 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) - If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows. format: int64 @@ -7730,6 +7638,32 @@ spec: Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string seLinuxOptions: description: |- The SELinux context to be applied to all containers. @@ -7766,14 +7700,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7783,17 +7716,28 @@ spec: type: object supplementalGroups: description: |- - 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. + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -7814,6 +7758,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -7834,12 +7779,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7932,7 +7874,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -7958,7 +7899,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -8281,10 +8221,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether @@ -8351,10 +8294,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether diff --git a/bundle/next/eclipse-che/metadata/annotations.yaml b/bundle/next/eclipse-che/metadata/annotations.yaml index 193dda9aa1..0af4afd36f 100644 --- a/bundle/next/eclipse-che/metadata/annotations.yaml +++ b/bundle/next/eclipse-che/metadata/annotations.yaml @@ -18,9 +18,9 @@ annotations: operators.operatorframework.io.bundle.package.v1: eclipse-che operators.operatorframework.io.bundle.channels.v1: next operators.operatorframework.io.bundle.channel.default.v1: next - operators.operatorframework.io.metrics.builder: operator-sdk-v1.9.0+git + operators.operatorframework.io.metrics.builder: operator-sdk-v1.39.2 operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 - operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 + operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4 # Annotations for testing. operators.operatorframework.io.test.mediatype.v1: scorecard+v1 diff --git a/bundle/next/eclipse-che/tests/scorecard/config.yaml b/bundle/next/eclipse-che/tests/scorecard/config.yaml index 08071ebe09..f1a147b370 100644 --- a/bundle/next/eclipse-che/tests/scorecard/config.yaml +++ b/bundle/next/eclipse-che/tests/scorecard/config.yaml @@ -24,6 +24,9 @@ stages: labels: suite: basic test: basic-check-spec-test + storage: + spec: + mountPath: {} - entrypoint: - scorecard-test - olm-bundle-validation @@ -31,6 +34,9 @@ stages: labels: suite: olm test: olm-bundle-validation-test + storage: + spec: + mountPath: {} - entrypoint: - scorecard-test - olm-crds-have-validation @@ -38,6 +44,9 @@ stages: labels: suite: olm test: olm-crds-have-validation-test + storage: + spec: + mountPath: {} - entrypoint: - scorecard-test - olm-spec-descriptors @@ -45,3 +54,9 @@ stages: labels: suite: olm test: olm-spec-descriptors-test + storage: + spec: + mountPath: {} +storage: + spec: + mountPath: {} diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000000..d3afbb9784 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,415 @@ +// +// Copyright (c) 2019-2025 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// + +package main + +import ( + "flag" + "os" + "time" + + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/eclipse-che/che-operator/controllers/namespacecache" + workspaceconfig "github.com/eclipse-che/che-operator/controllers/workspaceconfig" + + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/metrics/server" + + dwr "github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting" + + "github.com/eclipse-che/che-operator/controllers/devworkspace/solver" + "github.com/eclipse-che/che-operator/controllers/usernamespace" + + securityv1 "github.com/openshift/api/security/v1" + + dwoApi "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" + "github.com/devfile/devworkspace-operator/pkg/infrastructure" + devworkspaceinfra "github.com/devfile/devworkspace-operator/pkg/infrastructure" + "go.uber.org/zap/zapcore" + + "github.com/eclipse-che/che-operator/controllers/devworkspace" + "github.com/eclipse-che/che-operator/pkg/common/constants" + defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" + "github.com/eclipse-che/che-operator/pkg/common/signal" + "github.com/eclipse-che/che-operator/pkg/common/test" + + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + // to ensure that exec-entrypoint and run can make use of them. + "k8s.io/client-go/discovery" + _ "k8s.io/client-go/plugin/pkg/client/auth" + + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + osruntime "runtime" + + "fmt" + + "github.com/go-logr/logr" + configv1 "github.com/openshift/api/config/v1" + consolev1 "github.com/openshift/api/console/v1" + oauthv1 "github.com/openshift/api/oauth/v1" + templatev1 "github.com/openshift/api/template/v1" + + checontroller "github.com/eclipse-che/che-operator/controllers/che" + "github.com/eclipse-che/che-operator/pkg/common/utils" + + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + + operatorsv1 "github.com/operator-framework/api/pkg/operators/v1" + operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" + packagesv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" + + imagepullerapi "github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1" + projectv1 "github.com/openshift/api/project/v1" + routev1 "github.com/openshift/api/route/v1" + userv1 "github.com/openshift/api/user/v1" + appsv1 "k8s.io/api/apps/v1" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + rbacv1 "k8s.io/api/rbac/v1" + + chev1 "github.com/eclipse-che/che-operator/api/v1" + chev2 "github.com/eclipse-che/che-operator/api/v2" +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") + metricsAddr string + enableLeaderElection bool + probeAddr string + + leaseDuration = 40 * time.Second + renewDeadline = 30 * time.Second +) + +const ( + leasesApiResourceName = "leases" +) + +func init() { + flag.StringVar(&metricsAddr, "metrics-bind-address", ":60000", "The address the metric endpoint binds to.") + flag.StringVar(&probeAddr, "health-probe-bind-address", ":6789", "The address the probe endpoint binds to.") + flag.BoolVar(&enableLeaderElection, "leader-elect", false, + "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + + opts := zap.Options{ + Development: true, + Level: getLogLevel(), + } + opts.BindFlags(flag.CommandLine) + flag.Parse() + + logger := zap.New(zap.UseFlagOptions(&opts)) + ctrl.SetLogger(logger) + + if err := infrastructure.Initialize(); err != nil { + logger.Error(err, "Unable determine installation platform") + os.Exit(1) + } + + defaults.Initialize() + + printVersion(logger) + + utilruntime.Must(chev1.AddToScheme(scheme)) + utilruntime.Must(chev2.AddToScheme(scheme)) + + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(admissionregistrationv1.AddToScheme(scheme)) + utilruntime.Must(rbacv1.AddToScheme(scheme)) + + utilruntime.Must(imagepullerapi.AddToScheme(scheme)) + utilruntime.Must(packagesv1.AddToScheme(scheme)) + utilruntime.Must(operatorsv1alpha1.AddToScheme(scheme)) + utilruntime.Must(operatorsv1.AddToScheme(scheme)) + utilruntime.Must(corev1.AddToScheme(scheme)) + + if infrastructure.IsOpenShift() { + utilruntime.Must(routev1.AddToScheme(scheme)) + utilruntime.Must(oauthv1.AddToScheme(scheme)) + utilruntime.Must(userv1.AddToScheme(scheme)) + utilruntime.Must(configv1.AddToScheme(scheme)) + utilruntime.Must(consolev1.AddToScheme(scheme)) + utilruntime.Must(projectv1.AddToScheme(scheme)) + utilruntime.Must(securityv1.Install(scheme)) + utilruntime.Must(templatev1.Install(scheme)) + } +} + +func getLogLevel() zapcore.Level { + switch logLevel, _ := os.LookupEnv("LOG_LEVEL"); logLevel { + case zapcore.DebugLevel.String(): + return zapcore.DebugLevel + case zapcore.InfoLevel.String(): + return zapcore.InfoLevel + case zapcore.WarnLevel.String(): + return zapcore.WarnLevel + case zapcore.ErrorLevel.String(): + return zapcore.ErrorLevel + case zapcore.PanicLevel.String(): + return zapcore.PanicLevel + default: + return zapcore.InfoLevel + } +} + +func printVersion(logger logr.Logger) { + logger.Info("Binary info ", "Go version", osruntime.Version()) + logger.Info("Binary info ", "OS", osruntime.GOOS, "Arch", osruntime.GOARCH) + logger.Info("Address ", "Metrics", metricsAddr) + logger.Info("Address ", "Probe", probeAddr) + + infra := "Kubernetes" + if infrastructure.IsOpenShift() { + infra = "OpenShift v4.x" + } + logger.Info("Operator is running on ", "Infrastructure", infra) +} + +// getWatchNamespace returns the Namespace the operator should be watching for changes +func getWatchNamespace() (string, error) { + // WatchNamespaceEnvVar is the constant for env variable WATCH_NAMESPACE + // which specifies the Namespace to watch. + // An empty value means the operator is running with cluster scope. + var watchNamespaceEnvVar = "WATCH_NAMESPACE" + + ns, found := os.LookupEnv(watchNamespaceEnvVar) + if !found { + return "", fmt.Errorf("%s must be set", watchNamespaceEnvVar) + } + + return ns, nil +} + +func main() { + watchNamespace, err := getWatchNamespace() + if err != nil { + setupLog.Error(err, "unable to get WatchNamespace, "+ + "the manager will watch and manage resources in all namespaces") + } + + config := ctrl.GetConfigOrDie() + + discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) + if err != nil { + setupLog.Error(err, "failed to create discovery client") + os.Exit(1) + } + + if !utils.IsK8SResourceServed(discoveryClient, leasesApiResourceName) { + setupLog.Info("Leader election was disabled", "Cause:", leasesApiResourceName+"k8s api resource is an absent.") + enableLeaderElection = false + } + + // Add the Dev Workspace API to the scheme + if err := dwoApi.AddToScheme(scheme); err != nil { + setupLog.Error(err, "Dev Workspace Operator is not installed") + os.Exit(1) + } + + // DWO use the infrastructure package for openshift detection. It needs to be initialized + // but only supports OpenShift v4 or Kubernetes. + if err := devworkspaceinfra.Initialize(); err != nil { + setupLog.Error(err, "failed to evaluate infrastructure which is needed for DevWorkspace support") + os.Exit(1) + } + + cacheFunction, err := getCacheFunc() + if err != nil { + setupLog.Error(err, "failed to create cache function") + os.Exit(1) + } + + mgr, err := ctrl.NewManager(config, ctrl.Options{ + Scheme: scheme, + Metrics: server.Options{BindAddress: metricsAddr}, + WebhookServer: webhook.NewServer(webhook.Options{Port: 9443}), + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "e79b08a4.org.eclipse.che", + LeaderElectionReleaseOnCancel: true, + LeaseDuration: &leaseDuration, + RenewDeadline: &renewDeadline, + NewCache: cacheFunction, + + // NOTE: We CANNOT limit the manager to a single namespace, because that would limit the + // devworkspace routing reconciler to a single namespace, which would make it totally unusable. + // Instead, if some controller wants to limit itself to single namespace, it can do it + // for example using an event filter, as checontroller does. + // Namespace: watchNamespace, + }) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + nonCachingClient, err := client.New(mgr.GetConfig(), client.Options{Scheme: scheme}) + if err != nil { + setupLog.Error(err, "unable to initialize non cached client") + os.Exit(1) + } + + // Setup all Controllers + cheReconciler := checontroller.NewReconciler(mgr.GetClient(), nonCachingClient, discoveryClient, mgr.GetScheme(), watchNamespace) + if err = cheReconciler.SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to set up controller", "controller", "CheCluster") + os.Exit(1) + } + + routing := dwr.DevWorkspaceRoutingReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("DevWorkspaceRouting"), + Scheme: mgr.GetScheme(), + SolverGetter: solver.Getter(mgr.GetScheme()), + } + if err := routing.SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to set up controller", "controller", "DevWorkspaceRouting") + os.Exit(1) + } + + namespacecache := namespacecache.NewNamespaceCache(nonCachingClient) + + userNamespaceReconciler := usernamespace.NewCheUserNamespaceReconciler(mgr.GetClient(), nonCachingClient, mgr.GetScheme(), namespacecache) + if err = userNamespaceReconciler.SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to set up controller", "controller", "CheUserReconciler") + os.Exit(1) + } + + workspacesConfigReconciler := workspaceconfig.NewWorkspacesConfigReconciler(mgr.GetClient(), nonCachingClient, mgr.GetScheme(), namespacecache) + if err = workspacesConfigReconciler.SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to set up controller", "controller", "WorkspacesConfigReconciler") + os.Exit(1) + } + + terminationPeriod := int64(20) + if !test.IsTestMode() { + namespace, err := infrastructure.GetOperatorNamespace() + if err == nil { + terminationPeriod = signal.GetTerminationGracePeriodSeconds(mgr.GetAPIReader(), namespace) + } + } + sigHandler := signal.SetupSignalHandler(terminationPeriod) + + // we install the devworkspace CheCluster reconciler even if dw is not supported so that it + // can write meaningful status messages into the CheCluster CRs. + dwChe := devworkspace.CheClusterReconciler{} + if err := dwChe.SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to set up devWorkspace controller", "controller", "DevWorkspaceReconciler") + os.Exit(1) + } + + if os.Getenv("ENABLE_WEBHOOKS") != "false" { + if err = chev2.SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "CheCluster") + os.Exit(1) + } + } + + // +kubebuilder:scaffold:builder + if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up health check") + os.Exit(1) + } + if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up ready check") + os.Exit(1) + } + + // Start the Cmd + setupLog.Info("starting manager") + if err := mgr.Start(sigHandler); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} + +// watch k8s objects with labels `app.kubernetes.io/part-of=che.eclipse.org` +func getCacheFunc() (cache.NewCacheFunc, error) { + partOfCheObjectSelector, err := labels.Parse(fmt.Sprintf("%s=%s", constants.KubernetesPartOfLabelKey, constants.CheEclipseOrg)) + if err != nil { + return nil, err + } + + selectors := map[client.Object]cache.ByObject{ + &appsv1.Deployment{}: { + Label: partOfCheObjectSelector, + }, + &corev1.Pod{}: { + Label: partOfCheObjectSelector, + }, + &batchv1.Job{}: { + Label: partOfCheObjectSelector, + }, + &corev1.Service{}: { + Label: partOfCheObjectSelector, + }, + &networkingv1.Ingress{}: { + Label: partOfCheObjectSelector, + }, + &networkingv1.NetworkPolicy{}: { + Label: partOfCheObjectSelector, + }, + &corev1.ConfigMap{}: { + Label: partOfCheObjectSelector, + }, + &corev1.Secret{}: { + Label: partOfCheObjectSelector, + }, + &corev1.ServiceAccount{}: { + Label: partOfCheObjectSelector, + }, + &rbacv1.Role{}: { + Label: partOfCheObjectSelector, + }, + &rbacv1.RoleBinding{}: { + Label: partOfCheObjectSelector, + }, + &rbacv1.ClusterRole{}: { + Label: partOfCheObjectSelector, + }, + &rbacv1.ClusterRoleBinding{}: { + Label: partOfCheObjectSelector, + }, + &corev1.PersistentVolumeClaim{}: { + Label: partOfCheObjectSelector, + }, + &corev1.LimitRange{}: { + Label: partOfCheObjectSelector, + }, + &corev1.ResourceQuota{}: { + Label: partOfCheObjectSelector, + }, + } + + if infrastructure.IsOpenShift() { + selectors[&oauthv1.OAuthClient{}] = cache.ByObject{Label: partOfCheObjectSelector} + selectors[&routev1.Route{}] = cache.ByObject{Label: partOfCheObjectSelector} + selectors[&templatev1.Template{}] = cache.ByObject{Label: partOfCheObjectSelector} + } + + return func(config *rest.Config, opts cache.Options) (cache.Cache, error) { + opts.ByObject = selectors + return cache.New(config, opts) + }, nil +} diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml index ebe95be41e..2127158b8d 100644 --- a/config/certmanager/certificate.yaml +++ b/config/certmanager/certificate.yaml @@ -10,9 +10,6 @@ # Red Hat, Inc. - initial API and implementation # -# The following manifests contain a self-signed issuer CR and a certificate CR. -# More document can be found at https://docs.cert-manager.io -# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. apiVersion: cert-manager.io/v1 kind: Issuer metadata: diff --git a/config/crd/bases/org.eclipse.che_checlusters.yaml b/config/crd/bases/org.eclipse.che_checlusters.yaml index fa4c1d9e1b..ffd014378a 100644 --- a/config/crd/bases/org.eclipse.che_checlusters.yaml +++ b/config/crd/bases/org.eclipse.che_checlusters.yaml @@ -14,7 +14,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.18.0 name: checlusters.org.eclipse.che spec: group: org.eclipse.che @@ -121,10 +121,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -184,10 +187,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -236,10 +242,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -299,10 +308,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -355,10 +367,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -418,10 +433,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -470,10 +488,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -533,10 +554,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -859,10 +883,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -922,10 +949,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1010,10 +1040,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1073,10 +1106,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1392,10 +1428,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1455,10 +1494,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1568,10 +1610,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1631,10 +1676,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1751,10 +1799,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1814,10 +1865,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1987,10 +2041,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -2050,10 +2107,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2270,7 +2330,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2279,7 +2338,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2293,7 +2351,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -2309,13 +2366,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2324,20 +2378,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2356,27 +2406,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2405,13 +2448,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -2435,7 +2475,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -2502,7 +2541,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -2574,7 +2612,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -2612,7 +2649,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2628,13 +2664,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2643,20 +2676,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2675,27 +2704,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2751,7 +2773,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2767,13 +2788,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2782,20 +2800,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2814,27 +2828,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2876,7 +2883,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -2893,13 +2899,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -2993,13 +2997,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -3047,7 +3048,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -3059,13 +3059,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -3126,7 +3123,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3135,7 +3131,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3149,7 +3144,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -3166,13 +3160,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3180,20 +3171,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3211,27 +3198,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3259,13 +3239,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -3288,7 +3265,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -3330,7 +3306,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -3402,7 +3377,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -3439,7 +3413,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3456,13 +3429,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3470,20 +3440,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3501,27 +3467,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3577,7 +3536,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3594,13 +3552,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3608,20 +3563,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3639,27 +3590,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -4093,10 +4037,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4160,10 +4107,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4426,10 +4376,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4493,10 +4446,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4725,10 +4681,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4792,10 +4751,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5064,10 +5026,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -5131,10 +5096,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5356,6 +5324,8 @@ spec: description: OpenShift security context constraint to build containers. type: string + required: + - openShiftSecurityContextConstraint type: object defaultComponents: description: |- @@ -5402,7 +5372,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5411,7 +5380,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5425,7 +5393,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -5441,13 +5408,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5456,20 +5420,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5488,27 +5448,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5537,13 +5490,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -5567,7 +5517,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -5634,7 +5583,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -5706,7 +5654,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -5744,7 +5691,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5760,13 +5706,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5775,20 +5718,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5807,27 +5746,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5883,7 +5815,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5899,13 +5830,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5914,20 +5842,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5946,27 +5870,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6008,7 +5925,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -6025,13 +5941,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -6125,13 +6039,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -6179,7 +6090,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -6191,13 +6101,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -6258,7 +6165,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6267,7 +6173,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6281,7 +6186,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -6298,13 +6202,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6312,20 +6213,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6343,27 +6240,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6391,13 +6281,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -6420,7 +6307,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -6462,7 +6348,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -6534,7 +6419,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -6571,7 +6455,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6588,13 +6471,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6602,20 +6482,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6633,27 +6509,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6709,7 +6578,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6726,13 +6594,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6740,20 +6605,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6771,27 +6632,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6967,7 +6821,6 @@ spec: When set to `false` (the default value), the devEnvironments.security.containerSecurityContext field is ignored, and the following container SecurityContext is applied: - containerSecurityContext: allowPrivilegeEscalation: true capabilities: @@ -7011,10 +6864,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7074,10 +6930,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7275,10 +7134,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7338,10 +7200,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7466,6 +7331,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7479,6 +7368,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7486,6 +7376,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7497,7 +7388,7 @@ spec: procMount: description: |- procMount denotes the type of proc mount to use for the containers. - The default is DefaultProcMount which uses the container runtime defaults for + The default value is Default which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. @@ -7572,14 +7463,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7607,12 +7497,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7628,17 +7515,38 @@ spec: PodSecurityContext used by all workspace-related pods. If set, defined values are merged into the default PodSecurityContext configuration. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- 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: - 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) - If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows. format: int64 @@ -7682,6 +7590,32 @@ spec: Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string seLinuxOptions: description: |- The SELinux context to be applied to all containers. @@ -7718,14 +7652,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7735,17 +7668,28 @@ spec: type: object supplementalGroups: description: |- - 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. + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -7766,6 +7710,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -7786,12 +7731,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7883,7 +7825,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -7909,7 +7850,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -8230,10 +8170,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -8300,10 +8243,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the diff --git a/config/manifests/bases/che-operator.clusterserviceversion.yaml b/config/manifests/bases/che-operator.clusterserviceversion.yaml index 215743dbdd..fa27c042db 100644 --- a/config/manifests/bases/che-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/che-operator.clusterserviceversion.yaml @@ -45,11 +45,11 @@ spec: apiservicedefinitions: {} customresourcedefinitions: owned: - - description: 'The `CheCluster` custom resource allows defining and managing - Eclipse Che server installation. Based on these settings, the Operator automatically - creates and maintains several ConfigMaps: `che`, `plugin-registry` that will - contain the appropriate environment variables of the various components of - the installation. These generated ConfigMaps must NOT be updated manually.' + - description: |- + The `CheCluster` custom resource allows defining and managing Eclipse Che server installation. + Based on these settings, the Operator automatically creates and maintains several ConfigMaps: + `che`, `plugin-registry` that will contain the appropriate environment variables + of the various components of the installation. These generated ConfigMaps must NOT be updated manually. displayName: Eclipse Che instance Specification kind: CheCluster name: checlusters.org.eclipse.che @@ -104,8 +104,9 @@ spec: Service (dev.azure.com). displayName: Azure path: gitServices.azure - - description: 'Kubernetes secret, that contains Base64-encoded Azure DevOps - Service Application ID and Client Secret. See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-microsoft-azure-devops-services' + - description: |- + Kubernetes secret, that contains Base64-encoded Azure DevOps Service Application ID and Client Secret. + See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-microsoft-azure-devops-services displayName: Secret Name path: gitServices.azure[0].secretName x-descriptors: @@ -114,9 +115,10 @@ spec: or self-hosted). displayName: Bitbucket path: gitServices.bitbucket - - description: 'Kubernetes secret, that contains Base64-encoded Bitbucket OAuth - 1.0 or OAuth 2.0 data. See the following pages for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-1-for-a-bitbucket-server/ - and https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-the-bitbucket-cloud/.' + - description: |- + Kubernetes secret, that contains Base64-encoded Bitbucket OAuth 1.0 or OAuth 2.0 data. + See the following pages for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-1-for-a-bitbucket-server/ + and https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-the-bitbucket-cloud/. displayName: Secret Name path: gitServices.bitbucket[0].secretName x-descriptors: @@ -125,9 +127,9 @@ spec: or GitHub Enterprise). displayName: GitHub path: gitServices.github - - description: 'Kubernetes secret, that contains Base64-encoded GitHub OAuth - Client id and GitHub OAuth Client secret. See the following page for details: - https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-github/.' + - description: |- + Kubernetes secret, that contains Base64-encoded GitHub OAuth Client id and GitHub OAuth Client secret. + See the following page for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-github/. displayName: Secret Name path: gitServices.github[0].secretName x-descriptors: @@ -136,8 +138,9 @@ spec: or self-hosted). displayName: GitLab path: gitServices.gitlab - - description: 'Kubernetes secret, that contains Base64-encoded GitHub Application - id and GitLab Application Client secret. See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-gitlab/.' + - description: |- + Kubernetes secret, that contains Base64-encoded GitHub Application id and GitLab Application Client secret. + See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-gitlab/. displayName: Secret Name path: gitServices.gitlab[0].secretName x-descriptors: @@ -185,9 +188,9 @@ spec: path: reason x-descriptors: - urn:alm:descriptor:text - - description: The resolved workspace base domain. This is either the copy of - the explicitly defined property of the same name in the spec or, if it is - undefined in the spec and we're running on OpenShift, the automatically + - description: |- + The resolved workspace base domain. This is either the copy of the explicitly defined property of the + same name in the spec or, if it is undefined in the spec and we're running on OpenShift, the automatically resolved basedomain for routes. displayName: Workspace base domain path: workspaceBaseDomain @@ -252,9 +255,10 @@ spec: - description: DevWorkspace operator configuration displayName: Dev Workspace operator path: devWorkspace - - description: Deploys the DevWorkspace Operator in the cluster. Does nothing - when a matching version of the Operator is already installed. Fails when - a non-matching version of the Operator is already installed. + - description: |- + Deploys the DevWorkspace Operator in the cluster. + Does nothing when a matching version of the Operator is already installed. + Fails when a non-matching version of the Operator is already installed. displayName: Enable DevWorkspace operator path: devWorkspace.enable x-descriptors: @@ -266,9 +270,10 @@ spec: or self-hosted). displayName: Bitbucket path: gitServices.bitbucket - - description: 'Kubernetes secret, that contains Base64-encoded Bitbucket OAuth - 1.0 or OAuth 2.0 data. See the following pages for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-1-for-a-bitbucket-server/ - and https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-the-bitbucket-cloud/.' + - description: |- + Kubernetes secret, that contains Base64-encoded Bitbucket OAuth 1.0 or OAuth 2.0 data. + See the following pages for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-1-for-a-bitbucket-server/ + and https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-the-bitbucket-cloud/. displayName: Secret Name path: gitServices.bitbucket[0].secretName x-descriptors: @@ -277,9 +282,9 @@ spec: or GitHub Enterprise). displayName: GitHub path: gitServices.github - - description: 'Kubernetes secret, that contains Base64-encoded GitHub OAuth - Client id and GitHub OAuth Client secret. See the following page for details: - https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-github/.' + - description: |- + Kubernetes secret, that contains Base64-encoded GitHub OAuth Client id and GitHub OAuth Client secret. + See the following page for details: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-github/. displayName: Secret Name path: gitServices.github[0].secretName x-descriptors: @@ -288,8 +293,9 @@ spec: or self-hosted). displayName: GitLab path: gitServices.gitlab - - description: 'Kubernetes secret, that contains Base64-encoded GitHub Application - id and GitLab Application Client secret. See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-gitlab/.' + - description: |- + Kubernetes secret, that contains Base64-encoded GitHub Application id and GitLab Application Client secret. + See the following page: https://www.eclipse.org/che/docs/stable/administration-guide/configuring-oauth-2-for-gitlab/. displayName: Secret Name path: gitServices.gitlab[0].secretName x-descriptors: @@ -309,11 +315,10 @@ spec: plugin and devfile registries displayName: Che server path: server - - description: Deprecated. The value of this flag is ignored. Defines that a - user is allowed to specify a Kubernetes namespace, or an OpenShift project, - which differs from the default. It's NOT RECOMMENDED to set to `true` without - OpenShift OAuth configured. The OpenShift infrastructure also uses this - property. + - description: |- + Deprecated. The value of this flag is ignored. + Defines that a user is allowed to specify a Kubernetes namespace, or an OpenShift project, which differs from the default. + It's NOT RECOMMENDED to set to `true` without OpenShift OAuth configured. The OpenShift infrastructure also uses this property. displayName: Allow User Defined Workspace Namespaces path: server.allowUserDefinedWorkspaceNamespaces x-descriptors: @@ -323,9 +328,9 @@ spec: path: server.devfileRegistryUrl x-descriptors: - urn:alm:descriptor:com.tectonic.ui:hidden - - description: Deprecated. The value of this flag is ignored. The Che Operator - will automatically detect whether the router certificate is self-signed - and propagate it to other components, such as the Che server. + - description: |- + Deprecated. The value of this flag is ignored. + The Che Operator will automatically detect whether the router certificate is self-signed and propagate it to other components, such as the Che server. displayName: Self Signed Cert path: server.selfSignedCert x-descriptors: diff --git a/config/webhook/webhooks.yaml b/config/webhook/webhooks.yaml index 1b8cf8bb55..6fac5a16be 100644 --- a/config/webhook/webhooks.yaml +++ b/config/webhook/webhooks.yaml @@ -1,5 +1,5 @@ # -# Copyright (c) 2019-2023 Red Hat, Inc. +# Copyright (c) 2019-2025 Red Hat, Inc. # This program and the accompanying materials are made # available under the terms of the Eclipse Public License 2.0 # which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -22,7 +22,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service @@ -52,24 +51,23 @@ metadata: app.kubernetes.io/name: che app.kubernetes.io/part-of: che.eclipse.org webhooks: -- admissionReviewVersions: - - v1 - - v1beta1 - clientConfig: - service: - name: che-operator-service - namespace: eclipse-che - path: /validate-org-eclipse-che-v2-checluster - failurePolicy: Fail - name: vchecluster.kb.io - rules: - - apiGroups: - - org.eclipse.che - apiVersions: - - v2 - operations: - - CREATE - - UPDATE - resources: - - checlusters - sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: che-operator-service + namespace: eclipse-che + path: /validate-org-eclipse-che-v2-checluster + failurePolicy: Fail + name: vchecluster.kb.io + rules: + - apiGroups: + - org.eclipse.che + apiVersions: + - v2 + operations: + - CREATE + - UPDATE + resources: + - checlusters + sideEffects: None diff --git a/controllers/che/checluster_controller.go b/controllers/che/checluster_controller.go index f45fec7477..fa00b858b6 100644 --- a/controllers/che/checluster_controller.go +++ b/controllers/che/checluster_controller.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -15,6 +15,11 @@ package che import ( "context" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/controller" + + "sigs.k8s.io/controller-runtime/pkg/reconcile" + imagepuller "github.com/eclipse-che/che-operator/pkg/deploy/image-puller" editorsdefinitions "github.com/eclipse-che/che-operator/pkg/deploy/editors-definitions" @@ -39,24 +44,19 @@ import ( "github.com/eclipse-che/che-operator/pkg/deploy/server" "github.com/eclipse-che/che-operator/pkg/deploy/tls" + chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/go-logr/logr" routev1 "github.com/openshift/api/route/v1" "github.com/sirupsen/logrus" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + networking "k8s.io/api/networking/v1" rbacv1 "k8s.io/api/rbac/v1" k8sruntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/discovery" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/builder" "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/predicate" - "sigs.k8s.io/controller-runtime/pkg/source" - - chev2 "github.com/eclipse-che/che-operator/api/v2" - networking "k8s.io/api/networking/v1" ) // CheClusterReconciler reconciles a CheCluster object @@ -137,101 +137,56 @@ func NewReconciler( // SetupWithManager sets up the controller with the Manager. func (r *CheClusterReconciler) SetupWithManager(mgr ctrl.Manager) error { - onAllExceptGenericEventsPredicate := predicate.Funcs{ - UpdateFunc: func(evt event.UpdateEvent) bool { - return true - }, - CreateFunc: func(evt event.CreateEvent) bool { - return true - }, - DeleteFunc: func(evt event.DeleteEvent) bool { - return true - }, - GenericFunc: func(evt event.GenericEvent) bool { - return false - }, - } - - var toTrustedBundleConfigMapRequestMapper handler.MapFunc = func(obj client.Object) []ctrl.Request { + var toTrustedBundleConfigMapRequestMapper handler.MapFunc = func(ctx context.Context, obj client.Object) []reconcile.Request { isTrusted, reconcileRequest := IsTrustedBundleConfigMap(r.client, r.namespace, obj) if isTrusted { - return []ctrl.Request{reconcileRequest} + return []reconcile.Request{reconcileRequest} } - return []ctrl.Request{} + return []reconcile.Request{} } - var toEclipseCheRelatedObjRequestMapper handler.MapFunc = func(obj client.Object) []ctrl.Request { + var toEclipseCheRelatedObjRequestMapper handler.MapFunc = func(ctx context.Context, obj client.Object) []reconcile.Request { isEclipseCheRelatedObj, reconcileRequest := IsEclipseCheRelatedObj(r.client, r.namespace, obj) if isEclipseCheRelatedObj { - return []ctrl.Request{reconcileRequest} + return []reconcile.Request{reconcileRequest} } - return []ctrl.Request{} + return []reconcile.Request{} } - controllerBuilder := ctrl.NewControllerManagedBy(mgr). - // Watch for changes to primary resource CheCluster - Watches(&source.Kind{Type: &chev2.CheCluster{}}, &handler.EnqueueRequestForObject{}). - // Watch for changes to secondary resources and requeue the owner CheCluster - Watches(&source.Kind{Type: &corev1.Service{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &chev2.CheCluster{}, - }). - Watches(&source.Kind{Type: &corev1.Secret{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &chev2.CheCluster{}, - }). - Watches(&source.Kind{Type: &corev1.ConfigMap{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &chev2.CheCluster{}, - }). - Watches(&source.Kind{Type: &rbacv1.Role{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &chev2.CheCluster{}, - }). - Watches(&source.Kind{Type: &rbacv1.RoleBinding{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &chev2.CheCluster{}, - }). - Watches(&source.Kind{Type: &corev1.ServiceAccount{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &chev2.CheCluster{}, - }). - Watches(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &chev2.CheCluster{}, - }). - Watches(&source.Kind{Type: &corev1.ConfigMap{}}, + bld := ctrl.NewControllerManagedBy(mgr). + For(&chev2.CheCluster{}). + Owns(&corev1.Service{}). + Owns(&corev1.Secret{}). + Owns(&corev1.ConfigMap{}). + Owns(&rbacv1.Role{}). + Owns(&rbacv1.RoleBinding{}). + Owns(&corev1.ServiceAccount{}). + Owns(&appsv1.Deployment{}). + Watches(&corev1.ConfigMap{}, handler.EnqueueRequestsFromMapFunc(toTrustedBundleConfigMapRequestMapper), - builder.WithPredicates(onAllExceptGenericEventsPredicate), ). - Watches(&source.Kind{Type: &corev1.Secret{}}, + Watches(&corev1.Secret{}, handler.EnqueueRequestsFromMapFunc(toEclipseCheRelatedObjRequestMapper), - builder.WithPredicates(onAllExceptGenericEventsPredicate), ). - Watches(&source.Kind{Type: &corev1.ConfigMap{}}, + Watches(&corev1.ConfigMap{}, handler.EnqueueRequestsFromMapFunc(toEclipseCheRelatedObjRequestMapper), - builder.WithPredicates(onAllExceptGenericEventsPredicate), ) if infrastructure.IsOpenShift() { - controllerBuilder = controllerBuilder.Watches(&source.Kind{Type: &routev1.Route{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &chev2.CheCluster{}, - }) + bld.Owns(&routev1.Route{}) } else { - controllerBuilder = controllerBuilder.Watches(&source.Kind{Type: &networking.Ingress{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &chev2.CheCluster{}, - }) + bld.Owns(&networking.Ingress{}) } if r.namespace != "" { - controllerBuilder = controllerBuilder.WithEventFilter(utils.InNamespaceEventFilter(r.namespace)) + bld = bld.WithEventFilter(utils.InNamespaceEventFilter(r.namespace)) } - return controllerBuilder. - For(&chev2.CheCluster{}). - Complete(r) + // Use controller.TypedOptions to allow to configure 2 controllers for same object being reconciled + return bld.WithOptions( + controller.TypedOptions[reconcile.Request]{ + SkipNameValidation: pointer.Bool(true), + }).Complete(r) } // Reconcile is part of the main kubernetes reconciliation loop which aims to diff --git a/controllers/che/cheobj_verifier_test.go b/controllers/che/cheobj_verifier_test.go index 254189bd68..809861a7cb 100644 --- a/controllers/che/cheobj_verifier_test.go +++ b/controllers/che/cheobj_verifier_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -15,20 +15,20 @@ package che import ( "testing" + "sigs.k8s.io/controller-runtime/pkg/client" + chev2 "github.com/eclipse-che/che-operator/api/v2" defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" ) func TestIsTrustedBundleConfigMap(t *testing.T) { type testCase struct { name string - initObjects []runtime.Object - checluster *chev2.CheCluster + initObjects []client.Object objNamespace string objLabels map[string]string watchNamespace string @@ -53,21 +53,21 @@ func TestIsTrustedBundleConfigMap(t *testing.T) { testCases := []testCase{ { name: "Cluster scope object", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "", watchNamespace: "eclipse-che", expectedIsEclipseCheObj: false, }, { name: "Object in 'eclipse-che' namespace", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "eclipse-che", watchNamespace: "eclipse-che", expectedIsEclipseCheObj: true, }, { name: "Object in 'eclipse-che' namespace, not ca-bundle component", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objLabels: map[string]string{"app.kubernetes.io/part-of": "che.eclipse.org"}, objNamespace: "eclipse-che", watchNamespace: "eclipse-che", @@ -75,14 +75,14 @@ func TestIsTrustedBundleConfigMap(t *testing.T) { }, { name: "Object in another namespace than 'eclipse-che'", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "test-eclipse-che", watchNamespace: "eclipse-che", expectedIsEclipseCheObj: false, }, { name: "Object in 'eclipse-che' namespace, several checluster CR", - initObjects: []runtime.Object{ + initObjects: []client.Object{ // checluster CR in `default` namespace &chev2.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "default"}}, }, @@ -92,21 +92,21 @@ func TestIsTrustedBundleConfigMap(t *testing.T) { }, { name: "Cluster scope object, all-namespaces mode", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "", watchNamespace: "eclipse-che", expectedIsEclipseCheObj: false, }, { name: "Object in 'eclipse-che' namespace, all-namespaces mode", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "eclipse-che", watchNamespace: "", expectedIsEclipseCheObj: true, }, { name: "Object in another namespace than 'eclipse-che', all-namespaces mode", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "test-eclipse-che", watchNamespace: "", expectedIsEclipseCheObj: false, @@ -115,7 +115,7 @@ func TestIsTrustedBundleConfigMap(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.checluster, testCase.initObjects) + ctx := test.NewCtxBuilder().WithObjects(testCase.initObjects...).Build() newTestObject := testObject.DeepCopy() newTestObject.ObjectMeta.Namespace = testCase.objNamespace @@ -123,12 +123,12 @@ func TestIsTrustedBundleConfigMap(t *testing.T) { newTestObject.ObjectMeta.Labels = testCase.objLabels } - isEclipseCheObj, req := IsTrustedBundleConfigMap(deployContext.ClusterAPI.Client, testCase.watchNamespace, newTestObject) + isEclipseCheObj, req := IsTrustedBundleConfigMap(ctx.ClusterAPI.Client, testCase.watchNamespace, newTestObject) assert.Equal(t, testCase.expectedIsEclipseCheObj, isEclipseCheObj) if isEclipseCheObj { - assert.Equal(t, req.Namespace, deployContext.CheCluster.Namespace) - assert.Equal(t, req.Name, deployContext.CheCluster.Name) + assert.Equal(t, req.Namespace, ctx.CheCluster.Namespace) + assert.Equal(t, req.Name, ctx.CheCluster.Name) } }) } @@ -137,7 +137,7 @@ func TestIsTrustedBundleConfigMap(t *testing.T) { func TestIsEclipseCheRelatedObj(t *testing.T) { type testCase struct { name string - initObjects []runtime.Object + initObjects []client.Object objNamespace string watchNamespace string expectedIsEclipseCheObj bool @@ -160,28 +160,28 @@ func TestIsEclipseCheRelatedObj(t *testing.T) { testCases := []testCase{ { name: "Cluster scope object", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "", watchNamespace: "eclipse-che", expectedIsEclipseCheObj: false, }, { name: "Object in 'eclipse-che' namespace", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "eclipse-che", watchNamespace: "eclipse-che", expectedIsEclipseCheObj: true, }, { name: "Object in another namespace than 'eclipse-che'", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "test-eclipse-che", watchNamespace: "eclipse-che", expectedIsEclipseCheObj: false, }, { name: "Object in 'eclipse-che' namespace, several checluster CR", - initObjects: []runtime.Object{ + initObjects: []client.Object{ // checluster CR in `default` namespace &chev2.CheCluster{ObjectMeta: metav1.ObjectMeta{Name: "eclipse-che", Namespace: "default"}}, }, @@ -191,21 +191,21 @@ func TestIsEclipseCheRelatedObj(t *testing.T) { }, { name: "Cluster scope object, all-namespaces mode", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "", watchNamespace: "eclipse-che", expectedIsEclipseCheObj: false, }, { name: "Object in 'eclipse-che' namespace, all-namespaces mode", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "eclipse-che", watchNamespace: "", expectedIsEclipseCheObj: true, }, { name: "Object in another namespace than 'eclipse-che', all-namespaces mode", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, objNamespace: "test-eclipse-che", watchNamespace: "", expectedIsEclipseCheObj: false, @@ -214,15 +214,15 @@ func TestIsEclipseCheRelatedObj(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(nil, testCase.initObjects) + ctx := test.NewCtxBuilder().WithObjects(testCase.initObjects...).Build() testObject.ObjectMeta.Namespace = testCase.objNamespace - isEclipseCheObj, req := IsEclipseCheRelatedObj(deployContext.ClusterAPI.Client, testCase.watchNamespace, testObject) + isEclipseCheObj, req := IsEclipseCheRelatedObj(ctx.ClusterAPI.Client, testCase.watchNamespace, testObject) assert.Equal(t, testCase.expectedIsEclipseCheObj, isEclipseCheObj) if isEclipseCheObj { - assert.Equal(t, req.Namespace, deployContext.CheCluster.Namespace) - assert.Equal(t, req.Name, deployContext.CheCluster.Name) + assert.Equal(t, req.Namespace, ctx.CheCluster.Namespace) + assert.Equal(t, req.Name, ctx.CheCluster.Name) } }) } diff --git a/controllers/che/proxy_test.go b/controllers/che/proxy_test.go index e42cbf5660..0df4b36e2a 100644 --- a/controllers/che/proxy_test.go +++ b/controllers/che/proxy_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -13,23 +13,17 @@ package che import ( - "os" "reflect" "testing" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" + "github.com/eclipse-che/che-operator/pkg/common/test" + "sigs.k8s.io/controller-runtime/pkg/client" + chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/pkg/common/chetypes" "github.com/google/go-cmp/cmp" configv1 "github.com/openshift/api/config/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - fakeDiscovery "k8s.io/client-go/discovery/fake" - fakeclientset "k8s.io/client-go/kubernetes/fake" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" ) func TestReadProxyConfiguration(t *testing.T) { @@ -38,7 +32,7 @@ func TestReadProxyConfiguration(t *testing.T) { isOpenShift bool cheCluster *chev2.CheCluster clusterProxy *configv1.Proxy - initObjects []runtime.Object + initObjects []client.Object expectedProxyConf *chetypes.Proxy } @@ -56,7 +50,7 @@ func TestReadProxyConfiguration(t *testing.T) { Namespace: "eclipse-che", }, }, - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, expectedProxyConf: &chetypes.Proxy{}, }, { @@ -83,7 +77,7 @@ func TestReadProxyConfiguration(t *testing.T) { }, }, }, - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, expectedProxyConf: &chetypes.Proxy{ HttpProxy: "http://proxy:3128", HttpUser: "", @@ -128,7 +122,7 @@ func TestReadProxyConfiguration(t *testing.T) { }, }, }, - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, expectedProxyConf: &chetypes.Proxy{ HttpProxy: "http://proxy:3128", HttpUser: "", @@ -167,7 +161,7 @@ func TestReadProxyConfiguration(t *testing.T) { Namespace: "eclipse-che", }, }, - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, expectedProxyConf: &chetypes.Proxy{ HttpProxy: "http://proxy:3128", HttpUser: "", @@ -201,7 +195,7 @@ func TestReadProxyConfiguration(t *testing.T) { Namespace: "eclipse-che", }, }, - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, expectedProxyConf: &chetypes.Proxy{ TrustedCAMapName: "additional-cluster-ca-bundle", }, @@ -233,7 +227,7 @@ func TestReadProxyConfiguration(t *testing.T) { }, }, }, - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, expectedProxyConf: &chetypes.Proxy{ HttpProxy: "http://proxy:3128", HttpUser: "", @@ -269,7 +263,7 @@ func TestReadProxyConfiguration(t *testing.T) { }, }, }, - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, expectedProxyConf: &chetypes.Proxy{ HttpProxy: "http://proxy:3128", HttpUser: "", @@ -305,7 +299,7 @@ func TestReadProxyConfiguration(t *testing.T) { }, }, }, - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, expectedProxyConf: &chetypes.Proxy{ HttpProxy: "http://proxy:3128", HttpUser: "", @@ -325,31 +319,9 @@ func TestReadProxyConfiguration(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - testCase.initObjects = append(testCase.initObjects, testCase.clusterProxy, testCase.cheCluster) - - scheme := scheme.Scheme - chev2.SchemeBuilder.AddToScheme(scheme) - scheme.AddKnownTypes(configv1.SchemeGroupVersion, &configv1.Proxy{}) - - cli := fake.NewFakeClientWithScheme(scheme, testCase.initObjects...) - clientSet := fakeclientset.NewSimpleClientset() - fakeDiscovery, _ := clientSet.Discovery().(*fakeDiscovery.FakeDiscovery) - fakeDiscovery.Fake.Resources = []*metav1.APIResourceList{} - - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - deployContext := &chetypes.DeployContext{ - CheCluster: testCase.cheCluster, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme, - }, - } + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.clusterProxy).WithObjects(testCase.initObjects...).Build() - actualProxyConf, err := GetProxyConfiguration(deployContext) + actualProxyConf, err := GetProxyConfiguration(ctx) if err != nil { t.Fatalf("Error reading proxy configuration: %v", err) } diff --git a/controllers/devworkspace/controller.go b/controllers/devworkspace/controller.go index c1c0bac49c..4bcd8086d5 100644 --- a/controllers/devworkspace/controller.go +++ b/controllers/devworkspace/controller.go @@ -22,6 +22,10 @@ import ( "sync" "time" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/controllers/devworkspace/defaults" @@ -120,7 +124,12 @@ func (r *CheClusterReconciler) SetupWithManager(mgr ctrl.Manager) error { } else { bld.Owns(&networkingv1.Ingress{}) } - return bld.Complete(r) + + // Use controller.TypedOptions to allow to configure 2 controllers for same object being reconciled + return bld.WithOptions( + controller.TypedOptions[reconcile.Request]{ + SkipNameValidation: pointer.Bool(true), + }).Complete(r) } func (r *CheClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { diff --git a/controllers/devworkspace/controller_test.go b/controllers/devworkspace/controller_test.go index 6953e1caf5..d5f146bc38 100644 --- a/controllers/devworkspace/controller_test.go +++ b/controllers/devworkspace/controller_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -16,49 +16,25 @@ import ( "context" "os" "testing" - "time" + + "github.com/stretchr/testify/assert" defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" + "github.com/eclipse-che/che-operator/pkg/common/test" - dwo "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" devworkspacedefaults "github.com/eclipse-che/che-operator/controllers/devworkspace/defaults" "github.com/eclipse-che/che-operator/controllers/devworkspace/sync" - routev1 "github.com/openshift/api/route/v1" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - "k8s.io/api/node/v1alpha1" - rbac "k8s.io/api/rbac/v1" - - k8sErrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -func createTestScheme() *runtime.Scheme { - infrastructure.InitializeForTesting(infrastructure.Kubernetes) - - scheme := runtime.NewScheme() - utilruntime.Must(v1alpha1.AddToScheme(scheme)) - utilruntime.Must(networkingv1.AddToScheme(scheme)) - utilruntime.Must(corev1.AddToScheme(scheme)) - utilruntime.Must(appsv1.AddToScheme(scheme)) - utilruntime.Must(rbac.AddToScheme(scheme)) - utilruntime.Must(routev1.AddToScheme(scheme)) - utilruntime.Must(chev2.AddToScheme(scheme)) - utilruntime.Must(dwo.AddToScheme(scheme)) - - return scheme -} - func TestNoCustomResourceSharedWhenReconcilingNonExistent(t *testing.T) { infrastructure.InitializeForTesting(infrastructure.Kubernetes) @@ -69,10 +45,10 @@ func TestNoCustomResourceSharedWhenReconcilingNonExistent(t *testing.T) { managerName := "che" ns := "default" - scheme := createTestScheme() - cl := fake.NewFakeClientWithScheme(scheme) - ctx := context.TODO() + ctx := test.NewCtxBuilder().Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client reconciler := CheClusterReconciler{client: cl, scheme: scheme, syncer: sync.New(cl, scheme)} @@ -88,7 +64,7 @@ func TestNoCustomResourceSharedWhenReconcilingNonExistent(t *testing.T) { } // now add some manager and reconcile a non-existent one - cl.Create(ctx, &chev2.CheCluster{ + cl.Create(context.TODO(), &chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Name: managerName + "-not-me", Namespace: ns, @@ -125,8 +101,7 @@ func TestAddsCustomResourceToSharedMapOnCreate(t *testing.T) { managerName := "che" ns := "default" - scheme := createTestScheme() - cl := fake.NewFakeClientWithScheme(scheme, &chev2.CheCluster{ + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Name: managerName, Namespace: ns, @@ -138,7 +113,9 @@ func TestAddsCustomResourceToSharedMapOnCreate(t *testing.T) { Domain: "down.on.earth", }, }, - }) + }).Build() + cl := ctx.ClusterAPI.Client + scheme := ctx.ClusterAPI.Scheme reconciler := CheClusterReconciler{client: cl, scheme: scheme, syncer: sync.New(cl, scheme)} @@ -172,9 +149,8 @@ func TestUpdatesCustomResourceInSharedMapOnUpdate(t *testing.T) { managerName := "che" ns := "default" - scheme := createTestScheme() - cl := fake.NewFakeClientWithScheme(scheme, &chev2.CheCluster{ + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Name: managerName, Namespace: ns, @@ -186,7 +162,9 @@ func TestUpdatesCustomResourceInSharedMapOnUpdate(t *testing.T) { Domain: "down.on.earth", }, }, - }) + }).Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client reconciler := CheClusterReconciler{client: cl, scheme: scheme, syncer: sync.New(cl, scheme)} @@ -273,9 +251,8 @@ func TestRemovesCustomResourceFromSharedMapOnDelete(t *testing.T) { managerName := "che" ns := "default" - scheme := createTestScheme() - cl := fake.NewFakeClientWithScheme(scheme, &chev2.CheCluster{ + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Name: managerName, Namespace: ns, @@ -287,7 +264,9 @@ func TestRemovesCustomResourceFromSharedMapOnDelete(t *testing.T) { Domain: "down.on.earth", }, }, - }) + }).Build() + cl := ctx.ClusterAPI.Client + scheme := ctx.ClusterAPI.Scheme reconciler := CheClusterReconciler{client: cl, scheme: scheme, syncer: sync.New(cl, scheme)} @@ -331,105 +310,75 @@ func TestCustomResourceFinalization(t *testing.T) { managerName := "che" ns := "default" - scheme := createTestScheme() - ctx := context.TODO() - cl := fake.NewFakeClientWithScheme(scheme, - &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: managerName, - Namespace: ns, - Finalizers: []string{FinalizerName}, - }, - Spec: chev2.CheClusterSpec{ - Networking: chev2.CheClusterSpecNetworking{ - Hostname: "over.the.rainbow", - Domain: "down.on.earth", - }, + + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: managerName, + Namespace: ns, + Finalizers: []string{FinalizerName}, + }, + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Hostname: "over.the.rainbow", + Domain: "down.on.earth", }, }, - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ws1", - Namespace: ns, - Annotations: map[string]string{ - devworkspacedefaults.ConfigAnnotationCheManagerName: managerName, - devworkspacedefaults.ConfigAnnotationCheManagerNamespace: ns, - }, - Labels: devworkspacedefaults.GetLabelsFromNames(managerName, "gateway-config"), + }).WithObjects(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ws1", + Namespace: ns, + Annotations: map[string]string{ + devworkspacedefaults.ConfigAnnotationCheManagerName: managerName, + devworkspacedefaults.ConfigAnnotationCheManagerNamespace: ns, }, - }) + Labels: devworkspacedefaults.GetLabelsFromNames(managerName, "gateway-config"), + }, + }).Build() + cl := ctx.ClusterAPI.Client + scheme := ctx.ClusterAPI.Scheme reconciler := CheClusterReconciler{client: cl, scheme: scheme, syncer: sync.New(cl, scheme)} _, err := reconciler.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Name: managerName, Namespace: ns}}) - if err != nil { - t.Fatalf("Failed to reconcile che manager with error: %s", err) - } + assert.NoError(t, err) // check that the reconcile loop added the finalizer manager := chev2.CheCluster{} - err = cl.Get(ctx, client.ObjectKey{Name: managerName, Namespace: ns}, &manager) - if err != nil { - t.Fatalf("Failed to obtain the manager from the fake client: %s", err) - } - - if len(manager.Finalizers) != 1 { - t.Fatalf("Expected a single finalizer on the manager but found: %d", len(manager.Finalizers)) - } - - if manager.Finalizers[0] != FinalizerName { - t.Fatalf("Expected a finalizer called %s but got %s", FinalizerName, manager.Finalizers[0]) - } + err = cl.Get(context.TODO(), client.ObjectKey{Name: managerName, Namespace: ns}, &manager) + assert.NoError(t, err) + assert.Equal(t, 1, len(manager.Finalizers)) + assert.Equal(t, FinalizerName, manager.Finalizers[0]) // try to delete the manager and check that the configmap disallows that and that the status of the manager is updated - manager.DeletionTimestamp = &metav1.Time{Time: time.Now()} - err = cl.Update(ctx, &manager) - if err != nil { - t.Fatalf("Failed to update the manager in the fake client: %s", err) - } + err = cl.Delete(context.TODO(), &manager) + assert.NoError(t, err) + _, err = reconciler.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Name: managerName, Namespace: ns}}) - if err != nil { - t.Fatalf("Failed to reconcile che manager with error: %s", err) - } + assert.NoError(t, err) manager = chev2.CheCluster{} - err = cl.Get(ctx, client.ObjectKey{Name: managerName, Namespace: ns}, &manager) - if err != nil { - t.Fatalf("Failed to obtain the manager from the fake client: %s", err) - } - - if len(manager.Finalizers) != 1 { - t.Fatalf("There should have been a finalizer on the manager after a failed finalization attempt") - } - - if manager.Status.ChePhase != chev2.ClusterPhasePendingDeletion { - t.Fatalf("Expected the manager to be in the pending deletion phase but it is: %s", manager.Status.ChePhase) - } - if len(manager.Status.Message) == 0 { - t.Fatalf("Expected an non-empty message about the failed finalization in the manager status") - } + err = cl.Get(context.TODO(), client.ObjectKey{Name: managerName, Namespace: ns}, &manager) + assert.NoError(t, err) + assert.Equal(t, 1, len(manager.Finalizers)) + assert.Equal(t, chev2.ClusterPhasePendingDeletion, string(manager.Status.ChePhase)) + assert.NotEqual(t, 0, len(manager.Status.Message)) // now remove the config map and check that the finalization proceeds - err = cl.Delete(ctx, &corev1.ConfigMap{ + err = cl.Delete(context.TODO(), &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "ws1", Namespace: ns, }, }) - if err != nil { - t.Fatalf("Failed to delete the test configmap: %s", err) - } + assert.NoError(t, err) _, err = reconciler.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Name: managerName, Namespace: ns}}) - if err != nil { - t.Fatalf("Failed to reconcile che manager with error: %s", err) - } + assert.NoError(t, err) manager = chev2.CheCluster{} - err = cl.Get(ctx, client.ObjectKey{Name: managerName, Namespace: ns}, &manager) - if err == nil || !k8sErrors.IsNotFound(err) { - t.Fatalf("Failed to obtain the manager from the fake client: %s", err) - } + err = cl.Get(context.TODO(), client.ObjectKey{Name: managerName, Namespace: ns}, &manager) + assert.Error(t, err) + assert.True(t, errors.IsNotFound(err)) } // This test should be removed if we are again in charge of gateway creation. @@ -441,8 +390,6 @@ func TestExternalGatewayDetection(t *testing.T) { os.Setenv("CHE_FLAVOR", "test-che") - scheme := createTestScheme() - clusterName := "eclipse-che" ns := "default" @@ -458,7 +405,9 @@ func TestExternalGatewayDetection(t *testing.T) { } onKubernetes(func() { - cl := fake.NewFakeClientWithScheme(scheme, cluster) + ctx := test.NewCtxBuilder().WithCheCluster(cluster).Build() + cl := ctx.ClusterAPI.Client + scheme := ctx.ClusterAPI.Scheme reconciler := CheClusterReconciler{client: cl, scheme: scheme, syncer: sync.New(cl, scheme)} @@ -483,7 +432,9 @@ func TestExternalGatewayDetection(t *testing.T) { }) onOpenShift(func() { - cl := fake.NewFakeClientWithScheme(scheme, cluster) + ctx := test.NewCtxBuilder().WithCheCluster(cluster).Build() + cl := ctx.ClusterAPI.Client + scheme := ctx.ClusterAPI.Scheme reconciler := CheClusterReconciler{client: cl, scheme: scheme, syncer: sync.New(cl, scheme)} diff --git a/controllers/devworkspace/solver/che_routing_test.go b/controllers/devworkspace/solver/che_routing_test.go index 5d0a7e5dbb..a82b0f7256 100644 --- a/controllers/devworkspace/solver/che_routing_test.go +++ b/controllers/devworkspace/solver/che_routing_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -20,7 +20,6 @@ import ( "github.com/stretchr/testify/assert" - dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" dwo "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" "github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting/solvers" "github.com/eclipse-che/che-operator/pkg/common/test" @@ -33,19 +32,12 @@ import ( "github.com/eclipse-che/che-operator/controllers/devworkspace/defaults" constants "github.com/eclipse-che/che-operator/pkg/common/constants" "github.com/eclipse-che/che-operator/pkg/deploy/gateway" - routev1 "github.com/openshift/api/route/v1" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - rbac "k8s.io/api/rbac/v1" apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/yaml" @@ -55,28 +47,15 @@ var ( devfileEndpointAnnotations = map[string]string{"annotation-1": "value-1", "annotation-2": "value-2"} ) -func createTestScheme() *runtime.Scheme { - scheme := runtime.NewScheme() - utilruntime.Must(networkingv1.AddToScheme(scheme)) - utilruntime.Must(corev1.AddToScheme(scheme)) - utilruntime.Must(appsv1.AddToScheme(scheme)) - utilruntime.Must(rbac.AddToScheme(scheme)) - utilruntime.Must(dw.AddToScheme(scheme)) - utilruntime.Must(dwo.AddToScheme(scheme)) - utilruntime.Must(routev1.AddToScheme(scheme)) - utilruntime.Must(chev2.AddToScheme(scheme)) - - return scheme -} - -func getSpecObjectsForManager(t *testing.T, mgr *chev2.CheCluster, routing *dwo.DevWorkspaceRouting, additionalInitialObjects ...runtime.Object) (client.Client, solvers.RoutingSolver, solvers.RoutingObjects) { - scheme := createTestScheme() - - allObjs := []runtime.Object{mgr, routing} +func getSpecObjectsForManager(t *testing.T, mgr *chev2.CheCluster, routing *dwo.DevWorkspaceRouting, additionalInitialObjects ...client.Object) (client.Client, solvers.RoutingSolver, solvers.RoutingObjects) { + allObjs := []client.Object{mgr, routing} for i := range additionalInitialObjects { allObjs = append(allObjs, additionalInitialObjects[i]) } - cl := fake.NewFakeClientWithScheme(scheme, allObjs...) + + ctx := test.NewCtxBuilder().WithObjects(allObjs...).Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client solver, err := Getter(scheme).GetSolver(cl, "che") if err != nil { @@ -2199,10 +2178,11 @@ func TestOverrideGatewayContainerProvisioning(t *testing.T) { }, } - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - deployContext := test.GetDeployContext(cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(cheCluster).Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client - cheSolver := &CheRoutingSolver{client: deployContext.ClusterAPI.Client, scheme: deployContext.ClusterAPI.Scheme} + cheSolver := &CheRoutingSolver{client: cl, scheme: scheme} objs := &solvers.RoutingObjects{} routing := &dwo.DevWorkspaceRouting{ @@ -2252,10 +2232,11 @@ func TestOverridePartialLimitsGatewayContainerProvisioning(t *testing.T) { }, } - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - deployContext := test.GetDeployContext(cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(cheCluster).Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client - cheSolver := &CheRoutingSolver{client: deployContext.ClusterAPI.Client, scheme: deployContext.ClusterAPI.Scheme} + cheSolver := &CheRoutingSolver{client: cl, scheme: scheme} objs := &solvers.RoutingObjects{} routing := &dwo.DevWorkspaceRouting{ @@ -2310,10 +2291,11 @@ func TestOverrideGatewayEmptyContainerProvisioning(t *testing.T) { }, } - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - deployContext := test.GetDeployContext(cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(cheCluster).Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client - cheSolver := &CheRoutingSolver{client: deployContext.ClusterAPI.Client, scheme: deployContext.ClusterAPI.Scheme} + cheSolver := &CheRoutingSolver{client: cl, scheme: scheme} objs := &solvers.RoutingObjects{} routing := &dwo.DevWorkspaceRouting{ @@ -2353,10 +2335,11 @@ func TestDefaultGatewayContainerProvisioning(t *testing.T) { }, } - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - deployContext := test.GetDeployContext(cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(cheCluster).Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client - cheSolver := &CheRoutingSolver{client: deployContext.ClusterAPI.Client, scheme: deployContext.ClusterAPI.Scheme} + cheSolver := &CheRoutingSolver{client: cl, scheme: scheme} objs := &solvers.RoutingObjects{} routing := &dwo.DevWorkspaceRouting{ diff --git a/controllers/devworkspace/solver/solver.go b/controllers/devworkspace/solver/solver.go index 4b40a85c9f..4ac1a9211b 100644 --- a/controllers/devworkspace/solver/solver.go +++ b/controllers/devworkspace/solver/solver.go @@ -13,6 +13,7 @@ package solver import ( + "context" "fmt" "time" @@ -31,7 +32,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" ) var ( @@ -77,7 +77,7 @@ func (g *CheRouterGetter) SetupControllerManager(mgr *builder.Builder) error { // This way we can react on changes of the gateway configmap changes by re-reconciling the corresponding // devworkspace routing and thus keeping the devworkspace routing in a functional state // TODO is this going to be performant enough in a big cluster with very many configmaps? - mgr.Watches(&source.Kind{Type: &corev1.ConfigMap{}}, handler.EnqueueRequestsFromMapFunc(func(mo client.Object) []reconcile.Request { + mgr.Watches(&corev1.ConfigMap{}, handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, mo client.Object) []reconcile.Request { applicable, key := isGatewayWorkspaceConfig(mo) if applicable { diff --git a/controllers/devworkspace/sync/sync_test.go b/controllers/devworkspace/sync/sync_test.go index 2a707ea264..2499751d51 100644 --- a/controllers/devworkspace/sync/sync_test.go +++ b/controllers/devworkspace/sync/sync_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -17,22 +17,17 @@ import ( "reflect" "testing" + "github.com/eclipse-che/che-operator/pkg/common/test" + "github.com/devfile/devworkspace-operator/pkg/infrastructure" "github.com/google/go-cmp/cmp" 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/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" -) - -var ( - scheme = runtime.NewScheme() ) func init() { infrastructure.InitializeForTesting(infrastructure.Kubernetes) - corev1.AddToScheme(scheme) } func TestSyncCreates(t *testing.T) { @@ -51,7 +46,9 @@ func TestSyncCreates(t *testing.T) { }, } - cl := fake.NewFakeClientWithScheme(scheme, preexisting) + ctx := test.NewCtxBuilder().WithObjects(preexisting).Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client syncer := Syncer{client: cl, scheme: scheme} @@ -106,7 +103,9 @@ func TestSyncUpdates(t *testing.T) { }, } - cl := fake.NewFakeClientWithScheme(scheme, preexisting) + ctx := test.NewCtxBuilder().WithObjects(preexisting).Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client syncer := Syncer{client: cl, scheme: scheme} @@ -176,7 +175,9 @@ func TestSyncKeepsAdditionalAnnosAndLabels(t *testing.T) { }, } - cl := fake.NewFakeClientWithScheme(scheme, preexisting) + ctx := test.NewCtxBuilder().WithObjects(preexisting).Build() + scheme := ctx.ClusterAPI.Scheme + cl := ctx.ClusterAPI.Client syncer := Syncer{client: cl, scheme: scheme} diff --git a/controllers/namespacecache/init_test.go b/controllers/namespacecache/init_test.go new file mode 100644 index 0000000000..11e61f3018 --- /dev/null +++ b/controllers/namespacecache/init_test.go @@ -0,0 +1,26 @@ +// +// Copyright (c) 2019-2023 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// + +package namespacecache + +import ( + "github.com/devfile/devworkspace-operator/pkg/infrastructure" + defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" + "github.com/eclipse-che/che-operator/pkg/common/test" +) + +func init() { + test.EnableTestMode() + + infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + defaults.InitializeForTesting("../../config/manager/manager.yaml") +} diff --git a/controllers/namespacecache/namespacecache.go b/controllers/namespacecache/namespacecache.go new file mode 100644 index 0000000000..c689c93bc9 --- /dev/null +++ b/controllers/namespacecache/namespacecache.go @@ -0,0 +1,152 @@ +// +// Copyright (c) 2019-2023 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// + +package namespacecache + +import ( + "context" + "sync" + + "github.com/devfile/devworkspace-operator/pkg/infrastructure" + projectv1 "github.com/openshift/api/project/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const ( + WorkspaceNamespaceOwnerUidLabel string = "che.eclipse.org/workspace-namespace-owner-uid" + CheNameLabel string = "che.eclipse.org/che-name" + CheNamespaceLabel string = "che.eclipse.org/che-namespace" + ChePartOfLabel string = "app.kubernetes.io/part-of" + ChePartOfLabelValue string = "che.eclipse.org" + CheComponentLabel string = "app.kubernetes.io/component" + CheComponentLabelValue string = "workspaces-namespace" + CheUsernameAnnotation string = "che.eclipse.org/username" +) + +type NamespaceCache struct { + Client client.Client + KnownNamespaces map[string]NamespaceInfo + Lock sync.Mutex +} + +type NamespaceInfo struct { + IsWorkspaceNamespace bool + Username string + CheCluster *types.NamespacedName +} + +func NewNamespaceCache(client client.Client) *NamespaceCache { + return &NamespaceCache{ + Client: client, + KnownNamespaces: map[string]NamespaceInfo{}, + Lock: sync.Mutex{}, + } +} + +func (c *NamespaceCache) GetNamespaceInfo(ctx context.Context, namespace string) (*NamespaceInfo, error) { + c.Lock.Lock() + defer c.Lock.Unlock() + + for { + val, contains := c.KnownNamespaces[namespace] + if contains { + return &val, nil + } else { + existing, err := c.examineNamespaceUnsafe(ctx, namespace) + if err != nil { + return nil, err + } else if existing == nil { + return nil, nil + } + } + } +} +func (c *NamespaceCache) ExamineNamespace(ctx context.Context, ns string) (*NamespaceInfo, error) { + c.Lock.Lock() + defer c.Lock.Unlock() + + return c.examineNamespaceUnsafe(ctx, ns) +} + +func (c *NamespaceCache) GetAllKnownNamespaces() []string { + c.Lock.Lock() + defer c.Lock.Unlock() + + ret := make([]string, len(c.KnownNamespaces)) + i := 0 + for k := range c.KnownNamespaces { + ret[i] = k + i = i + 1 + } + + return ret +} + +func (c *NamespaceCache) examineNamespaceUnsafe(ctx context.Context, ns string) (*NamespaceInfo, error) { + var obj client.Object + if infrastructure.IsOpenShift() { + obj = &projectv1.Project{} + } else { + obj = &corev1.Namespace{} + } + + if err := c.Client.Get(ctx, client.ObjectKey{Name: ns}, obj); err != nil { + if errors.IsNotFound(err) { + delete(c.KnownNamespaces, ns) + return nil, nil + } + return nil, err + } + + var namespace = obj.(metav1.Object) + + if namespace.GetDeletionTimestamp() != nil { + delete(c.KnownNamespaces, ns) + return nil, nil + } + + labels := namespace.GetLabels() + if labels == nil { + labels = map[string]string{} + } + + annotations := namespace.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + } + + // ownerUid is the legacy label that we used to use. Let's not break the existing workspace namespaces and still + // recognize it + ownerUid := labels[WorkspaceNamespaceOwnerUidLabel] + cheName := labels[CheNameLabel] + cheNamespace := labels[CheNamespaceLabel] + partOfLabel := labels[ChePartOfLabel] + componentLabel := labels[CheComponentLabel] + username := annotations[CheUsernameAnnotation] + + ret := NamespaceInfo{ + IsWorkspaceNamespace: ownerUid != "" || (partOfLabel == ChePartOfLabelValue && componentLabel == CheComponentLabelValue), + Username: username, + CheCluster: &types.NamespacedName{ + Name: cheName, + Namespace: cheNamespace, + }, + } + + c.KnownNamespaces[ns] = ret + + return &ret, nil +} diff --git a/controllers/namespacecache/namespacecache_test.go b/controllers/namespacecache/namespacecache_test.go new file mode 100644 index 0000000000..078f0bf6ca --- /dev/null +++ b/controllers/namespacecache/namespacecache_test.go @@ -0,0 +1,121 @@ +// +// Copyright (c) 2019-2025 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// + +package namespacecache + +import ( + "context" + "sync" + "testing" + + "github.com/eclipse-che/che-operator/pkg/common/test" + + "github.com/devfile/devworkspace-operator/pkg/infrastructure" + "github.com/stretchr/testify/assert" + + projectv1 "github.com/openshift/api/project/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func TestGetNamespaceInfoReadsFromCache(t *testing.T) { + test := func(infraType infrastructure.Type, namespace metav1.Object) { + infrastructure.InitializeForTesting(infraType) + ns := namespace.GetName() + + ctx := test.NewCtxBuilder().WithObjects(namespace.(client.Object)).Build() + cl := ctx.ClusterAPI.Client + + nsc := NamespaceCache{ + Client: cl, + KnownNamespaces: map[string]NamespaceInfo{}, + Lock: sync.Mutex{}, + } + + _, err := nsc.GetNamespaceInfo(context.TODO(), ns) + assert.NoError(t, err) + assert.Contains(t, nsc.KnownNamespaces, ns, "The namespace info should have been cached") + } + + test(infrastructure.Kubernetes, &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns", + }, + }) + + test(infrastructure.OpenShiftv4, &projectv1.Project{ + ObjectMeta: metav1.ObjectMeta{ + Name: "prj", + }, + }) +} + +func TestExamineUpdatesCache(t *testing.T) { + test := func(infraType infrastructure.Type, namespace metav1.Object) { + nsName := namespace.GetName() + ctx := test.NewCtxBuilder().WithObjects(namespace.(client.Object)).Build() + cl := ctx.ClusterAPI.Client + infrastructure.InitializeForTesting(infraType) + + nsc := NamespaceCache{ + Client: cl, + KnownNamespaces: map[string]NamespaceInfo{}, + Lock: sync.Mutex{}, + } + + nsi, err := nsc.GetNamespaceInfo(context.TODO(), nsName) + assert.NoError(t, err) + + assert.False(t, nsi.IsWorkspaceNamespace, "The namespace should not be found as managed") + + assert.Contains(t, nsc.KnownNamespaces, nsName, "The namespace info should have been cached") + + ns := namespace.(client.Object) + assert.NoError(t, cl.Get(context.TODO(), client.ObjectKey{Name: nsName}, ns)) + + ns.(metav1.Object).SetLabels(map[string]string{ + WorkspaceNamespaceOwnerUidLabel: "uid", + }) + + assert.NoError(t, cl.Update(context.TODO(), ns)) + + nsi, err = nsc.ExamineNamespace(context.TODO(), nsName) + assert.NoError(t, err) + + assert.True(t, nsi.IsWorkspaceNamespace, "namespace should be found as managed using the legacy user UID label") + + ns.(metav1.Object).SetLabels(map[string]string{ + ChePartOfLabel: ChePartOfLabelValue, + CheComponentLabel: CheComponentLabelValue, + }) + + assert.NoError(t, cl.Update(context.TODO(), ns)) + + nsi, err = nsc.ExamineNamespace(context.TODO(), nsName) + assert.NoError(t, err) + + assert.True(t, nsi.IsWorkspaceNamespace, "namespace should be found as managed using the part-of and component labels") + } + + test(infrastructure.Kubernetes, &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns", + }, + }) + + test(infrastructure.OpenShiftv4, &projectv1.Project{ + ObjectMeta: metav1.ObjectMeta{ + Name: "prj", + }, + }) +} diff --git a/controllers/namespacecache/usernamespace_utils.go b/controllers/namespacecache/usernamespace_utils.go new file mode 100644 index 0000000000..f9f296d19a --- /dev/null +++ b/controllers/namespacecache/usernamespace_utils.go @@ -0,0 +1,44 @@ +// +// Copyright (c) 2019-2023 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// + +package namespacecache + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +type EventRule struct { + Check func(metav1.Object) bool + Namespaces func(metav1.Object) []string +} + +func AsReconcileRequestsForNamespaces(obj metav1.Object, rules []EventRule) []reconcile.Request { + for _, r := range rules { + if r.Check(obj) { + nss := r.Namespaces(obj) + ret := make([]reconcile.Request, len(nss)) + for i, n := range nss { + ret[i] = reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: n, + }, + } + } + + return ret + } + } + + return []reconcile.Request{} +} diff --git a/controllers/usernamespace/namespacecache.go b/controllers/usernamespace/namespacecache.go deleted file mode 100644 index c5d8c7a025..0000000000 --- a/controllers/usernamespace/namespacecache.go +++ /dev/null @@ -1,152 +0,0 @@ -// -// Copyright (c) 2019-2023 Red Hat, Inc. -// This program and the accompanying materials are made -// available under the terms of the Eclipse Public License 2.0 -// which is available at https://www.eclipse.org/legal/epl-2.0/ -// -// SPDX-License-Identifier: EPL-2.0 -// -// Contributors: -// Red Hat, Inc. - initial API and implementation -// - -package usernamespace - -import ( - "context" - "sync" - - "github.com/devfile/devworkspace-operator/pkg/infrastructure" - projectv1 "github.com/openshift/api/project/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -const ( - workspaceNamespaceOwnerUidLabel string = "che.eclipse.org/workspace-namespace-owner-uid" - cheNameLabel string = "che.eclipse.org/che-name" - cheNamespaceLabel string = "che.eclipse.org/che-namespace" - chePartOfLabel string = "app.kubernetes.io/part-of" - chePartOfLabelValue string = "che.eclipse.org" - cheComponentLabel string = "app.kubernetes.io/component" - cheComponentLabelValue string = "workspaces-namespace" - cheUsernameAnnotation string = "che.eclipse.org/username" -) - -type namespaceCache struct { - client client.Client - knownNamespaces map[string]namespaceInfo - lock sync.Mutex -} - -type namespaceInfo struct { - IsWorkspaceNamespace bool - Username string - CheCluster *types.NamespacedName -} - -func NewNamespaceCache(client client.Client) *namespaceCache { - return &namespaceCache{ - client: client, - knownNamespaces: map[string]namespaceInfo{}, - lock: sync.Mutex{}, - } -} - -func (c *namespaceCache) GetNamespaceInfo(ctx context.Context, namespace string) (*namespaceInfo, error) { - c.lock.Lock() - defer c.lock.Unlock() - - for { - val, contains := c.knownNamespaces[namespace] - if contains { - return &val, nil - } else { - existing, err := c.examineNamespaceUnsafe(ctx, namespace) - if err != nil { - return nil, err - } else if existing == nil { - return nil, nil - } - } - } -} -func (c *namespaceCache) ExamineNamespace(ctx context.Context, ns string) (*namespaceInfo, error) { - c.lock.Lock() - defer c.lock.Unlock() - - return c.examineNamespaceUnsafe(ctx, ns) -} - -func (c *namespaceCache) GetAllKnownNamespaces() []string { - c.lock.Lock() - defer c.lock.Unlock() - - ret := make([]string, len(c.knownNamespaces)) - i := 0 - for k := range c.knownNamespaces { - ret[i] = k - i = i + 1 - } - - return ret -} - -func (c *namespaceCache) examineNamespaceUnsafe(ctx context.Context, ns string) (*namespaceInfo, error) { - var obj client.Object - if infrastructure.IsOpenShift() { - obj = &projectv1.Project{} - } else { - obj = &corev1.Namespace{} - } - - if err := c.client.Get(ctx, client.ObjectKey{Name: ns}, obj); err != nil { - if errors.IsNotFound(err) { - delete(c.knownNamespaces, ns) - return nil, nil - } - return nil, err - } - - var namespace = obj.(metav1.Object) - - if namespace.GetDeletionTimestamp() != nil { - delete(c.knownNamespaces, ns) - return nil, nil - } - - labels := namespace.GetLabels() - if labels == nil { - labels = map[string]string{} - } - - annotations := namespace.GetAnnotations() - if annotations == nil { - annotations = map[string]string{} - } - - // ownerUid is the legacy label that we used to use. Let's not break the existing workspace namespaces and still - // recognize it - ownerUid := labels[workspaceNamespaceOwnerUidLabel] - cheName := labels[cheNameLabel] - cheNamespace := labels[cheNamespaceLabel] - partOfLabel := labels[chePartOfLabel] - componentLabel := labels[cheComponentLabel] - username := annotations[cheUsernameAnnotation] - - ret := namespaceInfo{ - IsWorkspaceNamespace: ownerUid != "" || (partOfLabel == chePartOfLabelValue && componentLabel == cheComponentLabelValue), - Username: username, - CheCluster: &types.NamespacedName{ - Name: cheName, - Namespace: cheNamespace, - }, - } - - c.knownNamespaces[ns] = ret - - return &ret, nil -} diff --git a/controllers/usernamespace/namespacecache_test.go b/controllers/usernamespace/namespacecache_test.go deleted file mode 100644 index 41d300ea7b..0000000000 --- a/controllers/usernamespace/namespacecache_test.go +++ /dev/null @@ -1,149 +0,0 @@ -// -// Copyright (c) 2019-2023 Red Hat, Inc. -// This program and the accompanying materials are made -// available under the terms of the Eclipse Public License 2.0 -// which is available at https://www.eclipse.org/legal/epl-2.0/ -// -// SPDX-License-Identifier: EPL-2.0 -// -// Contributors: -// Red Hat, Inc. - initial API and implementation -// - -package usernamespace - -import ( - "context" - "sync" - "testing" - - dwo "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/stretchr/testify/assert" - - projectv1 "github.com/openshift/api/project/v1" - routev1 "github.com/openshift/api/route/v1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - "k8s.io/api/node/v1alpha1" - rbac "k8s.io/api/rbac/v1" - - configv1 "github.com/openshift/api/config/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" -) - -func createTestScheme() *runtime.Scheme { - scheme := runtime.NewScheme() - utilruntime.Must(v1alpha1.AddToScheme(scheme)) - utilruntime.Must(corev1.AddToScheme(scheme)) - utilruntime.Must(appsv1.AddToScheme(scheme)) - utilruntime.Must(rbac.AddToScheme(scheme)) - utilruntime.Must(routev1.AddToScheme(scheme)) - utilruntime.Must(chev2.AddToScheme(scheme)) - utilruntime.Must(dwo.AddToScheme(scheme)) - utilruntime.Must(projectv1.AddToScheme(scheme)) - utilruntime.Must(configv1.AddToScheme(scheme)) - utilruntime.Must(routev1.AddToScheme(scheme)) - utilruntime.Must(networkingv1.AddToScheme(scheme)) - - return scheme -} - -func TestGetNamespaceInfoReadsFromCache(t *testing.T) { - test := func(infraType infrastructure.Type, namespace metav1.Object) { - infrastructure.InitializeForTesting(infraType) - ctx := context.TODO() - - ns := namespace.GetName() - cl := fake.NewFakeClientWithScheme(createTestScheme(), namespace.(runtime.Object)) - - nsc := namespaceCache{ - client: cl, - knownNamespaces: map[string]namespaceInfo{}, - lock: sync.Mutex{}, - } - - _, err := nsc.GetNamespaceInfo(ctx, ns) - assert.NoError(t, err) - assert.Contains(t, nsc.knownNamespaces, ns, "The namespace info should have been cached") - } - - test(infrastructure.Kubernetes, &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ns", - }, - }) - - test(infrastructure.OpenShiftv4, &projectv1.Project{ - ObjectMeta: metav1.ObjectMeta{ - Name: "prj", - }, - }) -} - -func TestExamineUpdatesCache(t *testing.T) { - test := func(infraType infrastructure.Type, namespace metav1.Object) { - ctx := context.TODO() - - nsName := namespace.GetName() - cl := fake.NewFakeClientWithScheme(createTestScheme(), namespace.(runtime.Object)) - infrastructure.InitializeForTesting(infraType) - - nsc := namespaceCache{ - client: cl, - knownNamespaces: map[string]namespaceInfo{}, - lock: sync.Mutex{}, - } - - nsi, err := nsc.GetNamespaceInfo(ctx, nsName) - assert.NoError(t, err) - - assert.False(t, nsi.IsWorkspaceNamespace, "The namespace should not be found as managed") - - assert.Contains(t, nsc.knownNamespaces, nsName, "The namespace info should have been cached") - - ns := namespace.(client.Object) - assert.NoError(t, cl.Get(ctx, client.ObjectKey{Name: nsName}, ns)) - - ns.(metav1.Object).SetLabels(map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid", - }) - - assert.NoError(t, cl.Update(ctx, ns)) - - nsi, err = nsc.ExamineNamespace(ctx, nsName) - assert.NoError(t, err) - - assert.True(t, nsi.IsWorkspaceNamespace, "namespace should be found as managed using the legacy user UID label") - - ns.(metav1.Object).SetLabels(map[string]string{ - chePartOfLabel: chePartOfLabelValue, - cheComponentLabel: cheComponentLabelValue, - }) - - assert.NoError(t, cl.Update(ctx, ns)) - - nsi, err = nsc.ExamineNamespace(ctx, nsName) - assert.NoError(t, err) - - assert.True(t, nsi.IsWorkspaceNamespace, "namespace should be found as managed using the part-of and component labels") - } - - test(infrastructure.Kubernetes, &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ns", - }, - }) - - test(infrastructure.OpenShiftv4, &projectv1.Project{ - ObjectMeta: metav1.ObjectMeta{ - Name: "prj", - }, - }) -} diff --git a/controllers/usernamespace/usernamespace_controller.go b/controllers/usernamespace/usernamespace_controller.go index 7e420e8c20..d205db628f 100644 --- a/controllers/usernamespace/usernamespace_controller.go +++ b/controllers/usernamespace/usernamespace_controller.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -18,6 +18,10 @@ import ( "fmt" "strconv" + "github.com/eclipse-che/che-operator/controllers/namespacecache" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/controller" + containerbuild "github.com/eclipse-che/che-operator/pkg/deploy/container-build" rbacv1 "k8s.io/api/rbac/v1" @@ -42,7 +46,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" ) const ( @@ -57,7 +60,7 @@ type CheUserNamespaceReconciler struct { scheme *runtime.Scheme client client.Client nonCachedClient client.Client - namespaceCache *namespaceCache + namespaceCache *namespacecache.NamespaceCache } var _ reconcile.Reconciler = (*CheUserNamespaceReconciler)(nil) @@ -66,7 +69,7 @@ func NewCheUserNamespaceReconciler( client client.Client, noncachedClient client.Client, scheme *runtime.Scheme, - namespaceCache *namespaceCache) *CheUserNamespaceReconciler { + namespaceCache *namespacecache.NamespaceCache) *CheUserNamespaceReconciler { return &CheUserNamespaceReconciler{ scheme: scheme, @@ -86,34 +89,38 @@ func (r *CheUserNamespaceReconciler) SetupWithManager(mgr ctrl.Manager) error { ctx := context.Background() bld := ctrl.NewControllerManagedBy(mgr). For(obj). - Watches(&source.Kind{Type: &corev1.Secret{}}, r.watchRulesForSecrets(ctx)). - Watches(&source.Kind{Type: &corev1.ConfigMap{}}, r.watchRulesForConfigMaps(ctx)). - Watches(&source.Kind{Type: &chev2.CheCluster{}}, r.triggerAllNamespaces()) - - return bld.Complete(r) + Watches(&corev1.Secret{}, r.watchRulesForSecrets(ctx)). + Watches(&corev1.ConfigMap{}, r.watchRulesForConfigMaps(ctx)). + Watches(&chev2.CheCluster{}, r.triggerAllNamespaces()) + + // Use controller.TypedOptions to allow to configure 2 controllers for same object being reconciled + return bld.WithOptions( + controller.TypedOptions[reconcile.Request]{ + SkipNameValidation: pointer.Bool(true), + }).Complete(r) } func (r *CheUserNamespaceReconciler) watchRulesForSecrets(ctx context.Context) handler.EventHandler { rules := r.commonRules(ctx, constants.DefaultSelfSignedCertificateSecretName) return handler.EnqueueRequestsFromMapFunc( - handler.MapFunc(func(obj client.Object) []reconcile.Request { - return asReconcileRequestsForNamespaces(obj, rules) + handler.MapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { + return namespacecache.AsReconcileRequestsForNamespaces(obj, rules) })) } -func (r *CheUserNamespaceReconciler) commonRules(ctx context.Context, namesInCheClusterNamespace ...string) []eventRule { - return []eventRule{ +func (r *CheUserNamespaceReconciler) commonRules(ctx context.Context, namesInCheClusterNamespace ...string) []namespacecache.EventRule { + return []namespacecache.EventRule{ { - check: func(o metav1.Object) bool { + Check: func(o metav1.Object) bool { return isLabeledAsUserSettings(o) && r.isInManagedNamespace(ctx, o) }, - namespaces: func(o metav1.Object) []string { return []string{o.GetNamespace()} }, + Namespaces: func(o metav1.Object) []string { return []string{o.GetNamespace()} }, }, { - check: func(o metav1.Object) bool { + Check: func(o metav1.Object) bool { return r.hasNameAndIsCollocatedWithCheCluster(ctx, o, namesInCheClusterNamespace...) }, - namespaces: func(o metav1.Object) []string { return r.namespaceCache.GetAllKnownNamespaces() }, + Namespaces: func(o metav1.Object) []string { return r.namespaceCache.GetAllKnownNamespaces() }, }, } } @@ -121,8 +128,8 @@ func (r *CheUserNamespaceReconciler) commonRules(ctx context.Context, namesInChe func (r *CheUserNamespaceReconciler) watchRulesForConfigMaps(ctx context.Context) handler.EventHandler { rules := r.commonRules(ctx, tls.CheMergedCABundleCertsCMName) return handler.EnqueueRequestsFromMapFunc( - handler.MapFunc(func(obj client.Object) []reconcile.Request { - return asReconcileRequestsForNamespaces(obj, rules) + handler.MapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { + return namespacecache.AsReconcileRequestsForNamespaces(obj, rules) })) } @@ -147,7 +154,7 @@ func (r *CheUserNamespaceReconciler) isInManagedNamespace(ctx context.Context, o func (r *CheUserNamespaceReconciler) triggerAllNamespaces() handler.EventHandler { return handler.EnqueueRequestsFromMapFunc( - handler.MapFunc(func(obj client.Object) []reconcile.Request { + handler.MapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { nss := r.namespaceCache.GetAllKnownNamespaces() ret := make([]reconcile.Request, len(nss)) diff --git a/controllers/usernamespace/usernamespace_controller_test.go b/controllers/usernamespace/usernamespace_controller_test.go index eca4f2efde..fc64a3d2e7 100644 --- a/controllers/usernamespace/usernamespace_controller_test.go +++ b/controllers/usernamespace/usernamespace_controller_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -18,12 +18,15 @@ import ( "sync" "testing" + "github.com/eclipse-che/che-operator/controllers/namespacecache" + + "github.com/eclipse-che/che-operator/pkg/common/test" + containerbuild "github.com/eclipse-che/che-operator/pkg/deploy/container-build" rbacv1 "k8s.io/api/rbac/v1" dwconstants "github.com/devfile/devworkspace-operator/pkg/constants" "github.com/devfile/devworkspace-operator/pkg/infrastructure" - devworkspaceinfra "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/controllers/devworkspace" "github.com/eclipse-che/che-operator/pkg/common/constants" @@ -38,7 +41,6 @@ import ( "k8s.io/client-go/util/workqueue" "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -150,23 +152,22 @@ func setupCheCluster(t *testing.T, ctx context.Context, cl client.Client, scheme } } -func setup(infraType devworkspaceinfra.Type, objs ...runtime.Object) (*runtime.Scheme, client.Client, *CheUserNamespaceReconciler) { - devworkspaceinfra.InitializeForTesting(infraType) +func setup(infraType infrastructure.Type, objs ...client.Object) (*runtime.Scheme, client.Client, *CheUserNamespaceReconciler) { devworkspace.CleanCheClusterInstancesForTest() infrastructure.InitializeForTesting(infraType) - scheme := createTestScheme() - - cl := fake.NewFakeClientWithScheme(scheme, objs...) + ctx := test.NewCtxBuilder().WithObjects(objs...).WithCheCluster(nil).Build() + cl := ctx.ClusterAPI.Client + scheme := ctx.ClusterAPI.Scheme r := &CheUserNamespaceReconciler{ client: cl, nonCachedClient: cl, scheme: scheme, - namespaceCache: &namespaceCache{ - client: cl, - knownNamespaces: map[string]namespaceInfo{}, - lock: sync.Mutex{}, + namespaceCache: &namespacecache.NamespaceCache{ + Client: cl, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{}, + Lock: sync.Mutex{}, }, } @@ -174,9 +175,9 @@ func setup(infraType devworkspaceinfra.Type, objs ...runtime.Object) (*runtime.S } func TestSkipsUnlabeledNamespaces(t *testing.T) { - test := func(t *testing.T, infraType devworkspaceinfra.Type, namespace metav1.Object) { + test := func(t *testing.T, infraType infrastructure.Type, namespace metav1.Object) { ctx := context.TODO() - scheme, cl, r := setup(infraType, namespace.(runtime.Object)) + scheme, cl, r := setup(infraType, namespace.(client.Object)) setupCheCluster(t, ctx, cl, scheme, "che", "che") if _, err := r.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Name: namespace.GetName()}}); err != nil { @@ -199,7 +200,7 @@ func TestSkipsUnlabeledNamespaces(t *testing.T) { } t.Run("k8s", func(t *testing.T) { - test(t, devworkspaceinfra.Kubernetes, &corev1.Namespace{ + test(t, infrastructure.Kubernetes, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "ns", }, @@ -207,7 +208,7 @@ func TestSkipsUnlabeledNamespaces(t *testing.T) { }) t.Run("openshift", func(t *testing.T) { - test(t, devworkspaceinfra.OpenShiftv4, &projectv1.Project{ + test(t, infrastructure.OpenShiftv4, &projectv1.Project{ ObjectMeta: metav1.ObjectMeta{ Name: "prj", }, @@ -232,9 +233,9 @@ func TestCreatesDataInNamespace(t *testing.T) { }) assert.NoError(t, err) - test := func(t *testing.T, infraType devworkspaceinfra.Type, namespace client.Object, objs ...runtime.Object) { + test := func(t *testing.T, infraType infrastructure.Type, namespace client.Object, objs ...client.Object) { ctx := context.TODO() - allObjs := append(objs, namespace.(runtime.Object)) + allObjs := append(objs, namespace.(client.Object)) scheme, cl, r := setup(infraType, allObjs...) setupCheCluster(t, ctx, cl, scheme, "eclipse-che", "che") @@ -283,23 +284,23 @@ func TestCreatesDataInNamespace(t *testing.T) { } t.Run("k8s", func(t *testing.T) { - test(t, devworkspaceinfra.Kubernetes, &corev1.Namespace{ + test(t, infrastructure.Kubernetes, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "ns", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid", }, }, }) }) t.Run("openshift", func(t *testing.T) { - test(t, devworkspaceinfra.OpenShiftv4, + test(t, infrastructure.OpenShiftv4, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "prj", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid", }, }, }, @@ -307,7 +308,7 @@ func TestCreatesDataInNamespace(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "prj", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid", }, }, }, &configv1.Proxy{ @@ -331,10 +332,10 @@ func TestUpdateSccClusterRoleBinding(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ns1", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid_1", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid_1", }, Annotations: map[string]string{ - cheUsernameAnnotation: "user_1", + namespacecache.CheUsernameAnnotation: "user_1", }, }, } @@ -343,10 +344,10 @@ func TestUpdateSccClusterRoleBinding(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ns1", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid_1", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid_1", }, Annotations: map[string]string{ - cheUsernameAnnotation: "user_1", + namespacecache.CheUsernameAnnotation: "user_1", }, }, } @@ -372,7 +373,7 @@ func TestUpdateSccClusterRoleBinding(t *testing.T) { }, } - allObjs := []runtime.Object{ns1, pr1, cheCluster} + allObjs := []client.Object{ns1, pr1, cheCluster} scheme, cl, usernamespaceReconciler := setup(infrastructure.OpenShiftv4, allObjs...) // the reconciliation needs to run twice for it to be truly finished - we're setting up finalizers etc... @@ -402,11 +403,11 @@ func TestWatchRulesForSecretsInSameNamespace(t *testing.T) { }, } - _, _, r := setup(devworkspaceinfra.Kubernetes, &corev1.Namespace{ + _, _, r := setup(infrastructure.Kubernetes, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "ns", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid", }, }, }, secret) @@ -414,15 +415,15 @@ func TestWatchRulesForSecretsInSameNamespace(t *testing.T) { ctx := context.TODO() h := r.watchRulesForSecrets(ctx) - rlq := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) + rlq := workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[reconcile.Request]()) // Let's throw event to controller about new secret creation. - h.Create(event.CreateEvent{Object: secret}, rlq) + h.Create(context.TODO(), event.CreateEvent{Object: secret}, rlq) amountReconcileRequests := rlq.Len() rs, _ := rlq.Get() assert.Equal(t, 1, amountReconcileRequests) - assert.Equal(t, "ns", rs.(reconcile.Request).Name) + assert.Equal(t, "ns", rs.Name) } func TestWatchRulesForConfigMapsInSameNamespace(t *testing.T) { @@ -434,11 +435,11 @@ func TestWatchRulesForConfigMapsInSameNamespace(t *testing.T) { }, } - _, _, r := setup(devworkspaceinfra.Kubernetes, &corev1.Namespace{ + _, _, r := setup(infrastructure.Kubernetes, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "ns", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid", }, }, }, cm) @@ -446,15 +447,15 @@ func TestWatchRulesForConfigMapsInSameNamespace(t *testing.T) { ctx := context.TODO() h := r.watchRulesForSecrets(ctx) - rlq := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) + rlq := workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[reconcile.Request]()) // Let's throw event to controller about new config map creation. - h.Create(event.CreateEvent{Object: cm}, rlq) + h.Create(context.TODO(), event.CreateEvent{Object: cm}, rlq) amountReconcileRequests := rlq.Len() rs, _ := rlq.Get() assert.Equal(t, 1, amountReconcileRequests) - assert.Equal(t, "ns", rs.(reconcile.Request).Name) + assert.Equal(t, "ns", rs.Name) } func TestWatchRulesForSecretsInOtherNamespaces(t *testing.T) { @@ -469,7 +470,7 @@ func TestWatchRulesForSecretsInOtherNamespaces(t *testing.T) { }, } - _, _, r := setup(devworkspaceinfra.Kubernetes, + _, _, r := setup(infrastructure.Kubernetes, &corev1.Namespace{ TypeMeta: metav1.TypeMeta{ Kind: "Namespace", @@ -478,7 +479,7 @@ func TestWatchRulesForSecretsInOtherNamespaces(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ns1", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid1", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid1", }, }, }, @@ -490,7 +491,7 @@ func TestWatchRulesForSecretsInOtherNamespaces(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ns2", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid2", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid2", }, }, }, @@ -518,15 +519,15 @@ func TestWatchRulesForSecretsInOtherNamespaces(t *testing.T) { r.namespaceCache.ExamineNamespace(ctx, "eclipse-che") h := r.watchRulesForSecrets(ctx) - rlq := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) + rlq := workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[reconcile.Request]()) // Let's throw event to controller about new secret creation. - h.Create(event.CreateEvent{Object: secret}, rlq) + h.Create(context.TODO(), event.CreateEvent{Object: secret}, rlq) amountReconcileRequests := rlq.Len() rs1, _ := rlq.Get() rs2, _ := rlq.Get() rs3, _ := rlq.Get() - reconciles := []reconcile.Request{rs1.(reconcile.Request), rs2.(reconcile.Request), rs3.(reconcile.Request)} + reconciles := []reconcile.Request{rs1, rs2, rs3} assert.Equal(t, 3, amountReconcileRequests) assert.Contains(t, reconciles, reconcile.Request{NamespacedName: types.NamespacedName{Name: "ns1"}}) @@ -546,7 +547,7 @@ func TestWatchRulesForConfigMapsInOtherNamespaces(t *testing.T) { }, } - _, _, r := setup(devworkspaceinfra.Kubernetes, + _, _, r := setup(infrastructure.Kubernetes, &corev1.Namespace{ TypeMeta: metav1.TypeMeta{ Kind: "Namespace", @@ -555,7 +556,7 @@ func TestWatchRulesForConfigMapsInOtherNamespaces(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ns1", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid1", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid1", }, }, }, @@ -567,7 +568,7 @@ func TestWatchRulesForConfigMapsInOtherNamespaces(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "ns2", Labels: map[string]string{ - workspaceNamespaceOwnerUidLabel: "uid2", + namespacecache.WorkspaceNamespaceOwnerUidLabel: "uid2", }, }, }, @@ -595,15 +596,15 @@ func TestWatchRulesForConfigMapsInOtherNamespaces(t *testing.T) { r.namespaceCache.ExamineNamespace(ctx, "eclipse-che") h := r.watchRulesForConfigMaps(ctx) - rlq := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()) + rlq := workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[reconcile.Request]()) // Let's throw event to controller about new config map creation. - h.Create(event.CreateEvent{Object: cm}, rlq) + h.Create(context.TODO(), event.CreateEvent{Object: cm}, rlq) amountReconcileRequests := rlq.Len() rs1, _ := rlq.Get() rs2, _ := rlq.Get() rs3, _ := rlq.Get() - reconciles := []reconcile.Request{rs1.(reconcile.Request), rs2.(reconcile.Request), rs3.(reconcile.Request)} + reconciles := []reconcile.Request{rs1, rs2, rs3} assert.Equal(t, 3, amountReconcileRequests) assert.Contains(t, reconciles, reconcile.Request{NamespacedName: types.NamespacedName{Name: "ns1"}}) diff --git a/controllers/usernamespace/usernamespace_utils.go b/controllers/usernamespace/usernamespace_utils.go deleted file mode 100644 index 3a5b2c96d4..0000000000 --- a/controllers/usernamespace/usernamespace_utils.go +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) 2019-2023 Red Hat, Inc. -// This program and the accompanying materials are made -// available under the terms of the Eclipse Public License 2.0 -// which is available at https://www.eclipse.org/legal/epl-2.0/ -// -// SPDX-License-Identifier: EPL-2.0 -// -// Contributors: -// Red Hat, Inc. - initial API and implementation -// - -package usernamespace - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -type eventRule struct { - check func(metav1.Object) bool - namespaces func(metav1.Object) []string -} - -func asReconcileRequestsForNamespaces(obj metav1.Object, rules []eventRule) []reconcile.Request { - for _, r := range rules { - if r.check(obj) { - nss := r.namespaces(obj) - ret := make([]reconcile.Request, len(nss)) - for i, n := range nss { - ret[i] = reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: n, - }, - } - } - - return ret - } - } - - return []reconcile.Request{} -} diff --git a/controllers/usernamespace/configmap2sync.go b/controllers/workspaceconfig/configmap2sync.go similarity index 98% rename from controllers/usernamespace/configmap2sync.go rename to controllers/workspaceconfig/configmap2sync.go index 8034713aca..760869bf10 100644 --- a/controllers/usernamespace/configmap2sync.go +++ b/controllers/workspaceconfig/configmap2sync.go @@ -10,7 +10,7 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( dwconstants "github.com/devfile/devworkspace-operator/pkg/constants" diff --git a/controllers/usernamespace/configmap2sync_test.go b/controllers/workspaceconfig/configmap2sync_test.go similarity index 87% rename from controllers/usernamespace/configmap2sync_test.go rename to controllers/workspaceconfig/configmap2sync_test.go index d716e8e285..29aee7f446 100644 --- a/controllers/usernamespace/configmap2sync_test.go +++ b/controllers/workspaceconfig/configmap2sync_test.go @@ -10,13 +10,15 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "context" "sync" "testing" + "github.com/eclipse-che/che-operator/controllers/namespacecache" + dwconstants "github.com/devfile/devworkspace-operator/pkg/constants" "github.com/eclipse-che/che-operator/pkg/common/constants" @@ -26,7 +28,6 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/pointer" "k8s.io/apimachinery/pkg/runtime/schema" @@ -47,41 +48,40 @@ var ( ) func TestSyncConfigMap(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{ - &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", + deployContext := test.NewCtxBuilder().WithObjects(&corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: objectName, + Namespace: "eclipse-che", + Labels: map[string]string{ + constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, + constants.KubernetesComponentLabelKey: constants.WorkspacesConfig, }, - ObjectMeta: metav1.ObjectMeta{ - Name: objectName, - Namespace: "eclipse-che", - Labels: map[string]string{ - constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, - constants.KubernetesComponentLabelKey: constants.WorkspacesConfig, - }, - Annotations: map[string]string{}, - }, - Data: map[string]string{ - "a": "b", - }, - Immutable: pointer.Bool(false), - }}) + Annotations: map[string]string{}, + }, + Data: map[string]string{ + "a": "b", + }, + Immutable: pointer.Bool(false), + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) // Sync ConfigMap @@ -212,43 +212,42 @@ func TestSyncConfigMap(t *testing.T) { } func TestSyncConfigMapShouldMergeLabelsAndAnnotationsOnUpdate(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{ - &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", + deployContext := test.NewCtxBuilder().WithObjects(&corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: objectName, + Namespace: "eclipse-che", + Labels: map[string]string{ + "label": "label-value", + constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, + constants.KubernetesComponentLabelKey: constants.WorkspacesConfig, }, - ObjectMeta: metav1.ObjectMeta{ - Name: objectName, - Namespace: "eclipse-che", - Labels: map[string]string{ - "label": "label-value", - constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, - constants.KubernetesComponentLabelKey: constants.WorkspacesConfig, - }, - Annotations: map[string]string{ - "annotation": "annotation-value", - }, + Annotations: map[string]string{ + "annotation": "annotation-value", }, - Data: map[string]string{ - "a": "b", - }, - }}) + }, + Data: map[string]string{ + "a": "b", + }, + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) // Sync ConfigMap @@ -335,38 +334,37 @@ func assertSyncConfig(t *testing.T, workspaceConfigReconciler *WorkspacesConfigR } func TestSyncConfigMapShouldRespectDWOLabels(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{ - &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: objectName, - Namespace: "eclipse-che", - Labels: map[string]string{ - constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, - constants.KubernetesComponentLabelKey: constants.WorkspacesConfig, - dwconstants.DevWorkspaceWatchConfigMapLabel: "false", - dwconstants.DevWorkspaceMountLabel: "false", - }, + deployContext := test.NewCtxBuilder().WithObjects(&corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: objectName, + Namespace: "eclipse-che", + Labels: map[string]string{ + constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg, + constants.KubernetesComponentLabelKey: constants.WorkspacesConfig, + dwconstants.DevWorkspaceWatchConfigMapLabel: "false", + dwconstants.DevWorkspaceMountLabel: "false", }, - }}) + }, + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) // Sync ConfigMap @@ -433,7 +431,7 @@ func TestSyncConfigMapShouldRespectDWOLabels(t *testing.T) { } func TestSyncConfigMapShouldRemoveSomeLabels(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{ + deployContext := test.NewCtxBuilder().WithObjects( &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -449,22 +447,22 @@ func TestSyncConfigMapShouldRemoveSomeLabels(t *testing.T) { "argocd.argoproj.io/managed-by": "argocd", }, }, - }}) + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) // Sync ConfigMap diff --git a/controllers/workspaceconfig/init_test.go b/controllers/workspaceconfig/init_test.go new file mode 100644 index 0000000000..26613fb7e1 --- /dev/null +++ b/controllers/workspaceconfig/init_test.go @@ -0,0 +1,26 @@ +// +// Copyright (c) 2019-2023 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// + +package workspace_config + +import ( + "github.com/devfile/devworkspace-operator/pkg/infrastructure" + defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" + "github.com/eclipse-che/che-operator/pkg/common/test" +) + +func init() { + test.EnableTestMode() + + infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + defaults.InitializeForTesting("../../config/manager/manager.yaml") +} diff --git a/controllers/usernamespace/object2sync_factory.go b/controllers/workspaceconfig/object2sync_factory.go similarity index 99% rename from controllers/usernamespace/object2sync_factory.go rename to controllers/workspaceconfig/object2sync_factory.go index cdbfc0f42b..16110bb9ce 100644 --- a/controllers/usernamespace/object2sync_factory.go +++ b/controllers/workspaceconfig/object2sync_factory.go @@ -10,7 +10,7 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "strings" diff --git a/controllers/usernamespace/pvc2sync.go b/controllers/workspaceconfig/pvc2sync.go similarity index 98% rename from controllers/usernamespace/pvc2sync.go rename to controllers/workspaceconfig/pvc2sync.go index 977d609198..9256d6e626 100644 --- a/controllers/usernamespace/pvc2sync.go +++ b/controllers/workspaceconfig/pvc2sync.go @@ -10,7 +10,7 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( corev1 "k8s.io/api/core/v1" diff --git a/controllers/usernamespace/pvc2sync_test.go b/controllers/workspaceconfig/pvc2sync_test.go similarity index 93% rename from controllers/usernamespace/pvc2sync_test.go rename to controllers/workspaceconfig/pvc2sync_test.go index 3bf1a690f1..016bd7ce75 100644 --- a/controllers/usernamespace/pvc2sync_test.go +++ b/controllers/workspaceconfig/pvc2sync_test.go @@ -10,13 +10,15 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "context" "sync" "testing" + "github.com/eclipse-che/che-operator/controllers/namespacecache" + "k8s.io/apimachinery/pkg/types" "github.com/eclipse-che/che-operator/pkg/deploy" @@ -28,11 +30,10 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" ) func TestSyncPVC(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{ + deployContext := test.NewCtxBuilder().WithObjects( &corev1.PersistentVolumeClaim{ TypeMeta: metav1.TypeMeta{ Kind: "PersistentVolumeClaim", @@ -47,28 +48,28 @@ func TestSyncPVC(t *testing.T) { }, }, Spec: corev1.PersistentVolumeClaimSpec{ - Resources: corev1.ResourceRequirements{ + Resources: corev1.VolumeResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceStorage: resource.MustParse("1Gi"), }, }, }, - }}) + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) assertSyncConfig(t, workspaceConfigReconciler, 0, v1PvcGKV) diff --git a/controllers/usernamespace/secret2sync.go b/controllers/workspaceconfig/secret2sync.go similarity index 98% rename from controllers/usernamespace/secret2sync.go rename to controllers/workspaceconfig/secret2sync.go index e7408cb009..1f976bd07c 100644 --- a/controllers/usernamespace/secret2sync.go +++ b/controllers/workspaceconfig/secret2sync.go @@ -10,7 +10,7 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( dwconstants "github.com/devfile/devworkspace-operator/pkg/constants" diff --git a/controllers/usernamespace/secret2sync_test.go b/controllers/workspaceconfig/secret2sync_test.go similarity index 94% rename from controllers/usernamespace/secret2sync_test.go rename to controllers/workspaceconfig/secret2sync_test.go index a650ae06d9..bbfe4e77aa 100644 --- a/controllers/usernamespace/secret2sync_test.go +++ b/controllers/workspaceconfig/secret2sync_test.go @@ -10,13 +10,15 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "context" "sync" "testing" + "github.com/eclipse-che/che-operator/controllers/namespacecache" + dwconstants "github.com/devfile/devworkspace-operator/pkg/constants" "k8s.io/apimachinery/pkg/types" @@ -31,12 +33,11 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/pointer" ) func TestSyncSecrets(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{ + deployContext := test.NewCtxBuilder().WithObjects( &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -57,22 +58,22 @@ func TestSyncSecrets(t *testing.T) { "c": []byte("d"), }, Immutable: pointer.Bool(false), - }}) + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) // Sync Secret @@ -212,7 +213,7 @@ func TestSyncSecrets(t *testing.T) { } func TestSyncSecretShouldMergeLabelsAndAnnotationsOnUpdate(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{ + deployContext := test.NewCtxBuilder().WithObjects( &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -233,22 +234,22 @@ func TestSyncSecretShouldMergeLabelsAndAnnotationsOnUpdate(t *testing.T) { StringData: map[string]string{ "a": "b", }, - }}) + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) // Sync Secret @@ -325,7 +326,7 @@ func TestSyncSecretShouldMergeLabelsAndAnnotationsOnUpdate(t *testing.T) { } func TestSyncSecretShouldRespectDWOLabels(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{ + deployContext := test.NewCtxBuilder().WithObjects( &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -340,22 +341,22 @@ func TestSyncSecretShouldRespectDWOLabels(t *testing.T) { dwconstants.DevWorkspaceWatchSecretLabel: "false", dwconstants.DevWorkspaceMountLabel: "false"}, }, - }}) + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) // Sync Secret @@ -424,7 +425,7 @@ func TestSyncSecretShouldRespectDWOLabels(t *testing.T) { } func TestSyncSecretShouldRemoveSomeLabels(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{ + deployContext := test.NewCtxBuilder().WithObjects( &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -439,22 +440,22 @@ func TestSyncSecretShouldRemoveSomeLabels(t *testing.T) { "argocd.argoproj.io/instance": "argocd", "argocd.argoproj.io/managed-by": "argocd"}, }, - }}) + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) // Sync Secret diff --git a/controllers/usernamespace/unstructured2sync.go b/controllers/workspaceconfig/unstructured2sync.go similarity index 97% rename from controllers/usernamespace/unstructured2sync.go rename to controllers/workspaceconfig/unstructured2sync.go index d2115b7d22..0d0fed257c 100644 --- a/controllers/usernamespace/unstructured2sync.go +++ b/controllers/workspaceconfig/unstructured2sync.go @@ -10,7 +10,7 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/controllers/usernamespace/unstructured2sync_test.go b/controllers/workspaceconfig/unstructured2sync_test.go similarity index 95% rename from controllers/usernamespace/unstructured2sync_test.go rename to controllers/workspaceconfig/unstructured2sync_test.go index 8d51f7ad4a..4cc6a7fe28 100644 --- a/controllers/usernamespace/unstructured2sync_test.go +++ b/controllers/workspaceconfig/unstructured2sync_test.go @@ -10,16 +10,17 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "context" "sync" "testing" + "github.com/eclipse-che/che-operator/controllers/namespacecache" + "k8s.io/apimachinery/pkg/types" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" "github.com/eclipse-che/che-operator/pkg/deploy" templatev1 "github.com/openshift/api/template/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -39,9 +40,7 @@ var ( ) func TestSyncTemplateWithLimitRange(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - deployContext := test.GetDeployContext(nil, []runtime.Object{ + deployContext := test.NewCtxBuilder().WithObjects( &templatev1.Template{ TypeMeta: metav1.TypeMeta{ Kind: "Template", @@ -79,22 +78,22 @@ func TestSyncTemplateWithLimitRange(t *testing.T) { }, }, }, - }}) + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Client, deployContext.ClusterAPI.Scheme, - &namespaceCache{ - client: deployContext.ClusterAPI.Client, - knownNamespaces: map[string]namespaceInfo{ + &namespacecache.NamespaceCache{ + Client: deployContext.ClusterAPI.Client, + KnownNamespaces: map[string]namespacecache.NamespaceInfo{ userNamespace: { IsWorkspaceNamespace: true, Username: "user", CheCluster: &types.NamespacedName{Name: "eclipse-che", Namespace: "eclipse-che"}, }, }, - lock: sync.Mutex{}, + Lock: sync.Mutex{}, }) // Sync Template diff --git a/controllers/usernamespace/workspaces_config_controller.go b/controllers/workspaceconfig/workspaces_config_controller.go similarity index 92% rename from controllers/usernamespace/workspaces_config_controller.go rename to controllers/workspaceconfig/workspaces_config_controller.go index 837528adca..bb0b426144 100644 --- a/controllers/usernamespace/workspaces_config_controller.go +++ b/controllers/workspaceconfig/workspaces_config_controller.go @@ -10,7 +10,7 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "context" @@ -19,6 +19,10 @@ import ( "regexp" "strings" + "github.com/eclipse-che/che-operator/controllers/namespacecache" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/controller" + networkingv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/api/meta" @@ -40,7 +44,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" ) const ( @@ -51,7 +54,7 @@ type WorkspacesConfigReconciler struct { scheme *runtime.Scheme client client.Client nonCachedClient client.Client - namespaceCache *namespaceCache + namespaceCache *namespacecache.NamespaceCache labelsToRemoveBeforeSync []*regexp.Regexp annotationsToRemoveBeforeSync []*regexp.Regexp } @@ -90,7 +93,7 @@ func NewWorkspacesConfigReconciler( client client.Client, nonCachedClient client.Client, scheme *runtime.Scheme, - namespaceCache *namespaceCache) *WorkspacesConfigReconciler { + namespaceCache *namespacecache.NamespaceCache) *WorkspacesConfigReconciler { labelsToRemoveBeforeSyncAsString := os.Getenv(envLabelsToRemoveBeforeSync) annotationsToRemoveBeforeSyncAsString := os.Getenv(envAnnotationsToRemoveBeforeSync) @@ -125,21 +128,25 @@ func (r *WorkspacesConfigReconciler) SetupWithManager(mgr ctrl.Manager) error { ctx := context.Background() bld := ctrl.NewControllerManagedBy(mgr). For(&corev1.Namespace{}). - Watches(&source.Kind{Type: &corev1.PersistentVolumeClaim{}}, r.watchRules(ctx, true, true)). - Watches(&source.Kind{Type: &corev1.Secret{}}, r.watchRules(ctx, true, true)). - Watches(&source.Kind{Type: &corev1.ConfigMap{}}, r.watchRules(ctx, true, true)). - Watches(&source.Kind{Type: &corev1.ResourceQuota{}}, r.watchRules(ctx, false, true)). - Watches(&source.Kind{Type: &corev1.LimitRange{}}, r.watchRules(ctx, false, true)). - Watches(&source.Kind{Type: &corev1.ServiceAccount{}}, r.watchRules(ctx, false, true)). - Watches(&source.Kind{Type: &rbacv1.Role{}}, r.watchRules(ctx, false, true)). - Watches(&source.Kind{Type: &rbacv1.RoleBinding{}}, r.watchRules(ctx, false, true)). - Watches(&source.Kind{Type: &networkingv1.NetworkPolicy{}}, r.watchRules(ctx, false, true)) + Watches(&corev1.PersistentVolumeClaim{}, r.watchRules(ctx, true, true)). + Watches(&corev1.Secret{}, r.watchRules(ctx, true, true)). + Watches(&corev1.ConfigMap{}, r.watchRules(ctx, true, true)). + Watches(&corev1.ResourceQuota{}, r.watchRules(ctx, false, true)). + Watches(&corev1.LimitRange{}, r.watchRules(ctx, false, true)). + Watches(&corev1.ServiceAccount{}, r.watchRules(ctx, false, true)). + Watches(&rbacv1.Role{}, r.watchRules(ctx, false, true)). + Watches(&rbacv1.RoleBinding{}, r.watchRules(ctx, false, true)). + Watches(&networkingv1.NetworkPolicy{}, r.watchRules(ctx, false, true)) if infrastructure.IsOpenShift() { - bld.Watches(&source.Kind{Type: &templatev1.Template{}}, r.watchRules(ctx, true, false)) + bld.Watches(&templatev1.Template{}, r.watchRules(ctx, true, false)) } - return bld.Complete(r) + // Use controller.TypedOptions to allow to configure 2 controllers for same object being reconciled + return bld.WithOptions( + controller.TypedOptions[reconcile.Request]{ + SkipNameValidation: pointer.Bool(true), + }).Complete(r) } func (r *WorkspacesConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { @@ -186,41 +193,41 @@ func (r *WorkspacesConfigReconciler) watchRules( userNamespaceRule bool, ) handler.EventHandler { return handler.EnqueueRequestsFromMapFunc( - func(obj client.Object) []reconcile.Request { - var eventRules []eventRule + func(context context.Context, obj client.Object) []reconcile.Request { + var eventRules []namespacecache.EventRule if cheNamespaceRule { eventRules = append(eventRules, - eventRule{ + namespacecache.EventRule{ // reconcile rule when workspace config is modified in a che namespace // to update the config in all users` namespaces - check: func(o metav1.Object) bool { + Check: func(o metav1.Object) bool { cheCluster, _ := deploy.FindCheClusterCRInNamespace(r.client, o.GetNamespace()) return hasWSConfigComponentLabels(o) && cheCluster != nil }, - namespaces: func(o metav1.Object) []string { return r.namespaceCache.GetAllKnownNamespaces() }, + Namespaces: func(o metav1.Object) []string { return r.namespaceCache.GetAllKnownNamespaces() }, }, ) } if userNamespaceRule { eventRules = append(eventRules, - eventRule{ + namespacecache.EventRule{ // reconcile rule when workspace config is modified in a user namespace // to revert the config - check: func(o metav1.Object) bool { + Check: func(o metav1.Object) bool { workspaceInfo, _ := r.namespaceCache.GetNamespaceInfo(ctx, o.GetNamespace()) return hasWSConfigComponentLabels(o) && o.GetName() != syncedWorkspacesConfig && workspaceInfo != nil && workspaceInfo.IsWorkspaceNamespace }, - namespaces: func(o metav1.Object) []string { return []string{o.GetNamespace()} }, + Namespaces: func(o metav1.Object) []string { return []string{o.GetNamespace()} }, }, ) } - return asReconcileRequestsForNamespaces(obj, eventRules) + return namespacecache.AsReconcileRequestsForNamespaces(obj, eventRules) }) } diff --git a/controllers/usernamespace/workspaces_config_controller_test.go b/controllers/workspaceconfig/workspaces_config_controller_test.go similarity index 91% rename from controllers/usernamespace/workspaces_config_controller_test.go rename to controllers/workspaceconfig/workspaces_config_controller_test.go index 34f0571a03..c3fef45781 100644 --- a/controllers/usernamespace/workspaces_config_controller_test.go +++ b/controllers/workspaceconfig/workspaces_config_controller_test.go @@ -10,20 +10,21 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "context" "fmt" "testing" + "github.com/eclipse-che/che-operator/controllers/namespacecache" + rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/runtime/schema" "github.com/eclipse-che/che-operator/pkg/common/constants" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/eclipse-che/che-operator/pkg/deploy" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "github.com/stretchr/testify/assert" @@ -62,13 +63,13 @@ func TestRecreateObjectIfAlreadyExists(t *testing.T) { }, } - ctx := test.GetDeployContext(nil, []runtime.Object{srcObject}) + ctx := test.NewCtxBuilder().Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( ctx.ClusterAPI.Client, ctx.ClusterAPI.Client, ctx.ClusterAPI.Scheme, - NewNamespaceCache(ctx.ClusterAPI.NonCachingClient)) + namespacecache.NewNamespaceCache(ctx.ClusterAPI.NonCachingClient)) syncContext := &syncContext{ dstNamespace: "user-che", @@ -89,24 +90,22 @@ func TestRecreateObjectIfAlreadyExists(t *testing.T) { } func TestDeleteIfObjectIsObsolete(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{ - &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "test_1", - Namespace: "user-che", - }, + ctx := test.NewCtxBuilder().WithObjects(&corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test_1", + Namespace: "user-che", }, - }) + }).Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( ctx.ClusterAPI.Client, ctx.ClusterAPI.Client, ctx.ClusterAPI.Scheme, - NewNamespaceCache(ctx.ClusterAPI.NonCachingClient)) + namespacecache.NewNamespaceCache(ctx.ClusterAPI.NonCachingClient)) test1CMInUserNS := buildKey(v1ConfigMapGKV, "test_1", "user-che") test2CMInUserNS := buildKey(v1ConfigMapGKV, "test_2", "user-che") @@ -158,13 +157,13 @@ func TestDeleteIfObjectIsObsolete(t *testing.T) { } func TestGetEmptySyncConfig(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() workspaceConfigReconciler := NewWorkspacesConfigReconciler( ctx.ClusterAPI.Client, ctx.ClusterAPI.Client, ctx.ClusterAPI.Scheme, - NewNamespaceCache(ctx.ClusterAPI.NonCachingClient)) + namespacecache.NewNamespaceCache(ctx.ClusterAPI.NonCachingClient)) cm, err := workspaceConfigReconciler.getSyncConfig(context.TODO(), "eclipse-che") assert.NoError(t, err) diff --git a/controllers/usernamespace/workspaces_config_diff_helper.go b/controllers/workspaceconfig/workspaces_config_diff_helper.go similarity index 99% rename from controllers/usernamespace/workspaces_config_diff_helper.go rename to controllers/workspaceconfig/workspaces_config_diff_helper.go index 2b6b0a1efd..bfb54718b5 100644 --- a/controllers/usernamespace/workspaces_config_diff_helper.go +++ b/controllers/workspaceconfig/workspaces_config_diff_helper.go @@ -10,7 +10,7 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "encoding/json" diff --git a/controllers/usernamespace/workspaces_config_diff_helper_test.go b/controllers/workspaceconfig/workspaces_config_diff_helper_test.go similarity index 98% rename from controllers/usernamespace/workspaces_config_diff_helper_test.go rename to controllers/workspaceconfig/workspaces_config_diff_helper_test.go index 1d191e4d41..2c2cebb7d8 100644 --- a/controllers/usernamespace/workspaces_config_diff_helper_test.go +++ b/controllers/workspaceconfig/workspaces_config_diff_helper_test.go @@ -10,7 +10,7 @@ // Red Hat, Inc. - initial API and implementation // -package usernamespace +package workspace_config import ( "testing" diff --git a/deploy/deployment/kubernetes/combined.yaml b/deploy/deployment/kubernetes/combined.yaml index ad66130a0e..afb2a9767f 100644 --- a/deploy/deployment/kubernetes/combined.yaml +++ b/deploy/deployment/kubernetes/combined.yaml @@ -20,7 +20,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: eclipse-che/che-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.18.0 labels: app.kubernetes.io/instance: che app.kubernetes.io/name: che @@ -142,10 +142,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -205,10 +208,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -257,10 +263,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -320,10 +329,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -376,10 +388,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -439,10 +454,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -491,10 +509,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -554,10 +575,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -880,10 +904,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -943,10 +970,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1031,10 +1061,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1094,10 +1127,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1413,10 +1449,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1476,10 +1515,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1589,10 +1631,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1652,10 +1697,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1772,10 +1820,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1835,10 +1886,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2008,10 +2062,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -2071,10 +2128,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2291,7 +2351,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2300,7 +2359,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2314,7 +2372,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -2330,13 +2387,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2345,20 +2399,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2377,27 +2427,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2426,13 +2469,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -2456,7 +2496,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -2523,7 +2562,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -2595,7 +2633,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -2633,7 +2670,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2649,13 +2685,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2664,20 +2697,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2696,27 +2725,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2772,7 +2794,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2788,13 +2809,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2803,20 +2821,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2835,27 +2849,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2897,7 +2904,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -2914,13 +2920,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -3014,13 +3018,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -3068,7 +3069,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -3080,13 +3080,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -3147,7 +3144,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3156,7 +3152,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3170,7 +3165,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -3187,13 +3181,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3201,20 +3192,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3232,27 +3219,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3280,13 +3260,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -3309,7 +3286,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -3351,7 +3327,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -3423,7 +3398,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -3460,7 +3434,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3477,13 +3450,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3491,20 +3461,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3522,27 +3488,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3598,7 +3557,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3615,13 +3573,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3629,20 +3584,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3660,27 +3611,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -4114,10 +4058,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4181,10 +4128,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4447,10 +4397,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4514,10 +4467,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4746,10 +4702,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4813,10 +4772,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5085,10 +5047,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -5152,10 +5117,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5377,6 +5345,8 @@ spec: description: OpenShift security context constraint to build containers. type: string + required: + - openShiftSecurityContextConstraint type: object defaultComponents: description: |- @@ -5423,7 +5393,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5432,7 +5401,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5446,7 +5414,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -5462,13 +5429,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5477,20 +5441,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5509,27 +5469,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5558,13 +5511,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -5588,7 +5538,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -5655,7 +5604,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -5727,7 +5675,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -5765,7 +5712,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5781,13 +5727,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5796,20 +5739,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5828,27 +5767,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5904,7 +5836,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5920,13 +5851,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5935,20 +5863,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5967,27 +5891,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6029,7 +5946,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -6046,13 +5962,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -6146,13 +6060,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -6200,7 +6111,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -6212,13 +6122,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -6279,7 +6186,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6288,7 +6194,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6302,7 +6207,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -6319,13 +6223,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6333,20 +6234,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6364,27 +6261,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6412,13 +6302,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -6441,7 +6328,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -6483,7 +6369,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -6555,7 +6440,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -6592,7 +6476,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6609,13 +6492,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6623,20 +6503,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6654,27 +6530,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6730,7 +6599,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6747,13 +6615,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6761,20 +6626,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6792,27 +6653,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6988,7 +6842,6 @@ spec: When set to `false` (the default value), the devEnvironments.security.containerSecurityContext field is ignored, and the following container SecurityContext is applied: - containerSecurityContext: allowPrivilegeEscalation: true capabilities: @@ -7032,10 +6885,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7095,10 +6951,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7296,10 +7155,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7359,10 +7221,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7487,6 +7352,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7500,6 +7389,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7507,6 +7397,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7518,7 +7409,7 @@ spec: procMount: description: |- procMount denotes the type of proc mount to use for the containers. - The default is DefaultProcMount which uses the container runtime defaults for + The default value is Default which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. @@ -7593,14 +7484,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7628,12 +7518,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7649,17 +7536,38 @@ spec: PodSecurityContext used by all workspace-related pods. If set, defined values are merged into the default PodSecurityContext configuration. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- 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: - 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) - If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows. format: int64 @@ -7703,6 +7611,32 @@ spec: Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string seLinuxOptions: description: |- The SELinux context to be applied to all containers. @@ -7739,14 +7673,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7756,17 +7689,28 @@ spec: type: object supplementalGroups: description: |- - 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. + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -7787,6 +7731,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -7807,12 +7752,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7904,7 +7846,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -7930,7 +7871,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -8251,10 +8191,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -8321,10 +8264,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -9323,7 +9269,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service @@ -9357,7 +9302,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service diff --git a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 578336c5e8..c60aa8d6cd 100644 --- a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -15,7 +15,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: eclipse-che/che-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.18.0 labels: app.kubernetes.io/instance: che app.kubernetes.io/name: che @@ -137,10 +137,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -200,10 +203,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -252,10 +258,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -315,10 +324,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -371,10 +383,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -434,10 +449,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -486,10 +504,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -549,10 +570,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -875,10 +899,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -938,10 +965,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1026,10 +1056,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1089,10 +1122,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1408,10 +1444,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1471,10 +1510,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1584,10 +1626,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1647,10 +1692,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1767,10 +1815,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1830,10 +1881,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2003,10 +2057,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -2066,10 +2123,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2286,7 +2346,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2295,7 +2354,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2309,7 +2367,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -2325,13 +2382,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2340,20 +2394,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2372,27 +2422,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2421,13 +2464,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -2451,7 +2491,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -2518,7 +2557,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -2590,7 +2628,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -2628,7 +2665,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2644,13 +2680,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2659,20 +2692,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2691,27 +2720,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2767,7 +2789,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2783,13 +2804,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2798,20 +2816,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2830,27 +2844,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2892,7 +2899,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -2909,13 +2915,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -3009,13 +3013,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -3063,7 +3064,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -3075,13 +3075,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -3142,7 +3139,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3151,7 +3147,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3165,7 +3160,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -3182,13 +3176,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3196,20 +3187,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3227,27 +3214,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3275,13 +3255,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -3304,7 +3281,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -3346,7 +3322,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -3418,7 +3393,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -3455,7 +3429,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3472,13 +3445,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3486,20 +3456,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3517,27 +3483,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3593,7 +3552,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3610,13 +3568,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3624,20 +3579,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3655,27 +3606,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -4109,10 +4053,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4176,10 +4123,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4442,10 +4392,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4509,10 +4462,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4741,10 +4697,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4808,10 +4767,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5080,10 +5042,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -5147,10 +5112,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5372,6 +5340,8 @@ spec: description: OpenShift security context constraint to build containers. type: string + required: + - openShiftSecurityContextConstraint type: object defaultComponents: description: |- @@ -5418,7 +5388,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5427,7 +5396,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5441,7 +5409,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -5457,13 +5424,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5472,20 +5436,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5504,27 +5464,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5553,13 +5506,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -5583,7 +5533,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -5650,7 +5599,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -5722,7 +5670,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -5760,7 +5707,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5776,13 +5722,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5791,20 +5734,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5823,27 +5762,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5899,7 +5831,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5915,13 +5846,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5930,20 +5858,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5962,27 +5886,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6024,7 +5941,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -6041,13 +5957,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -6141,13 +6055,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -6195,7 +6106,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -6207,13 +6117,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -6274,7 +6181,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6283,7 +6189,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6297,7 +6202,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -6314,13 +6218,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6328,20 +6229,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6359,27 +6256,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6407,13 +6297,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -6436,7 +6323,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -6478,7 +6364,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -6550,7 +6435,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -6587,7 +6471,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6604,13 +6487,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6618,20 +6498,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6649,27 +6525,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6725,7 +6594,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6742,13 +6610,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6756,20 +6621,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6787,27 +6648,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6983,7 +6837,6 @@ spec: When set to `false` (the default value), the devEnvironments.security.containerSecurityContext field is ignored, and the following container SecurityContext is applied: - containerSecurityContext: allowPrivilegeEscalation: true capabilities: @@ -7027,10 +6880,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7090,10 +6946,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7291,10 +7150,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7354,10 +7216,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7482,6 +7347,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7495,6 +7384,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7502,6 +7392,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7513,7 +7404,7 @@ spec: procMount: description: |- procMount denotes the type of proc mount to use for the containers. - The default is DefaultProcMount which uses the container runtime defaults for + The default value is Default which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. @@ -7588,14 +7479,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7623,12 +7513,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7644,17 +7531,38 @@ spec: PodSecurityContext used by all workspace-related pods. If set, defined values are merged into the default PodSecurityContext configuration. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- 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: - 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) - If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows. format: int64 @@ -7698,6 +7606,32 @@ spec: Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string seLinuxOptions: description: |- The SELinux context to be applied to all containers. @@ -7734,14 +7668,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7751,17 +7684,28 @@ spec: type: object supplementalGroups: description: |- - 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. + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -7782,6 +7726,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -7802,12 +7747,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7899,7 +7841,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -7925,7 +7866,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -8246,10 +8186,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -8316,10 +8259,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the diff --git a/deploy/deployment/kubernetes/objects/org.eclipse.che.MutatingWebhookConfiguration.yaml b/deploy/deployment/kubernetes/objects/org.eclipse.che.MutatingWebhookConfiguration.yaml index 4fa8fd4521..30348ac5fb 100644 --- a/deploy/deployment/kubernetes/objects/org.eclipse.che.MutatingWebhookConfiguration.yaml +++ b/deploy/deployment/kubernetes/objects/org.eclipse.che.MutatingWebhookConfiguration.yaml @@ -24,7 +24,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service diff --git a/deploy/deployment/kubernetes/objects/org.eclipse.che.ValidatingWebhookConfiguration.yaml b/deploy/deployment/kubernetes/objects/org.eclipse.che.ValidatingWebhookConfiguration.yaml index 39b0ff6bf7..bb92bcff69 100644 --- a/deploy/deployment/kubernetes/objects/org.eclipse.che.ValidatingWebhookConfiguration.yaml +++ b/deploy/deployment/kubernetes/objects/org.eclipse.che.ValidatingWebhookConfiguration.yaml @@ -24,7 +24,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service diff --git a/deploy/deployment/openshift/combined.yaml b/deploy/deployment/openshift/combined.yaml index 036c27cf1e..6b4cbc6bb7 100644 --- a/deploy/deployment/openshift/combined.yaml +++ b/deploy/deployment/openshift/combined.yaml @@ -19,7 +19,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.18.0 service.beta.openshift.io/inject-cabundle: "true" labels: app.kubernetes.io/instance: che @@ -142,10 +142,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -205,10 +208,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -257,10 +263,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -320,10 +329,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -376,10 +388,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -439,10 +454,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -491,10 +509,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -554,10 +575,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -880,10 +904,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -943,10 +970,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1031,10 +1061,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1094,10 +1127,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1413,10 +1449,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1476,10 +1515,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1589,10 +1631,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1652,10 +1697,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1772,10 +1820,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1835,10 +1886,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2008,10 +2062,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -2071,10 +2128,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2291,7 +2351,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2300,7 +2359,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2314,7 +2372,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -2330,13 +2387,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2345,20 +2399,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2377,27 +2427,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2426,13 +2469,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -2456,7 +2496,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -2523,7 +2562,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -2595,7 +2633,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -2633,7 +2670,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2649,13 +2685,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2664,20 +2697,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2696,27 +2725,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2772,7 +2794,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2788,13 +2809,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2803,20 +2821,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2835,27 +2849,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2897,7 +2904,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -2914,13 +2920,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -3014,13 +3018,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -3068,7 +3069,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -3080,13 +3080,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -3147,7 +3144,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3156,7 +3152,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3170,7 +3165,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -3187,13 +3181,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3201,20 +3192,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3232,27 +3219,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3280,13 +3260,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -3309,7 +3286,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -3351,7 +3327,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -3423,7 +3398,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -3460,7 +3434,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3477,13 +3450,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3491,20 +3461,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3522,27 +3488,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3598,7 +3557,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3615,13 +3573,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3629,20 +3584,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3660,27 +3611,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -4114,10 +4058,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4181,10 +4128,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4447,10 +4397,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4514,10 +4467,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4746,10 +4702,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4813,10 +4772,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5085,10 +5047,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -5152,10 +5117,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5377,6 +5345,8 @@ spec: description: OpenShift security context constraint to build containers. type: string + required: + - openShiftSecurityContextConstraint type: object defaultComponents: description: |- @@ -5423,7 +5393,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5432,7 +5401,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5446,7 +5414,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -5462,13 +5429,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5477,20 +5441,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5509,27 +5469,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5558,13 +5511,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -5588,7 +5538,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -5655,7 +5604,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -5727,7 +5675,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -5765,7 +5712,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5781,13 +5727,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5796,20 +5739,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5828,27 +5767,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5904,7 +5836,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5920,13 +5851,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5935,20 +5863,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5967,27 +5891,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6029,7 +5946,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -6046,13 +5962,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -6146,13 +6060,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -6200,7 +6111,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -6212,13 +6122,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -6279,7 +6186,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6288,7 +6194,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6302,7 +6207,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -6319,13 +6223,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6333,20 +6234,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6364,27 +6261,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6412,13 +6302,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -6441,7 +6328,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -6483,7 +6369,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -6555,7 +6440,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -6592,7 +6476,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6609,13 +6492,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6623,20 +6503,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6654,27 +6530,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6730,7 +6599,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6747,13 +6615,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6761,20 +6626,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6792,27 +6653,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6988,7 +6842,6 @@ spec: When set to `false` (the default value), the devEnvironments.security.containerSecurityContext field is ignored, and the following container SecurityContext is applied: - containerSecurityContext: allowPrivilegeEscalation: true capabilities: @@ -7032,10 +6885,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7095,10 +6951,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7296,10 +7155,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7359,10 +7221,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7487,6 +7352,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7500,6 +7389,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7507,6 +7397,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7518,7 +7409,7 @@ spec: procMount: description: |- procMount denotes the type of proc mount to use for the containers. - The default is DefaultProcMount which uses the container runtime defaults for + The default value is Default which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. @@ -7593,14 +7484,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7628,12 +7518,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7649,17 +7536,38 @@ spec: PodSecurityContext used by all workspace-related pods. If set, defined values are merged into the default PodSecurityContext configuration. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- 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: - 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) - If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows. format: int64 @@ -7703,6 +7611,32 @@ spec: Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string seLinuxOptions: description: |- The SELinux context to be applied to all containers. @@ -7739,14 +7673,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7756,17 +7689,28 @@ spec: type: object supplementalGroups: description: |- - 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. + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -7787,6 +7731,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -7807,12 +7752,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7904,7 +7846,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -7930,7 +7871,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -8251,10 +8191,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -8321,10 +8264,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -9281,7 +9227,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service @@ -9315,7 +9260,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service diff --git a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 05bf3a0bff..7195ae69e6 100644 --- a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -14,7 +14,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.18.0 service.beta.openshift.io/inject-cabundle: "true" labels: app.kubernetes.io/instance: che @@ -137,10 +137,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -200,10 +203,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -252,10 +258,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -315,10 +324,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -371,10 +383,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -434,10 +449,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -486,10 +504,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -549,10 +570,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -875,10 +899,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -938,10 +965,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1026,10 +1056,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1089,10 +1122,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1408,10 +1444,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1471,10 +1510,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1584,10 +1626,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1647,10 +1692,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1767,10 +1815,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1830,10 +1881,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2003,10 +2057,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -2066,10 +2123,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2286,7 +2346,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2295,7 +2354,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2309,7 +2367,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -2325,13 +2382,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2340,20 +2394,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2372,27 +2422,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2421,13 +2464,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -2451,7 +2491,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -2518,7 +2557,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -2590,7 +2628,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -2628,7 +2665,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2644,13 +2680,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2659,20 +2692,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2691,27 +2720,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2767,7 +2789,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2783,13 +2804,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2798,20 +2816,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2830,27 +2844,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2892,7 +2899,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -2909,13 +2915,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -3009,13 +3013,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -3063,7 +3064,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -3075,13 +3075,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -3142,7 +3139,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3151,7 +3147,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3165,7 +3160,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -3182,13 +3176,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3196,20 +3187,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3227,27 +3214,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3275,13 +3255,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -3304,7 +3281,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -3346,7 +3322,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -3418,7 +3393,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -3455,7 +3429,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3472,13 +3445,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3486,20 +3456,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3517,27 +3483,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3593,7 +3552,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3610,13 +3568,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3624,20 +3579,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3655,27 +3606,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -4109,10 +4053,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4176,10 +4123,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4442,10 +4392,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4509,10 +4462,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4741,10 +4697,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4808,10 +4767,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5080,10 +5042,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -5147,10 +5112,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5372,6 +5340,8 @@ spec: description: OpenShift security context constraint to build containers. type: string + required: + - openShiftSecurityContextConstraint type: object defaultComponents: description: |- @@ -5418,7 +5388,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5427,7 +5396,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5441,7 +5409,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -5457,13 +5424,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5472,20 +5436,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5504,27 +5464,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5553,13 +5506,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -5583,7 +5533,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -5650,7 +5599,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -5722,7 +5670,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -5760,7 +5707,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5776,13 +5722,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5791,20 +5734,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5823,27 +5762,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5899,7 +5831,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5915,13 +5846,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5930,20 +5858,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5962,27 +5886,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6024,7 +5941,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -6041,13 +5957,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -6141,13 +6055,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -6195,7 +6106,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -6207,13 +6117,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -6274,7 +6181,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6283,7 +6189,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6297,7 +6202,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -6314,13 +6218,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6328,20 +6229,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6359,27 +6256,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6407,13 +6297,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -6436,7 +6323,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -6478,7 +6364,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -6550,7 +6435,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -6587,7 +6471,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6604,13 +6487,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6618,20 +6498,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6649,27 +6525,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6725,7 +6594,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6742,13 +6610,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6756,20 +6621,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6787,27 +6648,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6983,7 +6837,6 @@ spec: When set to `false` (the default value), the devEnvironments.security.containerSecurityContext field is ignored, and the following container SecurityContext is applied: - containerSecurityContext: allowPrivilegeEscalation: true capabilities: @@ -7027,10 +6880,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7090,10 +6946,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7291,10 +7150,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7354,10 +7216,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7482,6 +7347,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7495,6 +7384,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7502,6 +7392,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7513,7 +7404,7 @@ spec: procMount: description: |- procMount denotes the type of proc mount to use for the containers. - The default is DefaultProcMount which uses the container runtime defaults for + The default value is Default which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. @@ -7588,14 +7479,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7623,12 +7513,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7644,17 +7531,38 @@ spec: PodSecurityContext used by all workspace-related pods. If set, defined values are merged into the default PodSecurityContext configuration. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- 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: - 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) - If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows. format: int64 @@ -7698,6 +7606,32 @@ spec: Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string seLinuxOptions: description: |- The SELinux context to be applied to all containers. @@ -7734,14 +7668,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7751,17 +7684,28 @@ spec: type: object supplementalGroups: description: |- - 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. + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -7782,6 +7726,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -7802,12 +7747,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7899,7 +7841,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -7925,7 +7866,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -8246,10 +8186,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -8316,10 +8259,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the diff --git a/deploy/deployment/openshift/objects/org.eclipse.che.MutatingWebhookConfiguration.yaml b/deploy/deployment/openshift/objects/org.eclipse.che.MutatingWebhookConfiguration.yaml index ceee5fef2a..faf86376af 100644 --- a/deploy/deployment/openshift/objects/org.eclipse.che.MutatingWebhookConfiguration.yaml +++ b/deploy/deployment/openshift/objects/org.eclipse.che.MutatingWebhookConfiguration.yaml @@ -24,7 +24,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service diff --git a/deploy/deployment/openshift/objects/org.eclipse.che.ValidatingWebhookConfiguration.yaml b/deploy/deployment/openshift/objects/org.eclipse.che.ValidatingWebhookConfiguration.yaml index 8059eed896..00c6a3a51e 100644 --- a/deploy/deployment/openshift/objects/org.eclipse.che.ValidatingWebhookConfiguration.yaml +++ b/deploy/deployment/openshift/objects/org.eclipse.che.ValidatingWebhookConfiguration.yaml @@ -24,7 +24,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service diff --git a/go.mod b/go.mod index 73bf869968..3b9e8f390b 100644 --- a/go.mod +++ b/go.mod @@ -1,514 +1,93 @@ module github.com/eclipse-che/che-operator -go 1.23.0 +go 1.23.6 toolchain go1.23.8 require ( - github.com/che-incubator/kubernetes-image-puller-operator v0.0.0-20210929175054-0128446f5af7 - github.com/devfile/api/v2 v2.2.2 - github.com/devfile/devworkspace-operator v0.35.0 - github.com/go-logr/logr v1.4.1 - github.com/google/go-cmp v0.6.0 - github.com/openshift/api v0.0.0-20230120182048-88b476f987ed - github.com/operator-framework/api v0.15.0 - github.com/operator-framework/operator-lifecycle-manager v0.18.1 - github.com/sirupsen/logrus v1.8.1 + github.com/che-incubator/kubernetes-image-puller-operator v0.0.0-20250214104625-65e5ec32f521 + github.com/devfile/api/v2 v2.3.0 + github.com/devfile/devworkspace-operator v0.35.1 + github.com/go-logr/logr v1.4.3 + github.com/google/go-cmp v0.7.0 + github.com/openshift/api v0.0.0-20250529074221-97812373b6b4 // ==release-4.19, a greater version require go 1.24 + github.com/operator-framework/api v0.31.0 // a greater version require go 1.24 + github.com/operator-framework/operator-lifecycle-manager v0.22.0 + github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.10.0 - go.uber.org/zap v1.24.0 - golang.org/x/net v0.38.0 - k8s.io/api v0.26.1 - k8s.io/apiextensions-apiserver v0.26.1 - k8s.io/apimachinery v0.26.1 - k8s.io/client-go v0.26.1 - k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 - sigs.k8s.io/controller-runtime v0.14.4 - sigs.k8s.io/yaml v1.3.0 + go.uber.org/zap v1.27.0 + golang.org/x/net v0.42.0 + k8s.io/api v0.32.7 // a greater version require go 1.24 + k8s.io/apiextensions-apiserver v0.32.7 // a greater version require go 1.24 + k8s.io/apimachinery v0.32.7 // a greater version require go 1.24 + k8s.io/client-go v0.32.7 // a greater version require go 1.24 + k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 + sigs.k8s.io/controller-runtime v0.20.4 // a greater version require go 1.24 + sigs.k8s.io/yaml v1.5.0 // a greater version not yet in clearlydefined.io ) require ( + github.com/Shopify/logrus-bugsnag v0.0.0-20250605201603-d55aa3c8353b // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // 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/evanphx/json-patch v5.6.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-logr/zapr v1.2.3 // 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.19.14 // indirect + github.com/bshuster-repo/logrus-logstash-hook v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.11.2 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/zapr v1.3.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/swag v0.23.0 // 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/golang/protobuf v1.5.4 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/imdario/mergo v0.3.13 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/h2non/filetype v1.1.1 // indirect + github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c // 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.2 // 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/onsi/gomega v1.34.1 // indirect - github.com/operator-framework/operator-registry v1.13.6 // indirect + github.com/onsi/gomega v1.36.1 // indirect; used for manifest generation + github.com/operator-framework/operator-registry v1.17.5 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.14.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/spf13/pflag v1.0.5 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/multierr v1.6.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/spf13/pflag v1.0.6 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/text v0.23.0 // indirect - golang.org/x/time v0.3.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect - google.golang.org/grpc v1.58.3 // indirect - google.golang.org/protobuf v1.34.1 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/term v0.33.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/time v0.7.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.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/component-base v0.26.1 // indirect - k8s.io/klog/v2 v2.80.1 // indirect - k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect - sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect -) - -require ( - github.com/BurntSushi/toml v0.3.1 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect - github.com/Shopify/logrus-bugsnag v0.0.0-00010101000000-000000000000 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect - go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee // indirect - golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/sync v0.12.0 // indirect - golang.org/x/tools v0.23.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect - honnef.co/go/tools v0.0.1-2020.1.3 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect ) replace ( - bazil.org/fuse => bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898 - cloud.google.com/go => cloud.google.com/go v0.54.0 - cloud.google.com/go/bigquery => cloud.google.com/go/bigquery v1.4.0 - cloud.google.com/go/datastore => cloud.google.com/go/datastore v1.2.0 - cloud.google.com/go/firestore => cloud.google.com/go/firestore v1.1.0 - cloud.google.com/go/pubsub => cloud.google.com/go/pubsub v1.2.0 - cloud.google.com/go/spanner => cloud.google.com/go/spanner v1.2.0 - cloud.google.com/go/storage => cloud.google.com/go/storage v1.5.0 - git/github/microsoft/go-winio => github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 - github.com/Azure/go-ansiterm => github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 - github.com/Azure/go-autorest => github.com/Azure/go-autorest v0.0.0-20200908233159-fafe600ec8bd - github.com/Azure/go-autorest/autorest => github.com/Azure/go-autorest/autorest v0.0.0-20200908233159-fafe600ec8bd - github.com/Azure/go-autorest/autorest/adal => github.com/Azure/go-autorest/autorest/adal v0.0.0-20200908233159-fafe600ec8bd - github.com/Azure/go-autorest/autorest/date => github.com/Azure/go-autorest/autorest/date v0.0.0-20200908233159-fafe600ec8bd - github.com/Azure/go-autorest/autorest/mocks => github.com/Azure/go-autorest/autorest/mocks v0.0.0-20200908233159-fafe600ec8bd - github.com/Azure/go-autorest/logger => github.com/Azure/go-autorest/logger v0.0.0-20200908233159-fafe600ec8bd - github.com/Azure/go-autorest/tracing => github.com/Azure/go-autorest/tracing v0.0.0-20200908233159-fafe600ec8bd - github.com/BurntSushi/toml => github.com/BurntSushi/toml v0.3.1 - github.com/BurntSushi/xgb => github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 - github.com/MakeNowJust/heredoc => github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e - github.com/Masterminds/goutils => github.com/Masterminds/goutils v1.1.0 - github.com/Masterminds/semver/v3 => github.com/Masterminds/semver/v3 v3.0.3 - github.com/Masterminds/sprig/v3 => github.com/Masterminds/sprig/v3 v3.0.2 - github.com/Microsoft/go-winio => github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 - github.com/Microsoft/hcsshim => github.com/Microsoft/hcsshim v0.8.9 - github.com/NYTimes/gziphandler => github.com/NYTimes/gziphandler v1.0.1 - github.com/PuerkitoBio/purell => github.com/PuerkitoBio/purell v1.1.1 - github.com/PuerkitoBio/urlesc => github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2 - github.com/Shopify/logrus-bugsnag => github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d - github.com/alecthomas/units => github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 - github.com/alessio/shellescape => github.com/alessio/shellescape v1.2.2 - github.com/antihax/optional => github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6 - github.com/armon/circbuf => github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e - github.com/armon/go-metrics => github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da - github.com/armon/go-radix => github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 - github.com/asaskevich/govalidator => github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a - github.com/aws/aws-sdk-go => github.com/aws/aws-sdk-go v0.0.0-20210122191723-2c7b39c8f2e2 - github.com/benbjohnson/clock => github.com/benbjohnson/clock v1.1.0 - github.com/beorn7/perks => github.com/beorn7/perks v1.0.1 - github.com/bgentry/speakeasy => github.com/bgentry/speakeasy v0.1.0 - github.com/bitly/go-hostpool => github.com/bitly/go-hostpool v0.0.0-20191224193725-5d3b4dc6ed47 - github.com/bitly/go-simplejson => github.com/bitly/go-simplejson v0.0.0-20171023175154-0c965951289c - github.com/bkaradzic/go-lz4 => github.com/bkaradzic/go-lz4 v1.0.0 - github.com/bketelsen/crypt => github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c - github.com/blang/semver => github.com/blang/semver v3.5.1+incompatible - github.com/blang/semver/v4 => github.com/blang/semver/v4 v4.0.0 - github.com/bshuster-repo/logrus-logstash-hook => github.com/bshuster-repo/logrus-logstash-hook v1.0.0 - github.com/bugsnag/bugsnag-go => github.com/bugsnag/bugsnag-go v1.5.3 - github.com/bugsnag/panicwrap => github.com/bugsnag/panicwrap v1.2.0 - github.com/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.2.1 - github.com/cespare/xxhash/v2 => github.com/cespare/xxhash/v2 v2.2.0 - github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 - github.com/chzyer/logex => github.com/chzyer/logex v1.1.10 - github.com/chzyer/readline => github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e - github.com/chzyer/test => github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 - github.com/clickhouse/clickhouse-go => github.com/clickhouse/clickhouse-go v1.3.12 - github.com/cloudflare/golz4 => github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 - github.com/cncf/udpa/go => github.com/cncf/udpa/go v0.0.0-20200327203949-e8cd3a4bb307 - github.com/cockroachdb/apd => github.com/cockroachdb/apd v1.1.0 - github.com/cockroachdb/datadriven => github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa - github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20191002205938-3de5a6bb4823 - github.com/containerd/console => github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 - github.com/containerd/containerd => github.com/containerd/containerd v1.3.3 - github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb - github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 - github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3 - github.com/containerd/ttrpc => github.com/containerd/ttrpc v1.0.1 - github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20 - github.com/coreos/bbolt => github.com/coreos/bbolt v1.3.3 - github.com/coreos/etcd => github.com/coreos/etcd v3.3.15+incompatible - github.com/coreos/go-oidc => github.com/coreos/go-oidc v2.1.0+incompatible - github.com/coreos/go-semver => github.com/coreos/go-semver v0.3.0 - github.com/coreos/go-systemd => github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f - github.com/coreos/pkg => github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f - github.com/cpuguy83/go-md2man => github.com/cpuguy83/go-md2man v1.0.10 - github.com/creack/pty => github.com/creack/pty v1.1.9 - github.com/cyphar/filepath-securejoin => github.com/cyphar/filepath-securejoin v0.2.2 - github.com/cznic/mathutil => github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369 - github.com/davecgh/go-spew => github.com/davecgh/go-spew v1.1.1 - github.com/daviddengcn/go-colortext => github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd - github.com/deislabs/oras => github.com/deislabs/oras v0.8.1 - github.com/denisenkom/go-mssqldb => github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289 - github.com/dgrijalva/jwt-go => github.com/dgrijalva/jwt-go v3.2.0+incompatible - github.com/docker/cli => github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492 - github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible - github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 - github.com/docker/docker-credential-helpers => github.com/docker/docker-credential-helpers v0.6.3 - github.com/docker/go-connections => github.com/docker/go-connections v0.4.0 - github.com/docker/go-events => github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c - github.com/docker/go-metrics => github.com/docker/go-metrics v0.0.1 - github.com/docker/go-units => github.com/docker/go-units v0.4.0 - github.com/docker/libtrust => github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 - github.com/docopt/docopt-go => github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 - github.com/dustin/go-humanize => github.com/dustin/go-humanize v1.0.0 - github.com/edsrzf/mmap-go => github.com/edsrzf/mmap-go v0.0.0-20181215214921-188cc3b666ba - github.com/elazarl/goproxy => github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 - github.com/emicklei/go-restful => github.com/emicklei/go-restful v0.0.0-20200129102538-a2fa14558f9a - github.com/envoyproxy/go-control-plane => github.com/envoyproxy/go-control-plane v0.0.0-20200213201256-ba8e577f987f - github.com/envoyproxy/protoc-gen-validate => github.com/envoyproxy/protoc-gen-validate v0.1.0 - github.com/evanphx/json-patch => github.com/evanphx/json-patch v4.11.0+incompatible - github.com/evanphx/json-patch/v5 => github.com/evanphx/json-patch/v5 v5.1.0 - github.com/exponent-io/jsonpath => github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d - github.com/fastly/go-utils => github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 - github.com/fatih/camelcase => github.com/fatih/camelcase v1.0.0 - github.com/fatih/color => github.com/fatih/color v1.9.0 - github.com/fatih/set => github.com/fatih/set v0.2.1 - github.com/flynn/go-shlex => github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 - github.com/fsnotify/fsnotify => github.com/fsnotify/fsnotify v1.4.7 - github.com/fsouza/fake-gcs-server => github.com/fsouza/fake-gcs-server v1.17.0 - github.com/fvbommel/sortorder => github.com/fvbommel/sortorder v1.0.1 - github.com/garyburd/redigo => github.com/garyburd/redigo v1.6.0 - github.com/ghodss/yaml => github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 - github.com/globalsign/mgo => github.com/globalsign/mgo v0.0.0-20160323214708-72aab81a5dec - github.com/go-bindata/go-bindata/v3 => github.com/go-bindata/go-bindata/v3 v3.1.3 - github.com/go-errors/errors => github.com/go-errors/errors v1.0.1 - github.com/go-ini/ini => github.com/go-ini/ini v1.25.4 - github.com/go-kit/log => github.com/go-kit/log v0.1.0 - github.com/go-logfmt/logfmt => github.com/go-logfmt/logfmt v0.5.0 - github.com/go-openapi/errors => github.com/go-openapi/errors v0.19.2 - github.com/go-openapi/jsonpointer => github.com/go-openapi/jsonpointer v0.19.3 - github.com/go-openapi/jsonreference => github.com/go-openapi/jsonreference v0.19.3 - github.com/go-openapi/loads => github.com/go-openapi/loads v0.19.2 - github.com/go-openapi/runtime => github.com/go-openapi/runtime v0.19.0 - github.com/go-openapi/spec => github.com/go-openapi/spec v0.19.3 - github.com/go-openapi/strfmt => github.com/go-openapi/strfmt v0.19.5 - github.com/go-openapi/swag => github.com/go-openapi/swag v0.19.5 - github.com/go-openapi/validate => github.com/go-openapi/validate v0.19.2 - github.com/go-playground/universal-translator => github.com/go-playground/universal-translator v0.16.0 - github.com/go-sql-driver/mysql => github.com/go-sql-driver/mysql v1.4.1 - github.com/go-stack/stack => github.com/go-stack/stack v1.8.0 - github.com/gobuffalo/flect => github.com/gobuffalo/flect v0.1.0 - github.com/gobuffalo/here => github.com/gobuffalo/here v0.6.0 - github.com/gobwas/glob => github.com/gobwas/glob v0.2.3 - github.com/goccy/go-yaml => github.com/goccy/go-yaml v1.8.1 - github.com/gocql/gocql => github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4 - github.com/godbus/dbus => github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e - github.com/gofrs/flock => github.com/gofrs/flock v0.7.1 - github.com/gofrs/uuid => github.com/gofrs/uuid v3.2.0+incompatible - github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 - github.com/golang-migrate/migrate/v4 => github.com/golang-migrate/migrate/v4 v4.10.0 - github.com/golang/glog => github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b - github.com/golang/groupcache => github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e - github.com/golang/protobuf => github.com/golang/protobuf v1.4.3 - github.com/golang/snappy => github.com/golang/snappy v0.0.1 - github.com/golangplus/bytes => github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 - github.com/golangplus/fmt => github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 - github.com/google/btree => github.com/google/btree v1.0.0 - github.com/google/go-cmp => github.com/google/go-cmp v0.5.6 - github.com/google/go-github => github.com/google/go-github/v18 v18.0.0-20180920013327-07716bad7a0c - github.com/google/go-querystring => github.com/google/go-querystring v1.0.0 - github.com/google/gofuzz => github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367 - github.com/google/martian => github.com/google/martian v0.0.0-20180813215018-c223d6f7955e - github.com/google/pprof => github.com/google/pprof v0.0.0-20180921154107-7dadf64105bb - github.com/google/renameio => github.com/google/renameio v0.1.0 - github.com/google/uuid => github.com/google/uuid v1.3.0 - github.com/googleapis/gax-go/v2 => github.com/googleapis/gax-go/v2 v2.0.5 - github.com/googleapis/gnostic => github.com/googleapis/gnostic v0.4.2 - github.com/gopherjs/gopherjs => github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 - github.com/gorilla/context => github.com/gorilla/context v1.1.1 - github.com/gorilla/handlers => github.com/gorilla/handlers v1.4.2 - github.com/gorilla/mux => github.com/gorilla/mux v1.7.2 - github.com/gorilla/websocket => github.com/gorilla/websocket v1.4.2 - github.com/gosuri/uitable => github.com/gosuri/uitable v0.0.4 - github.com/gregjones/httpcache => github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 - github.com/grpc-ecosystem/go-grpc-middleware => github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 - github.com/grpc-ecosystem/go-grpc-prometheus => github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 - github.com/grpc-ecosystem/grpc-gateway => github.com/grpc-ecosystem/grpc-gateway v1.9.5 - github.com/hailocab/go-hostpool => github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed - github.com/hashicorp/consul/api => github.com/hashicorp/consul/api v1.1.0 - github.com/hashicorp/consul/sdk => github.com/hashicorp/consul/sdk v0.1.1 - github.com/hashicorp/errwrap => github.com/hashicorp/errwrap v1.0.0 - github.com/hashicorp/go-cleanhttp => github.com/hashicorp/go-cleanhttp v0.5.1 - github.com/hashicorp/go-immutable-radix => github.com/hashicorp/go-immutable-radix v1.0.0 - github.com/hashicorp/go-msgpack => github.com/hashicorp/go-msgpack v0.5.5 - github.com/hashicorp/go-multierror => github.com/hashicorp/go-multierror v1.1.1 - github.com/hashicorp/go-rootcerts => github.com/hashicorp/go-rootcerts v1.0.1 - github.com/hashicorp/go-sockaddr => github.com/hashicorp/go-sockaddr v1.0.0 - github.com/hashicorp/go-syslog => github.com/hashicorp/go-syslog v1.0.0 - github.com/hashicorp/go-uuid => github.com/hashicorp/go-uuid v1.0.1 - github.com/hashicorp/go.net => github.com/hashicorp/go.net v0.0.1 - github.com/hashicorp/golang-lru => github.com/hashicorp/golang-lru v0.5.1 - github.com/hashicorp/hcl => github.com/hashicorp/hcl v1.0.0 - github.com/hashicorp/logutils => github.com/hashicorp/logutils v1.0.0 - github.com/hashicorp/mdns => github.com/hashicorp/mdns v1.0.0 - github.com/hashicorp/memberlist => github.com/hashicorp/memberlist v0.1.3 - github.com/hashicorp/serf => github.com/hashicorp/serf v0.8.2 - github.com/hokaccha/go-prettyjson => github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e - github.com/hpcloud/tail => github.com/hpcloud/tail v1.0.0 - github.com/huandu/xstrings => github.com/huandu/xstrings v1.2.0 - github.com/imdario/mergo => github.com/imdario/mergo v0.3.5 - github.com/inconshreveable/mousetrap => github.com/inconshreveable/mousetrap v1.0.0 - github.com/irifrance/gini => github.com/go-air/gini v1.0.1 - github.com/itchyny/astgen-go => github.com/itchyny/astgen-go v0.0.0-20200519013840-cf3ea398f645 - github.com/itchyny/go-flags => github.com/itchyny/go-flags v1.5.0 - github.com/itchyny/gojq => github.com/itchyny/gojq v0.11.0 - github.com/jackc/chunkreader/v2 => github.com/jackc/chunkreader/v2 v2.0.1 - github.com/jackc/pgconn => github.com/jackc/pgconn v1.3.2 - github.com/jackc/pgio => github.com/jackc/pgio v1.0.0 - github.com/jackc/pgmock => github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 - github.com/jackc/pgpassfile => github.com/jackc/pgpassfile v1.0.0 - github.com/jackc/pgproto3/v2 => github.com/jackc/pgproto3/v2 v2.0.1 - github.com/jackc/pgtype => github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59 - github.com/jackc/pgx/v4 => github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186 - github.com/jackc/puddle => github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9 - github.com/jehiah/go-strftime => github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 - github.com/jessevdk/go-flags => github.com/jessevdk/go-flags v1.4.0 - github.com/jmespath/go-jmespath => github.com/jmespath/go-jmespath v0.3.0 - github.com/joefitzgerald/rainbow-reporter => github.com/joefitzgerald/rainbow-reporter v0.1.0 - github.com/jonboulle/clockwork => github.com/jonboulle/clockwork v0.1.0 - github.com/jpillora/backoff => github.com/jpillora/backoff v1.0.0 - github.com/json-iterator/go => github.com/json-iterator/go v0.0.0-20200608025830-a1ca0830781e - github.com/jstemmer/go-junit-report => github.com/jstemmer/go-junit-report v0.9.1 - github.com/jtolds/gls => github.com/jtolds/gls v0.0.0-20150401064343-9a4a02dbe491 - github.com/julienschmidt/httprouter => github.com/julienschmidt/httprouter v1.2.0 - github.com/kardianos/osext => github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 - github.com/kisielk/errcheck => github.com/kisielk/errcheck v1.2.0 - github.com/kisielk/gotool => github.com/kisielk/gotool v1.0.0 - github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.1 - github.com/kr/pretty => github.com/kr/pretty v0.0.0-20200729040243-ead452280cd0 - github.com/kr/pty => github.com/kr/pty v0.0.0-20180113180813-282ce0e5322c - github.com/kr/text => github.com/kr/text v0.2.0 - github.com/kylelemons/godebug => github.com/kylelemons/godebug v1.1.0 - github.com/leodido/go-urn => github.com/leodido/go-urn v0.0.0-20201213191625-6c96508144d0 - github.com/lestrrat-go/envload => github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc - github.com/lestrrat-go/strftime => github.com/lestrrat-go/strftime v1.0.1 - github.com/lib/pq => github.com/lib/pq v0.0.0-20190415174712-51e2106eed1c - github.com/liggitt/tabwriter => github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de - github.com/lithammer/dedent => github.com/lithammer/dedent v1.1.0 - github.com/magiconair/properties => github.com/magiconair/properties v1.8.1 - github.com/mailru/easyjson => github.com/mailru/easyjson v0.0.0-20200218084223-8edcc4e51f39 - github.com/markbates/pkger => github.com/markbates/pkger v0.17.1 - github.com/mattn/go-colorable => github.com/mattn/go-colorable v0.1.7 - github.com/mattn/go-isatty => github.com/mattn/go-isatty v0.0.3 - github.com/mattn/go-runewidth => github.com/mattn/go-runewidth v0.0.9 - github.com/mattn/go-shellwords => github.com/mattn/go-shellwords v0.0.0-20180201004752-39dbbfa24bbc - github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v0.0.0-20190716055609-b612a2feea6a - github.com/matttproud/golang_protobuf_extensions => github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 - github.com/maxbrunsfeld/counterfeiter/v6 => github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2 - github.com/miekg/dns => github.com/miekg/dns v1.0.14 - github.com/mikefarah/yq/v3 => github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37 - github.com/mitchellh/cli => github.com/mitchellh/cli v1.0.0 - github.com/mitchellh/copystructure => github.com/mitchellh/copystructure v1.0.0 - github.com/mitchellh/go-homedir => github.com/mitchellh/go-homedir v1.1.0 - github.com/mitchellh/go-testing-interface => github.com/mitchellh/go-testing-interface v1.0.0 - github.com/mitchellh/go-wordwrap => github.com/mitchellh/go-wordwrap v1.0.0 - github.com/mitchellh/gox => github.com/mitchellh/gox v0.4.0 - github.com/mitchellh/hashstructure => github.com/mitchellh/hashstructure v1.0.0 - github.com/mitchellh/iochan => github.com/mitchellh/iochan v1.0.0 - github.com/mitchellh/mapstructure => github.com/mitchellh/mapstructure v1.1.2 - github.com/mitchellh/reflectwalk => github.com/mitchellh/reflectwalk v1.0.1 - github.com/moby/spdystream => github.com/moby/spdystream v0.2.0 - github.com/moby/term => github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 - github.com/modern-go/concurrent => github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd - github.com/modern-go/reflect2 => github.com/modern-go/reflect2 v1.0.1 - github.com/mongodb/mongo-go-driver => github.com/mongodb/mongo-go-driver v1.1.0 - github.com/monochromegane/go-gitignore => github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 - github.com/morikuni/aec => github.com/morikuni/aec v1.0.0 - github.com/munnerz/goautoneg => github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d - github.com/mwitkow/go-conntrack => github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 - github.com/nakagami/firebirdsql => github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8 - github.com/neo4j-drivers/gobolt => github.com/neo4j-drivers/gobolt v1.7.4 - github.com/neo4j/neo4j-go-driver => github.com/neo4j/neo4j-go-driver v1.7.4 - github.com/olekukonko/tablewriter => github.com/olekukonko/tablewriter v0.0.2 - github.com/onsi/ginkgo => github.com/onsi/ginkgo v1.11.0 - github.com/onsi/gomega => github.com/onsi/gomega v1.7.0 - github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0 - github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 - github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830 - github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.0 - github.com/openshift/api => github.com/openshift/api v0.0.0-20230120182048-88b476f987ed - github.com/openshift/client-go => github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0 - github.com/opentracing/opentracing-go => github.com/opentracing/opentracing-go v1.1.0 - github.com/operator-framework/operator-registry => github.com/operator-framework/operator-registry v1.13.6 - github.com/otiai10/copy => github.com/otiai10/copy v1.2.0 - github.com/otiai10/curr => github.com/otiai10/curr v1.0.0 - github.com/otiai10/mint => github.com/otiai10/mint v1.3.1 - github.com/pascaldekloe/goe => github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c - github.com/pbnjay/strptime => github.com/pbnjay/strptime v0.0.0-20140226051138-5c05b0d668c9 - github.com/pelletier/go-toml => github.com/pelletier/go-toml v1.4.0 - github.com/peterbourgon/diskv => github.com/peterbourgon/diskv v0.0.0-20180312054125-0646ccaebea1 - github.com/phayes/freeport => github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 - github.com/pierrec/lz4 => github.com/pierrec/lz4 v0.0.0-20180610162716-6b9367c9ff40 - github.com/pkg/errors => github.com/pkg/errors v0.0.0-20200114194744-614d223910a1 - github.com/pmezard/go-difflib => github.com/pmezard/go-difflib v1.0.0 - github.com/posener/complete => github.com/posener/complete v1.1.1 - github.com/pquerna/cachecontrol => github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021 - github.com/prometheus/client_golang => github.com/prometheus/client_golang v1.14.0 - github.com/prometheus/client_model => github.com/prometheus/client_model v0.3.0 - github.com/prometheus/common => github.com/prometheus/common v0.26.0 - github.com/prometheus/procfs => github.com/prometheus/procfs v0.6.0 - github.com/redhat-cop/operator-utils => github.com/redhat-cop/operator-utils v1.1.4 - github.com/remyoudompheng/bigfft => github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237 - github.com/rogpeppe/fastuuid => github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af - github.com/rogpeppe/go-internal => github.com/rogpeppe/go-internal v1.3.0 - github.com/rs/xid => github.com/rs/xid v1.2.1 - github.com/rs/zerolog => github.com/rs/zerolog v1.15.0 - github.com/russross/blackfriday => github.com/russross/blackfriday v1.5.2 - github.com/ryanuber/columnize => github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f - github.com/satori/go.uuid => github.com/satori/go.uuid v1.2.0 - github.com/sclevine/spec => github.com/sclevine/spec v1.2.0 - github.com/scylladb/go-set => github.com/scylladb/go-set v1.0.2 - github.com/sean-/seed => github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 - github.com/sergi/go-diff => github.com/sergi/go-diff v1.0.0 - github.com/shopspring/decimal => github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 - github.com/shurcooL/sanitized_anchor_name => github.com/shurcooL/sanitized_anchor_name v1.0.0 - github.com/sirupsen/logrus => github.com/sirupsen/logrus v1.4.2 - github.com/smartystreets/assertions => github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d - github.com/smartystreets/goconvey => github.com/smartystreets/goconvey v1.6.4 - github.com/soheilhy/cmux => github.com/soheilhy/cmux v0.1.4 - github.com/spf13/afero => github.com/spf13/afero v1.2.2 - github.com/spf13/cast => github.com/spf13/cast v1.3.0 - github.com/spf13/cobra => github.com/spf13/cobra v0.0.0-20190321000552-67fc4837d267 - github.com/spf13/jwalterweatherman => github.com/spf13/jwalterweatherman v1.1.0 - github.com/spf13/pflag => github.com/spf13/pflag v1.0.5 - github.com/spf13/viper => github.com/spf13/viper v1.7.0 - github.com/stretchr/objx => github.com/stretchr/objx v0.3.0 - github.com/stretchr/testify => github.com/stretchr/testify v1.4.0 - github.com/subosito/gotenv => github.com/subosito/gotenv v1.2.0 - github.com/tebeka/strftime => github.com/tebeka/strftime v0.1.3 - github.com/tidwall/pretty => github.com/tidwall/pretty v0.0.0-20200828150932-ef453c788d6a - github.com/tmc/grpc-websocket-proxy => github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 - github.com/urfave/cli => github.com/urfave/cli v1.2.0 - github.com/xanzy/go-gitlab => github.com/xanzy/go-gitlab v0.15.0 - github.com/xdg/scram => github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c - github.com/xdg/stringprep => github.com/xdg/stringprep v1.0.0 - github.com/xeipuuv/gojsonpointer => github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f - github.com/xeipuuv/gojsonreference => github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 - github.com/xeipuuv/gojsonschema => github.com/xeipuuv/gojsonschema v1.2.0 - github.com/xiang90/probing => github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 - github.com/xlab/treeprint => github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca - github.com/yuin/goldmark => github.com/yuin/goldmark v0.0.0-20200826112251-7b90f04af431 - github.com/yvasiyarov/go-metrics => github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 - github.com/yvasiyarov/gorelic => github.com/yvasiyarov/gorelic v0.0.7 - github.com/yvasiyarov/newrelic_platform_go => github.com/yvasiyarov/newrelic_platform_go v0.0.0-20160601141957-9c099fbc30e9 - github.com/zenazn/goji => github.com/zenazn/goji v0.9.0 - gitlab.com/nyarla/go-crypt => gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b - go.etcd.io/bbolt => go.etcd.io/bbolt v0.0.0-20190608165704-a0458a2b3570 - go.etcd.io/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 - go.opencensus.io => go.opencensus.io v0.22.3 - go.starlark.net => go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 - go.uber.org/atomic => go.uber.org/atomic v1.7.0 - go.uber.org/goleak => go.uber.org/goleak v1.1.10 - go.uber.org/multierr => go.uber.org/multierr v1.3.0 - go.uber.org/tools => go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee - go.uber.org/zap => go.uber.org/zap v1.18.1 - golang.org/x/crypto => golang.org/x/crypto v0.35.0 - golang.org/x/exp => golang.org/x/exp v0.0.0-20190426190305-956cc1757749 - golang.org/x/mod => golang.org/x/mod v0.17.0 - golang.org/x/net => golang.org/x/net v0.36.0 - golang.org/x/oauth2 => golang.org/x/oauth2 v0.27.0 - golang.org/x/sync => golang.org/x/sync v0.10.0 - golang.org/x/sys => golang.org/x/sys v0.28.0 - golang.org/x/term => golang.org/x/term v0.27.0 - golang.org/x/text => golang.org/x/text v0.21.0 - golang.org/x/tools => golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d - gomodules.xyz/jsonpatch/v2 => gomodules.xyz/jsonpatch/v2 v2.0.1 - google.golang.org/api => google.golang.org/api v0.20.0 - google.golang.org/appengine => google.golang.org/appengine v1.6.5 - google.golang.org/cloud => cloud.google.com/go v0.0.0-20200305180117-a6b88cf34a49 - google.golang.org/genproto/googleapis/rpc => google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/grpc => google.golang.org/grpc v1.58.3 - google.golang.org/protobuf => google.golang.org/protobuf v1.34.1 - gopkg.in/airbrake/gobrake.v2 => gopkg.in/airbrake/gobrake.v2 v2.0.9 - gopkg.in/alecthomas/kingpin.v2 => gopkg.in/alecthomas/kingpin.v2 v2.2.6 - gopkg.in/check.v1 => gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789 - gopkg.in/cheggaaa/pb.v1 => gopkg.in/cheggaaa/pb.v1 v1.0.25 - gopkg.in/errgo.v2 => gopkg.in/errgo.v2 v2.1.0 - gopkg.in/fsnotify.v1 => gopkg.in/fsnotify.v1 v1.4.7 - gopkg.in/gemnasium/logrus-airbrake-hook.v2 => gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 - gopkg.in/go-playground/assert.v1 => gopkg.in/go-playground/assert.v1 v1.2.1 - gopkg.in/go-playground/validator.v9 => gopkg.in/go-playground/validator.v9 v9.30.0 - gopkg.in/inconshreveable/log15.v2 => gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec - gopkg.in/inf.v0 => gopkg.in/inf.v0 v0.9.1 - gopkg.in/ini.v1 => gopkg.in/ini.v1 v1.51.0 - gopkg.in/natefinch/lumberjack.v2 => gopkg.in/natefinch/lumberjack.v2 v2.0.0 - gopkg.in/op/go-logging.v1 => gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 - gopkg.in/resty.v1 => gopkg.in/resty.v1 v1.12.0 - gopkg.in/square/go-jose.v2 => gopkg.in/square/go-jose.v2 v2.2.2 - gopkg.in/tomb.v1 => gopkg.in/tomb.v1 v1.0.0-20161208151619-d5d1b5820637 - gopkg.in/tomb.v2 => gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 - gopkg.in/yaml.v2 => gopkg.in/yaml.v2 v2.4.0 - gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 - grpc-ecosystem/grpc-health-probe => grpc-ecosystem/grpc-health-probe v0.3.2 - helm.sh/helm/v3 => helm.sh/helm/v3 v3.0.0-20200422233323-0a9a9a88e8af - honnef.co/go/tools => honnef.co/go/tools v0.0.0-20200822191040-81508471876c - k8s.io/code-generator => k8s.io/code-generator v0.0.0-20200708172309-f186a36abf5c - k8s.io/component-helpers => k8s.io/component-helpers v0.20.1 - k8s.io/gengo => k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.0.0-20180912235703-14b8d2d93fcb - k8s.io/kubectl => k8s.io/kubectl v0.0.0-20201218185502-10b66c3fd14b - k8s.io/metrics => k8s.io/metrics v0.20.2 - kubernetes/klog => kubernetes/klog v1.0.0 - modernc.org/b => modernc.org/b v1.0.0 - modernc.org/db => modernc.org/db v1.0.0 - modernc.org/file => modernc.org/file v1.0.0 - modernc.org/fileutil => modernc.org/fileutil v1.0.0 - modernc.org/golex => modernc.org/golex v1.0.0 - modernc.org/internal => modernc.org/internal v1.0.0 - modernc.org/lldb => modernc.org/lldb v1.0.0 - modernc.org/mathutil => modernc.org/mathutil v1.0.0 - modernc.org/ql => modernc.org/ql v1.0.0 - modernc.org/sortutil => modernc.org/sortutil v1.1.0 - modernc.org/strutil => modernc.org/strutil v1.1.0 - modernc.org/zappy => modernc.org/zappy v1.0.0 - rsc.io/letsencrypt => rsc.io/letsencrypt v0.0.3 - sigs.k8s.io/apiserver-network-proxy/konnectivity-client => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19 - sigs.k8s.io/controller-tgithub.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1ools => sigs.k8s.io/controller-tools v0.0.0-20200129215414-2bc3f5eb99cc - sigs.k8s.io/controller-tools => sigs.k8s.io/controller-tools v0.6.0 - sigs.k8s.io/kind => sigs.k8s.io/kind v0.10.0 - sigs.k8s.io/structured-merge-diff => sigs.k8s.io/structured-merge-diff v1.0.2 - sigs.k8s.io/structured-merge-diff/v3 => sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874 - sigs.k8s.io/yaml => sigs.k8s.io/yaml v1.2.0 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 ) diff --git a/go.sum b/go.sum index d8abffc1ec..8306201fcd 100644 --- a/go.sum +++ b/go.sum @@ -1,1236 +1,1169 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +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.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= +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/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= -cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= -cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= -cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68= -cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= -cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= -cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= -cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= -cloud.google.com/go/accesscontextmanager v1.8.0/go.mod h1:uI+AI/r1oyWK99NN8cQ3UK76AMelMzgZCvJfsi2c+ps= -cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo= -cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= -cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= -cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= -cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= -cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= -cloud.google.com/go/aiplatform v1.45.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= -cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= -cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= -cloud.google.com/go/analytics v0.21.2/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= -cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= -cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= -cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= -cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA= -cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= -cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= -cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= -cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs= -cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= -cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= -cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= -cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw= -cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= -cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= -cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= -cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= -cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= -cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= -cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= -cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= -cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY= -cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= -cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg= -cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= -cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= -cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= -cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= -cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= -cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= -cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E= -cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= -cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= -cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= -cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= -cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= -cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= -cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ= -cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= -cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= -cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= -cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= -cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= -cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0= -cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= -cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= -cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= -cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= -cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= -cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE= -cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= -cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= -cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= -cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= -cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= -cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= -cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= -cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= -cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= -cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= -cloud.google.com/go/beyondcorp v0.6.1/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= +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/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= -cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= -cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= -cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= -cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= -cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA= -cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= -cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= -cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= -cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= -cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U= -cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= -cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= -cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= -cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI= -cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= -cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= -cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= -cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= -cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc= -cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= -cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= -cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= -cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= -cloud.google.com/go/cloudbuild v1.10.1/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= -cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= -cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= -cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= -cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI= -cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= -cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= -cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= -cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= -cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= -cloud.google.com/go/cloudtasks v1.11.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= -cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= -cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= -cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= -cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= -cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= -cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= -cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= -cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= -cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= -cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= -cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= -cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= -cloud.google.com/go/container v1.22.1/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= -cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= -cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= -cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0= -cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= -cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= -cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= -cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= -cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= -cloud.google.com/go/datacatalog v1.14.1/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= -cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= -cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw= -cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= -cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= -cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= -cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= -cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M= -cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= -cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= -cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= -cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI= -cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= -cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY= -cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= -cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= -cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= -cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= -cloud.google.com/go/dataplex v1.8.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= -cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= -cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= -cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= -cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= -cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= -cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8= -cloud.google.com/go/datastore v1.2.0/go.mod h1:FKd9dFEjRui5757lkOJ7z/eKtL74o5hsbY0o6Z0ozz8= -cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= -cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= -cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= -cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= -cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= -cloud.google.com/go/datastream v1.9.1/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= -cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= -cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= -cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= -cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= -cloud.google.com/go/deploy v1.11.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= -cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= -cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= -cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= -cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= -cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= -cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= -cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= -cloud.google.com/go/dialogflow v1.38.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= -cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= -cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= -cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= -cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI= -cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= -cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= -cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= -cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= -cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= -cloud.google.com/go/documentai v1.20.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= -cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= -cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE= -cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= -cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= -cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= -cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= -cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= -cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4= -cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= -cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= -cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= -cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= -cloud.google.com/go/eventarc v1.12.1/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= -cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= -cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= -cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= -cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= -cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= +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/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= -cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= -cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= -cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= -cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= -cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= -cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE= -cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= -cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= -cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= -cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= -cloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s= -cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= -cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= -cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= -cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= -cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw= -cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= -cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= -cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY= -cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= -cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= -cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= -cloud.google.com/go/gkemulticloud v0.6.1/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= -cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= -cloud.google.com/go/grafeas v0.3.0/go.mod h1:P7hgN24EyONOTMyeJH6DxG4zD7fwiYa5Q6GUgyFSOU8= -cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= -cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= -cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= -cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= -cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= -cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= -cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= -cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= -cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= -cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8= -cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk= -cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= -cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= -cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= -cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= -cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= -cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= -cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ= -cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= -cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= -cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= -cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw= -cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= -cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= -cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= -cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= -cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk= -cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= -cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= -cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= -cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= -cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= -cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= -cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= -cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= -cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= -cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= -cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= -cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0= -cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= -cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc= -cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= -cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= -cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= -cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= -cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= -cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ= -cloud.google.com/go/longrunning v0.5.0/go.mod h1:0JNuqRShmscVAhIACGtskSAWtqtOoPkwP0YF1oVEchc= -cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= -cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= -cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= -cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= -cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak= -cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= -cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= -cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= -cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= -cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig= -cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= -cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= -cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= -cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= -cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA= -cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= -cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= -cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= -cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= -cloud.google.com/go/metastore v1.11.1/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= -cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= -cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= -cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= -cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= -cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= -cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= -cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= -cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= -cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= -cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= -cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E= -cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= -cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= -cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= -cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0= -cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= -cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= -cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ= -cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= -cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= -cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= -cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= -cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= -cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8= -cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= -cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= -cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= -cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk= -cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= -cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= -cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= -cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8= -cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= -cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= -cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= -cloud.google.com/go/orgpolicy v1.11.0/go.mod h1:2RK748+FtVvnfuynxBzdnyu7sygtoZa1za/0ZfpOs1M= -cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE= -cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= -cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= -cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= -cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= -cloud.google.com/go/osconfig v1.12.0/go.mod h1:8f/PaYzoS3JMVfdfTubkowZYGmAhUCjjwnjqWI7NVBc= -cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE= -cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= -cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= -cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= -cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= -cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs= -cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= -cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I= -cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= -cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= -cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= -cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= -cloud.google.com/go/policytroubleshooter v1.7.1/go.mod h1:0NaT5v3Ag1M7U5r0GfDCpUFkWd9YqpubBWsQlhanRv0= -cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= -cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= -cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA= +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/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= -cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= -cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= -cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= -cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= -cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= -cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= -cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= -cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= -cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU= -cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= -cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE= -cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= -cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= -cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= -cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= -cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA= -cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= -cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= -cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= -cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= -cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg= -cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= -cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= -cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= -cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= -cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= -cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8= -cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= -cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= -cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= -cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw= -cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= -cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= -cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= -cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= -cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE= -cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= -cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= -cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= -cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= -cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= -cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= -cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= -cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= -cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= -cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo= -cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= -cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= -cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= -cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw= -cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= -cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= -cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= -cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= -cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= -cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= -cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA= -cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= -cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= -cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= -cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= -cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= -cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ= -cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= -cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= -cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= -cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= -cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= -cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= -cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= -cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= -cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= -cloud.google.com/go/servicedirectory v1.10.1/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= -cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= -cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= -cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= -cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= -cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= -cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= -cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= -cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= -cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= -cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= -cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= -cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g= -cloud.google.com/go/spanner v1.2.0/go.mod h1:LfwGAsK42Yz8IeLsd/oagGFBqTXt3xVWtm8/KD2vrEI= -cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= -cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= -cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= -cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= -cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= -cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= -cloud.google.com/go/speech v1.17.1/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= +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/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= -cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= -cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= -cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= -cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA= -cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= -cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= -cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= -cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= -cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= -cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24= -cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= -cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= -cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= -cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk= -cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= -cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= -cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= -cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E= -cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= -cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= -cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= -cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= -cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= -cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= -cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= -cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= -cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= -cloud.google.com/go/translate v1.8.1/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= -cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= -cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= -cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= -cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= -cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= -cloud.google.com/go/video v1.17.1/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= -cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= -cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= -cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= -cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= -cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo= -cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= -cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= -cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= -cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= -cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= -cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU= -cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= -cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= -cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= -cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= -cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro= -cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= -cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= -cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= -cloud.google.com/go/vmwareengine v0.4.1/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= -cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= -cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= -cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= -cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs= -cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= -cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= -cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= -cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= -cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc= -cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= -cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= -cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= -cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= -cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= -cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= -cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= -cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= -cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= +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 v0.0.0-20200908233159-fafe600ec8bd/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.0.0-20200908233159-fafe600ec8bd/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest/adal v0.0.0-20200908233159-fafe600ec8bd/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= -github.com/Azure/go-autorest/autorest/date v0.0.0-20200908233159-fafe600ec8bd/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.0.0-20200908233159-fafe600ec8bd/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.0.0-20200908233159-fafe600ec8bd/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.0.0-20200908233159-fafe600ec8bd/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +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.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= 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/ClickHouse/clickhouse-go v1.3.12/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= -github.com/MakeNowJust/heredoc v0.0.0-20171113091838-e9091a26100e/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.0.2/go.mod h1:oesJ8kPONMONaZgtiHNzUShJbksypC5kWczhZAf6+aU= -github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= -github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= +github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/hcsshim v0.8.9 h1:VrfodqvztU8YSOvygU+DN1BGaSGxmrNfqOv5oOuX2Bk= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= -github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY= +github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2 h1:JCHLVE3B+kJde7bIEo5N4J+ZbLhp0J1Fs+ulyRws4gE= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/logrus-bugsnag v0.0.0-20250605201603-d55aa3c8353b h1:RWJnu6vQ5x4LoCuqk5T9gReTET0rQjQlpwcbNtB1KdI= +github.com/Shopify/logrus-bugsnag v0.0.0-20250605201603-d55aa3c8353b/go.mod h1:nBISMsZeFRL0qdZ1pKCSFv0j4veW0nOdVpOa49IMLeI= +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/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +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/alessio/shellescape v1.2.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/apache/thrift v0.12.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/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-sdk-go v0.0.0-20210122191723-2c7b39c8f2e2/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +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/bitly/go-hostpool v0.0.0-20191224193725-5d3b4dc6ed47/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= -github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= +github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= -github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/bshuster-repo/logrus-logstash-hook v1.1.0 h1:o2FzZifLg+z/DN1OFmzTWzZZx/roaqt8IPZCIVco8r4= +github.com/bshuster-repo/logrus-logstash-hook v1.1.0/go.mod h1:Q2aXOe7rNuPgbBtPCOzYyWDvKX7+FpxE5sRdvcPoui0= github.com/bugsnag/bugsnag-go v1.5.3 h1:yeRUT3mUE13jL1tGwvoQsKdVbAsQx9AJ+fqahKveP04= github.com/bugsnag/bugsnag-go v1.5.3/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA= +github.com/bugsnag/bugsnag-go/v2 v2.2.0 h1:y4JJ6xNJiK4jbmq/BLXe09MGUNRp/r1Zpye6RKcPJJ8= +github.com/bugsnag/bugsnag-go/v2 v2.2.0/go.mod h1:Aoi1ax1kGbbkArShzXUQjxp6jM8gMh4qOtHLis/jY1E= github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/bugsnag/panicwrap v1.3.4 h1:A6sXFtDGsgU/4BLf5JT0o5uYg3EeKgGx3Sfs+/uk3pU= +github.com/bugsnag/panicwrap v1.3.4/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= 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/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.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= -github.com/che-incubator/kubernetes-image-puller-operator v0.0.0-20210929175054-0128446f5af7 h1:E18RJWMhzdbW5C27h4/TgTD5n5I+r43EO+8YJ9/fqRU= -github.com/che-incubator/kubernetes-image-puller-operator v0.0.0-20210929175054-0128446f5af7/go.mod h1:2x0FwJwxUaaKmAHF5+DIq27BmL2d0mkwWOQiXYHmQQM= -github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= -github.com/cncf/udpa/go v0.0.0-20200327203949-e8cd3a4bb307/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/che-incubator/kubernetes-image-puller-operator v0.0.0-20250214104625-65e5ec32f521 h1:G+cOdbPstYLULrGVYyNB1nyLvBOeE868miLGPBN35Qc= +github.com/che-incubator/kubernetes-image-puller-operator v0.0.0-20250214104625-65e5ec32f521/go.mod h1:Zy82QzR+0uGCoM0EMjacJaJgmuciYEZT1JIDqW2AGRA= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/cockroach-go v0.0.0-20190925194419-606b3d062051/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= +github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/containerd/cgroups v0.0.0-20191002205938-3de5a6bb4823 h1:JNIm5GNY5szn/lEd6FqgAYmANPQwu0/roESxtsVdNes= -github.com/containerd/cgroups v0.0.0-20191002205938-3de5a6bb4823/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= +github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/containerd v1.3.3 h1:LoIzb5y9x5l8VKAlyrbusNPXqBY0+kviRloxFUMFwKc= -github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb h1:nXPkFq8X1a9ycY3GYQpFNxHh3j2JgY7zDZfq2EXMIzk= +github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.6.3 h1:JfgUEIAH07xDWk6kqz0P3ArZt+KJ9YeihSC9uyFtSKg= +github.com/containerd/containerd v1.6.3/go.mod h1:gCVGrYRYFm2E8GmuUIbj/NGD7DLZQLzSJQazjVKDOig= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= +github.com/containerd/continuity v0.2.2 h1:QSqfxcn8c+12slxwu00AtzXrsami0MJb/MQs9lOLHLA= +github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/ttrpc v1.0.1 h1:IfVOxKbjyBn9maoye2JN95pgGYOmPkQVqxtOu7rtNIc= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/containerd/ttrpc v1.1.0 h1:GbtyLRxb0gOLR0TYQWt3O6B0NvT8tMdorEHqIQo/lWI= +github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= 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-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +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-20180108230652-97fdf19511ea/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 v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +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/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= +github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= +github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= +github.com/cznic/internal v0.0.0-20180608152220-f44710a21d00/go.mod h1:olo7eAdKwJdXxb55TKGLiJ6xt1H0/tiiRCWKVLmtjY4= +github.com/cznic/lldb v1.1.0/go.mod h1:FIZVUmYUVhPwRiPzL8nD/mpFcJ/G7SSXjjXYG4uRI3A= github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/cznic/ql v1.2.0/go.mod h1:FbpzhyZrqr0PVlK6ury+PoW3T0ODUV22OeWIxcaOrSE= +github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ= +github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= +github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKXshKUbwUapqNncRrho4mkjQebgEHZLj8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= -github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As= -github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= -github.com/devfile/api/v2 v2.2.2 h1:DXRCPWFlZhTIE38Of2jzTRjQHadfbxBC8GS+m+EjoCU= -github.com/devfile/api/v2 v2.2.2/go.mod h1:qp8jcw12y1JdCsxjK/7LJ7uWaJOxcY1s2LUk5PhbkbM= -github.com/devfile/devworkspace-operator v0.35.0 h1:EY1EVIYa5kYsy8xxfnaWH7qyVmRYRMjDi1lENyuMVY4= -github.com/devfile/devworkspace-operator v0.35.0/go.mod h1:sq9bQSIVkt2c3pEBEgslCMA+xSt3hFur7tR5eE6h/+A= +github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= +github.com/devfile/api/v2 v2.3.0 h1:3LG0c5Z2jZuI8ReCf4OQMHfiKxsOgxTxz5c1Y9CqUYI= +github.com/devfile/api/v2 v2.3.0/go.mod h1:lVyGiwv71WQpJwcwCweXOVcTnknEg7CwhFS5EgwiqVQ= +github.com/devfile/devworkspace-operator v0.35.1 h1:2dyxbEJjHOPLRG0L+qZk+EZMNv2jD7tk3XSzQtkoPAA= +github.com/devfile/devworkspace-operator v0.35.1/go.mod h1:sq9bQSIVkt2c3pEBEgslCMA+xSt3hFur7tR5eE6h/+A= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dhui/dktest v0.3.2/go.mod h1:l1/ib23a/CmxAe7yixtrYPc8Iy90Zy2udyaHINM5p58= -github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492 h1:FwssHbCDJD025h+BchanCwE1Q8fyMgqDr2mOQAWOLGw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= +github.com/docker/cli v20.10.11+incompatible h1:tXU1ezXcruZQRrMP8RN2z9N91h+6egZTS1gsPsKantc= +github.com/docker/cli v20.10.11+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.7.0+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/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ= +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/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.14+incompatible h1:+T9/PRYWNDo5SZl5qS1r9Mo/0Q8AwxKKPtu9S1yxM0w= +github.com/docker/docker v20.10.14+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.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o= +github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= 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.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= 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/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/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/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/edsrzf/mmap-go v0.0.0-20181215214921-188cc3b666ba/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +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 v0.0.0-20170320065105-0bce6a688712/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-20200129102538-a2fa14558f9a/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -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.0.0-20200213201256-ba8e577f987f/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +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/v3 v3.11.2 h1:1onLa9DcsMYO9P+CXaL0dStDqQ2EHHXLiz+BtnqkLAU= +github.com/emicklei/go-restful/v3 v3.11.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= -github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.1.0 h1:B0aXl1o/1cP8NbviYiBMkcHBtUjIJ1/Ccg6b+SwCLQg= -github.com/evanphx/json-patch/v5 v5.1.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.9.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.2.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +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/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsouza/fake-gcs-server v1.17.0/go.mod h1:D1rTE4YCyHFNa99oyJJ5HyclvN/0uQR+pM/VdlL83bw= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/globalsign/mgo v0.0.0-20160323214708-72aab81a5dec/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-air/gini v1.0.1/go.mod h1:swH5OTtiG/X/YrU06r288qZwq6I1agpbuXQOB55xqGU= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7NhEvIN9+Z6R5/xH4I= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw= +github.com/go-git/go-git/v5 v5.13.0 h1:vLn5wlGIh/X78El6r3Jr+30W16Blk0CTcxTYcYPWi5E= +github.com/go-git/go-git/v5 v5.13.0/go.mod h1:Wjo7/JyVKtQgUNdXYXIepzWfJQkUEIGvkvVkiXRR/zw= +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-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-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.3.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.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU= -github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= -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.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= +github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= -github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= -github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-sql-driver/mysql v1.4.1/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 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= github.com/goccy/go-yaml v1.8.1/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y= github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +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.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-migrate/migrate/v4 v4.10.0 h1:76R6UL3BGnDTpYeittMtfpaNvGBH5zMZatO/fCzIjWo= -github.com/golang-migrate/migrate/v4 v4.10.0/go.mod h1:Llx0NRzBKs/zbR/Pc0huEpJA2195sJVkGU5dCyjQ678= +github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= +github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +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/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +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/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.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= +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/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.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-github/v18 v18.0.0-20180920013327-07716bad7a0c/go.mod h1:Bf4Ut1RTeH0WuX7Z4Zf7N+qp/YqgcFOxvTLuSO+aY/k= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367 h1:ScAXWS+TR6MZKex+7Z8rneuSJH+FSDqd6ocQyl+ZHo4= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/martian v0.0.0-20180813215018-c223d6f7955e/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20180921154107-7dadf64105bb h1:+A9aN/lFi+7+d3iTfMIy1sLWAJ1YQe5jfZVgSPhk53I= -github.com/google/pprof v0.0.0-20180921154107-7dadf64105bb/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/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/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= -github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -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/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +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.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/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.2/go.mod h1:P0d+GwDcJO8XvMi7aihGGl/CkivFa9JX/V/FfjyYzI0= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +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/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +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/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= +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/grpc-ecosystem/grpc-health-probe v0.3.2/go.mod h1:izVOQ4RWbjUR6lm4nn+VLJyQ+FyaiGmprEYgI04Gs7U= +github.com/h2non/filetype v1.1.1 h1:xvOwnXKAckvtLWsN398qS9QhlxlnVXBjXBydK2/UFB4= +github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= +github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c h1:fEE5/5VNnYUoBOj2I9TP8Jc+a7lge3QWn9DKE7NCwfc= +github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c/go.mod h1:ObS/W+h8RYb1Y7fYivughjxojTmIu5iAIjSrSLCLeqE= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/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.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +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.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/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/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= -github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= +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/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +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/itchyny/astgen-go v0.0.0-20200519013840-cf3ea398f645/go.mod h1:296z3W7Xsrp2mlIY88ruDKscuvrkL6zXCNRtaYVshzw= -github.com/itchyny/go-flags v1.5.0/go.mod h1:lenkYuCobuxLBAd/HGFE4LRoW8D3B6iXRQfWYJ+MNbA= -github.com/itchyny/gojq v0.11.0/go.mod h1:my6D2qN2Sm6qa+/5GsPDUZlCWGR+U8Qsa9he76sudv0= -github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/pgconn v1.3.2/go.mod h1:LvCquS3HbBKwgl7KbX9KyqEIumJAbm1UMcTvGaIf3bM= -github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= -github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= -github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= -github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= +github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= +github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d h1:A2/B900ip/Z20TzkLeGRNy1s6J2HmH9AmGt+dHyqb4I= +github.com/joelanford/ignore v0.0.0-20210607151042-0d25dc18b62d/go.mod h1:7HQupe4vyNxMKXmM5DFuwXHsqwMyglcYmZBtlDPIcZ8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +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/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v0.0.0-20200608025830-a1ca0830781e h1:WF9fQ5iQufxf34QPLSMWdShF5rABCC9tJ0sFAO4MrT0= -github.com/json-iterator/go v0.0.0-20200608025830-a1ca0830781e/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +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/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +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/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 v0.0.0-20150401064343-9a4a02dbe491/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +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/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +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 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.0.0-20200729040243-ead452280cd0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v0.0.0-20180113180813-282ce0e5322c/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/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/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/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/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/leodido/go-urn v0.0.0-20201213191625-6c96508144d0/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= -github.com/lestrrat-go/strftime v1.0.1/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= -github.com/lib/pq v0.0.0-20190415174712-51e2106eed1c/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20200218084223-8edcc4e51f39 h1:z5hZT2Yph+lco8ao95H3QFSoLwHZj6udVmA6QXCkCME= -github.com/mailru/easyjson v0.0.0-20200218084223-8edcc4e51f39/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-shellwords v0.0.0-20180201004752-39dbbfa24bbc/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-sqlite3 v0.0.0-20190716055609-b612a2feea6a h1:iD45s1L+IkClo7t1yIKGardyymjLbnV/oY4S/vwbAE8= -github.com/mattn/go-sqlite3 v0.0.0-20190716055609-b612a2feea6a/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +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/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mikefarah/yaml/v2 v2.4.0/go.mod h1:ahVqZF4n1W4NqwvVnZzC4es67xsW9uR/RRf2RRxieJU= -github.com/mikefarah/yq/v2 v2.4.1/go.mod h1:i8SYf1XdgUvY2OFwSqGAtWOOgimD2McJ6iutoxRm4k0= github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37/go.mod h1:dYWq+UWoFCDY1TndvFUQuhBbIYmZpjreC8adEAx93zE= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +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/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= 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/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 h1:cvy4lBOYN3gKfKj8Lzz5Q9TfviP+L7koMHY7SvkyTKs= -github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= -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/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +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/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= +github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +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.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d h1:7PxY7LVfSZm7PEeBTyK1rj1gABdCO2mbri6GKO1cMDs= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= -github.com/neo4j-drivers/gobolt v1.7.4/go.mod h1:O9AUbip4Dgre+CD3p40dnMD4a4r52QBIfblg5k7CTbE= -github.com/neo4j/neo4j-go-driver v1.7.4/go.mod h1:aPO0vVr+WnhEJne+FgFjfsjzAnssPFLucHgGZ76Zb/U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= -github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +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.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= +github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +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.5.0/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.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +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= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830 h1:yvQ/2Pupw60ON8TYEIGGTAI77yZsWYkiOeHFZWkwlCk= -github.com/opencontainers/runc v1.0.0-rc2.0.20190611121236-6cc515888830/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/openshift/api v0.0.0-20230120182048-88b476f987ed h1:G0GVW25yJYBOwVisC3K06d2TZDZtJOYWL8nyJPkD9Fg= -github.com/openshift/api v0.0.0-20230120182048-88b476f987ed/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4= -github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0/go.mod h1:uUQ4LClRO+fg5MF/P6QxjMCb1C9f7Oh4RKepftDnEJE= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/operator-framework/api v0.3.7-0.20200602203552-431198de9fc2/go.mod h1:Xbje9x0SHmh0nihE21kpesB38vk3cyxnE6JdDS8Jo1Q= -github.com/operator-framework/api v0.8.0/go.mod h1:L7IvLd/ckxJEJg/t4oTTlnHKAJIP/p51AvEslW3wYdY= -github.com/operator-framework/api v0.15.0 h1:4f9i0drtqHj7ykLoHxv92GR43S7MmQHhmFQkfm5YaGI= -github.com/operator-framework/api v0.15.0/go.mod h1:scnY9xqSeCsOdtJtNoHIXd7OtHZ14gj1hkDA4+DlgLY= -github.com/operator-framework/operator-lifecycle-manager v0.18.1 h1:Sp5EqkUR3udHysNAHQAFLAhnZBdZ4Gzhl9+nxL+sOjc= -github.com/operator-framework/operator-lifecycle-manager v0.18.1/go.mod h1:zFexXul1dzWyM1fe6ZymNvTo9nqPCFJ370AVmZB43lc= -github.com/operator-framework/operator-registry v1.13.6 h1:h/dIjQQS7uneQNRifrSz7h0xg4Xyjg6C9f6XZofbMPg= -github.com/operator-framework/operator-registry v1.13.6/go.mod h1:YhnIzOVjRU2ZwZtzt+fjcjW8ujJaSFynBEu7QVKaSdU= +github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= +github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +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/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/openshift/api v0.0.0-20250529074221-97812373b6b4 h1:jcY1inFa4gsygSbIId2jbCRGnGvEEcCmPZHaMc3PnT4= +github.com/openshift/api v0.0.0-20250529074221-97812373b6b4/go.mod h1:yk60tHAmHhtVpJQo3TwVYq2zpuP70iJIFDCmeKMIzPw= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/operator-framework/api v0.7.1/go.mod h1:L7IvLd/ckxJEJg/t4oTTlnHKAJIP/p51AvEslW3wYdY= +github.com/operator-framework/api v0.31.0 h1:tRsFTuZ51xD8U5QgiPo3+mZgVipHZVgRXYrI6RRXOh8= +github.com/operator-framework/api v0.31.0/go.mod h1:57oCiHNeWcxmzu1Se8qlnwEKr/GGXnuHvspIYFCcXmY= +github.com/operator-framework/operator-lifecycle-manager v0.22.0 h1:7DEWOq24HQ0l5xPOXMhn17XaJACgwoipz+JfQ7QCXZw= +github.com/operator-framework/operator-lifecycle-manager v0.22.0/go.mod h1:4zssIIl23ohxS1nXRU9xTkBmwt+qleuHMO02BaWOHLA= +github.com/operator-framework/operator-registry v1.17.5 h1:LR8m1rFz5Gcyje8WK6iYt+gIhtzqo52zMRALdmTYHT0= +github.com/operator-framework/operator-registry v1.17.5/go.mod h1:sRQIgDMZZdUcmHltzyCnM6RUoDF+WS8Arj1BQIARDS8= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pbnjay/strptime v0.0.0-20140226051138-5c05b0d668c9/go.mod h1:6Hr+C/olSdkdL3z68MlyXWzwhvwmwN7KuUFXGb3PoOk= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/peterbourgon/diskv v0.0.0-20180312054125-0646ccaebea1/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +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/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= -github.com/pierrec/lz4 v0.0.0-20180610162716-6b9367c9ff40/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.0.0-20200114194744-614d223910a1 h1:sQxdYJO27MY0gTFDEdflZlMZ4HxHLZIq/qkdYfhlXx8= -github.com/pkg/errors v0.0.0-20200114194744-614d223910a1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +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-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/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 v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -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/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -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/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +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.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +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.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.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.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +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.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +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.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +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/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/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/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +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 v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +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.0-20190321000552-67fc4837d267 h1:k5wQOOB9mm6XdgwnTGopZG83by3g8A2MJ7LvrP3h+/0= -github.com/spf13/cobra v0.0.0-20190321000552-67fc4837d267/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +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= +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/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= 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/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ= -github.com/tidwall/pretty v0.0.0-20200828150932-ef453c788d6a/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +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.2.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -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/yuin/goldmark v0.0.0-20200826112251-7b90f04af431/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.7 h1:4DTF1WOM2ZZS/xMOkTFBOcb6XiHu/PKn3rVo6dbewQE= github.com/yvasiyarov/gorelic v0.0.7/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20160601141957-9c099fbc30e9 h1:AsFN8kXcCVkUFHyuzp1FtYbzp1nCO/H6+1uPSGEyPzM= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20160601141957-9c099fbc30e9/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= -go.etcd.io/bbolt v0.0.0-20190608165704-a0458a2b3570 h1:dRKYt2UkSi5tJoDmlnbsZIHaSf1HYUDy3emO+S3qBhk= -go.etcd.io/bbolt v0.0.0-20190608165704-a0458a2b3570/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +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/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= +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.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.opencensus.io v0.20.1/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.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +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.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.18.1 h1:CSUJ2mjFszzEWt4CdKISEuChVIXGBn3lAPwkRGyVrc4= -go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= -golang.org/x/exp v0.0.0-20190426190305-956cc1757749/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= +go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= +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-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +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-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= -golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +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.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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-20181005035420-146acd28ed58/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-20181108082009-03003ca0c849/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-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-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-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191021144547-ec77196f6094/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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/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-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/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-20190222072716-a9d3bda3a223/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-20190321052220-f7bb7a8bee54/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-20190426135247-a129542de9ae/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-20190514135907-3a4b5fb9f71f/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-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/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-20190916202348-b4ddaad3f8a3/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-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/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-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-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/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-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= +golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= 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-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.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/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-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-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-20190425222832-ad9eeb80039a/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-20190617190820-da514acc4774/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-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +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-20190920225731-5eefd052ad72/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-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-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200616195046-dc31b401abb5/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-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= 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-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= -gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= +gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.3.2/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.3.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.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 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-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200128133413-58ce757ed39b/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-20200612171551-7676ae05be11/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200701001935-0939c5918c31/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-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= -google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= -google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= -google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto v0.0.0-20230629202037-9506855d4529/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= -google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= -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 v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e h1:YA5lmSs3zc/5w+xsRcHqpETkaYyK63ivEPzNTcUUlSA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +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.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.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v0.0.0-20200709232328-d8193ee9cc3e/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +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.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 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 v1.0.0-20141024133853-64131543e789 h1:NMiUjDZiD6qDVeBOzpImftxXzQHCp2Y2QLdmaqU9MRk= -gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/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/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= -gopkg.in/imdario/mergo.v0 v0.3.7/go.mod h1:9qPP6AGrlC1G2PTNXko614FwGZvorN7MiBU0Eppok+U= -gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= 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= @@ -1238,141 +1171,111 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24 gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog= 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-20161208151619-d5d1b5820637/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.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-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +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.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -helm.sh/helm/v3 v3.0.0-20200422233323-0a9a9a88e8af/go.mod h1:WYsFJuMASa/4XUqLyv54s0U/f3mlAaRErGmyy4z921g= -honnef.co/go/tools v0.0.0-20200822191040-81508471876c h1:o0L5lXsoqvBZzwlTTEWpbB5kS9ueptT+t4Q005w+URk= -honnef.co/go/tools v0.0.0-20200822191040-81508471876c/go.mod h1:9cTM0oWhtRNLsRAUBTXQteHk4uCimaaBtLKqcyyIozE= -k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4= -k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8= +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/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= -k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= -k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg= -k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= -k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= -k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs= +k8s.io/api v0.32.7 h1:CBhHkoi3YJW8QQI6VL/Hu9f1HHVImmuIh513d4H4VfQ= +k8s.io/api v0.32.7/go.mod h1:YEB46LZ/M0/9t0m+R2FxW5fkZAUR/eoS6sZQKS3mBYk= k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk= k8s.io/apiextensions-apiserver v0.20.6/go.mod h1:qO8YMqeMmZH+lV21LUNzV41vfpoE9QVAJRA+MNqj0mo= -k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA= -k8s.io/apiextensions-apiserver v0.21.3/go.mod h1:kl6dap3Gd45+21Jnh6utCx8Z2xxLm8LGDkprcd+KbsE= -k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI= -k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM= -k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= +k8s.io/apiextensions-apiserver v0.32.7 h1:w7IzqA3SZG9KNm5YMtrrqY3ipPgt13rZevDaZSubARA= +k8s.io/apiextensions-apiserver v0.32.7/go.mod h1:CelzsiBUTLZeJ+MxBEcuDEgu9Qr3LQkZqmydvA/W9UA= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= -k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI= -k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= -k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= -k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo= +k8s.io/apimachinery v0.32.7 h1:1vTegNQIfM7dvZrMV5//6jJv2odKAnadv9Bg+doJmaA= +k8s.io/apimachinery v0.32.7/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= -k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY= -k8s.io/apiserver v0.21.3/go.mod h1:eDPWlZG6/cCCMj/JBcEpDoK+I+6i3r9GsChYBHSbAzU= -k8s.io/cli-runtime v0.17.2/go.mod h1:aa8t9ziyQdbkuizkNLAw3qe3srSyWh9zlSB7zTqRNPI= -k8s.io/cli-runtime v0.20.1/go.mod h1:6wkMM16ZXTi7Ow3JLYPe10bS+XBnIkL6V9dmEz0mbuY= -k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI= -k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8= +k8s.io/cli-runtime v0.20.6/go.mod h1:JVERW478qcxWrUjJuWQSqyJeiz9QC4T6jmBznHFBC8w= k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= -k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= -k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU= -k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU= -k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE= -k8s.io/code-generator v0.0.0-20200708172309-f186a36abf5c/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= -k8s.io/component-base v0.17.2/go.mod h1:zMPW3g5aH7cHJpKYQ/ZsGMcgbsA/VyhEugF3QT1awLs= +k8s.io/client-go v0.32.7 h1:ZDhv3JTaQ/IejnNXRePBZdRecAEvxf8+pFdt/ruuWXc= +k8s.io/client-go v0.32.7/go.mod h1:/he4Akuzee/lTiWmcsrpZfCQ2LPNLTC2qqumLVAw/Fw= +k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= +k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= +k8s.io/code-generator v0.20.6/go.mod h1:i6FmG+QxaLxvJsezvZp0q/gAEzzOz3U53KFibghWToU= k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= -k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA= -k8s.io/component-base v0.21.3/go.mod h1:kkuhtfEHeZM6LkX0saqSK8PbdO7A0HigUngmhhrwfGQ= -k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4= -k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU= -k8s.io/component-helpers v0.20.1/go.mod h1:Q8trCj1zyLNdeur6pD2QvsF8d/nWVfK71YjN5+qVXy4= +k8s.io/component-helpers v0.20.6/go.mod h1:d4rFhZS/wxrZCxRiJJiWf1mVGVeMB5/ey3Yv8/rOp78= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= 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= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-aggregator v0.0.0-20180912235703-14b8d2d93fcb/go.mod h1:8sbzT4QQKDEmSCIbfqjV0sd97GpUT7A4W626sBiYJmU= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -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-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= -k8s.io/kubectl v0.0.0-20201218185502-10b66c3fd14b/go.mod h1:2bE0JLYTRDVKDiTREFsjLAx4R2GvUtL/mGYFXfFFMzY= -k8s.io/metrics v0.20.2/go.mod h1:yTck5nl5wt/lIeLcU6g0b8/AKJf2girwe0PQiaM4Mwk= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= +k8s.io/kubectl v0.20.6/go.mod h1:yTCGVrlkBuQhFbKA1R65+lQ9hH7XeyOqUd0FUPFicPg= +k8s.io/metrics v0.20.6/go.mod h1:d+OAIaXutom9kGWcBit/M8OkDpIzBKTsm47+KcUt7VI= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/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-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y= -k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg= -modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8= -modernc.org/file v1.0.0/go.mod h1:uqEokAEn1u6e+J45e54dsEA/pw4o7zLrA2GwyntZzjw= -modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8= -modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= -modernc.org/internal v1.0.0/go.mod h1:VUD/+JAkhCpvkUitlEOnhpVxCgsBI90oTzSCRcqQVSM= -modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8= -modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= -modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY= -modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k= -modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= -modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/letsencrypt v0.0.3 h1:H7xDfhkaFFSYEJlKeq38RwX2jYcnTeHuDQyT+mMNMwM= rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= 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.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= +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/controller-runtime v0.8.0/go.mod h1:v9Lbj5oX443uR7GXYY46E0EE2o7k2YxQ58GxVNeXSW4= -sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU= -sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA= -sigs.k8s.io/controller-runtime v0.14.4 h1:Kd/Qgx5pd2XUL08eOV2vwIq3L9GhIbJ5Nxengbd4/0M= -sigs.k8s.io/controller-runtime v0.14.4/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= -sigs.k8s.io/controller-tools v0.6.0/go.mod h1:baRMVPrctU77F+rfAuH2uPqW93k6yQnZA2dhUOr7ihc= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kind v0.10.0/go.mod h1:fb32zUw7ewC47bPwLnwhf47wd/vADtv3c38KP7sjIlo= +sigs.k8s.io/controller-runtime v0.20.4 h1:X3c+Odnxz+iPTRobG4tp092+CvBU9UK0t/bRf+n0DGU= +sigs.k8s.io/controller-runtime v0.20.4/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= +sigs.k8s.io/controller-tools v0.4.1/go.mod h1:G9rHdZMVlBDocIxGkK3jHLWqcTMNvveypYJwrvYKjWU= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/kind v0.11.1/go.mod h1:fRpgVhtqAWrtLB9ED7zQahUimpUXuG/iHT88xYqEGIA= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= -sigs.k8s.io/structured-merge-diff v1.0.2/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= 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.0/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.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +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.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ= +sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4= diff --git a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 578336c5e8..c60aa8d6cd 100644 --- a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -15,7 +15,7 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: eclipse-che/che-operator-serving-cert - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.18.0 labels: app.kubernetes.io/instance: che app.kubernetes.io/name: che @@ -137,10 +137,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -200,10 +203,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -252,10 +258,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -315,10 +324,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -371,10 +383,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -434,10 +449,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -486,10 +504,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -549,10 +570,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -875,10 +899,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -938,10 +965,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1026,10 +1056,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1089,10 +1122,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1408,10 +1444,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1471,10 +1510,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1584,10 +1626,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1647,10 +1692,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -1767,10 +1815,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -1830,10 +1881,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2003,10 +2057,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or its @@ -2066,10 +2123,13 @@ spec: be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its key @@ -2286,7 +2346,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2295,7 +2354,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -2309,7 +2367,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -2325,13 +2382,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2340,20 +2394,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2372,27 +2422,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2421,13 +2464,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -2451,7 +2491,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -2518,7 +2557,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -2590,7 +2628,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -2628,7 +2665,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2644,13 +2680,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2659,20 +2692,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2691,27 +2720,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2767,7 +2789,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -2783,13 +2804,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -2798,20 +2816,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -2830,27 +2844,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -2892,7 +2899,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -2909,13 +2915,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -3009,13 +3013,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -3063,7 +3064,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -3075,13 +3075,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -3142,7 +3139,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3151,7 +3147,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -3165,7 +3160,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -3182,13 +3176,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3196,20 +3187,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3227,27 +3214,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3275,13 +3255,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -3304,7 +3281,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -3346,7 +3322,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -3418,7 +3393,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -3455,7 +3429,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3472,13 +3445,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3486,20 +3456,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3517,27 +3483,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -3593,7 +3552,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -3610,13 +3568,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -3624,20 +3579,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -3655,27 +3606,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -4109,10 +4053,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4176,10 +4123,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4442,10 +4392,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4509,10 +4462,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -4741,10 +4697,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -4808,10 +4767,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5080,10 +5042,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap @@ -5147,10 +5112,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret @@ -5372,6 +5340,8 @@ spec: description: OpenShift security context constraint to build containers. type: string + required: + - openShiftSecurityContextConstraint type: object defaultComponents: description: |- @@ -5418,7 +5388,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5427,7 +5396,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -5441,7 +5409,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -5457,13 +5424,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5472,20 +5436,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5504,27 +5464,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5553,13 +5506,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -5583,7 +5533,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -5650,7 +5599,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -5722,7 +5670,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -5760,7 +5707,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5776,13 +5722,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5791,20 +5734,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5823,27 +5762,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -5899,7 +5831,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -5915,13 +5846,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -5930,20 +5858,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -5962,27 +5886,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6024,7 +5941,6 @@ spec: description: |- Allows importing a plugin. - Plugins are mainly imported devfiles that contribute components, commands and events as a consistent single unit. They are defined in either YAML files following the devfile syntax, @@ -6041,13 +5957,11 @@ spec: Command that consists in applying a given component definition, typically bound to a devworkspace event. - For example, when an `apply` command is bound to a `preStart` event, and references a `container` component, it will start the container as a K8S initContainer in the devworkspace POD, unless the component has its `dedicatedPod` field set to `true`. - When no `apply` command exist for a given component, it is assumed the component will be applied at devworkspace start by default, unless `deployByDefault` for that component is set to false. @@ -6141,13 +6055,10 @@ spec: description: |- The actual command-line string - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string component: @@ -6195,7 +6106,6 @@ spec: A *hotReloadCapable* `build` command is expected to be executed only once and won't be executed again. This field is taken into account only for commands `build`, `run` and `debug` with `isDefault` set to `true`. - Default value is `false` type: boolean label: @@ -6207,13 +6117,10 @@ spec: description: |- Working directory where the command should be executed - Special variables that can be used: - - `$PROJECTS_ROOT`: A path where projects sources are mounted as defined by container component's sourceMapping. - - `$PROJECT_SOURCE`: A path to a project source ($PROJECTS_ROOT/). If there are multiple projects, this will point to the directory of the first one. type: string type: object @@ -6274,7 +6181,6 @@ spec: description: |- The arguments to supply to the command running the dockerimage component. The arguments are supplied either to the default command provided in the image or to the overridden command. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6283,7 +6189,6 @@ spec: description: |- The command to run in the dockerimage component instead of the default one provided in the image. - Defaults to an empty array, meaning use whatever is defined in the image. items: type: string @@ -6297,7 +6202,6 @@ spec: Specify if a container should run in its own separated pod, instead of running as part of the main development environment pod. - Default value is `false` type: boolean endpoints: @@ -6314,13 +6218,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6328,20 +6229,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6359,27 +6256,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6407,13 +6297,10 @@ spec: description: |- Environment variables used in this container. - The following variables are reserved and cannot be overridden via env: - - `$PROJECTS_ROOT` - - `$PROJECT_SOURCE` items: properties: @@ -6436,7 +6323,6 @@ spec: Toggles whether or not the project source code should be mounted in the component. - Defaults to true for all component types except plugins and components that set `dedicatedPod` to true. type: boolean sourceMapping: @@ -6478,7 +6364,6 @@ spec: description: |- Defines if the image should be built during startup. - Default value is `false` type: boolean dockerfile: @@ -6550,7 +6435,6 @@ spec: description: |- Specify if a privileged builder pod is required. - Default value is `false` type: boolean srcType: @@ -6587,7 +6471,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6604,13 +6487,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6618,20 +6498,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6649,27 +6525,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6725,7 +6594,6 @@ spec: description: |- Defines if the component should be deployed during startup. - Default value is `false` type: boolean endpoints: @@ -6742,13 +6610,10 @@ spec: description: |- Map of implementation-dependant string-based free-form attributes. - Examples of Che-specific attributes: - - cookiesAuthEnabled: "true" / "false", - - type: "terminal" / "ide" / "ide-dev", type: object x-kubernetes-preserve-unknown-fields: true @@ -6756,20 +6621,16 @@ spec: description: |- Describes how the endpoint should be exposed on the network. - - `public` means that the endpoint will be exposed on the public network, typically through a K8S ingress or an OpenShift route. - - `internal` means that the endpoint will be exposed internally outside of the main devworkspace POD, typically by K8S services, to be consumed by other elements running on the same cloud internal network. - - `none` means that the endpoint will not be exposed and will only be accessible inside the main devworkspace POD, on a local address. - Default value is `public` enum: - public @@ -6787,27 +6648,20 @@ spec: description: |- Describes the application and transport protocols of the traffic that will go through this endpoint. - - `http`: Endpoint will have `http` traffic, typically on a TCP connection. It will be automaticaly promoted to `https` when the `secure` field is set to `true`. - - `https`: Endpoint will have `https` traffic, typically on a TCP connection. - - `ws`: Endpoint will have `ws` traffic, typically on a TCP connection. It will be automaticaly promoted to `wss` when the `secure` field is set to `true`. - - `wss`: Endpoint will have `wss` traffic, typically on a TCP connection. - - `tcp`: Endpoint will have traffic on a TCP connection, without specifying an application protocol. - - `udp`: Endpoint will have traffic on an UDP connection, without specifying an application protocol. - Default value is `http` enum: - http @@ -6983,7 +6837,6 @@ spec: When set to `false` (the default value), the devEnvironments.security.containerSecurityContext field is ignored, and the following container SecurityContext is applied: - containerSecurityContext: allowPrivilegeEscalation: true capabilities: @@ -7027,10 +6880,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7090,10 +6946,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7291,10 +7150,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the ConfigMap or @@ -7354,10 +7216,13 @@ spec: from. Must be a valid secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the Secret or its @@ -7482,6 +7347,30 @@ spec: 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows. type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object capabilities: description: |- The capabilities to add/drop when running containers. @@ -7495,6 +7384,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic drop: description: Removed capabilities items: @@ -7502,6 +7392,7 @@ spec: type type: string type: array + x-kubernetes-list-type: atomic type: object privileged: description: |- @@ -7513,7 +7404,7 @@ spec: procMount: description: |- procMount denotes the type of proc mount to use for the containers. - The default is DefaultProcMount which uses the container runtime defaults for + The default value is Default which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. @@ -7588,14 +7479,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7623,12 +7513,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7644,17 +7531,38 @@ spec: PodSecurityContext used by all workspace-related pods. If set, defined values are merged into the default PodSecurityContext configuration. properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object fsGroup: description: |- 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: - 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) - If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows. format: int64 @@ -7698,6 +7606,32 @@ spec: Note that this field cannot be set when spec.os.name is windows. format: int64 type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string seLinuxOptions: description: |- The SELinux context to be applied to all containers. @@ -7734,14 +7668,13 @@ spec: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be set for any other type. type: string type: description: |- type indicates which kind of seccomp profile will be applied. Valid options are: - Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied. @@ -7751,17 +7684,28 @@ spec: type: object supplementalGroups: description: |- - 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. + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. Note that this field cannot be set when spec.os.name is windows. items: format: int64 type: integer type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string sysctls: description: |- Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported @@ -7782,6 +7726,7 @@ spec: - value type: object type: array + x-kubernetes-list-type: atomic windowsOptions: description: |- The Windows specific settings applied to all containers. @@ -7802,12 +7747,9 @@ spec: hostProcess: description: |- HostProcess determines if a container should be run as a 'Host Process' container. - This field is alpha-level and will only be honored by components that enable the - WindowsHostProcessContainers feature flag. Setting this field without the feature - flag will result in errors when validating the Pod. All of a Pod's containers must - have the same effective HostProcess value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: description: |- @@ -7899,7 +7841,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -7925,7 +7866,6 @@ spec: It is used to specify PersistentVolume access mode type to RWO/RWX when using per-user strategy, allowing user to re-use volume across multiple workspaces. - It defaults to ReadWriteOnce if not specified items: type: string @@ -8246,10 +8186,13 @@ spec: description: The key to select. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the @@ -8316,10 +8259,13 @@ spec: secret key. type: string name: + default: "" description: |- Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid? type: string optional: description: Specify whether the diff --git a/helmcharts/next/templates/org.eclipse.che.MutatingWebhookConfiguration.yaml b/helmcharts/next/templates/org.eclipse.che.MutatingWebhookConfiguration.yaml index 4fa8fd4521..30348ac5fb 100644 --- a/helmcharts/next/templates/org.eclipse.che.MutatingWebhookConfiguration.yaml +++ b/helmcharts/next/templates/org.eclipse.che.MutatingWebhookConfiguration.yaml @@ -24,7 +24,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service diff --git a/helmcharts/next/templates/org.eclipse.che.ValidatingWebhookConfiguration.yaml b/helmcharts/next/templates/org.eclipse.che.ValidatingWebhookConfiguration.yaml index 39b0ff6bf7..bb92bcff69 100644 --- a/helmcharts/next/templates/org.eclipse.che.ValidatingWebhookConfiguration.yaml +++ b/helmcharts/next/templates/org.eclipse.che.ValidatingWebhookConfiguration.yaml @@ -24,7 +24,6 @@ metadata: webhooks: - admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: name: che-operator-service diff --git a/main.go b/main.go deleted file mode 100644 index b0e3cfbc53..0000000000 --- a/main.go +++ /dev/null @@ -1,410 +0,0 @@ -// -// Copyright (c) 2019-2025 Red Hat, Inc. -// This program and the accompanying materials are made -// available under the terms of the Eclipse Public License 2.0 -// which is available at https://www.eclipse.org/legal/epl-2.0/ -// -// SPDX-License-Identifier: EPL-2.0 -// -// Contributors: -// Red Hat, Inc. - initial API and implementation -// - -package main - -import ( - "flag" - "os" - "time" - - dwr "github.com/devfile/devworkspace-operator/controllers/controller/devworkspacerouting" - "github.com/eclipse-che/che-operator/controllers/devworkspace/solver" - "github.com/eclipse-che/che-operator/controllers/usernamespace" - - securityv1 "github.com/openshift/api/security/v1" - - "github.com/devfile/devworkspace-operator/pkg/infrastructure" - devworkspaceinfra "github.com/devfile/devworkspace-operator/pkg/infrastructure" - "github.com/eclipse-che/che-operator/pkg/common/constants" - defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" - "github.com/eclipse-che/che-operator/pkg/common/signal" - "github.com/eclipse-che/che-operator/pkg/common/test" - "github.com/sirupsen/logrus" - - dwoApi "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" - "github.com/eclipse-che/che-operator/controllers/devworkspace" - "go.uber.org/zap/zapcore" - - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - // to ensure that exec-entrypoint and run can make use of them. - "k8s.io/client-go/discovery" - _ "k8s.io/client-go/plugin/pkg/client/auth" - - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/selection" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - osruntime "runtime" - - "fmt" - - "github.com/go-logr/logr" - configv1 "github.com/openshift/api/config/v1" - consolev1 "github.com/openshift/api/console/v1" - oauthv1 "github.com/openshift/api/oauth/v1" - templatev1 "github.com/openshift/api/template/v1" - - checontroller "github.com/eclipse-che/che-operator/controllers/che" - "github.com/eclipse-che/che-operator/pkg/common/utils" - - admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - - operatorsv1 "github.com/operator-framework/api/pkg/operators/v1" - operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" - packagesv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" - - image_puller_api "github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1" - projectv1 "github.com/openshift/api/project/v1" - routev1 "github.com/openshift/api/route/v1" - userv1 "github.com/openshift/api/user/v1" - appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - networkingv1 "k8s.io/api/networking/v1" - rbacv1 "k8s.io/api/rbac/v1" - - chev1 "github.com/eclipse-che/che-operator/api/v1" - chev2 "github.com/eclipse-che/che-operator/api/v2" -) - -var ( - scheme = runtime.NewScheme() - setupLog = ctrl.Log.WithName("setup") - metricsAddr string - enableLeaderElection bool - probeAddr string - - leaseDuration = 40 * time.Second - renewDeadline = 30 * time.Second -) - -const ( - leasesApiResourceName = "leases" -) - -func init() { - flag.StringVar(&metricsAddr, "metrics-bind-address", ":60000", "The address the metric endpoint binds to.") - flag.StringVar(&probeAddr, "health-probe-bind-address", ":6789", "The address the probe endpoint binds to.") - flag.BoolVar(&enableLeaderElection, "leader-elect", false, - "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") - - opts := zap.Options{ - Development: true, - Level: getLogLevel(), - } - opts.BindFlags(flag.CommandLine) - flag.Parse() - - logger := zap.New(zap.UseFlagOptions(&opts)) - ctrl.SetLogger(logger) - - if err := infrastructure.Initialize(); err != nil { - logger.Error(err, "Unable determine installation platform") - os.Exit(1) - } - - defaults.Initialize() - - printVersion(logger) - - utilruntime.Must(chev1.AddToScheme(scheme)) - utilruntime.Must(chev2.AddToScheme(scheme)) - //+kubebuilder:scaffold:scheme - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(admissionregistrationv1.AddToScheme(scheme)) - utilruntime.Must(rbacv1.AddToScheme(scheme)) - - // Setup Scheme for all resources - utilruntime.Must(image_puller_api.AddToScheme(scheme)) - utilruntime.Must(packagesv1.AddToScheme(scheme)) - utilruntime.Must(operatorsv1alpha1.AddToScheme(scheme)) - utilruntime.Must(operatorsv1.AddToScheme(scheme)) - utilruntime.Must(corev1.AddToScheme(scheme)) - - if infrastructure.IsOpenShift() { - utilruntime.Must(routev1.AddToScheme(scheme)) - utilruntime.Must(oauthv1.AddToScheme(scheme)) - utilruntime.Must(userv1.AddToScheme(scheme)) - utilruntime.Must(configv1.AddToScheme(scheme)) - utilruntime.Must(consolev1.AddToScheme(scheme)) - utilruntime.Must(projectv1.AddToScheme(scheme)) - utilruntime.Must(securityv1.Install(scheme)) - utilruntime.Must(templatev1.Install(scheme)) - } -} - -func getLogLevel() zapcore.Level { - switch logLevel, _ := os.LookupEnv("LOG_LEVEL"); logLevel { - case zapcore.DebugLevel.String(): - return zapcore.DebugLevel - case zapcore.InfoLevel.String(): - return zapcore.InfoLevel - case zapcore.WarnLevel.String(): - return zapcore.WarnLevel - case zapcore.ErrorLevel.String(): - return zapcore.ErrorLevel - case zapcore.PanicLevel.String(): - return zapcore.PanicLevel - default: - return zapcore.InfoLevel - } -} - -func printVersion(logger logr.Logger) { - logger.Info("Binary info ", "Go version", osruntime.Version()) - logger.Info("Binary info ", "OS", osruntime.GOOS, "Arch", osruntime.GOARCH) - logger.Info("Address ", "Metrics", metricsAddr) - logger.Info("Address ", "Probe", probeAddr) - - infra := "Kubernetes" - if infrastructure.IsOpenShift() { - infra = "OpenShift v4.x" - } - logger.Info("Operator is running on ", "Infrastructure", infra) -} - -// getWatchNamespace returns the Namespace the operator should be watching for changes -func getWatchNamespace() (string, error) { - // WatchNamespaceEnvVar is the constant for env variable WATCH_NAMESPACE - // which specifies the Namespace to watch. - // An empty value means the operator is running with cluster scope. - var watchNamespaceEnvVar = "WATCH_NAMESPACE" - - ns, found := os.LookupEnv(watchNamespaceEnvVar) - if !found { - return "", fmt.Errorf("%s must be set", watchNamespaceEnvVar) - } - - return ns, nil -} - -func main() { - watchNamespace, err := getWatchNamespace() - if err != nil { - setupLog.Error(err, "unable to get WatchNamespace, "+ - "the manager will watch and manage resources in all namespaces") - } - - config := ctrl.GetConfigOrDie() - - discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) - if err != nil { - setupLog.Error(err, "failed to create discovery client") - os.Exit(1) - } - - if !utils.IsK8SResourceServed(discoveryClient, leasesApiResourceName) { - setupLog.Info("Leader election was disabled", "Cause:", leasesApiResourceName+"k8s api resource is an absent.") - enableLeaderElection = false - } - - // Add the Dev Workspace API to the scheme - if err := dwoApi.AddToScheme(scheme); err != nil { - setupLog.Error(err, "Dev Workspace Operator is not installed") - os.Exit(1) - } - - // DWO use the infrastructure package for openshift detection. It needs to be initialized - // but only supports OpenShift v4 or Kubernetes. - if err := devworkspaceinfra.Initialize(); err != nil { - setupLog.Error(err, "failed to evaluate infrastructure which is needed for DevWorkspace support") - os.Exit(1) - } - - cacheFunction, err := getCacheFunc() - if err != nil { - setupLog.Error(err, "failed to create cache function") - os.Exit(1) - } - - mgr, err := ctrl.NewManager(config, ctrl.Options{ - Scheme: scheme, - MetricsBindAddress: metricsAddr, - Port: 9443, - HealthProbeBindAddress: probeAddr, - LeaderElection: enableLeaderElection, - LeaderElectionID: "e79b08a4.org.eclipse.che", - LeaderElectionReleaseOnCancel: true, - LeaseDuration: &leaseDuration, - RenewDeadline: &renewDeadline, - NewCache: cacheFunction, - - // NOTE: We CANNOT limit the manager to a single namespace, because that would limit the - // devworkspace routing reconciler to a single namespace, which would make it totally unusable. - // Instead, if some controller wants to limit itself to single namespace, it can do it - // for example using an event filter, as checontroller does. - // Namespace: watchNamespace, - }) - if err != nil { - setupLog.Error(err, "unable to start manager") - os.Exit(1) - } - - nonCachingClient, err := client.New(mgr.GetConfig(), client.Options{Scheme: scheme}) - if err != nil { - setupLog.Error(err, "unable to initialize non cached client") - os.Exit(1) - } - - // Setup all Controllers - cheReconciler := checontroller.NewReconciler(mgr.GetClient(), nonCachingClient, discoveryClient, mgr.GetScheme(), watchNamespace) - if err = cheReconciler.SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to set up controller", "controller", "CheCluster") - os.Exit(1) - } - - routing := dwr.DevWorkspaceRoutingReconciler{ - Client: mgr.GetClient(), - Log: ctrl.Log.WithName("controllers").WithName("DevWorkspaceRouting"), - Scheme: mgr.GetScheme(), - SolverGetter: solver.Getter(mgr.GetScheme()), - } - if err := routing.SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to set up controller", "controller", "DevWorkspaceRouting") - os.Exit(1) - } - - namespacechace := usernamespace.NewNamespaceCache(nonCachingClient) - - userNamespaceReconciler := usernamespace.NewCheUserNamespaceReconciler(mgr.GetClient(), nonCachingClient, mgr.GetScheme(), namespacechace) - if err = userNamespaceReconciler.SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to set up controller", "controller", "CheUserReconciler") - os.Exit(1) - } - - workspacesConfigReconciler := usernamespace.NewWorkspacesConfigReconciler(mgr.GetClient(), nonCachingClient, mgr.GetScheme(), namespacechace) - if err = workspacesConfigReconciler.SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to set up controller", "controller", "WorkspacesConfigReconciler") - os.Exit(1) - } - - terminationPeriod := int64(20) - if !test.IsTestMode() { - namespace, err := infrastructure.GetOperatorNamespace() - if err == nil { - terminationPeriod = signal.GetTerminationGracePeriodSeconds(mgr.GetAPIReader(), namespace) - } - } - sigHandler := signal.SetupSignalHandler(terminationPeriod) - - // we install the devworkspace CheCluster reconciler even if dw is not supported so that it - // can write meaningful status messages into the CheCluster CRs. - dwChe := devworkspace.CheClusterReconciler{} - if err := dwChe.SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to set up devWorkspace controller", "controller", "DevWorkspaceReconciler") - os.Exit(1) - } - - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = (&chev2.CheCluster{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "CheCluster") - os.Exit(1) - } - } - - // +kubebuilder:scaffold:builder - if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up health check") - os.Exit(1) - } - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up ready check") - os.Exit(1) - } - - // Start the Cmd - setupLog.Info("starting manager") - if err := mgr.Start(sigHandler); err != nil { - setupLog.Error(err, "problem running manager") - os.Exit(1) - } -} - -func getCacheFunc() (cache.NewCacheFunc, error) { - partOfCheRequirement, err := labels.NewRequirement(constants.KubernetesPartOfLabelKey, selection.Equals, []string{constants.CheEclipseOrg}) - if err != nil { - return nil, err - } - partOfCheObjectSelector := labels.NewSelector().Add(*partOfCheRequirement) - - logrus.Infof("Limit cache by selector: %s", partOfCheObjectSelector.String()) - - selectors := cache.SelectorsByObject{ - &appsv1.Deployment{}: { - Label: partOfCheObjectSelector, - }, - &corev1.Pod{}: { - Label: partOfCheObjectSelector, - }, - &batchv1.Job{}: { - Label: partOfCheObjectSelector, - }, - &corev1.Service{}: { - Label: partOfCheObjectSelector, - }, - &networkingv1.Ingress{}: { - Label: partOfCheObjectSelector, - }, - &networkingv1.NetworkPolicy{}: { - Label: partOfCheObjectSelector, - }, - &corev1.ConfigMap{}: { - Label: partOfCheObjectSelector, - }, - &corev1.Secret{}: { - Label: partOfCheObjectSelector, - }, - &corev1.ServiceAccount{}: { - Label: partOfCheObjectSelector, - }, - &rbacv1.Role{}: { - Label: partOfCheObjectSelector, - }, - &rbacv1.RoleBinding{}: { - Label: partOfCheObjectSelector, - }, - &rbacv1.ClusterRole{}: { - Label: partOfCheObjectSelector, - }, - &rbacv1.ClusterRoleBinding{}: { - Label: partOfCheObjectSelector, - }, - &corev1.PersistentVolumeClaim{}: { - Label: partOfCheObjectSelector, - }, - &corev1.LimitRange{}: { - Label: partOfCheObjectSelector, - }, - &corev1.ResourceQuota{}: { - Label: partOfCheObjectSelector, - }, - } - - if infrastructure.IsOpenShift() { - selectors[&oauthv1.OAuthClient{}] = cache.ObjectSelector{Label: partOfCheObjectSelector} - selectors[&routev1.Route{}] = cache.ObjectSelector{Label: partOfCheObjectSelector} - selectors[&templatev1.Template{}] = cache.ObjectSelector{Label: partOfCheObjectSelector} - } - - return cache.BuilderWithOptions(cache.Options{ - SelectorsByObject: selectors, - }), nil -} diff --git a/pkg/common/sync/sync_test.go b/pkg/common/sync/sync_test.go index 9f6d4e37c8..e9b34c7374 100644 --- a/pkg/common/sync/sync_test.go +++ b/pkg/common/sync/sync_test.go @@ -17,7 +17,6 @@ import ( "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "testing" @@ -27,18 +26,16 @@ import ( ) func TestGetExistedObject(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{ - &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - Namespace: "eclipse-che", - }, + ctx := test.NewCtxBuilder().WithObjects(&corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", }, - }) + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "eclipse-che", + }, + }).Build() syncer := ObjSyncer{ cli: ctx.ClusterAPI.Client, scheme: ctx.ClusterAPI.Scheme, @@ -51,7 +48,7 @@ func TestGetExistedObject(t *testing.T) { } func TestGetNotExistedObject(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() syncer := ObjSyncer{ cli: ctx.ClusterAPI.Client, scheme: ctx.ClusterAPI.Scheme, diff --git a/pkg/common/test/utils.go b/pkg/common/test/utils.go index b39ec6bef8..b4ed7eb360 100644 --- a/pkg/common/test/utils.go +++ b/pkg/common/test/utils.go @@ -18,6 +18,11 @@ import ( "strings" "testing" + projectv1 "github.com/openshift/api/project/v1" + batchv1 "k8s.io/api/batch/v1" + networkingv1 "k8s.io/api/networking/v1" + rbacv1 "k8s.io/api/rbac/v1" + "sigs.k8s.io/controller-runtime/pkg/reconcile" securityv1 "github.com/openshift/api/security/v1" @@ -45,10 +50,14 @@ import ( configv1 "github.com/openshift/api/config/v1" fakeDiscovery "k8s.io/client-go/discovery/fake" fakeclientset "k8s.io/client-go/kubernetes/fake" - "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) +type DeployContextBuild struct { + cheCluster *chev2.CheCluster + initObject []client.Object +} + type TestExpectedResources struct { MemoryLimit string MemoryRequest string @@ -157,51 +166,6 @@ func IsTestMode() bool { return len(testMode) != 0 } -// Initialize DeployContext for tests -func GetDeployContext(cheCluster *chev2.CheCluster, initObjs []runtime.Object) *chetypes.DeployContext { - if cheCluster == nil { - // use a default checluster - cheCluster = &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: "eclipse-che", - Namespace: "eclipse-che", - }, - Status: chev2.CheClusterStatus{ - CheURL: "https://che-host", - }, - } - } - - scheme := scheme.Scheme - chev2.SchemeBuilder.AddToScheme(scheme) - scheme.AddKnownTypes(controllerv1alpha1.SchemeBuilder.GroupVersion, &controllerv1alpha1.DevWorkspaceOperatorConfig{}) - scheme.AddKnownTypes(oauthv1.GroupVersion, &oauthv1.OAuthClient{}, &oauthv1.OAuthClientList{}) - scheme.AddKnownTypes(configv1.GroupVersion, &configv1.Proxy{}, &configv1.Console{}) - scheme.AddKnownTypes(templatev1.GroupVersion, &templatev1.Template{}, &templatev1.TemplateList{}) - scheme.AddKnownTypes(routev1.GroupVersion, &routev1.Route{}) - scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.Secret{}) - scheme.AddKnownTypes(console.GroupVersion, &console.ConsoleLink{}) - scheme.AddKnownTypes(chev1alpha1.GroupVersion, &chev1alpha1.KubernetesImagePuller{}) - securityv1.Install(scheme) - - initObjs = append(initObjs, cheCluster) - cli := fake.NewFakeClientWithScheme(scheme, initObjs...) - clientSet := fakeclientset.NewSimpleClientset() - fakeDiscovery, _ := clientSet.Discovery().(*fakeDiscovery.FakeDiscovery) - - return &chetypes.DeployContext{ - CheCluster: cheCluster, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme, - DiscoveryClient: fakeDiscovery, - }, - Proxy: &chetypes.Proxy{}, - CheHost: strings.TrimPrefix(cheCluster.Status.CheURL, "https://"), - } -} - // EnsureReconcile runs the testReconcileFunc until it returns done=true or 10 iterations func EnsureReconcile( t *testing.T, @@ -218,3 +182,128 @@ func EnsureReconcile( assert.Fail(t, "Reconcile did not finish in 10 iterations") } + +func NewCtxBuilder() *DeployContextBuild { + return &DeployContextBuild{ + initObject: []client.Object{}, + cheCluster: getDefaultCheCluster(), + } +} + +func (f *DeployContextBuild) WithObjects(initObjs ...client.Object) *DeployContextBuild { + f.initObject = append(f.initObject, initObjs...) + return f +} + +func (f *DeployContextBuild) WithCheCluster(cheCluster *chev2.CheCluster) *DeployContextBuild { + f.cheCluster = cheCluster + if f.cheCluster != nil && f.cheCluster.TypeMeta.Kind == "" { + f.cheCluster.TypeMeta = metav1.TypeMeta{ + Kind: "CheCluster", + APIVersion: chev2.GroupVersion.String(), + } + } + return f +} + +func (f *DeployContextBuild) Build() *chetypes.DeployContext { + if f.cheCluster != nil { + f.initObject = append(f.initObject, f.cheCluster) + } + scheme := addKnownTypes() + + fakeClient := fake. + NewClientBuilder(). + WithScheme(scheme). + WithObjects(f.initObject...). + WithStatusSubresource(&chev2.CheCluster{}, &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: appsv1.SchemeGroupVersion.String(), + }, + }). + Build() + + clientSet := fakeclientset.NewClientset() + discoveryClient, _ := clientSet.Discovery().(*fakeDiscovery.FakeDiscovery) + discoveryClient.Fake.Resources = []*metav1.APIResourceList{ + { + APIResources: []metav1.APIResource{ + {Name: "consolelinks"}, + }, + }, + { + GroupVersion: "che.eclipse.org/v1alpha1", + APIResources: []metav1.APIResource{ + { + Name: "kubernetesimagepullers", + }, + }, + }, + } + + ctx := &chetypes.DeployContext{ + CheCluster: f.cheCluster, + ClusterAPI: chetypes.ClusterAPI{ + Client: fakeClient, + NonCachingClient: fakeClient, + Scheme: scheme, + DiscoveryClient: discoveryClient, + }, + Proxy: &chetypes.Proxy{}, + } + + if f.cheCluster != nil { + ctx.CheHost = strings.TrimPrefix(f.cheCluster.Status.CheURL, "https://") + } + + return ctx +} + +func getDefaultCheCluster() *chev2.CheCluster { + return &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "eclipse-che", + Namespace: "eclipse-che", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "CheCluster", + APIVersion: chev2.GroupVersion.String(), + }, + Status: chev2.CheClusterStatus{ + CheURL: "https://che-host", + }, + } +} + +func addKnownTypes() *runtime.Scheme { + scheme := runtime.NewScheme() + scheme.AddKnownTypes(controllerv1alpha1.GroupVersion, &controllerv1alpha1.DevWorkspaceOperatorConfig{}, &controllerv1alpha1.DevWorkspaceOperatorConfigList{}) + scheme.AddKnownTypes(controllerv1alpha1.GroupVersion, &controllerv1alpha1.DevWorkspaceRouting{}, &controllerv1alpha1.DevWorkspaceRoutingList{}) + scheme.AddKnownTypes(oauthv1.GroupVersion, &oauthv1.OAuthClient{}, &oauthv1.OAuthClientList{}) + scheme.AddKnownTypes(configv1.GroupVersion, &configv1.Proxy{}, &configv1.Console{}) + scheme.AddKnownTypes(templatev1.GroupVersion, &templatev1.Template{}, &templatev1.TemplateList{}) + scheme.AddKnownTypes(routev1.GroupVersion, &routev1.Route{}, &routev1.RouteList{}) + scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.Secret{}, &corev1.SecretList{}) + scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.ConfigMap{}, &corev1.ConfigMapList{}) + scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.Service{}, &corev1.ServiceList{}) + scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.ServiceAccount{}, &corev1.ServiceAccountList{}) + scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.Pod{}, &corev1.PodList{}) + scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.Namespace{}, &corev1.NamespaceList{}) + scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.PersistentVolumeClaim{}, &corev1.PersistentVolumeClaimList{}) + scheme.AddKnownTypes(corev1.SchemeGroupVersion, &corev1.LimitRange{}, &corev1.LimitRangeList{}) + scheme.AddKnownTypes(console.GroupVersion, &console.ConsoleLink{}) + scheme.AddKnownTypes(chev1alpha1.GroupVersion, &chev1alpha1.KubernetesImagePuller{}) + scheme.AddKnownTypes(securityv1.GroupVersion, &securityv1.SecurityContextConstraints{}) + scheme.AddKnownTypes(rbacv1.SchemeGroupVersion, &rbacv1.Role{}, &rbacv1.RoleList{}) + scheme.AddKnownTypes(rbacv1.SchemeGroupVersion, &rbacv1.RoleBinding{}, &rbacv1.RoleBindingList{}) + scheme.AddKnownTypes(rbacv1.SchemeGroupVersion, &rbacv1.ClusterRole{}, &rbacv1.ClusterRoleList{}) + scheme.AddKnownTypes(rbacv1.SchemeGroupVersion, &rbacv1.ClusterRoleBinding{}, &rbacv1.ClusterRoleBindingList{}) + scheme.AddKnownTypes(appsv1.SchemeGroupVersion, &appsv1.Deployment{}, &appsv1.DeploymentList{}) + scheme.AddKnownTypes(chev2.GroupVersion, &chev2.CheCluster{}, &chev2.CheClusterList{}) + scheme.AddKnownTypes(networkingv1.SchemeGroupVersion, &networkingv1.Ingress{}, &networkingv1.IngressList{}) + scheme.AddKnownTypes(batchv1.SchemeGroupVersion, &batchv1.Job{}, &batchv1.JobList{}) + scheme.AddKnownTypes(projectv1.SchemeGroupVersion, &projectv1.Project{}, &projectv1.ProjectList{}) + + return scheme +} diff --git a/pkg/deploy/checluster_test.go b/pkg/deploy/checluster_test.go index 7ea4767bac..616fecad9f 100644 --- a/pkg/deploy/checluster_test.go +++ b/pkg/deploy/checluster_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -13,51 +13,37 @@ package deploy import ( + "testing" + chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" "k8s.io/utils/pointer" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "testing" ) func TestReload(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme( - scheme.Scheme, - &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - ResourceVersion: "1", - }, - }) + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + ResourceVersion: "1", + }, + }).Build() - ctx := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - ResourceVersion: "2", - }, - Spec: chev2.CheClusterSpec{ - Components: chev2.CheClusterComponents{ - PluginRegistry: chev2.PluginRegistry{ - OpenVSXURL: pointer.StringPtr("https://open-vsx.org"), - }, + ctx.CheCluster = &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + ResourceVersion: "2", + }, + Spec: chev2.CheClusterSpec{ + Components: chev2.CheClusterComponents{ + PluginRegistry: chev2.PluginRegistry{ + OpenVSXURL: pointer.StringPtr("https://open-vsx.org"), }, }, }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, } err := ReloadCheClusterCR(ctx) @@ -100,7 +86,7 @@ func TestFindCheCRinNamespace(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.checluster, []runtime.Object{}) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.checluster).Build() checluster, err := FindCheClusterCRInNamespace(deployContext.ClusterAPI.Client, testCase.namespace) if testCase.found { assert.NoError(t, err) diff --git a/pkg/deploy/clusterrole_test.go b/pkg/deploy/clusterrole_test.go index 883e9c4c07..a23a5dd74e 100644 --- a/pkg/deploy/clusterrole_test.go +++ b/pkg/deploy/clusterrole_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -14,37 +14,17 @@ package deploy import ( "context" + "testing" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/test" rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "testing" ) func TestSyncClusterRole(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - rbacv1.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - done, err := SyncClusterRoleToCluster(deployContext, "test", []rbacv1.PolicyRule{ + done, err := SyncClusterRoleToCluster(ctx, "test", []rbacv1.PolicyRule{ { APIGroups: []string{"test-1"}, Resources: []string{"test-1"}, @@ -57,7 +37,7 @@ func TestSyncClusterRole(t *testing.T) { } // sync a new cluster role - _, err = SyncClusterRoleToCluster(deployContext, "test", []rbacv1.PolicyRule{ + _, err = SyncClusterRoleToCluster(ctx, "test", []rbacv1.PolicyRule{ { APIGroups: []string{"test-2"}, Resources: []string{"test-2"}, @@ -69,7 +49,7 @@ func TestSyncClusterRole(t *testing.T) { } // sync twice to be sure update done correctly - done, err = SyncClusterRoleToCluster(deployContext, "test", []rbacv1.PolicyRule{ + done, err = SyncClusterRoleToCluster(ctx, "test", []rbacv1.PolicyRule{ { APIGroups: []string{"test-2"}, Resources: []string{"test-2"}, @@ -81,7 +61,7 @@ func TestSyncClusterRole(t *testing.T) { } actual := &rbacv1.ClusterRole{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test"}, actual) if err != nil { t.Fatalf("Failed to get cluster role: %v", err) } diff --git a/pkg/deploy/clusterrolebinding_test.go b/pkg/deploy/clusterrolebinding_test.go index ae5cb164e5..aaadab5d70 100644 --- a/pkg/deploy/clusterrolebinding_test.go +++ b/pkg/deploy/clusterrolebinding_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -14,54 +14,35 @@ package deploy import ( "context" + "testing" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/test" rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "testing" ) func TestSyncClusterRoleBindingToCluster(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - rbacv1.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - done, err := SyncClusterRoleBindingToCluster(deployContext, "test", "sa", "clusterrole-1") + done, err := SyncClusterRoleBindingToCluster(ctx, "test", "sa", "clusterrole-1") if !done || err != nil { t.Fatalf("Failed to sync crb: %v", err) } // sync a new cluster role binding - _, err = SyncClusterRoleBindingToCluster(deployContext, "test", "sa", "clusterrole-2") + _, err = SyncClusterRoleBindingToCluster(ctx, "test", "sa", "clusterrole-2") if err != nil { t.Fatalf("Failed to sync crb: %v", err) } // sync twice to be sure update done correctly - done, err = SyncClusterRoleBindingToCluster(deployContext, "test", "sa", "clusterrole-2") + done, err = SyncClusterRoleBindingToCluster(ctx, "test", "sa", "clusterrole-2") if !done || err != nil { t.Fatalf("Failed to sync crb: %v", err) } actual := &rbacv1.ClusterRoleBinding{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test"}, actual) if err != nil { t.Fatalf("Failed to get crb: %v", err) } diff --git a/pkg/deploy/configmap_test.go b/pkg/deploy/configmap_test.go index e29c7caf22..59dc5ba8de 100644 --- a/pkg/deploy/configmap_test.go +++ b/pkg/deploy/configmap_test.go @@ -14,55 +14,36 @@ package deploy import ( "context" - "testing" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/test" + corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" ) func TestSyncConfigMapDataToCluster(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - corev1.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - done, err := SyncConfigMapDataToCluster(deployContext, "test", map[string]string{"a": "b"}, "che") + done, err := SyncConfigMapDataToCluster(ctx, "test", map[string]string{"a": "b"}, "che") if !done || err != nil { t.Fatalf("Failed to sync config map: %v", err) } // sync a new config map - _, err = SyncConfigMapDataToCluster(deployContext, "test", map[string]string{"c": "d"}, "che") + _, err = SyncConfigMapDataToCluster(ctx, "test", map[string]string{"c": "d"}, "che") if err != nil { t.Fatalf("Failed to sync config map: %v", err) } // sync twice to be sure update done correctly - done, err = SyncConfigMapDataToCluster(deployContext, "test", map[string]string{"c": "d"}, "che") + done, err = SyncConfigMapDataToCluster(ctx, "test", map[string]string{"c": "d"}, "che") if !done || err != nil { t.Fatalf("Failed to sync config map: %v", err) } actual := &corev1.ConfigMap{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) if err != nil { t.Fatalf("Failed to get config map: %v", err) } @@ -77,45 +58,30 @@ func TestSyncConfigMapDataToCluster(t *testing.T) { } func TestSyncConfigMapSpecDataToCluster(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - corev1.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - spec := InitConfigMap(deployContext, "test", map[string]string{"a": "b"}, "che") - done, err := SyncConfigMapSpecToCluster(deployContext, spec) + spec := InitConfigMap(ctx, "test", map[string]string{"a": "b"}, "che") + done, err := SyncConfigMapSpecToCluster(ctx, spec) if !done || err != nil { t.Fatalf("Failed to sync config map: %v", err) } // check if labels - spec = InitConfigMap(deployContext, "test", map[string]string{"a": "b"}, "che") + spec = InitConfigMap(ctx, "test", map[string]string{"a": "b"}, "che") spec.ObjectMeta.Labels = map[string]string{"l": "v"} - _, err = SyncConfigMapSpecToCluster(deployContext, spec) + _, err = SyncConfigMapSpecToCluster(ctx, spec) if err != nil { t.Fatalf("Failed to sync config map: %v", err) } // sync twice to be sure update done correctly - done, err = SyncConfigMapSpecToCluster(deployContext, spec) + done, err = SyncConfigMapSpecToCluster(ctx, spec) if !done || err != nil { t.Fatalf("Failed to sync config map: %v", err) } actual := &corev1.ConfigMap{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) if err != nil { t.Fatalf("Failed to get config map: %v", err) } diff --git a/pkg/deploy/consolelink/consolelink_test.go b/pkg/deploy/consolelink/consolelink_test.go index 887fea5958..29ad578da3 100644 --- a/pkg/deploy/consolelink/consolelink_test.go +++ b/pkg/deploy/consolelink/consolelink_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -16,56 +16,33 @@ import ( "context" "fmt" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" + + "testing" + defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/eclipse-che/che-operator/pkg/common/utils" consolev1 "github.com/openshift/api/console/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - fakeDiscovery "k8s.io/client-go/discovery/fake" - - "testing" ) func TestReconcileConsoleLink(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - cheCluster := &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - Status: chev2.CheClusterStatus{ - CheURL: "https://che-host", - }, - } - - ctx := test.GetDeployContext(cheCluster, []runtime.Object{}) - ctx.ClusterAPI.DiscoveryClient.(*fakeDiscovery.FakeDiscovery).Fake.Resources = []*metav1.APIResourceList{ - { - APIResources: []metav1.APIResource{ - {Name: ConsoleLinksResourceName}, - }, - }, - } + ctx := test.NewCtxBuilder().Build() consolelink := NewConsoleLinkReconciler() - _, done, err := consolelink.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, consolelink.Reconcile) consoleLink := &consolev1.ConsoleLink{} - err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: defaults.GetConsoleLinkName()}, consoleLink) + err := ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: defaults.GetConsoleLinkName()}, consoleLink) assert.Nil(t, err) assert.True(t, utils.Contains(ctx.CheCluster.Finalizers, ConsoleLinkFinalizerName)) assert.Equal(t, "https://che-host", consoleLink.Spec.Href) // Initialize DeletionTimestamp => checluster is being deleted - done = consolelink.Finalize(ctx) + done := consolelink.Finalize(ctx) assert.True(t, done) assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: defaults.GetConsoleLinkName()}, &consolev1.ConsoleLink{})) @@ -73,8 +50,6 @@ func TestReconcileConsoleLink(t *testing.T) { } func TestReconcileConsoleLinkWhenCheURLChanged(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - cheCluster := &chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Namespace: "eclipse-che", @@ -105,21 +80,13 @@ func TestReconcileConsoleLinkWhenCheURLChanged(t *testing.T) { }, } - ctx := test.GetDeployContext(cheCluster, []runtime.Object{existedConsoleLink}) - ctx.ClusterAPI.DiscoveryClient.(*fakeDiscovery.FakeDiscovery).Fake.Resources = []*metav1.APIResourceList{ - { - APIResources: []metav1.APIResource{ - {Name: ConsoleLinksResourceName}, - }, - }, - } + ctx := test.NewCtxBuilder().WithCheCluster(cheCluster).WithObjects(existedConsoleLink).Build() consoleLinkReconciler := NewConsoleLinkReconciler() - _, _, err := consoleLinkReconciler.Reconcile(ctx) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, consoleLinkReconciler.Reconcile) consoleLink := &consolev1.ConsoleLink{} - err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: defaults.GetConsoleLinkName()}, consoleLink) + err := ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: defaults.GetConsoleLinkName()}, consoleLink) assert.Nil(t, err) assert.True(t, utils.Contains(ctx.CheCluster.Finalizers, ConsoleLinkFinalizerName)) assert.Equal(t, "https://test-host", consoleLink.Spec.Href) diff --git a/pkg/deploy/container-build/container_build_test.go b/pkg/deploy/container-build/container_build_test.go index 86859713fc..f045edb562 100644 --- a/pkg/deploy/container-build/container_build_test.go +++ b/pkg/deploy/container-build/container_build_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -25,7 +25,6 @@ import ( corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/pointer" @@ -50,22 +49,19 @@ func TestContainerBuildReconciler(t *testing.T) { ServiceAccountName: constants.DevWorkspaceServiceAccountName, }, } - ctx := test.GetDeployContext(nil, []runtime.Object{dwPod}) + + ctx := test.NewCtxBuilder().WithObjects(dwPod).Build() containerBuildReconciler := NewContainerBuildReconciler() - _, done, err := containerBuildReconciler.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, containerBuildReconciler.Reconcile) // Enable Container build capabilities ctx.CheCluster.Spec.DevEnvironments.DisableContainerBuildCapabilities = pointer.BoolPtr(false) ctx.CheCluster.Spec.DevEnvironments.ContainerBuildConfiguration = &chev2.ContainerBuildConfiguration{OpenShiftSecurityContextConstraint: "scc"} - err = ctx.ClusterAPI.Client.Update(context.TODO(), ctx.CheCluster) + err := ctx.ClusterAPI.Client.Update(context.TODO(), ctx.CheCluster) assert.NoError(t, err) - _, done, err = containerBuildReconciler.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, containerBuildReconciler.Reconcile) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "scc"}, &securityv1.SecurityContextConstraints{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: GetDevWorkspaceSccRbacResourcesName()}, &rbacv1.ClusterRole{})) @@ -78,9 +74,7 @@ func TestContainerBuildReconciler(t *testing.T) { err = ctx.ClusterAPI.Client.Update(context.TODO(), ctx.CheCluster) assert.NoError(t, err) - _, done, err = containerBuildReconciler.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, containerBuildReconciler.Reconcile) assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "scc"}, &securityv1.SecurityContextConstraints{})) assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: GetDevWorkspaceSccRbacResourcesName()}, &rbacv1.ClusterRole{})) @@ -107,7 +101,7 @@ func TestSyncAndRemoveRBAC(t *testing.T) { ServiceAccountName: constants.DevWorkspaceServiceAccountName, }, } - ctx := test.GetDeployContext(nil, []runtime.Object{dwPod}) + ctx := test.NewCtxBuilder().WithObjects(dwPod).Build() ctx.CheCluster.Spec.DevEnvironments.DisableContainerBuildCapabilities = pointer.Bool(false) ctx.CheCluster.Spec.DevEnvironments.ContainerBuildConfiguration = &chev2.ContainerBuildConfiguration{OpenShiftSecurityContextConstraint: "scc"} @@ -131,7 +125,7 @@ func TestSyncAndRemoveRBAC(t *testing.T) { } func TestSyncAndRemoveSCC(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() ctx.CheCluster.Spec.DevEnvironments.DisableContainerBuildCapabilities = pointer.Bool(false) ctx.CheCluster.Spec.DevEnvironments.ContainerBuildConfiguration = &chev2.ContainerBuildConfiguration{OpenShiftSecurityContextConstraint: "scc"} @@ -161,7 +155,7 @@ func TestShouldNotSyncSCCIfAlreadyExists(t *testing.T) { }, } - ctx := test.GetDeployContext(nil, []runtime.Object{scc}) + ctx := test.NewCtxBuilder().WithObjects(scc).Build() ctx.CheCluster.Spec.DevEnvironments.DisableContainerBuildCapabilities = pointer.BoolPtr(false) ctx.CheCluster.Spec.DevEnvironments.ContainerBuildConfiguration = &chev2.ContainerBuildConfiguration{OpenShiftSecurityContextConstraint: "scc"} diff --git a/pkg/deploy/dashboard/dashboard_deployment_test.go b/pkg/deploy/dashboard/dashboard_deployment_test.go index 03257beaf0..2334b69412 100644 --- a/pkg/deploy/dashboard/dashboard_deployment_test.go +++ b/pkg/deploy/dashboard/dashboard_deployment_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -16,9 +16,8 @@ import ( "fmt" "os" - fakeDiscovery "k8s.io/client-go/discovery/fake" + "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" configv1 "github.com/openshift/api/config/v1" "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/api/resource" @@ -41,7 +40,7 @@ import ( ) func TestDashboardDeploymentSecurityContext(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() dashboard := NewDashboardReconciler() deployment, err := dashboard.getDashboardDeploymentSpec(ctx) @@ -123,7 +122,7 @@ func TestDashboardDeploymentResources(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() dashboard := NewDashboardReconciler() deployment, err := dashboard.getDashboardDeploymentSpec(ctx) @@ -149,27 +148,15 @@ func TestDashboardDeploymentEnvVars(t *testing.T) { _ = os.Unsetenv("RELATED_IMAGE_sample_encoded_") }() - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - ctx := test.GetDeployContext( - nil, - []runtime.Object{ - &configv1.Console{ - ObjectMeta: metav1.ObjectMeta{ - Name: "cluster", - Namespace: "openshift-console", - }, - Status: configv1.ConsoleStatus{ - ConsoleURL: "https://console-openshift-console.apps.my-host/", - }, - }, - }) - ctx.ClusterAPI.DiscoveryClient.(*fakeDiscovery.FakeDiscovery).Fake.Resources = []*metav1.APIResourceList{ - { - APIResources: []metav1.APIResource{ - {Name: ConsoleLinksResourceName}, - }, + ctx := test.NewCtxBuilder().WithObjects(&configv1.Console{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster", + Namespace: "openshift-console", }, - } + Status: configv1.ConsoleStatus{ + ConsoleURL: "https://console-openshift-console.apps.my-host/", + }, + }).Build() deployment, err := NewDashboardReconciler().getDashboardDeploymentSpec(ctx) @@ -290,11 +277,9 @@ func TestDashboardDeploymentEnvVars(t *testing.T) { } func TestDashboardDeploymentVolumes(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - type resourcesTestCase struct { name string - initObjects []runtime.Object + initObjects []client.Object volumes []corev1.Volume volumeMounts []corev1.VolumeMount cheCluster *chev2.CheCluster @@ -302,7 +287,7 @@ func TestDashboardDeploymentVolumes(t *testing.T) { testCases := []resourcesTestCase{ { name: "Test provisioning Custom CAs only", - initObjects: []runtime.Object{ + initObjects: []client.Object{ // no deploy.CheTLSSelfSignedCertificateSecretName is created }, volumes: []corev1.Volume{ @@ -328,7 +313,7 @@ func TestDashboardDeploymentVolumes(t *testing.T) { }, { name: "Test provisioning Che and Custom CAs", - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: constants.DefaultSelfSignedCertificateSecretName, @@ -377,7 +362,7 @@ func TestDashboardDeploymentVolumes(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - ctx := test.GetDeployContext(testCase.cheCluster, testCase.initObjects) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.initObjects...).Build() dashboard := NewDashboardReconciler() deployment, err := dashboard.getDashboardDeploymentSpec(ctx) diff --git a/pkg/deploy/dashboard/dashboard_test.go b/pkg/deploy/dashboard/dashboard_test.go index 715c645d03..296ef26602 100644 --- a/pkg/deploy/dashboard/dashboard_test.go +++ b/pkg/deploy/dashboard/dashboard_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -17,26 +17,18 @@ import ( "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/eclipse-che/che-operator/pkg/common/utils" "github.com/stretchr/testify/assert" - rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/runtime" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/types" "testing" ) -const Namespace = "eclipse-che" - func TestDashboardOpenShift(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() dashboard := NewDashboardReconciler() - _, done, err := dashboard.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, dashboard.Reconcile) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: dashboard.getComponentName(ctx), Namespace: "eclipse-che"}, &corev1.Service{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: dashboard.getComponentName(ctx), Namespace: "eclipse-che"}, &appsv1.Deployment{})) @@ -51,11 +43,9 @@ func TestDashboardOpenShift(t *testing.T) { func TestDashboardKubernetes(t *testing.T) { infrastructure.InitializeForTesting(infrastructure.Kubernetes) - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() dashboard := NewDashboardReconciler() - _, done, err := dashboard.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, dashboard.Reconcile) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: dashboard.getComponentName(ctx), Namespace: "eclipse-che"}, &corev1.Service{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: dashboard.getComponentName(ctx), Namespace: "eclipse-che"}, &appsv1.Deployment{})) @@ -69,17 +59,15 @@ func TestDashboardKubernetes(t *testing.T) { func TestDashboardClusterRBACFinalizerOnKubernetes(t *testing.T) { infrastructure.InitializeForTesting(infrastructure.Kubernetes) - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() dashboard := NewDashboardReconciler() - _, done, err := dashboard.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, dashboard.Reconcile) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: dashboard.getClusterRoleBindingName(ctx)}, &rbacv1.ClusterRoleBinding{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: dashboard.getClusterRoleName(ctx)}, &rbacv1.ClusterRole{})) assert.True(t, utils.Contains(ctx.CheCluster.Finalizers, ClusterPermissionsDashboardFinalizer)) - done = dashboard.Finalize(ctx) + done := dashboard.Finalize(ctx) assert.True(t, done) assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: dashboard.getClusterRoleBindingName(ctx)}, &rbacv1.ClusterRoleBinding{})) diff --git a/pkg/deploy/deployment_test.go b/pkg/deploy/deployment_test.go index 90c06e1bb8..35e77e9601 100644 --- a/pkg/deploy/deployment_test.go +++ b/pkg/deploy/deployment_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -14,9 +14,10 @@ package deploy import ( "context" - "os" "reflect" + "sigs.k8s.io/controller-runtime/pkg/client" + k8shelper "github.com/eclipse-che/che-operator/pkg/common/k8s-helper" "github.com/eclipse-che/che-operator/pkg/common/test" @@ -26,21 +27,15 @@ import ( "github.com/google/go-cmp/cmp" + "testing" + chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" "github.com/eclipse-che/che-operator/pkg/common/constants" "github.com/eclipse-che/che-operator/pkg/common/utils" 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/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - "testing" ) var ( @@ -70,7 +65,7 @@ func TestMountSecret(t *testing.T) { name string initDeployment *appsv1.Deployment expectedDeployment *appsv1.Deployment - initObjects []runtime.Object + initObjects []client.Object } testCases := []testCase{ @@ -121,7 +116,7 @@ func TestMountSecret(t *testing.T) { }, }, }, - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -193,7 +188,7 @@ func TestMountSecret(t *testing.T) { }, }, }, - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -261,7 +256,7 @@ func TestMountSecret(t *testing.T) { }, }, }, - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -351,7 +346,7 @@ func TestMountSecret(t *testing.T) { }, }, }, - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -383,25 +378,10 @@ func TestMountSecret(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) testCase.initObjects = append(testCase.initObjects, testCase.initDeployment) - cli := fake.NewFakeClientWithScheme(scheme.Scheme, testCase.initObjects...) + ctx := test.NewCtxBuilder().WithObjects(testCase.initObjects...).Build() - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } - - err := MountSecrets(testCase.initDeployment, deployContext) + err := MountSecrets(testCase.initDeployment, ctx) if err != nil { t.Fatalf("Error mounting secret: %v", err) } @@ -418,7 +398,7 @@ func TestMountConfigMaps(t *testing.T) { name string initDeployment *appsv1.Deployment expectedDeployment *appsv1.Deployment - initObjects []runtime.Object + initObjects []client.Object } testCases := []testCase{ @@ -471,7 +451,7 @@ func TestMountConfigMaps(t *testing.T) { }, }, }, - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -545,7 +525,7 @@ func TestMountConfigMaps(t *testing.T) { }, }, }, - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -613,7 +593,7 @@ func TestMountConfigMaps(t *testing.T) { }, }, }, - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -703,7 +683,7 @@ func TestMountConfigMaps(t *testing.T) { }, }, }, - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{ Kind: "ConfigMap", @@ -735,25 +715,10 @@ func TestMountConfigMaps(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) testCase.initObjects = append(testCase.initObjects, testCase.initDeployment) - cli := fake.NewFakeClientWithScheme(scheme.Scheme, testCase.initObjects...) + ctx := test.NewCtxBuilder().WithObjects(testCase.initObjects...).Build() - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } - - err := MountConfigMaps(testCase.initDeployment, deployContext) + err := MountConfigMaps(testCase.initDeployment, ctx) if err != nil { t.Fatalf("Error mounting configmap: %v", err) } @@ -766,25 +731,10 @@ func TestMountConfigMaps(t *testing.T) { } func TestSyncEnvVarDeploymentToCluster(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - Proxy: &chetypes.Proxy{}, - } + ctx := test.NewCtxBuilder().Build() // initial sync - done, err := SyncDeploymentSpecToCluster(deployContext, deployment, DefaultDeploymentDiffOpts) + done, err := SyncDeploymentSpecToCluster(ctx, deployment, DefaultDeploymentDiffOpts) if !done || err != nil { t.Fatalf("Failed to sync deployment: %v", err) } @@ -797,19 +747,19 @@ func TestSyncEnvVarDeploymentToCluster(t *testing.T) { } // sync deployment - _, err = SyncDeploymentSpecToCluster(deployContext, deployment, DefaultDeploymentDiffOpts) + _, err = SyncDeploymentSpecToCluster(ctx, deployment, DefaultDeploymentDiffOpts) if err != nil { t.Fatalf("Failed to sync deployment: %v", err) } // sync twice to be sure update done correctly - done, err = SyncDeploymentSpecToCluster(deployContext, deployment, DefaultDeploymentDiffOpts) + done, err = SyncDeploymentSpecToCluster(ctx, deployment, DefaultDeploymentDiffOpts) if !done || err != nil { t.Fatalf("Failed to sync deployment: %v", err) } actual := &appsv1.Deployment{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) if err != nil { t.Fatalf("Failed to sync deployment: %v", err) } @@ -858,7 +808,7 @@ func TestCustomizeDeploymentShouldNotUpdateResources(t *testing.T) { }, } - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() err := OverrideDeployment(ctx, deployment, customizationDeployment) assert.Nil(t, err) @@ -942,9 +892,7 @@ func TestCustomizeDeploymentImagePullPolicy(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() err := OverrideDeployment(ctx, testCase.initDeployment, testCase.customizationDeployment) assert.Nil(t, err) @@ -1027,9 +975,7 @@ func TestCustomizeDeploymentEnvVar(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() err := OverrideDeployment(ctx, testCase.initDeployment, testCase.customizationDeployment) assert.Nil(t, err) @@ -1059,7 +1005,7 @@ func TestShouldNotThrowErrorIfOverrideDeploymentSettingsIsEmpty(t *testing.T) { overrideDeploymentSettings := &chev2.Deployment{} - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() err := OverrideDeployment(ctx, deployment, overrideDeploymentSettings) assert.Nil(t, err) } @@ -1191,7 +1137,7 @@ func TestOverrideContainerCpuLimit(t *testing.T) { } func TestOverrideNodeSelector(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -1222,7 +1168,7 @@ func TestOverrideNodeSelector(t *testing.T) { } func TestOverrideTolerations(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: "test", diff --git a/pkg/deploy/dev-workspace-config/dev_workspace_config.go b/pkg/deploy/dev-workspace-config/dev_workspace_config.go index 7b4688d8c9..d2688004d5 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -49,16 +49,17 @@ func (d *DevWorkspaceConfigReconciler) Reconcile(ctx *chetypes.DeployContext) (r Name: devWorkspaceConfigName, Namespace: ctx.CheCluster.Namespace, }, - TypeMeta: metav1.TypeMeta{ - Kind: "DevWorkspaceOperatorConfig", - APIVersion: controllerv1alpha1.GroupVersion.String(), - }, } - if _, err := deploy.GetNamespacedObject(ctx, devWorkspaceConfigName, dwoc); err != nil { return reconcile.Result{}, false, err } + // Ensure TypeMeta is set correctly + dwoc.TypeMeta = metav1.TypeMeta{ + Kind: "DevWorkspaceOperatorConfig", + APIVersion: controllerv1alpha1.GroupVersion.String(), + } + if dwoc.Config == nil { dwoc.Config = &controllerv1alpha1.OperatorConfiguration{} } @@ -216,6 +217,11 @@ func updateWorkspaceServiceAccountConfig(devEnvironments *chev2.CheClusterDevEnv // If user's Namespace is not auto provisioned (is pre-created by admin), then ServiceAccount must be pre-created as well DisableCreation: pointer.Bool(!isNamespaceAutoProvisioned && devEnvironments.ServiceAccount != ""), } + + if len(workspaceConfig.ServiceAccount.ServiceAccountTokens) == 0 { + // Keep it nil to prevent endless reconciling + workspaceConfig.ServiceAccount.ServiceAccountTokens = nil + } } func updateWorkspacePodSchedulerNameConfig(devEnvironments *chev2.CheClusterDevEnvironments, workspaceConfig *controllerv1alpha1.WorkspaceConfig) { diff --git a/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go b/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go index e3df2abbbd..ba481cd291 100644 --- a/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go +++ b/pkg/deploy/dev-workspace-config/dev_workspace_config_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -19,8 +19,9 @@ import ( "sort" "testing" + "sigs.k8s.io/controller-runtime/pkg/client" + controllerv1alpha1 "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/pkg/common/constants" "github.com/eclipse-che/che-operator/pkg/common/test" @@ -30,7 +31,6 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/pointer" ) @@ -39,14 +39,14 @@ func TestReconcileDevWorkspaceConfigStorage(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } type errorTestCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedErrorMessage string } @@ -281,7 +281,7 @@ func TestReconcileDevWorkspaceConfigStorage(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -331,7 +331,7 @@ func TestReconcileDevWorkspaceConfigStorage(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -381,7 +381,7 @@ func TestReconcileDevWorkspaceConfigStorage(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -415,15 +415,13 @@ func TestReconcileDevWorkspaceConfigStorage(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, testCase.existedObjects) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.existedObjects...).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) diff := cmp.Diff(testCase.expectedOperatorConfig, dwoc.Config, cmp.Options{cmpopts.IgnoreFields(controllerv1alpha1.WorkspaceConfig{}, "ServiceAccount")}) @@ -433,8 +431,7 @@ func TestReconcileDevWorkspaceConfigStorage(t *testing.T) { for _, testCase := range expectedErrorTestCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, testCase.existedObjects) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.existedObjects...).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) @@ -448,7 +445,7 @@ func TestReconcileDevWorkspaceConfigForContainerBuilds(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -510,7 +507,7 @@ func TestReconcileDevWorkspaceConfigForContainerBuilds(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -552,7 +549,7 @@ func TestReconcileDevWorkspaceConfigForContainerBuilds(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -584,15 +581,13 @@ func TestReconcileDevWorkspaceConfigForContainerBuilds(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, testCase.existedObjects) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.existedObjects...).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) diff := cmp.Diff(testCase.expectedOperatorConfig, dwoc.Config, @@ -606,7 +601,7 @@ func TestReconcileDevWorkspaceConfigProgressTimeout(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -646,7 +641,7 @@ func TestReconcileDevWorkspaceConfigProgressTimeout(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -681,7 +676,7 @@ func TestReconcileDevWorkspaceConfigProgressTimeout(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -717,7 +712,7 @@ func TestReconcileDevWorkspaceConfigProgressTimeout(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -742,15 +737,13 @@ func TestReconcileDevWorkspaceConfigProgressTimeout(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, testCase.existedObjects) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.existedObjects...).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) diff := cmp.Diff(testCase.expectedOperatorConfig, dwoc.Config, @@ -865,15 +858,13 @@ func TestReconcileServiceAccountConfig(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) assert.Equal(t, testCase.expectedOperatorConfig.Workspace.ServiceAccount, dwoc.Config.Workspace.ServiceAccount) @@ -885,7 +876,7 @@ func TestReconcileDevWorkspaceConfigPodSchedulerName(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -923,7 +914,7 @@ func TestReconcileDevWorkspaceConfigPodSchedulerName(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -955,7 +946,7 @@ func TestReconcileDevWorkspaceConfigPodSchedulerName(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -992,7 +983,7 @@ func TestReconcileDevWorkspaceConfigPodSchedulerName(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1019,15 +1010,13 @@ func TestReconcileDevWorkspaceConfigPodSchedulerName(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.existedObjects...).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) assert.Equal(t, testCase.expectedOperatorConfig.Workspace.SchedulerName, dwoc.Config.Workspace.SchedulerName) }) @@ -1038,7 +1027,7 @@ func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -1052,13 +1041,13 @@ func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - RuntimeClassName: pointer.StringPtr("test-runtime-class"), + RuntimeClassName: pointer.String("test-runtime-class"), }, }, }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - RuntimeClassName: pointer.StringPtr("test-runtime-class"), + RuntimeClassName: pointer.String("test-runtime-class"), }, }, }, @@ -1071,11 +1060,11 @@ func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - RuntimeClassName: pointer.StringPtr("test-runtime-class"), + RuntimeClassName: pointer.String("test-runtime-class"), }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1089,7 +1078,7 @@ func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - RuntimeClassName: pointer.StringPtr("test-runtime-class"), + RuntimeClassName: pointer.String("test-runtime-class"), }, }, }, @@ -1102,11 +1091,11 @@ func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { }, Spec: chev2.CheClusterSpec{ DevEnvironments: chev2.CheClusterDevEnvironments{ - RuntimeClassName: pointer.StringPtr("test-runtime-class"), + RuntimeClassName: pointer.String("test-runtime-class"), }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1118,14 +1107,14 @@ func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { }, Config: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - RuntimeClassName: pointer.StringPtr("previous-runtime-class"), + RuntimeClassName: pointer.String("previous-runtime-class"), }, }, }, }, expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - RuntimeClassName: pointer.StringPtr("test-runtime-class"), + RuntimeClassName: pointer.String("test-runtime-class"), }, }, }, @@ -1142,7 +1131,7 @@ func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1154,7 +1143,7 @@ func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { }, Config: &controllerv1alpha1.OperatorConfiguration{ Workspace: &controllerv1alpha1.WorkspaceConfig{ - RuntimeClassName: pointer.StringPtr("previous-runtime-class"), + RuntimeClassName: pointer.String("previous-runtime-class"), }, }, }, @@ -1167,15 +1156,13 @@ func TestReconcileDevWorkspaceConfigRuntimeClassName(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.existedObjects...).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) assert.Equal(t, testCase.expectedOperatorConfig.Workspace.SchedulerName, dwoc.Config.Workspace.SchedulerName) }) @@ -1186,7 +1173,7 @@ func TestReconcileDevWorkspaceConfigServiceAccountTokens(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -1264,7 +1251,7 @@ func TestReconcileDevWorkspaceConfigServiceAccountTokens(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1318,7 +1305,7 @@ func TestReconcileDevWorkspaceConfigServiceAccountTokens(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1373,7 +1360,7 @@ func TestReconcileDevWorkspaceConfigServiceAccountTokens(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1416,15 +1403,13 @@ func TestReconcileDevWorkspaceConfigServiceAccountTokens(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.existedObjects...).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) assert.Equal(t, testCase.expectedOperatorConfig.Workspace.ServiceAccount.ServiceAccountTokens, dwoc.Config.Workspace.ServiceAccount.ServiceAccountTokens) }) @@ -1435,7 +1420,7 @@ func TestReconcileDevWorkspaceConfigDeploymentStrategy(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -1472,7 +1457,7 @@ func TestReconcileDevWorkspaceConfigDeploymentStrategy(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1503,7 +1488,7 @@ func TestReconcileDevWorkspaceConfigDeploymentStrategy(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1530,15 +1515,13 @@ func TestReconcileDevWorkspaceConfigDeploymentStrategy(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.existedObjects...).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) assert.Equal(t, testCase.expectedOperatorConfig.Workspace.DeploymentStrategy, dwoc.Config.Workspace.DeploymentStrategy) }) @@ -1716,17 +1699,15 @@ func TestReconcileDevWorkspaceProjectCloneConfig(t *testing.T) { }, }, } - runtimeDWOC := runtime.Object(existingDWOC) + runtimeDWOC := client.Object(existingDWOC) - deployContext := test.GetDeployContext(cheCluster, []runtime.Object{runtimeDWOC}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(cheCluster).WithObjects(runtimeDWOC).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testNamespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testNamespace}, dwoc) assert.NoError(t, err) diff := cmp.Diff(testCase.expectedDevWorkspaceConfig, dwoc.Config.Workspace.ProjectCloneConfig) @@ -1740,7 +1721,7 @@ func TestReconcileDevWorkspaceConfigPersistUserHome(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -1783,7 +1764,7 @@ func TestReconcileDevWorkspaceConfigPersistUserHome(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1818,7 +1799,7 @@ func TestReconcileDevWorkspaceConfigPersistUserHome(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1861,7 +1842,7 @@ func TestReconcileDevWorkspaceConfigPersistUserHome(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1905,7 +1886,7 @@ func TestReconcileDevWorkspaceConfigPersistUserHome(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1949,7 +1930,7 @@ func TestReconcileDevWorkspaceConfigPersistUserHome(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -1987,7 +1968,7 @@ func TestReconcileDevWorkspaceConfigPersistUserHome(t *testing.T) { DevEnvironments: chev2.CheClusterDevEnvironments{}, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2014,15 +1995,13 @@ func TestReconcileDevWorkspaceConfigPersistUserHome(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, testCase.existedObjects) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.existedObjects...).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) diff := cmp.Diff(testCase.expectedOperatorConfig, dwoc.Config, cmp.Options{cmpopts.IgnoreFields(controllerv1alpha1.WorkspaceConfig{}, "ServiceAccount", "DeploymentStrategy", "ContainerSecurityContext")}) assert.Empty(t, diff) @@ -2034,7 +2013,7 @@ func TestReconcileDevWorkspaceContainerSecurityContext(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -2116,7 +2095,7 @@ func TestReconcileDevWorkspaceContainerSecurityContext(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2176,7 +2155,7 @@ func TestReconcileDevWorkspaceContainerSecurityContext(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2235,7 +2214,7 @@ func TestReconcileDevWorkspaceContainerSecurityContext(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2270,15 +2249,13 @@ func TestReconcileDevWorkspaceContainerSecurityContext(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) sortCapabilities := func(capabilites []corev1.Capability) func(i, j int) bool { @@ -2308,7 +2285,7 @@ func TestReconcileDevWorkspacePodSecurityContext(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -2355,7 +2332,7 @@ func TestReconcileDevWorkspacePodSecurityContext(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2388,7 +2365,7 @@ func TestReconcileDevWorkspacePodSecurityContext(t *testing.T) { }, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2429,7 +2406,7 @@ func TestReconcileDevWorkspacePodSecurityContext(t *testing.T) { DevEnvironments: chev2.CheClusterDevEnvironments{}, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2461,15 +2438,13 @@ func TestReconcileDevWorkspacePodSecurityContext(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) assert.Equal(t, testCase.expectedOperatorConfig.Workspace.PodSecurityContext, dwoc.Config.Workspace.PodSecurityContext, fmt.Sprintf("Did not get expected PodSecurityContext.\nDiff:%s", cmp.Diff(testCase.expectedOperatorConfig.Workspace.PodSecurityContext, dwoc.Config.Workspace.PodSecurityContext))) @@ -2481,7 +2456,7 @@ func TestReconcileDevWorkspaceImagePullPolicy(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -2523,7 +2498,7 @@ func TestReconcileDevWorkspaceImagePullPolicy(t *testing.T) { ImagePullPolicy: "", }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2545,15 +2520,13 @@ func TestReconcileDevWorkspaceImagePullPolicy(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) assert.Equal(t, testCase.expectedOperatorConfig.Workspace.ImagePullPolicy, dwoc.Config.Workspace.ImagePullPolicy) }) @@ -2564,7 +2537,7 @@ func TestReconcileDevWorkspaceAnnotations(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -2612,7 +2585,7 @@ func TestReconcileDevWorkspaceAnnotations(t *testing.T) { PodAnnotations: nil, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2637,15 +2610,13 @@ func TestReconcileDevWorkspaceAnnotations(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) assert.Equal(t, testCase.expectedOperatorConfig.Workspace.PodAnnotations, dwoc.Config.Workspace.PodAnnotations) }) @@ -2656,7 +2627,7 @@ func TestReconcileDevWorkspaceIgnoredUnrecoverableEvents(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - existedObjects []runtime.Object + existedObjects []client.Object expectedOperatorConfig *controllerv1alpha1.OperatorConfiguration } @@ -2704,7 +2675,7 @@ func TestReconcileDevWorkspaceIgnoredUnrecoverableEvents(t *testing.T) { IgnoredUnrecoverableEvents: nil, }, }, - existedObjects: []runtime.Object{ + existedObjects: []client.Object{ &controllerv1alpha1.DevWorkspaceOperatorConfig{ ObjectMeta: metav1.ObjectMeta{ Name: devWorkspaceConfigName, @@ -2729,15 +2700,13 @@ func TestReconcileDevWorkspaceIgnoredUnrecoverableEvents(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + deployContext := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() devWorkspaceConfigReconciler := NewDevWorkspaceConfigReconciler() - _, _, err := devWorkspaceConfigReconciler.Reconcile(deployContext) - assert.NoError(t, err) + test.EnsureReconcile(t, deployContext, devWorkspaceConfigReconciler.Reconcile) dwoc := &controllerv1alpha1.DevWorkspaceOperatorConfig{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) + err := deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: devWorkspaceConfigName, Namespace: testCase.cheCluster.Namespace}, dwoc) assert.NoError(t, err) assert.Equal(t, testCase.expectedOperatorConfig.Workspace.IgnoredUnrecoverableEvents, dwoc.Config.Workspace.IgnoredUnrecoverableEvents) }) diff --git a/pkg/deploy/devfileregistry/devfileregistry_test.go b/pkg/deploy/devfileregistry/devfileregistry_test.go index 15c8b3367e..ce474d3c65 100644 --- a/pkg/deploy/devfileregistry/devfileregistry_test.go +++ b/pkg/deploy/devfileregistry/devfileregistry_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -18,12 +18,10 @@ import ( defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" ) func TestDevfileRegistryReconciler(t *testing.T) { @@ -168,15 +166,10 @@ func TestDevfileRegistryReconciler(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() devfileRegistryReconciler := NewDevfileRegistryReconciler() - for i := 0; i < 2; i++ { - _, done, err := devfileRegistryReconciler.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) - } + test.EnsureReconcile(t, ctx, devfileRegistryReconciler.Reconcile) assert.Equal(t, testCase.expectedDevfileRegistryURL, ctx.CheCluster.Status.DevfileRegistryURL) assert.Equal(t, testCase.expectedDisableInternalRegistry, ctx.CheCluster.Spec.Components.DevfileRegistry.DisableInternalRegistry) diff --git a/pkg/deploy/editors-definitions/editors_definitions_test.go b/pkg/deploy/editors-definitions/editors_definitions_test.go index a4888ff884..d62abbd1aa 100644 --- a/pkg/deploy/editors-definitions/editors_definitions_test.go +++ b/pkg/deploy/editors-definitions/editors_definitions_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -18,7 +18,6 @@ import ( "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/yaml" ) @@ -66,7 +65,7 @@ func TestReadEditorDefinitions(t *testing.T) { } func TestSyncEditorDefinitions(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() editorDefinitions, err := readEditorDefinitions() assert.NoError(t, err) diff --git a/pkg/deploy/expose/expose.go b/pkg/deploy/expose/expose.go index 45b89d0b47..2c3cb6d109 100644 --- a/pkg/deploy/expose/expose.go +++ b/pkg/deploy/expose/expose.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -26,10 +26,6 @@ import ( networking "k8s.io/api/networking/v1" ) -const ( - gatewayConfigComponentName = "che-gateway-config" -) - // Expose exposes the specified component according to the configured exposure strategy rules func Expose( deployContext *chetypes.DeployContext, diff --git a/pkg/deploy/finalizer_test.go b/pkg/deploy/finalizer_test.go index 81558ffd2f..0b4aed9ad0 100644 --- a/pkg/deploy/finalizer_test.go +++ b/pkg/deploy/finalizer_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -13,19 +13,12 @@ package deploy import ( - "os" + "testing" chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/eclipse-che/che-operator/pkg/common/utils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - "testing" ) const ( @@ -33,40 +26,24 @@ const ( ) func TestAppendFinalizer(t *testing.T) { - cheCluster := &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - } - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme, cheCluster) - - deployContext := &chetypes.DeployContext{ - CheCluster: cheCluster, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - err := AppendFinalizer(deployContext, finalizer) + err := AppendFinalizer(ctx, finalizer) if err != nil { t.Fatalf("Failed to append finalizer: %v", err) } - if !utils.Contains(deployContext.CheCluster.ObjectMeta.Finalizers, finalizer) { + if !utils.Contains(ctx.CheCluster.ObjectMeta.Finalizers, finalizer) { t.Fatalf("Failed to append finalizer: %v", err) } // shouldn't add finalizer twice - err = AppendFinalizer(deployContext, finalizer) + err = AppendFinalizer(ctx, finalizer) if err != nil { t.Fatalf("Failed to append finalizer: %v", err) } - if len(deployContext.CheCluster.ObjectMeta.Finalizers) != 1 { + if len(ctx.CheCluster.ObjectMeta.Finalizers) != 1 { t.Fatalf("Finalizer shouldn't be added twice") } } @@ -79,24 +56,15 @@ func TestDeleteFinalizer(t *testing.T) { Finalizers: []string{finalizer}, }, } - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme, cheCluster) - deployContext := &chetypes.DeployContext{ - CheCluster: cheCluster, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().WithCheCluster(cheCluster).Build() - err := DeleteFinalizer(deployContext, finalizer) + err := DeleteFinalizer(ctx, finalizer) if err != nil { t.Fatalf("Failed to append finalizer: %v", err) } - if utils.Contains(deployContext.CheCluster.ObjectMeta.Finalizers, finalizer) { + if utils.Contains(ctx.CheCluster.ObjectMeta.Finalizers, finalizer) { t.Fatalf("Failed to delete finalizer: %v", err) } } diff --git a/pkg/deploy/gateway/gateway_test.go b/pkg/deploy/gateway/gateway_test.go index 0ec9ff56cd..a87fbe8a13 100644 --- a/pkg/deploy/gateway/gateway_test.go +++ b/pkg/deploy/gateway/gateway_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -20,7 +20,6 @@ import ( "k8s.io/utils/pointer" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/pkg/common/chetypes" "github.com/eclipse-che/che-operator/pkg/common/constants" @@ -30,40 +29,20 @@ import ( 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/types" "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/yaml" ) func TestSyncAllToCluster(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + ctx := test.NewCtxBuilder().Build() - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - corev1.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - Proxy: &chetypes.Proxy{}, - } - - done, err := SyncGatewayToCluster(deployContext) + done, err := SyncGatewayToCluster(ctx) assert.True(t, done) assert.Nil(t, err) deployment := &appsv1.Deployment{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: GatewayServiceName, Namespace: "eclipse-che"}, deployment) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: GatewayServiceName, Namespace: "eclipse-che"}, deployment) if err != nil { t.Fatalf("Failed to get deployment: %v", err) } @@ -75,39 +54,21 @@ func TestSyncAllToCluster(t *testing.T) { } service := &corev1.Service{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: GatewayServiceName, Namespace: "eclipse-che"}, service) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: GatewayServiceName, Namespace: "eclipse-che"}, service) if err != nil { t.Fatalf("Failed to get service: %v", err) } } func TestNativeUserGateway(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + ctx := test.NewCtxBuilder().Build() - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - corev1.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - Proxy: &chetypes.Proxy{}, - } - - done, err := SyncGatewayToCluster(deployContext) + done, err := SyncGatewayToCluster(ctx) assert.True(t, done) assert.Nil(t, err) deployment := &appsv1.Deployment{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: GatewayServiceName, Namespace: "eclipse-che"}, deployment) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: GatewayServiceName, Namespace: "eclipse-che"}, deployment) if err != nil { t.Fatalf("Failed to get deployment: %v", err) } @@ -126,7 +87,7 @@ func TestNativeUserGateway(t *testing.T) { } service := &corev1.Service{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: GatewayServiceName, Namespace: "eclipse-che"}, service) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: GatewayServiceName, Namespace: "eclipse-che"}, service) if err != nil { t.Fatalf("Failed to get service: %v", err) } @@ -145,18 +106,15 @@ func TestRandomCookieSecret(t *testing.T) { } func TestOauthProxyConfigUnauthorizedPaths(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - t.Run("no skip auth", func(t *testing.T) { - ctx := test.GetDeployContext( - &chev2.CheCluster{ - Spec: chev2.CheClusterSpec{ - Components: chev2.CheClusterComponents{ - PluginRegistry: chev2.PluginRegistry{ - DisableInternalRegistry: true, - }, - }}, - }, nil) + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + Spec: chev2.CheClusterSpec{ + Components: chev2.CheClusterComponents{ + PluginRegistry: chev2.PluginRegistry{ + DisableInternalRegistry: true, + }, + }}, + }).Build() configmap := getGatewayOauthProxyConfigSpec(ctx, "blabol") config := configmap.Data["oauth-proxy.cfg"] @@ -166,16 +124,15 @@ func TestOauthProxyConfigUnauthorizedPaths(t *testing.T) { }) t.Run("skip plugin registry", func(t *testing.T) { - ctx := test.GetDeployContext( - &chev2.CheCluster{ - Spec: chev2.CheClusterSpec{ - Components: chev2.CheClusterComponents{ - PluginRegistry: chev2.PluginRegistry{ - DisableInternalRegistry: false, - OpenVSXURL: pointer.String(""), - }, - }}, - }, nil) + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + Spec: chev2.CheClusterSpec{ + Components: chev2.CheClusterComponents{ + PluginRegistry: chev2.PluginRegistry{ + DisableInternalRegistry: false, + OpenVSXURL: pointer.String(""), + }, + }}, + }).Build() configmap := getGatewayOauthProxyConfigSpec(ctx, "blabol") config := configmap.Data["oauth-proxy.cfg"] @@ -185,10 +142,7 @@ func TestOauthProxyConfigUnauthorizedPaths(t *testing.T) { }) t.Run("skip '/healthz' path", func(t *testing.T) { - ctx := test.GetDeployContext( - &chev2.CheCluster{ - Spec: chev2.CheClusterSpec{}, - }, nil) + ctx := test.NewCtxBuilder().Build() configmap := getGatewayOauthProxyConfigSpec(ctx, "blabol") config := configmap.Data["oauth-proxy.cfg"] assert.Contains(t, config, "/healthz$") @@ -196,8 +150,6 @@ func TestOauthProxyConfigUnauthorizedPaths(t *testing.T) { } func TestTokenValidityCheckOnOpenShiftNativeUser(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) corev1.SchemeBuilder.AddToScheme(scheme.Scheme) @@ -256,7 +208,7 @@ func TestCustomizeGatewayDeploymentAllImages(t *testing.T) { }, }, } - ctx := test.GetDeployContext(checluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).Build() deployment, err := getGatewayDeploymentSpec(ctx) assert.NoError(t, err) @@ -297,7 +249,7 @@ func TestCustomizeGatewayDeploymentSingleImage(t *testing.T) { }, }, } - ctx := test.GetDeployContext(checluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).Build() deployment, err := getGatewayDeploymentSpec(ctx) assert.NoError(t, err) @@ -366,7 +318,7 @@ func TestKubeRbacProxyLogLevel(t *testing.T) { }, }, } - ctx := test.GetDeployContext(checluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).Build() deployment, err := getGatewayDeploymentSpec(ctx) assert.NoError(t, err) @@ -377,9 +329,7 @@ func TestKubeRbacProxyLogLevel(t *testing.T) { } func TestKubeRbacProxyLogLevelDefault(t *testing.T) { - ctx := test.GetDeployContext(&chev2.CheCluster{ - Spec: chev2.CheClusterSpec{}, - }, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() deployment, err := getGatewayDeploymentSpec(ctx) assert.NoError(t, err) diff --git a/pkg/deploy/gateway/oauth_proxy_test.go b/pkg/deploy/gateway/oauth_proxy_test.go index 4ba3008eba..a0cd74aeb7 100644 --- a/pkg/deploy/gateway/oauth_proxy_test.go +++ b/pkg/deploy/gateway/oauth_proxy_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -17,51 +17,47 @@ import ( "k8s.io/utils/pointer" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/pkg/common/constants" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestCookieExpireForOpenShiftOauthProxyConfig(t *testing.T) { - ctx := test.GetDeployContext( - &chev2.CheCluster{ - Spec: chev2.CheClusterSpec{ - Networking: chev2.CheClusterSpecNetworking{ - Auth: chev2.Auth{ - Gateway: chev2.Gateway{ - OAuthProxy: &chev2.OAuthProxy{ - CookieExpireSeconds: pointer.Int32(3665), - }, + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Auth: chev2.Auth{ + Gateway: chev2.Gateway{ + OAuthProxy: &chev2.OAuthProxy{ + CookieExpireSeconds: pointer.Int32(3665), }, }, - }}, - }, nil) - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + }, + }}, + }).Build() config := openshiftOauthProxyConfig(ctx, "") assert.Contains(t, config, "cookie_expire = \"1h1m5s\"") } func TestCookieExpireKubernetesOauthProxyConfig(t *testing.T) { - ctx := test.GetDeployContext( - &chev2.CheCluster{ - Spec: chev2.CheClusterSpec{ - Networking: chev2.CheClusterSpecNetworking{ - Auth: chev2.Auth{ - Gateway: chev2.Gateway{ - OAuthProxy: &chev2.OAuthProxy{ - CookieExpireSeconds: pointer.Int32(3665), - }, + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Auth: chev2.Auth{ + Gateway: chev2.Gateway{ + OAuthProxy: &chev2.OAuthProxy{ + CookieExpireSeconds: pointer.Int32(3665), }, }, - }}, - }, nil) + }, + }}, + }).Build() + infrastructure.InitializeForTesting(infrastructure.Kubernetes) config := kubernetesOauthProxyConfig(ctx, "") @@ -69,33 +65,31 @@ func TestCookieExpireKubernetesOauthProxyConfig(t *testing.T) { } func TestKubernetesOauthProxySecretSecretFoundWithKey(t *testing.T) { - ctx := test.GetDeployContext( - &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - }, - Spec: chev2.CheClusterSpec{ - Networking: chev2.CheClusterSpecNetworking{ - Auth: chev2.Auth{ - OAuthSecret: "my-secret", - }, - }}, + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", }, - []runtime.Object{ - &corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - Kind: "Secret", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-secret", - Namespace: "eclipse-che", - Labels: map[string]string{constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg}, + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Auth: chev2.Auth{ + OAuthSecret: "my-secret", }, - Type: corev1.SecretTypeOpaque, - Data: map[string][]byte{"oAuthSecret": []byte("my")}, - }, - }) + }}, + }).WithObjects(&corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-secret", + Namespace: "eclipse-che", + Labels: map[string]string{constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg}, + }, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{"oAuthSecret": []byte("my")}, + }, + ).Build() + ctx.CheHost = "che-site.che-domain.com" infrastructure.InitializeForTesting(infrastructure.Kubernetes) @@ -104,33 +98,30 @@ func TestKubernetesOauthProxySecretSecretFoundWithKey(t *testing.T) { } func TestKubernetesOauthProxySecretSecretFoundWithWrongKey(t *testing.T) { - ctx := test.GetDeployContext( - &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - }, - Spec: chev2.CheClusterSpec{ - Networking: chev2.CheClusterSpecNetworking{ - Auth: chev2.Auth{ - OAuthSecret: "my-secret", - }, - }}, + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", }, - []runtime.Object{ - &corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - Kind: "Secret", - APIVersion: "v1", + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Auth: chev2.Auth{ + OAuthSecret: "my-secret", }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-secret", - Namespace: "eclipse-che", - Labels: map[string]string{constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg}, - }, - Type: corev1.SecretTypeOpaque, - Data: map[string][]byte{"keyIsNotoAuthSecret": []byte("my")}, - }, - }) + }}, + }).WithObjects(&corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-secret", + Namespace: "eclipse-che", + Labels: map[string]string{constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg}, + }, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{"keyIsNotoAuthSecret": []byte("my")}, + }).Build() + ctx.CheHost = "che-site.che-domain.com" infrastructure.InitializeForTesting(infrastructure.Kubernetes) @@ -140,33 +131,29 @@ func TestKubernetesOauthProxySecretSecretFoundWithWrongKey(t *testing.T) { } func TestKubernetesOauthProxySecretSecretFoundWithWrongSecretName(t *testing.T) { - ctx := test.GetDeployContext( - &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - }, - Spec: chev2.CheClusterSpec{ - Networking: chev2.CheClusterSpecNetworking{ - Auth: chev2.Auth{ - OAuthSecret: "wrong-secret-name", - }, - }}, + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", }, - []runtime.Object{ - &corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - Kind: "Secret", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-secret", - Namespace: "eclipse-che", - Labels: map[string]string{constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg}, + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Auth: chev2.Auth{ + OAuthSecret: "wrong-secret-name", }, - Type: corev1.SecretTypeOpaque, - Data: map[string][]byte{"oAuthSecret": []byte("my")}, - }, - }) + }}, + }).WithObjects(&corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-secret", + Namespace: "eclipse-che", + Labels: map[string]string{constants.KubernetesPartOfLabelKey: constants.CheEclipseOrg}, + }, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{"oAuthSecret": []byte("my")}, + }).Build() ctx.CheHost = "che-site.che-domain.com" infrastructure.InitializeForTesting(infrastructure.Kubernetes) @@ -176,19 +163,18 @@ func TestKubernetesOauthProxySecretSecretFoundWithWrongSecretName(t *testing.T) } func TestKubernetesOauthProxySecretLegacyPlaintextSecretName(t *testing.T) { - ctx := test.GetDeployContext( - &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - }, - Spec: chev2.CheClusterSpec{ - Networking: chev2.CheClusterSpecNetworking{ - Auth: chev2.Auth{ - OAuthSecret: "abcdefPlainTextSecret", - }, + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + Networking: chev2.CheClusterSpecNetworking{ + Auth: chev2.Auth{ + OAuthSecret: "abcdefPlainTextSecret", }, }, - }, nil) + }, + }).Build() ctx.CheHost = "che-site.che-domain.com" infrastructure.InitializeForTesting(infrastructure.Kubernetes) @@ -198,7 +184,7 @@ func TestKubernetesOauthProxySecretLegacyPlaintextSecretName(t *testing.T) { } func TestKubernetesOauthProxyConfig(t *testing.T) { - ctx := test.GetDeployContext( + ctx := test.NewCtxBuilder().WithCheCluster( &chev2.CheCluster{ Spec: chev2.CheClusterSpec{ Networking: chev2.CheClusterSpecNetworking{ @@ -208,7 +194,7 @@ func TestKubernetesOauthProxyConfig(t *testing.T) { OAuthSecret: "secret", }, }}, - }, nil) + }).Build() ctx.CheHost = "che-site.che-domain.com" infrastructure.InitializeForTesting(infrastructure.Kubernetes) @@ -221,7 +207,7 @@ func TestKubernetesOauthProxyConfig(t *testing.T) { } func TestScopeDefinedForKubernetesOauthProxyConfig(t *testing.T) { - ctx := test.GetDeployContext( + ctx := test.NewCtxBuilder().WithCheCluster( &chev2.CheCluster{ Spec: chev2.CheClusterSpec{ Networking: chev2.CheClusterSpecNetworking{ @@ -232,7 +218,7 @@ func TestScopeDefinedForKubernetesOauthProxyConfig(t *testing.T) { OAuthScope: "scope1 scope2 scope3 scope4 scope5", }, }}, - }, nil) + }).Build() infrastructure.InitializeForTesting(infrastructure.Kubernetes) config := kubernetesOauthProxyConfig(ctx, "blabol") @@ -240,7 +226,7 @@ func TestScopeDefinedForKubernetesOauthProxyConfig(t *testing.T) { } func TestAccessTokenDefinedForKubernetesOauthProxyConfig(t *testing.T) { - ctx := test.GetDeployContext( + ctx := test.NewCtxBuilder().WithCheCluster( &chev2.CheCluster{ Spec: chev2.CheClusterSpec{ Networking: chev2.CheClusterSpecNetworking{ @@ -251,7 +237,7 @@ func TestAccessTokenDefinedForKubernetesOauthProxyConfig(t *testing.T) { IdentityToken: "access_token", }, }}, - }, nil) + }).Build() infrastructure.InitializeForTesting(infrastructure.Kubernetes) config := kubernetesOauthProxyConfig(ctx, "blabol") diff --git a/pkg/deploy/identity-provider/identity_provider_reconciler_test.go b/pkg/deploy/identity-provider/identity_provider_reconciler_test.go index ef1f254507..a857bca139 100644 --- a/pkg/deploy/identity-provider/identity_provider_reconciler_test.go +++ b/pkg/deploy/identity-provider/identity_provider_reconciler_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -23,7 +23,6 @@ import ( oauthv1 "github.com/openshift/api/oauth/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -41,7 +40,7 @@ func TestFinalizeDefaultOAuthClientName(t *testing.T) { }, } - ctx := test.GetDeployContext(checluster, []runtime.Object{oauthClient}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).WithObjects(oauthClient).Build() assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "eclipse-che-client"}, &oauthv1.OAuthClient{})) @@ -71,7 +70,7 @@ func TestFinalizeOAuthClient(t *testing.T) { }, } - ctx := test.GetDeployContext(checluster, []runtime.Object{oauthClient}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).WithObjects(oauthClient).Build() assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "test"}, &oauthv1.OAuthClient{})) @@ -100,7 +99,7 @@ func TestShouldFindSingleOAuthClient(t *testing.T) { }, } - ctx := test.GetDeployContext(checluster, []runtime.Object{oauthClient1, oauthClient2}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).WithObjects(oauthClient1).WithObjects(oauthClient2).Build() oauthClient, err := GetOAuthClient(ctx) assert.Nil(t, err) assert.NotNil(t, oauthClient) @@ -123,7 +122,7 @@ func TestSyncOAuthClientShouldSyncTokenTimeout(t *testing.T) { }, } - ctx := test.GetDeployContext(checluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).Build() done, err := syncOAuthClient(ctx) assert.True(t, done) assert.Nil(t, err) @@ -214,7 +213,7 @@ func TestSyncOAuthClient(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() _, err := syncOAuthClient(ctx) assert.Nil(t, err) @@ -315,7 +314,7 @@ func TestSyncExistedOAuthClient(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{oauthClient1, oauthClient2}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(oauthClient1).WithObjects(oauthClient2).Build() _, err := syncOAuthClient(ctx) assert.Nil(t, err) diff --git a/pkg/deploy/image-puller/imagepuller_test.go b/pkg/deploy/image-puller/imagepuller_test.go index 958ffd721f..e4c0790a5a 100644 --- a/pkg/deploy/image-puller/imagepuller_test.go +++ b/pkg/deploy/image-puller/imagepuller_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -16,6 +16,8 @@ import ( "context" "os" + "sigs.k8s.io/controller-runtime/pkg/client" + chev1alpha1 "github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1" "github.com/eclipse-che/che-operator/pkg/deploy" "github.com/google/go-cmp/cmp" @@ -23,22 +25,20 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/api/errors" + "testing" + chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/pkg/common/constants" "github.com/eclipse-che/che-operator/pkg/common/test" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - fakeDiscovery "k8s.io/client-go/discovery/fake" - - "testing" ) func TestImagePullerConfiguration(t *testing.T) { type testCase struct { name string cheCluster *chev2.CheCluster - initObjects []runtime.Object + initObjects []client.Object testCaseFilePath string expectedImagePuller *chev1alpha1.KubernetesImagePuller } @@ -81,7 +81,7 @@ func TestImagePullerConfiguration(t *testing.T) { Enable: true, }), testCaseFilePath: "image-puller-resources-test/imagepuller_testcase_2.json", - initObjects: []runtime.Object{ + initObjects: []client.Object{ InitImagePuller(chev1alpha1.KubernetesImagePullerSpec{ DeploymentName: defaultDeploymentName, ConfigMapName: defaultConfigMapName, @@ -106,7 +106,7 @@ func TestImagePullerConfiguration(t *testing.T) { Images: "image=image_url;", }}), testCaseFilePath: "image-puller-resources-test/imagepuller_testcase_1.json", - initObjects: []runtime.Object{ + initObjects: []client.Object{ InitImagePuller(chev1alpha1.KubernetesImagePullerSpec{ DeploymentName: defaultDeploymentName, ConfigMapName: defaultConfigMapName, @@ -126,7 +126,7 @@ func TestImagePullerConfiguration(t *testing.T) { Enable: false, }), testCaseFilePath: "image-puller-resources-test/imagepuller_testcase_1.json", - initObjects: []runtime.Object{ + initObjects: []client.Object{ InitImagePuller(chev1alpha1.KubernetesImagePullerSpec{ DeploymentName: defaultDeploymentName, ConfigMapName: defaultConfigMapName, @@ -138,17 +138,7 @@ func TestImagePullerConfiguration(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, testCase.initObjects) - ctx.ClusterAPI.DiscoveryClient.(*fakeDiscovery.FakeDiscovery).Fake.Resources = []*metav1.APIResourceList{ - { - GroupVersion: "che.eclipse.org/v1alpha1", - APIResources: []metav1.APIResource{ - { - Name: resourceName, - }, - }, - }, - } + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.initObjects...).Build() ip := &ImagePuller{ imageProvider: &DashboardApiDefaultImagesProvider{ @@ -157,11 +147,11 @@ func TestImagePullerConfiguration(t *testing.T) { }, }, } - _, _, err := ip.Reconcile(ctx) - assert.NoError(t, err) + + test.EnsureReconcile(t, ctx, ip.Reconcile) actualImagePuller := &chev1alpha1.KubernetesImagePuller{} - err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: "eclipse-che", Name: "eclipse-che-image-puller"}, actualImagePuller) + err := ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Namespace: "eclipse-che", Name: "eclipse-che-image-puller"}, actualImagePuller) if testCase.cheCluster.Spec.Components.ImagePuller.Enable { assert.NoError(t, err) diff --git a/pkg/deploy/ingress_test.go b/pkg/deploy/ingress_test.go index 11baaf257d..8068de1f70 100644 --- a/pkg/deploy/ingress_test.go +++ b/pkg/deploy/ingress_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -23,7 +23,6 @@ import ( networking "k8s.io/api/networking/v1" v1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/pointer" @@ -173,8 +172,8 @@ func TestIngressSpec(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) - _, actualIngress := GetIngressSpec(deployContext, + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() + _, actualIngress := GetIngressSpec(ctx, "test", "", "che-host", @@ -199,7 +198,7 @@ func TestSyncIngressToCluster(t *testing.T) { }, } - deployContext := test.GetDeployContext(cheCluster, []runtime.Object{}) + deployContext := test.NewCtxBuilder().WithCheCluster(cheCluster).Build() _, done, err := SyncIngressToCluster(deployContext, "test", "", "service-1", 8080, "component") assert.Nil(t, err) assert.True(t, done) diff --git a/pkg/deploy/job_test.go b/pkg/deploy/job_test.go index 25f82f0b9b..19b311cd7e 100644 --- a/pkg/deploy/job_test.go +++ b/pkg/deploy/job_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -14,47 +14,28 @@ package deploy import ( "context" + "testing" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/test" batchv1 "k8s.io/api/batch/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "testing" ) func TestSyncJobToCluster(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - done, err := SyncJobToCluster(deployContext, "test", "component", "image-1", "sa", map[string]string{}) + done, err := SyncJobToCluster(ctx, "test", "component", "image-1", "sa", map[string]string{}) if !done || err != nil { t.Fatalf("Failed to sync job: %v", err) } - done, err = SyncJobToCluster(deployContext, "test", "component", "image-2", "sa", map[string]string{}) + done, err = SyncJobToCluster(ctx, "test", "component", "image-2", "sa", map[string]string{}) if !done || err != nil { t.Fatalf("Failed to sync job: %v", err) } actual := &batchv1.Job{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) if err != nil { t.Fatalf("Failed to get job: %v", err) } diff --git a/pkg/deploy/migration/checluster-defaults-cleaner_test.go b/pkg/deploy/migration/checluster-defaults-cleaner_test.go index 3f6cc54117..e8f2ef5c99 100644 --- a/pkg/deploy/migration/checluster-defaults-cleaner_test.go +++ b/pkg/deploy/migration/checluster-defaults-cleaner_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -25,7 +25,6 @@ import ( "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/pointer" chev2 "github.com/eclipse-che/che-operator/api/v2" @@ -107,12 +106,10 @@ func TestCheClusterDefaultsCleanerShouldNotChangeValuesOnInstallation(t *testing cheClusterCopy := testCase.cheCluster.DeepCopy() - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() cheClusterDefaultsCleanup := NewCheClusterDefaultsCleaner() - _, done, err := cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, cheClusterCopy.Spec.DevEnvironments.DefaultEditor, ctx.CheCluster.Spec.DevEnvironments.DefaultEditor) assert.Equal(t, cheClusterCopy.Spec.DevEnvironments.DefaultComponents, ctx.CheCluster.Spec.DevEnvironments.DefaultComponents) @@ -191,22 +188,17 @@ func TestCheClusterDefaultsCleanerDefaultEditor(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { infrastructure.InitializeForTesting(testCase.infra) - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() cheClusterDefaultsCleanup := NewCheClusterDefaultsCleaner() - _, done, err := cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedDefaultEditor, ctx.CheCluster.Spec.DevEnvironments.DefaultEditor) cheClusterFields := cheClusterDefaultsCleanup.readCheClusterDefaultsCleanupAnnotation(ctx) assert.Equal(t, "true", cheClusterFields["spec.devEnvironments.defaultEditor"]) - // run twice to check that fields are not changed - _, done, err = cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedDefaultEditor, ctx.CheCluster.Spec.DevEnvironments.DefaultEditor) }) @@ -313,22 +305,17 @@ func TestCheClusterDefaultsCleanerDefaultComponents(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { infrastructure.InitializeForTesting(testCase.infra) - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() cheClusterDefaultsCleanup := NewCheClusterDefaultsCleaner() - _, done, err := cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedDefaultComponents, ctx.CheCluster.Spec.DevEnvironments.DefaultComponents) cheClusterFields := cheClusterDefaultsCleanup.readCheClusterDefaultsCleanupAnnotation(ctx) assert.Equal(t, "true", cheClusterFields["spec.devEnvironments.defaultComponents"]) - // run twice to check that fields are not changed - _, done, err = cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedDefaultComponents, ctx.CheCluster.Spec.DevEnvironments.DefaultComponents) }) @@ -407,22 +394,17 @@ func TestCheClusterDefaultsCleanerOpenVSXURL(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() cheClusterDefaultsCleanup := NewCheClusterDefaultsCleaner() - _, done, err := cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedOpenVSXURL, ctx.CheCluster.Spec.Components.PluginRegistry.OpenVSXURL) cheClusterFields := cheClusterDefaultsCleanup.readCheClusterDefaultsCleanupAnnotation(ctx) assert.Equal(t, "true", cheClusterFields["spec.components.pluginRegistry.openVSXURL"]) - // run twice to check that fields are not changed - _, done, err = cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedOpenVSXURL, ctx.CheCluster.Spec.Components.PluginRegistry.OpenVSXURL) }) @@ -520,22 +502,17 @@ func TestCheClusterDefaultsCleanerDashboardHeaderMessage(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { infrastructure.InitializeForTesting(testCase.infra) - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() cheClusterDefaultsCleanup := NewCheClusterDefaultsCleaner() - _, done, err := cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedHeaderMessage, ctx.CheCluster.Spec.Components.Dashboard.HeaderMessage) cheClusterFields := cheClusterDefaultsCleanup.readCheClusterDefaultsCleanupAnnotation(ctx) assert.Equal(t, "true", cheClusterFields["spec.components.dashboard.headerMessage"]) - // run twice to check that fields are not changed - _, done, err = cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedHeaderMessage, ctx.CheCluster.Spec.Components.Dashboard.HeaderMessage) }) @@ -590,12 +567,10 @@ func TestCheClusterDefaultsCleanerDisableContainerBuildCapabilities(t *testing.T t.Run(testCase.name, func(t *testing.T) { infrastructure.InitializeForTesting(testCase.infra) - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() cheClusterDefaultsCleanup := NewCheClusterDefaultsCleaner() - _, done, err := cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedDisableContainerBuildCapabilities, ctx.CheCluster.Spec.DevEnvironments.DisableContainerBuildCapabilities) @@ -603,9 +578,7 @@ func TestCheClusterDefaultsCleanerDisableContainerBuildCapabilities(t *testing.T assert.Equal(t, "true", cheClusterFields["spec.devEnvironments.disableContainerBuildCapabilities"]) // run twice to check that fields are not changed - _, done, err = cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedDisableContainerBuildCapabilities, ctx.CheCluster.Spec.DevEnvironments.DisableContainerBuildCapabilities) }) @@ -732,12 +705,10 @@ func TestCheClusterDefaultsCleanerContainerResources(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() cheClusterDefaultsCleanup := NewCheClusterDefaultsCleaner() - _, done, err := cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedDeployment, ctx.CheCluster.Spec.Components.CheServer.Deployment) @@ -745,9 +716,7 @@ func TestCheClusterDefaultsCleanerContainerResources(t *testing.T) { assert.Equal(t, "true", cheClusterFields["containers.resources"]) // run twice to check that fields are not changed - _, done, err = cheClusterDefaultsCleanup.Reconcile(ctx) - assert.NoError(t, err) - assert.True(t, done) + test.EnsureReconcile(t, ctx, cheClusterDefaultsCleanup.Reconcile) assert.Equal(t, testCase.expectedDeployment, ctx.CheCluster.Spec.Components.CheServer.Deployment) }) diff --git a/pkg/deploy/migration/on-reconcile-one-time-migration.go b/pkg/deploy/migration/on-reconcile-one-time-migration.go index 16e05d228c..9aaac3ddb7 100644 --- a/pkg/deploy/migration/on-reconcile-one-time-migration.go +++ b/pkg/deploy/migration/on-reconcile-one-time-migration.go @@ -202,7 +202,7 @@ func addPartOfCheLabelForObjectsWithLabel(ctx *chetypes.DeployContext, labelKey Namespace: ctx.CheCluster.GetNamespace(), } - // This list should be based on the list from the cache function (see NewCache filed of the managar in main.go) + // This list should be based on the list from the cache function (see NewCache filed of the manager in main.go) kindsToMigrate := []client.ObjectList{ &appsv1.DeploymentList{}, &corev1.PodList{}, diff --git a/pkg/deploy/pluginregistry/pluginregistry_deployment_test.go b/pkg/deploy/pluginregistry/pluginregistry_deployment_test.go index 849dcad484..8b8bbba3b5 100644 --- a/pkg/deploy/pluginregistry/pluginregistry_deployment_test.go +++ b/pkg/deploy/pluginregistry/pluginregistry_deployment_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -126,7 +126,7 @@ func TestGetPluginRegistryDeploymentSpec(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() pluginregistry := NewPluginRegistryReconciler() deployment, err := pluginregistry.getPluginRegistryDeploymentSpec(ctx) diff --git a/pkg/deploy/pluginregistry/pluginregistry_test.go b/pkg/deploy/pluginregistry/pluginregistry_test.go index fa6434bf64..bd6c38784b 100644 --- a/pkg/deploy/pluginregistry/pluginregistry_test.go +++ b/pkg/deploy/pluginregistry/pluginregistry_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2024 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -15,7 +15,6 @@ package pluginregistry import ( "os" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" "github.com/eclipse-che/che-operator/pkg/common/test" @@ -23,7 +22,6 @@ import ( 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/types" "k8s.io/utils/pointer" @@ -31,9 +29,7 @@ import ( ) func TestShouldDeployPluginRegistryIfOpenVSXIsEmpty(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - ctx := test.GetDeployContext(&chev2.CheCluster{ + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Name: "eclipse-che", Namespace: "eclipse-che", @@ -45,12 +41,10 @@ func TestShouldDeployPluginRegistryIfOpenVSXIsEmpty(t *testing.T) { }, }, }, - }, []runtime.Object{}) + }).Build() pluginregistry := NewPluginRegistryReconciler() - _, done, err := pluginregistry.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, pluginregistry.Reconcile) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.Service{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.ConfigMap{})) @@ -71,19 +65,10 @@ func TestShouldDeployPluginRegistryIfOpenVSXIsEmptyByDefault(t *testing.T) { // re initialize defaults with new env var defaults.Initialize() - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - ctx := test.GetDeployContext(&chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: "eclipse-che", - Namespace: "eclipse-che", - }, - }, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() pluginregistry := NewPluginRegistryReconciler() - _, done, err := pluginregistry.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, pluginregistry.Reconcile) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.Service{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.ConfigMap{})) @@ -92,9 +77,7 @@ func TestShouldDeployPluginRegistryIfOpenVSXIsEmptyByDefault(t *testing.T) { } func TestShouldNotDeployPluginRegistryIfOpenVSXConfigured(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - ctx := test.GetDeployContext(&chev2.CheCluster{ + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Name: "eclipse-che", Namespace: "eclipse-che", @@ -106,12 +89,10 @@ func TestShouldNotDeployPluginRegistryIfOpenVSXConfigured(t *testing.T) { }, }, }, - }, []runtime.Object{}) + }).Build() pluginregistry := NewPluginRegistryReconciler() - _, done, err := pluginregistry.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, pluginregistry.Reconcile) assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.Service{})) assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.ConfigMap{})) @@ -131,19 +112,10 @@ func TestShouldNotDeployPluginRegistryIfOpenVSXConfiguredByDefault(t *testing.T) // re initialize defaults with new env var defaults.Initialize() - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - ctx := test.GetDeployContext(&chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: "eclipse-che", - Namespace: "eclipse-che", - }, - }, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() pluginregistry := NewPluginRegistryReconciler() - _, done, err := pluginregistry.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, pluginregistry.Reconcile) assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.Service{})) assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "plugin-registry", Namespace: "eclipse-che"}, &corev1.ConfigMap{})) diff --git a/pkg/deploy/proxy_test.go b/pkg/deploy/proxy_test.go index 3fb4e3e78a..78f0e10079 100644 --- a/pkg/deploy/proxy_test.go +++ b/pkg/deploy/proxy_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -25,13 +25,6 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" -) - -const ( - expectedProxyURLWithUsernamePassword = "https://user:password@myproxy.com:1234" - expectedProxyURLWithoutUsernamePassword = "https://myproxy.com:1234" - expectedNoProxy = "localhost,myhost.com" ) func TestGenerateProxyJavaOptsWithUsernameAndPassword(t *testing.T) { @@ -154,7 +147,7 @@ func TestReadCheClusterProxyConfiguration(t *testing.T) { NoProxy: "host1,host2", } - ctx := test.GetDeployContext(checluster, []runtime.Object{proxySecret}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).WithObjects(proxySecret).Build() actualProxy, _ := ReadCheClusterProxyConfiguration(ctx) if !reflect.DeepEqual(actualProxy, expectedProxy) { @@ -189,7 +182,7 @@ func TestReadCheClusterProxyConfigurationNoUser(t *testing.T) { NoProxy: "host1,host2", } - ctx := test.GetDeployContext(checluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).Build() actualProxy, _ := ReadCheClusterProxyConfiguration(ctx) if !reflect.DeepEqual(actualProxy, expectedProxy) { @@ -239,7 +232,7 @@ func TestReadCheClusterProxyConfigurationNoPort(t *testing.T) { NoProxy: "host1,host2", } - ctx := test.GetDeployContext(checluster, []runtime.Object{proxySecret}) + ctx := test.NewCtxBuilder().WithCheCluster(checluster).WithObjects(proxySecret).Build() actualProxy, _ := ReadCheClusterProxyConfiguration(ctx) assert.Equal(t, actualProxy, expectedProxy) } diff --git a/pkg/deploy/reconcile_manager_test.go b/pkg/deploy/reconcile_manager_test.go index 5d3b2f63e6..1821af7ba2 100644 --- a/pkg/deploy/reconcile_manager_test.go +++ b/pkg/deploy/reconcile_manager_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -19,7 +19,6 @@ import ( "github.com/eclipse-che/che-operator/pkg/common/chetypes" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -59,32 +58,32 @@ func (tr *TestReconcilable) Finalize(ctx *chetypes.DeployContext) bool { } func TestShouldUpdateAndCleanStatus(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() tr := NewTestReconcilable(true, false) rm := NewReconcileManager() rm.RegisterReconciler(tr) - _, done, err := rm.ReconcileAll(deployContext) + _, done, err := rm.ReconcileAll(ctx) assert.False(t, done) assert.NotNil(t, err) - assert.NotEmpty(t, deployContext.CheCluster.Status.Reason) - assert.Equal(t, "Reconciler failed deploy.TestReconcilable, cause: reconcile error", deployContext.CheCluster.Status.Message) + assert.NotEmpty(t, ctx.CheCluster.Status.Reason) + assert.Equal(t, "Reconciler failed deploy.TestReconcilable, cause: reconcile error", ctx.CheCluster.Status.Message) assert.Equal(t, tr, rm.failedReconciler) - _, done, err = rm.ReconcileAll(deployContext) + _, done, err = rm.ReconcileAll(ctx) assert.True(t, done) assert.Nil(t, err) - assert.Empty(t, deployContext.CheCluster.Status.Reason) - assert.Empty(t, deployContext.CheCluster.Status.Message) + assert.Empty(t, ctx.CheCluster.Status.Reason) + assert.Empty(t, ctx.CheCluster.Status.Message) assert.Nil(t, rm.failedReconciler) } func TestShouldCleanUpAllFinalizers(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() rm := NewReconcileManager() rm.RegisterReconciler(NewTestReconcilable(false, false)) @@ -100,7 +99,7 @@ func TestShouldCleanUpAllFinalizers(t *testing.T) { } func TestShouldNotCleanUpAllFinalizersIfFailure(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() rm := NewReconcileManager() rm.RegisterReconciler(NewTestReconcilable(false, true)) diff --git a/pkg/deploy/role_test.go b/pkg/deploy/role_test.go index cc73558794..4fe5f63eab 100644 --- a/pkg/deploy/role_test.go +++ b/pkg/deploy/role_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -14,37 +14,17 @@ package deploy import ( "context" + "testing" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/test" rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "testing" ) func TestSyncRoleToCluster(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - rbacv1.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - done, err := SyncRoleToCluster(deployContext, "test", []rbacv1.PolicyRule{ + done, err := SyncRoleToCluster(ctx, "test", []rbacv1.PolicyRule{ { APIGroups: []string{"test-1"}, Resources: []string{"test-1"}, @@ -55,7 +35,7 @@ func TestSyncRoleToCluster(t *testing.T) { t.Fatalf("Failed to sync role: %v", err) } - done, err = SyncRoleToCluster(deployContext, "test", []rbacv1.PolicyRule{ + done, err = SyncRoleToCluster(ctx, "test", []rbacv1.PolicyRule{ { APIGroups: []string{"test-2"}, Resources: []string{"test-2"}, @@ -64,7 +44,7 @@ func TestSyncRoleToCluster(t *testing.T) { }) actual := &rbacv1.Role{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) if err != nil { t.Fatalf("Failed to get role: %v", err) } diff --git a/pkg/deploy/rolebinding_test.go b/pkg/deploy/rolebinding_test.go index eccea0d6c0..66d2b92880 100644 --- a/pkg/deploy/rolebinding_test.go +++ b/pkg/deploy/rolebinding_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -14,54 +14,35 @@ package deploy import ( "context" + "testing" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/test" rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "testing" ) func TestSyncRoleBindingToCluster(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - rbacv1.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - done, err := SyncRoleBindingToCluster(deployContext, "test", "sa", "clusterrole-1", "kind") + done, err := SyncRoleBindingToCluster(ctx, "test", "sa", "clusterrole-1", "kind") if !done || err != nil { t.Fatalf("Failed to sync crb: %v", err) } // sync a new role binding - _, err = SyncRoleBindingToCluster(deployContext, "test", "sa", "clusterrole-2", "kind") + _, err = SyncRoleBindingToCluster(ctx, "test", "sa", "clusterrole-2", "kind") if err != nil { t.Fatalf("Failed to sync crb: %v", err) } // sync role binding twice to be sure update done correctly - done, err = SyncRoleBindingToCluster(deployContext, "test", "sa", "clusterrole-2", "kind") + done, err = SyncRoleBindingToCluster(ctx, "test", "sa", "clusterrole-2", "kind") if !done || err != nil { t.Fatalf("Failed to sync crb: %v", err) } actual := &rbacv1.RoleBinding{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) if err != nil { t.Fatalf("Failed to get crb: %v", err) } diff --git a/pkg/deploy/route_test.go b/pkg/deploy/route_test.go index 9b26837032..c5c118eb4c 100644 --- a/pkg/deploy/route_test.go +++ b/pkg/deploy/route_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -23,7 +23,6 @@ import ( defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" "github.com/eclipse-che/che-operator/pkg/common/test" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" @@ -153,9 +152,9 @@ func TestRouteSpec(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - deployContext := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() - actualRoute, err := GetRouteSpec(deployContext, + actualRoute, err := GetRouteSpec(ctx, testCase.routeName, testCase.routePath, testCase.serviceName, @@ -170,31 +169,31 @@ func TestRouteSpec(t *testing.T) { } func TestSyncRouteToCluster(t *testing.T) { - deployContext := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() - done, err := SyncRouteToCluster(deployContext, "test", "", "service", 80, "test") + done, err := SyncRouteToCluster(ctx, "test", "", "service", 80, "test") assert.Nil(t, err) assert.True(t, done) // sync another route - done, err = SyncRouteToCluster(deployContext, "test", "", "service", 90, "test") + done, err = SyncRouteToCluster(ctx, "test", "", "service", 90, "test") assert.Nil(t, err) assert.True(t, done) actual := &routev1.Route{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) assert.Nil(t, err) assert.Equal(t, int32(90), actual.Spec.Port.TargetPort.IntVal) // sync route with labels & domain - deployContext.CheCluster.Spec.Networking.Domain = "domain" - deployContext.CheCluster.Spec.Networking.Labels = map[string]string{"a": "b"} - done, err = SyncRouteToCluster(deployContext, "test", "", "service", 90, "test") + ctx.CheCluster.Spec.Networking.Domain = "domain" + ctx.CheCluster.Spec.Networking.Labels = map[string]string{"a": "b"} + done, err = SyncRouteToCluster(ctx, "test", "", "service", 90, "test") assert.Nil(t, err) assert.True(t, done) actual = &routev1.Route{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) assert.Nil(t, err) assert.Equal(t, "b", actual.ObjectMeta.Labels["a"]) @@ -202,11 +201,11 @@ func TestSyncRouteToCluster(t *testing.T) { assert.Equal(t, expectedHost, actual.Spec.Host) // sync route with annotations - deployContext.CheCluster.Spec.Networking.Annotations = map[string]string{"a": "b"} - done, err = SyncRouteToCluster(deployContext, "test", "", "service", 90, "test") + ctx.CheCluster.Spec.Networking.Annotations = map[string]string{"a": "b"} + done, err = SyncRouteToCluster(ctx, "test", "", "service", 90, "test") actual = &routev1.Route{} - err = deployContext.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) assert.Nil(t, err) assert.True(t, done) assert.Equal(t, "b", actual.ObjectMeta.Annotations["a"]) diff --git a/pkg/deploy/secret_test.go b/pkg/deploy/secret_test.go index 40d12f0f2a..dc5aaf4182 100644 --- a/pkg/deploy/secret_test.go +++ b/pkg/deploy/secret_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -14,21 +14,13 @@ package deploy import ( "context" - "os" + "testing" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/test" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - "testing" + "sigs.k8s.io/controller-runtime/pkg/client" ) func TestGetSecrets(t *testing.T) { @@ -36,11 +28,11 @@ func TestGetSecrets(t *testing.T) { name string labels map[string]string annotations map[string]string - initObjects []runtime.Object + initObjects []client.Object expectedAmount int } - runtimeSecrets := []runtime.Object{ + runtimeSecrets := []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -82,7 +74,7 @@ func TestGetSecrets(t *testing.T) { testCases := []testCase{ { name: "Get secrets", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, labels: map[string]string{ "l1": "v1", }, @@ -93,7 +85,7 @@ func TestGetSecrets(t *testing.T) { }, { name: "Get secrets", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, labels: map[string]string{ "l1": "v1", }, @@ -105,7 +97,7 @@ func TestGetSecrets(t *testing.T) { }, { name: "Get secrets", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, labels: map[string]string{ "l1": "v1", "l2": "v2", @@ -117,7 +109,7 @@ func TestGetSecrets(t *testing.T) { }, { name: "Get secrets, unknown label", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, labels: map[string]string{ "l4": "v4", }, @@ -126,7 +118,7 @@ func TestGetSecrets(t *testing.T) { }, { name: "Get secrets, unknown annotation", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, labels: map[string]string{ "l1": "v1", }, @@ -139,25 +131,10 @@ func TestGetSecrets(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - logf.SetLogger(zap.New(zap.WriteTo(os.Stdout), zap.UseDevMode(true))) - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) testCase.initObjects = append(testCase.initObjects, runtimeSecrets...) - cli := fake.NewFakeClientWithScheme(scheme.Scheme, testCase.initObjects...) - - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().WithObjects(testCase.initObjects...).Build() - secrets, err := GetSecrets(deployContext, testCase.labels, testCase.annotations) + secrets, err := GetSecrets(ctx, testCase.labels, testCase.annotations) if err != nil { t.Fatalf("Error getting secrets: %v", err) } @@ -170,35 +147,21 @@ func TestGetSecrets(t *testing.T) { } func TestSyncSecretToCluster(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - done, err := SyncSecretToCluster(deployContext, "test", "eclipse-che", map[string][]byte{"A": []byte("AAAA")}) + done, err := SyncSecretToCluster(ctx, "test", "eclipse-che", map[string][]byte{"A": []byte("AAAA")}) if !done || err != nil { t.Fatalf("Failed to sync secret: %v", err) } // sync another secret - done, err = SyncSecretToCluster(deployContext, "test", "eclipse-che", map[string][]byte{"B": []byte("BBBB")}) + done, err = SyncSecretToCluster(ctx, "test", "eclipse-che", map[string][]byte{"B": []byte("BBBB")}) if !done || err != nil { t.Fatalf("Failed to sync secret: %v", err) } actual := &corev1.Secret{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) if err != nil { t.Fatalf("Failed to get secret: %v", err) } diff --git a/pkg/deploy/server/chehost_reconciler_test.go b/pkg/deploy/server/chehost_reconciler_test.go index 00bd0a11f0..741773f189 100644 --- a/pkg/deploy/server/chehost_reconciler_test.go +++ b/pkg/deploy/server/chehost_reconciler_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -17,53 +17,37 @@ import ( "k8s.io/utils/pointer" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" "github.com/eclipse-che/che-operator/pkg/common/constants" - defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/eclipse-che/che-operator/pkg/deploy" routev1 "github.com/openshift/api/route/v1" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" + "testing" + chev2 "github.com/eclipse-che/che-operator/api/v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "testing" ) func TestSyncService(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - corev1.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - ctx := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: defaults.GetCheFlavor(), - }, - Spec: chev2.CheClusterSpec{ - Components: chev2.CheClusterComponents{ - CheServer: chev2.CheServer{ - Debug: pointer.BoolPtr(true), - }, - Metrics: chev2.ServerMetrics{ - Enable: true, - }, + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Spec: chev2.CheClusterSpec{ + Components: chev2.CheClusterComponents{ + CheServer: chev2.CheServer{ + Debug: pointer.Bool(true), + }, + Metrics: chev2.ServerMetrics{ + Enable: true, }, }, }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + }).Build() server := NewCheHostReconciler() done, err := server.syncCheService(ctx) @@ -84,9 +68,7 @@ func TestSyncService(t *testing.T) { } func TestConfiguringLabelsForRoutes(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - cheCluster := &chev2.CheCluster{ + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Namespace: "eclipse-che", Name: "eclipse-che", @@ -97,9 +79,7 @@ func TestConfiguringLabelsForRoutes(t *testing.T) { }, }, Status: chev2.CheClusterStatus{}, - } - - ctx := test.GetDeployContext(cheCluster, []runtime.Object{}) + }).Build() server := NewCheHostReconciler() _, done, err := server.exposeCheEndpoint(ctx) @@ -113,20 +93,11 @@ func TestConfiguringLabelsForRoutes(t *testing.T) { } func TestCheHostReconciler(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - cheCluster := &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - } - ctx := test.GetDeployContext(cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() cheHostReconciler := NewCheHostReconciler() - _, done, err := cheHostReconciler.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, cheHostReconciler.Reconcile) + assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: getComponentName(ctx), Namespace: "eclipse-che"}, &routev1.Route{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: deploy.CheServiceName, Namespace: "eclipse-che"}, &corev1.Service{})) } diff --git a/pkg/deploy/server/rbac_test.go b/pkg/deploy/server/rbac_test.go index 65bddc4640..7bd69311d3 100644 --- a/pkg/deploy/server/rbac_test.go +++ b/pkg/deploy/server/rbac_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -20,9 +20,6 @@ import ( "github.com/eclipse-che/che-operator/pkg/deploy" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - - "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" @@ -31,8 +28,6 @@ import ( ) func TestSyncPermissions(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - type testCase struct { name string checluster *chev2.CheCluster @@ -59,7 +54,7 @@ func TestSyncPermissions(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.checluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.checluster).Build() reconciler := NewCheServerReconciler() @@ -93,8 +88,6 @@ func TestSyncPermissions(t *testing.T) { // TestSyncClusterRoleBinding tests that CRB is deleted when no roles are specified in CR. func TestSyncPermissionsWhenCheClusterUpdated(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - cheCluster := &chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Name: "eclipse-che", @@ -109,7 +102,7 @@ func TestSyncPermissionsWhenCheClusterUpdated(t *testing.T) { }, } - ctx := test.GetDeployContext(cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(cheCluster).Build() reconciler := NewCheServerReconciler() done, err := reconciler.syncPermissions(ctx) diff --git a/pkg/deploy/server/server_configmap_test.go b/pkg/deploy/server/server_configmap_test.go index 3469f38b31..edc7d17d5e 100644 --- a/pkg/deploy/server/server_configmap_test.go +++ b/pkg/deploy/server/server_configmap_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -15,9 +15,10 @@ package server import ( "testing" + "sigs.k8s.io/controller-runtime/pkg/client" + "k8s.io/utils/pointer" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -66,9 +67,7 @@ func TestNewCheConfigMap(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() server := NewCheServerReconciler() actualData, err := server.getCheConfigMapData(ctx) @@ -81,7 +80,7 @@ func TestNewCheConfigMap(t *testing.T) { func TestConfigMap(t *testing.T) { type testCase struct { name string - initObjects []runtime.Object + initObjects []client.Object cheCluster *chev2.CheCluster expectedData map[string]string } @@ -89,7 +88,7 @@ func TestConfigMap(t *testing.T) { testCases := []testCase{ { name: "Test k8s data, no tls secret", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, cheCluster: &chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Namespace: "eclipse-che", @@ -109,7 +108,7 @@ func TestConfigMap(t *testing.T) { }, { name: "Test k8s data, with tls secret", - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "che-tls", @@ -187,7 +186,7 @@ func TestConfigMap(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, testCase.initObjects) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.initObjects...).Build() server := NewCheServerReconciler() actualData, err := server.getCheConfigMapData(ctx) @@ -200,7 +199,7 @@ func TestConfigMap(t *testing.T) { func TestUpdateIntegrationServerEndpoints(t *testing.T) { type testCase struct { name string - initObjects []runtime.Object + initObjects []client.Object cheCluster *chev2.CheCluster expectedData map[string]string } @@ -208,7 +207,7 @@ func TestUpdateIntegrationServerEndpoints(t *testing.T) { testCases := []testCase{ { name: "Test set BitBucket endpoints from secret", - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -240,7 +239,7 @@ func TestUpdateIntegrationServerEndpoints(t *testing.T) { }, { name: "Test update BitBucket endpoints", - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -281,7 +280,7 @@ func TestUpdateIntegrationServerEndpoints(t *testing.T) { }, { name: "Test don't update BitBucket endpoints", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, cheCluster: &chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Namespace: "eclipse-che", @@ -304,7 +303,7 @@ func TestUpdateIntegrationServerEndpoints(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, testCase.initObjects) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.initObjects...).Build() server := NewCheServerReconciler() actualData, err := server.getCheConfigMapData(ctx) @@ -317,7 +316,7 @@ func TestUpdateIntegrationServerEndpoints(t *testing.T) { func TestShouldSetUpCorrectlyPluginRegistryURL(t *testing.T) { type testCase struct { name string - initObjects []runtime.Object + initObjects []client.Object cheCluster *chev2.CheCluster expectedData map[string]string } @@ -372,7 +371,7 @@ func TestShouldSetUpCorrectlyPluginRegistryURL(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.initObjects...).Build() server := NewCheServerReconciler() actualData, err := server.getCheConfigMapData(ctx) @@ -411,7 +410,7 @@ func TestShouldSetUpCorrectlyInternalCheServerURL(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() server := NewCheServerReconciler() actualData, err := server.getCheConfigMapData(ctx) @@ -488,7 +487,7 @@ func TestUpdateUserClusterRoles(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, []runtime.Object{}) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).Build() reconciler := NewCheServerReconciler() cheEnv, err := reconciler.getCheConfigMapData(ctx) diff --git a/pkg/deploy/server/server_deployment_test.go b/pkg/deploy/server/server_deployment_test.go index 06738af5a0..be9b331f84 100644 --- a/pkg/deploy/server/server_deployment_test.go +++ b/pkg/deploy/server/server_deployment_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -14,6 +14,7 @@ package server import ( "k8s.io/apimachinery/pkg/api/resource" + "sigs.k8s.io/controller-runtime/pkg/client" "github.com/eclipse-che/che-operator/pkg/common/constants" defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" @@ -26,7 +27,6 @@ import ( chev2 "github.com/eclipse-che/che-operator/api/v2" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" ) func TestDeployment(t *testing.T) { @@ -37,7 +37,7 @@ func TestDeployment(t *testing.T) { type testCase struct { name string - initObjects []runtime.Object + initObjects []client.Object memoryLimit string memoryRequest string cpuLimit string @@ -48,7 +48,7 @@ func TestDeployment(t *testing.T) { testCases := []testCase{ { name: "Test default limits", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, memoryLimit: constants.DefaultServerMemoryLimit, memoryRequest: constants.DefaultServerMemoryRequest, cpuLimit: "0", // no CPU limit if LimitRange does not exists @@ -61,7 +61,7 @@ func TestDeployment(t *testing.T) { }, { name: "Test custom limits", - initObjects: []runtime.Object{}, + initObjects: []client.Object{}, cpuLimit: "250m", cpuRequest: "150m", memoryLimit: "250Mi", @@ -99,7 +99,7 @@ func TestDeployment(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(testCase.cheCluster, testCase.initObjects) + ctx := test.NewCtxBuilder().WithCheCluster(testCase.cheCluster).WithObjects(testCase.initObjects...).Build() server := NewCheServerReconciler() deployment, err := server.getDeploymentSpec(ctx) @@ -122,7 +122,7 @@ func TestDeployment(t *testing.T) { func TestMountBitBucketServerOAuthEnvVar(t *testing.T) { type testCase struct { name string - initObjects []runtime.Object + initObjects []client.Object expectedConsumerKeyPath string expectedPrivateKeyPath string expectedOAuthEndpoint string @@ -133,7 +133,7 @@ func TestMountBitBucketServerOAuthEnvVar(t *testing.T) { testCases := []testCase{ { name: "Test", - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -177,7 +177,7 @@ func TestMountBitBucketServerOAuthEnvVar(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(nil, testCase.initObjects) + ctx := test.NewCtxBuilder().WithObjects(testCase.initObjects...).Build() server := NewCheServerReconciler() deployment, err := server.getDeploymentSpec(ctx) @@ -208,7 +208,7 @@ func TestMountBitBucketServerOAuthEnvVar(t *testing.T) { func TestMountBitbucketOAuthEnvVar(t *testing.T) { type testCase struct { name string - initObjects []runtime.Object + initObjects []client.Object expectedIdKeyPath string expectedSecretKeyPath string expectedOAuthEndpoint string @@ -219,7 +219,7 @@ func TestMountBitbucketOAuthEnvVar(t *testing.T) { testCases := []testCase{ { name: "Test", - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -262,7 +262,7 @@ func TestMountBitbucketOAuthEnvVar(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(nil, testCase.initObjects) + ctx := test.NewCtxBuilder().WithObjects(testCase.initObjects...).Build() server := NewCheServerReconciler() deployment, err := server.getDeploymentSpec(ctx) @@ -336,7 +336,7 @@ func TestMountGitHubOAuthEnvVar(t *testing.T) { }, } - ctx := test.GetDeployContext(nil, []runtime.Object{secret1, secret2}) + ctx := test.NewCtxBuilder().WithObjects(secret1).WithObjects(secret2).Build() server := NewCheServerReconciler() deployment, err := server.getDeploymentSpec(ctx) @@ -396,7 +396,7 @@ func TestMountGitHubOAuthEnvVar(t *testing.T) { func TestMountAzureDevOpsOAuthEnvVar(t *testing.T) { type testCase struct { name string - initObjects []runtime.Object + initObjects []client.Object expectedIdKeyPath string expectedSecretKeyPath string expectedOAuthEndpoint string @@ -407,7 +407,7 @@ func TestMountAzureDevOpsOAuthEnvVar(t *testing.T) { testCases := []testCase{ { name: "Test", - initObjects: []runtime.Object{ + initObjects: []client.Object{ &corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -450,7 +450,7 @@ func TestMountAzureDevOpsOAuthEnvVar(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - ctx := test.GetDeployContext(nil, testCase.initObjects) + ctx := test.NewCtxBuilder().WithObjects(testCase.initObjects...).Build() server := NewCheServerReconciler() deployment, err := server.getDeploymentSpec(ctx) @@ -523,7 +523,7 @@ func TestMountGitLabOAuthEnvVar(t *testing.T) { }, } - ctx := test.GetDeployContext(nil, []runtime.Object{secret1, secret2}) + ctx := test.NewCtxBuilder().WithObjects(secret1).WithObjects(secret2).Build() server := NewCheServerReconciler() deployment, err := server.getDeploymentSpec(ctx) diff --git a/pkg/deploy/server/server_reconciler_test.go b/pkg/deploy/server/server_reconciler_test.go index f5ca71acc6..7aa4ac4883 100644 --- a/pkg/deploy/server/server_reconciler_test.go +++ b/pkg/deploy/server/server_reconciler_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -15,7 +15,6 @@ package server import ( "context" - "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" "github.com/eclipse-che/che-operator/pkg/common/test" @@ -24,16 +23,13 @@ import ( corev1 "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "testing" ) func TestReconcile(t *testing.T) { - infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) - - cheCluster := &chev2.CheCluster{ + ctx := test.NewCtxBuilder().WithCheCluster(&chev2.CheCluster{ ObjectMeta: metav1.ObjectMeta{ Namespace: "eclipse-che", Name: "eclipse-che", @@ -45,14 +41,10 @@ func TestReconcile(t *testing.T) { }, }, }, - } - - ctx := test.GetDeployContext(cheCluster, []runtime.Object{}) + }).Build() server := NewCheServerReconciler() - _, done, err := server.Reconcile(ctx) - assert.False(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, server.Reconcile) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: CheConfigMapName, Namespace: "eclipse-che"}, &corev1.ConfigMap{})) assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Namespace: "eclipse-che", Name: "che"}, &corev1.ServiceAccount{})) @@ -62,22 +54,20 @@ func TestReconcile(t *testing.T) { assert.Equal(t, 1, len(ctx.CheCluster.Finalizers)) cheDeployment := &appsv1.Deployment{} - err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: defaults.GetCheFlavor(), Namespace: "eclipse-che"}, cheDeployment) + err := ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: defaults.GetCheFlavor(), Namespace: "eclipse-che"}, cheDeployment) assert.Nil(t, err) cheDeployment.Status.Replicas = 1 cheDeployment.Status.AvailableReplicas = 1 - err = ctx.ClusterAPI.Client.Update(context.TODO(), cheDeployment) + err = ctx.ClusterAPI.Client.Status().Update(context.TODO(), cheDeployment) - _, done, err = server.Reconcile(ctx) - assert.True(t, done) - assert.Nil(t, err) + test.EnsureReconcile(t, ctx, server.Reconcile) assert.Equal(t, ctx.CheCluster.Status.ChePhase, chev2.CheClusterPhase(chev2.ClusterPhaseActive)) assert.NotEmpty(t, ctx.CheCluster.Status.CheVersion) assert.NotEmpty(t, ctx.CheCluster.Status.CheURL) - done = server.Finalize(ctx) + done := server.Finalize(ctx) assert.True(t, done) assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: "test-role"}, &rbac.ClusterRoleBinding{})) @@ -89,12 +79,16 @@ func TestUpdateAvailabilityStatus(t *testing.T) { Name: defaults.GetCheFlavor(), Namespace: "eclipse-che", }, + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "apps/v1", + }, Status: appsv1.DeploymentStatus{ AvailableReplicas: 1, Replicas: 1, }, } - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() server := NewCheServerReconciler() done, err := server.syncActiveChePhase(ctx) @@ -111,7 +105,7 @@ func TestUpdateAvailabilityStatus(t *testing.T) { assert.Equal(t, ctx.CheCluster.Status.ChePhase, chev2.CheClusterPhase(chev2.ClusterPhaseActive)) cheDeployment.Status.Replicas = 2 - err = ctx.ClusterAPI.Client.Update(context.TODO(), cheDeployment) + err = ctx.ClusterAPI.Client.Status().Update(context.TODO(), cheDeployment) assert.Nil(t, err) done, err = server.syncActiveChePhase(ctx) diff --git a/pkg/deploy/service_account_test.go b/pkg/deploy/service_account_test.go index 888b9d4e3a..676648cc54 100644 --- a/pkg/deploy/service_account_test.go +++ b/pkg/deploy/service_account_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -13,15 +13,14 @@ package deploy import ( + "testing" + "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/runtime" - - "testing" ) func TestSyncServiceAccountToCluster(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() done, err := SyncServiceAccountToCluster(ctx, "test") assert.NoError(t, err) diff --git a/pkg/deploy/service_test.go b/pkg/deploy/service_test.go index ff764114f4..b6eb28c63d 100644 --- a/pkg/deploy/service_test.go +++ b/pkg/deploy/service_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -14,48 +14,29 @@ package deploy import ( "context" + "testing" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "github.com/eclipse-che/che-operator/pkg/common/test" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "testing" ) func TestServiceToCluster(t *testing.T) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } + ctx := test.NewCtxBuilder().Build() - done, err := SyncServiceToCluster(deployContext, "test", []string{"port"}, []int32{8080}, "test") + done, err := SyncServiceToCluster(ctx, "test", []string{"port"}, []int32{8080}, "test") if !done || err != nil { t.Fatalf("Failed to sync service: %v", err) } // sync another service - done, err = SyncServiceToCluster(deployContext, "test", []string{"port"}, []int32{9090}, "test") + done, err = SyncServiceToCluster(ctx, "test", []string{"port"}, []int32{9090}, "test") if !done || err != nil { t.Fatalf("Failed to sync service: %v", err) } actual := &corev1.Service{} - err = cli.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: "test", Namespace: "eclipse-che"}, actual) if err != nil { t.Fatalf("Failed to get service: %v", err) } diff --git a/pkg/deploy/sync_test.go b/pkg/deploy/sync_test.go index 43aafcce41..31d4c12eb8 100644 --- a/pkg/deploy/sync_test.go +++ b/pkg/deploy/sync_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -15,20 +15,17 @@ package deploy import ( "context" + "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/stretchr/testify/assert" - chev2 "github.com/eclipse-che/che-operator/api/v2" - "github.com/eclipse-che/che-operator/pkg/common/chetypes" + "testing" + "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "testing" ) var ( @@ -62,64 +59,64 @@ var ( ) func TestGet(t *testing.T) { - cli, deployContext := initDeployContext() + ctx := test.NewCtxBuilder().Build() - err := cli.Create(context.TODO(), testObj.DeepCopy()) + err := ctx.ClusterAPI.Client.Create(context.TODO(), testObj.DeepCopy()) if err != nil { t.Fatalf("Failed to create object: %v", err) } actual := &corev1.Secret{} - exists, err := Get(deployContext, testKey, actual) + exists, err := Get(ctx, testKey, actual) if !exists || err != nil { t.Fatalf("Failed to get object: %v", err) } } func TestCreateIgnoreIfExistsShouldReturnTrueIfObjectCreated(t *testing.T) { - cli, deployContext := initDeployContext() + ctx := test.NewCtxBuilder().Build() - done, err := CreateIgnoreIfExists(deployContext, testObj.DeepCopy()) + done, err := CreateIgnoreIfExists(ctx, testObj.DeepCopy()) assert.NoError(t, err) assert.True(t, done) actual := &corev1.Secret{} - err = cli.Get(context.TODO(), testKey, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), testKey, actual) assert.NoError(t, err) assert.NotNil(t, actual) } func TestCreateIgnoreIfExistsShouldReturnTrueIfObjectExist(t *testing.T) { - cli, deployContext := initDeployContext() + ctx := test.NewCtxBuilder().Build() - err := cli.Create(context.TODO(), testObj.DeepCopy()) + err := ctx.ClusterAPI.Client.Create(context.TODO(), testObj.DeepCopy()) assert.NoError(t, err) - done, err := CreateIgnoreIfExists(deployContext, testObj.DeepCopy()) + done, err := CreateIgnoreIfExists(ctx, testObj.DeepCopy()) assert.NoError(t, err) assert.True(t, done) } func TestUpdate(t *testing.T) { - cli, deployContext := initDeployContext() + ctx := test.NewCtxBuilder().Build() - err := cli.Create(context.TODO(), testObj.DeepCopy()) + err := ctx.ClusterAPI.Client.Create(context.TODO(), testObj.DeepCopy()) if err != nil { t.Fatalf("Failed to create object: %v", err) } actual := &corev1.Secret{} - err = cli.Get(context.TODO(), testKey, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), testKey, actual) if err != nil && !errors.IsNotFound(err) { t.Fatalf("Failed to get object: %v", err) } - _, err = doUpdate(cli, deployContext, actual, testObjLabeled.DeepCopy(), cmp.Options{}) + _, err = doUpdate(ctx.ClusterAPI.Client, ctx, actual, testObjLabeled.DeepCopy(), cmp.Options{}) if err != nil { t.Fatalf("Failed to update object: %v", err) } - err = cli.Get(context.TODO(), testKey, actual) + err = ctx.ClusterAPI.Client.Get(context.TODO(), testKey, actual) if err != nil && !errors.IsNotFound(err) { t.Fatalf("Failed to get object: %v", err) } @@ -134,14 +131,14 @@ func TestUpdate(t *testing.T) { } func TestShouldDeleteExistedObject(t *testing.T) { - cli, deployContext := initDeployContext() + ctx := test.NewCtxBuilder().Build() - err := cli.Create(context.TODO(), testObj.DeepCopy()) + err := ctx.ClusterAPI.Client.Create(context.TODO(), testObj.DeepCopy()) if err != nil { t.Fatalf("Failed to create object: %v", err) } - done, err := Delete(deployContext, testKey, testObj.DeepCopy()) + done, err := Delete(ctx, testKey, testObj.DeepCopy()) if err != nil { t.Fatalf("Failed to delete object: %v", err) } @@ -151,7 +148,7 @@ func TestShouldDeleteExistedObject(t *testing.T) { } actualObj := &corev1.Secret{} - err = cli.Get(context.TODO(), testKey, actualObj) + err = ctx.ClusterAPI.Client.Get(context.TODO(), testKey, actualObj) if err != nil && !errors.IsNotFound(err) { t.Fatalf("Failed to get object: %v", err) } @@ -162,9 +159,9 @@ func TestShouldDeleteExistedObject(t *testing.T) { } func TestShouldNotDeleteObject(t *testing.T) { - _, deployContext := initDeployContext() + ctx := test.NewCtxBuilder().Build() - done, err := Delete(deployContext, testKey, testObj.DeepCopy()) + done, err := Delete(ctx, testKey, testObj.DeepCopy()) if err != nil { t.Fatalf("Failed to delete object: %v", err) } @@ -173,23 +170,3 @@ func TestShouldNotDeleteObject(t *testing.T) { t.Fatalf("Object has not been deleted") } } - -func initDeployContext() (client.Client, *chetypes.DeployContext) { - chev2.SchemeBuilder.AddToScheme(scheme.Scheme) - cli := fake.NewFakeClientWithScheme(scheme.Scheme) - deployContext := &chetypes.DeployContext{ - CheCluster: &chev2.CheCluster{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "eclipse-che", - Name: "eclipse-che", - }, - }, - ClusterAPI: chetypes.ClusterAPI{ - Client: cli, - NonCachingClient: cli, - Scheme: scheme.Scheme, - }, - } - - return cli, deployContext -} diff --git a/pkg/deploy/tls/certificates_test.go b/pkg/deploy/tls/certificates_test.go index a569af6540..b7b10032c9 100644 --- a/pkg/deploy/tls/certificates_test.go +++ b/pkg/deploy/tls/certificates_test.go @@ -1,5 +1,5 @@ // -// Copyright (c) 2019-2023 Red Hat, Inc. +// Copyright (c) 2019-2025 Red Hat, Inc. // This program and the accompanying materials are made // available under the terms of the Eclipse Public License 2.0 // which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -28,12 +28,11 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ) func TestSyncOpenShiftCABundleCertificates(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() test.EnsureReconcile(t, ctx, NewCertificatesReconciler().Reconcile) @@ -55,7 +54,7 @@ func TestSyncOpenShiftCABundleCertificates(t *testing.T) { } func TestSyncEmptyOpenShiftCABundleCertificates(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() test.EnsureReconcile(t, ctx, NewCertificatesReconciler().Reconcile) @@ -84,18 +83,15 @@ func TestSyncEmptyOpenShiftCABundleCertificates(t *testing.T) { } func TestSyncOnlyCustomOpenShiftCertificates(t *testing.T) { - ctx := test.GetDeployContext( - nil, - []runtime.Object{ - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "custom-openshift-trusted-certs-cm", - Namespace: "openshift-config", - }, - Data: map[string]string{ - "ca-bundle.crt": "openshift-cert", - }, - }}) + ctx := test.NewCtxBuilder().WithObjects(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "custom-openshift-trusted-certs-cm", + Namespace: "openshift-config", + }, + Data: map[string]string{ + "ca-bundle.crt": "openshift-cert", + }, + }).Build() ctx.CheCluster.Spec.DevEnvironments.TrustedCerts = &chev2.TrustedCerts{DisableWorkspaceCaBundleMount: pointer.Bool(true)} ctx.Proxy.TrustedCAMapName = "custom-openshift-trusted-certs-cm" @@ -119,7 +115,7 @@ func TestSyncOnlyCustomOpenShiftCertificates(t *testing.T) { } func TestSyncKubernetesCABundleCertificates(t *testing.T) { - ctx := test.GetDeployContext(nil, []runtime.Object{}) + ctx := test.NewCtxBuilder().Build() certificates := &CertificatesReconciler{ readKubernetesCaBundle: func() ([]byte, error) { @@ -148,7 +144,7 @@ func TestSyncKubernetesRootCertificates(t *testing.T) { "ca.crt": "root-cert", }, } - ctx := test.GetDeployContext(nil, []runtime.Object{kubeRootCert}) + ctx := test.NewCtxBuilder().WithObjects(kubeRootCert).Build() certificates := NewCertificatesReconciler() @@ -185,7 +181,7 @@ func TestSyncGitTrustedCertificates(t *testing.T) { "ca.crt": "git-cert", }, } - ctx := test.GetDeployContext(cheCluster, []runtime.Object{gitCerts}) + ctx := test.NewCtxBuilder().WithCheCluster(cheCluster).WithObjects(gitCerts).Build() certificates := NewCertificatesReconciler() @@ -210,7 +206,7 @@ func TestSyncSelfSignedCertificates(t *testing.T) { "ca.crt": []byte("self-signed-cert"), }, } - ctx := test.GetDeployContext(nil, []runtime.Object{selfSignedCerts}) + ctx := test.NewCtxBuilder().WithObjects(selfSignedCerts).Build() certificates := NewCertificatesReconciler() @@ -237,7 +233,7 @@ func TestSyncCheCABundleCerts(t *testing.T) { }, Data: map[string]string{"a1": "b1"}, } - ctx := test.GetDeployContext(nil, []runtime.Object{cert1}) + ctx := test.NewCtxBuilder().WithObjects(cert1).Build() certificates := NewCertificatesReconciler() @@ -274,18 +270,15 @@ func TestSyncCheCABundleCerts(t *testing.T) { func TestToggleDisableWorkspaceCaBundleMount(t *testing.T) { // Enable workspace CA bundle mount - ctx := test.GetDeployContext( - nil, - []runtime.Object{ - &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "custom-openshift-trusted-certs-cm", - Namespace: "openshift-config", - }, - Data: map[string]string{ - "ca-bundle.crt": "openshift-cert", - }, - }}) + ctx := test.NewCtxBuilder().WithObjects(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "custom-openshift-trusted-certs-cm", + Namespace: "openshift-config", + }, + Data: map[string]string{ + "ca-bundle.crt": "openshift-cert", + }, + }).Build() ctx.Proxy.TrustedCAMapName = "custom-openshift-trusted-certs-cm" ctx.CheCluster.Spec.DevEnvironments.TrustedCerts = &chev2.TrustedCerts{DisableWorkspaceCaBundleMount: pointer.Bool(false)} diff --git a/vendor/github.com/BurntSushi/toml/.gitignore b/vendor/github.com/BurntSushi/toml/.gitignore deleted file mode 100644 index 0cd3800377..0000000000 --- a/vendor/github.com/BurntSushi/toml/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -TAGS -tags -.*.swp -tomlcheck/tomlcheck -toml.test diff --git a/vendor/github.com/BurntSushi/toml/.travis.yml b/vendor/github.com/BurntSushi/toml/.travis.yml deleted file mode 100644 index 8b8afc4f0e..0000000000 --- a/vendor/github.com/BurntSushi/toml/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -go: - - 1.1 - - 1.2 - - 1.3 - - 1.4 - - 1.5 - - 1.6 - - tip -install: - - go install ./... - - go get github.com/BurntSushi/toml-test -script: - - export PATH="$PATH:$HOME/gopath/bin" - - make test diff --git a/vendor/github.com/BurntSushi/toml/COMPATIBLE b/vendor/github.com/BurntSushi/toml/COMPATIBLE deleted file mode 100644 index 6efcfd0ce5..0000000000 --- a/vendor/github.com/BurntSushi/toml/COMPATIBLE +++ /dev/null @@ -1,3 +0,0 @@ -Compatible with TOML version -[v0.4.0](https://github.com/toml-lang/toml/blob/v0.4.0/versions/en/toml-v0.4.0.md) - diff --git a/vendor/github.com/BurntSushi/toml/COPYING b/vendor/github.com/BurntSushi/toml/COPYING deleted file mode 100644 index 01b5743200..0000000000 --- a/vendor/github.com/BurntSushi/toml/COPYING +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 TOML authors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/BurntSushi/toml/Makefile b/vendor/github.com/BurntSushi/toml/Makefile deleted file mode 100644 index 3600848d33..0000000000 --- a/vendor/github.com/BurntSushi/toml/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -install: - go install ./... - -test: install - go test -v - toml-test toml-test-decoder - toml-test -encoder toml-test-encoder - -fmt: - gofmt -w *.go */*.go - colcheck *.go */*.go - -tags: - find ./ -name '*.go' -print0 | xargs -0 gotags > TAGS - -push: - git push origin master - git push github master - diff --git a/vendor/github.com/BurntSushi/toml/README.md b/vendor/github.com/BurntSushi/toml/README.md deleted file mode 100644 index 7c1b37ecc7..0000000000 --- a/vendor/github.com/BurntSushi/toml/README.md +++ /dev/null @@ -1,218 +0,0 @@ -## TOML parser and encoder for Go with reflection - -TOML stands for Tom's Obvious, Minimal Language. This Go package provides a -reflection interface similar to Go's standard library `json` and `xml` -packages. This package also supports the `encoding.TextUnmarshaler` and -`encoding.TextMarshaler` interfaces so that you can define custom data -representations. (There is an example of this below.) - -Spec: https://github.com/toml-lang/toml - -Compatible with TOML version -[v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md) - -Documentation: https://godoc.org/github.com/BurntSushi/toml - -Installation: - -```bash -go get github.com/BurntSushi/toml -``` - -Try the toml validator: - -```bash -go get github.com/BurntSushi/toml/cmd/tomlv -tomlv some-toml-file.toml -``` - -[![Build Status](https://travis-ci.org/BurntSushi/toml.svg?branch=master)](https://travis-ci.org/BurntSushi/toml) [![GoDoc](https://godoc.org/github.com/BurntSushi/toml?status.svg)](https://godoc.org/github.com/BurntSushi/toml) - -### Testing - -This package passes all tests in -[toml-test](https://github.com/BurntSushi/toml-test) for both the decoder -and the encoder. - -### Examples - -This package works similarly to how the Go standard library handles `XML` -and `JSON`. Namely, data is loaded into Go values via reflection. - -For the simplest example, consider some TOML file as just a list of keys -and values: - -```toml -Age = 25 -Cats = [ "Cauchy", "Plato" ] -Pi = 3.14 -Perfection = [ 6, 28, 496, 8128 ] -DOB = 1987-07-05T05:45:00Z -``` - -Which could be defined in Go as: - -```go -type Config struct { - Age int - Cats []string - Pi float64 - Perfection []int - DOB time.Time // requires `import time` -} -``` - -And then decoded with: - -```go -var conf Config -if _, err := toml.Decode(tomlData, &conf); err != nil { - // handle error -} -``` - -You can also use struct tags if your struct field name doesn't map to a TOML -key value directly: - -```toml -some_key_NAME = "wat" -``` - -```go -type TOML struct { - ObscureKey string `toml:"some_key_NAME"` -} -``` - -### Using the `encoding.TextUnmarshaler` interface - -Here's an example that automatically parses duration strings into -`time.Duration` values: - -```toml -[[song]] -name = "Thunder Road" -duration = "4m49s" - -[[song]] -name = "Stairway to Heaven" -duration = "8m03s" -``` - -Which can be decoded with: - -```go -type song struct { - Name string - Duration duration -} -type songs struct { - Song []song -} -var favorites songs -if _, err := toml.Decode(blob, &favorites); err != nil { - log.Fatal(err) -} - -for _, s := range favorites.Song { - fmt.Printf("%s (%s)\n", s.Name, s.Duration) -} -``` - -And you'll also need a `duration` type that satisfies the -`encoding.TextUnmarshaler` interface: - -```go -type duration struct { - time.Duration -} - -func (d *duration) UnmarshalText(text []byte) error { - var err error - d.Duration, err = time.ParseDuration(string(text)) - return err -} -``` - -### More complex usage - -Here's an example of how to load the example from the official spec page: - -```toml -# This is a TOML document. Boom. - -title = "TOML Example" - -[owner] -name = "Tom Preston-Werner" -organization = "GitHub" -bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." -dob = 1979-05-27T07:32:00Z # First class dates? Why not? - -[database] -server = "192.168.1.1" -ports = [ 8001, 8001, 8002 ] -connection_max = 5000 -enabled = true - -[servers] - - # You can indent as you please. Tabs or spaces. TOML don't care. - [servers.alpha] - ip = "10.0.0.1" - dc = "eqdc10" - - [servers.beta] - ip = "10.0.0.2" - dc = "eqdc10" - -[clients] -data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it - -# Line breaks are OK when inside arrays -hosts = [ - "alpha", - "omega" -] -``` - -And the corresponding Go types are: - -```go -type tomlConfig struct { - Title string - Owner ownerInfo - DB database `toml:"database"` - Servers map[string]server - Clients clients -} - -type ownerInfo struct { - Name string - Org string `toml:"organization"` - Bio string - DOB time.Time -} - -type database struct { - Server string - Ports []int - ConnMax int `toml:"connection_max"` - Enabled bool -} - -type server struct { - IP string - DC string -} - -type clients struct { - Data [][]interface{} - Hosts []string -} -``` - -Note that a case insensitive match will be tried if an exact match can't be -found. - -A working example of the above can be found in `_examples/example.{go,toml}`. diff --git a/vendor/github.com/BurntSushi/toml/decode.go b/vendor/github.com/BurntSushi/toml/decode.go deleted file mode 100644 index b0fd51d5b6..0000000000 --- a/vendor/github.com/BurntSushi/toml/decode.go +++ /dev/null @@ -1,509 +0,0 @@ -package toml - -import ( - "fmt" - "io" - "io/ioutil" - "math" - "reflect" - "strings" - "time" -) - -func e(format string, args ...interface{}) error { - return fmt.Errorf("toml: "+format, args...) -} - -// Unmarshaler is the interface implemented by objects that can unmarshal a -// TOML description of themselves. -type Unmarshaler interface { - UnmarshalTOML(interface{}) error -} - -// Unmarshal decodes the contents of `p` in TOML format into a pointer `v`. -func Unmarshal(p []byte, v interface{}) error { - _, err := Decode(string(p), v) - return err -} - -// Primitive is a TOML value that hasn't been decoded into a Go value. -// When using the various `Decode*` functions, the type `Primitive` may -// be given to any value, and its decoding will be delayed. -// -// A `Primitive` value can be decoded using the `PrimitiveDecode` function. -// -// The underlying representation of a `Primitive` value is subject to change. -// Do not rely on it. -// -// N.B. Primitive values are still parsed, so using them will only avoid -// the overhead of reflection. They can be useful when you don't know the -// exact type of TOML data until run time. -type Primitive struct { - undecoded interface{} - context Key -} - -// DEPRECATED! -// -// Use MetaData.PrimitiveDecode instead. -func PrimitiveDecode(primValue Primitive, v interface{}) error { - md := MetaData{decoded: make(map[string]bool)} - return md.unify(primValue.undecoded, rvalue(v)) -} - -// PrimitiveDecode is just like the other `Decode*` functions, except it -// decodes a TOML value that has already been parsed. Valid primitive values -// can *only* be obtained from values filled by the decoder functions, -// including this method. (i.e., `v` may contain more `Primitive` -// values.) -// -// Meta data for primitive values is included in the meta data returned by -// the `Decode*` functions with one exception: keys returned by the Undecoded -// method will only reflect keys that were decoded. Namely, any keys hidden -// behind a Primitive will be considered undecoded. Executing this method will -// update the undecoded keys in the meta data. (See the example.) -func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error { - md.context = primValue.context - defer func() { md.context = nil }() - return md.unify(primValue.undecoded, rvalue(v)) -} - -// Decode will decode the contents of `data` in TOML format into a pointer -// `v`. -// -// TOML hashes correspond to Go structs or maps. (Dealer's choice. They can be -// used interchangeably.) -// -// TOML arrays of tables correspond to either a slice of structs or a slice -// of maps. -// -// TOML datetimes correspond to Go `time.Time` values. -// -// All other TOML types (float, string, int, bool and array) correspond -// to the obvious Go types. -// -// An exception to the above rules is if a type implements the -// encoding.TextUnmarshaler interface. In this case, any primitive TOML value -// (floats, strings, integers, booleans and datetimes) will be converted to -// a byte string and given to the value's UnmarshalText method. See the -// Unmarshaler example for a demonstration with time duration strings. -// -// Key mapping -// -// TOML keys can map to either keys in a Go map or field names in a Go -// struct. The special `toml` struct tag may be used to map TOML keys to -// struct fields that don't match the key name exactly. (See the example.) -// A case insensitive match to struct names will be tried if an exact match -// can't be found. -// -// The mapping between TOML values and Go values is loose. That is, there -// may exist TOML values that cannot be placed into your representation, and -// there may be parts of your representation that do not correspond to -// TOML values. This loose mapping can be made stricter by using the IsDefined -// and/or Undecoded methods on the MetaData returned. -// -// This decoder will not handle cyclic types. If a cyclic type is passed, -// `Decode` will not terminate. -func Decode(data string, v interface{}) (MetaData, error) { - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr { - return MetaData{}, e("Decode of non-pointer %s", reflect.TypeOf(v)) - } - if rv.IsNil() { - return MetaData{}, e("Decode of nil %s", reflect.TypeOf(v)) - } - p, err := parse(data) - if err != nil { - return MetaData{}, err - } - md := MetaData{ - p.mapping, p.types, p.ordered, - make(map[string]bool, len(p.ordered)), nil, - } - return md, md.unify(p.mapping, indirect(rv)) -} - -// DecodeFile is just like Decode, except it will automatically read the -// contents of the file at `fpath` and decode it for you. -func DecodeFile(fpath string, v interface{}) (MetaData, error) { - bs, err := ioutil.ReadFile(fpath) - if err != nil { - return MetaData{}, err - } - return Decode(string(bs), v) -} - -// DecodeReader is just like Decode, except it will consume all bytes -// from the reader and decode it for you. -func DecodeReader(r io.Reader, v interface{}) (MetaData, error) { - bs, err := ioutil.ReadAll(r) - if err != nil { - return MetaData{}, err - } - return Decode(string(bs), v) -} - -// unify performs a sort of type unification based on the structure of `rv`, -// which is the client representation. -// -// Any type mismatch produces an error. Finding a type that we don't know -// how to handle produces an unsupported type error. -func (md *MetaData) unify(data interface{}, rv reflect.Value) error { - - // Special case. Look for a `Primitive` value. - if rv.Type() == reflect.TypeOf((*Primitive)(nil)).Elem() { - // Save the undecoded data and the key context into the primitive - // value. - context := make(Key, len(md.context)) - copy(context, md.context) - rv.Set(reflect.ValueOf(Primitive{ - undecoded: data, - context: context, - })) - return nil - } - - // Special case. Unmarshaler Interface support. - if rv.CanAddr() { - if v, ok := rv.Addr().Interface().(Unmarshaler); ok { - return v.UnmarshalTOML(data) - } - } - - // Special case. Handle time.Time values specifically. - // TODO: Remove this code when we decide to drop support for Go 1.1. - // This isn't necessary in Go 1.2 because time.Time satisfies the encoding - // interfaces. - if rv.Type().AssignableTo(rvalue(time.Time{}).Type()) { - return md.unifyDatetime(data, rv) - } - - // Special case. Look for a value satisfying the TextUnmarshaler interface. - if v, ok := rv.Interface().(TextUnmarshaler); ok { - return md.unifyText(data, v) - } - // BUG(burntsushi) - // The behavior here is incorrect whenever a Go type satisfies the - // encoding.TextUnmarshaler interface but also corresponds to a TOML - // hash or array. In particular, the unmarshaler should only be applied - // to primitive TOML values. But at this point, it will be applied to - // all kinds of values and produce an incorrect error whenever those values - // are hashes or arrays (including arrays of tables). - - k := rv.Kind() - - // laziness - if k >= reflect.Int && k <= reflect.Uint64 { - return md.unifyInt(data, rv) - } - switch k { - case reflect.Ptr: - elem := reflect.New(rv.Type().Elem()) - err := md.unify(data, reflect.Indirect(elem)) - if err != nil { - return err - } - rv.Set(elem) - return nil - case reflect.Struct: - return md.unifyStruct(data, rv) - case reflect.Map: - return md.unifyMap(data, rv) - case reflect.Array: - return md.unifyArray(data, rv) - case reflect.Slice: - return md.unifySlice(data, rv) - case reflect.String: - return md.unifyString(data, rv) - case reflect.Bool: - return md.unifyBool(data, rv) - case reflect.Interface: - // we only support empty interfaces. - if rv.NumMethod() > 0 { - return e("unsupported type %s", rv.Type()) - } - return md.unifyAnything(data, rv) - case reflect.Float32: - fallthrough - case reflect.Float64: - return md.unifyFloat64(data, rv) - } - return e("unsupported type %s", rv.Kind()) -} - -func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error { - tmap, ok := mapping.(map[string]interface{}) - if !ok { - if mapping == nil { - return nil - } - return e("type mismatch for %s: expected table but found %T", - rv.Type().String(), mapping) - } - - for key, datum := range tmap { - var f *field - fields := cachedTypeFields(rv.Type()) - for i := range fields { - ff := &fields[i] - if ff.name == key { - f = ff - break - } - if f == nil && strings.EqualFold(ff.name, key) { - f = ff - } - } - if f != nil { - subv := rv - for _, i := range f.index { - subv = indirect(subv.Field(i)) - } - if isUnifiable(subv) { - md.decoded[md.context.add(key).String()] = true - md.context = append(md.context, key) - if err := md.unify(datum, subv); err != nil { - return err - } - md.context = md.context[0 : len(md.context)-1] - } else if f.name != "" { - // Bad user! No soup for you! - return e("cannot write unexported field %s.%s", - rv.Type().String(), f.name) - } - } - } - return nil -} - -func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error { - tmap, ok := mapping.(map[string]interface{}) - if !ok { - if tmap == nil { - return nil - } - return badtype("map", mapping) - } - if rv.IsNil() { - rv.Set(reflect.MakeMap(rv.Type())) - } - for k, v := range tmap { - md.decoded[md.context.add(k).String()] = true - md.context = append(md.context, k) - - rvkey := indirect(reflect.New(rv.Type().Key())) - rvval := reflect.Indirect(reflect.New(rv.Type().Elem())) - if err := md.unify(v, rvval); err != nil { - return err - } - md.context = md.context[0 : len(md.context)-1] - - rvkey.SetString(k) - rv.SetMapIndex(rvkey, rvval) - } - return nil -} - -func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error { - datav := reflect.ValueOf(data) - if datav.Kind() != reflect.Slice { - if !datav.IsValid() { - return nil - } - return badtype("slice", data) - } - sliceLen := datav.Len() - if sliceLen != rv.Len() { - return e("expected array length %d; got TOML array of length %d", - rv.Len(), sliceLen) - } - return md.unifySliceArray(datav, rv) -} - -func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error { - datav := reflect.ValueOf(data) - if datav.Kind() != reflect.Slice { - if !datav.IsValid() { - return nil - } - return badtype("slice", data) - } - n := datav.Len() - if rv.IsNil() || rv.Cap() < n { - rv.Set(reflect.MakeSlice(rv.Type(), n, n)) - } - rv.SetLen(n) - return md.unifySliceArray(datav, rv) -} - -func (md *MetaData) unifySliceArray(data, rv reflect.Value) error { - sliceLen := data.Len() - for i := 0; i < sliceLen; i++ { - v := data.Index(i).Interface() - sliceval := indirect(rv.Index(i)) - if err := md.unify(v, sliceval); err != nil { - return err - } - } - return nil -} - -func (md *MetaData) unifyDatetime(data interface{}, rv reflect.Value) error { - if _, ok := data.(time.Time); ok { - rv.Set(reflect.ValueOf(data)) - return nil - } - return badtype("time.Time", data) -} - -func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error { - if s, ok := data.(string); ok { - rv.SetString(s) - return nil - } - return badtype("string", data) -} - -func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error { - if num, ok := data.(float64); ok { - switch rv.Kind() { - case reflect.Float32: - fallthrough - case reflect.Float64: - rv.SetFloat(num) - default: - panic("bug") - } - return nil - } - return badtype("float", data) -} - -func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error { - if num, ok := data.(int64); ok { - if rv.Kind() >= reflect.Int && rv.Kind() <= reflect.Int64 { - switch rv.Kind() { - case reflect.Int, reflect.Int64: - // No bounds checking necessary. - case reflect.Int8: - if num < math.MinInt8 || num > math.MaxInt8 { - return e("value %d is out of range for int8", num) - } - case reflect.Int16: - if num < math.MinInt16 || num > math.MaxInt16 { - return e("value %d is out of range for int16", num) - } - case reflect.Int32: - if num < math.MinInt32 || num > math.MaxInt32 { - return e("value %d is out of range for int32", num) - } - } - rv.SetInt(num) - } else if rv.Kind() >= reflect.Uint && rv.Kind() <= reflect.Uint64 { - unum := uint64(num) - switch rv.Kind() { - case reflect.Uint, reflect.Uint64: - // No bounds checking necessary. - case reflect.Uint8: - if num < 0 || unum > math.MaxUint8 { - return e("value %d is out of range for uint8", num) - } - case reflect.Uint16: - if num < 0 || unum > math.MaxUint16 { - return e("value %d is out of range for uint16", num) - } - case reflect.Uint32: - if num < 0 || unum > math.MaxUint32 { - return e("value %d is out of range for uint32", num) - } - } - rv.SetUint(unum) - } else { - panic("unreachable") - } - return nil - } - return badtype("integer", data) -} - -func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error { - if b, ok := data.(bool); ok { - rv.SetBool(b) - return nil - } - return badtype("boolean", data) -} - -func (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error { - rv.Set(reflect.ValueOf(data)) - return nil -} - -func (md *MetaData) unifyText(data interface{}, v TextUnmarshaler) error { - var s string - switch sdata := data.(type) { - case TextMarshaler: - text, err := sdata.MarshalText() - if err != nil { - return err - } - s = string(text) - case fmt.Stringer: - s = sdata.String() - case string: - s = sdata - case bool: - s = fmt.Sprintf("%v", sdata) - case int64: - s = fmt.Sprintf("%d", sdata) - case float64: - s = fmt.Sprintf("%f", sdata) - default: - return badtype("primitive (string-like)", data) - } - if err := v.UnmarshalText([]byte(s)); err != nil { - return err - } - return nil -} - -// rvalue returns a reflect.Value of `v`. All pointers are resolved. -func rvalue(v interface{}) reflect.Value { - return indirect(reflect.ValueOf(v)) -} - -// indirect returns the value pointed to by a pointer. -// Pointers are followed until the value is not a pointer. -// New values are allocated for each nil pointer. -// -// An exception to this rule is if the value satisfies an interface of -// interest to us (like encoding.TextUnmarshaler). -func indirect(v reflect.Value) reflect.Value { - if v.Kind() != reflect.Ptr { - if v.CanSet() { - pv := v.Addr() - if _, ok := pv.Interface().(TextUnmarshaler); ok { - return pv - } - } - return v - } - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - return indirect(reflect.Indirect(v)) -} - -func isUnifiable(rv reflect.Value) bool { - if rv.CanSet() { - return true - } - if _, ok := rv.Interface().(TextUnmarshaler); ok { - return true - } - return false -} - -func badtype(expected string, data interface{}) error { - return e("cannot load TOML value of type %T into a Go %s", data, expected) -} diff --git a/vendor/github.com/BurntSushi/toml/decode_meta.go b/vendor/github.com/BurntSushi/toml/decode_meta.go deleted file mode 100644 index b9914a6798..0000000000 --- a/vendor/github.com/BurntSushi/toml/decode_meta.go +++ /dev/null @@ -1,121 +0,0 @@ -package toml - -import "strings" - -// MetaData allows access to meta information about TOML data that may not -// be inferrable via reflection. In particular, whether a key has been defined -// and the TOML type of a key. -type MetaData struct { - mapping map[string]interface{} - types map[string]tomlType - keys []Key - decoded map[string]bool - context Key // Used only during decoding. -} - -// IsDefined returns true if the key given exists in the TOML data. The key -// should be specified hierarchially. e.g., -// -// // access the TOML key 'a.b.c' -// IsDefined("a", "b", "c") -// -// IsDefined will return false if an empty key given. Keys are case sensitive. -func (md *MetaData) IsDefined(key ...string) bool { - if len(key) == 0 { - return false - } - - var hash map[string]interface{} - var ok bool - var hashOrVal interface{} = md.mapping - for _, k := range key { - if hash, ok = hashOrVal.(map[string]interface{}); !ok { - return false - } - if hashOrVal, ok = hash[k]; !ok { - return false - } - } - return true -} - -// Type returns a string representation of the type of the key specified. -// -// Type will return the empty string if given an empty key or a key that -// does not exist. Keys are case sensitive. -func (md *MetaData) Type(key ...string) string { - fullkey := strings.Join(key, ".") - if typ, ok := md.types[fullkey]; ok { - return typ.typeString() - } - return "" -} - -// Key is the type of any TOML key, including key groups. Use (MetaData).Keys -// to get values of this type. -type Key []string - -func (k Key) String() string { - return strings.Join(k, ".") -} - -func (k Key) maybeQuotedAll() string { - var ss []string - for i := range k { - ss = append(ss, k.maybeQuoted(i)) - } - return strings.Join(ss, ".") -} - -func (k Key) maybeQuoted(i int) string { - quote := false - for _, c := range k[i] { - if !isBareKeyChar(c) { - quote = true - break - } - } - if quote { - return "\"" + strings.Replace(k[i], "\"", "\\\"", -1) + "\"" - } - return k[i] -} - -func (k Key) add(piece string) Key { - newKey := make(Key, len(k)+1) - copy(newKey, k) - newKey[len(k)] = piece - return newKey -} - -// Keys returns a slice of every key in the TOML data, including key groups. -// Each key is itself a slice, where the first element is the top of the -// hierarchy and the last is the most specific. -// -// The list will have the same order as the keys appeared in the TOML data. -// -// All keys returned are non-empty. -func (md *MetaData) Keys() []Key { - return md.keys -} - -// Undecoded returns all keys that have not been decoded in the order in which -// they appear in the original TOML document. -// -// This includes keys that haven't been decoded because of a Primitive value. -// Once the Primitive value is decoded, the keys will be considered decoded. -// -// Also note that decoding into an empty interface will result in no decoding, -// and so no keys will be considered decoded. -// -// In this sense, the Undecoded keys correspond to keys in the TOML document -// that do not have a concrete type in your representation. -func (md *MetaData) Undecoded() []Key { - undecoded := make([]Key, 0, len(md.keys)) - for _, key := range md.keys { - if !md.decoded[key.String()] { - undecoded = append(undecoded, key) - } - } - return undecoded -} diff --git a/vendor/github.com/BurntSushi/toml/doc.go b/vendor/github.com/BurntSushi/toml/doc.go deleted file mode 100644 index b371f396ed..0000000000 --- a/vendor/github.com/BurntSushi/toml/doc.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Package toml provides facilities for decoding and encoding TOML configuration -files via reflection. There is also support for delaying decoding with -the Primitive type, and querying the set of keys in a TOML document with the -MetaData type. - -The specification implemented: https://github.com/toml-lang/toml - -The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify -whether a file is a valid TOML document. It can also be used to print the -type of each key in a TOML document. - -Testing - -There are two important types of tests used for this package. The first is -contained inside '*_test.go' files and uses the standard Go unit testing -framework. These tests are primarily devoted to holistically testing the -decoder and encoder. - -The second type of testing is used to verify the implementation's adherence -to the TOML specification. These tests have been factored into their own -project: https://github.com/BurntSushi/toml-test - -The reason the tests are in a separate project is so that they can be used by -any implementation of TOML. Namely, it is language agnostic. -*/ -package toml diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go deleted file mode 100644 index d905c21a24..0000000000 --- a/vendor/github.com/BurntSushi/toml/encode.go +++ /dev/null @@ -1,568 +0,0 @@ -package toml - -import ( - "bufio" - "errors" - "fmt" - "io" - "reflect" - "sort" - "strconv" - "strings" - "time" -) - -type tomlEncodeError struct{ error } - -var ( - errArrayMixedElementTypes = errors.New( - "toml: cannot encode array with mixed element types") - errArrayNilElement = errors.New( - "toml: cannot encode array with nil element") - errNonString = errors.New( - "toml: cannot encode a map with non-string key type") - errAnonNonStruct = errors.New( - "toml: cannot encode an anonymous field that is not a struct") - errArrayNoTable = errors.New( - "toml: TOML array element cannot contain a table") - errNoKey = errors.New( - "toml: top-level values must be Go maps or structs") - errAnything = errors.New("") // used in testing -) - -var quotedReplacer = strings.NewReplacer( - "\t", "\\t", - "\n", "\\n", - "\r", "\\r", - "\"", "\\\"", - "\\", "\\\\", -) - -// Encoder controls the encoding of Go values to a TOML document to some -// io.Writer. -// -// The indentation level can be controlled with the Indent field. -type Encoder struct { - // A single indentation level. By default it is two spaces. - Indent string - - // hasWritten is whether we have written any output to w yet. - hasWritten bool - w *bufio.Writer -} - -// NewEncoder returns a TOML encoder that encodes Go values to the io.Writer -// given. By default, a single indentation level is 2 spaces. -func NewEncoder(w io.Writer) *Encoder { - return &Encoder{ - w: bufio.NewWriter(w), - Indent: " ", - } -} - -// Encode writes a TOML representation of the Go value to the underlying -// io.Writer. If the value given cannot be encoded to a valid TOML document, -// then an error is returned. -// -// The mapping between Go values and TOML values should be precisely the same -// as for the Decode* functions. Similarly, the TextMarshaler interface is -// supported by encoding the resulting bytes as strings. (If you want to write -// arbitrary binary data then you will need to use something like base64 since -// TOML does not have any binary types.) -// -// When encoding TOML hashes (i.e., Go maps or structs), keys without any -// sub-hashes are encoded first. -// -// If a Go map is encoded, then its keys are sorted alphabetically for -// deterministic output. More control over this behavior may be provided if -// there is demand for it. -// -// Encoding Go values without a corresponding TOML representation---like map -// types with non-string keys---will cause an error to be returned. Similarly -// for mixed arrays/slices, arrays/slices with nil elements, embedded -// non-struct types and nested slices containing maps or structs. -// (e.g., [][]map[string]string is not allowed but []map[string]string is OK -// and so is []map[string][]string.) -func (enc *Encoder) Encode(v interface{}) error { - rv := eindirect(reflect.ValueOf(v)) - if err := enc.safeEncode(Key([]string{}), rv); err != nil { - return err - } - return enc.w.Flush() -} - -func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) { - defer func() { - if r := recover(); r != nil { - if terr, ok := r.(tomlEncodeError); ok { - err = terr.error - return - } - panic(r) - } - }() - enc.encode(key, rv) - return nil -} - -func (enc *Encoder) encode(key Key, rv reflect.Value) { - // Special case. Time needs to be in ISO8601 format. - // Special case. If we can marshal the type to text, then we used that. - // Basically, this prevents the encoder for handling these types as - // generic structs (or whatever the underlying type of a TextMarshaler is). - switch rv.Interface().(type) { - case time.Time, TextMarshaler: - enc.keyEqElement(key, rv) - return - } - - k := rv.Kind() - switch k { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, - reflect.Uint64, - reflect.Float32, reflect.Float64, reflect.String, reflect.Bool: - enc.keyEqElement(key, rv) - case reflect.Array, reflect.Slice: - if typeEqual(tomlArrayHash, tomlTypeOfGo(rv)) { - enc.eArrayOfTables(key, rv) - } else { - enc.keyEqElement(key, rv) - } - case reflect.Interface: - if rv.IsNil() { - return - } - enc.encode(key, rv.Elem()) - case reflect.Map: - if rv.IsNil() { - return - } - enc.eTable(key, rv) - case reflect.Ptr: - if rv.IsNil() { - return - } - enc.encode(key, rv.Elem()) - case reflect.Struct: - enc.eTable(key, rv) - default: - panic(e("unsupported type for key '%s': %s", key, k)) - } -} - -// eElement encodes any value that can be an array element (primitives and -// arrays). -func (enc *Encoder) eElement(rv reflect.Value) { - switch v := rv.Interface().(type) { - case time.Time: - // Special case time.Time as a primitive. Has to come before - // TextMarshaler below because time.Time implements - // encoding.TextMarshaler, but we need to always use UTC. - enc.wf(v.UTC().Format("2006-01-02T15:04:05Z")) - return - case TextMarshaler: - // Special case. Use text marshaler if it's available for this value. - if s, err := v.MarshalText(); err != nil { - encPanic(err) - } else { - enc.writeQuoted(string(s)) - } - return - } - switch rv.Kind() { - case reflect.Bool: - enc.wf(strconv.FormatBool(rv.Bool())) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64: - enc.wf(strconv.FormatInt(rv.Int(), 10)) - case reflect.Uint, reflect.Uint8, reflect.Uint16, - reflect.Uint32, reflect.Uint64: - enc.wf(strconv.FormatUint(rv.Uint(), 10)) - case reflect.Float32: - enc.wf(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 32))) - case reflect.Float64: - enc.wf(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 64))) - case reflect.Array, reflect.Slice: - enc.eArrayOrSliceElement(rv) - case reflect.Interface: - enc.eElement(rv.Elem()) - case reflect.String: - enc.writeQuoted(rv.String()) - default: - panic(e("unexpected primitive type: %s", rv.Kind())) - } -} - -// By the TOML spec, all floats must have a decimal with at least one -// number on either side. -func floatAddDecimal(fstr string) string { - if !strings.Contains(fstr, ".") { - return fstr + ".0" - } - return fstr -} - -func (enc *Encoder) writeQuoted(s string) { - enc.wf("\"%s\"", quotedReplacer.Replace(s)) -} - -func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) { - length := rv.Len() - enc.wf("[") - for i := 0; i < length; i++ { - elem := rv.Index(i) - enc.eElement(elem) - if i != length-1 { - enc.wf(", ") - } - } - enc.wf("]") -} - -func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) { - if len(key) == 0 { - encPanic(errNoKey) - } - for i := 0; i < rv.Len(); i++ { - trv := rv.Index(i) - if isNil(trv) { - continue - } - panicIfInvalidKey(key) - enc.newline() - enc.wf("%s[[%s]]", enc.indentStr(key), key.maybeQuotedAll()) - enc.newline() - enc.eMapOrStruct(key, trv) - } -} - -func (enc *Encoder) eTable(key Key, rv reflect.Value) { - panicIfInvalidKey(key) - if len(key) == 1 { - // Output an extra newline between top-level tables. - // (The newline isn't written if nothing else has been written though.) - enc.newline() - } - if len(key) > 0 { - enc.wf("%s[%s]", enc.indentStr(key), key.maybeQuotedAll()) - enc.newline() - } - enc.eMapOrStruct(key, rv) -} - -func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value) { - switch rv := eindirect(rv); rv.Kind() { - case reflect.Map: - enc.eMap(key, rv) - case reflect.Struct: - enc.eStruct(key, rv) - default: - panic("eTable: unhandled reflect.Value Kind: " + rv.Kind().String()) - } -} - -func (enc *Encoder) eMap(key Key, rv reflect.Value) { - rt := rv.Type() - if rt.Key().Kind() != reflect.String { - encPanic(errNonString) - } - - // Sort keys so that we have deterministic output. And write keys directly - // underneath this key first, before writing sub-structs or sub-maps. - var mapKeysDirect, mapKeysSub []string - for _, mapKey := range rv.MapKeys() { - k := mapKey.String() - if typeIsHash(tomlTypeOfGo(rv.MapIndex(mapKey))) { - mapKeysSub = append(mapKeysSub, k) - } else { - mapKeysDirect = append(mapKeysDirect, k) - } - } - - var writeMapKeys = func(mapKeys []string) { - sort.Strings(mapKeys) - for _, mapKey := range mapKeys { - mrv := rv.MapIndex(reflect.ValueOf(mapKey)) - if isNil(mrv) { - // Don't write anything for nil fields. - continue - } - enc.encode(key.add(mapKey), mrv) - } - } - writeMapKeys(mapKeysDirect) - writeMapKeys(mapKeysSub) -} - -func (enc *Encoder) eStruct(key Key, rv reflect.Value) { - // Write keys for fields directly under this key first, because if we write - // a field that creates a new table, then all keys under it will be in that - // table (not the one we're writing here). - rt := rv.Type() - var fieldsDirect, fieldsSub [][]int - var addFields func(rt reflect.Type, rv reflect.Value, start []int) - addFields = func(rt reflect.Type, rv reflect.Value, start []int) { - for i := 0; i < rt.NumField(); i++ { - f := rt.Field(i) - // skip unexported fields - if f.PkgPath != "" && !f.Anonymous { - continue - } - frv := rv.Field(i) - if f.Anonymous { - t := f.Type - switch t.Kind() { - case reflect.Struct: - // Treat anonymous struct fields with - // tag names as though they are not - // anonymous, like encoding/json does. - if getOptions(f.Tag).name == "" { - addFields(t, frv, f.Index) - continue - } - case reflect.Ptr: - if t.Elem().Kind() == reflect.Struct && - getOptions(f.Tag).name == "" { - if !frv.IsNil() { - addFields(t.Elem(), frv.Elem(), f.Index) - } - continue - } - // Fall through to the normal field encoding logic below - // for non-struct anonymous fields. - } - } - - if typeIsHash(tomlTypeOfGo(frv)) { - fieldsSub = append(fieldsSub, append(start, f.Index...)) - } else { - fieldsDirect = append(fieldsDirect, append(start, f.Index...)) - } - } - } - addFields(rt, rv, nil) - - var writeFields = func(fields [][]int) { - for _, fieldIndex := range fields { - sft := rt.FieldByIndex(fieldIndex) - sf := rv.FieldByIndex(fieldIndex) - if isNil(sf) { - // Don't write anything for nil fields. - continue - } - - opts := getOptions(sft.Tag) - if opts.skip { - continue - } - keyName := sft.Name - if opts.name != "" { - keyName = opts.name - } - if opts.omitempty && isEmpty(sf) { - continue - } - if opts.omitzero && isZero(sf) { - continue - } - - enc.encode(key.add(keyName), sf) - } - } - writeFields(fieldsDirect) - writeFields(fieldsSub) -} - -// tomlTypeName returns the TOML type name of the Go value's type. It is -// used to determine whether the types of array elements are mixed (which is -// forbidden). If the Go value is nil, then it is illegal for it to be an array -// element, and valueIsNil is returned as true. - -// Returns the TOML type of a Go value. The type may be `nil`, which means -// no concrete TOML type could be found. -func tomlTypeOfGo(rv reflect.Value) tomlType { - if isNil(rv) || !rv.IsValid() { - return nil - } - switch rv.Kind() { - case reflect.Bool: - return tomlBool - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, - reflect.Uint64: - return tomlInteger - case reflect.Float32, reflect.Float64: - return tomlFloat - case reflect.Array, reflect.Slice: - if typeEqual(tomlHash, tomlArrayType(rv)) { - return tomlArrayHash - } - return tomlArray - case reflect.Ptr, reflect.Interface: - return tomlTypeOfGo(rv.Elem()) - case reflect.String: - return tomlString - case reflect.Map: - return tomlHash - case reflect.Struct: - switch rv.Interface().(type) { - case time.Time: - return tomlDatetime - case TextMarshaler: - return tomlString - default: - return tomlHash - } - default: - panic("unexpected reflect.Kind: " + rv.Kind().String()) - } -} - -// tomlArrayType returns the element type of a TOML array. The type returned -// may be nil if it cannot be determined (e.g., a nil slice or a zero length -// slize). This function may also panic if it finds a type that cannot be -// expressed in TOML (such as nil elements, heterogeneous arrays or directly -// nested arrays of tables). -func tomlArrayType(rv reflect.Value) tomlType { - if isNil(rv) || !rv.IsValid() || rv.Len() == 0 { - return nil - } - firstType := tomlTypeOfGo(rv.Index(0)) - if firstType == nil { - encPanic(errArrayNilElement) - } - - rvlen := rv.Len() - for i := 1; i < rvlen; i++ { - elem := rv.Index(i) - switch elemType := tomlTypeOfGo(elem); { - case elemType == nil: - encPanic(errArrayNilElement) - case !typeEqual(firstType, elemType): - encPanic(errArrayMixedElementTypes) - } - } - // If we have a nested array, then we must make sure that the nested - // array contains ONLY primitives. - // This checks arbitrarily nested arrays. - if typeEqual(firstType, tomlArray) || typeEqual(firstType, tomlArrayHash) { - nest := tomlArrayType(eindirect(rv.Index(0))) - if typeEqual(nest, tomlHash) || typeEqual(nest, tomlArrayHash) { - encPanic(errArrayNoTable) - } - } - return firstType -} - -type tagOptions struct { - skip bool // "-" - name string - omitempty bool - omitzero bool -} - -func getOptions(tag reflect.StructTag) tagOptions { - t := tag.Get("toml") - if t == "-" { - return tagOptions{skip: true} - } - var opts tagOptions - parts := strings.Split(t, ",") - opts.name = parts[0] - for _, s := range parts[1:] { - switch s { - case "omitempty": - opts.omitempty = true - case "omitzero": - opts.omitzero = true - } - } - return opts -} - -func isZero(rv reflect.Value) bool { - switch rv.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return rv.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return rv.Uint() == 0 - case reflect.Float32, reflect.Float64: - return rv.Float() == 0.0 - } - return false -} - -func isEmpty(rv reflect.Value) bool { - switch rv.Kind() { - case reflect.Array, reflect.Slice, reflect.Map, reflect.String: - return rv.Len() == 0 - case reflect.Bool: - return !rv.Bool() - } - return false -} - -func (enc *Encoder) newline() { - if enc.hasWritten { - enc.wf("\n") - } -} - -func (enc *Encoder) keyEqElement(key Key, val reflect.Value) { - if len(key) == 0 { - encPanic(errNoKey) - } - panicIfInvalidKey(key) - enc.wf("%s%s = ", enc.indentStr(key), key.maybeQuoted(len(key)-1)) - enc.eElement(val) - enc.newline() -} - -func (enc *Encoder) wf(format string, v ...interface{}) { - if _, err := fmt.Fprintf(enc.w, format, v...); err != nil { - encPanic(err) - } - enc.hasWritten = true -} - -func (enc *Encoder) indentStr(key Key) string { - return strings.Repeat(enc.Indent, len(key)-1) -} - -func encPanic(err error) { - panic(tomlEncodeError{err}) -} - -func eindirect(v reflect.Value) reflect.Value { - switch v.Kind() { - case reflect.Ptr, reflect.Interface: - return eindirect(v.Elem()) - default: - return v - } -} - -func isNil(rv reflect.Value) bool { - switch rv.Kind() { - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return rv.IsNil() - default: - return false - } -} - -func panicIfInvalidKey(key Key) { - for _, k := range key { - if len(k) == 0 { - encPanic(e("Key '%s' is not a valid table name. Key names "+ - "cannot be empty.", key.maybeQuotedAll())) - } - } -} - -func isValidKeyName(s string) bool { - return len(s) != 0 -} diff --git a/vendor/github.com/BurntSushi/toml/encoding_types.go b/vendor/github.com/BurntSushi/toml/encoding_types.go deleted file mode 100644 index d36e1dd600..0000000000 --- a/vendor/github.com/BurntSushi/toml/encoding_types.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build go1.2 - -package toml - -// In order to support Go 1.1, we define our own TextMarshaler and -// TextUnmarshaler types. For Go 1.2+, we just alias them with the -// standard library interfaces. - -import ( - "encoding" -) - -// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here -// so that Go 1.1 can be supported. -type TextMarshaler encoding.TextMarshaler - -// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined -// here so that Go 1.1 can be supported. -type TextUnmarshaler encoding.TextUnmarshaler diff --git a/vendor/github.com/BurntSushi/toml/encoding_types_1.1.go b/vendor/github.com/BurntSushi/toml/encoding_types_1.1.go deleted file mode 100644 index e8d503d046..0000000000 --- a/vendor/github.com/BurntSushi/toml/encoding_types_1.1.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build !go1.2 - -package toml - -// These interfaces were introduced in Go 1.2, so we add them manually when -// compiling for Go 1.1. - -// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here -// so that Go 1.1 can be supported. -type TextMarshaler interface { - MarshalText() (text []byte, err error) -} - -// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined -// here so that Go 1.1 can be supported. -type TextUnmarshaler interface { - UnmarshalText(text []byte) error -} diff --git a/vendor/github.com/BurntSushi/toml/lex.go b/vendor/github.com/BurntSushi/toml/lex.go deleted file mode 100644 index e0a742a887..0000000000 --- a/vendor/github.com/BurntSushi/toml/lex.go +++ /dev/null @@ -1,953 +0,0 @@ -package toml - -import ( - "fmt" - "strings" - "unicode" - "unicode/utf8" -) - -type itemType int - -const ( - itemError itemType = iota - itemNIL // used in the parser to indicate no type - itemEOF - itemText - itemString - itemRawString - itemMultilineString - itemRawMultilineString - itemBool - itemInteger - itemFloat - itemDatetime - itemArray // the start of an array - itemArrayEnd - itemTableStart - itemTableEnd - itemArrayTableStart - itemArrayTableEnd - itemKeyStart - itemCommentStart - itemInlineTableStart - itemInlineTableEnd -) - -const ( - eof = 0 - comma = ',' - tableStart = '[' - tableEnd = ']' - arrayTableStart = '[' - arrayTableEnd = ']' - tableSep = '.' - keySep = '=' - arrayStart = '[' - arrayEnd = ']' - commentStart = '#' - stringStart = '"' - stringEnd = '"' - rawStringStart = '\'' - rawStringEnd = '\'' - inlineTableStart = '{' - inlineTableEnd = '}' -) - -type stateFn func(lx *lexer) stateFn - -type lexer struct { - input string - start int - pos int - line int - state stateFn - items chan item - - // Allow for backing up up to three runes. - // This is necessary because TOML contains 3-rune tokens (""" and '''). - prevWidths [3]int - nprev int // how many of prevWidths are in use - // If we emit an eof, we can still back up, but it is not OK to call - // next again. - atEOF bool - - // A stack of state functions used to maintain context. - // The idea is to reuse parts of the state machine in various places. - // For example, values can appear at the top level or within arbitrarily - // nested arrays. The last state on the stack is used after a value has - // been lexed. Similarly for comments. - stack []stateFn -} - -type item struct { - typ itemType - val string - line int -} - -func (lx *lexer) nextItem() item { - for { - select { - case item := <-lx.items: - return item - default: - lx.state = lx.state(lx) - } - } -} - -func lex(input string) *lexer { - lx := &lexer{ - input: input, - state: lexTop, - line: 1, - items: make(chan item, 10), - stack: make([]stateFn, 0, 10), - } - return lx -} - -func (lx *lexer) push(state stateFn) { - lx.stack = append(lx.stack, state) -} - -func (lx *lexer) pop() stateFn { - if len(lx.stack) == 0 { - return lx.errorf("BUG in lexer: no states to pop") - } - last := lx.stack[len(lx.stack)-1] - lx.stack = lx.stack[0 : len(lx.stack)-1] - return last -} - -func (lx *lexer) current() string { - return lx.input[lx.start:lx.pos] -} - -func (lx *lexer) emit(typ itemType) { - lx.items <- item{typ, lx.current(), lx.line} - lx.start = lx.pos -} - -func (lx *lexer) emitTrim(typ itemType) { - lx.items <- item{typ, strings.TrimSpace(lx.current()), lx.line} - lx.start = lx.pos -} - -func (lx *lexer) next() (r rune) { - if lx.atEOF { - panic("next called after EOF") - } - if lx.pos >= len(lx.input) { - lx.atEOF = true - return eof - } - - if lx.input[lx.pos] == '\n' { - lx.line++ - } - lx.prevWidths[2] = lx.prevWidths[1] - lx.prevWidths[1] = lx.prevWidths[0] - if lx.nprev < 3 { - lx.nprev++ - } - r, w := utf8.DecodeRuneInString(lx.input[lx.pos:]) - lx.prevWidths[0] = w - lx.pos += w - return r -} - -// ignore skips over the pending input before this point. -func (lx *lexer) ignore() { - lx.start = lx.pos -} - -// backup steps back one rune. Can be called only twice between calls to next. -func (lx *lexer) backup() { - if lx.atEOF { - lx.atEOF = false - return - } - if lx.nprev < 1 { - panic("backed up too far") - } - w := lx.prevWidths[0] - lx.prevWidths[0] = lx.prevWidths[1] - lx.prevWidths[1] = lx.prevWidths[2] - lx.nprev-- - lx.pos -= w - if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' { - lx.line-- - } -} - -// accept consumes the next rune if it's equal to `valid`. -func (lx *lexer) accept(valid rune) bool { - if lx.next() == valid { - return true - } - lx.backup() - return false -} - -// peek returns but does not consume the next rune in the input. -func (lx *lexer) peek() rune { - r := lx.next() - lx.backup() - return r -} - -// skip ignores all input that matches the given predicate. -func (lx *lexer) skip(pred func(rune) bool) { - for { - r := lx.next() - if pred(r) { - continue - } - lx.backup() - lx.ignore() - return - } -} - -// errorf stops all lexing by emitting an error and returning `nil`. -// Note that any value that is a character is escaped if it's a special -// character (newlines, tabs, etc.). -func (lx *lexer) errorf(format string, values ...interface{}) stateFn { - lx.items <- item{ - itemError, - fmt.Sprintf(format, values...), - lx.line, - } - return nil -} - -// lexTop consumes elements at the top level of TOML data. -func lexTop(lx *lexer) stateFn { - r := lx.next() - if isWhitespace(r) || isNL(r) { - return lexSkip(lx, lexTop) - } - switch r { - case commentStart: - lx.push(lexTop) - return lexCommentStart - case tableStart: - return lexTableStart - case eof: - if lx.pos > lx.start { - return lx.errorf("unexpected EOF") - } - lx.emit(itemEOF) - return nil - } - - // At this point, the only valid item can be a key, so we back up - // and let the key lexer do the rest. - lx.backup() - lx.push(lexTopEnd) - return lexKeyStart -} - -// lexTopEnd is entered whenever a top-level item has been consumed. (A value -// or a table.) It must see only whitespace, and will turn back to lexTop -// upon a newline. If it sees EOF, it will quit the lexer successfully. -func lexTopEnd(lx *lexer) stateFn { - r := lx.next() - switch { - case r == commentStart: - // a comment will read to a newline for us. - lx.push(lexTop) - return lexCommentStart - case isWhitespace(r): - return lexTopEnd - case isNL(r): - lx.ignore() - return lexTop - case r == eof: - lx.emit(itemEOF) - return nil - } - return lx.errorf("expected a top-level item to end with a newline, "+ - "comment, or EOF, but got %q instead", r) -} - -// lexTable lexes the beginning of a table. Namely, it makes sure that -// it starts with a character other than '.' and ']'. -// It assumes that '[' has already been consumed. -// It also handles the case that this is an item in an array of tables. -// e.g., '[[name]]'. -func lexTableStart(lx *lexer) stateFn { - if lx.peek() == arrayTableStart { - lx.next() - lx.emit(itemArrayTableStart) - lx.push(lexArrayTableEnd) - } else { - lx.emit(itemTableStart) - lx.push(lexTableEnd) - } - return lexTableNameStart -} - -func lexTableEnd(lx *lexer) stateFn { - lx.emit(itemTableEnd) - return lexTopEnd -} - -func lexArrayTableEnd(lx *lexer) stateFn { - if r := lx.next(); r != arrayTableEnd { - return lx.errorf("expected end of table array name delimiter %q, "+ - "but got %q instead", arrayTableEnd, r) - } - lx.emit(itemArrayTableEnd) - return lexTopEnd -} - -func lexTableNameStart(lx *lexer) stateFn { - lx.skip(isWhitespace) - switch r := lx.peek(); { - case r == tableEnd || r == eof: - return lx.errorf("unexpected end of table name " + - "(table names cannot be empty)") - case r == tableSep: - return lx.errorf("unexpected table separator " + - "(table names cannot be empty)") - case r == stringStart || r == rawStringStart: - lx.ignore() - lx.push(lexTableNameEnd) - return lexValue // reuse string lexing - default: - return lexBareTableName - } -} - -// lexBareTableName lexes the name of a table. It assumes that at least one -// valid character for the table has already been read. -func lexBareTableName(lx *lexer) stateFn { - r := lx.next() - if isBareKeyChar(r) { - return lexBareTableName - } - lx.backup() - lx.emit(itemText) - return lexTableNameEnd -} - -// lexTableNameEnd reads the end of a piece of a table name, optionally -// consuming whitespace. -func lexTableNameEnd(lx *lexer) stateFn { - lx.skip(isWhitespace) - switch r := lx.next(); { - case isWhitespace(r): - return lexTableNameEnd - case r == tableSep: - lx.ignore() - return lexTableNameStart - case r == tableEnd: - return lx.pop() - default: - return lx.errorf("expected '.' or ']' to end table name, "+ - "but got %q instead", r) - } -} - -// lexKeyStart consumes a key name up until the first non-whitespace character. -// lexKeyStart will ignore whitespace. -func lexKeyStart(lx *lexer) stateFn { - r := lx.peek() - switch { - case r == keySep: - return lx.errorf("unexpected key separator %q", keySep) - case isWhitespace(r) || isNL(r): - lx.next() - return lexSkip(lx, lexKeyStart) - case r == stringStart || r == rawStringStart: - lx.ignore() - lx.emit(itemKeyStart) - lx.push(lexKeyEnd) - return lexValue // reuse string lexing - default: - lx.ignore() - lx.emit(itemKeyStart) - return lexBareKey - } -} - -// lexBareKey consumes the text of a bare key. Assumes that the first character -// (which is not whitespace) has not yet been consumed. -func lexBareKey(lx *lexer) stateFn { - switch r := lx.next(); { - case isBareKeyChar(r): - return lexBareKey - case isWhitespace(r): - lx.backup() - lx.emit(itemText) - return lexKeyEnd - case r == keySep: - lx.backup() - lx.emit(itemText) - return lexKeyEnd - default: - return lx.errorf("bare keys cannot contain %q", r) - } -} - -// lexKeyEnd consumes the end of a key and trims whitespace (up to the key -// separator). -func lexKeyEnd(lx *lexer) stateFn { - switch r := lx.next(); { - case r == keySep: - return lexSkip(lx, lexValue) - case isWhitespace(r): - return lexSkip(lx, lexKeyEnd) - default: - return lx.errorf("expected key separator %q, but got %q instead", - keySep, r) - } -} - -// lexValue starts the consumption of a value anywhere a value is expected. -// lexValue will ignore whitespace. -// After a value is lexed, the last state on the next is popped and returned. -func lexValue(lx *lexer) stateFn { - // We allow whitespace to precede a value, but NOT newlines. - // In array syntax, the array states are responsible for ignoring newlines. - r := lx.next() - switch { - case isWhitespace(r): - return lexSkip(lx, lexValue) - case isDigit(r): - lx.backup() // avoid an extra state and use the same as above - return lexNumberOrDateStart - } - switch r { - case arrayStart: - lx.ignore() - lx.emit(itemArray) - return lexArrayValue - case inlineTableStart: - lx.ignore() - lx.emit(itemInlineTableStart) - return lexInlineTableValue - case stringStart: - if lx.accept(stringStart) { - if lx.accept(stringStart) { - lx.ignore() // Ignore """ - return lexMultilineString - } - lx.backup() - } - lx.ignore() // ignore the '"' - return lexString - case rawStringStart: - if lx.accept(rawStringStart) { - if lx.accept(rawStringStart) { - lx.ignore() // Ignore """ - return lexMultilineRawString - } - lx.backup() - } - lx.ignore() // ignore the "'" - return lexRawString - case '+', '-': - return lexNumberStart - case '.': // special error case, be kind to users - return lx.errorf("floats must start with a digit, not '.'") - } - if unicode.IsLetter(r) { - // Be permissive here; lexBool will give a nice error if the - // user wrote something like - // x = foo - // (i.e. not 'true' or 'false' but is something else word-like.) - lx.backup() - return lexBool - } - return lx.errorf("expected value but found %q instead", r) -} - -// lexArrayValue consumes one value in an array. It assumes that '[' or ',' -// have already been consumed. All whitespace and newlines are ignored. -func lexArrayValue(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r) || isNL(r): - return lexSkip(lx, lexArrayValue) - case r == commentStart: - lx.push(lexArrayValue) - return lexCommentStart - case r == comma: - return lx.errorf("unexpected comma") - case r == arrayEnd: - // NOTE(caleb): The spec isn't clear about whether you can have - // a trailing comma or not, so we'll allow it. - return lexArrayEnd - } - - lx.backup() - lx.push(lexArrayValueEnd) - return lexValue -} - -// lexArrayValueEnd consumes everything between the end of an array value and -// the next value (or the end of the array): it ignores whitespace and newlines -// and expects either a ',' or a ']'. -func lexArrayValueEnd(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r) || isNL(r): - return lexSkip(lx, lexArrayValueEnd) - case r == commentStart: - lx.push(lexArrayValueEnd) - return lexCommentStart - case r == comma: - lx.ignore() - return lexArrayValue // move on to the next value - case r == arrayEnd: - return lexArrayEnd - } - return lx.errorf( - "expected a comma or array terminator %q, but got %q instead", - arrayEnd, r, - ) -} - -// lexArrayEnd finishes the lexing of an array. -// It assumes that a ']' has just been consumed. -func lexArrayEnd(lx *lexer) stateFn { - lx.ignore() - lx.emit(itemArrayEnd) - return lx.pop() -} - -// lexInlineTableValue consumes one key/value pair in an inline table. -// It assumes that '{' or ',' have already been consumed. Whitespace is ignored. -func lexInlineTableValue(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r): - return lexSkip(lx, lexInlineTableValue) - case isNL(r): - return lx.errorf("newlines not allowed within inline tables") - case r == commentStart: - lx.push(lexInlineTableValue) - return lexCommentStart - case r == comma: - return lx.errorf("unexpected comma") - case r == inlineTableEnd: - return lexInlineTableEnd - } - lx.backup() - lx.push(lexInlineTableValueEnd) - return lexKeyStart -} - -// lexInlineTableValueEnd consumes everything between the end of an inline table -// key/value pair and the next pair (or the end of the table): -// it ignores whitespace and expects either a ',' or a '}'. -func lexInlineTableValueEnd(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r): - return lexSkip(lx, lexInlineTableValueEnd) - case isNL(r): - return lx.errorf("newlines not allowed within inline tables") - case r == commentStart: - lx.push(lexInlineTableValueEnd) - return lexCommentStart - case r == comma: - lx.ignore() - return lexInlineTableValue - case r == inlineTableEnd: - return lexInlineTableEnd - } - return lx.errorf("expected a comma or an inline table terminator %q, "+ - "but got %q instead", inlineTableEnd, r) -} - -// lexInlineTableEnd finishes the lexing of an inline table. -// It assumes that a '}' has just been consumed. -func lexInlineTableEnd(lx *lexer) stateFn { - lx.ignore() - lx.emit(itemInlineTableEnd) - return lx.pop() -} - -// lexString consumes the inner contents of a string. It assumes that the -// beginning '"' has already been consumed and ignored. -func lexString(lx *lexer) stateFn { - r := lx.next() - switch { - case r == eof: - return lx.errorf("unexpected EOF") - case isNL(r): - return lx.errorf("strings cannot contain newlines") - case r == '\\': - lx.push(lexString) - return lexStringEscape - case r == stringEnd: - lx.backup() - lx.emit(itemString) - lx.next() - lx.ignore() - return lx.pop() - } - return lexString -} - -// lexMultilineString consumes the inner contents of a string. It assumes that -// the beginning '"""' has already been consumed and ignored. -func lexMultilineString(lx *lexer) stateFn { - switch lx.next() { - case eof: - return lx.errorf("unexpected EOF") - case '\\': - return lexMultilineStringEscape - case stringEnd: - if lx.accept(stringEnd) { - if lx.accept(stringEnd) { - lx.backup() - lx.backup() - lx.backup() - lx.emit(itemMultilineString) - lx.next() - lx.next() - lx.next() - lx.ignore() - return lx.pop() - } - lx.backup() - } - } - return lexMultilineString -} - -// lexRawString consumes a raw string. Nothing can be escaped in such a string. -// It assumes that the beginning "'" has already been consumed and ignored. -func lexRawString(lx *lexer) stateFn { - r := lx.next() - switch { - case r == eof: - return lx.errorf("unexpected EOF") - case isNL(r): - return lx.errorf("strings cannot contain newlines") - case r == rawStringEnd: - lx.backup() - lx.emit(itemRawString) - lx.next() - lx.ignore() - return lx.pop() - } - return lexRawString -} - -// lexMultilineRawString consumes a raw string. Nothing can be escaped in such -// a string. It assumes that the beginning "'''" has already been consumed and -// ignored. -func lexMultilineRawString(lx *lexer) stateFn { - switch lx.next() { - case eof: - return lx.errorf("unexpected EOF") - case rawStringEnd: - if lx.accept(rawStringEnd) { - if lx.accept(rawStringEnd) { - lx.backup() - lx.backup() - lx.backup() - lx.emit(itemRawMultilineString) - lx.next() - lx.next() - lx.next() - lx.ignore() - return lx.pop() - } - lx.backup() - } - } - return lexMultilineRawString -} - -// lexMultilineStringEscape consumes an escaped character. It assumes that the -// preceding '\\' has already been consumed. -func lexMultilineStringEscape(lx *lexer) stateFn { - // Handle the special case first: - if isNL(lx.next()) { - return lexMultilineString - } - lx.backup() - lx.push(lexMultilineString) - return lexStringEscape(lx) -} - -func lexStringEscape(lx *lexer) stateFn { - r := lx.next() - switch r { - case 'b': - fallthrough - case 't': - fallthrough - case 'n': - fallthrough - case 'f': - fallthrough - case 'r': - fallthrough - case '"': - fallthrough - case '\\': - return lx.pop() - case 'u': - return lexShortUnicodeEscape - case 'U': - return lexLongUnicodeEscape - } - return lx.errorf("invalid escape character %q; only the following "+ - "escape characters are allowed: "+ - `\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX`, r) -} - -func lexShortUnicodeEscape(lx *lexer) stateFn { - var r rune - for i := 0; i < 4; i++ { - r = lx.next() - if !isHexadecimal(r) { - return lx.errorf(`expected four hexadecimal digits after '\u', `+ - "but got %q instead", lx.current()) - } - } - return lx.pop() -} - -func lexLongUnicodeEscape(lx *lexer) stateFn { - var r rune - for i := 0; i < 8; i++ { - r = lx.next() - if !isHexadecimal(r) { - return lx.errorf(`expected eight hexadecimal digits after '\U', `+ - "but got %q instead", lx.current()) - } - } - return lx.pop() -} - -// lexNumberOrDateStart consumes either an integer, a float, or datetime. -func lexNumberOrDateStart(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexNumberOrDate - } - switch r { - case '_': - return lexNumber - case 'e', 'E': - return lexFloat - case '.': - return lx.errorf("floats must start with a digit, not '.'") - } - return lx.errorf("expected a digit but got %q", r) -} - -// lexNumberOrDate consumes either an integer, float or datetime. -func lexNumberOrDate(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexNumberOrDate - } - switch r { - case '-': - return lexDatetime - case '_': - return lexNumber - case '.', 'e', 'E': - return lexFloat - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexDatetime consumes a Datetime, to a first approximation. -// The parser validates that it matches one of the accepted formats. -func lexDatetime(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexDatetime - } - switch r { - case '-', 'T', ':', '.', 'Z', '+': - return lexDatetime - } - - lx.backup() - lx.emit(itemDatetime) - return lx.pop() -} - -// lexNumberStart consumes either an integer or a float. It assumes that a sign -// has already been read, but that *no* digits have been consumed. -// lexNumberStart will move to the appropriate integer or float states. -func lexNumberStart(lx *lexer) stateFn { - // We MUST see a digit. Even floats have to start with a digit. - r := lx.next() - if !isDigit(r) { - if r == '.' { - return lx.errorf("floats must start with a digit, not '.'") - } - return lx.errorf("expected a digit but got %q", r) - } - return lexNumber -} - -// lexNumber consumes an integer or a float after seeing the first digit. -func lexNumber(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexNumber - } - switch r { - case '_': - return lexNumber - case '.', 'e', 'E': - return lexFloat - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexFloat consumes the elements of a float. It allows any sequence of -// float-like characters, so floats emitted by the lexer are only a first -// approximation and must be validated by the parser. -func lexFloat(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexFloat - } - switch r { - case '_', '.', '-', '+', 'e', 'E': - return lexFloat - } - - lx.backup() - lx.emit(itemFloat) - return lx.pop() -} - -// lexBool consumes a bool string: 'true' or 'false. -func lexBool(lx *lexer) stateFn { - var rs []rune - for { - r := lx.next() - if !unicode.IsLetter(r) { - lx.backup() - break - } - rs = append(rs, r) - } - s := string(rs) - switch s { - case "true", "false": - lx.emit(itemBool) - return lx.pop() - } - return lx.errorf("expected value but found %q instead", s) -} - -// lexCommentStart begins the lexing of a comment. It will emit -// itemCommentStart and consume no characters, passing control to lexComment. -func lexCommentStart(lx *lexer) stateFn { - lx.ignore() - lx.emit(itemCommentStart) - return lexComment -} - -// lexComment lexes an entire comment. It assumes that '#' has been consumed. -// It will consume *up to* the first newline character, and pass control -// back to the last state on the stack. -func lexComment(lx *lexer) stateFn { - r := lx.peek() - if isNL(r) || r == eof { - lx.emit(itemText) - return lx.pop() - } - lx.next() - return lexComment -} - -// lexSkip ignores all slurped input and moves on to the next state. -func lexSkip(lx *lexer, nextState stateFn) stateFn { - return func(lx *lexer) stateFn { - lx.ignore() - return nextState - } -} - -// isWhitespace returns true if `r` is a whitespace character according -// to the spec. -func isWhitespace(r rune) bool { - return r == '\t' || r == ' ' -} - -func isNL(r rune) bool { - return r == '\n' || r == '\r' -} - -func isDigit(r rune) bool { - return r >= '0' && r <= '9' -} - -func isHexadecimal(r rune) bool { - return (r >= '0' && r <= '9') || - (r >= 'a' && r <= 'f') || - (r >= 'A' && r <= 'F') -} - -func isBareKeyChar(r rune) bool { - return (r >= 'A' && r <= 'Z') || - (r >= 'a' && r <= 'z') || - (r >= '0' && r <= '9') || - r == '_' || - r == '-' -} - -func (itype itemType) String() string { - switch itype { - case itemError: - return "Error" - case itemNIL: - return "NIL" - case itemEOF: - return "EOF" - case itemText: - return "Text" - case itemString, itemRawString, itemMultilineString, itemRawMultilineString: - return "String" - case itemBool: - return "Bool" - case itemInteger: - return "Integer" - case itemFloat: - return "Float" - case itemDatetime: - return "DateTime" - case itemTableStart: - return "TableStart" - case itemTableEnd: - return "TableEnd" - case itemKeyStart: - return "KeyStart" - case itemArray: - return "Array" - case itemArrayEnd: - return "ArrayEnd" - case itemCommentStart: - return "CommentStart" - } - panic(fmt.Sprintf("BUG: Unknown type '%d'.", int(itype))) -} - -func (item item) String() string { - return fmt.Sprintf("(%s, %s)", item.typ.String(), item.val) -} diff --git a/vendor/github.com/BurntSushi/toml/parse.go b/vendor/github.com/BurntSushi/toml/parse.go deleted file mode 100644 index 50869ef926..0000000000 --- a/vendor/github.com/BurntSushi/toml/parse.go +++ /dev/null @@ -1,592 +0,0 @@ -package toml - -import ( - "fmt" - "strconv" - "strings" - "time" - "unicode" - "unicode/utf8" -) - -type parser struct { - mapping map[string]interface{} - types map[string]tomlType - lx *lexer - - // A list of keys in the order that they appear in the TOML data. - ordered []Key - - // the full key for the current hash in scope - context Key - - // the base key name for everything except hashes - currentKey string - - // rough approximation of line number - approxLine int - - // A map of 'key.group.names' to whether they were created implicitly. - implicits map[string]bool -} - -type parseError string - -func (pe parseError) Error() string { - return string(pe) -} - -func parse(data string) (p *parser, err error) { - defer func() { - if r := recover(); r != nil { - var ok bool - if err, ok = r.(parseError); ok { - return - } - panic(r) - } - }() - - p = &parser{ - mapping: make(map[string]interface{}), - types: make(map[string]tomlType), - lx: lex(data), - ordered: make([]Key, 0), - implicits: make(map[string]bool), - } - for { - item := p.next() - if item.typ == itemEOF { - break - } - p.topLevel(item) - } - - return p, nil -} - -func (p *parser) panicf(format string, v ...interface{}) { - msg := fmt.Sprintf("Near line %d (last key parsed '%s'): %s", - p.approxLine, p.current(), fmt.Sprintf(format, v...)) - panic(parseError(msg)) -} - -func (p *parser) next() item { - it := p.lx.nextItem() - if it.typ == itemError { - p.panicf("%s", it.val) - } - return it -} - -func (p *parser) bug(format string, v ...interface{}) { - panic(fmt.Sprintf("BUG: "+format+"\n\n", v...)) -} - -func (p *parser) expect(typ itemType) item { - it := p.next() - p.assertEqual(typ, it.typ) - return it -} - -func (p *parser) assertEqual(expected, got itemType) { - if expected != got { - p.bug("Expected '%s' but got '%s'.", expected, got) - } -} - -func (p *parser) topLevel(item item) { - switch item.typ { - case itemCommentStart: - p.approxLine = item.line - p.expect(itemText) - case itemTableStart: - kg := p.next() - p.approxLine = kg.line - - var key Key - for ; kg.typ != itemTableEnd && kg.typ != itemEOF; kg = p.next() { - key = append(key, p.keyString(kg)) - } - p.assertEqual(itemTableEnd, kg.typ) - - p.establishContext(key, false) - p.setType("", tomlHash) - p.ordered = append(p.ordered, key) - case itemArrayTableStart: - kg := p.next() - p.approxLine = kg.line - - var key Key - for ; kg.typ != itemArrayTableEnd && kg.typ != itemEOF; kg = p.next() { - key = append(key, p.keyString(kg)) - } - p.assertEqual(itemArrayTableEnd, kg.typ) - - p.establishContext(key, true) - p.setType("", tomlArrayHash) - p.ordered = append(p.ordered, key) - case itemKeyStart: - kname := p.next() - p.approxLine = kname.line - p.currentKey = p.keyString(kname) - - val, typ := p.value(p.next()) - p.setValue(p.currentKey, val) - p.setType(p.currentKey, typ) - p.ordered = append(p.ordered, p.context.add(p.currentKey)) - p.currentKey = "" - default: - p.bug("Unexpected type at top level: %s", item.typ) - } -} - -// Gets a string for a key (or part of a key in a table name). -func (p *parser) keyString(it item) string { - switch it.typ { - case itemText: - return it.val - case itemString, itemMultilineString, - itemRawString, itemRawMultilineString: - s, _ := p.value(it) - return s.(string) - default: - p.bug("Unexpected key type: %s", it.typ) - panic("unreachable") - } -} - -// value translates an expected value from the lexer into a Go value wrapped -// as an empty interface. -func (p *parser) value(it item) (interface{}, tomlType) { - switch it.typ { - case itemString: - return p.replaceEscapes(it.val), p.typeOfPrimitive(it) - case itemMultilineString: - trimmed := stripFirstNewline(stripEscapedWhitespace(it.val)) - return p.replaceEscapes(trimmed), p.typeOfPrimitive(it) - case itemRawString: - return it.val, p.typeOfPrimitive(it) - case itemRawMultilineString: - return stripFirstNewline(it.val), p.typeOfPrimitive(it) - case itemBool: - switch it.val { - case "true": - return true, p.typeOfPrimitive(it) - case "false": - return false, p.typeOfPrimitive(it) - } - p.bug("Expected boolean value, but got '%s'.", it.val) - case itemInteger: - if !numUnderscoresOK(it.val) { - p.panicf("Invalid integer %q: underscores must be surrounded by digits", - it.val) - } - val := strings.Replace(it.val, "_", "", -1) - num, err := strconv.ParseInt(val, 10, 64) - if err != nil { - // Distinguish integer values. Normally, it'd be a bug if the lexer - // provides an invalid integer, but it's possible that the number is - // out of range of valid values (which the lexer cannot determine). - // So mark the former as a bug but the latter as a legitimate user - // error. - if e, ok := err.(*strconv.NumError); ok && - e.Err == strconv.ErrRange { - - p.panicf("Integer '%s' is out of the range of 64-bit "+ - "signed integers.", it.val) - } else { - p.bug("Expected integer value, but got '%s'.", it.val) - } - } - return num, p.typeOfPrimitive(it) - case itemFloat: - parts := strings.FieldsFunc(it.val, func(r rune) bool { - switch r { - case '.', 'e', 'E': - return true - } - return false - }) - for _, part := range parts { - if !numUnderscoresOK(part) { - p.panicf("Invalid float %q: underscores must be "+ - "surrounded by digits", it.val) - } - } - if !numPeriodsOK(it.val) { - // As a special case, numbers like '123.' or '1.e2', - // which are valid as far as Go/strconv are concerned, - // must be rejected because TOML says that a fractional - // part consists of '.' followed by 1+ digits. - p.panicf("Invalid float %q: '.' must be followed "+ - "by one or more digits", it.val) - } - val := strings.Replace(it.val, "_", "", -1) - num, err := strconv.ParseFloat(val, 64) - if err != nil { - if e, ok := err.(*strconv.NumError); ok && - e.Err == strconv.ErrRange { - - p.panicf("Float '%s' is out of the range of 64-bit "+ - "IEEE-754 floating-point numbers.", it.val) - } else { - p.panicf("Invalid float value: %q", it.val) - } - } - return num, p.typeOfPrimitive(it) - case itemDatetime: - var t time.Time - var ok bool - var err error - for _, format := range []string{ - "2006-01-02T15:04:05Z07:00", - "2006-01-02T15:04:05", - "2006-01-02", - } { - t, err = time.ParseInLocation(format, it.val, time.Local) - if err == nil { - ok = true - break - } - } - if !ok { - p.panicf("Invalid TOML Datetime: %q.", it.val) - } - return t, p.typeOfPrimitive(it) - case itemArray: - array := make([]interface{}, 0) - types := make([]tomlType, 0) - - for it = p.next(); it.typ != itemArrayEnd; it = p.next() { - if it.typ == itemCommentStart { - p.expect(itemText) - continue - } - - val, typ := p.value(it) - array = append(array, val) - types = append(types, typ) - } - return array, p.typeOfArray(types) - case itemInlineTableStart: - var ( - hash = make(map[string]interface{}) - outerContext = p.context - outerKey = p.currentKey - ) - - p.context = append(p.context, p.currentKey) - p.currentKey = "" - for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() { - if it.typ != itemKeyStart { - p.bug("Expected key start but instead found %q, around line %d", - it.val, p.approxLine) - } - if it.typ == itemCommentStart { - p.expect(itemText) - continue - } - - // retrieve key - k := p.next() - p.approxLine = k.line - kname := p.keyString(k) - - // retrieve value - p.currentKey = kname - val, typ := p.value(p.next()) - // make sure we keep metadata up to date - p.setType(kname, typ) - p.ordered = append(p.ordered, p.context.add(p.currentKey)) - hash[kname] = val - } - p.context = outerContext - p.currentKey = outerKey - return hash, tomlHash - } - p.bug("Unexpected value type: %s", it.typ) - panic("unreachable") -} - -// numUnderscoresOK checks whether each underscore in s is surrounded by -// characters that are not underscores. -func numUnderscoresOK(s string) bool { - accept := false - for _, r := range s { - if r == '_' { - if !accept { - return false - } - accept = false - continue - } - accept = true - } - return accept -} - -// numPeriodsOK checks whether every period in s is followed by a digit. -func numPeriodsOK(s string) bool { - period := false - for _, r := range s { - if period && !isDigit(r) { - return false - } - period = r == '.' - } - return !period -} - -// establishContext sets the current context of the parser, -// where the context is either a hash or an array of hashes. Which one is -// set depends on the value of the `array` parameter. -// -// Establishing the context also makes sure that the key isn't a duplicate, and -// will create implicit hashes automatically. -func (p *parser) establishContext(key Key, array bool) { - var ok bool - - // Always start at the top level and drill down for our context. - hashContext := p.mapping - keyContext := make(Key, 0) - - // We only need implicit hashes for key[0:-1] - for _, k := range key[0 : len(key)-1] { - _, ok = hashContext[k] - keyContext = append(keyContext, k) - - // No key? Make an implicit hash and move on. - if !ok { - p.addImplicit(keyContext) - hashContext[k] = make(map[string]interface{}) - } - - // If the hash context is actually an array of tables, then set - // the hash context to the last element in that array. - // - // Otherwise, it better be a table, since this MUST be a key group (by - // virtue of it not being the last element in a key). - switch t := hashContext[k].(type) { - case []map[string]interface{}: - hashContext = t[len(t)-1] - case map[string]interface{}: - hashContext = t - default: - p.panicf("Key '%s' was already created as a hash.", keyContext) - } - } - - p.context = keyContext - if array { - // If this is the first element for this array, then allocate a new - // list of tables for it. - k := key[len(key)-1] - if _, ok := hashContext[k]; !ok { - hashContext[k] = make([]map[string]interface{}, 0, 5) - } - - // Add a new table. But make sure the key hasn't already been used - // for something else. - if hash, ok := hashContext[k].([]map[string]interface{}); ok { - hashContext[k] = append(hash, make(map[string]interface{})) - } else { - p.panicf("Key '%s' was already created and cannot be used as "+ - "an array.", keyContext) - } - } else { - p.setValue(key[len(key)-1], make(map[string]interface{})) - } - p.context = append(p.context, key[len(key)-1]) -} - -// setValue sets the given key to the given value in the current context. -// It will make sure that the key hasn't already been defined, account for -// implicit key groups. -func (p *parser) setValue(key string, value interface{}) { - var tmpHash interface{} - var ok bool - - hash := p.mapping - keyContext := make(Key, 0) - for _, k := range p.context { - keyContext = append(keyContext, k) - if tmpHash, ok = hash[k]; !ok { - p.bug("Context for key '%s' has not been established.", keyContext) - } - switch t := tmpHash.(type) { - case []map[string]interface{}: - // The context is a table of hashes. Pick the most recent table - // defined as the current hash. - hash = t[len(t)-1] - case map[string]interface{}: - hash = t - default: - p.bug("Expected hash to have type 'map[string]interface{}', but "+ - "it has '%T' instead.", tmpHash) - } - } - keyContext = append(keyContext, key) - - if _, ok := hash[key]; ok { - // Typically, if the given key has already been set, then we have - // to raise an error since duplicate keys are disallowed. However, - // it's possible that a key was previously defined implicitly. In this - // case, it is allowed to be redefined concretely. (See the - // `tests/valid/implicit-and-explicit-after.toml` test in `toml-test`.) - // - // But we have to make sure to stop marking it as an implicit. (So that - // another redefinition provokes an error.) - // - // Note that since it has already been defined (as a hash), we don't - // want to overwrite it. So our business is done. - if p.isImplicit(keyContext) { - p.removeImplicit(keyContext) - return - } - - // Otherwise, we have a concrete key trying to override a previous - // key, which is *always* wrong. - p.panicf("Key '%s' has already been defined.", keyContext) - } - hash[key] = value -} - -// setType sets the type of a particular value at a given key. -// It should be called immediately AFTER setValue. -// -// Note that if `key` is empty, then the type given will be applied to the -// current context (which is either a table or an array of tables). -func (p *parser) setType(key string, typ tomlType) { - keyContext := make(Key, 0, len(p.context)+1) - for _, k := range p.context { - keyContext = append(keyContext, k) - } - if len(key) > 0 { // allow type setting for hashes - keyContext = append(keyContext, key) - } - p.types[keyContext.String()] = typ -} - -// addImplicit sets the given Key as having been created implicitly. -func (p *parser) addImplicit(key Key) { - p.implicits[key.String()] = true -} - -// removeImplicit stops tagging the given key as having been implicitly -// created. -func (p *parser) removeImplicit(key Key) { - p.implicits[key.String()] = false -} - -// isImplicit returns true if the key group pointed to by the key was created -// implicitly. -func (p *parser) isImplicit(key Key) bool { - return p.implicits[key.String()] -} - -// current returns the full key name of the current context. -func (p *parser) current() string { - if len(p.currentKey) == 0 { - return p.context.String() - } - if len(p.context) == 0 { - return p.currentKey - } - return fmt.Sprintf("%s.%s", p.context, p.currentKey) -} - -func stripFirstNewline(s string) string { - if len(s) == 0 || s[0] != '\n' { - return s - } - return s[1:] -} - -func stripEscapedWhitespace(s string) string { - esc := strings.Split(s, "\\\n") - if len(esc) > 1 { - for i := 1; i < len(esc); i++ { - esc[i] = strings.TrimLeftFunc(esc[i], unicode.IsSpace) - } - } - return strings.Join(esc, "") -} - -func (p *parser) replaceEscapes(str string) string { - var replaced []rune - s := []byte(str) - r := 0 - for r < len(s) { - if s[r] != '\\' { - c, size := utf8.DecodeRune(s[r:]) - r += size - replaced = append(replaced, c) - continue - } - r += 1 - if r >= len(s) { - p.bug("Escape sequence at end of string.") - return "" - } - switch s[r] { - default: - p.bug("Expected valid escape code after \\, but got %q.", s[r]) - return "" - case 'b': - replaced = append(replaced, rune(0x0008)) - r += 1 - case 't': - replaced = append(replaced, rune(0x0009)) - r += 1 - case 'n': - replaced = append(replaced, rune(0x000A)) - r += 1 - case 'f': - replaced = append(replaced, rune(0x000C)) - r += 1 - case 'r': - replaced = append(replaced, rune(0x000D)) - r += 1 - case '"': - replaced = append(replaced, rune(0x0022)) - r += 1 - case '\\': - replaced = append(replaced, rune(0x005C)) - r += 1 - case 'u': - // At this point, we know we have a Unicode escape of the form - // `uXXXX` at [r, r+5). (Because the lexer guarantees this - // for us.) - escaped := p.asciiEscapeToUnicode(s[r+1 : r+5]) - replaced = append(replaced, escaped) - r += 5 - case 'U': - // At this point, we know we have a Unicode escape of the form - // `uXXXX` at [r, r+9). (Because the lexer guarantees this - // for us.) - escaped := p.asciiEscapeToUnicode(s[r+1 : r+9]) - replaced = append(replaced, escaped) - r += 9 - } - } - return string(replaced) -} - -func (p *parser) asciiEscapeToUnicode(bs []byte) rune { - s := string(bs) - hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32) - if err != nil { - p.bug("Could not parse '%s' as a hexadecimal number, but the "+ - "lexer claims it's OK: %s", s, err) - } - if !utf8.ValidRune(rune(hex)) { - p.panicf("Escaped character '\\u%s' is not valid UTF-8.", s) - } - return rune(hex) -} - -func isStringType(ty itemType) bool { - return ty == itemString || ty == itemMultilineString || - ty == itemRawString || ty == itemRawMultilineString -} diff --git a/vendor/github.com/BurntSushi/toml/session.vim b/vendor/github.com/BurntSushi/toml/session.vim deleted file mode 100644 index 562164be06..0000000000 --- a/vendor/github.com/BurntSushi/toml/session.vim +++ /dev/null @@ -1 +0,0 @@ -au BufWritePost *.go silent!make tags > /dev/null 2>&1 diff --git a/vendor/github.com/BurntSushi/toml/type_check.go b/vendor/github.com/BurntSushi/toml/type_check.go deleted file mode 100644 index c73f8afc1a..0000000000 --- a/vendor/github.com/BurntSushi/toml/type_check.go +++ /dev/null @@ -1,91 +0,0 @@ -package toml - -// tomlType represents any Go type that corresponds to a TOML type. -// While the first draft of the TOML spec has a simplistic type system that -// probably doesn't need this level of sophistication, we seem to be militating -// toward adding real composite types. -type tomlType interface { - typeString() string -} - -// typeEqual accepts any two types and returns true if they are equal. -func typeEqual(t1, t2 tomlType) bool { - if t1 == nil || t2 == nil { - return false - } - return t1.typeString() == t2.typeString() -} - -func typeIsHash(t tomlType) bool { - return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash) -} - -type tomlBaseType string - -func (btype tomlBaseType) typeString() string { - return string(btype) -} - -func (btype tomlBaseType) String() string { - return btype.typeString() -} - -var ( - tomlInteger tomlBaseType = "Integer" - tomlFloat tomlBaseType = "Float" - tomlDatetime tomlBaseType = "Datetime" - tomlString tomlBaseType = "String" - tomlBool tomlBaseType = "Bool" - tomlArray tomlBaseType = "Array" - tomlHash tomlBaseType = "Hash" - tomlArrayHash tomlBaseType = "ArrayHash" -) - -// typeOfPrimitive returns a tomlType of any primitive value in TOML. -// Primitive values are: Integer, Float, Datetime, String and Bool. -// -// Passing a lexer item other than the following will cause a BUG message -// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime. -func (p *parser) typeOfPrimitive(lexItem item) tomlType { - switch lexItem.typ { - case itemInteger: - return tomlInteger - case itemFloat: - return tomlFloat - case itemDatetime: - return tomlDatetime - case itemString: - return tomlString - case itemMultilineString: - return tomlString - case itemRawString: - return tomlString - case itemRawMultilineString: - return tomlString - case itemBool: - return tomlBool - } - p.bug("Cannot infer primitive type of lex item '%s'.", lexItem) - panic("unreachable") -} - -// typeOfArray returns a tomlType for an array given a list of types of its -// values. -// -// In the current spec, if an array is homogeneous, then its type is always -// "Array". If the array is not homogeneous, an error is generated. -func (p *parser) typeOfArray(types []tomlType) tomlType { - // Empty arrays are cool. - if len(types) == 0 { - return tomlArray - } - - theType := types[0] - for _, t := range types[1:] { - if !typeEqual(theType, t) { - p.panicf("Array contains values of type '%s' and '%s', but "+ - "arrays must be homogeneous.", theType, t) - } - } - return tomlArray -} diff --git a/vendor/github.com/BurntSushi/toml/type_fields.go b/vendor/github.com/BurntSushi/toml/type_fields.go deleted file mode 100644 index 608997c22f..0000000000 --- a/vendor/github.com/BurntSushi/toml/type_fields.go +++ /dev/null @@ -1,242 +0,0 @@ -package toml - -// Struct field handling is adapted from code in encoding/json: -// -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the Go distribution. - -import ( - "reflect" - "sort" - "sync" -) - -// A field represents a single field found in a struct. -type field struct { - name string // the name of the field (`toml` tag included) - tag bool // whether field has a `toml` tag - index []int // represents the depth of an anonymous field - typ reflect.Type // the type of the field -} - -// byName sorts field by name, breaking ties with depth, -// then breaking ties with "name came from toml 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 TOML 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 != "" && !sf.Anonymous { // unexported - continue - } - opts := getOptions(sf.Tag) - if opts.skip { - continue - } - 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 opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { - tagged := opts.name != "" - name := opts.name - if name == "" { - name = sf.Name - } - fields = append(fields, field{name, tagged, index, ft}) - 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 { - f := field{name: ft.Name(), index: index, typ: ft} - next = append(next, f) - } - } - } - } - - sort.Sort(byName(fields)) - - // Delete all fields that are hidden by the Go rules for embedded fields, - // except that fields with TOML 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 -// TOML 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 -} diff --git a/vendor/github.com/PuerkitoBio/purell/.gitignore b/vendor/github.com/PuerkitoBio/purell/.gitignore deleted file mode 100644 index 748e4c8073..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.sublime-* -.DS_Store -*.swp -*.swo -tags diff --git a/vendor/github.com/PuerkitoBio/purell/.travis.yml b/vendor/github.com/PuerkitoBio/purell/.travis.yml deleted file mode 100644 index cf31e6af6d..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: go - -go: - - 1.4.x - - 1.5.x - - 1.6.x - - 1.7.x - - 1.8.x - - 1.9.x - - "1.10.x" - - "1.11.x" - - tip diff --git a/vendor/github.com/PuerkitoBio/purell/LICENSE b/vendor/github.com/PuerkitoBio/purell/LICENSE deleted file mode 100644 index 4b9986dea7..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2012, Martin Angers -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 author 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/PuerkitoBio/purell/README.md b/vendor/github.com/PuerkitoBio/purell/README.md deleted file mode 100644 index 07de0c4986..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/README.md +++ /dev/null @@ -1,188 +0,0 @@ -# Purell - -Purell is a tiny Go library to normalize URLs. It returns a pure URL. Pure-ell. Sanitizer and all. Yeah, I know... - -Based on the [wikipedia paper][wiki] and the [RFC 3986 document][rfc]. - -[![build status](https://travis-ci.org/PuerkitoBio/purell.svg?branch=master)](http://travis-ci.org/PuerkitoBio/purell) - -## Install - -`go get github.com/PuerkitoBio/purell` - -## Changelog - -* **v1.1.1** : Fix failing test due to Go1.12 changes (thanks to @ianlancetaylor). -* **2016-11-14 (v1.1.0)** : IDN: Conform to RFC 5895: Fold character width (thanks to @beeker1121). -* **2016-07-27 (v1.0.0)** : Normalize IDN to ASCII (thanks to @zenovich). -* **2015-02-08** : Add fix for relative paths issue ([PR #5][pr5]) and add fix for unnecessary encoding of reserved characters ([see issue #7][iss7]). -* **v0.2.0** : Add benchmarks, Attempt IDN support. -* **v0.1.0** : Initial release. - -## Examples - -From `example_test.go` (note that in your code, you would import "github.com/PuerkitoBio/purell", and would prefix references to its methods and constants with "purell."): - -```go -package purell - -import ( - "fmt" - "net/url" -) - -func ExampleNormalizeURLString() { - if normalized, err := NormalizeURLString("hTTp://someWEBsite.com:80/Amazing%3f/url/", - FlagLowercaseScheme|FlagLowercaseHost|FlagUppercaseEscapes); err != nil { - panic(err) - } else { - fmt.Print(normalized) - } - // Output: http://somewebsite.com:80/Amazing%3F/url/ -} - -func ExampleMustNormalizeURLString() { - normalized := MustNormalizeURLString("hTTpS://someWEBsite.com:443/Amazing%fa/url/", - FlagsUnsafeGreedy) - fmt.Print(normalized) - - // Output: http://somewebsite.com/Amazing%FA/url -} - -func ExampleNormalizeURL() { - if u, err := url.Parse("Http://SomeUrl.com:8080/a/b/.././c///g?c=3&a=1&b=9&c=0#target"); err != nil { - panic(err) - } else { - normalized := NormalizeURL(u, FlagsUsuallySafeGreedy|FlagRemoveDuplicateSlashes|FlagRemoveFragment) - fmt.Print(normalized) - } - - // Output: http://someurl.com:8080/a/c/g?c=3&a=1&b=9&c=0 -} -``` - -## API - -As seen in the examples above, purell offers three methods, `NormalizeURLString(string, NormalizationFlags) (string, error)`, `MustNormalizeURLString(string, NormalizationFlags) (string)` and `NormalizeURL(*url.URL, NormalizationFlags) (string)`. They all normalize the provided URL based on the specified flags. Here are the available flags: - -```go -const ( - // Safe normalizations - FlagLowercaseScheme NormalizationFlags = 1 << iota // HTTP://host -> http://host, applied by default in Go1.1 - FlagLowercaseHost // http://HOST -> http://host - FlagUppercaseEscapes // http://host/t%ef -> http://host/t%EF - FlagDecodeUnnecessaryEscapes // http://host/t%41 -> http://host/tA - FlagEncodeNecessaryEscapes // http://host/!"#$ -> http://host/%21%22#$ - FlagRemoveDefaultPort // http://host:80 -> http://host - FlagRemoveEmptyQuerySeparator // http://host/path? -> http://host/path - - // Usually safe normalizations - FlagRemoveTrailingSlash // http://host/path/ -> http://host/path - FlagAddTrailingSlash // http://host/path -> http://host/path/ (should choose only one of these add/remove trailing slash flags) - FlagRemoveDotSegments // http://host/path/./a/b/../c -> http://host/path/a/c - - // Unsafe normalizations - FlagRemoveDirectoryIndex // http://host/path/index.html -> http://host/path/ - FlagRemoveFragment // http://host/path#fragment -> http://host/path - FlagForceHTTP // https://host -> http://host - FlagRemoveDuplicateSlashes // http://host/path//a///b -> http://host/path/a/b - FlagRemoveWWW // http://www.host/ -> http://host/ - FlagAddWWW // http://host/ -> http://www.host/ (should choose only one of these add/remove WWW flags) - FlagSortQuery // http://host/path?c=3&b=2&a=1&b=1 -> http://host/path?a=1&b=1&b=2&c=3 - - // Normalizations not in the wikipedia article, required to cover tests cases - // submitted by jehiah - FlagDecodeDWORDHost // http://1113982867 -> http://66.102.7.147 - FlagDecodeOctalHost // http://0102.0146.07.0223 -> http://66.102.7.147 - FlagDecodeHexHost // http://0x42660793 -> http://66.102.7.147 - FlagRemoveUnnecessaryHostDots // http://.host../path -> http://host/path - FlagRemoveEmptyPortSeparator // http://host:/path -> http://host/path - - // Convenience set of safe normalizations - FlagsSafe NormalizationFlags = FlagLowercaseHost | FlagLowercaseScheme | FlagUppercaseEscapes | FlagDecodeUnnecessaryEscapes | FlagEncodeNecessaryEscapes | FlagRemoveDefaultPort | FlagRemoveEmptyQuerySeparator - - // For convenience sets, "greedy" uses the "remove trailing slash" and "remove www. prefix" flags, - // while "non-greedy" uses the "add (or keep) the trailing slash" and "add www. prefix". - - // Convenience set of usually safe normalizations (includes FlagsSafe) - FlagsUsuallySafeGreedy NormalizationFlags = FlagsSafe | FlagRemoveTrailingSlash | FlagRemoveDotSegments - FlagsUsuallySafeNonGreedy NormalizationFlags = FlagsSafe | FlagAddTrailingSlash | FlagRemoveDotSegments - - // Convenience set of unsafe normalizations (includes FlagsUsuallySafe) - FlagsUnsafeGreedy NormalizationFlags = FlagsUsuallySafeGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagRemoveWWW | FlagSortQuery - FlagsUnsafeNonGreedy NormalizationFlags = FlagsUsuallySafeNonGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagAddWWW | FlagSortQuery - - // Convenience set of all available flags - FlagsAllGreedy = FlagsUnsafeGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator - FlagsAllNonGreedy = FlagsUnsafeNonGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator -) -``` - -For convenience, the set of flags `FlagsSafe`, `FlagsUsuallySafe[Greedy|NonGreedy]`, `FlagsUnsafe[Greedy|NonGreedy]` and `FlagsAll[Greedy|NonGreedy]` are provided for the similarly grouped normalizations on [wikipedia's URL normalization page][wiki]. You can add (using the bitwise OR `|` operator) or remove (using the bitwise AND NOT `&^` operator) individual flags from the sets if required, to build your own custom set. - -The [full godoc reference is available on gopkgdoc][godoc]. - -Some things to note: - -* `FlagDecodeUnnecessaryEscapes`, `FlagEncodeNecessaryEscapes`, `FlagUppercaseEscapes` and `FlagRemoveEmptyQuerySeparator` are always implicitly set, because internally, the URL string is parsed as an URL object, which automatically decodes unnecessary escapes, uppercases and encodes necessary ones, and removes empty query separators (an unnecessary `?` at the end of the url). So this operation cannot **not** be done. For this reason, `FlagRemoveEmptyQuerySeparator` (as well as the other three) has been included in the `FlagsSafe` convenience set, instead of `FlagsUnsafe`, where Wikipedia puts it. - -* The `FlagDecodeUnnecessaryEscapes` decodes the following escapes (*from -> to*): - - %24 -> $ - - %26 -> & - - %2B-%3B -> +,-./0123456789:; - - %3D -> = - - %40-%5A -> @ABCDEFGHIJKLMNOPQRSTUVWXYZ - - %5F -> _ - - %61-%7A -> abcdefghijklmnopqrstuvwxyz - - %7E -> ~ - - -* When the `NormalizeURL` function is used (passing an URL object), this source URL object is modified (that is, after the call, the URL object will be modified to reflect the normalization). - -* The *replace IP with domain name* normalization (`http://208.77.188.166/ → http://www.example.com/`) is obviously not possible for a library without making some network requests. This is not implemented in purell. - -* The *remove unused query string parameters* and *remove default query parameters* are also not implemented, since this is a very case-specific normalization, and it is quite trivial to do with an URL object. - -### Safe vs Usually Safe vs Unsafe - -Purell allows you to control the level of risk you take while normalizing an URL. You can aggressively normalize, play it totally safe, or anything in between. - -Consider the following URL: - -`HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid` - -Normalizing with the `FlagsSafe` gives: - -`https://www.root.com/toto/tE%1F///a/./b/../c/?z=3&w=2&a=4&w=1#invalid` - -With the `FlagsUsuallySafeGreedy`: - -`https://www.root.com/toto/tE%1F///a/c?z=3&w=2&a=4&w=1#invalid` - -And with `FlagsUnsafeGreedy`: - -`http://root.com/toto/tE%1F/a/c?a=4&w=1&w=2&z=3` - -## TODOs - -* Add a class/default instance to allow specifying custom directory index names? At the moment, removing directory index removes `(^|/)((?:default|index)\.\w{1,4})$`. - -## Thanks / Contributions - -@rogpeppe -@jehiah -@opennota -@pchristopher1275 -@zenovich -@beeker1121 - -## License - -The [BSD 3-Clause license][bsd]. - -[bsd]: http://opensource.org/licenses/BSD-3-Clause -[wiki]: http://en.wikipedia.org/wiki/URL_normalization -[rfc]: http://tools.ietf.org/html/rfc3986#section-6 -[godoc]: http://go.pkgdoc.org/github.com/PuerkitoBio/purell -[pr5]: https://github.com/PuerkitoBio/purell/pull/5 -[iss7]: https://github.com/PuerkitoBio/purell/issues/7 diff --git a/vendor/github.com/PuerkitoBio/purell/purell.go b/vendor/github.com/PuerkitoBio/purell/purell.go deleted file mode 100644 index 6d0fc190a1..0000000000 --- a/vendor/github.com/PuerkitoBio/purell/purell.go +++ /dev/null @@ -1,379 +0,0 @@ -/* -Package purell offers URL normalization as described on the wikipedia page: -http://en.wikipedia.org/wiki/URL_normalization -*/ -package purell - -import ( - "bytes" - "fmt" - "net/url" - "regexp" - "sort" - "strconv" - "strings" - - "github.com/PuerkitoBio/urlesc" - "golang.org/x/net/idna" - "golang.org/x/text/unicode/norm" - "golang.org/x/text/width" -) - -// A set of normalization flags determines how a URL will -// be normalized. -type NormalizationFlags uint - -const ( - // Safe normalizations - FlagLowercaseScheme NormalizationFlags = 1 << iota // HTTP://host -> http://host, applied by default in Go1.1 - FlagLowercaseHost // http://HOST -> http://host - FlagUppercaseEscapes // http://host/t%ef -> http://host/t%EF - FlagDecodeUnnecessaryEscapes // http://host/t%41 -> http://host/tA - FlagEncodeNecessaryEscapes // http://host/!"#$ -> http://host/%21%22#$ - FlagRemoveDefaultPort // http://host:80 -> http://host - FlagRemoveEmptyQuerySeparator // http://host/path? -> http://host/path - - // Usually safe normalizations - FlagRemoveTrailingSlash // http://host/path/ -> http://host/path - FlagAddTrailingSlash // http://host/path -> http://host/path/ (should choose only one of these add/remove trailing slash flags) - FlagRemoveDotSegments // http://host/path/./a/b/../c -> http://host/path/a/c - - // Unsafe normalizations - FlagRemoveDirectoryIndex // http://host/path/index.html -> http://host/path/ - FlagRemoveFragment // http://host/path#fragment -> http://host/path - FlagForceHTTP // https://host -> http://host - FlagRemoveDuplicateSlashes // http://host/path//a///b -> http://host/path/a/b - FlagRemoveWWW // http://www.host/ -> http://host/ - FlagAddWWW // http://host/ -> http://www.host/ (should choose only one of these add/remove WWW flags) - FlagSortQuery // http://host/path?c=3&b=2&a=1&b=1 -> http://host/path?a=1&b=1&b=2&c=3 - - // Normalizations not in the wikipedia article, required to cover tests cases - // submitted by jehiah - FlagDecodeDWORDHost // http://1113982867 -> http://66.102.7.147 - FlagDecodeOctalHost // http://0102.0146.07.0223 -> http://66.102.7.147 - FlagDecodeHexHost // http://0x42660793 -> http://66.102.7.147 - FlagRemoveUnnecessaryHostDots // http://.host../path -> http://host/path - FlagRemoveEmptyPortSeparator // http://host:/path -> http://host/path - - // Convenience set of safe normalizations - FlagsSafe NormalizationFlags = FlagLowercaseHost | FlagLowercaseScheme | FlagUppercaseEscapes | FlagDecodeUnnecessaryEscapes | FlagEncodeNecessaryEscapes | FlagRemoveDefaultPort | FlagRemoveEmptyQuerySeparator - - // For convenience sets, "greedy" uses the "remove trailing slash" and "remove www. prefix" flags, - // while "non-greedy" uses the "add (or keep) the trailing slash" and "add www. prefix". - - // Convenience set of usually safe normalizations (includes FlagsSafe) - FlagsUsuallySafeGreedy NormalizationFlags = FlagsSafe | FlagRemoveTrailingSlash | FlagRemoveDotSegments - FlagsUsuallySafeNonGreedy NormalizationFlags = FlagsSafe | FlagAddTrailingSlash | FlagRemoveDotSegments - - // Convenience set of unsafe normalizations (includes FlagsUsuallySafe) - FlagsUnsafeGreedy NormalizationFlags = FlagsUsuallySafeGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagRemoveWWW | FlagSortQuery - FlagsUnsafeNonGreedy NormalizationFlags = FlagsUsuallySafeNonGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagAddWWW | FlagSortQuery - - // Convenience set of all available flags - FlagsAllGreedy = FlagsUnsafeGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator - FlagsAllNonGreedy = FlagsUnsafeNonGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator -) - -const ( - defaultHttpPort = ":80" - defaultHttpsPort = ":443" -) - -// Regular expressions used by the normalizations -var rxPort = regexp.MustCompile(`(:\d+)/?$`) -var rxDirIndex = regexp.MustCompile(`(^|/)((?:default|index)\.\w{1,4})$`) -var rxDupSlashes = regexp.MustCompile(`/{2,}`) -var rxDWORDHost = regexp.MustCompile(`^(\d+)((?:\.+)?(?:\:\d*)?)$`) -var rxOctalHost = regexp.MustCompile(`^(0\d*)\.(0\d*)\.(0\d*)\.(0\d*)((?:\.+)?(?:\:\d*)?)$`) -var rxHexHost = regexp.MustCompile(`^0x([0-9A-Fa-f]+)((?:\.+)?(?:\:\d*)?)$`) -var rxHostDots = regexp.MustCompile(`^(.+?)(:\d+)?$`) -var rxEmptyPort = regexp.MustCompile(`:+$`) - -// Map of flags to implementation function. -// FlagDecodeUnnecessaryEscapes has no action, since it is done automatically -// by parsing the string as an URL. Same for FlagUppercaseEscapes and FlagRemoveEmptyQuerySeparator. - -// Since maps have undefined traversing order, make a slice of ordered keys -var flagsOrder = []NormalizationFlags{ - FlagLowercaseScheme, - FlagLowercaseHost, - FlagRemoveDefaultPort, - FlagRemoveDirectoryIndex, - FlagRemoveDotSegments, - FlagRemoveFragment, - FlagForceHTTP, // Must be after remove default port (because https=443/http=80) - FlagRemoveDuplicateSlashes, - FlagRemoveWWW, - FlagAddWWW, - FlagSortQuery, - FlagDecodeDWORDHost, - FlagDecodeOctalHost, - FlagDecodeHexHost, - FlagRemoveUnnecessaryHostDots, - FlagRemoveEmptyPortSeparator, - FlagRemoveTrailingSlash, // These two (add/remove trailing slash) must be last - FlagAddTrailingSlash, -} - -// ... and then the map, where order is unimportant -var flags = map[NormalizationFlags]func(*url.URL){ - FlagLowercaseScheme: lowercaseScheme, - FlagLowercaseHost: lowercaseHost, - FlagRemoveDefaultPort: removeDefaultPort, - FlagRemoveDirectoryIndex: removeDirectoryIndex, - FlagRemoveDotSegments: removeDotSegments, - FlagRemoveFragment: removeFragment, - FlagForceHTTP: forceHTTP, - FlagRemoveDuplicateSlashes: removeDuplicateSlashes, - FlagRemoveWWW: removeWWW, - FlagAddWWW: addWWW, - FlagSortQuery: sortQuery, - FlagDecodeDWORDHost: decodeDWORDHost, - FlagDecodeOctalHost: decodeOctalHost, - FlagDecodeHexHost: decodeHexHost, - FlagRemoveUnnecessaryHostDots: removeUnncessaryHostDots, - FlagRemoveEmptyPortSeparator: removeEmptyPortSeparator, - FlagRemoveTrailingSlash: removeTrailingSlash, - FlagAddTrailingSlash: addTrailingSlash, -} - -// MustNormalizeURLString returns the normalized string, and panics if an error occurs. -// It takes an URL string as input, as well as the normalization flags. -func MustNormalizeURLString(u string, f NormalizationFlags) string { - result, e := NormalizeURLString(u, f) - if e != nil { - panic(e) - } - return result -} - -// NormalizeURLString returns the normalized string, or an error if it can't be parsed into an URL object. -// It takes an URL string as input, as well as the normalization flags. -func NormalizeURLString(u string, f NormalizationFlags) (string, error) { - parsed, err := url.Parse(u) - if err != nil { - return "", err - } - - if f&FlagLowercaseHost == FlagLowercaseHost { - parsed.Host = strings.ToLower(parsed.Host) - } - - // The idna package doesn't fully conform to RFC 5895 - // (https://tools.ietf.org/html/rfc5895), so we do it here. - // Taken from Go 1.8 cycle source, courtesy of bradfitz. - // TODO: Remove when (if?) idna package conforms to RFC 5895. - parsed.Host = width.Fold.String(parsed.Host) - parsed.Host = norm.NFC.String(parsed.Host) - if parsed.Host, err = idna.ToASCII(parsed.Host); err != nil { - return "", err - } - - return NormalizeURL(parsed, f), nil -} - -// NormalizeURL returns the normalized string. -// It takes a parsed URL object as input, as well as the normalization flags. -func NormalizeURL(u *url.URL, f NormalizationFlags) string { - for _, k := range flagsOrder { - if f&k == k { - flags[k](u) - } - } - return urlesc.Escape(u) -} - -func lowercaseScheme(u *url.URL) { - if len(u.Scheme) > 0 { - u.Scheme = strings.ToLower(u.Scheme) - } -} - -func lowercaseHost(u *url.URL) { - if len(u.Host) > 0 { - u.Host = strings.ToLower(u.Host) - } -} - -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) { - return "" - } - return val - }) - } -} - -func removeTrailingSlash(u *url.URL) { - if l := len(u.Path); l > 0 { - if strings.HasSuffix(u.Path, "/") { - u.Path = u.Path[:l-1] - } - } else if l = len(u.Host); l > 0 { - if strings.HasSuffix(u.Host, "/") { - u.Host = u.Host[:l-1] - } - } -} - -func addTrailingSlash(u *url.URL) { - if l := len(u.Path); l > 0 { - if !strings.HasSuffix(u.Path, "/") { - u.Path += "/" - } - } else if l = len(u.Host); l > 0 { - if !strings.HasSuffix(u.Host, "/") { - u.Host += "/" - } - } -} - -func removeDotSegments(u *url.URL) { - if len(u.Path) > 0 { - var dotFree []string - var lastIsDot bool - - sections := strings.Split(u.Path, "/") - for _, s := range sections { - if s == ".." { - if len(dotFree) > 0 { - dotFree = dotFree[:len(dotFree)-1] - } - } else if s != "." { - dotFree = append(dotFree, s) - } - lastIsDot = (s == "." || s == "..") - } - // Special case if host does not end with / and new path does not begin with / - u.Path = strings.Join(dotFree, "/") - if u.Host != "" && !strings.HasSuffix(u.Host, "/") && !strings.HasPrefix(u.Path, "/") { - u.Path = "/" + u.Path - } - // Special case if the last segment was a dot, make sure the path ends with a slash - if lastIsDot && !strings.HasSuffix(u.Path, "/") { - u.Path += "/" - } - } -} - -func removeDirectoryIndex(u *url.URL) { - if len(u.Path) > 0 { - u.Path = rxDirIndex.ReplaceAllString(u.Path, "$1") - } -} - -func removeFragment(u *url.URL) { - u.Fragment = "" -} - -func forceHTTP(u *url.URL) { - if strings.ToLower(u.Scheme) == "https" { - u.Scheme = "http" - } -} - -func removeDuplicateSlashes(u *url.URL) { - if len(u.Path) > 0 { - u.Path = rxDupSlashes.ReplaceAllString(u.Path, "/") - } -} - -func removeWWW(u *url.URL) { - if len(u.Host) > 0 && strings.HasPrefix(strings.ToLower(u.Host), "www.") { - u.Host = u.Host[4:] - } -} - -func addWWW(u *url.URL) { - if len(u.Host) > 0 && !strings.HasPrefix(strings.ToLower(u.Host), "www.") { - u.Host = "www." + u.Host - } -} - -func sortQuery(u *url.URL) { - q := u.Query() - - if len(q) > 0 { - arKeys := make([]string, len(q)) - i := 0 - for k := range q { - arKeys[i] = k - i++ - } - sort.Strings(arKeys) - buf := new(bytes.Buffer) - for _, k := range arKeys { - sort.Strings(q[k]) - for _, v := range q[k] { - if buf.Len() > 0 { - buf.WriteRune('&') - } - buf.WriteString(fmt.Sprintf("%s=%s", k, urlesc.QueryEscape(v))) - } - } - - // Rebuild the raw query string - u.RawQuery = buf.String() - } -} - -func decodeDWORDHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxDWORDHost.FindStringSubmatch(u.Host); len(matches) > 2 { - var parts [4]int64 - - dword, _ := strconv.ParseInt(matches[1], 10, 0) - for i, shift := range []uint{24, 16, 8, 0} { - parts[i] = dword >> shift & 0xFF - } - u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[2]) - } - } -} - -func decodeOctalHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxOctalHost.FindStringSubmatch(u.Host); len(matches) > 5 { - var parts [4]int64 - - for i := 1; i <= 4; i++ { - parts[i-1], _ = strconv.ParseInt(matches[i], 8, 0) - } - u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[5]) - } - } -} - -func decodeHexHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxHexHost.FindStringSubmatch(u.Host); len(matches) > 2 { - // Conversion is safe because of regex validation - parsed, _ := strconv.ParseInt(matches[1], 16, 0) - // Set host as DWORD (base 10) encoded host - u.Host = fmt.Sprintf("%d%s", parsed, matches[2]) - // The rest is the same as decoding a DWORD host - decodeDWORDHost(u) - } - } -} - -func removeUnncessaryHostDots(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxHostDots.FindStringSubmatch(u.Host); len(matches) > 1 { - // Trim the leading and trailing dots - u.Host = strings.Trim(matches[1], ".") - if len(matches) > 2 { - u.Host += matches[2] - } - } - } -} - -func removeEmptyPortSeparator(u *url.URL) { - if len(u.Host) > 0 { - u.Host = rxEmptyPort.ReplaceAllString(u.Host, "") - } -} diff --git a/vendor/github.com/PuerkitoBio/urlesc/.travis.yml b/vendor/github.com/PuerkitoBio/urlesc/.travis.yml deleted file mode 100644 index 478630e505..0000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: go - -go: - - 1.4 - - tip - -install: - - go build . - -script: - - go test -v diff --git a/vendor/github.com/PuerkitoBio/urlesc/LICENSE b/vendor/github.com/PuerkitoBio/urlesc/LICENSE deleted file mode 100644 index 7448756763..0000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -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/PuerkitoBio/urlesc/README.md b/vendor/github.com/PuerkitoBio/urlesc/README.md deleted file mode 100644 index bebe305e0d..0000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/README.md +++ /dev/null @@ -1,16 +0,0 @@ -urlesc [![Build Status](https://travis-ci.org/PuerkitoBio/urlesc.png?branch=master)](https://travis-ci.org/PuerkitoBio/urlesc) [![GoDoc](http://godoc.org/github.com/PuerkitoBio/urlesc?status.svg)](http://godoc.org/github.com/PuerkitoBio/urlesc) -====== - -Package urlesc implements query escaping as per RFC 3986. - -It contains some parts of the net/url package, modified so as to allow -some reserved characters incorrectly escaped by net/url (see [issue 5684](https://github.com/golang/go/issues/5684)). - -## Install - - go get github.com/PuerkitoBio/urlesc - -## License - -Go license (BSD-3-Clause) - diff --git a/vendor/github.com/PuerkitoBio/urlesc/urlesc.go b/vendor/github.com/PuerkitoBio/urlesc/urlesc.go deleted file mode 100644 index 1b84624594..0000000000 --- a/vendor/github.com/PuerkitoBio/urlesc/urlesc.go +++ /dev/null @@ -1,180 +0,0 @@ -// 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. - -// Package urlesc implements query escaping as per RFC 3986. -// It contains some parts of the net/url package, modified so as to allow -// some reserved characters incorrectly escaped by net/url. -// See https://github.com/golang/go/issues/5684 -package urlesc - -import ( - "bytes" - "net/url" - "strings" -) - -type encoding int - -const ( - encodePath encoding = 1 + iota - encodeUserPassword - encodeQueryComponent - encodeFragment -) - -// Return true if the specified character should be escaped when -// appearing in a URL string, according to RFC 3986. -func shouldEscape(c byte, mode encoding) bool { - // §2.3 Unreserved characters (alphanum) - if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' { - return false - } - - switch c { - case '-', '.', '_', '~': // §2.3 Unreserved characters (mark) - return false - - // §2.2 Reserved characters (reserved) - case ':', '/', '?', '#', '[', ']', '@', // gen-delims - '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': // sub-delims - // Different sections of the URL allow a few of - // the reserved characters to appear unescaped. - switch mode { - case encodePath: // §3.3 - // The RFC allows sub-delims and : @. - // '/', '[' and ']' can be used to assign meaning to individual path - // segments. This package only manipulates the path as a whole, - // so we allow those as well. That leaves only ? and # to escape. - return c == '?' || c == '#' - - case encodeUserPassword: // §3.2.1 - // The RFC allows : and sub-delims in - // userinfo. The parsing of userinfo treats ':' as special so we must escape - // all the gen-delims. - return c == ':' || c == '/' || c == '?' || c == '#' || c == '[' || c == ']' || c == '@' - - case encodeQueryComponent: // §3.4 - // The RFC allows / and ?. - return c != '/' && c != '?' - - case encodeFragment: // §4.1 - // The RFC text is silent but the grammar allows - // everything, so escape nothing but # - return c == '#' - } - } - - // Everything else must be escaped. - return true -} - -// QueryEscape escapes the string so it can be safely placed -// inside a URL query. -func QueryEscape(s string) string { - return escape(s, encodeQueryComponent) -} - -func escape(s string, mode encoding) string { - spaceCount, hexCount := 0, 0 - for i := 0; i < len(s); i++ { - c := s[i] - if shouldEscape(c, mode) { - if c == ' ' && mode == encodeQueryComponent { - spaceCount++ - } else { - hexCount++ - } - } - } - - if spaceCount == 0 && hexCount == 0 { - return s - } - - t := make([]byte, len(s)+2*hexCount) - j := 0 - for i := 0; i < len(s); i++ { - switch c := s[i]; { - case c == ' ' && mode == encodeQueryComponent: - t[j] = '+' - j++ - case shouldEscape(c, mode): - t[j] = '%' - t[j+1] = "0123456789ABCDEF"[c>>4] - t[j+2] = "0123456789ABCDEF"[c&15] - j += 3 - default: - t[j] = s[i] - j++ - } - } - return string(t) -} - -var uiReplacer = strings.NewReplacer( - "%21", "!", - "%27", "'", - "%28", "(", - "%29", ")", - "%2A", "*", -) - -// unescapeUserinfo unescapes some characters that need not to be escaped as per RFC3986. -func unescapeUserinfo(s string) string { - return uiReplacer.Replace(s) -} - -// Escape reassembles the URL into a valid URL string. -// The general form of the result is one of: -// -// scheme:opaque -// scheme://userinfo@host/path?query#fragment -// -// If u.Opaque is non-empty, String uses the first form; -// otherwise it uses the second form. -// -// In the second form, the following rules apply: -// - if u.Scheme is empty, scheme: is omitted. -// - if u.User is nil, userinfo@ is omitted. -// - if u.Host is empty, host/ is omitted. -// - if u.Scheme and u.Host are empty and u.User is nil, -// the entire scheme://userinfo@host/ is omitted. -// - if u.Host is non-empty and u.Path begins with a /, -// the form host/path does not add its own /. -// - if u.RawQuery is empty, ?query is omitted. -// - if u.Fragment is empty, #fragment is omitted. -func Escape(u *url.URL) string { - var buf bytes.Buffer - if u.Scheme != "" { - buf.WriteString(u.Scheme) - buf.WriteByte(':') - } - if u.Opaque != "" { - buf.WriteString(u.Opaque) - } else { - if u.Scheme != "" || u.Host != "" || u.User != nil { - buf.WriteString("//") - if ui := u.User; ui != nil { - buf.WriteString(unescapeUserinfo(ui.String())) - buf.WriteByte('@') - } - if h := u.Host; h != "" { - buf.WriteString(h) - } - } - if u.Path != "" && u.Path[0] != '/' && u.Host != "" { - buf.WriteByte('/') - } - buf.WriteString(escape(u.Path, encodePath)) - } - if u.RawQuery != "" { - buf.WriteByte('?') - buf.WriteString(u.RawQuery) - } - if u.Fragment != "" { - buf.WriteByte('#') - buf.WriteString(escape(u.Fragment, encodeFragment)) - } - return buf.String() -} diff --git a/vendor/github.com/cespare/xxhash/v2/README.md b/vendor/github.com/cespare/xxhash/v2/README.md index 8bf0e5b781..33c88305c4 100644 --- a/vendor/github.com/cespare/xxhash/v2/README.md +++ b/vendor/github.com/cespare/xxhash/v2/README.md @@ -70,3 +70,5 @@ benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$') - [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics) - [FreeCache](https://github.com/coocood/freecache) - [FastCache](https://github.com/VictoriaMetrics/fastcache) +- [Ristretto](https://github.com/dgraph-io/ristretto) +- [Badger](https://github.com/dgraph-io/badger) diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash.go b/vendor/github.com/cespare/xxhash/v2/xxhash.go index a9e0d45c9d..78bddf1cee 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash.go @@ -19,10 +19,13 @@ const ( // 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. +// contiguous array for the assembly code. var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5} // Digest implements hash.Hash64. +// +// Note that a zero-valued Digest is not ready to receive writes. +// Call Reset or create a Digest using New before calling other methods. type Digest struct { v1 uint64 v2 uint64 @@ -33,19 +36,31 @@ type Digest struct { n int // how much of mem is used } -// New creates a new Digest that computes the 64-bit xxHash algorithm. +// New creates a new Digest with a zero seed. func New() *Digest { + return NewWithSeed(0) +} + +// NewWithSeed creates a new Digest with the given seed. +func NewWithSeed(seed uint64) *Digest { var d Digest - d.Reset() + d.ResetWithSeed(seed) return &d } // Reset clears the Digest's state so that it can be reused. +// It uses a seed value of zero. func (d *Digest) Reset() { - d.v1 = primes[0] + prime2 - d.v2 = prime2 - d.v3 = 0 - d.v4 = -primes[0] + d.ResetWithSeed(0) +} + +// ResetWithSeed clears the Digest's state so that it can be reused. +// It uses the given seed to initialize the state. +func (d *Digest) ResetWithSeed(seed uint64) { + d.v1 = seed + prime1 + prime2 + d.v2 = seed + prime2 + d.v3 = seed + d.v4 = seed - prime1 d.total = 0 d.n = 0 } diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go index 9216e0a40c..78f95f2561 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go @@ -6,7 +6,7 @@ package xxhash -// Sum64 computes the 64-bit xxHash digest of b. +// Sum64 computes the 64-bit xxHash digest of b with a zero seed. // //go:noescape func Sum64(b []byte) uint64 diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go index 26df13bba4..118e49e819 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go @@ -3,7 +3,7 @@ package xxhash -// Sum64 computes the 64-bit xxHash digest of b. +// Sum64 computes the 64-bit xxHash digest of b with a zero seed. func Sum64(b []byte) uint64 { // A simpler version would be // d := New() diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go index e86f1b5fd8..05f5e7dfe7 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go @@ -5,7 +5,7 @@ package xxhash -// Sum64String computes the 64-bit xxHash digest of s. +// Sum64String computes the 64-bit xxHash digest of s with a zero seed. func Sum64String(s string) uint64 { return Sum64([]byte(s)) } diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go index 1c1638fd88..cf9d42aed5 100644 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go +++ b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go @@ -33,7 +33,7 @@ import ( // // See https://github.com/golang/go/issues/42739 for discussion. -// Sum64String computes the 64-bit xxHash digest of s. +// Sum64String computes the 64-bit xxHash digest of s with a zero seed. // It may be faster than Sum64([]byte(s)) by avoiding a copy. func Sum64String(s string) uint64 { b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)})) diff --git a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/LICENSE b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/LICENSE new file mode 100644 index 0000000000..e48e096345 --- /dev/null +++ b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/LICENSE @@ -0,0 +1,277 @@ +Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + +"Contributor" means any person or entity that Distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions Distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED 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. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. diff --git a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/doc.go b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/doc.go index cfb4b9aaf1..30b5c8edbf 100644 --- a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/doc.go +++ b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/doc.go @@ -1,3 +1,15 @@ +// +// Copyright (c) 2012-2021 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// + // Package v1alpha1 contains API Schema definitions for the che v1alpha1 API group // +k8s:deepcopy-gen=package,register // +groupName=che.eclipse.org diff --git a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/groupversion_info.go b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/groupversion_info.go index c4071bc462..7ea6b483e7 100644 --- a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/groupversion_info.go +++ b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/groupversion_info.go @@ -1,22 +1,18 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// +// Copyright (c) 2012-2021 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// // Package v1alpha1 contains API Schema definitions for the org v1alpha1 API group -//+kubebuilder:object:generate=true -//+groupName=che.eclipse.org +// +kubebuilder:object:generate=true +// +groupName=che.eclipse.org package v1alpha1 import ( diff --git a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/kubernetesimagepuller_types.go b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/kubernetesimagepuller_types.go index b46946d498..9e6281778a 100644 --- a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/kubernetesimagepuller_types.go +++ b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/kubernetesimagepuller_types.go @@ -1,18 +1,14 @@ -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// +// Copyright (c) 2012-2021 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// package v1alpha1 @@ -26,30 +22,48 @@ import ( // KubernetesImagePullerSpec defines the desired state of KubernetesImagePuller type KubernetesImagePullerSpec struct { - ConfigMapName string `json:"configMapName,omitempty"` - DaemonsetName string `json:"daemonsetName,omitempty"` - DeploymentName string `json:"deploymentName,omitempty"` - Images string `json:"images,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="ConfigMap name" + ConfigMapName string `json:"configMapName,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="DaemonSet name" + DaemonsetName string `json:"daemonsetName,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Deployment name" + DeploymentName string `json:"deploymentName,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Images to pull" + Images string `json:"images,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Caching internal hours" CachingIntervalHours string `json:"cachingIntervalHours,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Caching memory request" CachingMemoryRequest string `json:"cachingMemoryRequest,omitempty"` - CachingMemoryLimit string `json:"cachingMemoryLimit,omitempty"` - CachingCpuRequest string `json:"cachingCPURequest,omitempty"` - CachingCpuLimit string `json:"cachingCPULimit,omitempty"` - NodeSelector string `json:"nodeSelector,omitempty"` - ImagePullSecrets string `json:"imagePullSecrets,omitempty"` - Affinity string `json:"affinity,omitempty"` - ImagePullerImage string `json:"imagePullerImage,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Cache memory limit" + CachingMemoryLimit string `json:"cachingMemoryLimit,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Caching CPU request" + CachingCpuRequest string `json:"cachingCPURequest,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Caching CPU limit" + CachingCpuLimit string `json:"cachingCPULimit,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="NodeSelector" + NodeSelector string `json:"nodeSelector,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="ImagePull secrets" + ImagePullSecrets string `json:"imagePullSecrets,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Affinity" + Affinity string `json:"affinity,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="ImagePull name" + ImagePullerImage string `json:"imagePullerImage,omitempty"` } // KubernetesImagePullerStatus defines the observed state of KubernetesImagePuller type KubernetesImagePullerStatus struct { + // KubernetesImagePuller image in use. + // +operator-sdk:csv:customresourcedefinitions:type=status + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Image" + // +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors="urn:alm:descriptor:text" ImagePullerImage string `json:"imagePullerImage,omitempty"` } // KubernetesImagePuller is the Schema for the kubernetesimagepullers API -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status // +kubebuilder:resource:path=kubernetesimagepullers,scope=Namespaced +// +operator-sdk:csv:customresourcedefinitions:resources={{ConfigMap,v1},{Deployment,apps/v1},{DaemonSet,apps/v1}} type KubernetesImagePuller struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` diff --git a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/kubernetesimagepuller_webhook.go b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/kubernetesimagepuller_webhook.go new file mode 100644 index 0000000000..6c726afd7e --- /dev/null +++ b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/kubernetesimagepuller_webhook.go @@ -0,0 +1,46 @@ +// +// Copyright (c) 2012-2023 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// + +package v1alpha1 + +import ( + "context" + + ctrl "sigs.k8s.io/controller-runtime" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +func (r *KubernetesImagePuller) SetupWebhookWithManager(mgr ctrl.Manager) error { + mgr.GetWebhookServer().Register("/validate-che-eclipse-org-v1alpha1-kubernetesimagepuller", &webhook.Admission{Handler: &validationHandler{k8sClient: mgr.GetClient()}}) + return nil +} + +// +kubebuilder:webhook:path=/validate-che-eclipse-org-v1alpha1-kubernetesimagepuller,mutating=false,failurePolicy=fail,sideEffects=None,groups=che.eclipse.org,resources=kubernetesimagepullers,verbs=create,versions=v1alpha1,name=vkubernetesimagepuller.kb.io,admissionReviewVersions={v1,v1beta1} + +type validationHandler struct { + k8sClient client.Client +} + +func (v *validationHandler) Handle(ctx context.Context, req webhook.AdmissionRequest) webhook.AdmissionResponse { + imagePullers := &KubernetesImagePullerList{} + err := v.k8sClient.List(ctx, imagePullers, &client.ListOptions{Namespace: req.Namespace}) + if err != nil { + return webhook.Denied(err.Error()) + } + + if len(imagePullers.Items) > 0 { + return webhook.Denied("only one KubernetesImagePuller is allowed per namespace") + } + return webhook.Allowed("there are no KubernetesImagePuller resources in this namespace") +} diff --git a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/zz_generated.deepcopy.go index 37afb3e17e..bda604f220 100644 --- a/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/che-incubator/kubernetes-image-puller-operator/api/v1alpha1/zz_generated.deepcopy.go @@ -1,20 +1,17 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated -/* -Copyright 2021. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ +// +// Copyright (c) 2012-2023 Red Hat, Inc. +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// +// Contributors: +// Red Hat, Inc. - initial API and implementation +// // Code generated by controller-gen. DO NOT EDIT. diff --git a/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_container.go b/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_container.go index cb937cd33d..3e2775fdc2 100644 --- a/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_container.go +++ b/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/component_container.go @@ -105,7 +105,7 @@ type Container struct { DedicatedPod *bool `json:"dedicatedPod,omitempty"` } -//GetMountSources returns the value of the boolean property. If it's unset, the default value is true for all component types except plugins and components that set `dedicatedPod` to true. +// GetMountSources returns the value of the boolean property. If it's unset, the default value is true for all component types except plugins and components that set `dedicatedPod` to true. func (in *Container) GetMountSources() bool { if in.MountSources != nil { return *in.MountSources diff --git a/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/components.go b/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/components.go index 83631575cf..9409463c7a 100644 --- a/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/components.go +++ b/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/components.go @@ -41,7 +41,7 @@ const ( type BaseComponent struct { } -//+k8s:openapi-gen=true +// +k8s:openapi-gen=true type Component struct { // Mandatory name that allows referencing the component // from other elements (such as commands) or from an external diff --git a/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/doc.go b/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/doc.go index 04b838fb36..f2b13b5cb6 100644 --- a/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/doc.go +++ b/vendor/github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2/doc.go @@ -18,5 +18,5 @@ // +k8s:deepcopy-gen=package,register // +k8s:openapi-gen=true // +groupName=workspace.devfile.io -// +devfile:jsonschema:version=2.2.2 +// +devfile:jsonschema:version=2.3.0 package v1alpha2 diff --git a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go index b638306593..8087aad7e3 100644 --- a/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go +++ b/vendor/github.com/devfile/devworkspace-operator/pkg/constants/constants.go @@ -96,8 +96,3 @@ const ( // ProjectCloneDisable specifies that project cloning should be disabled. ProjectCloneDisable = "disable" ) - -const ( - // SelectedNodeAnnotation annotation is added to a PVC that is triggered by a scheduler to be dynamically provisioned. Its value is the name of the selected node. - SelectedNodeAnnotation = "volume.kubernetes.io/selected-node" -) diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md index 74a378157a..5edd5a7ca9 100644 --- a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md +++ b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md @@ -1,10 +1,30 @@ # Change history of go-restful -## [v3.9.0] - 20221-07-21 +## [v3.11.0] - 2023-08-19 + +- restored behavior as <= v3.9.0 with option to change path strategy using TrimRightSlashEnabled. + +## [v3.10.2] - 2023-03-09 - DO NOT USE + +- introduced MergePathStrategy to be able to revert behaviour of path concatenation to 3.9.0 + see comment in Readme how to customize this behaviour. + +## [v3.10.1] - 2022-11-19 - DO NOT USE + +- 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] - 20221-06-06 +## [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 diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md index 0625359dc4..95a05a0894 100644 --- a/vendor/github.com/emicklei/go-restful/v3/README.md +++ b/vendor/github.com/emicklei/go-restful/v3/README.md @@ -79,7 +79,7 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo - 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)) +- API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi)) - Panic recovery to produce HTTP 500, customizable using RecoverHandler(...) - Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...) - Configurable (trace) logging @@ -95,7 +95,7 @@ There are several hooks to customize the behavior of the go-restful package. - 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 .` +- Use the package variable `TrimRightSlashEnabled` (default true) to control the behavior of matching routes that end with a slash `/` ## Resources @@ -108,4 +108,4 @@ There are several hooks to customize the behavior of the go-restful package. Type ```git shortlog -s``` for a full list of contributors. -© 2012 - 2022, http://ernestmicklei.com. MIT License. Contributions are welcome. +© 2012 - 2023, http://ernestmicklei.com. MIT License. Contributions are welcome. diff --git a/vendor/github.com/emicklei/go-restful/v3/constants.go b/vendor/github.com/emicklei/go-restful/v3/constants.go index 203439c5e5..2328bde6c7 100644 --- a/vendor/github.com/emicklei/go-restful/v3/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/entity_accessors.go b/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go index 66dfc824f5..9808752acd 100644 --- a/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go +++ b/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go @@ -5,11 +5,18 @@ package restful // that can be found in the LICENSE file. import ( + "encoding/json" "encoding/xml" "strings" "sync" ) +var ( + MarshalIndent = json.MarshalIndent + NewDecoder = json.NewDecoder + NewEncoder = json.NewEncoder +) + // EntityReaderWriter can read and write values using an encoding such as JSON,XML. type EntityReaderWriter interface { // Read a serialized version of the value from the request. diff --git a/vendor/github.com/emicklei/go-restful/v3/json.go b/vendor/github.com/emicklei/go-restful/v3/json.go deleted file mode 100644 index 871165166a..0000000000 --- a/vendor/github.com/emicklei/go-restful/v3/json.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !jsoniter - -package restful - -import "encoding/json" - -var ( - MarshalIndent = json.MarshalIndent - NewDecoder = json.NewDecoder - NewEncoder = json.NewEncoder -) diff --git a/vendor/github.com/emicklei/go-restful/v3/jsoniter.go b/vendor/github.com/emicklei/go-restful/v3/jsoniter.go deleted file mode 100644 index 11b8f8ae7f..0000000000 --- a/vendor/github.com/emicklei/go-restful/v3/jsoniter.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build jsoniter - -package restful - -import "github.com/json-iterator/go" - -var ( - json = jsoniter.ConfigCompatibleWithStandardLibrary - MarshalIndent = json.MarshalIndent - NewDecoder = json.NewDecoder - NewEncoder = json.NewEncoder -) diff --git a/vendor/github.com/emicklei/go-restful/v3/request.go b/vendor/github.com/emicklei/go-restful/v3/request.go index 5725a07595..0020095e86 100644 --- a/vendor/github.com/emicklei/go-restful/v3/request.go +++ b/vendor/github.com/emicklei/go-restful/v3/request.go @@ -31,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 } @@ -48,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 diff --git a/vendor/github.com/emicklei/go-restful/v3/response.go b/vendor/github.com/emicklei/go-restful/v3/response.go index 8f0b56aa2d..a41a92cc2c 100644 --- a/vendor/github.com/emicklei/go-restful/v3/response.go +++ b/vendor/github.com/emicklei/go-restful/v3/response.go @@ -109,6 +109,9 @@ func (r *Response) EntityWriter() (EntityReaderWriter, bool) { 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 { diff --git a/vendor/github.com/emicklei/go-restful/v3/route.go b/vendor/github.com/emicklei/go-restful/v3/route.go index 193f4a6b01..306c44be77 100644 --- a/vendor/github.com/emicklei/go-restful/v3/route.go +++ b/vendor/github.com/emicklei/go-restful/v3/route.go @@ -40,7 +40,8 @@ type Route struct { ParameterDocs []*Parameter ResponseErrors map[int]ResponseError DefaultResponse *ResponseError - ReadSample, WriteSample interface{} // structs that model an example request or response payload + ReadSample, WriteSample interface{} // structs that model an example request or response payload + WriteSamples []interface{} // if more than one return types is possible (oneof) then this will contain multiple values // Extra information used to store custom information about the route. Metadata map[string]interface{} @@ -164,7 +165,13 @@ func tokenizePath(path string) []string { if "/" == path { return nil } - return strings.Split(strings.Trim(path, "/"), "/") + if TrimRightSlashEnabled { + // 3.9.0 + return strings.Split(strings.Trim(path, "/"), "/") + } else { + // 3.10.2 + return strings.Split(strings.TrimLeft(path, "/"), "/") + } } // for debugging @@ -176,3 +183,9 @@ func (r *Route) String() string { func (r *Route) EnableContentEncoding(enabled bool) { r.contentEncodingEnabled = &enabled } + +// TrimRightSlashEnabled controls whether +// - path on route building is using path.Join +// - the path of the incoming request is trimmed of its slash suffux. +// Value of true matches the behavior of <= 3.9.0 +var TrimRightSlashEnabled = true diff --git a/vendor/github.com/emicklei/go-restful/v3/route_builder.go b/vendor/github.com/emicklei/go-restful/v3/route_builder.go index 23641b6dd5..75168c12e1 100644 --- a/vendor/github.com/emicklei/go-restful/v3/route_builder.go +++ b/vendor/github.com/emicklei/go-restful/v3/route_builder.go @@ -7,6 +7,7 @@ package restful import ( "fmt" "os" + "path" "reflect" "runtime" "strings" @@ -30,27 +31,29 @@ type RouteBuilder struct { typeNameHandleFunc TypeNameHandleFunction // required // documentation - doc string - notes string - operation string - readSample, writeSample interface{} - parameters []*Parameter - errorMap map[int]ResponseError - defaultResponse *ResponseError - metadata map[string]interface{} - extensions map[string]interface{} - deprecated bool - contentEncodingEnabled *bool + doc string + notes string + operation string + readSample interface{} + writeSamples []interface{} + parameters []*Parameter + errorMap map[int]ResponseError + defaultResponse *ResponseError + metadata map[string]interface{} + extensions map[string]interface{} + deprecated bool + contentEncodingEnabled *bool } // 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) @@ -133,9 +136,9 @@ func (b RouteBuilder) ParameterNamed(name string) (p *Parameter) { return p } -// Writes tells what resource type will be written as the response payload. Optional. -func (b *RouteBuilder) Writes(sample interface{}) *RouteBuilder { - b.writeSample = sample +// Writes tells which one of the resource types will be written as the response payload. Optional. +func (b *RouteBuilder) Writes(samples ...interface{}) *RouteBuilder { + b.writeSamples = samples // oneof return b } @@ -340,19 +343,29 @@ func (b *RouteBuilder) Build() Route { ResponseErrors: b.errorMap, DefaultResponse: b.defaultResponse, ReadSample: b.readSample, - WriteSample: b.writeSample, + WriteSamples: b.writeSamples, Metadata: b.metadata, Deprecated: b.deprecated, contentEncodingEnabled: b.contentEncodingEnabled, allowedMethodsWithoutContentType: b.allowedMethodsWithoutContentType, } + // set WriteSample if one specified + if len(b.writeSamples) == 1 { + route.WriteSample = b.writeSamples[0] + } route.Extensions = b.extensions route.postBuild() return route } -func concatPath(path1, path2 string) string { - return strings.TrimRight(path1, "/") + "/" + strings.TrimLeft(path2, "/") +// merge two paths using the current (package global) merge path strategy. +func concatPath(rootPath, routePath string) string { + + if TrimRightSlashEnabled { + return strings.TrimRight(rootPath, "/") + "/" + strings.TrimLeft(routePath, "/") + } else { + return path.Join(rootPath, routePath) + } } var anonymousFuncCount int32 diff --git a/vendor/github.com/evanphx/json-patch/v5/LICENSE b/vendor/github.com/evanphx/json-patch/v5/LICENSE index 0eb9b72d84..df76d7d771 100644 --- a/vendor/github.com/evanphx/json-patch/v5/LICENSE +++ b/vendor/github.com/evanphx/json-patch/v5/LICENSE @@ -6,7 +6,7 @@ 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 +* 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 diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/decode.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/decode.go new file mode 100644 index 0000000000..e9bb0efe77 --- /dev/null +++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/decode.go @@ -0,0 +1,1385 @@ +// Copyright 2010 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. + +// Represents JSON data structure using native Go types: booleans, floats, +// strings, arrays, and maps. + +package json + +import ( + "encoding" + "encoding/base64" + "fmt" + "reflect" + "strconv" + "strings" + "sync" + "unicode" + "unicode/utf16" + "unicode/utf8" +) + +// Unmarshal parses the JSON-encoded data and stores the result +// in the value pointed to by v. If v is nil or not a pointer, +// Unmarshal returns an InvalidUnmarshalError. +// +// Unmarshal uses the inverse of the encodings that +// Marshal uses, allocating maps, slices, and pointers as necessary, +// with the following additional rules: +// +// To unmarshal JSON into a pointer, Unmarshal first handles the case of +// the JSON being the JSON literal null. In that case, Unmarshal sets +// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into +// the value pointed at by the pointer. If the pointer is nil, Unmarshal +// allocates a new value for it to point to. +// +// To unmarshal JSON into a value implementing the Unmarshaler interface, +// Unmarshal calls that value's UnmarshalJSON method, including +// when the input is a JSON null. +// Otherwise, if the value implements encoding.TextUnmarshaler +// and the input is a JSON quoted string, Unmarshal calls that value's +// UnmarshalText method with the unquoted form of the string. +// +// To unmarshal JSON into a struct, Unmarshal matches incoming object +// keys to the keys used by Marshal (either the struct field name or its tag), +// preferring an exact match but also accepting a case-insensitive match. By +// default, object keys which don't have a corresponding struct field are +// ignored (see Decoder.DisallowUnknownFields for an alternative). +// +// To unmarshal JSON into an interface value, +// Unmarshal stores one of these in the interface value: +// +// bool, for JSON booleans +// float64, for JSON numbers +// string, for JSON strings +// []interface{}, for JSON arrays +// map[string]interface{}, for JSON objects +// nil for JSON null +// +// To unmarshal a JSON array into a slice, Unmarshal resets the slice length +// to zero and then appends each element to the slice. +// As a special case, to unmarshal an empty JSON array into a slice, +// Unmarshal replaces the slice with a new empty slice. +// +// To unmarshal a JSON array into a Go array, Unmarshal decodes +// JSON array elements into corresponding Go array elements. +// If the Go array is smaller than the JSON array, +// the additional JSON array elements are discarded. +// If the JSON array is smaller than the Go array, +// the additional Go array elements are set to zero values. +// +// To unmarshal a JSON object into a map, Unmarshal first establishes a map to +// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal +// reuses the existing map, keeping existing entries. Unmarshal then stores +// key-value pairs from the JSON object into the map. The map's key type must +// 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. +// If no more serious errors are encountered, Unmarshal returns +// an UnmarshalTypeError describing the earliest such error. In any +// case, it's not guaranteed that all the remaining fields following +// the problematic one will be unmarshaled into the target object. +// +// 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 +// 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 any) error { + // Check for well-formedness. + // Avoids filling out half a data structure + // before discovering a JSON syntax error. + d := ds.Get().(*decodeState) + defer ds.Put(d) + //var d decodeState + d.useNumber = true + err := checkValid(data, &d.scan) + if err != nil { + return err + } + + d.init(data) + return d.unmarshal(v) +} + +var ds = sync.Pool{ + New: func() any { + return new(decodeState) + }, +} + +func UnmarshalWithKeys(data []byte, v any) ([]string, error) { + // Check for well-formedness. + // Avoids filling out half a data structure + // before discovering a JSON syntax error. + + d := ds.Get().(*decodeState) + defer ds.Put(d) + //var d decodeState + d.useNumber = true + err := checkValid(data, &d.scan) + if err != nil { + return nil, err + } + + d.init(data) + err = d.unmarshal(v) + if err != nil { + return nil, err + } + + return d.lastKeys, nil +} + +func UnmarshalValid(data []byte, v any) error { + // Check for well-formedness. + // Avoids filling out half a data structure + // before discovering a JSON syntax error. + d := ds.Get().(*decodeState) + defer ds.Put(d) + //var d decodeState + d.useNumber = true + + d.init(data) + return d.unmarshal(v) +} + +func UnmarshalValidWithKeys(data []byte, v any) ([]string, error) { + // Check for well-formedness. + // Avoids filling out half a data structure + // before discovering a JSON syntax error. + + d := ds.Get().(*decodeState) + defer ds.Put(d) + //var d decodeState + d.useNumber = true + + d.init(data) + err := d.unmarshal(v) + if err != nil { + return nil, err + } + + return d.lastKeys, nil +} + +// Unmarshaler is the interface implemented by types +// that can unmarshal a JSON description of themselves. +// The input can be assumed to be a valid encoding of +// a JSON value. UnmarshalJSON must copy the JSON data +// if it wishes to retain the data after returning. +// +// By convention, to approximate the behavior of Unmarshal itself, +// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op. +type Unmarshaler interface { + UnmarshalJSON([]byte) error +} + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError struct { + Value string // description of JSON value - "bool", "array", "number -5" + Type reflect.Type // type of Go value it could not be assigned to + Offset int64 // error occurred after reading Offset bytes + Struct string // name of the struct type containing the field + Field string // the full path from root node to the field +} + +func (e *UnmarshalTypeError) Error() string { + if e.Struct != "" || e.Field != "" { + return "json: cannot unmarshal " + e.Value + " into Go struct field " + e.Struct + "." + e.Field + " of type " + e.Type.String() + } + return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String() +} + +// An UnmarshalFieldError describes a JSON object key that +// led to an unexported (and therefore unwritable) struct field. +// +// Deprecated: No longer used; kept for compatibility. +type UnmarshalFieldError struct { + Key string + Type reflect.Type + Field reflect.StructField +} + +func (e *UnmarshalFieldError) Error() string { + return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String() +} + +// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. +// (The argument to Unmarshal must be a non-nil pointer.) +type InvalidUnmarshalError struct { + Type reflect.Type +} + +func (e *InvalidUnmarshalError) Error() string { + if e.Type == nil { + return "json: Unmarshal(nil)" + } + + 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 any) error { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Pointer || rv.IsNil() { + return &InvalidUnmarshalError{reflect.TypeOf(v)} + } + + d.scan.reset() + d.scanWhile(scanSkipSpace) + // We decode rv not rv.Elem because the Unmarshaler interface + // test must be applied at the top level of the value. + err := d.value(rv) + if err != nil { + return d.addErrorContext(err) + } + return d.savedError +} + +// A Number represents a JSON number literal. +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +// An errorContext provides context for type errors during decoding. +type errorContext struct { + Struct reflect.Type + FieldStack []string +} + +// decodeState represents the state while decoding a JSON value. +type decodeState struct { + data []byte + off int // next read offset in data + opcode int // last read result + scan scanner + errorContext *errorContext + savedError error + useNumber bool + disallowUnknownFields bool + lastKeys []string +} + +// readIndex returns the position of the last byte read. +func (d *decodeState) readIndex() int { + return d.off - 1 +} + +// phasePanicMsg is used as a panic message when we end up with something that +// shouldn't happen. It can indicate a bug in the JSON decoder, or that +// something is editing the data slice while the decoder executes. +const phasePanicMsg = "JSON decoder out of sync - data changing underfoot?" + +func (d *decodeState) init(data []byte) *decodeState { + d.data = data + d.off = 0 + d.savedError = nil + if d.errorContext != nil { + d.errorContext.Struct = nil + // Reuse the allocated space for the FieldStack slice. + d.errorContext.FieldStack = d.errorContext.FieldStack[:0] + } + return d +} + +// saveError saves the first err it is called with, +// for reporting at the end of the unmarshal. +func (d *decodeState) saveError(err error) { + if d.savedError == nil { + d.savedError = d.addErrorContext(err) + } +} + +// addErrorContext returns a new error enhanced with information from d.errorContext +func (d *decodeState) addErrorContext(err error) error { + if d.errorContext != nil && (d.errorContext.Struct != nil || len(d.errorContext.FieldStack) > 0) { + switch err := err.(type) { + case *UnmarshalTypeError: + err.Struct = d.errorContext.Struct.Name() + err.Field = strings.Join(d.errorContext.FieldStack, ".") + } + } + return err +} + +// skip scans to the end of what was started. +func (d *decodeState) skip() { + s, data, i := &d.scan, d.data, d.off + depth := len(s.parseState) + for { + op := s.step(s, data[i]) + i++ + if len(s.parseState) < depth { + d.off = i + d.opcode = op + return + } + } +} + +// scanNext processes the byte at d.data[d.off]. +func (d *decodeState) scanNext() { + if d.off < len(d.data) { + d.opcode = d.scan.step(&d.scan, d.data[d.off]) + d.off++ + } else { + d.opcode = d.scan.eof() + d.off = len(d.data) + 1 // mark processed EOF with len+1 + } +} + +// scanWhile processes bytes in d.data[d.off:] until it +// receives a scan code not equal to op. +func (d *decodeState) scanWhile(op int) { + s, data, i := &d.scan, d.data, d.off + for i < len(data) { + newOp := s.step(s, data[i]) + i++ + if newOp != op { + d.opcode = newOp + d.off = i + return + } + } + + d.off = len(data) + 1 // mark processed EOF with len+1 + d.opcode = d.scan.eof() +} + +// rescanLiteral is similar to scanWhile(scanContinue), but it specialises the +// common case where we're decoding a literal. The decoder scans the input +// twice, once for syntax errors and to check the length of the value, and the +// second to perform the decoding. +// +// Only in the second step do we use decodeState to tokenize literals, so we +// know there aren't any syntax errors. We can take advantage of that knowledge, +// and scan a literal's bytes much more quickly. +func (d *decodeState) rescanLiteral() { + data, i := d.data, d.off +Switch: + switch data[i-1] { + case '"': // string + for ; i < len(data); i++ { + switch data[i] { + case '\\': + i++ // escaped char + case '"': + i++ // tokenize the closing quote too + break Switch + } + } + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': // number + for ; i < len(data); i++ { + switch data[i] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '.', 'e', 'E', '+', '-': + default: + break Switch + } + } + case 't': // true + i += len("rue") + case 'f': // false + i += len("alse") + case 'n': // null + i += len("ull") + } + if i < len(data) { + d.opcode = stateEndValue(&d.scan, data[i]) + } else { + d.opcode = scanEnd + } + d.off = i + 1 +} + +// value consumes a JSON value from d.data[d.off-1:], decoding into v, and +// reads the following byte ahead. If v is invalid, the value is discarded. +// The first byte of the value has been read already. +func (d *decodeState) value(v reflect.Value) error { + switch d.opcode { + default: + panic(phasePanicMsg) + + case scanBeginArray: + if v.IsValid() { + if err := d.array(v); err != nil { + return err + } + } else { + d.skip() + } + d.scanNext() + + case scanBeginObject: + if v.IsValid() { + if err := d.object(v); err != nil { + return err + } + } else { + d.skip() + } + d.scanNext() + + case scanBeginLiteral: + // All bytes inside literal return scanContinue op code. + start := d.readIndex() + d.rescanLiteral() + + if v.IsValid() { + if err := d.literalStore(d.data[start:d.readIndex()], v, false); err != nil { + return err + } + } + } + return nil +} + +type unquotedValue struct{} + +// valueQuoted is like value but decodes a +// 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() any { + switch d.opcode { + default: + panic(phasePanicMsg) + + case scanBeginArray, scanBeginObject: + d.skip() + d.scanNext() + + case scanBeginLiteral: + v := d.literalInterface() + switch v.(type) { + case nil, string: + return v + } + } + return unquotedValue{} +} + +// 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 first settable pointer so it +// can be set to nil. +func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { + // Issue #24153 indicates that it is generally not a guaranteed property + // that you may round-trip a reflect.Value by calling Value.Addr().Elem() + // and expect the value to still be settable for values derived from + // unexported embedded struct fields. + // + // The logic below effectively does this when it first addresses the value + // (to satisfy possible pointer methods) and continues to dereference + // subsequent pointers as necessary. + // + // After the first round-trip, we set v back to the original value to + // preserve the original RW flags contained in reflect.Value. + v0 := v + haveAddr := false + + // 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.Pointer && v.Type().Name() != "" && v.CanAddr() { + haveAddr = true + 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.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) { + haveAddr = false + v = e + continue + } + } + + if v.Kind() != reflect.Pointer { + break + } + + if decodingNull && v.CanSet() { + break + } + + // Prevent infinite loop if v is an interface pointing to its own address: + // var v interface{} + // v = &v + if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v { + v = v.Elem() + break + } + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + if v.Type().NumMethod() > 0 && v.CanInterface() { + if u, ok := v.Interface().(Unmarshaler); ok { + return u, nil, reflect.Value{} + } + if !decodingNull { + if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { + return nil, u, reflect.Value{} + } + } + } + + if haveAddr { + v = v0 // restore original value after round-trip Value.Addr().Elem() + haveAddr = false + } else { + v = v.Elem() + } + } + return nil, nil, v +} + +// array consumes an array from d.data[d.off-1:], decoding into v. +// The first byte of the array ('[') has been read already. +func (d *decodeState) array(v reflect.Value) error { + // Check for unmarshaler. + u, ut, pv := indirect(v, false) + if u != nil { + start := d.readIndex() + d.skip() + return u.UnmarshalJSON(d.data[start:d.off]) + } + if ut != nil { + d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)}) + d.skip() + return nil + } + v = pv + + // Check type of target. + switch v.Kind() { + case reflect.Interface: + if v.NumMethod() == 0 { + // Decoding into nil interface? Switch to non-reflect code. + ai := d.arrayInterface() + v.Set(reflect.ValueOf(ai)) + return nil + } + // Otherwise it's invalid. + fallthrough + default: + d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)}) + d.skip() + return nil + case reflect.Array, reflect.Slice: + break + } + + i := 0 + for { + // Look ahead for ] - can only happen on first iteration. + d.scanWhile(scanSkipSpace) + if d.opcode == scanEndArray { + break + } + + // Get element of array, growing if necessary. + if v.Kind() == reflect.Slice { + // Grow slice if necessary + if i >= v.Cap() { + newcap := v.Cap() + v.Cap()/2 + if newcap < 4 { + newcap = 4 + } + newv := reflect.MakeSlice(v.Type(), v.Len(), newcap) + reflect.Copy(newv, v) + v.Set(newv) + } + if i >= v.Len() { + v.SetLen(i + 1) + } + } + + if i < v.Len() { + // Decode into element. + if err := d.value(v.Index(i)); err != nil { + return err + } + } else { + // Ran out of fixed array: skip. + if err := d.value(reflect.Value{}); err != nil { + return err + } + } + i++ + + // Next token must be , or ]. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode == scanEndArray { + break + } + if d.opcode != scanArrayValue { + panic(phasePanicMsg) + } + } + + if i < v.Len() { + if v.Kind() == reflect.Array { + // Array. Zero the rest. + z := reflect.Zero(v.Type().Elem()) + for ; i < v.Len(); i++ { + v.Index(i).Set(z) + } + } else { + v.SetLen(i) + } + } + if i == 0 && v.Kind() == reflect.Slice { + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + } + return nil +} + +var nullLiteral = []byte("null") +var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + +// object consumes an object from d.data[d.off-1:], decoding into v. +// The first byte ('{') of the object has been read already. +func (d *decodeState) object(v reflect.Value) error { + // Check for unmarshaler. + u, ut, pv := indirect(v, false) + if u != nil { + start := d.readIndex() + d.skip() + return u.UnmarshalJSON(d.data[start:d.off]) + } + if ut != nil { + d.saveError(&UnmarshalTypeError{Value: "object", Type: v.Type(), Offset: int64(d.off)}) + d.skip() + return nil + } + v = pv + t := v.Type() + + // Decoding into nil interface? Switch to non-reflect code. + if v.Kind() == reflect.Interface && v.NumMethod() == 0 { + oi := d.objectInterface() + v.Set(reflect.ValueOf(oi)) + return nil + } + + var fields structFields + + // Check type of target: + // struct or + // map[T1]T2 where T1 is string, an integer type, + // or an encoding.TextUnmarshaler + switch v.Kind() { + case reflect.Map: + // Map key must either have string kind, have an integer kind, + // or be an encoding.TextUnmarshaler. + switch t.Key().Kind() { + case reflect.String, + 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.PointerTo(t.Key()).Implements(textUnmarshalerType) { + d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)}) + d.skip() + return nil + } + } + if v.IsNil() { + v.Set(reflect.MakeMap(t)) + } + case reflect.Struct: + fields = cachedTypeFields(t) + // ok + default: + d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)}) + d.skip() + return nil + } + + var mapElem reflect.Value + var origErrorContext errorContext + if d.errorContext != nil { + origErrorContext = *d.errorContext + } + + var keys []string + + for { + // Read opening " of string key or closing }. + d.scanWhile(scanSkipSpace) + if d.opcode == scanEndObject { + // closing } - can only happen on first iteration. + break + } + if d.opcode != scanBeginLiteral { + panic(phasePanicMsg) + } + + // Read key. + start := d.readIndex() + d.rescanLiteral() + item := d.data[start:d.readIndex()] + key, ok := unquoteBytes(item) + if !ok { + panic(phasePanicMsg) + } + + keys = append(keys, string(key)) + + // Figure out field corresponding to key. + var subv reflect.Value + destring := false // whether the value is wrapped in a string to be decoded first + + if v.Kind() == reflect.Map { + elemType := t.Elem() + if !mapElem.IsValid() { + mapElem = reflect.New(elemType).Elem() + } else { + mapElem.Set(reflect.Zero(elemType)) + } + subv = mapElem + } else { + var f *field + if i, ok := fields.nameIndex[string(key)]; ok { + // Found an exact name match. + f = &fields.list[i] + } else { + // Fall back to the expensive case-insensitive + // linear search. + for i := range fields.list { + ff := &fields.list[i] + if ff.equalFold(ff.nameBytes, key) { + f = ff + break + } + } + } + if f != nil { + subv = v + destring = f.quoted + for _, i := range f.index { + if subv.Kind() == reflect.Pointer { + if subv.IsNil() { + // If a struct embeds a pointer to an unexported type, + // it is not possible to set a newly allocated value + // since the field is unexported. + // + // See https://golang.org/issue/21357 + if !subv.CanSet() { + d.saveError(fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", subv.Type().Elem())) + // Invalidate subv to ensure d.value(subv) skips over + // the JSON value without assigning it to subv. + subv = reflect.Value{} + destring = false + break + } + subv.Set(reflect.New(subv.Type().Elem())) + } + subv = subv.Elem() + } + subv = subv.Field(i) + } + if d.errorContext == nil { + d.errorContext = new(errorContext) + } + d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name) + d.errorContext.Struct = t + } else if d.disallowUnknownFields { + d.saveError(fmt.Errorf("json: unknown field %q", key)) + } + } + + // Read : before value. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode != scanObjectKey { + panic(phasePanicMsg) + } + d.scanWhile(scanSkipSpace) + + if destring { + switch qv := d.valueQuoted().(type) { + case nil: + if err := d.literalStore(nullLiteral, subv, false); err != nil { + return err + } + case string: + if err := d.literalStore([]byte(qv), subv, true); err != nil { + return err + } + default: + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type())) + } + } else { + if err := d.value(subv); err != nil { + return err + } + } + + // Write value back to map; + // if using struct, subv points into struct already. + if v.Kind() == reflect.Map { + kt := t.Key() + var kv reflect.Value + switch { + case reflect.PointerTo(kt).Implements(textUnmarshalerType): + kv = reflect.New(kt) + if err := d.literalStore(item, kv, true); err != nil { + return err + } + kv = kv.Elem() + case kt.Kind() == reflect.String: + kv = reflect.ValueOf(key).Convert(kt) + default: + switch kt.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + s := string(key) + n, err := strconv.ParseInt(s, 10, 64) + if err != nil || reflect.Zero(kt).OverflowInt(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)}) + break + } + kv = reflect.ValueOf(n).Convert(kt) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + s := string(key) + n, err := strconv.ParseUint(s, 10, 64) + if err != nil || reflect.Zero(kt).OverflowUint(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)}) + break + } + kv = reflect.ValueOf(n).Convert(kt) + default: + panic("json: Unexpected key type") // should never occur + } + } + if kv.IsValid() { + v.SetMapIndex(kv, subv) + } + } + + // Next token must be , or }. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.errorContext != nil { + // Reset errorContext to its original state. + // Keep the same underlying array for FieldStack, to reuse the + // space and avoid unnecessary allocs. + d.errorContext.FieldStack = d.errorContext.FieldStack[:len(origErrorContext.FieldStack)] + d.errorContext.Struct = origErrorContext.Struct + } + if d.opcode == scanEndObject { + break + } + if d.opcode != scanObjectValue { + panic(phasePanicMsg) + } + } + + if v.Kind() == reflect.Map { + d.lastKeys = keys + } + return nil +} + +// convertNumber converts the number literal s to a float64 or a Number +// depending on the setting of d.useNumber. +func (d *decodeState) convertNumber(s string) (any, error) { + if d.useNumber { + return Number(s), nil + } + f, err := strconv.ParseFloat(s, 64) + if err != nil { + return nil, &UnmarshalTypeError{Value: "number " + s, Type: reflect.TypeOf(0.0), Offset: int64(d.off)} + } + return f, nil +} + +var numberType = reflect.TypeOf(Number("")) + +// literalStore decodes a literal stored in item into v. +// +// fromQuoted indicates whether this literal came from unwrapping a +// string from the ",string" struct tag option. this is used only to +// produce more helpful error messages. +func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) error { + // Check for unmarshaler. + if len(item) == 0 { + //Empty string given + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + return nil + } + isNull := item[0] == 'n' // null + u, ut, pv := indirect(v, isNull) + if u != nil { + return u.UnmarshalJSON(item) + } + if ut != nil { + if item[0] != '"' { + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + return nil + } + val := "number" + switch item[0] { + case 'n': + val = "null" + case 't', 'f': + val = "bool" + } + d.saveError(&UnmarshalTypeError{Value: val, Type: v.Type(), Offset: int64(d.readIndex())}) + return nil + } + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) + } + panic(phasePanicMsg) + } + return ut.UnmarshalText(s) + } + + v = pv + + switch c := item[0]; c { + case 'n': // null + // The main parser checks that only true and false can reach here, + // but if this was a quoted string input, it could be anything. + if fromQuoted && string(item) != "null" { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + break + } + switch v.Kind() { + case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice: + v.Set(reflect.Zero(v.Type())) + // otherwise, ignore null for primitives/string + } + case 't', 'f': // true, false + value := item[0] == 't' + // The main parser checks that only true and false can reach here, + // but if this was a quoted string input, it could be anything. + if fromQuoted && string(item) != "true" && string(item) != "false" { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + break + } + switch v.Kind() { + default: + if fromQuoted { + d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) + } else { + d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())}) + } + case reflect.Bool: + v.SetBool(value) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(value)) + } else { + d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())}) + } + } + + case '"': // string + s, ok := unquoteBytes(item) + if !ok { + if fromQuoted { + return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) + } + panic(phasePanicMsg) + } + switch v.Kind() { + default: + d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())}) + case reflect.Slice: + if v.Type().Elem().Kind() != reflect.Uint8 { + d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + b := make([]byte, base64.StdEncoding.DecodedLen(len(s))) + n, err := base64.StdEncoding.Decode(b, s) + if err != nil { + d.saveError(err) + break + } + v.SetBytes(b[:n]) + case reflect.String: + if v.Type() == numberType && !isValidNumber(string(s)) { + return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item) + } + v.SetString(string(s)) + case reflect.Interface: + if v.NumMethod() == 0 { + v.Set(reflect.ValueOf(string(s))) + } else { + d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())}) + } + } + + default: // number + if c != '-' && (c < '0' || c > '9') { + if fromQuoted { + return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) + } + panic(phasePanicMsg) + } + s := string(item) + switch v.Kind() { + default: + if v.Kind() == reflect.String && v.Type() == numberType { + // s must be a valid number, because it's + // already been tokenized. + v.SetString(s) + break + } + if fromQuoted { + return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) + } + d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())}) + case reflect.Interface: + n, err := d.convertNumber(s) + if err != nil { + d.saveError(err) + break + } + if v.NumMethod() != 0 { + d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + v.Set(reflect.ValueOf(n)) + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n, err := strconv.ParseInt(s, 10, 64) + if err != nil || v.OverflowInt(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + v.SetInt(n) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n, err := strconv.ParseUint(s, 10, 64) + if err != nil || v.OverflowUint(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + v.SetUint(n) + + case reflect.Float32, reflect.Float64: + n, err := strconv.ParseFloat(s, v.Type().Bits()) + if err != nil || v.OverflowFloat(n) { + d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())}) + break + } + v.SetFloat(n) + } + } + return nil +} + +// The xxxInterface routines build up a value to be stored +// in an empty interface. They are not strictly necessary, +// but they avoid the weight of reflection in this common case. + +// valueInterface is like value but returns interface{} +func (d *decodeState) valueInterface() (val any) { + switch d.opcode { + default: + panic(phasePanicMsg) + case scanBeginArray: + val = d.arrayInterface() + d.scanNext() + case scanBeginObject: + val = d.objectInterface() + d.scanNext() + case scanBeginLiteral: + val = d.literalInterface() + } + return +} + +// arrayInterface is like array but returns []interface{}. +func (d *decodeState) arrayInterface() []any { + var v = make([]any, 0) + for { + // Look ahead for ] - can only happen on first iteration. + d.scanWhile(scanSkipSpace) + if d.opcode == scanEndArray { + break + } + + v = append(v, d.valueInterface()) + + // Next token must be , or ]. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode == scanEndArray { + break + } + if d.opcode != scanArrayValue { + panic(phasePanicMsg) + } + } + return v +} + +// objectInterface is like object but returns map[string]interface{}. +func (d *decodeState) objectInterface() map[string]any { + m := make(map[string]any) + for { + // Read opening " of string key or closing }. + d.scanWhile(scanSkipSpace) + if d.opcode == scanEndObject { + // closing } - can only happen on first iteration. + break + } + if d.opcode != scanBeginLiteral { + panic(phasePanicMsg) + } + + // Read string key. + start := d.readIndex() + d.rescanLiteral() + item := d.data[start:d.readIndex()] + key, ok := unquote(item) + if !ok { + panic(phasePanicMsg) + } + + // Read : before value. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode != scanObjectKey { + panic(phasePanicMsg) + } + d.scanWhile(scanSkipSpace) + + // Read value. + m[key] = d.valueInterface() + + // Next token must be , or }. + if d.opcode == scanSkipSpace { + d.scanWhile(scanSkipSpace) + } + if d.opcode == scanEndObject { + break + } + if d.opcode != scanObjectValue { + panic(phasePanicMsg) + } + } + return m +} + +// literalInterface consumes and returns a literal from d.data[d.off-1:] and +// it reads the following byte ahead. The first byte of the literal has been +// read already (that's how the caller knows it's a literal). +func (d *decodeState) literalInterface() any { + // All bytes inside literal return scanContinue op code. + start := d.readIndex() + d.rescanLiteral() + + item := d.data[start:d.readIndex()] + + switch c := item[0]; c { + case 'n': // null + return nil + + case 't', 'f': // true, false + return c == 't' + + case '"': // string + s, ok := unquote(item) + if !ok { + panic(phasePanicMsg) + } + return s + + default: // number + if c != '-' && (c < '0' || c > '9') { + panic(phasePanicMsg) + } + n, err := d.convertNumber(string(item)) + if err != nil { + d.saveError(err) + } + return n + } +} + +// getu4 decodes \uXXXX from the beginning of s, returning the hex value, +// or it returns -1. +func getu4(s []byte) rune { + if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { + return -1 + } + var r rune + for _, c := range s[2:6] { + switch { + case '0' <= c && c <= '9': + c = c - '0' + case 'a' <= c && c <= 'f': + c = c - 'a' + 10 + case 'A' <= c && c <= 'F': + c = c - 'A' + 10 + default: + return -1 + } + r = r*16 + rune(c) + } + return r +} + +// unquote converts a quoted JSON string literal s into an actual string t. +// The rules are different than for Go, so cannot use strconv.Unquote. +func unquote(s []byte) (t string, ok bool) { + s, ok = unquoteBytes(s) + t = string(s) + return +} + +func unquoteBytes(s []byte) (t []byte, ok bool) { + if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { + return + } + s = s[1 : len(s)-1] + + // Check for unusual characters. If there are none, + // then no unquoting is needed, so return a slice of the + // original bytes. + r := 0 + for r < len(s) { + c := s[r] + if c == '\\' || c == '"' || c < ' ' { + break + } + if c < utf8.RuneSelf { + r++ + continue + } + rr, size := utf8.DecodeRune(s[r:]) + if rr == utf8.RuneError && size == 1 { + break + } + r += size + } + if r == len(s) { + return s, true + } + + b := make([]byte, len(s)+2*utf8.UTFMax) + w := copy(b, s[0:r]) + for r < len(s) { + // Out of room? Can only happen if s is full of + // malformed UTF-8 and we're replacing each + // byte with RuneError. + if w >= len(b)-2*utf8.UTFMax { + nb := make([]byte, (len(b)+utf8.UTFMax)*2) + copy(nb, b[0:w]) + b = nb + } + switch c := s[r]; { + case c == '\\': + r++ + if r >= len(s) { + return + } + switch s[r] { + default: + return + case '"', '\\', '/', '\'': + b[w] = s[r] + r++ + w++ + case 'b': + b[w] = '\b' + r++ + w++ + case 'f': + b[w] = '\f' + r++ + w++ + case 'n': + b[w] = '\n' + r++ + w++ + case 'r': + b[w] = '\r' + r++ + w++ + case 't': + b[w] = '\t' + r++ + w++ + case 'u': + r-- + rr := getu4(s[r:]) + if rr < 0 { + return + } + r += 6 + if utf16.IsSurrogate(rr) { + rr1 := getu4(s[r:]) + if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { + // A valid pair; consume. + r += 6 + w += utf8.EncodeRune(b[w:], dec) + break + } + // Invalid surrogate; fall back to replacement rune. + rr = unicode.ReplacementChar + } + w += utf8.EncodeRune(b[w:], rr) + } + + // Quote, control characters are invalid. + case c == '"', c < ' ': + return + + // ASCII + case c < utf8.RuneSelf: + b[w] = c + r++ + w++ + + // Coerce to well-formed UTF-8. + default: + rr, size := utf8.DecodeRune(s[r:]) + r += size + w += utf8.EncodeRune(b[w:], rr) + } + } + return b[0:w], true +} diff --git a/vendor/github.com/evanphx/json-patch/v5/internal/json/encode.go b/vendor/github.com/evanphx/json-patch/v5/internal/json/encode.go new file mode 100644 index 0000000000..2e6eca4487 --- /dev/null +++ b/vendor/github.com/evanphx/json-patch/v5/internal/json/encode.go @@ -0,0 +1,1486 @@ +// Copyright 2010 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 encoding and decoding of JSON as defined in +// RFC 7159. The mapping between JSON and Go values is described +// in the documentation for the Marshal and Unmarshal functions. +// +// See "JSON and Go" for an introduction to this package: +// https://golang.org/doc/articles/json_and_go.html +package json + +import ( + "bytes" + "encoding" + "encoding/base64" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "unicode" + "unicode/utf8" +) + +// Marshal returns the JSON encoding of v. +// +// Marshal traverses the value v recursively. +// If an encountered value implements the Marshaler interface +// and is not a nil pointer, Marshal calls its MarshalJSON method +// to produce JSON. If no MarshalJSON method is present but the +// value implements encoding.TextMarshaler instead, Marshal calls +// its MarshalText method and encodes the result as a JSON string. +// The nil pointer exception is not strictly necessary +// but mimics a similar, necessary exception in the behavior of +// UnmarshalJSON. +// +// Otherwise, Marshal uses the following type-dependent default encodings: +// +// Boolean values encode as JSON booleans. +// +// Floating point, integer, and Number values encode as JSON numbers. +// +// String values encode as JSON strings coerced to valid UTF-8, +// replacing invalid bytes with the Unicode replacement rune. +// So that the JSON will be safe to embed inside HTML - -`) - w.WriteString("") - w.WriteString("

") - w.WriteString(html.EscapeString(name)) - w.WriteString("

") - w.WriteString(` -help -
- -

-Click on a value or block to toggle highlighting of that value/block -and its uses. (Values and blocks are highlighted by ID, and IDs of -dead items may be reused, so not all highlights necessarily correspond -to the clicked item.) -

- -

-Faded out values and blocks are dead code that has not been eliminated. -

- -

-Values printed in italics have a dependency cycle. -

- -

-CFG: Dashed edge is for unlikely branches. Blue color is for backward edges. -Edge with a dot means that this edge follows the order in which blocks were laidout. -

- -
-`) - w.WriteString("") - w.WriteString("") -} - -func (w *HTMLWriter) Close() { - if w == nil { - return - } - io.WriteString(w.w, "") - io.WriteString(w.w, "
") - io.WriteString(w.w, "") - io.WriteString(w.w, "") - w.w.Close() - fmt.Printf("dumped IR to %v\n", w.path) -} - -// WriteFunc writes f in a column headed by title. -// phase is used for collapsing columns and should be unique across the table. -func (w *HTMLWriter) WriteFunc(phase, title string, f *Function) { - if w == nil { - return - } - w.WriteColumn(phase, title, "", funcHTML(f, phase, w.dot)) -} - -// WriteColumn writes raw HTML in a column headed by title. -// It is intended for pre- and post-compilation log output. -func (w *HTMLWriter) WriteColumn(phase, title, class, html string) { - if w == nil { - return - } - id := strings.Replace(phase, " ", "-", -1) - // collapsed column - w.Printf("
%v
", id, phase) - - if class == "" { - w.Printf("", id) - } else { - w.Printf("", id, class) - } - w.WriteString("

" + title + "

") - w.WriteString(html) - w.WriteString("") -} - -func (w *HTMLWriter) Printf(msg string, v ...interface{}) { - if _, err := fmt.Fprintf(w.w, msg, v...); err != nil { - log.Fatalf("%v", err) - } -} - -func (w *HTMLWriter) WriteString(s string) { - if _, err := io.WriteString(w.w, s); err != nil { - log.Fatalf("%v", err) - } -} - -func valueHTML(v Node) string { - if v == nil { - return "<nil>" - } - // TODO: Using the value ID as the class ignores the fact - // that value IDs get recycled and that some values - // are transmuted into other values. - class := fmt.Sprintf("t%d", v.ID()) - var label string - switch v := v.(type) { - case *Function: - label = v.RelString(nil) - case *Builtin: - label = v.Name() - default: - label = class - } - return fmt.Sprintf("%s", class, label) -} - -func valueLongHTML(v Node) string { - // TODO: Any intra-value formatting? - // I'm wary of adding too much visual noise, - // but a little bit might be valuable. - // We already have visual noise in the form of punctuation - // maybe we could replace some of that with formatting. - s := fmt.Sprintf("", v.ID()) - - linenumber := "(?)" - if v.Pos().IsValid() { - line := v.Parent().Prog.Fset.Position(v.Pos()).Line - linenumber = fmt.Sprintf("(%d)", line, line) - } - - s += fmt.Sprintf("%s %s = %s", valueHTML(v), linenumber, opName(v)) - - if v, ok := v.(Value); ok { - s += " <" + html.EscapeString(v.Type().String()) + ">" - } - - switch v := v.(type) { - case *Parameter: - s += fmt.Sprintf(" {%s}", html.EscapeString(v.name)) - case *BinOp: - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String())) - case *UnOp: - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String())) - case *Extract: - name := v.Tuple.Type().(*types.Tuple).At(v.Index).Name() - s += fmt.Sprintf(" [%d] (%s)", v.Index, name) - case *Field: - st := v.X.Type().Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - s += fmt.Sprintf(" [%d] (%s)", v.Field, name) - case *FieldAddr: - st := deref(v.X.Type()).Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - - s += fmt.Sprintf(" [%d] (%s)", v.Field, name) - case *Recv: - s += fmt.Sprintf(" {%t}", v.CommaOk) - case *Call: - if v.Common().IsInvoke() { - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Common().Method.FullName())) - } - case *Const: - if v.Value == nil { - s += " {<nil>}" - } else { - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Value.String())) - } - case *Sigma: - s += fmt.Sprintf(" [#%s]", v.From) - } - for _, a := range v.Operands(nil) { - s += fmt.Sprintf(" %s", valueHTML(*a)) - } - - // OPT(dh): we're calling namedValues many times on the same function. - allNames := namedValues(v.Parent()) - var names []string - for name, values := range allNames { - for _, value := range values { - if v == value { - names = append(names, name.Name()) - break - } - } - } - if len(names) != 0 { - s += " (" + strings.Join(names, ", ") + ")" - } - - s += "" - return s -} - -func blockHTML(b *BasicBlock) string { - // TODO: Using the value ID as the class ignores the fact - // that value IDs get recycled and that some values - // are transmuted into other values. - s := html.EscapeString(b.String()) - return fmt.Sprintf("%s", s, s) -} - -func blockLongHTML(b *BasicBlock) string { - var kind string - var term Instruction - if len(b.Instrs) > 0 { - term = b.Control() - kind = opName(term) - } - // TODO: improve this for HTML? - s := fmt.Sprintf("%s", b.Index, kind) - - if term != nil { - ops := term.Operands(nil) - if len(ops) > 0 { - var ss []string - for _, op := range ops { - ss = append(ss, valueHTML(*op)) - } - s += " " + strings.Join(ss, ", ") - } - } - if len(b.Succs) > 0 { - s += " →" // right arrow - for _, c := range b.Succs { - s += " " + blockHTML(c) - } - } - return s -} - -func funcHTML(f *Function, phase string, dot *dotWriter) string { - buf := new(bytes.Buffer) - if dot != nil { - dot.writeFuncSVG(buf, phase, f) - } - fmt.Fprint(buf, "") - p := htmlFuncPrinter{w: buf} - fprintFunc(p, f) - - // fprintFunc(&buf, f) // TODO: HTML, not text,
for line breaks, etc. - fmt.Fprint(buf, "
") - return buf.String() -} - -type htmlFuncPrinter struct { - w io.Writer -} - -func (p htmlFuncPrinter) startBlock(b *BasicBlock, reachable bool) { - var dead string - if !reachable { - dead = "dead-block" - } - fmt.Fprintf(p.w, "
    ", b, dead) - fmt.Fprintf(p.w, "
  • %s:", blockHTML(b)) - if len(b.Preds) > 0 { - io.WriteString(p.w, " ←") // left arrow - for _, pred := range b.Preds { - fmt.Fprintf(p.w, " %s", blockHTML(pred)) - } - } - if len(b.Instrs) > 0 { - io.WriteString(p.w, ``) - } - io.WriteString(p.w, "
  • ") - if len(b.Instrs) > 0 { // start list of values - io.WriteString(p.w, "
  • ") - io.WriteString(p.w, "
      ") - } -} - -func (p htmlFuncPrinter) endBlock(b *BasicBlock) { - if len(b.Instrs) > 0 { // end list of values - io.WriteString(p.w, "
    ") - io.WriteString(p.w, "
  • ") - } - io.WriteString(p.w, "
  • ") - fmt.Fprint(p.w, blockLongHTML(b)) - io.WriteString(p.w, "
  • ") - io.WriteString(p.w, "
") -} - -func (p htmlFuncPrinter) value(v Node, live bool) { - var dead string - if !live { - dead = "dead-value" - } - fmt.Fprintf(p.w, "
  • ", dead) - fmt.Fprint(p.w, valueLongHTML(v)) - io.WriteString(p.w, "
  • ") -} - -func (p htmlFuncPrinter) startDepCycle() { - fmt.Fprintln(p.w, "") -} - -func (p htmlFuncPrinter) endDepCycle() { - fmt.Fprintln(p.w, "") -} - -func (p htmlFuncPrinter) named(n string, vals []Value) { - fmt.Fprintf(p.w, "
  • name %s: ", n) - for _, val := range vals { - fmt.Fprintf(p.w, "%s ", valueHTML(val)) - } - fmt.Fprintf(p.w, "
  • ") -} - -type dotWriter struct { - path string - broken bool -} - -// newDotWriter returns non-nil value when mask is valid. -// dotWriter will generate SVGs only for the phases specified in the mask. -// mask can contain following patterns and combinations of them: -// * - all of them; -// x-y - x through y, inclusive; -// x,y - x and y, but not the passes between. -func newDotWriter() *dotWriter { - path, err := exec.LookPath("dot") - if err != nil { - fmt.Println(err) - return nil - } - return &dotWriter{path: path} -} - -func (d *dotWriter) writeFuncSVG(w io.Writer, phase string, f *Function) { - if d.broken { - return - } - cmd := exec.Command(d.path, "-Tsvg") - pipe, err := cmd.StdinPipe() - if err != nil { - d.broken = true - fmt.Println(err) - return - } - buf := new(bytes.Buffer) - cmd.Stdout = buf - bufErr := new(bytes.Buffer) - cmd.Stderr = bufErr - err = cmd.Start() - if err != nil { - d.broken = true - fmt.Println(err) - return - } - fmt.Fprint(pipe, `digraph "" { margin=0; size="4,40"; ranksep=.2; `) - id := strings.Replace(phase, " ", "-", -1) - fmt.Fprintf(pipe, `id="g_graph_%s";`, id) - fmt.Fprintf(pipe, `node [style=filled,fillcolor=white,fontsize=16,fontname="Menlo,Times,serif",margin="0.01,0.03"];`) - fmt.Fprintf(pipe, `edge [fontsize=16,fontname="Menlo,Times,serif"];`) - for _, b := range f.Blocks { - layout := "" - fmt.Fprintf(pipe, `%v [label="%v%s\n%v",id="graph_node_%v_%v"];`, b, b, layout, b.Control().String(), id, b) - } - indexOf := make([]int, len(f.Blocks)) - for i, b := range f.Blocks { - indexOf[b.Index] = i - } - - // XXX - /* - ponums := make([]int32, len(f.Blocks)) - _ = postorderWithNumbering(f, ponums) - isBackEdge := func(from, to int) bool { - return ponums[from] <= ponums[to] - } - */ - isBackEdge := func(from, to int) bool { return false } - - for _, b := range f.Blocks { - for i, s := range b.Succs { - style := "solid" - color := "black" - arrow := "vee" - if isBackEdge(b.Index, s.Index) { - color = "blue" - } - fmt.Fprintf(pipe, `%v -> %v [label=" %d ",style="%s",color="%s",arrowhead="%s"];`, b, s, i, style, color, arrow) - } - } - fmt.Fprint(pipe, "}") - pipe.Close() - err = cmd.Wait() - if err != nil { - d.broken = true - fmt.Printf("dot: %v\n%v\n", err, bufErr.String()) - return - } - - svgID := "svg_graph_" + id - fmt.Fprintf(w, `
    `, svgID, svgID) - // For now, an awful hack: edit the html as it passes through - // our fingers, finding ' 0 { - fset = initial[0].Fset - } - - prog := ir.NewProgram(fset, mode) - if opts != nil { - prog.PrintFunc = opts.PrintFunc - } - - isInitial := make(map[*packages.Package]bool, len(initial)) - for _, p := range initial { - isInitial[p] = true - } - - irmap := make(map[*packages.Package]*ir.Package) - packages.Visit(initial, nil, func(p *packages.Package) { - if p.Types != nil && !p.IllTyped { - var files []*ast.File - if deps || isInitial[p] { - files = p.Syntax - } - irmap[p] = prog.CreatePackage(p.Types, files, p.TypesInfo, true) - } - }) - - var irpkgs []*ir.Package - for _, p := range initial { - irpkgs = append(irpkgs, irmap[p]) // may be nil - } - return prog, irpkgs -} - -// CreateProgram returns a new program in IR form, given a program -// loaded from source. An IR package is created for each transitively -// error-free package of lprog. -// -// Code for bodies of functions is not built until Build is called -// on the result. -// -// The mode parameter controls diagnostics and checking during IR construction. -// -// Deprecated: use golang.org/x/tools/go/packages and the Packages -// function instead; see ir.ExampleLoadPackages. -// -func CreateProgram(lprog *loader.Program, mode ir.BuilderMode) *ir.Program { - prog := ir.NewProgram(lprog.Fset, mode) - - for _, info := range lprog.AllPackages { - if info.TransitivelyErrorFree { - prog.CreatePackage(info.Pkg, info.Files, &info.Info, info.Importable) - } - } - - return prog -} - -// BuildPackage builds an IR program with IR for a single package. -// -// It populates pkg by type-checking the specified file ASTs. All -// dependencies are loaded using the importer specified by tc, which -// typically loads compiler export data; IR code cannot be built for -// those packages. BuildPackage then constructs an ir.Program with all -// dependency packages created, and builds and returns the IR package -// corresponding to pkg. -// -// The caller must have set pkg.Path() to the import path. -// -// The operation fails if there were any type-checking or import errors. -// -// See ../ir/example_test.go for an example. -// -func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, files []*ast.File, mode ir.BuilderMode) (*ir.Package, *types.Info, error) { - if fset == nil { - panic("no token.FileSet") - } - if pkg.Path() == "" { - panic("package has no import path") - } - - info := &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - } - if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil { - return nil, nil, err - } - - prog := ir.NewProgram(fset, mode) - - // Create IR packages for all imports. - // Order is not significant. - created := make(map[*types.Package]bool) - var createAll func(pkgs []*types.Package) - createAll = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !created[p] { - created[p] = true - prog.CreatePackage(p, nil, nil, true) - createAll(p.Imports()) - } - } - } - createAll(pkg.Imports()) - - // Create and build the primary package. - irpkg := prog.CreatePackage(pkg, files, info, false) - irpkg.Build() - return irpkg, info, nil -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/loops.go b/vendor/honnef.co/go/tools/go/ir/irutil/loops.go deleted file mode 100644 index 751cc680ba..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/loops.go +++ /dev/null @@ -1,54 +0,0 @@ -package irutil - -import "honnef.co/go/tools/go/ir" - -type Loop struct{ *ir.BlockSet } - -func FindLoops(fn *ir.Function) []Loop { - if fn.Blocks == nil { - return nil - } - tree := fn.DomPreorder() - var sets []Loop - for _, h := range tree { - for _, n := range h.Preds { - if !h.Dominates(n) { - continue - } - // n is a back-edge to h - // h is the loop header - if n == h { - set := Loop{ir.NewBlockSet(len(fn.Blocks))} - set.Add(n) - sets = append(sets, set) - continue - } - set := Loop{ir.NewBlockSet(len(fn.Blocks))} - set.Add(h) - set.Add(n) - for _, b := range allPredsBut(n, h, nil) { - set.Add(b) - } - sets = append(sets, set) - } - } - return sets -} - -func allPredsBut(b, but *ir.BasicBlock, list []*ir.BasicBlock) []*ir.BasicBlock { -outer: - for _, pred := range b.Preds { - if pred == but { - continue - } - for _, p := range list { - // TODO improve big-o complexity of this function - if pred == p { - continue outer - } - } - list = append(list, pred) - list = allPredsBut(pred, but, list) - } - return list -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/stub.go b/vendor/honnef.co/go/tools/go/ir/irutil/stub.go deleted file mode 100644 index 4311c7dbe9..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/stub.go +++ /dev/null @@ -1,32 +0,0 @@ -package irutil - -import ( - "honnef.co/go/tools/go/ir" -) - -// IsStub reports whether a function is a stub. A function is -// considered a stub if it has no instructions or if all it does is -// return a constant value. -func IsStub(fn *ir.Function) bool { - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - switch instr.(type) { - case *ir.Const: - // const naturally has no side-effects - case *ir.Panic: - // panic is a stub if it only uses constants - case *ir.Return: - // return is a stub if it only uses constants - case *ir.DebugRef: - case *ir.Jump: - // if there are no disallowed instructions, then we're - // only jumping to the exit block (or possibly - // somewhere else that's stubby?) - default: - // all other instructions are assumed to do actual work - return false - } - } - } - return true -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/switch.go b/vendor/honnef.co/go/tools/go/ir/irutil/switch.go deleted file mode 100644 index e7654e0081..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/switch.go +++ /dev/null @@ -1,264 +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 irutil - -// This file implements discovery of switch and type-switch constructs -// from low-level control flow. -// -// Many techniques exist for compiling a high-level switch with -// constant cases to efficient machine code. The optimal choice will -// depend on the data type, the specific case values, the code in the -// body of each case, and the hardware. -// Some examples: -// - a lookup table (for a switch that maps constants to constants) -// - a computed goto -// - a binary tree -// - a perfect hash -// - a two-level switch (to partition constant strings by their first byte). - -import ( - "bytes" - "fmt" - "go/token" - "go/types" - - "honnef.co/go/tools/go/ir" -) - -// A ConstCase represents a single constant comparison. -// It is part of a Switch. -type ConstCase struct { - Block *ir.BasicBlock // block performing the comparison - Body *ir.BasicBlock // body of the case - Value *ir.Const // case comparand -} - -// A TypeCase represents a single type assertion. -// It is part of a Switch. -type TypeCase struct { - Block *ir.BasicBlock // block performing the type assert - Body *ir.BasicBlock // body of the case - Type types.Type // case type - Binding ir.Value // value bound by this case -} - -// A Switch is a logical high-level control flow operation -// (a multiway branch) discovered by analysis of a CFG containing -// only if/else chains. It is not part of the ir.Instruction set. -// -// One of ConstCases and TypeCases has length >= 2; -// the other is nil. -// -// In a value switch, the list of cases may contain duplicate constants. -// A type switch may contain duplicate types, or types assignable -// to an interface type also in the list. -// TODO(adonovan): eliminate such duplicates. -// -type Switch struct { - Start *ir.BasicBlock // block containing start of if/else chain - X ir.Value // the switch operand - ConstCases []ConstCase // ordered list of constant comparisons - TypeCases []TypeCase // ordered list of type assertions - Default *ir.BasicBlock // successor if all comparisons fail -} - -func (sw *Switch) String() string { - // We represent each block by the String() of its - // first Instruction, e.g. "print(42:int)". - var buf bytes.Buffer - if sw.ConstCases != nil { - fmt.Fprintf(&buf, "switch %s {\n", sw.X.Name()) - for _, c := range sw.ConstCases { - fmt.Fprintf(&buf, "case %s: %s\n", c.Value.Name(), c.Body.Instrs[0]) - } - } else { - fmt.Fprintf(&buf, "switch %s.(type) {\n", sw.X.Name()) - for _, c := range sw.TypeCases { - fmt.Fprintf(&buf, "case %s %s: %s\n", - c.Binding.Name(), c.Type, c.Body.Instrs[0]) - } - } - if sw.Default != nil { - fmt.Fprintf(&buf, "default: %s\n", sw.Default.Instrs[0]) - } - fmt.Fprintf(&buf, "}") - return buf.String() -} - -// Switches examines the control-flow graph of fn and returns the -// set of inferred value and type switches. A value switch tests an -// ir.Value for equality against two or more compile-time constant -// values. Switches involving link-time constants (addresses) are -// ignored. A type switch type-asserts an ir.Value against two or -// more types. -// -// The switches are returned in dominance order. -// -// The resulting switches do not necessarily correspond to uses of the -// 'switch' keyword in the source: for example, a single source-level -// switch statement with non-constant cases may result in zero, one or -// many Switches, one per plural sequence of constant cases. -// Switches may even be inferred from if/else- or goto-based control flow. -// (In general, the control flow constructs of the source program -// cannot be faithfully reproduced from the IR.) -// -func Switches(fn *ir.Function) []Switch { - // Traverse the CFG in dominance order, so we don't - // enter an if/else-chain in the middle. - var switches []Switch - seen := make(map[*ir.BasicBlock]bool) // TODO(adonovan): opt: use ir.blockSet - for _, b := range fn.DomPreorder() { - if x, k := isComparisonBlock(b); x != nil { - // Block b starts a switch. - sw := Switch{Start: b, X: x} - valueSwitch(&sw, k, seen) - if len(sw.ConstCases) > 1 { - switches = append(switches, sw) - } - } - - if y, x, T := isTypeAssertBlock(b); y != nil { - // Block b starts a type switch. - sw := Switch{Start: b, X: x} - typeSwitch(&sw, y, T, seen) - if len(sw.TypeCases) > 1 { - switches = append(switches, sw) - } - } - } - return switches -} - -func isSameX(x1 ir.Value, x2 ir.Value) bool { - if x1 == x2 { - return true - } - if x2, ok := x2.(*ir.Sigma); ok { - return isSameX(x1, x2.X) - } - return false -} - -func valueSwitch(sw *Switch, k *ir.Const, seen map[*ir.BasicBlock]bool) { - b := sw.Start - x := sw.X - for isSameX(sw.X, x) { - if seen[b] { - break - } - seen[b] = true - - sw.ConstCases = append(sw.ConstCases, ConstCase{ - Block: b, - Body: b.Succs[0], - Value: k, - }) - b = b.Succs[1] - n := 0 - for _, instr := range b.Instrs { - switch instr.(type) { - case *ir.If, *ir.BinOp: - n++ - case *ir.Sigma, *ir.Phi, *ir.DebugRef: - default: - n += 1000 - } - } - if n != 2 { - // Block b contains not just 'if x == k' and σ/ϕ nodes, - // so it may have side effects that - // make it unsafe to elide. - break - } - if len(b.Preds) != 1 { - // Block b has multiple predecessors, - // so it cannot be treated as a case. - break - } - x, k = isComparisonBlock(b) - } - sw.Default = b -} - -func typeSwitch(sw *Switch, y ir.Value, T types.Type, seen map[*ir.BasicBlock]bool) { - b := sw.Start - x := sw.X - for isSameX(sw.X, x) { - if seen[b] { - break - } - seen[b] = true - - sw.TypeCases = append(sw.TypeCases, TypeCase{ - Block: b, - Body: b.Succs[0], - Type: T, - Binding: y, - }) - b = b.Succs[1] - n := 0 - for _, instr := range b.Instrs { - switch instr.(type) { - case *ir.TypeAssert, *ir.Extract, *ir.If: - n++ - case *ir.Sigma, *ir.Phi: - default: - n += 1000 - } - } - if n != 4 { - // Block b contains not just - // {TypeAssert; Extract #0; Extract #1; If} - // so it may have side effects that - // make it unsafe to elide. - break - } - if len(b.Preds) != 1 { - // Block b has multiple predecessors, - // so it cannot be treated as a case. - break - } - y, x, T = isTypeAssertBlock(b) - } - sw.Default = b -} - -// isComparisonBlock returns the operands (v, k) if a block ends with -// a comparison v==k, where k is a compile-time constant. -// -func isComparisonBlock(b *ir.BasicBlock) (v ir.Value, k *ir.Const) { - if n := len(b.Instrs); n >= 2 { - if i, ok := b.Instrs[n-1].(*ir.If); ok { - if binop, ok := i.Cond.(*ir.BinOp); ok && binop.Block() == b && binop.Op == token.EQL { - if k, ok := binop.Y.(*ir.Const); ok { - return binop.X, k - } - if k, ok := binop.X.(*ir.Const); ok { - return binop.Y, k - } - } - } - } - return -} - -// isTypeAssertBlock returns the operands (y, x, T) if a block ends with -// a type assertion "if y, ok := x.(T); ok {". -// -func isTypeAssertBlock(b *ir.BasicBlock) (y, x ir.Value, T types.Type) { - if n := len(b.Instrs); n >= 4 { - if i, ok := b.Instrs[n-1].(*ir.If); ok { - if ext1, ok := i.Cond.(*ir.Extract); ok && ext1.Block() == b && ext1.Index == 1 { - if ta, ok := ext1.Tuple.(*ir.TypeAssert); ok && ta.Block() == b { - // hack: relies upon instruction ordering. - if ext0, ok := b.Instrs[n-3].(*ir.Extract); ok { - return ext0, ta.X, ta.AssertedType - } - } - } - } - } - return -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/terminates.go b/vendor/honnef.co/go/tools/go/ir/irutil/terminates.go deleted file mode 100644 index 84e7503bb3..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/terminates.go +++ /dev/null @@ -1,70 +0,0 @@ -package irutil - -import ( - "go/types" - - "honnef.co/go/tools/go/ir" -) - -// Terminates reports whether fn is supposed to return, that is if it -// has at least one theoretic path that returns from the function. -// Explicit panics do not count as terminating. -func Terminates(fn *ir.Function) bool { - if fn.Blocks == nil { - // assuming that a function terminates is the conservative - // choice - return true - } - - for _, block := range fn.Blocks { - if _, ok := block.Control().(*ir.Return); ok { - if len(block.Preds) == 0 { - return true - } - for _, pred := range block.Preds { - switch ctrl := pred.Control().(type) { - case *ir.Panic: - // explicit panics do not count as terminating - case *ir.If: - // Check if we got here by receiving from a closed - // time.Tick channel – this cannot happen at - // runtime and thus doesn't constitute termination - iff := ctrl - if !ok { - return true - } - ex, ok := iff.Cond.(*ir.Extract) - if !ok { - return true - } - if ex.Index != 1 { - return true - } - recv, ok := ex.Tuple.(*ir.Recv) - if !ok { - return true - } - call, ok := recv.Chan.(*ir.Call) - if !ok { - return true - } - fn, ok := call.Common().Value.(*ir.Function) - if !ok { - return true - } - fn2, ok := fn.Object().(*types.Func) - if !ok { - return true - } - if fn2.FullName() != "time.Tick" { - return true - } - default: - // we've reached the exit block - return true - } - } - } - } - return false -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/util.go b/vendor/honnef.co/go/tools/go/ir/irutil/util.go deleted file mode 100644 index dace40be0e..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/util.go +++ /dev/null @@ -1,124 +0,0 @@ -package irutil - -import ( - "go/types" - "strings" - - "honnef.co/go/tools/go/ir" - "honnef.co/go/tools/go/types/typeutil" -) - -func Reachable(from, to *ir.BasicBlock) bool { - if from == to { - return true - } - if from.Dominates(to) { - return true - } - - found := false - Walk(from, func(b *ir.BasicBlock) bool { - if b == to { - found = true - return false - } - return true - }) - return found -} - -func Walk(b *ir.BasicBlock, fn func(*ir.BasicBlock) bool) { - seen := map[*ir.BasicBlock]bool{} - wl := []*ir.BasicBlock{b} - for len(wl) > 0 { - b := wl[len(wl)-1] - wl = wl[:len(wl)-1] - if seen[b] { - continue - } - seen[b] = true - if !fn(b) { - continue - } - wl = append(wl, b.Succs...) - } -} - -func Vararg(x *ir.Slice) ([]ir.Value, bool) { - var out []ir.Value - slice, ok := x.X.(*ir.Alloc) - if !ok { - return nil, false - } - for _, ref := range *slice.Referrers() { - if ref == x { - continue - } - if ref.Block() != x.Block() { - return nil, false - } - idx, ok := ref.(*ir.IndexAddr) - if !ok { - return nil, false - } - if len(*idx.Referrers()) != 1 { - return nil, false - } - store, ok := (*idx.Referrers())[0].(*ir.Store) - if !ok { - return nil, false - } - out = append(out, store.Val) - } - return out, true -} - -func CallName(call *ir.CallCommon) string { - if call.IsInvoke() { - return "" - } - switch v := call.Value.(type) { - case *ir.Function: - fn, ok := v.Object().(*types.Func) - if !ok { - return "" - } - return typeutil.FuncName(fn) - case *ir.Builtin: - return v.Name() - } - return "" -} - -func IsCallTo(call *ir.CallCommon, name string) bool { return CallName(call) == name } - -func IsCallToAny(call *ir.CallCommon, names ...string) bool { - q := CallName(call) - for _, name := range names { - if q == name { - return true - } - } - return false -} - -func FilterDebug(instr []ir.Instruction) []ir.Instruction { - var out []ir.Instruction - for _, ins := range instr { - if _, ok := ins.(*ir.DebugRef); !ok { - out = append(out, ins) - } - } - return out -} - -func IsExample(fn *ir.Function) bool { - if !strings.HasPrefix(fn.Name(), "Example") { - return false - } - f := fn.Prog.Fset.File(fn.Pos()) - if f == nil { - return false - } - return strings.HasSuffix(f.Name(), "_test.go") -} diff --git a/vendor/honnef.co/go/tools/go/ir/irutil/visit.go b/vendor/honnef.co/go/tools/go/ir/irutil/visit.go deleted file mode 100644 index f6d0503ddd..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/irutil/visit.go +++ /dev/null @@ -1,79 +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 irutil - -import "honnef.co/go/tools/go/ir" - -// This file defines utilities for visiting the IR of -// a Program. -// -// TODO(adonovan): test coverage. - -// AllFunctions finds and returns the set of functions potentially -// needed by program prog, as determined by a simple linker-style -// reachability algorithm starting from the members and method-sets of -// each package. The result may include anonymous functions and -// synthetic wrappers. -// -// Precondition: all packages are built. -// -func AllFunctions(prog *ir.Program) map[*ir.Function]bool { - visit := visitor{ - prog: prog, - seen: make(map[*ir.Function]bool), - } - visit.program() - return visit.seen -} - -type visitor struct { - prog *ir.Program - seen map[*ir.Function]bool -} - -func (visit *visitor) program() { - for _, pkg := range visit.prog.AllPackages() { - for _, mem := range pkg.Members { - if fn, ok := mem.(*ir.Function); ok { - visit.function(fn) - } - } - } - for _, T := range visit.prog.RuntimeTypes() { - mset := visit.prog.MethodSets.MethodSet(T) - for i, n := 0, mset.Len(); i < n; i++ { - visit.function(visit.prog.MethodValue(mset.At(i))) - } - } -} - -func (visit *visitor) function(fn *ir.Function) { - if !visit.seen[fn] { - visit.seen[fn] = true - var buf [10]*ir.Value // avoid alloc in common case - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - for _, op := range instr.Operands(buf[:0]) { - if fn, ok := (*op).(*ir.Function); ok { - visit.function(fn) - } - } - } - } - } -} - -// MainPackages returns the subset of the specified packages -// named "main" that define a main function. -// The result may include synthetic "testmain" packages. -func MainPackages(pkgs []*ir.Package) []*ir.Package { - var mains []*ir.Package - for _, pkg := range pkgs { - if pkg.Pkg.Name() == "main" && pkg.Func("main") != nil { - mains = append(mains, pkg) - } - } - return mains -} diff --git a/vendor/honnef.co/go/tools/go/ir/lift.go b/vendor/honnef.co/go/tools/go/ir/lift.go deleted file mode 100644 index 71d5c8cb06..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/lift.go +++ /dev/null @@ -1,1063 +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 ir - -// This file defines the lifting pass which tries to "lift" Alloc -// cells (new/local variables) into SSA registers, replacing loads -// with the dominating stored value, eliminating loads and stores, and -// inserting φ- and σ-nodes as needed. - -// Cited papers and resources: -// -// Ron Cytron et al. 1991. Efficiently computing SSA form... -// http://doi.acm.org/10.1145/115372.115320 -// -// Cooper, Harvey, Kennedy. 2001. A Simple, Fast Dominance Algorithm. -// Software Practice and Experience 2001, 4:1-10. -// http://www.hipersoft.rice.edu/grads/publications/dom14.pdf -// -// Daniel Berlin, llvmdev mailing list, 2012. -// http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-January/046638.html -// (Be sure to expand the whole thread.) -// -// C. Scott Ananian. 1997. The static single information form. -// -// Jeremy Singer. 2006. Static program analysis based on virtual register renaming. - -// TODO(adonovan): opt: there are many optimizations worth evaluating, and -// the conventional wisdom for SSA construction is that a simple -// algorithm well engineered often beats those of better asymptotic -// complexity on all but the most egregious inputs. -// -// Danny Berlin suggests that the Cooper et al. algorithm for -// computing the dominance frontier is superior to Cytron et al. -// Furthermore he recommends that rather than computing the DF for the -// whole function then renaming all alloc cells, it may be cheaper to -// compute the DF for each alloc cell separately and throw it away. -// -// Consider exploiting liveness information to avoid creating dead -// φ-nodes which we then immediately remove. -// -// Also see many other "TODO: opt" suggestions in the code. - -import ( - "fmt" - "go/types" - "os" -) - -// If true, show diagnostic information at each step of lifting. -// Very verbose. -const debugLifting = false - -// domFrontier maps each block to the set of blocks in its dominance -// frontier. The outer slice is conceptually a map keyed by -// Block.Index. The inner slice is conceptually a set, possibly -// containing duplicates. -// -// TODO(adonovan): opt: measure impact of dups; consider a packed bit -// representation, e.g. big.Int, and bitwise parallel operations for -// the union step in the Children loop. -// -// domFrontier's methods mutate the slice's elements but not its -// length, so their receivers needn't be pointers. -// -type domFrontier [][]*BasicBlock - -func (df domFrontier) add(u, v *BasicBlock) { - df[u.Index] = append(df[u.Index], v) -} - -// build builds the dominance frontier df for the dominator tree of -// fn, using the algorithm found in A Simple, Fast Dominance -// Algorithm, Figure 5. -// -// TODO(adonovan): opt: consider Berlin approach, computing pruned SSA -// by pruning the entire IDF computation, rather than merely pruning -// the DF -> IDF step. -func (df domFrontier) build(fn *Function) { - for _, b := range fn.Blocks { - if len(b.Preds) >= 2 { - for _, p := range b.Preds { - runner := p - for runner != b.dom.idom { - df.add(runner, b) - runner = runner.dom.idom - } - } - } - } -} - -func buildDomFrontier(fn *Function) domFrontier { - df := make(domFrontier, len(fn.Blocks)) - df.build(fn) - return df -} - -type postDomFrontier [][]*BasicBlock - -func (rdf postDomFrontier) add(u, v *BasicBlock) { - rdf[u.Index] = append(rdf[u.Index], v) -} - -func (rdf postDomFrontier) build(fn *Function) { - for _, b := range fn.Blocks { - if len(b.Succs) >= 2 { - for _, s := range b.Succs { - runner := s - for runner != b.pdom.idom { - rdf.add(runner, b) - runner = runner.pdom.idom - } - } - } - } -} - -func buildPostDomFrontier(fn *Function) postDomFrontier { - rdf := make(postDomFrontier, len(fn.Blocks)) - rdf.build(fn) - return rdf -} - -func removeInstr(refs []Instruction, instr Instruction) []Instruction { - i := 0 - for _, ref := range refs { - if ref == instr { - continue - } - refs[i] = ref - i++ - } - for j := i; j != len(refs); j++ { - refs[j] = nil // aid GC - } - return refs[:i] -} - -func clearInstrs(instrs []Instruction) { - for i := range instrs { - instrs[i] = nil - } -} - -// lift replaces local and new Allocs accessed only with -// load/store by IR registers, inserting φ- and σ-nodes where necessary. -// The result is a program in pruned SSI form. -// -// Preconditions: -// - fn has no dead blocks (blockopt has run). -// - Def/use info (Operands and Referrers) is up-to-date. -// - The dominator tree is up-to-date. -// -func lift(fn *Function) { - // TODO(adonovan): opt: lots of little optimizations may be - // worthwhile here, especially if they cause us to avoid - // buildDomFrontier. For example: - // - // - Alloc never loaded? Eliminate. - // - Alloc never stored? Replace all loads with a zero constant. - // - Alloc stored once? Replace loads with dominating store; - // don't forget that an Alloc is itself an effective store - // of zero. - // - Alloc used only within a single block? - // Use degenerate algorithm avoiding φ-nodes. - // - Consider synergy with scalar replacement of aggregates (SRA). - // e.g. *(&x.f) where x is an Alloc. - // Perhaps we'd get better results if we generated this as x.f - // i.e. Field(x, .f) instead of Load(FieldIndex(x, .f)). - // Unclear. - // - // But we will start with the simplest correct code. - var df domFrontier - var rdf postDomFrontier - var closure *closure - var newPhis newPhiMap - var newSigmas newSigmaMap - - // During this pass we will replace some BasicBlock.Instrs - // (allocs, loads and stores) with nil, keeping a count in - // BasicBlock.gaps. At the end we will reset Instrs to the - // concatenation of all non-dead newPhis and non-nil Instrs - // for the block, reusing the original array if space permits. - - // While we're here, we also eliminate 'rundefers' - // instructions in functions that contain no 'defer' - // instructions. - usesDefer := false - - // Determine which allocs we can lift and number them densely. - // The renaming phase uses this numbering for compact maps. - numAllocs := 0 - for _, b := range fn.Blocks { - b.gaps = 0 - b.rundefers = 0 - for _, instr := range b.Instrs { - switch instr := instr.(type) { - case *Alloc: - if !liftable(instr) { - instr.index = -1 - continue - } - index := -1 - if numAllocs == 0 { - df = buildDomFrontier(fn) - rdf = buildPostDomFrontier(fn) - if len(fn.Blocks) > 2 { - closure = transitiveClosure(fn) - } - newPhis = make(newPhiMap, len(fn.Blocks)) - newSigmas = make(newSigmaMap, len(fn.Blocks)) - - if debugLifting { - title := false - for i, blocks := range df { - if blocks != nil { - if !title { - fmt.Fprintf(os.Stderr, "Dominance frontier of %s:\n", fn) - title = true - } - fmt.Fprintf(os.Stderr, "\t%s: %s\n", fn.Blocks[i], blocks) - } - } - } - } - liftAlloc(closure, df, rdf, instr, newPhis, newSigmas) - index = numAllocs - numAllocs++ - instr.index = index - case *Defer: - usesDefer = true - case *RunDefers: - b.rundefers++ - } - } - } - - if numAllocs > 0 { - // renaming maps an alloc (keyed by index) to its replacement - // value. Initially the renaming contains nil, signifying the - // zero constant of the appropriate type; we construct the - // Const lazily at most once on each path through the domtree. - // TODO(adonovan): opt: cache per-function not per subtree. - renaming := make([]Value, numAllocs) - - // Renaming. - rename(fn.Blocks[0], renaming, newPhis, newSigmas) - - simplifyPhis(newPhis) - - // Eliminate dead φ- and σ-nodes. - markLiveNodes(fn.Blocks, newPhis, newSigmas) - } - - // Prepend remaining live φ-nodes to each block and possibly kill rundefers. - for _, b := range fn.Blocks { - var head []Instruction - if numAllocs > 0 { - nps := newPhis[b.Index] - head = make([]Instruction, 0, len(nps)) - for _, pred := range b.Preds { - nss := newSigmas[pred.Index] - idx := pred.succIndex(b) - for _, newSigma := range nss { - if sigma := newSigma.sigmas[idx]; sigma != nil && sigma.live { - head = append(head, sigma) - - // we didn't populate referrers before, as most - // sigma nodes will be killed - if refs := sigma.X.Referrers(); refs != nil { - *refs = append(*refs, sigma) - } - } else if sigma != nil { - sigma.block = nil - } - } - } - for _, np := range nps { - if np.phi.live { - head = append(head, np.phi) - } else { - for _, edge := range np.phi.Edges { - if refs := edge.Referrers(); refs != nil { - *refs = removeInstr(*refs, np.phi) - } - } - np.phi.block = nil - } - } - } - - rundefersToKill := b.rundefers - if usesDefer { - rundefersToKill = 0 - } - - j := len(head) - if j+b.gaps+rundefersToKill == 0 { - continue // fast path: no new phis or gaps - } - - // We could do straight copies instead of element-wise copies - // when both b.gaps and rundefersToKill are zero. However, - // that seems to only be the case ~1% of the time, which - // doesn't seem worth the extra branch. - - // Remove dead instructions, add phis and sigmas - ns := len(b.Instrs) + j - b.gaps - rundefersToKill - if ns <= cap(b.Instrs) { - // b.Instrs has enough capacity to store all instructions - - // OPT(dh): check cap vs the actually required space; if - // there is a big enough difference, it may be worth - // allocating a new slice, to avoid pinning memory. - dst := b.Instrs[:cap(b.Instrs)] - i := len(dst) - 1 - for n := len(b.Instrs) - 1; n >= 0; n-- { - instr := dst[n] - if instr == nil { - continue - } - if !usesDefer { - if _, ok := instr.(*RunDefers); ok { - continue - } - } - dst[i] = instr - i-- - } - off := i + 1 - len(head) - // aid GC - clearInstrs(dst[:off]) - dst = dst[off:] - copy(dst, head) - b.Instrs = dst - } else { - // not enough space, so allocate a new slice and copy - // over. - dst := make([]Instruction, ns) - copy(dst, head) - - for _, instr := range b.Instrs { - if instr == nil { - continue - } - if !usesDefer { - if _, ok := instr.(*RunDefers); ok { - continue - } - } - dst[j] = instr - j++ - } - b.Instrs = dst - } - } - - // Remove any fn.Locals that were lifted. - j := 0 - for _, l := range fn.Locals { - if l.index < 0 { - fn.Locals[j] = l - j++ - } - } - // Nil out fn.Locals[j:] to aid GC. - for i := j; i < len(fn.Locals); i++ { - fn.Locals[i] = nil - } - fn.Locals = fn.Locals[:j] -} - -func hasDirectReferrer(instr Instruction) bool { - for _, instr := range *instr.Referrers() { - switch instr.(type) { - case *Phi, *Sigma: - // ignore - default: - return true - } - } - return false -} - -func markLiveNodes(blocks []*BasicBlock, newPhis newPhiMap, newSigmas newSigmaMap) { - // Phi and sigma nodes are considered live if a non-phi, non-sigma - // node uses them. Once we find a node that is live, we mark all - // of its operands as used, too. - for _, npList := range newPhis { - for _, np := range npList { - phi := np.phi - if !phi.live && hasDirectReferrer(phi) { - markLivePhi(phi) - } - } - } - for _, npList := range newSigmas { - for _, np := range npList { - for _, sigma := range np.sigmas { - if sigma != nil && !sigma.live && hasDirectReferrer(sigma) { - markLiveSigma(sigma) - } - } - } - } - // Existing φ-nodes due to && and || operators - // are all considered live (see Go issue 19622). - for _, b := range blocks { - for _, phi := range b.phis() { - markLivePhi(phi.(*Phi)) - } - } -} - -func markLivePhi(phi *Phi) { - phi.live = true - for _, rand := range phi.Edges { - switch rand := rand.(type) { - case *Phi: - if !rand.live { - markLivePhi(rand) - } - case *Sigma: - if !rand.live { - markLiveSigma(rand) - } - } - } -} - -func markLiveSigma(sigma *Sigma) { - sigma.live = true - switch rand := sigma.X.(type) { - case *Phi: - if !rand.live { - markLivePhi(rand) - } - case *Sigma: - if !rand.live { - markLiveSigma(rand) - } - } -} - -// simplifyPhis replaces trivial phis with non-phi alternatives. Phi -// nodes where all edges are identical, or consist of only the phi -// itself and one other value, may be replaced with the value. -func simplifyPhis(newPhis newPhiMap) { - // find all phis that are trivial and can be replaced with a - // non-phi value. run until we reach a fixpoint, because replacing - // a phi may make other phis trivial. - for changed := true; changed; { - changed = false - for _, npList := range newPhis { - for _, np := range npList { - if np.phi.live { - // we're reusing 'live' to mean 'dead' in the context of simplifyPhis - continue - } - if r, ok := isUselessPhi(np.phi); ok { - // useless phi, replace its uses with the - // replacement value. the dead phi pass will clean - // up the phi afterwards. - replaceAll(np.phi, r) - np.phi.live = true - changed = true - } - } - } - } - - for _, npList := range newPhis { - for _, np := range npList { - np.phi.live = false - } - } -} - -type BlockSet struct { - idx int - values []bool - count int -} - -func NewBlockSet(size int) *BlockSet { - return &BlockSet{values: make([]bool, size)} -} - -func (s *BlockSet) Set(s2 *BlockSet) { - copy(s.values, s2.values) - s.count = 0 - for _, v := range s.values { - if v { - s.count++ - } - } -} - -func (s *BlockSet) Num() int { - return s.count -} - -func (s *BlockSet) Has(b *BasicBlock) bool { - if b.Index >= len(s.values) { - return false - } - return s.values[b.Index] -} - -// add adds b to the set and returns true if the set changed. -func (s *BlockSet) Add(b *BasicBlock) bool { - if s.values[b.Index] { - return false - } - s.count++ - s.values[b.Index] = true - s.idx = b.Index - - return true -} - -func (s *BlockSet) Clear() { - for j := range s.values { - s.values[j] = false - } - s.count = 0 -} - -// take removes an arbitrary element from a set s and -// returns its index, or returns -1 if empty. -func (s *BlockSet) Take() int { - // [i, end] - for i := s.idx; i < len(s.values); i++ { - if s.values[i] { - s.values[i] = false - s.idx = i - s.count-- - return i - } - } - - // [start, i) - for i := 0; i < s.idx; i++ { - if s.values[i] { - s.values[i] = false - s.idx = i - s.count-- - return i - } - } - - return -1 -} - -type closure struct { - span []uint32 - reachables []interval -} - -type interval uint32 - -const ( - flagMask = 1 << 31 - numBits = 20 - lengthBits = 32 - numBits - 1 - lengthMask = (1<>numBits - } else { - // large interval - i++ - start = uint32(inv & numMask) - end = uint32(r[i]) - } - if idx >= start && idx <= end { - return true - } - } - return false -} - -func (c closure) reachable(id int) []interval { - return c.reachables[c.span[id]:c.span[id+1]] -} - -func (c closure) walk(current *BasicBlock, b *BasicBlock, visited []bool) { - visited[b.Index] = true - for _, succ := range b.Succs { - if visited[succ.Index] { - continue - } - visited[succ.Index] = true - c.walk(current, succ, visited) - } -} - -func transitiveClosure(fn *Function) *closure { - reachable := make([]bool, len(fn.Blocks)) - c := &closure{} - c.span = make([]uint32, len(fn.Blocks)+1) - - addInterval := func(start, end uint32) { - if l := end - start; l <= 1<= 0 { // store of zero to Alloc cell - // Replace dominated loads by the zero value. - renaming[instr.index] = nil - if debugLifting { - fmt.Fprintf(os.Stderr, "\tkill alloc %s\n", instr) - } - // Delete the Alloc. - u.Instrs[i] = nil - u.gaps++ - } - - case *Store: - if alloc, ok := instr.Addr.(*Alloc); ok && alloc.index >= 0 { // store to Alloc cell - // Replace dominated loads by the stored value. - renaming[alloc.index] = instr.Val - if debugLifting { - fmt.Fprintf(os.Stderr, "\tkill store %s; new value: %s\n", - instr, instr.Val.Name()) - } - if refs := instr.Addr.Referrers(); refs != nil { - *refs = removeInstr(*refs, instr) - } - if refs := instr.Val.Referrers(); refs != nil { - *refs = removeInstr(*refs, instr) - } - // Delete the Store. - u.Instrs[i] = nil - u.gaps++ - } - - case *Load: - if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // load of Alloc cell - // In theory, we wouldn't be able to replace loads - // directly, because a loaded value could be used in - // different branches, in which case it should be - // replaced with different sigma nodes. But we can't - // simply defer replacement, either, because then - // later stores might incorrectly affect this load. - // - // To avoid doing renaming on _all_ values (instead of - // just loads and stores like we're doing), we make - // sure during code generation that each load is only - // used in one block. For example, in constant switch - // statements, where the tag is only evaluated once, - // we store it in a temporary and load it for each - // comparison, so that we have individual loads to - // replace. - newval := renamed(u.Parent(), renaming, alloc) - if debugLifting { - fmt.Fprintf(os.Stderr, "\tupdate load %s = %s with %s\n", - instr.Name(), instr, newval) - } - replaceAll(instr, newval) - u.Instrs[i] = nil - u.gaps++ - } - - case *DebugRef: - if x, ok := instr.X.(*Alloc); ok && x.index >= 0 { - if instr.IsAddr { - instr.X = renamed(u.Parent(), renaming, x) - instr.IsAddr = false - - // Add DebugRef to instr.X's referrers. - if refs := instr.X.Referrers(); refs != nil { - *refs = append(*refs, instr) - } - } else { - // A source expression denotes the address - // of an Alloc that was optimized away. - instr.X = nil - - // Delete the DebugRef. - u.Instrs[i] = nil - u.gaps++ - } - } - } - } - - // update all outgoing sigma nodes with the dominating store - for _, sigmas := range newSigmas[u.Index] { - for _, sigma := range sigmas.sigmas { - if sigma == nil { - continue - } - sigma.X = renamed(u.Parent(), renaming, sigmas.alloc) - } - } - - // For each φ-node in a CFG successor, rename the edge. - for succi, v := range u.Succs { - phis := newPhis[v.Index] - if len(phis) == 0 { - continue - } - i := v.predIndex(u) - for _, np := range phis { - phi := np.phi - alloc := np.alloc - // if there's a sigma node, use it, else use the dominating value - var newval Value - for _, sigmas := range newSigmas[u.Index] { - if sigmas.alloc == alloc && sigmas.sigmas[succi] != nil { - newval = sigmas.sigmas[succi] - break - } - } - if newval == nil { - newval = renamed(u.Parent(), renaming, alloc) - } - if debugLifting { - fmt.Fprintf(os.Stderr, "\tsetphi %s edge %s -> %s (#%d) (alloc=%s) := %s\n", - phi.Name(), u, v, i, alloc.Name(), newval.Name()) - } - phi.Edges[i] = newval - if prefs := newval.Referrers(); prefs != nil { - *prefs = append(*prefs, phi) - } - } - } - - // Continue depth-first recursion over domtree, pushing a - // fresh copy of the renaming map for each subtree. - r := make([]Value, len(renaming)) - for _, v := range u.dom.children { - // XXX add debugging - copy(r, renaming) - - // on entry to a block, the incoming sigma nodes become the new values for their alloc - if idx := u.succIndex(v); idx != -1 { - for _, sigma := range newSigmas[u.Index] { - if sigma.sigmas[idx] != nil { - r[sigma.alloc.index] = sigma.sigmas[idx] - } - } - } - rename(v, r, newPhis, newSigmas) - } - -} diff --git a/vendor/honnef.co/go/tools/go/ir/lvalue.go b/vendor/honnef.co/go/tools/go/ir/lvalue.go deleted file mode 100644 index f676a1f7ab..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/lvalue.go +++ /dev/null @@ -1,116 +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 ir - -// lvalues are the union of addressable expressions and map-index -// expressions. - -import ( - "go/ast" - "go/types" -) - -// An lvalue represents an assignable location that may appear on the -// left-hand side of an assignment. This is a generalization of a -// pointer to permit updates to elements of maps. -// -type lvalue interface { - store(fn *Function, v Value, source ast.Node) // stores v into the location - load(fn *Function, source ast.Node) Value // loads the contents of the location - address(fn *Function) Value // address of the location - typ() types.Type // returns the type of the location -} - -// An address is an lvalue represented by a true pointer. -type address struct { - addr Value - expr ast.Expr // source syntax of the value (not address) [debug mode] -} - -func (a *address) load(fn *Function, source ast.Node) Value { - return emitLoad(fn, a.addr, source) -} - -func (a *address) store(fn *Function, v Value, source ast.Node) { - store := emitStore(fn, a.addr, v, source) - if a.expr != nil { - // store.Val is v, converted for assignability. - emitDebugRef(fn, a.expr, store.Val, false) - } -} - -func (a *address) address(fn *Function) Value { - if a.expr != nil { - emitDebugRef(fn, a.expr, a.addr, true) - } - return a.addr -} - -func (a *address) typ() types.Type { - return deref(a.addr.Type()) -} - -// An element is an lvalue represented by m[k], the location of an -// element of a map. These locations are not addressable -// since pointers cannot be formed from them, but they do support -// load() and store(). -// -type element struct { - m, k Value // map - t types.Type // map element type -} - -func (e *element) load(fn *Function, source ast.Node) Value { - l := &MapLookup{ - X: e.m, - Index: e.k, - } - l.setType(e.t) - return fn.emit(l, source) -} - -func (e *element) store(fn *Function, v Value, source ast.Node) { - up := &MapUpdate{ - Map: e.m, - Key: e.k, - Value: emitConv(fn, v, e.t, source), - } - fn.emit(up, source) -} - -func (e *element) address(fn *Function) Value { - panic("map elements are not addressable") -} - -func (e *element) typ() types.Type { - return e.t -} - -// A blank is a dummy variable whose name is "_". -// It is not reified: loads are illegal and stores are ignored. -// -type blank struct{} - -func (bl blank) load(fn *Function, source ast.Node) Value { - panic("blank.load is illegal") -} - -func (bl blank) store(fn *Function, v Value, source ast.Node) { - s := &BlankStore{ - Val: v, - } - fn.emit(s, source) -} - -func (bl blank) address(fn *Function) Value { - panic("blank var is not addressable") -} - -func (bl blank) typ() types.Type { - // This should be the type of the blank Ident; the typechecker - // doesn't provide this yet, but fortunately, we don't need it - // yet either. - panic("blank.typ is unimplemented") -} diff --git a/vendor/honnef.co/go/tools/go/ir/methods.go b/vendor/honnef.co/go/tools/go/ir/methods.go deleted file mode 100644 index 517f448b8c..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/methods.go +++ /dev/null @@ -1,239 +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 ir - -// This file defines utilities for population of method sets. - -import ( - "fmt" - "go/types" -) - -// MethodValue returns the Function implementing method sel, building -// wrapper methods on demand. It returns nil if sel denotes an -// abstract (interface) method. -// -// Precondition: sel.Kind() == MethodVal. -// -// Thread-safe. -// -// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu) -// -func (prog *Program) MethodValue(sel *types.Selection) *Function { - if sel.Kind() != types.MethodVal { - panic(fmt.Sprintf("MethodValue(%s) kind != MethodVal", sel)) - } - T := sel.Recv() - if isInterface(T) { - return nil // abstract method - } - if prog.mode&LogSource != 0 { - defer logStack("MethodValue %s %v", T, sel)() - } - - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - - return prog.addMethod(prog.createMethodSet(T), sel) -} - -// LookupMethod returns the implementation of the method of type T -// identified by (pkg, name). It returns nil if the method exists but -// is abstract, and panics if T has no such method. -// -func (prog *Program) LookupMethod(T types.Type, pkg *types.Package, name string) *Function { - sel := prog.MethodSets.MethodSet(T).Lookup(pkg, name) - if sel == nil { - panic(fmt.Sprintf("%s has no method %s", T, types.Id(pkg, name))) - } - return prog.MethodValue(sel) -} - -// methodSet contains the (concrete) methods of a non-interface type. -type methodSet struct { - mapping map[string]*Function // populated lazily - complete bool // mapping contains all methods -} - -// Precondition: !isInterface(T). -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -func (prog *Program) createMethodSet(T types.Type) *methodSet { - mset, ok := prog.methodSets.At(T).(*methodSet) - if !ok { - mset = &methodSet{mapping: make(map[string]*Function)} - prog.methodSets.Set(T, mset) - } - return mset -} - -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -func (prog *Program) addMethod(mset *methodSet, sel *types.Selection) *Function { - if sel.Kind() == types.MethodExpr { - panic(sel) - } - id := sel.Obj().Id() - fn := mset.mapping[id] - if fn == nil { - obj := sel.Obj().(*types.Func) - - needsPromotion := len(sel.Index()) > 1 - needsIndirection := !isPointer(recvType(obj)) && isPointer(sel.Recv()) - if needsPromotion || needsIndirection { - fn = makeWrapper(prog, sel) - } else { - fn = prog.declaredFunc(obj) - } - if fn.Signature.Recv() == nil { - panic(fn) // missing receiver - } - mset.mapping[id] = fn - } - return fn -} - -// RuntimeTypes returns a new unordered slice containing all -// concrete types in the program for which a complete (non-empty) -// method set is required at run-time. -// -// Thread-safe. -// -// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu) -// -func (prog *Program) RuntimeTypes() []types.Type { - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - - var res []types.Type - prog.methodSets.Iterate(func(T types.Type, v interface{}) { - if v.(*methodSet).complete { - res = append(res, T) - } - }) - return res -} - -// declaredFunc returns the concrete function/method denoted by obj. -// Panic ensues if there is none. -// -func (prog *Program) declaredFunc(obj *types.Func) *Function { - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Function) - } - panic("no concrete method: " + obj.String()) -} - -// needMethodsOf ensures that runtime type information (including the -// complete method set) is available for the specified type T and all -// its subcomponents. -// -// needMethodsOf must be called for at least every type that is an -// operand of some MakeInterface instruction, and for the type of -// every exported package member. -// -// Precondition: T is not a method signature (*Signature with Recv()!=nil). -// -// Thread-safe. (Called via emitConv from multiple builder goroutines.) -// -// TODO(adonovan): make this faster. It accounts for 20% of SSA build time. -// -// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu) -// -func (prog *Program) needMethodsOf(T types.Type) { - prog.methodsMu.Lock() - prog.needMethods(T, false) - prog.methodsMu.Unlock() -} - -// Precondition: T is not a method signature (*Signature with Recv()!=nil). -// Recursive case: skip => don't create methods for T. -// -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -// -func (prog *Program) needMethods(T types.Type, skip bool) { - // Each package maintains its own set of types it has visited. - if prevSkip, ok := prog.runtimeTypes.At(T).(bool); ok { - // needMethods(T) was previously called - if !prevSkip || skip { - return // already seen, with same or false 'skip' value - } - } - prog.runtimeTypes.Set(T, skip) - - tmset := prog.MethodSets.MethodSet(T) - - if !skip && !isInterface(T) && tmset.Len() > 0 { - // Create methods of T. - mset := prog.createMethodSet(T) - if !mset.complete { - mset.complete = true - n := tmset.Len() - for i := 0; i < n; i++ { - prog.addMethod(mset, tmset.At(i)) - } - } - } - - // Recursion over signatures of each method. - for i := 0; i < tmset.Len(); i++ { - sig := tmset.At(i).Type().(*types.Signature) - prog.needMethods(sig.Params(), false) - prog.needMethods(sig.Results(), false) - } - - switch t := T.(type) { - case *types.Basic: - // nop - - case *types.Interface: - // nop---handled by recursion over method set. - - case *types.Pointer: - prog.needMethods(t.Elem(), false) - - case *types.Slice: - prog.needMethods(t.Elem(), false) - - case *types.Chan: - prog.needMethods(t.Elem(), false) - - case *types.Map: - prog.needMethods(t.Key(), false) - prog.needMethods(t.Elem(), false) - - case *types.Signature: - if t.Recv() != nil { - panic(fmt.Sprintf("Signature %s has Recv %s", t, t.Recv())) - } - prog.needMethods(t.Params(), false) - prog.needMethods(t.Results(), false) - - case *types.Named: - // A pointer-to-named type can be derived from a named - // type via reflection. It may have methods too. - prog.needMethods(types.NewPointer(T), false) - - // Consider 'type T struct{S}' where S has methods. - // Reflection provides no way to get from T to struct{S}, - // only to S, so the method set of struct{S} is unwanted, - // so set 'skip' flag during recursion. - prog.needMethods(t.Underlying(), true) - - case *types.Array: - prog.needMethods(t.Elem(), false) - - case *types.Struct: - for i, n := 0, t.NumFields(); i < n; i++ { - prog.needMethods(t.Field(i).Type(), false) - } - - case *types.Tuple: - for i, n := 0, t.Len(); i < n; i++ { - prog.needMethods(t.At(i).Type(), false) - } - - default: - panic(T) - } -} diff --git a/vendor/honnef.co/go/tools/go/ir/mode.go b/vendor/honnef.co/go/tools/go/ir/mode.go deleted file mode 100644 index da548fdbb2..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/mode.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2015 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 ir - -// This file defines the BuilderMode type and its command-line flag. - -import ( - "bytes" - "fmt" -) - -// BuilderMode is a bitmask of options for diagnostics and checking. -// -// *BuilderMode satisfies the flag.Value interface. Example: -// -// var mode = ir.BuilderMode(0) -// func init() { flag.Var(&mode, "build", ir.BuilderModeDoc) } -// -type BuilderMode uint - -const ( - PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout - PrintFunctions // Print function IR code to stdout - PrintSource // Print source code when printing function IR - LogSource // Log source locations as IR builder progresses - SanityCheckFunctions // Perform sanity checking of function bodies - NaiveForm // Build naïve IR form: don't replace local loads/stores with registers - GlobalDebug // Enable debug info for all packages -) - -const BuilderModeDoc = `Options controlling the IR builder. -The value is a sequence of zero or more of these letters: -C perform sanity [C]hecking of the IR form. -D include [D]ebug info for every function. -P print [P]ackage inventory. -F print [F]unction IR code. -A print [A]ST nodes responsible for IR instructions -S log [S]ource locations as IR builder progresses. -N build [N]aive IR form: don't replace local loads/stores with registers. -` - -func (m BuilderMode) String() string { - var buf bytes.Buffer - if m&GlobalDebug != 0 { - buf.WriteByte('D') - } - if m&PrintPackages != 0 { - buf.WriteByte('P') - } - if m&PrintFunctions != 0 { - buf.WriteByte('F') - } - if m&PrintSource != 0 { - buf.WriteByte('A') - } - if m&LogSource != 0 { - buf.WriteByte('S') - } - if m&SanityCheckFunctions != 0 { - buf.WriteByte('C') - } - if m&NaiveForm != 0 { - buf.WriteByte('N') - } - return buf.String() -} - -// Set parses the flag characters in s and updates *m. -func (m *BuilderMode) Set(s string) error { - var mode BuilderMode - for _, c := range s { - switch c { - case 'D': - mode |= GlobalDebug - case 'P': - mode |= PrintPackages - case 'F': - mode |= PrintFunctions - case 'A': - mode |= PrintSource - case 'S': - mode |= LogSource - case 'C': - mode |= SanityCheckFunctions - case 'N': - mode |= NaiveForm - default: - return fmt.Errorf("unknown BuilderMode option: %q", c) - } - } - *m = mode - return nil -} - -// Get returns m. -func (m BuilderMode) Get() interface{} { return m } diff --git a/vendor/honnef.co/go/tools/go/ir/print.go b/vendor/honnef.co/go/tools/go/ir/print.go deleted file mode 100644 index c16c08efa6..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/print.go +++ /dev/null @@ -1,472 +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 ir - -// This file implements the String() methods for all Value and -// Instruction types. - -import ( - "bytes" - "fmt" - "go/types" - "io" - "reflect" - "sort" - - "golang.org/x/tools/go/types/typeutil" -) - -// relName returns the name of v relative to i. -// In most cases, this is identical to v.Name(), but references to -// Functions (including methods) and Globals use RelString and -// all types are displayed with relType, so that only cross-package -// references are package-qualified. -// -func relName(v Value, i Instruction) string { - if v == nil { - return "" - } - var from *types.Package - if i != nil { - from = i.Parent().pkg() - } - switch v := v.(type) { - case Member: // *Function or *Global - return v.RelString(from) - } - return v.Name() -} - -func relType(t types.Type, from *types.Package) string { - return types.TypeString(t, types.RelativeTo(from)) -} - -func relString(m Member, from *types.Package) string { - // NB: not all globals have an Object (e.g. init$guard), - // so use Package().Object not Object.Package(). - if pkg := m.Package().Pkg; pkg != nil && pkg != from { - return fmt.Sprintf("%s.%s", pkg.Path(), m.Name()) - } - return m.Name() -} - -// Value.String() -// -// This method is provided only for debugging. -// It never appears in disassembly, which uses Value.Name(). - -func (v *Parameter) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Parameter <%s> {%s}", relType(v.Type(), from), v.name) -} - -func (v *FreeVar) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("FreeVar <%s> %s", relType(v.Type(), from), v.Name()) -} - -func (v *Builtin) String() string { - return fmt.Sprintf("Builtin %s", v.Name()) -} - -// Instruction.String() - -func (v *Alloc) String() string { - from := v.Parent().pkg() - storage := "Stack" - if v.Heap { - storage = "Heap" - } - return fmt.Sprintf("%sAlloc <%s>", storage, relType(v.Type(), from)) -} - -func (v *Sigma) String() string { - from := v.Parent().pkg() - s := fmt.Sprintf("Sigma <%s> [b%d] %s", relType(v.Type(), from), v.From.Index, v.X.Name()) - return s -} - -func (v *Phi) String() string { - var b bytes.Buffer - fmt.Fprintf(&b, "Phi <%s>", v.Type()) - for i, edge := range v.Edges { - b.WriteString(" ") - // Be robust against malformed CFG. - if v.block == nil { - b.WriteString("??") - continue - } - block := -1 - if i < len(v.block.Preds) { - block = v.block.Preds[i].Index - } - fmt.Fprintf(&b, "%d:", block) - edgeVal := "" // be robust - if edge != nil { - edgeVal = relName(edge, v) - } - b.WriteString(edgeVal) - } - return b.String() -} - -func printCall(v *CallCommon, prefix string, instr Instruction) string { - var b bytes.Buffer - if !v.IsInvoke() { - if value, ok := instr.(Value); ok { - fmt.Fprintf(&b, "%s <%s> %s", prefix, relType(value.Type(), instr.Parent().pkg()), relName(v.Value, instr)) - } else { - fmt.Fprintf(&b, "%s %s", prefix, relName(v.Value, instr)) - } - } else { - if value, ok := instr.(Value); ok { - fmt.Fprintf(&b, "%sInvoke <%s> %s.%s", prefix, relType(value.Type(), instr.Parent().pkg()), relName(v.Value, instr), v.Method.Name()) - } else { - fmt.Fprintf(&b, "%sInvoke %s.%s", prefix, relName(v.Value, instr), v.Method.Name()) - } - } - for _, arg := range v.Args { - b.WriteString(" ") - b.WriteString(relName(arg, instr)) - } - return b.String() -} - -func (c *CallCommon) String() string { - return printCall(c, "", nil) -} - -func (v *Call) String() string { - return printCall(&v.Call, "Call", v) -} - -func (v *BinOp) String() string { - return fmt.Sprintf("BinOp <%s> {%s} %s %s", relType(v.Type(), v.Parent().pkg()), v.Op.String(), relName(v.X, v), relName(v.Y, v)) -} - -func (v *UnOp) String() string { - return fmt.Sprintf("UnOp <%s> {%s} %s", relType(v.Type(), v.Parent().pkg()), v.Op.String(), relName(v.X, v)) -} - -func (v *Load) String() string { - return fmt.Sprintf("Load <%s> %s", relType(v.Type(), v.Parent().pkg()), relName(v.X, v)) -} - -func printConv(prefix string, v, x Value) string { - from := v.Parent().pkg() - return fmt.Sprintf("%s <%s> %s", - prefix, - relType(v.Type(), from), - relName(x, v.(Instruction))) -} - -func (v *ChangeType) String() string { return printConv("ChangeType", v, v.X) } -func (v *Convert) String() string { return printConv("Convert", v, v.X) } -func (v *ChangeInterface) String() string { return printConv("ChangeInterface", v, v.X) } -func (v *MakeInterface) String() string { return printConv("MakeInterface", v, v.X) } - -func (v *MakeClosure) String() string { - from := v.Parent().pkg() - var b bytes.Buffer - fmt.Fprintf(&b, "MakeClosure <%s> %s", relType(v.Type(), from), relName(v.Fn, v)) - if v.Bindings != nil { - for _, c := range v.Bindings { - b.WriteString(" ") - b.WriteString(relName(c, v)) - } - } - return b.String() -} - -func (v *MakeSlice) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("MakeSlice <%s> %s %s", - relType(v.Type(), from), - relName(v.Len, v), - relName(v.Cap, v)) -} - -func (v *Slice) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Slice <%s> %s %s %s %s", - relType(v.Type(), from), relName(v.X, v), relName(v.Low, v), relName(v.High, v), relName(v.Max, v)) -} - -func (v *MakeMap) String() string { - res := "" - if v.Reserve != nil { - res = relName(v.Reserve, v) - } - from := v.Parent().pkg() - return fmt.Sprintf("MakeMap <%s> %s", relType(v.Type(), from), res) -} - -func (v *MakeChan) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("MakeChan <%s> %s", relType(v.Type(), from), relName(v.Size, v)) -} - -func (v *FieldAddr) String() string { - from := v.Parent().pkg() - st := deref(v.X.Type()).Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - return fmt.Sprintf("FieldAddr <%s> [%d] (%s) %s", relType(v.Type(), from), v.Field, name, relName(v.X, v)) -} - -func (v *Field) String() string { - st := v.X.Type().Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - from := v.Parent().pkg() - return fmt.Sprintf("Field <%s> [%d] (%s) %s", relType(v.Type(), from), v.Field, name, relName(v.X, v)) -} - -func (v *IndexAddr) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("IndexAddr <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *Index) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Index <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *MapLookup) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("MapLookup <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *StringLookup) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("StringLookup <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *Range) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Range <%s> %s", relType(v.Type(), from), relName(v.X, v)) -} - -func (v *Next) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Next <%s> %s", relType(v.Type(), from), relName(v.Iter, v)) -} - -func (v *TypeAssert) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("TypeAssert <%s> %s", relType(v.Type(), from), relName(v.X, v)) -} - -func (v *Extract) String() string { - from := v.Parent().pkg() - name := v.Tuple.Type().(*types.Tuple).At(v.Index).Name() - return fmt.Sprintf("Extract <%s> [%d] (%s) %s", relType(v.Type(), from), v.Index, name, relName(v.Tuple, v)) -} - -func (s *Jump) String() string { - // Be robust against malformed CFG. - block := -1 - if s.block != nil && len(s.block.Succs) == 1 { - block = s.block.Succs[0].Index - } - str := fmt.Sprintf("Jump → b%d", block) - if s.Comment != "" { - str = fmt.Sprintf("%s # %s", str, s.Comment) - } - return str -} - -func (s *Unreachable) String() string { - // Be robust against malformed CFG. - block := -1 - if s.block != nil && len(s.block.Succs) == 1 { - block = s.block.Succs[0].Index - } - return fmt.Sprintf("Unreachable → b%d", block) -} - -func (s *If) String() string { - // Be robust against malformed CFG. - tblock, fblock := -1, -1 - if s.block != nil && len(s.block.Succs) == 2 { - tblock = s.block.Succs[0].Index - fblock = s.block.Succs[1].Index - } - return fmt.Sprintf("If %s → b%d b%d", relName(s.Cond, s), tblock, fblock) -} - -func (s *ConstantSwitch) String() string { - var b bytes.Buffer - fmt.Fprintf(&b, "ConstantSwitch %s", relName(s.Tag, s)) - for _, cond := range s.Conds { - fmt.Fprintf(&b, " %s", relName(cond, s)) - } - fmt.Fprint(&b, " →") - for _, succ := range s.block.Succs { - fmt.Fprintf(&b, " b%d", succ.Index) - } - return b.String() -} - -func (s *TypeSwitch) String() string { - from := s.Parent().pkg() - var b bytes.Buffer - fmt.Fprintf(&b, "TypeSwitch <%s> %s", relType(s.typ, from), relName(s.Tag, s)) - for _, cond := range s.Conds { - fmt.Fprintf(&b, " %q", relType(cond, s.block.parent.pkg())) - } - return b.String() -} - -func (s *Go) String() string { - return printCall(&s.Call, "Go", s) -} - -func (s *Panic) String() string { - // Be robust against malformed CFG. - block := -1 - if s.block != nil && len(s.block.Succs) == 1 { - block = s.block.Succs[0].Index - } - return fmt.Sprintf("Panic %s → b%d", relName(s.X, s), block) -} - -func (s *Return) String() string { - var b bytes.Buffer - b.WriteString("Return") - for _, r := range s.Results { - b.WriteString(" ") - b.WriteString(relName(r, s)) - } - return b.String() -} - -func (*RunDefers) String() string { - return "RunDefers" -} - -func (s *Send) String() string { - return fmt.Sprintf("Send %s %s", relName(s.Chan, s), relName(s.X, s)) -} - -func (recv *Recv) String() string { - from := recv.Parent().pkg() - return fmt.Sprintf("Recv <%s> %s", relType(recv.Type(), from), relName(recv.Chan, recv)) -} - -func (s *Defer) String() string { - return printCall(&s.Call, "Defer", s) -} - -func (s *Select) String() string { - var b bytes.Buffer - for i, st := range s.States { - if i > 0 { - b.WriteString(", ") - } - if st.Dir == types.RecvOnly { - b.WriteString("<-") - b.WriteString(relName(st.Chan, s)) - } else { - b.WriteString(relName(st.Chan, s)) - b.WriteString("<-") - b.WriteString(relName(st.Send, s)) - } - } - non := "" - if !s.Blocking { - non = "Non" - } - from := s.Parent().pkg() - return fmt.Sprintf("Select%sBlocking <%s> [%s]", non, relType(s.Type(), from), b.String()) -} - -func (s *Store) String() string { - return fmt.Sprintf("Store {%s} %s %s", - s.Val.Type(), relName(s.Addr, s), relName(s.Val, s)) -} - -func (s *BlankStore) String() string { - return fmt.Sprintf("BlankStore %s", relName(s.Val, s)) -} - -func (s *MapUpdate) String() string { - return fmt.Sprintf("MapUpdate %s %s %s", relName(s.Map, s), relName(s.Key, s), relName(s.Value, s)) -} - -func (s *DebugRef) String() string { - p := s.Parent().Prog.Fset.Position(s.Pos()) - var descr interface{} - if s.object != nil { - descr = s.object // e.g. "var x int" - } else { - descr = reflect.TypeOf(s.Expr) // e.g. "*ast.CallExpr" - } - var addr string - if s.IsAddr { - addr = "address of " - } - return fmt.Sprintf("; %s%s @ %d:%d is %s", addr, descr, p.Line, p.Column, s.X.Name()) -} - -func (p *Package) String() string { - return "package " + p.Pkg.Path() -} - -var _ io.WriterTo = (*Package)(nil) // *Package implements io.Writer - -func (p *Package) WriteTo(w io.Writer) (int64, error) { - var buf bytes.Buffer - WritePackage(&buf, p) - n, err := w.Write(buf.Bytes()) - return int64(n), err -} - -// WritePackage writes to buf a human-readable summary of p. -func WritePackage(buf *bytes.Buffer, p *Package) { - fmt.Fprintf(buf, "%s:\n", p) - - var names []string - maxname := 0 - for name := range p.Members { - if l := len(name); l > maxname { - maxname = l - } - names = append(names, name) - } - - from := p.Pkg - sort.Strings(names) - for _, name := range names { - switch mem := p.Members[name].(type) { - case *NamedConst: - fmt.Fprintf(buf, " const %-*s %s = %s\n", - maxname, name, mem.Name(), mem.Value.RelString(from)) - - case *Function: - fmt.Fprintf(buf, " func %-*s %s\n", - maxname, name, relType(mem.Type(), from)) - - case *Type: - fmt.Fprintf(buf, " type %-*s %s\n", - maxname, name, relType(mem.Type().Underlying(), from)) - for _, meth := range typeutil.IntuitiveMethodSet(mem.Type(), &p.Prog.MethodSets) { - fmt.Fprintf(buf, " %s\n", types.SelectionString(meth, types.RelativeTo(from))) - } - - case *Global: - fmt.Fprintf(buf, " var %-*s %s\n", - maxname, name, relType(mem.Type().(*types.Pointer).Elem(), from)) - } - } - - fmt.Fprintf(buf, "\n") -} diff --git a/vendor/honnef.co/go/tools/go/ir/sanity.go b/vendor/honnef.co/go/tools/go/ir/sanity.go deleted file mode 100644 index c94f2bf837..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/sanity.go +++ /dev/null @@ -1,554 +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 ir - -// An optional pass for sanity-checking invariants of the IR representation. -// Currently it checks CFG invariants but little at the instruction level. - -import ( - "fmt" - "go/types" - "io" - "os" - "strings" -) - -type sanity struct { - reporter io.Writer - fn *Function - block *BasicBlock - instrs map[Instruction]struct{} - insane bool -} - -// sanityCheck performs integrity checking of the IR representation -// of the function fn and returns true if it was valid. Diagnostics -// are written to reporter if non-nil, os.Stderr otherwise. Some -// diagnostics are only warnings and do not imply a negative result. -// -// Sanity-checking is intended to facilitate the debugging of code -// transformation passes. -// -func sanityCheck(fn *Function, reporter io.Writer) bool { - if reporter == nil { - reporter = os.Stderr - } - return (&sanity{reporter: reporter}).checkFunction(fn) -} - -// mustSanityCheck is like sanityCheck but panics instead of returning -// a negative result. -// -func mustSanityCheck(fn *Function, reporter io.Writer) { - if !sanityCheck(fn, reporter) { - fn.WriteTo(os.Stderr) - panic("SanityCheck failed") - } -} - -func (s *sanity) diagnostic(prefix, format string, args ...interface{}) { - fmt.Fprintf(s.reporter, "%s: function %s", prefix, s.fn) - if s.block != nil { - fmt.Fprintf(s.reporter, ", block %s", s.block) - } - io.WriteString(s.reporter, ": ") - fmt.Fprintf(s.reporter, format, args...) - io.WriteString(s.reporter, "\n") -} - -func (s *sanity) errorf(format string, args ...interface{}) { - s.insane = true - s.diagnostic("Error", format, args...) -} - -func (s *sanity) warnf(format string, args ...interface{}) { - s.diagnostic("Warning", format, args...) -} - -// findDuplicate returns an arbitrary basic block that appeared more -// than once in blocks, or nil if all were unique. -func findDuplicate(blocks []*BasicBlock) *BasicBlock { - if len(blocks) < 2 { - return nil - } - if blocks[0] == blocks[1] { - return blocks[0] - } - // Slow path: - m := make(map[*BasicBlock]bool) - for _, b := range blocks { - if m[b] { - return b - } - m[b] = true - } - return nil -} - -func (s *sanity) checkInstr(idx int, instr Instruction) { - switch instr := instr.(type) { - case *If, *Jump, *Return, *Panic, *Unreachable, *ConstantSwitch: - s.errorf("control flow instruction not at end of block") - case *Sigma: - if idx > 0 { - prev := s.block.Instrs[idx-1] - if _, ok := prev.(*Sigma); !ok { - s.errorf("Sigma instruction follows a non-Sigma: %T", prev) - } - } - case *Phi: - if idx == 0 { - // It suffices to apply this check to just the first phi node. - if dup := findDuplicate(s.block.Preds); dup != nil { - s.errorf("phi node in block with duplicate predecessor %s", dup) - } - } else { - prev := s.block.Instrs[idx-1] - switch prev.(type) { - case *Phi, *Sigma: - default: - s.errorf("Phi instruction follows a non-Phi, non-Sigma: %T", prev) - } - } - if ne, np := len(instr.Edges), len(s.block.Preds); ne != np { - s.errorf("phi node has %d edges but %d predecessors", ne, np) - - } else { - for i, e := range instr.Edges { - if e == nil { - s.errorf("phi node '%v' has no value for edge #%d from %s", instr, i, s.block.Preds[i]) - } - } - } - - case *Alloc: - if !instr.Heap { - found := false - for _, l := range s.fn.Locals { - if l == instr { - found = true - break - } - } - if !found { - s.errorf("local alloc %s = %s does not appear in Function.Locals", instr.Name(), instr) - } - } - - case *BinOp: - case *Call: - case *ChangeInterface: - case *ChangeType: - case *Convert: - if _, ok := instr.X.Type().Underlying().(*types.Basic); !ok { - if _, ok := instr.Type().Underlying().(*types.Basic); !ok { - s.errorf("convert %s -> %s: at least one type must be basic", instr.X.Type(), instr.Type()) - } - } - - case *Defer: - case *Extract: - case *Field: - case *FieldAddr: - case *Go: - case *Index: - case *IndexAddr: - case *MapLookup: - case *StringLookup: - case *MakeChan: - case *MakeClosure: - numFree := len(instr.Fn.(*Function).FreeVars) - numBind := len(instr.Bindings) - if numFree != numBind { - s.errorf("MakeClosure has %d Bindings for function %s with %d free vars", - numBind, instr.Fn, numFree) - - } - if recv := instr.Type().(*types.Signature).Recv(); recv != nil { - s.errorf("MakeClosure's type includes receiver %s", recv.Type()) - } - - case *MakeInterface: - case *MakeMap: - case *MakeSlice: - case *MapUpdate: - case *Next: - case *Range: - case *RunDefers: - case *Select: - case *Send: - case *Slice: - case *Store: - case *TypeAssert: - case *UnOp: - case *DebugRef: - case *BlankStore: - case *Load: - case *Parameter: - case *Const: - case *Recv: - case *TypeSwitch: - default: - panic(fmt.Sprintf("Unknown instruction type: %T", instr)) - } - - if call, ok := instr.(CallInstruction); ok { - if call.Common().Signature() == nil { - s.errorf("nil signature: %s", call) - } - } - - // Check that value-defining instructions have valid types - // and a valid referrer list. - if v, ok := instr.(Value); ok { - t := v.Type() - if t == nil { - s.errorf("no type: %s = %s", v.Name(), v) - } else if t == tRangeIter { - // not a proper type; ignore. - } else if b, ok := t.Underlying().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 { - if _, ok := v.(*Const); !ok { - s.errorf("instruction has 'untyped' result: %s = %s : %s", v.Name(), v, t) - } - } - s.checkReferrerList(v) - } - - // Untyped constants are legal as instruction Operands(), - // for example: - // _ = "foo"[0] - // or: - // if wordsize==64 {...} - - // All other non-Instruction Values can be found via their - // enclosing Function or Package. -} - -func (s *sanity) checkFinalInstr(instr Instruction) { - switch instr := instr.(type) { - case *If: - if nsuccs := len(s.block.Succs); nsuccs != 2 { - s.errorf("If-terminated block has %d successors; expected 2", nsuccs) - return - } - if s.block.Succs[0] == s.block.Succs[1] { - s.errorf("If-instruction has same True, False target blocks: %s", s.block.Succs[0]) - return - } - - case *Jump: - if nsuccs := len(s.block.Succs); nsuccs != 1 { - s.errorf("Jump-terminated block has %d successors; expected 1", nsuccs) - return - } - - case *Return: - if nsuccs := len(s.block.Succs); nsuccs != 0 { - s.errorf("Return-terminated block has %d successors; expected none", nsuccs) - return - } - if na, nf := len(instr.Results), s.fn.Signature.Results().Len(); nf != na { - s.errorf("%d-ary return in %d-ary function", na, nf) - } - - case *Panic: - if nsuccs := len(s.block.Succs); nsuccs != 1 { - s.errorf("Panic-terminated block has %d successors; expected one", nsuccs) - return - } - - case *Unreachable: - if nsuccs := len(s.block.Succs); nsuccs != 1 { - s.errorf("Unreachable-terminated block has %d successors; expected one", nsuccs) - return - } - - case *ConstantSwitch: - - default: - s.errorf("non-control flow instruction at end of block") - } -} - -func (s *sanity) checkBlock(b *BasicBlock, index int) { - s.block = b - - if b.Index != index { - s.errorf("block has incorrect Index %d", b.Index) - } - if b.parent != s.fn { - s.errorf("block has incorrect parent %s", b.parent) - } - - // Check all blocks are reachable. - // (The entry block is always implicitly reachable, the exit block may be unreachable.) - if index > 1 && len(b.Preds) == 0 { - s.warnf("unreachable block") - if b.Instrs == nil { - // Since this block is about to be pruned, - // tolerating transient problems in it - // simplifies other optimizations. - return - } - } - - // Check predecessor and successor relations are dual, - // and that all blocks in CFG belong to same function. - for _, a := range b.Preds { - found := false - for _, bb := range a.Succs { - if bb == b { - found = true - break - } - } - if !found { - s.errorf("expected successor edge in predecessor %s; found only: %s", a, a.Succs) - } - if a.parent != s.fn { - s.errorf("predecessor %s belongs to different function %s", a, a.parent) - } - } - for _, c := range b.Succs { - found := false - for _, bb := range c.Preds { - if bb == b { - found = true - break - } - } - if !found { - s.errorf("expected predecessor edge in successor %s; found only: %s", c, c.Preds) - } - if c.parent != s.fn { - s.errorf("successor %s belongs to different function %s", c, c.parent) - } - } - - // Check each instruction is sane. - n := len(b.Instrs) - if n == 0 { - s.errorf("basic block contains no instructions") - } - var rands [10]*Value // reuse storage - for j, instr := range b.Instrs { - if instr == nil { - s.errorf("nil instruction at index %d", j) - continue - } - if b2 := instr.Block(); b2 == nil { - s.errorf("nil Block() for instruction at index %d", j) - continue - } else if b2 != b { - s.errorf("wrong Block() (%s) for instruction at index %d ", b2, j) - continue - } - if j < n-1 { - s.checkInstr(j, instr) - } else { - s.checkFinalInstr(instr) - } - - // Check Instruction.Operands. - operands: - for i, op := range instr.Operands(rands[:0]) { - if op == nil { - s.errorf("nil operand pointer %d of %s", i, instr) - continue - } - val := *op - if val == nil { - continue // a nil operand is ok - } - - // Check that "untyped" types only appear on constant operands. - if _, ok := (*op).(*Const); !ok { - if basic, ok := (*op).Type().(*types.Basic); ok { - if basic.Info()&types.IsUntyped != 0 { - s.errorf("operand #%d of %s is untyped: %s", i, instr, basic) - } - } - } - - // Check that Operands that are also Instructions belong to same function. - // TODO(adonovan): also check their block dominates block b. - if val, ok := val.(Instruction); ok { - if val.Block() == nil { - s.errorf("operand %d of %s is an instruction (%s) that belongs to no block", i, instr, val) - } else if val.Parent() != s.fn { - s.errorf("operand %d of %s is an instruction (%s) from function %s", i, instr, val, val.Parent()) - } - } - - // Check that each function-local operand of - // instr refers back to instr. (NB: quadratic) - switch val := val.(type) { - case *Const, *Global, *Builtin: - continue // not local - case *Function: - if val.parent == nil { - continue // only anon functions are local - } - } - - // TODO(adonovan): check val.Parent() != nil <=> val.Referrers() is defined. - - if refs := val.Referrers(); refs != nil { - for _, ref := range *refs { - if ref == instr { - continue operands - } - } - s.errorf("operand %d of %s (%s) does not refer to us", i, instr, val) - } else { - s.errorf("operand %d of %s (%s) has no referrers", i, instr, val) - } - } - } -} - -func (s *sanity) checkReferrerList(v Value) { - refs := v.Referrers() - if refs == nil { - s.errorf("%s has missing referrer list", v.Name()) - return - } - for i, ref := range *refs { - if _, ok := s.instrs[ref]; !ok { - if val, ok := ref.(Value); ok { - s.errorf("%s.Referrers()[%d] = %s = %s is not an instruction belonging to this function", v.Name(), i, val.Name(), val) - } else { - s.errorf("%s.Referrers()[%d] = %s is not an instruction belonging to this function", v.Name(), i, ref) - } - } - } -} - -func (s *sanity) checkFunction(fn *Function) bool { - // TODO(adonovan): check Function invariants: - // - check params match signature - // - check transient fields are nil - // - warn if any fn.Locals do not appear among block instructions. - s.fn = fn - if fn.Prog == nil { - s.errorf("nil Prog") - } - - _ = fn.String() // must not crash - _ = fn.RelString(fn.pkg()) // must not crash - - // All functions have a package, except delegates (which are - // shared across packages, or duplicated as weak symbols in a - // separate-compilation model), and error.Error. - if fn.Pkg == nil { - switch fn.Synthetic { - case SyntheticWrapper, SyntheticBound, SyntheticThunk: - default: - if !strings.HasSuffix(fn.name, "Error") { - s.errorf("nil Pkg") - } - } - } - if src, syn := fn.Synthetic == 0, fn.source != nil; src != syn { - s.errorf("got fromSource=%t, hasSyntax=%t; want same values", src, syn) - } - for i, l := range fn.Locals { - if l.Parent() != fn { - s.errorf("Local %s at index %d has wrong parent", l.Name(), i) - } - if l.Heap { - s.errorf("Local %s at index %d has Heap flag set", l.Name(), i) - } - } - // Build the set of valid referrers. - s.instrs = make(map[Instruction]struct{}) - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - s.instrs[instr] = struct{}{} - } - } - for i, p := range fn.Params { - if p.Parent() != fn { - s.errorf("Param %s at index %d has wrong parent", p.Name(), i) - } - // Check common suffix of Signature and Params match type. - if sig := fn.Signature; sig != nil { - j := i - len(fn.Params) + sig.Params().Len() // index within sig.Params - if j < 0 { - continue - } - if !types.Identical(p.Type(), sig.Params().At(j).Type()) { - s.errorf("Param %s at index %d has wrong type (%s, versus %s in Signature)", p.Name(), i, p.Type(), sig.Params().At(j).Type()) - - } - } - - s.checkReferrerList(p) - } - for i, fv := range fn.FreeVars { - if fv.Parent() != fn { - s.errorf("FreeVar %s at index %d has wrong parent", fv.Name(), i) - } - s.checkReferrerList(fv) - } - - if fn.Blocks != nil && len(fn.Blocks) == 0 { - // Function _had_ blocks (so it's not external) but - // they were "optimized" away, even the entry block. - s.errorf("Blocks slice is non-nil but empty") - } - for i, b := range fn.Blocks { - if b == nil { - s.warnf("nil *BasicBlock at f.Blocks[%d]", i) - continue - } - s.checkBlock(b, i) - } - - s.block = nil - for i, anon := range fn.AnonFuncs { - if anon.Parent() != fn { - s.errorf("AnonFuncs[%d]=%s but %s.Parent()=%s", i, anon, anon, anon.Parent()) - } - } - s.fn = nil - return !s.insane -} - -// sanityCheckPackage checks invariants of packages upon creation. -// It does not require that the package is built. -// Unlike sanityCheck (for functions), it just panics at the first error. -func sanityCheckPackage(pkg *Package) { - if pkg.Pkg == nil { - panic(fmt.Sprintf("Package %s has no Object", pkg)) - } - _ = pkg.String() // must not crash - - for name, mem := range pkg.Members { - if name != mem.Name() { - panic(fmt.Sprintf("%s: %T.Name() = %s, want %s", - pkg.Pkg.Path(), mem, mem.Name(), name)) - } - obj := mem.Object() - if obj == nil { - // This check is sound because fields - // {Global,Function}.object have type - // types.Object. (If they were declared as - // *types.{Var,Func}, we'd have a non-empty - // interface containing a nil pointer.) - - continue // not all members have typechecker objects - } - if obj.Name() != name { - if obj.Name() == "init" && strings.HasPrefix(mem.Name(), "init#") { - // Ok. The name of a declared init function varies between - // its types.Func ("init") and its ir.Function ("init#%d"). - } else { - panic(fmt.Sprintf("%s: %T.Object().Name() = %s, want %s", - pkg.Pkg.Path(), mem, obj.Name(), name)) - } - } - } -} diff --git a/vendor/honnef.co/go/tools/go/ir/source.go b/vendor/honnef.co/go/tools/go/ir/source.go deleted file mode 100644 index 93d1ccbd29..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/source.go +++ /dev/null @@ -1,270 +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 ir - -// This file defines utilities for working with source positions -// or source-level named entities ("objects"). - -// TODO(adonovan): test that {Value,Instruction}.Pos() positions match -// the originating syntax, as specified. - -import ( - "go/ast" - "go/token" - "go/types" -) - -// EnclosingFunction returns the function that contains the syntax -// node denoted by path. -// -// Syntax associated with package-level variable specifications is -// enclosed by the package's init() function. -// -// Returns nil if not found; reasons might include: -// - the node is not enclosed by any function. -// - the node is within an anonymous function (FuncLit) and -// its IR function has not been created yet -// (pkg.Build() has not yet been called). -// -func EnclosingFunction(pkg *Package, path []ast.Node) *Function { - // Start with package-level function... - fn := findEnclosingPackageLevelFunction(pkg, path) - if fn == nil { - return nil // not in any function - } - - // ...then walk down the nested anonymous functions. - n := len(path) -outer: - for i := range path { - if lit, ok := path[n-1-i].(*ast.FuncLit); ok { - for _, anon := range fn.AnonFuncs { - if anon.Pos() == lit.Type.Func { - fn = anon - continue outer - } - } - // IR function not found: - // - package not yet built, or maybe - // - builder skipped FuncLit in dead block - // (in principle; but currently the Builder - // generates even dead FuncLits). - return nil - } - } - return fn -} - -// HasEnclosingFunction returns true if the AST node denoted by path -// is contained within the declaration of some function or -// package-level variable. -// -// Unlike EnclosingFunction, the behaviour of this function does not -// depend on whether IR code for pkg has been built, so it can be -// used to quickly reject check inputs that will cause -// EnclosingFunction to fail, prior to IR building. -// -func HasEnclosingFunction(pkg *Package, path []ast.Node) bool { - return findEnclosingPackageLevelFunction(pkg, path) != nil -} - -// findEnclosingPackageLevelFunction returns the Function -// corresponding to the package-level function enclosing path. -// -func findEnclosingPackageLevelFunction(pkg *Package, path []ast.Node) *Function { - if n := len(path); n >= 2 { // [... {Gen,Func}Decl File] - switch decl := path[n-2].(type) { - case *ast.GenDecl: - if decl.Tok == token.VAR && n >= 3 { - // Package-level 'var' initializer. - return pkg.init - } - - case *ast.FuncDecl: - // Declared function/method. - fn := findNamedFunc(pkg, decl.Pos()) - if fn == nil && decl.Recv == nil && decl.Name.Name == "init" { - // Hack: return non-nil when IR is not yet - // built so that HasEnclosingFunction works. - return pkg.init - } - return fn - } - } - return nil // not in any function -} - -// findNamedFunc returns the named function whose FuncDecl.Ident is at -// position pos. -// -func findNamedFunc(pkg *Package, pos token.Pos) *Function { - for _, fn := range pkg.Functions { - if fn.Pos() == pos { - return fn - } - } - return nil -} - -// ValueForExpr returns the IR Value that corresponds to non-constant -// expression e. -// -// It returns nil if no value was found, e.g. -// - the expression is not lexically contained within f; -// - f was not built with debug information; or -// - e is a constant expression. (For efficiency, no debug -// information is stored for constants. Use -// go/types.Info.Types[e].Value instead.) -// - e is a reference to nil or a built-in function. -// - the value was optimised away. -// -// If e is an addressable expression used in an lvalue context, -// value is the address denoted by e, and isAddr is true. -// -// The types of e (or &e, if isAddr) and the result are equal -// (modulo "untyped" bools resulting from comparisons). -// -// (Tip: to find the ir.Value given a source position, use -// astutil.PathEnclosingInterval to locate the ast.Node, then -// EnclosingFunction to locate the Function, then ValueForExpr to find -// the ir.Value.) -// -func (f *Function) ValueForExpr(e ast.Expr) (value Value, isAddr bool) { - if f.debugInfo() { // (opt) - e = unparen(e) - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - if ref, ok := instr.(*DebugRef); ok { - if ref.Expr == e { - return ref.X, ref.IsAddr - } - } - } - } - } - return -} - -// --- Lookup functions for source-level named entities (types.Objects) --- - -// Package returns the IR Package corresponding to the specified -// type-checker package object. -// It returns nil if no such IR package has been created. -// -func (prog *Program) Package(obj *types.Package) *Package { - return prog.packages[obj] -} - -// packageLevelValue returns the package-level value corresponding to -// the specified named object, which may be a package-level const -// (*Const), var (*Global) or func (*Function) of some package in -// prog. It returns nil if the object is not found. -// -func (prog *Program) packageLevelValue(obj types.Object) Value { - if pkg, ok := prog.packages[obj.Pkg()]; ok { - return pkg.values[obj] - } - return nil -} - -// FuncValue returns the concrete Function denoted by the source-level -// named function obj, or nil if obj denotes an interface method. -// -// TODO(adonovan): check the invariant that obj.Type() matches the -// result's Signature, both in the params/results and in the receiver. -// -func (prog *Program) FuncValue(obj *types.Func) *Function { - fn, _ := prog.packageLevelValue(obj).(*Function) - return fn -} - -// ConstValue returns the IR Value denoted by the source-level named -// constant obj. -// -func (prog *Program) ConstValue(obj *types.Const) *Const { - // TODO(adonovan): opt: share (don't reallocate) - // Consts for const objects and constant ast.Exprs. - - // Universal constant? {true,false,nil} - if obj.Parent() == types.Universe { - return NewConst(obj.Val(), obj.Type()) - } - // Package-level named constant? - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Const) - } - return NewConst(obj.Val(), obj.Type()) -} - -// VarValue returns the IR Value that corresponds to a specific -// identifier denoting the source-level named variable obj. -// -// VarValue returns nil if a local variable was not found, perhaps -// because its package was not built, the debug information was not -// requested during IR construction, or the value was optimized away. -// -// ref is the path to an ast.Ident (e.g. from PathEnclosingInterval), -// and that ident must resolve to obj. -// -// pkg is the package enclosing the reference. (A reference to a var -// always occurs within a function, so we need to know where to find it.) -// -// If the identifier is a field selector and its base expression is -// non-addressable, then VarValue returns the value of that field. -// For example: -// func f() struct {x int} -// f().x // VarValue(x) returns a *Field instruction of type int -// -// All other identifiers denote addressable locations (variables). -// For them, VarValue may return either the variable's address or its -// value, even when the expression is evaluated only for its value; the -// situation is reported by isAddr, the second component of the result. -// -// If !isAddr, the returned value is the one associated with the -// specific identifier. For example, -// var x int // VarValue(x) returns Const 0 here -// x = 1 // VarValue(x) returns Const 1 here -// -// It is not specified whether the value or the address is returned in -// any particular case, as it may depend upon optimizations performed -// during IR code generation, such as registerization, constant -// folding, avoidance of materialization of subexpressions, etc. -// -func (prog *Program) VarValue(obj *types.Var, pkg *Package, ref []ast.Node) (value Value, isAddr bool) { - // All references to a var are local to some function, possibly init. - fn := EnclosingFunction(pkg, ref) - if fn == nil { - return // e.g. def of struct field; IR not built? - } - - id := ref[0].(*ast.Ident) - - // Defining ident of a parameter? - if id.Pos() == obj.Pos() { - for _, param := range fn.Params { - if param.Object() == obj { - return param, false - } - } - } - - // Other ident? - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - if dr, ok := instr.(*DebugRef); ok { - if dr.Pos() == id.Pos() { - return dr.X, dr.IsAddr - } - } - } - } - - // Defining ident of package-level var? - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Global), true - } - - return // e.g. debug info not requested, or var optimized away -} diff --git a/vendor/honnef.co/go/tools/go/ir/ssa.go b/vendor/honnef.co/go/tools/go/ir/ssa.go deleted file mode 100644 index fc8e841147..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/ssa.go +++ /dev/null @@ -1,1883 +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 ir - -// This package defines a high-level intermediate representation for -// Go programs using static single-information (SSI) form. - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "go/types" - "sync" - - "golang.org/x/tools/go/types/typeutil" -) - -type ID int - -// A Program is a partial or complete Go program converted to IR form. -type Program struct { - Fset *token.FileSet // position information for the files of this Program - PrintFunc string // create ir.html for function specified in PrintFunc - imported map[string]*Package // all importable Packages, keyed by import path - packages map[*types.Package]*Package // all loaded Packages, keyed by object - mode BuilderMode // set of mode bits for IR construction - MethodSets typeutil.MethodSetCache // cache of type-checker's method-sets - - methodsMu sync.Mutex // guards the following maps: - methodSets typeutil.Map // maps type to its concrete methodSet - runtimeTypes typeutil.Map // types for which rtypes are needed - canon typeutil.Map // type canonicalization map - bounds map[*types.Func]*Function // bounds for curried x.Method closures - thunks map[selectionKey]*Function // thunks for T.Method expressions -} - -// A Package is a single analyzed Go package containing Members for -// all package-level functions, variables, constants and types it -// declares. These may be accessed directly via Members, or via the -// type-specific accessor methods Func, Type, Var and Const. -// -// Members also contains entries for "init" (the synthetic package -// initializer) and "init#%d", the nth declared init function, -// and unspecified other things too. -// -type Package struct { - Prog *Program // the owning program - Pkg *types.Package // the corresponding go/types.Package - Members map[string]Member // all package members keyed by name (incl. init and init#%d) - Functions []*Function // all functions, excluding anonymous ones - values map[types.Object]Value // package members (incl. types and methods), keyed by object - init *Function // Func("init"); the package's init function - debug bool // include full debug info in this package - printFunc string // which function to print in HTML form - - // The following fields are set transiently, then cleared - // after building. - buildOnce sync.Once // ensures package building occurs once - ninit int32 // number of init functions - info *types.Info // package type information - files []*ast.File // package ASTs -} - -// A Member is a member of a Go package, implemented by *NamedConst, -// *Global, *Function, or *Type; they are created by package-level -// const, var, func and type declarations respectively. -// -type Member interface { - Name() string // declared name of the package member - String() string // package-qualified name of the package member - RelString(*types.Package) string // like String, but relative refs are unqualified - Object() types.Object // typechecker's object for this member, if any - Type() types.Type // type of the package member - Token() token.Token // token.{VAR,FUNC,CONST,TYPE} - Package() *Package // the containing package -} - -// A Type is a Member of a Package representing a package-level named type. -type Type struct { - object *types.TypeName - pkg *Package -} - -// A NamedConst is a Member of a Package representing a package-level -// named constant. -// -// Pos() returns the position of the declaring ast.ValueSpec.Names[*] -// identifier. -// -// NB: a NamedConst is not a Value; it contains a constant Value, which -// it augments with the name and position of its 'const' declaration. -// -type NamedConst struct { - object *types.Const - Value *Const - pkg *Package -} - -// A Value is an IR value that can be referenced by an instruction. -type Value interface { - setID(ID) - - // Name returns the name of this value, and determines how - // this Value appears when used as an operand of an - // Instruction. - // - // This is the same as the source name for Parameters, - // Builtins, Functions, FreeVars, Globals. - // For constants, it is a representation of the constant's value - // and type. For all other Values this is the name of the - // virtual register defined by the instruction. - // - // The name of an IR Value is not semantically significant, - // and may not even be unique within a function. - Name() string - - // ID returns the ID of this value. IDs are unique within a single - // function and are densely numbered, but may contain gaps. - // Values and other Instructions share the same ID space. - // Globally, values are identified by their addresses. However, - // IDs exist to facilitate efficient storage of mappings between - // values and data when analysing functions. - // - // NB: IDs are allocated late in the IR construction process and - // are not available to early stages of said process. - ID() ID - - // If this value is an Instruction, String returns its - // disassembled form; otherwise it returns unspecified - // human-readable information about the Value, such as its - // kind, name and type. - String() string - - // Type returns the type of this value. Many instructions - // (e.g. IndexAddr) change their behaviour depending on the - // types of their operands. - Type() types.Type - - // Parent returns the function to which this Value belongs. - // It returns nil for named Functions, Builtin and Global. - Parent() *Function - - // Referrers returns the list of instructions that have this - // value as one of their operands; it may contain duplicates - // if an instruction has a repeated operand. - // - // Referrers actually returns a pointer through which the - // caller may perform mutations to the object's state. - // - // Referrers is currently only defined if Parent()!=nil, - // i.e. for the function-local values FreeVar, Parameter, - // Functions (iff anonymous) and all value-defining instructions. - // It returns nil for named Functions, Builtin and Global. - // - // Instruction.Operands contains the inverse of this relation. - Referrers() *[]Instruction - - Operands(rands []*Value) []*Value // nil for non-Instructions - - // Source returns the AST node responsible for creating this - // value. A single AST node may be responsible for more than one - // value, and not all values have an associated AST node. - // - // Do not use this method to find a Value given an ast.Expr; use - // ValueForExpr instead. - Source() ast.Node - - // Pos returns Source().Pos() if Source is not nil, else it - // returns token.NoPos. - Pos() token.Pos -} - -// An Instruction is an IR instruction that computes a new Value or -// has some effect. -// -// An Instruction that defines a value (e.g. BinOp) also implements -// the Value interface; an Instruction that only has an effect (e.g. Store) -// does not. -// -type Instruction interface { - setSource(ast.Node) - setID(ID) - - // String returns the disassembled form of this value. - // - // Examples of Instructions that are Values: - // "BinOp {+} t1 t2" (BinOp) - // "Call len t1" (Call) - // Note that the name of the Value is not printed. - // - // Examples of Instructions that are not Values: - // "Return t1" (Return) - // "Store {int} t2 t1" (Store) - // - // (The separation of Value.Name() from Value.String() is useful - // for some analyses which distinguish the operation from the - // value it defines, e.g., 'y = local int' is both an allocation - // of memory 'local int' and a definition of a pointer y.) - String() string - - // ID returns the ID of this instruction. IDs are unique within a single - // function and are densely numbered, but may contain gaps. - // Globally, instructions are identified by their addresses. However, - // IDs exist to facilitate efficient storage of mappings between - // instructions and data when analysing functions. - // - // NB: IDs are allocated late in the IR construction process and - // are not available to early stages of said process. - ID() ID - - // Parent returns the function to which this instruction - // belongs. - Parent() *Function - - // Block returns the basic block to which this instruction - // belongs. - Block() *BasicBlock - - // setBlock sets the basic block to which this instruction belongs. - setBlock(*BasicBlock) - - // Operands returns the operands of this instruction: the - // set of Values it references. - // - // Specifically, it appends their addresses to rands, a - // user-provided slice, and returns the resulting slice, - // permitting avoidance of memory allocation. - // - // The operands are appended in undefined order, but the order - // is consistent for a given Instruction; the addresses are - // always non-nil but may point to a nil Value. Clients may - // store through the pointers, e.g. to effect a value - // renaming. - // - // Value.Referrers is a subset of the inverse of this - // relation. (Referrers are not tracked for all types of - // Values.) - Operands(rands []*Value) []*Value - - Referrers() *[]Instruction // nil for non-Values - - // Source returns the AST node responsible for creating this - // instruction. A single AST node may be responsible for more than - // one instruction, and not all instructions have an associated - // AST node. - Source() ast.Node - - // Pos returns Source().Pos() if Source is not nil, else it - // returns token.NoPos. - Pos() token.Pos -} - -// A Node is a node in the IR value graph. Every concrete type that -// implements Node is also either a Value, an Instruction, or both. -// -// Node contains the methods common to Value and Instruction, plus the -// Operands and Referrers methods generalized to return nil for -// non-Instructions and non-Values, respectively. -// -// Node is provided to simplify IR graph algorithms. Clients should -// use the more specific and informative Value or Instruction -// interfaces where appropriate. -// -type Node interface { - setID(ID) - - // Common methods: - ID() ID - String() string - Source() ast.Node - Pos() token.Pos - Parent() *Function - - // Partial methods: - Operands(rands []*Value) []*Value // nil for non-Instructions - Referrers() *[]Instruction // nil for non-Values -} - -type Synthetic int - -const ( - SyntheticLoadedFromExportData Synthetic = iota + 1 - SyntheticPackageInitializer - SyntheticThunk - SyntheticWrapper - SyntheticBound -) - -func (syn Synthetic) String() string { - switch syn { - case SyntheticLoadedFromExportData: - return "loaded from export data" - case SyntheticPackageInitializer: - return "package initializer" - case SyntheticThunk: - return "thunk" - case SyntheticWrapper: - return "wrapper" - case SyntheticBound: - return "bound" - default: - return fmt.Sprintf("Synthetic(%d)", syn) - } -} - -// Function represents the parameters, results, and code of a function -// or method. -// -// If Blocks is nil, this indicates an external function for which no -// Go source code is available. In this case, FreeVars and Locals -// are nil too. Clients performing whole-program analysis must -// handle external functions specially. -// -// Blocks contains the function's control-flow graph (CFG). -// Blocks[0] is the function entry point; block order is not otherwise -// semantically significant, though it may affect the readability of -// the disassembly. -// To iterate over the blocks in dominance order, use DomPreorder(). -// -// A nested function (Parent()!=nil) that refers to one or more -// lexically enclosing local variables ("free variables") has FreeVars. -// Such functions cannot be called directly but require a -// value created by MakeClosure which, via its Bindings, supplies -// values for these parameters. -// -// If the function is a method (Signature.Recv() != nil) then the first -// element of Params is the receiver parameter. -// -// A Go package may declare many functions called "init". -// For each one, Object().Name() returns "init" but Name() returns -// "init#1", etc, in declaration order. -// -// Pos() returns the declaring ast.FuncLit.Type.Func or the position -// of the ast.FuncDecl.Name, if the function was explicit in the -// source. Synthetic wrappers, for which Synthetic != "", may share -// the same position as the function they wrap. -// Syntax.Pos() always returns the position of the declaring "func" token. -// -// Type() returns the function's Signature. -// -type Function struct { - node - - name string - object types.Object // a declared *types.Func or one of its wrappers - method *types.Selection // info about provenance of synthetic methods - Signature *types.Signature - - Synthetic Synthetic - parent *Function // enclosing function if anon; nil if global - Pkg *Package // enclosing package; nil for shared funcs (wrappers and error.Error) - Prog *Program // enclosing program - Params []*Parameter // function parameters; for methods, includes receiver - FreeVars []*FreeVar // free variables whose values must be supplied by closure - Locals []*Alloc // local variables of this function - Blocks []*BasicBlock // basic blocks of the function; nil => external - Exit *BasicBlock // The function's exit block - AnonFuncs []*Function // anonymous functions directly beneath this one - referrers []Instruction // referring instructions (iff Parent() != nil) - WillExit bool // Calling this function will always terminate the process - WillUnwind bool // Calling this function will always unwind (it will call runtime.Goexit or panic) - - *functionBody -} - -type functionBody struct { - // The following fields are set transiently during building, - // then cleared. - currentBlock *BasicBlock // where to emit code - objects map[types.Object]Value // addresses of local variables - namedResults []*Alloc // tuple of named results - implicitResults []*Alloc // tuple of results - targets *targets // linked stack of branch targets - lblocks map[*ast.Object]*lblock // labelled blocks - consts []*Const - wr *HTMLWriter - fakeExits BlockSet - blocksets [5]BlockSet - hasDefer bool -} - -func (fn *Function) results() []*Alloc { - if len(fn.namedResults) > 0 { - return fn.namedResults - } - return fn.implicitResults -} - -// BasicBlock represents an IR basic block. -// -// The final element of Instrs is always an explicit transfer of -// control (If, Jump, Return, Panic, or Unreachable). -// -// A block may contain no Instructions only if it is unreachable, -// i.e., Preds is nil. Empty blocks are typically pruned. -// -// BasicBlocks and their Preds/Succs relation form a (possibly cyclic) -// graph independent of the IR Value graph: the control-flow graph or -// CFG. It is illegal for multiple edges to exist between the same -// pair of blocks. -// -// Each BasicBlock is also a node in the dominator tree of the CFG. -// The tree may be navigated using Idom()/Dominees() and queried using -// Dominates(). -// -// The order of Preds and Succs is significant (to Phi and If -// instructions, respectively). -// -type BasicBlock struct { - Index int // index of this block within Parent().Blocks - Comment string // optional label; no semantic significance - parent *Function // parent function - Instrs []Instruction // instructions in order - Preds, Succs []*BasicBlock // predecessors and successors - succs2 [2]*BasicBlock // initial space for Succs - dom domInfo // dominator tree info - pdom domInfo // post-dominator tree info - post int - gaps int // number of nil Instrs (transient) - rundefers int // number of rundefers (transient) -} - -// Pure values ---------------------------------------- - -// A FreeVar represents a free variable of the function to which it -// belongs. -// -// FreeVars are used to implement anonymous functions, whose free -// variables are lexically captured in a closure formed by -// MakeClosure. The value of such a free var is an Alloc or another -// FreeVar and is considered a potentially escaping heap address, with -// pointer type. -// -// FreeVars are also used to implement bound method closures. Such a -// free var represents the receiver value and may be of any type that -// has concrete methods. -// -// Pos() returns the position of the value that was captured, which -// belongs to an enclosing function. -// -type FreeVar struct { - node - - name string - typ types.Type - parent *Function - referrers []Instruction - - // Transiently needed during building. - outer Value // the Value captured from the enclosing context. -} - -// A Parameter represents an input parameter of a function. -// -type Parameter struct { - register - - name string - object types.Object // a *types.Var; nil for non-source locals -} - -// A Const represents the value of a constant expression. -// -// The underlying type of a constant may be any boolean, numeric, or -// string type. In addition, a Const may represent the nil value of -// any reference type---interface, map, channel, pointer, slice, or -// function---but not "untyped nil". -// -// All source-level constant expressions are represented by a Const -// of the same type and value. -// -// Value holds the exact value of the constant, independent of its -// Type(), using the same representation as package go/constant uses for -// constants, or nil for a typed nil value. -// -// Pos() returns token.NoPos. -// -// Example printed form: -// Const {42} -// Const {"test"} -// Const {(3 + 4i)} -// -type Const struct { - register - - Value constant.Value -} - -// A Global is a named Value holding the address of a package-level -// variable. -// -// Pos() returns the position of the ast.ValueSpec.Names[*] -// identifier. -// -type Global struct { - node - - name string - object types.Object // a *types.Var; may be nil for synthetics e.g. init$guard - typ types.Type - - Pkg *Package -} - -// A Builtin represents a specific use of a built-in function, e.g. len. -// -// Builtins are immutable values. Builtins do not have addresses. -// Builtins can only appear in CallCommon.Func. -// -// Name() indicates the function: one of the built-in functions from the -// Go spec (excluding "make" and "new") or one of these ir-defined -// intrinsics: -// -// // wrapnilchk returns ptr if non-nil, panics otherwise. -// // (For use in indirection wrappers.) -// func ir:wrapnilchk(ptr *T, recvType, methodName string) *T -// -// Object() returns a *types.Builtin for built-ins defined by the spec, -// nil for others. -// -// Type() returns a *types.Signature representing the effective -// signature of the built-in for this call. -// -type Builtin struct { - node - - name string - sig *types.Signature -} - -// Value-defining instructions ---------------------------------------- - -// The Alloc instruction reserves space for a variable of the given type, -// zero-initializes it, and yields its address. -// -// Alloc values are always addresses, and have pointer types, so the -// type of the allocated variable is actually -// Type().Underlying().(*types.Pointer).Elem(). -// -// If Heap is false, Alloc allocates space in the function's -// activation record (frame); we refer to an Alloc(Heap=false) as a -// "stack" alloc. Each stack Alloc returns the same address each time -// it is executed within the same activation; the space is -// re-initialized to zero. -// -// If Heap is true, Alloc allocates space in the heap; we -// refer to an Alloc(Heap=true) as a "heap" alloc. Each heap Alloc -// returns a different address each time it is executed. -// -// When Alloc is applied to a channel, map or slice type, it returns -// the address of an uninitialized (nil) reference of that kind; store -// the result of MakeSlice, MakeMap or MakeChan in that location to -// instantiate these types. -// -// Pos() returns the ast.CompositeLit.Lbrace for a composite literal, -// or the ast.CallExpr.Rparen for a call to new() or for a call that -// allocates a varargs slice. -// -// Example printed form: -// t1 = StackAlloc <*int> -// t2 = HeapAlloc <*int> (new) -// -type Alloc struct { - register - Heap bool - index int // dense numbering; for lifting -} - -var _ Instruction = (*Sigma)(nil) -var _ Value = (*Sigma)(nil) - -// The Sigma instruction represents an SSI σ-node, which splits values -// at branches in the control flow. -// -// Conceptually, σ-nodes exist at the end of blocks that branch and -// constitute parallel assignments to one value per destination block. -// However, such a representation would be awkward to work with, so -// instead we place σ-nodes at the beginning of branch targets. The -// From field denotes to which incoming edge the node applies. -// -// Within a block, all σ-nodes must appear before all non-σ nodes. -// -// Example printed form: -// t2 = Sigma [#0] t1 (x) -// -type Sigma struct { - register - From *BasicBlock - X Value - - live bool // used during lifting -} - -// The Phi instruction represents an SSA φ-node, which combines values -// that differ across incoming control-flow edges and yields a new -// value. Within a block, all φ-nodes must appear before all non-φ, non-σ -// nodes. -// -// Pos() returns the position of the && or || for short-circuit -// control-flow joins, or that of the *Alloc for φ-nodes inserted -// during SSA renaming. -// -// Example printed form: -// t3 = Phi 2:t1 4:t2 (x) -// -type Phi struct { - register - Edges []Value // Edges[i] is value for Block().Preds[i] - - live bool // used during lifting -} - -// The Call instruction represents a function or method call. -// -// The Call instruction yields the function result if there is exactly -// one. Otherwise it returns a tuple, the components of which are -// accessed via Extract. -// -// See CallCommon for generic function call documentation. -// -// Pos() returns the ast.CallExpr.Lparen, if explicit in the source. -// -// Example printed form: -// t3 = Call <()> println t1 t2 -// t4 = Call <()> foo$1 -// t6 = Invoke t5.String -// -type Call struct { - register - Call CallCommon -} - -// The BinOp instruction yields the result of binary operation X Op Y. -// -// Pos() returns the ast.BinaryExpr.OpPos, if explicit in the source. -// -// Example printed form: -// t3 = BinOp {+} t2 t1 -// -type BinOp struct { - register - // One of: - // ADD SUB MUL QUO REM + - * / % - // AND OR XOR SHL SHR AND_NOT & | ^ << >> &^ - // EQL NEQ LSS LEQ GTR GEQ == != < <= < >= - Op token.Token - X, Y Value -} - -// The UnOp instruction yields the result of Op X. -// XOR is bitwise complement. -// SUB is negation. -// NOT is logical negation. -// -// -// Example printed form: -// t2 = UnOp {^} t1 -// -type UnOp struct { - register - Op token.Token // One of: NOT SUB XOR ! - ^ - X Value -} - -// The Load instruction loads a value from a memory address. -// -// For implicit memory loads, Pos() returns the position of the -// most closely associated source-level construct; the details are not -// specified. -// -// Example printed form: -// t2 = Load t1 -// -type Load struct { - register - X Value -} - -// The ChangeType instruction applies to X a value-preserving type -// change to Type(). -// -// Type changes are permitted: -// - between a named type and its underlying type. -// - between two named types of the same underlying type. -// - between (possibly named) pointers to identical base types. -// - from a bidirectional channel to a read- or write-channel, -// optionally adding/removing a name. -// -// This operation cannot fail dynamically. -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// t2 = ChangeType <*T> t1 -// -type ChangeType struct { - register - X Value -} - -// The Convert instruction yields the conversion of value X to type -// Type(). One or both of those types is basic (but possibly named). -// -// A conversion may change the value and representation of its operand. -// Conversions are permitted: -// - between real numeric types. -// - between complex numeric types. -// - between string and []byte or []rune. -// - between pointers and unsafe.Pointer. -// - between unsafe.Pointer and uintptr. -// - from (Unicode) integer to (UTF-8) string. -// A conversion may imply a type name change also. -// -// This operation cannot fail dynamically. -// -// Conversions of untyped string/number/bool constants to a specific -// representation are eliminated during IR construction. -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// t2 = Convert <[]byte> t1 -// -type Convert struct { - register - X Value -} - -// ChangeInterface constructs a value of one interface type from a -// value of another interface type known to be assignable to it. -// This operation cannot fail. -// -// Pos() returns the ast.CallExpr.Lparen if the instruction arose from -// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the -// instruction arose from an explicit e.(T) operation; or token.NoPos -// otherwise. -// -// Example printed form: -// t2 = ChangeInterface t1 -// -type ChangeInterface struct { - register - X Value -} - -// MakeInterface constructs an instance of an interface type from a -// value of a concrete type. -// -// Use Program.MethodSets.MethodSet(X.Type()) to find the method-set -// of X, and Program.MethodValue(m) to find the implementation of a method. -// -// To construct the zero value of an interface type T, use: -// NewConst(constant.MakeNil(), T, pos) -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// t2 = MakeInterface t1 -// -type MakeInterface struct { - register - X Value -} - -// The MakeClosure instruction yields a closure value whose code is -// Fn and whose free variables' values are supplied by Bindings. -// -// Type() returns a (possibly named) *types.Signature. -// -// Pos() returns the ast.FuncLit.Type.Func for a function literal -// closure or the ast.SelectorExpr.Sel for a bound method closure. -// -// Example printed form: -// t1 = MakeClosure foo$1 t1 t2 -// t5 = MakeClosure (T).foo$bound t4 -// -type MakeClosure struct { - register - Fn Value // always a *Function - Bindings []Value // values for each free variable in Fn.FreeVars -} - -// The MakeMap instruction creates a new hash-table-based map object -// and yields a value of kind map. -// -// Type() returns a (possibly named) *types.Map. -// -// Pos() returns the ast.CallExpr.Lparen, if created by make(map), or -// the ast.CompositeLit.Lbrack if created by a literal. -// -// Example printed form: -// t1 = MakeMap -// t2 = MakeMap t1 -// -type MakeMap struct { - register - Reserve Value // initial space reservation; nil => default -} - -// The MakeChan instruction creates a new channel object and yields a -// value of kind chan. -// -// Type() returns a (possibly named) *types.Chan. -// -// Pos() returns the ast.CallExpr.Lparen for the make(chan) that -// created it. -// -// Example printed form: -// t3 = MakeChan t1 -// t4 = MakeChan t2 -// -type MakeChan struct { - register - Size Value // int; size of buffer; zero => synchronous. -} - -// The MakeSlice instruction yields a slice of length Len backed by a -// newly allocated array of length Cap. -// -// Both Len and Cap must be non-nil Values of integer type. -// -// (Alloc(types.Array) followed by Slice will not suffice because -// Alloc can only create arrays of constant length.) -// -// Type() returns a (possibly named) *types.Slice. -// -// Pos() returns the ast.CallExpr.Lparen for the make([]T) that -// created it. -// -// Example printed form: -// t3 = MakeSlice <[]string> t1 t2 -// t4 = MakeSlice t1 t2 -// -type MakeSlice struct { - register - Len Value - Cap Value -} - -// The Slice instruction yields a slice of an existing string, slice -// or *array X between optional integer bounds Low and High. -// -// Dynamically, this instruction panics if X evaluates to a nil *array -// pointer. -// -// Type() returns string if the type of X was string, otherwise a -// *types.Slice with the same element type as X. -// -// Pos() returns the ast.SliceExpr.Lbrack if created by a x[:] slice -// operation, the ast.CompositeLit.Lbrace if created by a literal, or -// NoPos if not explicit in the source (e.g. a variadic argument slice). -// -// Example printed form: -// t4 = Slice <[]int> t3 t2 t1 -// -type Slice struct { - register - X Value // slice, string, or *array - Low, High, Max Value // each may be nil -} - -// The FieldAddr instruction yields the address of Field of *struct X. -// -// The field is identified by its index within the field list of the -// struct type of X. -// -// Dynamically, this instruction panics if X evaluates to a nil -// pointer. -// -// Type() returns a (possibly named) *types.Pointer. -// -// Pos() returns the position of the ast.SelectorExpr.Sel for the -// field, if explicit in the source. -// -// Example printed form: -// t2 = FieldAddr <*int> [0] (X) t1 -// -type FieldAddr struct { - register - X Value // *struct - Field int // field is X.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Struct).Field(Field) -} - -// The Field instruction yields the Field of struct X. -// -// The field is identified by its index within the field list of the -// struct type of X; by using numeric indices we avoid ambiguity of -// package-local identifiers and permit compact representations. -// -// Pos() returns the position of the ast.SelectorExpr.Sel for the -// field, if explicit in the source. -// -// Example printed form: -// t2 = FieldAddr [0] (X) t1 -// -type Field struct { - register - X Value // struct - Field int // index into X.Type().(*types.Struct).Fields -} - -// The IndexAddr instruction yields the address of the element at -// index Index of collection X. Index is an integer expression. -// -// The elements of maps and strings are not addressable; use StringLookup, MapLookup or -// MapUpdate instead. -// -// Dynamically, this instruction panics if X evaluates to a nil *array -// pointer. -// -// Type() returns a (possibly named) *types.Pointer. -// -// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if -// explicit in the source. -// -// Example printed form: -// t3 = IndexAddr <*int> t2 t1 -// -type IndexAddr struct { - register - X Value // slice or *array, - Index Value // numeric index -} - -// The Index instruction yields element Index of array X. -// -// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if -// explicit in the source. -// -// Example printed form: -// t3 = Index t2 t1 -// -type Index struct { - register - X Value // array - Index Value // integer index -} - -// The MapLookup instruction yields element Index of collection X, a map. -// -// If CommaOk, the result is a 2-tuple of the value above and a -// boolean indicating the result of a map membership test for the key. -// The components of the tuple are accessed using Extract. -// -// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source. -// -// Example printed form: -// t4 = MapLookup t3 t1 -// t6 = MapLookup <(string, bool)> t3 t2 -// -type MapLookup struct { - register - X Value // map - Index Value // key-typed index - CommaOk bool // return a value,ok pair -} - -// The StringLookup instruction yields element Index of collection X, a string. -// Index is an integer expression. -// -// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source. -// -// Example printed form: -// t3 = StringLookup t2 t1 -// -type StringLookup struct { - register - X Value // string - Index Value // numeric index -} - -// SelectState is a helper for Select. -// It represents one goal state and its corresponding communication. -// -type SelectState struct { - Dir types.ChanDir // direction of case (SendOnly or RecvOnly) - Chan Value // channel to use (for send or receive) - Send Value // value to send (for send) - Pos token.Pos // position of token.ARROW - DebugNode ast.Node // ast.SendStmt or ast.UnaryExpr(<-) [debug mode] -} - -// The Select instruction tests whether (or blocks until) one -// of the specified sent or received states is entered. -// -// Let n be the number of States for which Dir==RECV and Tᵢ (0 ≤ i < n) -// be the element type of each such state's Chan. -// Select returns an n+2-tuple -// (index int, recvOk bool, r₀ T₀, ... rₙ-1 Tₙ-1) -// The tuple's components, described below, must be accessed via the -// Extract instruction. -// -// If Blocking, select waits until exactly one state holds, i.e. a -// channel becomes ready for the designated operation of sending or -// receiving; select chooses one among the ready states -// pseudorandomly, performs the send or receive operation, and sets -// 'index' to the index of the chosen channel. -// -// If !Blocking, select doesn't block if no states hold; instead it -// returns immediately with index equal to -1. -// -// If the chosen channel was used for a receive, the rᵢ component is -// set to the received value, where i is the index of that state among -// all n receive states; otherwise rᵢ has the zero value of type Tᵢ. -// Note that the receive index i is not the same as the state -// index index. -// -// The second component of the triple, recvOk, is a boolean whose value -// is true iff the selected operation was a receive and the receive -// successfully yielded a value. -// -// Pos() returns the ast.SelectStmt.Select. -// -// Example printed form: -// t6 = SelectNonBlocking <(index int, ok bool, int)> [<-t4, t5<-t1] -// t11 = SelectBlocking <(index int, ok bool)> [] -// -type Select struct { - register - States []*SelectState - Blocking bool -} - -// The Range instruction yields an iterator over the domain and range -// of X, which must be a string or map. -// -// Elements are accessed via Next. -// -// Type() returns an opaque and degenerate "rangeIter" type. -// -// Pos() returns the ast.RangeStmt.For. -// -// Example printed form: -// t2 = Range t1 -// -type Range struct { - register - X Value // string or map -} - -// The Next instruction reads and advances the (map or string) -// iterator Iter and returns a 3-tuple value (ok, k, v). If the -// iterator is not exhausted, ok is true and k and v are the next -// elements of the domain and range, respectively. Otherwise ok is -// false and k and v are undefined. -// -// Components of the tuple are accessed using Extract. -// -// The IsString field distinguishes iterators over strings from those -// over maps, as the Type() alone is insufficient: consider -// map[int]rune. -// -// Type() returns a *types.Tuple for the triple (ok, k, v). -// The types of k and/or v may be types.Invalid. -// -// Example printed form: -// t5 = Next <(ok bool, k int, v rune)> t2 -// t5 = Next <(ok bool, k invalid type, v invalid type)> t2 -// -type Next struct { - register - Iter Value - IsString bool // true => string iterator; false => map iterator. -} - -// The TypeAssert instruction tests whether interface value X has type -// AssertedType. -// -// If !CommaOk, on success it returns v, the result of the conversion -// (defined below); on failure it panics. -// -// If CommaOk: on success it returns a pair (v, true) where v is the -// result of the conversion; on failure it returns (z, false) where z -// is AssertedType's zero value. The components of the pair must be -// accessed using the Extract instruction. -// -// If AssertedType is a concrete type, TypeAssert checks whether the -// dynamic type in interface X is equal to it, and if so, the result -// of the conversion is a copy of the value in the interface. -// -// If AssertedType is an interface, TypeAssert checks whether the -// dynamic type of the interface is assignable to it, and if so, the -// result of the conversion is a copy of the interface value X. -// If AssertedType is a superinterface of X.Type(), the operation will -// fail iff the operand is nil. (Contrast with ChangeInterface, which -// performs no nil-check.) -// -// Type() reflects the actual type of the result, possibly a -// 2-types.Tuple; AssertedType is the asserted type. -// -// Pos() returns the ast.CallExpr.Lparen if the instruction arose from -// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the -// instruction arose from an explicit e.(T) operation; or the -// ast.CaseClause.Case if the instruction arose from a case of a -// type-switch statement. -// -// Example printed form: -// t2 = TypeAssert t1 -// t4 = TypeAssert <(value fmt.Stringer, ok bool)> t1 -// -type TypeAssert struct { - register - X Value - AssertedType types.Type - CommaOk bool -} - -// The Extract instruction yields component Index of Tuple. -// -// This is used to access the results of instructions with multiple -// return values, such as Call, TypeAssert, Next, Recv, -// MapLookup and others. -// -// Example printed form: -// t7 = Extract [1] (ok) t4 -// -type Extract struct { - register - Tuple Value - Index int -} - -// Instructions executed for effect. They do not yield a value. -------------------- - -// The Jump instruction transfers control to the sole successor of its -// owning block. -// -// A Jump must be the last instruction of its containing BasicBlock. -// -// Pos() returns NoPos. -// -// Example printed form: -// Jump → b1 -// -type Jump struct { - anInstruction - Comment string -} - -// The Unreachable pseudo-instruction signals that execution cannot -// continue after the preceding function call because it terminates -// the process. -// -// The instruction acts as a control instruction, jumping to the exit -// block. However, this jump will never execute. -// -// An Unreachable instruction must be the last instruction of its -// containing BasicBlock. -// -// Example printed form: -// Unreachable → b1 -// -type Unreachable struct { - anInstruction -} - -// The If instruction transfers control to one of the two successors -// of its owning block, depending on the boolean Cond: the first if -// true, the second if false. -// -// An If instruction must be the last instruction of its containing -// BasicBlock. -// -// Pos() returns the *ast.IfStmt, if explicit in the source. -// -// Example printed form: -// If t2 → b1 b2 -// -type If struct { - anInstruction - Cond Value -} - -type ConstantSwitch struct { - anInstruction - Tag Value - // Constant branch conditions. A nil Value denotes the (implicit - // or explicit) default branch. - Conds []Value -} - -type TypeSwitch struct { - register - Tag Value - Conds []types.Type -} - -// The Return instruction returns values and control back to the calling -// function. -// -// len(Results) is always equal to the number of results in the -// function's signature. -// -// If len(Results) > 1, Return returns a tuple value with the specified -// components which the caller must access using Extract instructions. -// -// There is no instruction to return a ready-made tuple like those -// returned by a "value,ok"-mode TypeAssert, MapLookup or Recv or -// a tail-call to a function with multiple result parameters. -// -// Return must be the last instruction of its containing BasicBlock. -// Such a block has no successors. -// -// Pos() returns the ast.ReturnStmt.Return, if explicit in the source. -// -// Example printed form: -// Return -// Return t1 t2 -// -type Return struct { - anInstruction - Results []Value -} - -// The RunDefers instruction pops and invokes the entire stack of -// procedure calls pushed by Defer instructions in this function. -// -// It is legal to encounter multiple 'rundefers' instructions in a -// single control-flow path through a function; this is useful in -// the combined init() function, for example. -// -// Pos() returns NoPos. -// -// Example printed form: -// RunDefers -// -type RunDefers struct { - anInstruction -} - -// The Panic instruction initiates a panic with value X. -// -// A Panic instruction must be the last instruction of its containing -// BasicBlock, which must have one successor, the exit block. -// -// NB: 'go panic(x)' and 'defer panic(x)' do not use this instruction; -// they are treated as calls to a built-in function. -// -// Pos() returns the ast.CallExpr.Lparen if this panic was explicit -// in the source. -// -// Example printed form: -// Panic t1 -// -type Panic struct { - anInstruction - X Value // an interface{} -} - -// The Go instruction creates a new goroutine and calls the specified -// function within it. -// -// See CallCommon for generic function call documentation. -// -// Pos() returns the ast.GoStmt.Go. -// -// Example printed form: -// Go println t1 -// Go t3 -// GoInvoke t4.Bar t2 -// -type Go struct { - anInstruction - Call CallCommon -} - -// The Defer instruction pushes the specified call onto a stack of -// functions to be called by a RunDefers instruction or by a panic. -// -// See CallCommon for generic function call documentation. -// -// Pos() returns the ast.DeferStmt.Defer. -// -// Example printed form: -// Defer println t1 -// Defer t3 -// DeferInvoke t4.Bar t2 -// -type Defer struct { - anInstruction - Call CallCommon -} - -// The Send instruction sends X on channel Chan. -// -// Pos() returns the ast.SendStmt.Arrow, if explicit in the source. -// -// Example printed form: -// Send t2 t1 -// -type Send struct { - anInstruction - Chan, X Value -} - -// The Recv instruction receives from channel Chan. -// -// If CommaOk, the result is a 2-tuple of the value above -// and a boolean indicating the success of the receive. The -// components of the tuple are accessed using Extract. -// -// Pos() returns the ast.UnaryExpr.OpPos, if explicit in the source. -// For receive operations implicit in ranging over a channel, -// Pos() returns the ast.RangeStmt.For. -// -// Example printed form: -// t2 = Recv t1 -// t3 = Recv <(int, bool)> t1 -type Recv struct { - register - Chan Value - CommaOk bool -} - -// The Store instruction stores Val at address Addr. -// Stores can be of arbitrary types. -// -// Pos() returns the position of the source-level construct most closely -// associated with the memory store operation. -// Since implicit memory stores are numerous and varied and depend upon -// implementation choices, the details are not specified. -// -// Example printed form: -// Store {int} t2 t1 -// -type Store struct { - anInstruction - Addr Value - Val Value -} - -// The BlankStore instruction is emitted for assignments to the blank -// identifier. -// -// BlankStore is a pseudo-instruction: it has no dynamic effect. -// -// Pos() returns NoPos. -// -// Example printed form: -// BlankStore t1 -// -type BlankStore struct { - anInstruction - Val Value -} - -// The MapUpdate instruction updates the association of Map[Key] to -// Value. -// -// Pos() returns the ast.KeyValueExpr.Colon or ast.IndexExpr.Lbrack, -// if explicit in the source. -// -// Example printed form: -// MapUpdate t3 t1 t2 -// -type MapUpdate struct { - anInstruction - Map Value - Key Value - Value Value -} - -// A DebugRef instruction maps a source-level expression Expr to the -// IR value X that represents the value (!IsAddr) or address (IsAddr) -// of that expression. -// -// DebugRef is a pseudo-instruction: it has no dynamic effect. -// -// Pos() returns Expr.Pos(), the start position of the source-level -// expression. This is not the same as the "designated" token as -// documented at Value.Pos(). e.g. CallExpr.Pos() does not return the -// position of the ("designated") Lparen token. -// -// DebugRefs are generated only for functions built with debugging -// enabled; see Package.SetDebugMode() and the GlobalDebug builder -// mode flag. -// -// DebugRefs are not emitted for ast.Idents referring to constants or -// predeclared identifiers, since they are trivial and numerous. -// Nor are they emitted for ast.ParenExprs. -// -// (By representing these as instructions, rather than out-of-band, -// consistency is maintained during transformation passes by the -// ordinary SSA renaming machinery.) -// -// Example printed form: -// ; *ast.CallExpr @ 102:9 is t5 -// ; var x float64 @ 109:72 is x -// ; address of *ast.CompositeLit @ 216:10 is t0 -// -type DebugRef struct { - anInstruction - Expr ast.Expr // the referring expression (never *ast.ParenExpr) - object types.Object // the identity of the source var/func - IsAddr bool // Expr is addressable and X is the address it denotes - X Value // the value or address of Expr -} - -// Embeddable mix-ins and helpers for common parts of other structs. ----------- - -// register is a mix-in embedded by all IR values that are also -// instructions, i.e. virtual registers, and provides a uniform -// implementation of most of the Value interface: Value.Name() is a -// numbered register (e.g. "t0"); the other methods are field accessors. -// -// Temporary names are automatically assigned to each register on -// completion of building a function in IR form. -// -type register struct { - anInstruction - typ types.Type // type of virtual register - referrers []Instruction -} - -type node struct { - source ast.Node - id ID -} - -func (n *node) setID(id ID) { n.id = id } -func (n node) ID() ID { return n.id } - -func (n *node) setSource(source ast.Node) { n.source = source } -func (n *node) Source() ast.Node { return n.source } - -func (n *node) Pos() token.Pos { - if n.source != nil { - return n.source.Pos() - } - return token.NoPos -} - -// anInstruction is a mix-in embedded by all Instructions. -// It provides the implementations of the Block and setBlock methods. -type anInstruction struct { - node - block *BasicBlock // the basic block of this instruction -} - -// CallCommon is contained by Go, Defer and Call to hold the -// common parts of a function or method call. -// -// Each CallCommon exists in one of two modes, function call and -// interface method invocation, or "call" and "invoke" for short. -// -// 1. "call" mode: when Method is nil (!IsInvoke), a CallCommon -// represents an ordinary function call of the value in Value, -// which may be a *Builtin, a *Function or any other value of kind -// 'func'. -// -// Value may be one of: -// (a) a *Function, indicating a statically dispatched call -// to a package-level function, an anonymous function, or -// a method of a named type. -// (b) a *MakeClosure, indicating an immediately applied -// function literal with free variables. -// (c) a *Builtin, indicating a statically dispatched call -// to a built-in function. -// (d) any other value, indicating a dynamically dispatched -// function call. -// StaticCallee returns the identity of the callee in cases -// (a) and (b), nil otherwise. -// -// Args contains the arguments to the call. If Value is a method, -// Args[0] contains the receiver parameter. -// -// Example printed form: -// t3 = Call <()> println t1 t2 -// Go t3 -// Defer t3 -// -// 2. "invoke" mode: when Method is non-nil (IsInvoke), a CallCommon -// represents a dynamically dispatched call to an interface method. -// In this mode, Value is the interface value and Method is the -// interface's abstract method. Note: an abstract method may be -// shared by multiple interfaces due to embedding; Value.Type() -// provides the specific interface used for this call. -// -// Value is implicitly supplied to the concrete method implementation -// as the receiver parameter; in other words, Args[0] holds not the -// receiver but the first true argument. -// -// Example printed form: -// t6 = Invoke t5.String -// GoInvoke t4.Bar t2 -// DeferInvoke t4.Bar t2 -// -// For all calls to variadic functions (Signature().Variadic()), -// the last element of Args is a slice. -// -type CallCommon struct { - Value Value // receiver (invoke mode) or func value (call mode) - Method *types.Func // abstract method (invoke mode) - Args []Value // actual parameters (in static method call, includes receiver) - Results Value -} - -// IsInvoke returns true if this call has "invoke" (not "call") mode. -func (c *CallCommon) IsInvoke() bool { - return c.Method != nil -} - -// Signature returns the signature of the called function. -// -// For an "invoke"-mode call, the signature of the interface method is -// returned. -// -// In either "call" or "invoke" mode, if the callee is a method, its -// receiver is represented by sig.Recv, not sig.Params().At(0). -// -func (c *CallCommon) Signature() *types.Signature { - if c.Method != nil { - return c.Method.Type().(*types.Signature) - } - return c.Value.Type().Underlying().(*types.Signature) -} - -// StaticCallee returns the callee if this is a trivially static -// "call"-mode call to a function. -func (c *CallCommon) StaticCallee() *Function { - switch fn := c.Value.(type) { - case *Function: - return fn - case *MakeClosure: - return fn.Fn.(*Function) - } - return nil -} - -// Description returns a description of the mode of this call suitable -// for a user interface, e.g., "static method call". -func (c *CallCommon) Description() string { - switch fn := c.Value.(type) { - case *Builtin: - return "built-in function call" - case *MakeClosure: - return "static function closure call" - case *Function: - if fn.Signature.Recv() != nil { - return "static method call" - } - return "static function call" - } - if c.IsInvoke() { - return "dynamic method call" // ("invoke" mode) - } - return "dynamic function call" -} - -// The CallInstruction interface, implemented by *Go, *Defer and *Call, -// exposes the common parts of function-calling instructions, -// yet provides a way back to the Value defined by *Call alone. -// -type CallInstruction interface { - Instruction - Common() *CallCommon // returns the common parts of the call - Value() *Call -} - -func (s *Call) Common() *CallCommon { return &s.Call } -func (s *Defer) Common() *CallCommon { return &s.Call } -func (s *Go) Common() *CallCommon { return &s.Call } - -func (s *Call) Value() *Call { return s } -func (s *Defer) Value() *Call { return nil } -func (s *Go) Value() *Call { return nil } - -func (v *Builtin) Type() types.Type { return v.sig } -func (v *Builtin) Name() string { return v.name } -func (*Builtin) Referrers() *[]Instruction { return nil } -func (v *Builtin) Pos() token.Pos { return token.NoPos } -func (v *Builtin) Object() types.Object { return types.Universe.Lookup(v.name) } -func (v *Builtin) Parent() *Function { return nil } - -func (v *FreeVar) Type() types.Type { return v.typ } -func (v *FreeVar) Name() string { return v.name } -func (v *FreeVar) Referrers() *[]Instruction { return &v.referrers } -func (v *FreeVar) Parent() *Function { return v.parent } - -func (v *Global) Type() types.Type { return v.typ } -func (v *Global) Name() string { return v.name } -func (v *Global) Parent() *Function { return nil } -func (v *Global) Referrers() *[]Instruction { return nil } -func (v *Global) Token() token.Token { return token.VAR } -func (v *Global) Object() types.Object { return v.object } -func (v *Global) String() string { return v.RelString(nil) } -func (v *Global) Package() *Package { return v.Pkg } -func (v *Global) RelString(from *types.Package) string { return relString(v, from) } - -func (v *Function) Name() string { return v.name } -func (v *Function) Type() types.Type { return v.Signature } -func (v *Function) Token() token.Token { return token.FUNC } -func (v *Function) Object() types.Object { return v.object } -func (v *Function) String() string { return v.RelString(nil) } -func (v *Function) Package() *Package { return v.Pkg } -func (v *Function) Parent() *Function { return v.parent } -func (v *Function) Referrers() *[]Instruction { - if v.parent != nil { - return &v.referrers - } - return nil -} - -func (v *Parameter) Object() types.Object { return v.object } - -func (v *Alloc) Type() types.Type { return v.typ } -func (v *Alloc) Referrers() *[]Instruction { return &v.referrers } - -func (v *register) Type() types.Type { return v.typ } -func (v *register) setType(typ types.Type) { v.typ = typ } -func (v *register) Name() string { return fmt.Sprintf("t%d", v.id) } -func (v *register) Referrers() *[]Instruction { return &v.referrers } - -func (v *anInstruction) Parent() *Function { return v.block.parent } -func (v *anInstruction) Block() *BasicBlock { return v.block } -func (v *anInstruction) setBlock(block *BasicBlock) { v.block = block } -func (v *anInstruction) Referrers() *[]Instruction { return nil } - -func (t *Type) Name() string { return t.object.Name() } -func (t *Type) Pos() token.Pos { return t.object.Pos() } -func (t *Type) Type() types.Type { return t.object.Type() } -func (t *Type) Token() token.Token { return token.TYPE } -func (t *Type) Object() types.Object { return t.object } -func (t *Type) String() string { return t.RelString(nil) } -func (t *Type) Package() *Package { return t.pkg } -func (t *Type) RelString(from *types.Package) string { return relString(t, from) } - -func (c *NamedConst) Name() string { return c.object.Name() } -func (c *NamedConst) Pos() token.Pos { return c.object.Pos() } -func (c *NamedConst) String() string { return c.RelString(nil) } -func (c *NamedConst) Type() types.Type { return c.object.Type() } -func (c *NamedConst) Token() token.Token { return token.CONST } -func (c *NamedConst) Object() types.Object { return c.object } -func (c *NamedConst) Package() *Package { return c.pkg } -func (c *NamedConst) RelString(from *types.Package) string { return relString(c, from) } - -// Func returns the package-level function of the specified name, -// or nil if not found. -// -func (p *Package) Func(name string) (f *Function) { - f, _ = p.Members[name].(*Function) - return -} - -// Var returns the package-level variable of the specified name, -// or nil if not found. -// -func (p *Package) Var(name string) (g *Global) { - g, _ = p.Members[name].(*Global) - return -} - -// Const returns the package-level constant of the specified name, -// or nil if not found. -// -func (p *Package) Const(name string) (c *NamedConst) { - c, _ = p.Members[name].(*NamedConst) - return -} - -// Type returns the package-level type of the specified name, -// or nil if not found. -// -func (p *Package) Type(name string) (t *Type) { - t, _ = p.Members[name].(*Type) - return -} - -func (s *DebugRef) Pos() token.Pos { return s.Expr.Pos() } - -// Operands. - -func (v *Alloc) Operands(rands []*Value) []*Value { - return rands -} - -func (v *BinOp) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Y) -} - -func (c *CallCommon) Operands(rands []*Value) []*Value { - rands = append(rands, &c.Value) - for i := range c.Args { - rands = append(rands, &c.Args[i]) - } - return rands -} - -func (s *Go) Operands(rands []*Value) []*Value { - return s.Call.Operands(rands) -} - -func (s *Call) Operands(rands []*Value) []*Value { - return s.Call.Operands(rands) -} - -func (s *Defer) Operands(rands []*Value) []*Value { - return s.Call.Operands(rands) -} - -func (v *ChangeInterface) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *ChangeType) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *Convert) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (s *DebugRef) Operands(rands []*Value) []*Value { - return append(rands, &s.X) -} - -func (v *Extract) Operands(rands []*Value) []*Value { - return append(rands, &v.Tuple) -} - -func (v *Field) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *FieldAddr) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (s *If) Operands(rands []*Value) []*Value { - return append(rands, &s.Cond) -} - -func (s *ConstantSwitch) Operands(rands []*Value) []*Value { - rands = append(rands, &s.Tag) - for i := range s.Conds { - rands = append(rands, &s.Conds[i]) - } - return rands -} - -func (s *TypeSwitch) Operands(rands []*Value) []*Value { - rands = append(rands, &s.Tag) - return rands -} - -func (v *Index) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (v *IndexAddr) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (*Jump) Operands(rands []*Value) []*Value { - return rands -} - -func (*Unreachable) Operands(rands []*Value) []*Value { - return rands -} - -func (v *MapLookup) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (v *StringLookup) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (v *MakeChan) Operands(rands []*Value) []*Value { - return append(rands, &v.Size) -} - -func (v *MakeClosure) Operands(rands []*Value) []*Value { - rands = append(rands, &v.Fn) - for i := range v.Bindings { - rands = append(rands, &v.Bindings[i]) - } - return rands -} - -func (v *MakeInterface) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *MakeMap) Operands(rands []*Value) []*Value { - return append(rands, &v.Reserve) -} - -func (v *MakeSlice) Operands(rands []*Value) []*Value { - return append(rands, &v.Len, &v.Cap) -} - -func (v *MapUpdate) Operands(rands []*Value) []*Value { - return append(rands, &v.Map, &v.Key, &v.Value) -} - -func (v *Next) Operands(rands []*Value) []*Value { - return append(rands, &v.Iter) -} - -func (s *Panic) Operands(rands []*Value) []*Value { - return append(rands, &s.X) -} - -func (v *Sigma) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *Phi) Operands(rands []*Value) []*Value { - for i := range v.Edges { - rands = append(rands, &v.Edges[i]) - } - return rands -} - -func (v *Range) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (s *Return) Operands(rands []*Value) []*Value { - for i := range s.Results { - rands = append(rands, &s.Results[i]) - } - return rands -} - -func (*RunDefers) Operands(rands []*Value) []*Value { - return rands -} - -func (v *Select) Operands(rands []*Value) []*Value { - for i := range v.States { - rands = append(rands, &v.States[i].Chan, &v.States[i].Send) - } - return rands -} - -func (s *Send) Operands(rands []*Value) []*Value { - return append(rands, &s.Chan, &s.X) -} - -func (recv *Recv) Operands(rands []*Value) []*Value { - return append(rands, &recv.Chan) -} - -func (v *Slice) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Low, &v.High, &v.Max) -} - -func (s *Store) Operands(rands []*Value) []*Value { - return append(rands, &s.Addr, &s.Val) -} - -func (s *BlankStore) Operands(rands []*Value) []*Value { - return append(rands, &s.Val) -} - -func (v *TypeAssert) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *UnOp) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *Load) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -// Non-Instruction Values: -func (v *Builtin) Operands(rands []*Value) []*Value { return rands } -func (v *FreeVar) Operands(rands []*Value) []*Value { return rands } -func (v *Const) Operands(rands []*Value) []*Value { return rands } -func (v *Function) Operands(rands []*Value) []*Value { return rands } -func (v *Global) Operands(rands []*Value) []*Value { return rands } -func (v *Parameter) Operands(rands []*Value) []*Value { return rands } diff --git a/vendor/honnef.co/go/tools/go/ir/staticcheck.conf b/vendor/honnef.co/go/tools/go/ir/staticcheck.conf deleted file mode 100644 index d7b38bc356..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/staticcheck.conf +++ /dev/null @@ -1,3 +0,0 @@ -# ssa/... is mostly imported from upstream and we don't want to -# deviate from it too much, hence disabling SA1019 -checks = ["inherit", "-SA1019"] diff --git a/vendor/honnef.co/go/tools/go/ir/util.go b/vendor/honnef.co/go/tools/go/ir/util.go deleted file mode 100644 index df0f8bf971..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/util.go +++ /dev/null @@ -1,89 +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 ir - -// This file defines a number of miscellaneous utility functions. - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "io" - "os" - - "golang.org/x/tools/go/ast/astutil" -) - -//// AST utilities - -func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) } - -// isBlankIdent returns true iff e is an Ident with name "_". -// They have no associated types.Object, and thus no type. -// -func isBlankIdent(e ast.Expr) bool { - id, ok := e.(*ast.Ident) - return ok && id.Name == "_" -} - -//// Type utilities. Some of these belong in go/types. - -// isPointer returns true for types whose underlying type is a pointer. -func isPointer(typ types.Type) bool { - _, ok := typ.Underlying().(*types.Pointer) - return ok -} - -func isInterface(T types.Type) bool { return types.IsInterface(T) } - -// deref returns a pointer's element type; otherwise it returns typ. -func deref(typ types.Type) types.Type { - if p, ok := typ.Underlying().(*types.Pointer); ok { - return p.Elem() - } - return typ -} - -// recvType returns the receiver type of method obj. -func recvType(obj *types.Func) types.Type { - return obj.Type().(*types.Signature).Recv().Type() -} - -// logStack prints the formatted "start" message to stderr and -// returns a closure that prints the corresponding "end" message. -// Call using 'defer logStack(...)()' to show builder stack on panic. -// Don't forget trailing parens! -// -func logStack(format string, args ...interface{}) func() { - msg := fmt.Sprintf(format, args...) - io.WriteString(os.Stderr, msg) - io.WriteString(os.Stderr, "\n") - return func() { - io.WriteString(os.Stderr, msg) - io.WriteString(os.Stderr, " end\n") - } -} - -// newVar creates a 'var' for use in a types.Tuple. -func newVar(name string, typ types.Type) *types.Var { - return types.NewParam(token.NoPos, nil, name, typ) -} - -// anonVar creates an anonymous 'var' for use in a types.Tuple. -func anonVar(typ types.Type) *types.Var { - return newVar("", typ) -} - -var lenResults = types.NewTuple(anonVar(tInt)) - -// makeLen returns the len builtin specialized to type func(T)int. -func makeLen(T types.Type) *Builtin { - lenParams := types.NewTuple(anonVar(T)) - return &Builtin{ - name: "len", - sig: types.NewSignature(nil, lenParams, lenResults, false), - } -} diff --git a/vendor/honnef.co/go/tools/go/ir/wrappers.go b/vendor/honnef.co/go/tools/go/ir/wrappers.go deleted file mode 100644 index 1d51b5dc9d..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/wrappers.go +++ /dev/null @@ -1,290 +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 ir - -// This file defines synthesis of Functions that delegate to declared -// methods; they come in three kinds: -// -// (1) wrappers: methods that wrap declared methods, performing -// implicit pointer indirections and embedded field selections. -// -// (2) thunks: funcs that wrap declared methods. Like wrappers, -// thunks perform indirections and field selections. The thunk's -// first parameter is used as the receiver for the method call. -// -// (3) bounds: funcs that wrap declared methods. The bound's sole -// free variable, supplied by a closure, is used as the receiver -// for the method call. No indirections or field selections are -// performed since they can be done before the call. - -import ( - "fmt" - - "go/types" -) - -// -- wrappers ----------------------------------------------------------- - -// makeWrapper returns a synthetic method that delegates to the -// declared method denoted by meth.Obj(), first performing any -// necessary pointer indirections or field selections implied by meth. -// -// The resulting method's receiver type is meth.Recv(). -// -// This function is versatile but quite subtle! Consider the -// following axes of variation when making changes: -// - optional receiver indirection -// - optional implicit field selections -// - meth.Obj() may denote a concrete or an interface method -// - the result may be a thunk or a wrapper. -// -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -// -func makeWrapper(prog *Program, sel *types.Selection) *Function { - obj := sel.Obj().(*types.Func) // the declared function - sig := sel.Type().(*types.Signature) // type of this wrapper - - var recv *types.Var // wrapper's receiver or thunk's params[0] - name := obj.Name() - var description Synthetic - var start int // first regular param - if sel.Kind() == types.MethodExpr { - name += "$thunk" - description = SyntheticThunk - recv = sig.Params().At(0) - start = 1 - } else { - description = SyntheticWrapper - recv = sig.Recv() - } - - if prog.mode&LogSource != 0 { - defer logStack("make %s to (%s)", description, recv.Type())() - } - fn := &Function{ - name: name, - method: sel, - object: obj, - Signature: sig, - Synthetic: description, - Prog: prog, - functionBody: new(functionBody), - } - fn.initHTML(prog.PrintFunc) - fn.startBody() - fn.addSpilledParam(recv, nil) - createParams(fn, start) - - indices := sel.Index() - - var v Value = fn.Locals[0] // spilled receiver - if isPointer(sel.Recv()) { - v = emitLoad(fn, v, nil) - - // For simple indirection wrappers, perform an informative nil-check: - // "value method (T).f called using nil *T pointer" - if len(indices) == 1 && !isPointer(recvType(obj)) { - var c Call - c.Call.Value = &Builtin{ - name: "ir:wrapnilchk", - sig: types.NewSignature(nil, - types.NewTuple(anonVar(sel.Recv()), anonVar(tString), anonVar(tString)), - types.NewTuple(anonVar(sel.Recv())), false), - } - c.Call.Args = []Value{ - v, - emitConst(fn, stringConst(deref(sel.Recv()).String())), - emitConst(fn, stringConst(sel.Obj().Name())), - } - c.setType(v.Type()) - v = fn.emit(&c, nil) - } - } - - // Invariant: v is a pointer, either - // value of *A receiver param, or - // address of A spilled receiver. - - // We use pointer arithmetic (FieldAddr possibly followed by - // Load) in preference to value extraction (Field possibly - // preceded by Load). - - v = emitImplicitSelections(fn, v, indices[:len(indices)-1], nil) - - // Invariant: v is a pointer, either - // value of implicit *C field, or - // address of implicit C field. - - var c Call - if r := recvType(obj); !isInterface(r) { // concrete method - if !isPointer(r) { - v = emitLoad(fn, v, nil) - } - c.Call.Value = prog.declaredFunc(obj) - c.Call.Args = append(c.Call.Args, v) - } else { - c.Call.Method = obj - c.Call.Value = emitLoad(fn, v, nil) - } - for _, arg := range fn.Params[1:] { - c.Call.Args = append(c.Call.Args, arg) - } - emitTailCall(fn, &c, nil) - fn.finishBody() - return fn -} - -// createParams creates parameters for wrapper method fn based on its -// Signature.Params, which do not include the receiver. -// start is the index of the first regular parameter to use. -// -func createParams(fn *Function, start int) { - tparams := fn.Signature.Params() - for i, n := start, tparams.Len(); i < n; i++ { - fn.addParamObj(tparams.At(i), nil) - } -} - -// -- bounds ----------------------------------------------------------- - -// makeBound returns a bound method wrapper (or "bound"), a synthetic -// function that delegates to a concrete or interface method denoted -// by obj. The resulting function has no receiver, but has one free -// variable which will be used as the method's receiver in the -// tail-call. -// -// Use MakeClosure with such a wrapper to construct a bound method -// closure. e.g.: -// -// type T int or: type T interface { meth() } -// func (t T) meth() -// var t T -// f := t.meth -// f() // calls t.meth() -// -// f is a closure of a synthetic wrapper defined as if by: -// -// f := func() { return t.meth() } -// -// Unlike makeWrapper, makeBound need perform no indirection or field -// selections because that can be done before the closure is -// constructed. -// -// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu) -// -func makeBound(prog *Program, obj *types.Func) *Function { - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - fn, ok := prog.bounds[obj] - if !ok { - if prog.mode&LogSource != 0 { - defer logStack("%s", SyntheticBound)() - } - fn = &Function{ - name: obj.Name() + "$bound", - object: obj, - Signature: changeRecv(obj.Type().(*types.Signature), nil), // drop receiver - Synthetic: SyntheticBound, - Prog: prog, - functionBody: new(functionBody), - } - fn.initHTML(prog.PrintFunc) - - fv := &FreeVar{name: "recv", typ: recvType(obj), parent: fn} - fn.FreeVars = []*FreeVar{fv} - fn.startBody() - createParams(fn, 0) - var c Call - - if !isInterface(recvType(obj)) { // concrete - c.Call.Value = prog.declaredFunc(obj) - c.Call.Args = []Value{fv} - } else { - c.Call.Value = fv - c.Call.Method = obj - } - for _, arg := range fn.Params { - c.Call.Args = append(c.Call.Args, arg) - } - emitTailCall(fn, &c, nil) - fn.finishBody() - - prog.bounds[obj] = fn - } - return fn -} - -// -- thunks ----------------------------------------------------------- - -// makeThunk returns a thunk, a synthetic function that delegates to a -// concrete or interface method denoted by sel.Obj(). The resulting -// function has no receiver, but has an additional (first) regular -// parameter. -// -// Precondition: sel.Kind() == types.MethodExpr. -// -// type T int or: type T interface { meth() } -// func (t T) meth() -// f := T.meth -// var t T -// f(t) // calls t.meth() -// -// f is a synthetic wrapper defined as if by: -// -// f := func(t T) { return t.meth() } -// -// TODO(adonovan): opt: currently the stub is created even when used -// directly in a function call: C.f(i, 0). This is less efficient -// than inlining the stub. -// -// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu) -// -func makeThunk(prog *Program, sel *types.Selection) *Function { - if sel.Kind() != types.MethodExpr { - panic(sel) - } - - key := selectionKey{ - kind: sel.Kind(), - recv: sel.Recv(), - obj: sel.Obj(), - index: fmt.Sprint(sel.Index()), - indirect: sel.Indirect(), - } - - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - - // Canonicalize key.recv to avoid constructing duplicate thunks. - canonRecv, ok := prog.canon.At(key.recv).(types.Type) - if !ok { - canonRecv = key.recv - prog.canon.Set(key.recv, canonRecv) - } - key.recv = canonRecv - - fn, ok := prog.thunks[key] - if !ok { - fn = makeWrapper(prog, sel) - if fn.Signature.Recv() != nil { - panic(fn) // unexpected receiver - } - prog.thunks[key] = fn - } - return fn -} - -func changeRecv(s *types.Signature, recv *types.Var) *types.Signature { - return types.NewSignature(recv, s.Params(), s.Results(), s.Variadic()) -} - -// selectionKey is like types.Selection but a usable map key. -type selectionKey struct { - kind types.SelectionKind - recv types.Type // canonicalized via Program.canon - obj types.Object - index string - indirect bool -} diff --git a/vendor/honnef.co/go/tools/go/ir/write.go b/vendor/honnef.co/go/tools/go/ir/write.go deleted file mode 100644 index b936bc9852..0000000000 --- a/vendor/honnef.co/go/tools/go/ir/write.go +++ /dev/null @@ -1,5 +0,0 @@ -package ir - -func NewJump(parent *BasicBlock) *Jump { - return &Jump{anInstruction{block: parent}, ""} -} diff --git a/vendor/honnef.co/go/tools/go/loader/buildid.go b/vendor/honnef.co/go/tools/go/loader/buildid.go deleted file mode 100644 index 32c026b7db..0000000000 --- a/vendor/honnef.co/go/tools/go/loader/buildid.go +++ /dev/null @@ -1,238 +0,0 @@ -// 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 loader - -import ( - "bytes" - "debug/elf" - "errors" - "fmt" - "io" - "os" - "strconv" - "strings" -) - -var errBuildIDMalformed = fmt.Errorf("malformed object file") - -var ( - bangArch = []byte("!") - pkgdef = []byte("__.PKGDEF") - goobject = []byte("go object ") - buildid = []byte("build id ") -) - -// ReadFile reads the build ID from an archive or executable file. -func ReadFile(name string) (id string, err error) { - f, err := os.Open(name) - if err != nil { - return "", err - } - defer f.Close() - - buf := make([]byte, 8) - if _, err := f.ReadAt(buf, 0); err != nil { - return "", err - } - if string(buf) != "!\n" { - if string(buf) == "\n" { - return "", errors.New("unsupported") - } - return readBinary(name, f) - } - - // Read just enough of the target to fetch the build ID. - // The archive is expected to look like: - // - // ! - // __.PKGDEF 0 0 0 644 7955 ` - // go object darwin amd64 devel X:none - // build id "b41e5c45250e25c9fd5e9f9a1de7857ea0d41224" - // - // The variable-sized strings are GOOS, GOARCH, and the experiment list (X:none). - // Reading the first 1024 bytes should be plenty. - data := make([]byte, 1024) - n, err := io.ReadFull(f, data) - if err != nil && n == 0 { - return "", err - } - - tryGccgo := func() (string, error) { - return readGccgoArchive(name, f) - } - - // Archive header. - for i := 0; ; i++ { // returns during i==3 - j := bytes.IndexByte(data, '\n') - if j < 0 { - return tryGccgo() - } - line := data[:j] - data = data[j+1:] - switch i { - case 0: - if !bytes.Equal(line, bangArch) { - return tryGccgo() - } - case 1: - if !bytes.HasPrefix(line, pkgdef) { - return tryGccgo() - } - case 2: - if !bytes.HasPrefix(line, goobject) { - return tryGccgo() - } - case 3: - if !bytes.HasPrefix(line, buildid) { - // Found the object header, just doesn't have a build id line. - // Treat as successful, with empty build id. - return "", nil - } - id, err := strconv.Unquote(string(line[len(buildid):])) - if err != nil { - return tryGccgo() - } - return id, nil - } - } -} - -// readGccgoArchive tries to parse the archive as a standard Unix -// archive file, and fetch the build ID from the _buildid.o entry. -// The _buildid.o entry is written by (*Builder).gccgoBuildIDELFFile -// in cmd/go/internal/work/exec.go. -func readGccgoArchive(name string, f *os.File) (string, error) { - bad := func() (string, error) { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} - } - - off := int64(8) - for { - if _, err := f.Seek(off, io.SeekStart); err != nil { - return "", err - } - - // TODO(iant): Make a debug/ar package, and use it - // here and in cmd/link. - var hdr [60]byte - if _, err := io.ReadFull(f, hdr[:]); err != nil { - if err == io.EOF { - // No more entries, no build ID. - return "", nil - } - return "", err - } - off += 60 - - sizeStr := strings.TrimSpace(string(hdr[48:58])) - size, err := strconv.ParseInt(sizeStr, 0, 64) - if err != nil { - return bad() - } - - name := strings.TrimSpace(string(hdr[:16])) - if name == "_buildid.o/" { - sr := io.NewSectionReader(f, off, size) - e, err := elf.NewFile(sr) - if err != nil { - return bad() - } - s := e.Section(".go.buildid") - if s == nil { - return bad() - } - data, err := s.Data() - if err != nil { - return bad() - } - return string(data), nil - } - - off += size - if off&1 != 0 { - off++ - } - } -} - -var ( - goBuildPrefix = []byte("\xff Go build ID: \"") - goBuildEnd = []byte("\"\n \xff") - - elfPrefix = []byte("\x7fELF") - - machoPrefixes = [][]byte{ - {0xfe, 0xed, 0xfa, 0xce}, - {0xfe, 0xed, 0xfa, 0xcf}, - {0xce, 0xfa, 0xed, 0xfe}, - {0xcf, 0xfa, 0xed, 0xfe}, - } -) - -var readSize = 32 * 1024 // changed for testing - -// readBinary reads the build ID from a binary. -// -// ELF binaries store the build ID in a proper PT_NOTE section. -// -// Other binary formats are not so flexible. For those, the linker -// stores the build ID as non-instruction bytes at the very beginning -// of the text segment, which should appear near the beginning -// of the file. This is clumsy but fairly portable. Custom locations -// can be added for other binary types as needed, like we did for ELF. -func readBinary(name string, f *os.File) (id string, err error) { - // Read the first 32 kB of the binary file. - // That should be enough to find the build ID. - // In ELF files, the build ID is in the leading headers, - // which are typically less than 4 kB, not to mention 32 kB. - // In Mach-O files, there's no limit, so we have to parse the file. - // On other systems, we're trying to read enough that - // we get the beginning of the text segment in the read. - // The offset where the text segment begins in a hello - // world compiled for each different object format today: - // - // Plan 9: 0x20 - // Windows: 0x600 - // - data := make([]byte, readSize) - _, err = io.ReadFull(f, data) - if err == io.ErrUnexpectedEOF { - err = nil - } - if err != nil { - return "", err - } - - if bytes.HasPrefix(data, elfPrefix) { - return readELF(name, f, data) - } - for _, m := range machoPrefixes { - if bytes.HasPrefix(data, m) { - return readMacho(name, f, data) - } - } - return readRaw(name, data) -} - -// readRaw finds the raw build ID stored in text segment data. -func readRaw(name string, data []byte) (id string, err error) { - i := bytes.Index(data, goBuildPrefix) - if i < 0 { - // Missing. Treat as successful but build ID empty. - return "", nil - } - - j := bytes.Index(data[i+len(goBuildPrefix):], goBuildEnd) - if j < 0 { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} - } - - quoted := data[i+len(goBuildPrefix)-1 : i+len(goBuildPrefix)+j+1] - id, err = strconv.Unquote(string(quoted)) - if err != nil { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} - } - return id, nil -} diff --git a/vendor/honnef.co/go/tools/go/loader/hash.go b/vendor/honnef.co/go/tools/go/loader/hash.go deleted file mode 100644 index 68c067a8d5..0000000000 --- a/vendor/honnef.co/go/tools/go/loader/hash.go +++ /dev/null @@ -1,83 +0,0 @@ -package loader - -import ( - "fmt" - "runtime" - "sort" - "strings" - - "honnef.co/go/tools/internal/cache" -) - -// computeHash computes a package's hash. The hash is based on all Go -// files that make up the package, as well as the hashes of imported -// packages. -func computeHash(pkg *PackageSpec) (cache.ActionID, error) { - key := cache.NewHash("package " + pkg.PkgPath) - fmt.Fprintf(key, "goos %s goarch %s\n", runtime.GOOS, runtime.GOARCH) - fmt.Fprintf(key, "import %q\n", pkg.PkgPath) - - // Compute the hashes of all files making up the package. As an - // optimization, we use the build ID that Go already computed for - // us, because it is virtually identical to hashed all - // CompiledGoFiles. - success := false - if pkg.ExportFile != "" { - id, err := getBuildid(pkg.ExportFile) - if err == nil { - if idx := strings.IndexRune(id, '/'); idx > -1 { - fmt.Fprintf(key, "files %s\n", id[:idx]) - success = true - } - } - } - if !success { - for _, f := range pkg.CompiledGoFiles { - h, err := cache.FileHash(f) - if err != nil { - return cache.ActionID{}, err - } - fmt.Fprintf(key, "file %s %x\n", f, h) - } - } - - imps := make([]*PackageSpec, 0, len(pkg.Imports)) - for _, v := range pkg.Imports { - imps = append(imps, v) - } - sort.Slice(imps, func(i, j int) bool { - return imps[i].PkgPath < imps[j].PkgPath - }) - - for _, dep := range imps { - if dep.ExportFile == "" { - fmt.Fprintf(key, "import %s \n", dep.PkgPath) - } else { - id, err := getBuildid(dep.ExportFile) - if err == nil { - fmt.Fprintf(key, "import %s %s\n", dep.PkgPath, id) - } else { - fh, err := cache.FileHash(dep.ExportFile) - if err != nil { - return cache.ActionID{}, err - } - fmt.Fprintf(key, "import %s %x\n", dep.PkgPath, fh) - } - } - } - return key.Sum(), nil -} - -var buildidCache = map[string]string{} - -func getBuildid(f string) (string, error) { - if h, ok := buildidCache[f]; ok { - return h, nil - } - h, err := ReadFile(f) - if err != nil { - return "", err - } - buildidCache[f] = h - return h, nil -} diff --git a/vendor/honnef.co/go/tools/go/loader/loader.go b/vendor/honnef.co/go/tools/go/loader/loader.go deleted file mode 100644 index 678f3d4698..0000000000 --- a/vendor/honnef.co/go/tools/go/loader/loader.go +++ /dev/null @@ -1,340 +0,0 @@ -package loader - -import ( - "errors" - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "go/types" - "os" - "time" - - "honnef.co/go/tools/config" - "honnef.co/go/tools/internal/cache" - "honnef.co/go/tools/internal/go/gcimporter" - - "golang.org/x/tools/go/packages" -) - -const MaxFileSize = 50 * 1024 * 1024 // 50 MB - -var errMaxFileSize = errors.New("file exceeds max file size") - -type PackageSpec struct { - ID string - Name string - PkgPath string - // Errors that occured while building the import graph. These will - // primarily be parse errors or failure to resolve imports, but - // may also be other errors. - Errors []packages.Error - GoFiles []string - CompiledGoFiles []string - OtherFiles []string - ExportFile string - Imports map[string]*PackageSpec - TypesSizes types.Sizes - Hash cache.ActionID - - Config config.Config -} - -func (spec *PackageSpec) String() string { - return spec.ID -} - -type Package struct { - *PackageSpec - - // Errors that occured while loading the package. These will - // primarily be parse or type errors, but may also be lower-level - // failures such as file-system ones. - Errors []packages.Error - Types *types.Package - Fset *token.FileSet - Syntax []*ast.File - TypesInfo *types.Info -} - -// Graph resolves patterns and returns packages with all the -// information required to later load type information, and optionally -// syntax trees. -// -// The provided config can set any setting with the exception of Mode. -func Graph(cfg *packages.Config, patterns ...string) ([]*PackageSpec, error) { - var dcfg packages.Config - if cfg != nil { - dcfg = *cfg - } - dcfg.Mode = packages.NeedName | - packages.NeedImports | - packages.NeedDeps | - packages.NeedExportsFile | - packages.NeedFiles | - packages.NeedCompiledGoFiles | - packages.NeedTypesSizes - pkgs, err := packages.Load(&dcfg, patterns...) - if err != nil { - return nil, err - } - - m := map[*packages.Package]*PackageSpec{} - packages.Visit(pkgs, nil, func(pkg *packages.Package) { - spec := &PackageSpec{ - ID: pkg.ID, - Name: pkg.Name, - PkgPath: pkg.PkgPath, - Errors: pkg.Errors, - GoFiles: pkg.GoFiles, - CompiledGoFiles: pkg.CompiledGoFiles, - OtherFiles: pkg.OtherFiles, - ExportFile: pkg.ExportFile, - Imports: map[string]*PackageSpec{}, - TypesSizes: pkg.TypesSizes, - } - for path, imp := range pkg.Imports { - spec.Imports[path] = m[imp] - } - if cdir := config.Dir(pkg.GoFiles); cdir != "" { - cfg, err := config.Load(cdir) - if err != nil { - spec.Errors = append(spec.Errors, convertError(err)...) - } - spec.Config = cfg - } else { - spec.Config = config.DefaultConfig - } - spec.Hash, err = computeHash(spec) - if err != nil { - spec.Errors = append(spec.Errors, convertError(err)...) - } - m[pkg] = spec - }) - out := make([]*PackageSpec, 0, len(pkgs)) - for _, pkg := range pkgs { - if len(pkg.CompiledGoFiles) == 0 && len(pkg.Errors) == 0 && pkg.PkgPath != "unsafe" { - // If a package consists only of test files, then - // go/packages incorrectly(?) returns an empty package for - // the non-test variant. Get rid of those packages. See - // #646. - // - // Do not, however, skip packages that have errors. Those, - // too, may have no files, but we want to print the - // errors. - continue - } - out = append(out, m[pkg]) - } - - return out, nil -} - -type program struct { - fset *token.FileSet - packages map[string]*types.Package -} - -type Stats struct { - Source time.Duration - Export map[*PackageSpec]time.Duration -} - -// Load loads the package described in spec. Imports will be loaded -// from export data, while the package itself will be loaded from -// source. -// -// An error will only be returned for system failures, such as failure -// to read export data from disk. Syntax and type errors, among -// others, will only populate the returned package's Errors field. -func Load(spec *PackageSpec) (*Package, Stats, error) { - prog := &program{ - fset: token.NewFileSet(), - packages: map[string]*types.Package{}, - } - - stats := Stats{ - Export: map[*PackageSpec]time.Duration{}, - } - var b []byte - for _, imp := range spec.Imports { - if imp.PkgPath == "unsafe" { - continue - } - t := time.Now() - var err error - _, b, err = prog.loadFromExport(imp, b) - stats.Export[imp] = time.Since(t) - if err != nil { - return nil, stats, err - } - } - t := time.Now() - pkg, err := prog.loadFromSource(spec) - if err == errMaxFileSize { - pkg, _, err = prog.loadFromExport(spec, b) - } - stats.Source = time.Since(t) - return pkg, stats, err -} - -// loadFromExport loads a package from export data. -func (prog *program) loadFromExport(spec *PackageSpec, b []byte) (*Package, []byte, error) { - // log.Printf("Loading package %s from export", spec) - if spec.ExportFile == "" { - return nil, b, fmt.Errorf("no export data for %q", spec.ID) - } - f, err := os.Open(spec.ExportFile) - if err != nil { - return nil, b, err - } - defer f.Close() - - b, err = gcimporter.GetExportData(f, b) - if err != nil { - return nil, b, err - } - - _, tpkg, err := gcimporter.IImportData(prog.fset, prog.packages, b[1:], spec.PkgPath) - if err != nil { - return nil, b, err - } - pkg := &Package{ - PackageSpec: spec, - Types: tpkg, - Fset: prog.fset, - } - // runtime.SetFinalizer(pkg, func(pkg *Package) { - // log.Println("Unloading package", pkg.PkgPath) - // }) - return pkg, b, nil -} - -// loadFromSource loads a package from source. All of its dependencies -// must have been loaded already. -func (prog *program) loadFromSource(spec *PackageSpec) (*Package, error) { - if len(spec.Errors) > 0 { - panic("LoadFromSource called on package with errors") - } - - pkg := &Package{ - PackageSpec: spec, - Types: types.NewPackage(spec.PkgPath, spec.Name), - Syntax: make([]*ast.File, len(spec.CompiledGoFiles)), - Fset: prog.fset, - TypesInfo: &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - }, - } - // runtime.SetFinalizer(pkg, func(pkg *Package) { - // log.Println("Unloading package", pkg.PkgPath) - // }) - - // OPT(dh): many packages have few files, much fewer than there - // are CPU cores. Additionally, parsing each individual file is - // very fast. A naive parallel implementation of this loop won't - // be faster, and tends to be slower due to extra scheduling, - // bookkeeping and potentially false sharing of cache lines. - for i, file := range spec.CompiledGoFiles { - f, err := os.Open(file) - if err != nil { - return nil, err - } - fi, err := f.Stat() - if err != nil { - return nil, err - } - if fi.Size() >= MaxFileSize { - return nil, errMaxFileSize - } - af, err := parser.ParseFile(prog.fset, file, f, parser.ParseComments) - f.Close() - if err != nil { - pkg.Errors = append(pkg.Errors, convertError(err)...) - return pkg, nil - } - pkg.Syntax[i] = af - } - importer := func(path string) (*types.Package, error) { - if path == "unsafe" { - return types.Unsafe, nil - } - if path == "C" { - // go/packages doesn't tell us that cgo preprocessing - // failed. When we subsequently try to parse the package, - // we'll encounter the raw C import. - return nil, errors.New("cgo preprocessing failed") - } - ispecpkg := spec.Imports[path] - if ispecpkg == nil { - return nil, fmt.Errorf("trying to import %q in the context of %q returned nil PackageSpec", path, spec) - } - ipkg := prog.packages[ispecpkg.PkgPath] - if ipkg == nil { - return nil, fmt.Errorf("trying to import %q (%q) in the context of %q returned nil PackageSpec", ispecpkg.PkgPath, path, spec) - } - return ipkg, nil - } - tc := &types.Config{ - Importer: importerFunc(importer), - Error: func(err error) { - pkg.Errors = append(pkg.Errors, convertError(err)...) - }, - } - types.NewChecker(tc, pkg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax) - return pkg, nil -} - -func convertError(err error) []packages.Error { - var errs []packages.Error - // taken from go/packages - switch err := err.(type) { - case packages.Error: - // from driver - errs = append(errs, err) - - case *os.PathError: - // from parser - errs = append(errs, packages.Error{ - Pos: err.Path + ":1", - Msg: err.Err.Error(), - Kind: packages.ParseError, - }) - - case scanner.ErrorList: - // from parser - for _, err := range err { - errs = append(errs, packages.Error{ - Pos: err.Pos.String(), - Msg: err.Msg, - Kind: packages.ParseError, - }) - } - - case types.Error: - // from type checker - errs = append(errs, packages.Error{ - Pos: err.Fset.Position(err.Pos).String(), - Msg: err.Msg, - Kind: packages.TypeError, - }) - - default: - errs = append(errs, packages.Error{ - Pos: "-", - Msg: err.Error(), - Kind: packages.UnknownError, - }) - } - return errs -} - -type importerFunc func(path string) (*types.Package, error) - -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } diff --git a/vendor/honnef.co/go/tools/go/loader/note.go b/vendor/honnef.co/go/tools/go/loader/note.go deleted file mode 100644 index a56ee70051..0000000000 --- a/vendor/honnef.co/go/tools/go/loader/note.go +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2015 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 loader - -import ( - "bytes" - "debug/elf" - "debug/macho" - "encoding/binary" - "fmt" - "io" - "os" -) - -func readAligned4(r io.Reader, sz int32) ([]byte, error) { - full := (sz + 3) &^ 3 - data := make([]byte, full) - _, err := io.ReadFull(r, data) - if err != nil { - return nil, err - } - data = data[:sz] - return data, nil -} - -func ReadELFNote(filename, name string, typ int32) ([]byte, error) { - f, err := elf.Open(filename) - if err != nil { - return nil, err - } - defer f.Close() - for _, sect := range f.Sections { - if sect.Type != elf.SHT_NOTE { - continue - } - r := sect.Open() - for { - var namesize, descsize, noteType int32 - err = binary.Read(r, f.ByteOrder, &namesize) - if err != nil { - if err == io.EOF { - break - } - return nil, fmt.Errorf("read namesize failed: %v", err) - } - err = binary.Read(r, f.ByteOrder, &descsize) - if err != nil { - return nil, fmt.Errorf("read descsize failed: %v", err) - } - err = binary.Read(r, f.ByteOrder, ¬eType) - if err != nil { - return nil, fmt.Errorf("read type failed: %v", err) - } - noteName, err := readAligned4(r, namesize) - if err != nil { - return nil, fmt.Errorf("read name failed: %v", err) - } - desc, err := readAligned4(r, descsize) - if err != nil { - return nil, fmt.Errorf("read desc failed: %v", err) - } - if name == string(noteName) && typ == noteType { - return desc, nil - } - } - } - return nil, nil -} - -var elfGoNote = []byte("Go\x00\x00") -var elfGNUNote = []byte("GNU\x00") - -// The Go build ID is stored in a note described by an ELF PT_NOTE prog -// header. The caller has already opened filename, to get f, and read -// at least 4 kB out, in data. -func readELF(name string, f *os.File, data []byte) (buildid string, err error) { - // Assume the note content is in the data, already read. - // Rewrite the ELF header to set shnum to 0, so that we can pass - // the data to elf.NewFile and it will decode the Prog list but not - // try to read the section headers and the string table from disk. - // That's a waste of I/O when all we care about is the Prog list - // and the one ELF note. - switch elf.Class(data[elf.EI_CLASS]) { - case elf.ELFCLASS32: - data[48] = 0 - data[49] = 0 - case elf.ELFCLASS64: - data[60] = 0 - data[61] = 0 - } - - const elfGoBuildIDTag = 4 - const gnuBuildIDTag = 3 - - ef, err := elf.NewFile(bytes.NewReader(data)) - if err != nil { - return "", &os.PathError{Path: name, Op: "parse", Err: err} - } - var gnu string - for _, p := range ef.Progs { - if p.Type != elf.PT_NOTE || p.Filesz < 16 { - continue - } - - var note []byte - if p.Off+p.Filesz < uint64(len(data)) { - note = data[p.Off : p.Off+p.Filesz] - } else { - // For some linkers, such as the Solaris linker, - // the buildid may not be found in data (which - // likely contains the first 16kB of the file) - // or even the first few megabytes of the file - // due to differences in note segment placement; - // in that case, extract the note data manually. - _, err = f.Seek(int64(p.Off), io.SeekStart) - if err != nil { - return "", err - } - - note = make([]byte, p.Filesz) - _, err = io.ReadFull(f, note) - if err != nil { - return "", err - } - } - - filesz := p.Filesz - off := p.Off - for filesz >= 16 { - nameSize := ef.ByteOrder.Uint32(note) - valSize := ef.ByteOrder.Uint32(note[4:]) - tag := ef.ByteOrder.Uint32(note[8:]) - nname := note[12:16] - if nameSize == 4 && 16+valSize <= uint32(len(note)) && tag == elfGoBuildIDTag && bytes.Equal(nname, elfGoNote) { - return string(note[16 : 16+valSize]), nil - } - - if nameSize == 4 && 16+valSize <= uint32(len(note)) && tag == gnuBuildIDTag && bytes.Equal(nname, elfGNUNote) { - gnu = string(note[16 : 16+valSize]) - } - - nameSize = (nameSize + 3) &^ 3 - valSize = (valSize + 3) &^ 3 - notesz := uint64(12 + nameSize + valSize) - if filesz <= notesz { - break - } - off += notesz - align := p.Align - alignedOff := (off + align - 1) &^ (align - 1) - notesz += alignedOff - off - off = alignedOff - filesz -= notesz - note = note[notesz:] - } - } - - // If we didn't find a Go note, use a GNU note if available. - // This is what gccgo uses. - if gnu != "" { - return gnu, nil - } - - // No note. Treat as successful but build ID empty. - return "", nil -} - -// The Go build ID is stored at the beginning of the Mach-O __text segment. -// The caller has already opened filename, to get f, and read a few kB out, in data. -// Sadly, that's not guaranteed to hold the note, because there is an arbitrary amount -// of other junk placed in the file ahead of the main text. -func readMacho(name string, f *os.File, data []byte) (buildid string, err error) { - // If the data we want has already been read, don't worry about Mach-O parsing. - // This is both an optimization and a hedge against the Mach-O parsing failing - // in the future due to, for example, the name of the __text section changing. - if b, err := readRaw(name, data); b != "" && err == nil { - return b, err - } - - mf, err := macho.NewFile(f) - if err != nil { - return "", &os.PathError{Path: name, Op: "parse", Err: err} - } - - sect := mf.Section("__text") - if sect == nil { - // Every binary has a __text section. Something is wrong. - return "", &os.PathError{Path: name, Op: "parse", Err: fmt.Errorf("cannot find __text section")} - } - - // It should be in the first few bytes, but read a lot just in case, - // especially given our past problems on OS X with the build ID moving. - // There shouldn't be much difference between reading 4kB and 32kB: - // the hard part is getting to the data, not transferring it. - n := sect.Size - if n > uint64(readSize) { - n = uint64(readSize) - } - buf := make([]byte, n) - if _, err := f.ReadAt(buf, int64(sect.Offset)); err != nil { - return "", err - } - - return readRaw(name, buf) -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/callee.go b/vendor/honnef.co/go/tools/go/types/typeutil/callee.go deleted file mode 100644 index 38f596daf9..0000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/callee.go +++ /dev/null @@ -1,46 +0,0 @@ -// 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 typeutil - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/ast/astutil" -) - -// Callee returns the named target of a function call, if any: -// a function, method, builtin, or variable. -func Callee(info *types.Info, call *ast.CallExpr) types.Object { - var obj types.Object - switch fun := astutil.Unparen(call.Fun).(type) { - case *ast.Ident: - obj = info.Uses[fun] // type, var, builtin, or declared func - case *ast.SelectorExpr: - if sel, ok := info.Selections[fun]; ok { - obj = sel.Obj() // method or field - } else { - obj = info.Uses[fun.Sel] // qualified identifier? - } - } - if _, ok := obj.(*types.TypeName); ok { - return nil // T(x) is a conversion, not a call - } - return obj -} - -// StaticCallee returns the target (function or method) of a static -// function call, if any. It returns nil for calls to builtins. -func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { - if f, ok := Callee(info, call).(*types.Func); ok && !interfaceMethod(f) { - return f - } - return nil -} - -func interfaceMethod(f *types.Func) bool { - recv := f.Type().(*types.Signature).Recv() - return recv != nil && types.IsInterface(recv.Type()) -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/imports.go b/vendor/honnef.co/go/tools/go/types/typeutil/imports.go deleted file mode 100644 index 9c441dba9c..0000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/imports.go +++ /dev/null @@ -1,31 +0,0 @@ -// 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 typeutil - -import "go/types" - -// Dependencies returns all dependencies of the specified packages. -// -// Dependent packages appear in topological order: if package P imports -// package Q, Q appears earlier than P in the result. -// The algorithm follows import statements in the order they -// appear in the source code, so the result is a total order. -// -func Dependencies(pkgs ...*types.Package) []*types.Package { - var result []*types.Package - seen := make(map[*types.Package]bool) - var visit func(pkgs []*types.Package) - visit = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !seen[p] { - seen[p] = true - visit(p.Imports()) - result = append(result, p) - } - } - } - visit(pkgs) - return result -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/methodsetcache.go b/vendor/honnef.co/go/tools/go/types/typeutil/methodsetcache.go deleted file mode 100644 index 32084610f4..0000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/methodsetcache.go +++ /dev/null @@ -1,72 +0,0 @@ -// 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. - -// This file implements a cache of method sets. - -package typeutil - -import ( - "go/types" - "sync" -) - -// A MethodSetCache records the method set of each type T for which -// MethodSet(T) is called so that repeat queries are fast. -// The zero value is a ready-to-use cache instance. -type MethodSetCache struct { - mu sync.Mutex - named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N - others map[types.Type]*types.MethodSet // all other types -} - -// MethodSet returns the method set of type T. It is thread-safe. -// -// If cache is nil, this function is equivalent to types.NewMethodSet(T). -// Utility functions can thus expose an optional *MethodSetCache -// parameter to clients that care about performance. -// -func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { - if cache == nil { - return types.NewMethodSet(T) - } - cache.mu.Lock() - defer cache.mu.Unlock() - - switch T := T.(type) { - case *types.Named: - return cache.lookupNamed(T).value - - case *types.Pointer: - if N, ok := T.Elem().(*types.Named); ok { - return cache.lookupNamed(N).pointer - } - } - - // all other types - // (The map uses pointer equivalence, not type identity.) - mset := cache.others[T] - if mset == nil { - mset = types.NewMethodSet(T) - if cache.others == nil { - cache.others = make(map[types.Type]*types.MethodSet) - } - cache.others[T] = mset - } - return mset -} - -func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } { - if cache.named == nil { - cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet }) - } - // Avoid recomputing mset(*T) for each distinct Pointer - // instance whose underlying type is a named type. - msets, ok := cache.named[named] - if !ok { - msets.value = types.NewMethodSet(named) - msets.pointer = types.NewMethodSet(types.NewPointer(named)) - cache.named[named] = msets - } - return msets -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/ui.go b/vendor/honnef.co/go/tools/go/types/typeutil/ui.go deleted file mode 100644 index 9849c24cef..0000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/ui.go +++ /dev/null @@ -1,52 +0,0 @@ -// 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 typeutil - -// This file defines utilities for user interfaces that display types. - -import "go/types" - -// IntuitiveMethodSet returns the intuitive method set of a type T, -// which is the set of methods you can call on an addressable value of -// that type. -// -// The result always contains MethodSet(T), and is exactly MethodSet(T) -// for interface types and for pointer-to-concrete types. -// For all other concrete types T, the result additionally -// contains each method belonging to *T if there is no identically -// named method on T itself. -// -// This corresponds to user intuition about method sets; -// this function is intended only for user interfaces. -// -// The order of the result is as for types.MethodSet(T). -// -func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { - isPointerToConcrete := func(T types.Type) bool { - ptr, ok := T.(*types.Pointer) - return ok && !types.IsInterface(ptr.Elem()) - } - - var result []*types.Selection - mset := msets.MethodSet(T) - if types.IsInterface(T) || isPointerToConcrete(T) { - for i, n := 0, mset.Len(); i < n; i++ { - result = append(result, mset.At(i)) - } - } else { - // T is some other concrete type. - // Report methods of T and *T, preferring those of T. - pmset := msets.MethodSet(types.NewPointer(T)) - for i, n := 0, pmset.Len(); i < n; i++ { - meth := pmset.At(i) - if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { - meth = m - } - result = append(result, meth) - } - - } - return result -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/util.go b/vendor/honnef.co/go/tools/go/types/typeutil/util.go deleted file mode 100644 index c96c1a7d3b..0000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/util.go +++ /dev/null @@ -1,131 +0,0 @@ -package typeutil - -import ( - "bytes" - "go/types" - "sync" -) - -var bufferPool = &sync.Pool{ - New: func() interface{} { - buf := bytes.NewBuffer(nil) - buf.Grow(64) - return buf - }, -} - -func FuncName(f *types.Func) string { - buf := bufferPool.Get().(*bytes.Buffer) - buf.Reset() - if f.Type() != nil { - sig := f.Type().(*types.Signature) - if recv := sig.Recv(); recv != nil { - buf.WriteByte('(') - if _, ok := recv.Type().(*types.Interface); ok { - // gcimporter creates abstract methods of - // named interfaces using the interface type - // (not the named type) as the receiver. - // Don't print it in full. - buf.WriteString("interface") - } else { - types.WriteType(buf, recv.Type(), nil) - } - buf.WriteByte(')') - buf.WriteByte('.') - } else if f.Pkg() != nil { - writePackage(buf, f.Pkg()) - } - } - buf.WriteString(f.Name()) - s := buf.String() - bufferPool.Put(buf) - return s -} - -func writePackage(buf *bytes.Buffer, pkg *types.Package) { - if pkg == nil { - return - } - s := pkg.Path() - if s != "" { - buf.WriteString(s) - buf.WriteByte('.') - } -} - -// Dereference returns a pointer's element type; otherwise it returns -// T. -func Dereference(T types.Type) types.Type { - if p, ok := T.Underlying().(*types.Pointer); ok { - return p.Elem() - } - return T -} - -// DereferenceR returns a pointer's element type; otherwise it returns -// T. If the element type is itself a pointer, DereferenceR will be -// applied recursively. -func DereferenceR(T types.Type) types.Type { - if p, ok := T.Underlying().(*types.Pointer); ok { - return DereferenceR(p.Elem()) - } - return T -} - -func IsObject(obj types.Object, name string) bool { - var path string - if pkg := obj.Pkg(); pkg != nil { - path = pkg.Path() + "." - } - return path+obj.Name() == name -} - -// OPT(dh): IsType is kind of expensive; should we really use it? -func IsType(T types.Type, name string) bool { return types.TypeString(T, nil) == name } - -func IsPointerLike(T types.Type) bool { - switch T := T.Underlying().(type) { - case *types.Interface, *types.Chan, *types.Map, *types.Signature, *types.Pointer: - return true - case *types.Basic: - return T.Kind() == types.UnsafePointer - } - return false -} - -type Field struct { - Var *types.Var - Tag string - Path []int -} - -// FlattenFields recursively flattens T and embedded structs, -// returning a list of fields. If multiple fields with the same name -// exist, all will be returned. -func FlattenFields(T *types.Struct) []Field { - return flattenFields(T, nil, nil) -} - -func flattenFields(T *types.Struct, path []int, seen map[types.Type]bool) []Field { - if seen == nil { - seen = map[types.Type]bool{} - } - if seen[T] { - return nil - } - seen[T] = true - var out []Field - for i := 0; i < T.NumFields(); i++ { - field := T.Field(i) - tag := T.Tag(i) - np := append(path[:len(path):len(path)], i) - if field.Anonymous() { - if s, ok := Dereference(field.Type()).Underlying().(*types.Struct); ok { - out = append(out, flattenFields(s, np, seen)...) - } - } else { - out = append(out, Field{field, tag, np}) - } - } - return out -} diff --git a/vendor/honnef.co/go/tools/internal/cache/cache.go b/vendor/honnef.co/go/tools/internal/cache/cache.go deleted file mode 100644 index 0031edc693..0000000000 --- a/vendor/honnef.co/go/tools/internal/cache/cache.go +++ /dev/null @@ -1,528 +0,0 @@ -// 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 cache implements a build artifact cache. -// -// This package is a slightly modified fork of Go's -// cmd/go/internal/cache package. -package cache - -import ( - "bytes" - "crypto/sha256" - "encoding/hex" - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "honnef.co/go/tools/internal/renameio" -) - -// An ActionID is a cache action key, the hash of a complete description of a -// repeatable computation (command line, environment variables, -// input file contents, executable contents). -type ActionID [HashSize]byte - -// An OutputID is a cache output key, the hash of an output of a computation. -type OutputID [HashSize]byte - -// A Cache is a package cache, backed by a file system directory tree. -type Cache struct { - dir string - now func() time.Time -} - -// Open opens and returns the cache in the given directory. -// -// It is safe for multiple processes on a single machine to use the -// same cache directory in a local file system simultaneously. -// They will coordinate using operating system file locks and may -// duplicate effort but will not corrupt the cache. -// -// However, it is NOT safe for multiple processes on different machines -// to share a cache directory (for example, if the directory were stored -// in a network file system). File locking is notoriously unreliable in -// network file systems and may not suffice to protect the cache. -// -func Open(dir string) (*Cache, error) { - info, err := os.Stat(dir) - if err != nil { - return nil, err - } - if !info.IsDir() { - return nil, &os.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")} - } - for i := 0; i < 256; i++ { - name := filepath.Join(dir, fmt.Sprintf("%02x", i)) - if err := os.MkdirAll(name, 0777); err != nil { - return nil, err - } - } - c := &Cache{ - dir: dir, - now: time.Now, - } - return c, nil -} - -// fileName returns the name of the file corresponding to the given id. -func (c *Cache) fileName(id [HashSize]byte, key string) string { - return filepath.Join(c.dir, fmt.Sprintf("%02x", id[0]), fmt.Sprintf("%x", id)+"-"+key) -} - -// An entryNotFoundError indicates that a cache entry was not found, with an -// optional underlying reason. -type entryNotFoundError struct { - Err error -} - -func (e *entryNotFoundError) Error() string { - if e.Err == nil { - return "cache entry not found" - } - return fmt.Sprintf("cache entry not found: %v", e.Err) -} - -func (e *entryNotFoundError) Unwrap() error { - return e.Err -} - -const ( - // action entry file is "v1 \n" - hexSize = HashSize * 2 - entrySize = 2 + 1 + hexSize + 1 + hexSize + 1 + 20 + 1 + 20 + 1 -) - -// verify controls whether to run the cache in verify mode. -// In verify mode, the cache always returns errMissing from Get -// but then double-checks in Put that the data being written -// exactly matches any existing entry. This provides an easy -// way to detect program behavior that would have been different -// had the cache entry been returned from Get. -// -// verify is enabled by setting the environment variable -// GODEBUG=gocacheverify=1. -var verify = false - -var errVerifyMode = errors.New("gocacheverify=1") - -// DebugTest is set when GODEBUG=gocachetest=1 is in the environment. -var DebugTest = false - -func init() { initEnv() } - -func initEnv() { - verify = false - debugHash = false - debug := strings.Split(os.Getenv("GODEBUG"), ",") - for _, f := range debug { - if f == "gocacheverify=1" { - verify = true - } - if f == "gocachehash=1" { - debugHash = true - } - if f == "gocachetest=1" { - DebugTest = true - } - } -} - -// Get looks up the action ID in the cache, -// returning the corresponding output ID and file size, if any. -// Note that finding an output ID does not guarantee that the -// saved file for that output ID is still available. -func (c *Cache) Get(id ActionID) (Entry, error) { - if verify { - return Entry{}, &entryNotFoundError{Err: errVerifyMode} - } - return c.get(id) -} - -type Entry struct { - OutputID OutputID - Size int64 - Time time.Time -} - -// get is Get but does not respect verify mode, so that Put can use it. -func (c *Cache) get(id ActionID) (Entry, error) { - missing := func(reason error) (Entry, error) { - return Entry{}, &entryNotFoundError{Err: reason} - } - f, err := os.Open(c.fileName(id, "a")) - if err != nil { - return missing(err) - } - defer f.Close() - entry := make([]byte, entrySize+1) // +1 to detect whether f is too long - if n, err := io.ReadFull(f, entry); n > entrySize { - return missing(errors.New("too long")) - } else if err != io.ErrUnexpectedEOF { - if err == io.EOF { - return missing(errors.New("file is empty")) - } - return missing(err) - } else if n < entrySize { - return missing(errors.New("entry file incomplete")) - } - if entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\n' { - return missing(errors.New("invalid header")) - } - eid, entry := entry[3:3+hexSize], entry[3+hexSize:] - eout, entry := entry[1:1+hexSize], entry[1+hexSize:] - esize, entry := entry[1:1+20], entry[1+20:] - //lint:ignore SA4006 See https://github.com/dominikh/go-tools/issues/465 - etime, entry := entry[1:1+20], entry[1+20:] - var buf [HashSize]byte - if _, err := hex.Decode(buf[:], eid); err != nil { - return missing(fmt.Errorf("decoding ID: %v", err)) - } else if buf != id { - return missing(errors.New("mismatched ID")) - } - if _, err := hex.Decode(buf[:], eout); err != nil { - return missing(fmt.Errorf("decoding output ID: %v", err)) - } - i := 0 - for i < len(esize) && esize[i] == ' ' { - i++ - } - size, err := strconv.ParseInt(string(esize[i:]), 10, 64) - if err != nil { - return missing(fmt.Errorf("parsing size: %v", err)) - } else if size < 0 { - return missing(errors.New("negative size")) - } - i = 0 - for i < len(etime) && etime[i] == ' ' { - i++ - } - tm, err := strconv.ParseInt(string(etime[i:]), 10, 64) - if err != nil { - return missing(fmt.Errorf("parsing timestamp: %v", err)) - } else if tm < 0 { - return missing(errors.New("negative timestamp")) - } - - c.used(c.fileName(id, "a")) - - return Entry{buf, size, time.Unix(0, tm)}, nil -} - -// GetFile looks up the action ID in the cache and returns -// the name of the corresponding data file. -func (c *Cache) GetFile(id ActionID) (file string, entry Entry, err error) { - entry, err = c.Get(id) - if err != nil { - return "", Entry{}, err - } - file = c.OutputFile(entry.OutputID) - info, err := os.Stat(file) - if err != nil { - return "", Entry{}, &entryNotFoundError{Err: err} - } - if info.Size() != entry.Size { - return "", Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")} - } - return file, entry, nil -} - -// GetBytes looks up the action ID in the cache and returns -// the corresponding output bytes. -// GetBytes should only be used for data that can be expected to fit in memory. -func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) { - entry, err := c.Get(id) - if err != nil { - return nil, entry, err - } - data, _ := ioutil.ReadFile(c.OutputFile(entry.OutputID)) - if sha256.Sum256(data) != entry.OutputID { - return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")} - } - return data, entry, nil -} - -// OutputFile returns the name of the cache file storing output with the given OutputID. -func (c *Cache) OutputFile(out OutputID) string { - file := c.fileName(out, "d") - c.used(file) - return file -} - -// Time constants for cache expiration. -// -// We set the mtime on a cache file on each use, but at most one per mtimeInterval (1 hour), -// to avoid causing many unnecessary inode updates. The mtimes therefore -// roughly reflect "time of last use" but may in fact be older by at most an hour. -// -// We scan the cache for entries to delete at most once per trimInterval (1 day). -// -// When we do scan the cache, we delete entries that have not been used for -// at least trimLimit (5 days). Statistics gathered from a month of usage by -// Go developers found that essentially all reuse of cached entries happened -// within 5 days of the previous reuse. See golang.org/issue/22990. -const ( - mtimeInterval = 1 * time.Hour - trimInterval = 24 * time.Hour - trimLimit = 5 * 24 * time.Hour -) - -// used makes a best-effort attempt to update mtime on file, -// so that mtime reflects cache access time. -// -// Because the reflection only needs to be approximate, -// and to reduce the amount of disk activity caused by using -// cache entries, used only updates the mtime if the current -// mtime is more than an hour old. This heuristic eliminates -// nearly all of the mtime updates that would otherwise happen, -// while still keeping the mtimes useful for cache trimming. -func (c *Cache) used(file string) { - info, err := os.Stat(file) - if err == nil && c.now().Sub(info.ModTime()) < mtimeInterval { - return - } - os.Chtimes(file, c.now(), c.now()) -} - -// Trim removes old cache entries that are likely not to be reused. -func (c *Cache) Trim() { - now := c.now() - - // We maintain in dir/trim.txt the time of the last completed cache trim. - // If the cache has been trimmed recently enough, do nothing. - // This is the common case. - data, _ := renameio.ReadFile(filepath.Join(c.dir, "trim.txt")) - t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64) - if err == nil && now.Sub(time.Unix(t, 0)) < trimInterval { - return - } - - // Trim each of the 256 subdirectories. - // We subtract an additional mtimeInterval - // to account for the imprecision of our "last used" mtimes. - cutoff := now.Add(-trimLimit - mtimeInterval) - for i := 0; i < 256; i++ { - subdir := filepath.Join(c.dir, fmt.Sprintf("%02x", i)) - c.trimSubdir(subdir, cutoff) - } - - // Ignore errors from here: if we don't write the complete timestamp, the - // cache will appear older than it is, and we'll trim it again next time. - renameio.WriteFile(filepath.Join(c.dir, "trim.txt"), []byte(fmt.Sprintf("%d", now.Unix())), 0666) -} - -// trimSubdir trims a single cache subdirectory. -func (c *Cache) trimSubdir(subdir string, cutoff time.Time) { - // Read all directory entries from subdir before removing - // any files, in case removing files invalidates the file offset - // in the directory scan. Also, ignore error from f.Readdirnames, - // because we don't care about reporting the error and we still - // want to process any entries found before the error. - f, err := os.Open(subdir) - if err != nil { - return - } - names, _ := f.Readdirnames(-1) - f.Close() - - for _, name := range names { - // Remove only cache entries (xxxx-a and xxxx-d). - if !strings.HasSuffix(name, "-a") && !strings.HasSuffix(name, "-d") { - continue - } - entry := filepath.Join(subdir, name) - info, err := os.Stat(entry) - if err == nil && info.ModTime().Before(cutoff) { - os.Remove(entry) - } - } -} - -// putIndexEntry adds an entry to the cache recording that executing the action -// with the given id produces an output with the given output id (hash) and size. -func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify bool) error { - // Note: We expect that for one reason or another it may happen - // that repeating an action produces a different output hash - // (for example, if the output contains a time stamp or temp dir name). - // While not ideal, this is also not a correctness problem, so we - // don't make a big deal about it. In particular, we leave the action - // cache entries writable specifically so that they can be overwritten. - // - // Setting GODEBUG=gocacheverify=1 does make a big deal: - // in verify mode we are double-checking that the cache entries - // are entirely reproducible. As just noted, this may be unrealistic - // in some cases but the check is also useful for shaking out real bugs. - entry := fmt.Sprintf("v1 %x %x %20d %20d\n", id, out, size, time.Now().UnixNano()) - if verify && allowVerify { - old, err := c.get(id) - if err == nil && (old.OutputID != out || old.Size != size) { - // panic to show stack trace, so we can see what code is generating this cache entry. - msg := fmt.Sprintf("go: internal cache error: cache verify failed: id=%x changed:<<<\n%s\n>>>\nold: %x %d\nnew: %x %d", id, reverseHash(id), out, size, old.OutputID, old.Size) - panic(msg) - } - } - file := c.fileName(id, "a") - - // Copy file to cache directory. - mode := os.O_WRONLY | os.O_CREATE - f, err := os.OpenFile(file, mode, 0666) - if err != nil { - return err - } - _, err = f.WriteString(entry) - if err == nil { - // Truncate the file only *after* writing it. - // (This should be a no-op, but truncate just in case of previous corruption.) - // - // This differs from ioutil.WriteFile, which truncates to 0 *before* writing - // via os.O_TRUNC. Truncating only after writing ensures that a second write - // of the same content to the same file is idempotent, and does not — even - // temporarily! — undo the effect of the first write. - err = f.Truncate(int64(len(entry))) - } - if closeErr := f.Close(); err == nil { - err = closeErr - } - if err != nil { - // TODO(bcmills): This Remove potentially races with another go command writing to file. - // Can we eliminate it? - os.Remove(file) - return err - } - os.Chtimes(file, c.now(), c.now()) // mainly for tests - - return nil -} - -// Put stores the given output in the cache as the output for the action ID. -// It may read file twice. The content of file must not change between the two passes. -func (c *Cache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) { - return c.put(id, file, true) -} - -// PutNoVerify is like Put but disables the verify check -// when GODEBUG=goverifycache=1 is set. -// It is meant for data that is OK to cache but that we expect to vary slightly from run to run, -// like test output containing times and the like. -func (c *Cache) PutNoVerify(id ActionID, file io.ReadSeeker) (OutputID, int64, error) { - return c.put(id, file, false) -} - -func (c *Cache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) { - // Compute output ID. - h := sha256.New() - if _, err := file.Seek(0, 0); err != nil { - return OutputID{}, 0, err - } - size, err := io.Copy(h, file) - if err != nil { - return OutputID{}, 0, err - } - var out OutputID - h.Sum(out[:0]) - - // Copy to cached output file (if not already present). - if err := c.copyFile(file, out, size); err != nil { - return out, size, err - } - - // Add to cache index. - return out, size, c.putIndexEntry(id, out, size, allowVerify) -} - -// PutBytes stores the given bytes in the cache as the output for the action ID. -func (c *Cache) PutBytes(id ActionID, data []byte) error { - _, _, err := c.Put(id, bytes.NewReader(data)) - return err -} - -// copyFile copies file into the cache, expecting it to have the given -// output ID and size, if that file is not present already. -func (c *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error { - name := c.fileName(out, "d") - info, err := os.Stat(name) - if err == nil && info.Size() == size { - // Check hash. - if f, err := os.Open(name); err == nil { - h := sha256.New() - io.Copy(h, f) - f.Close() - var out2 OutputID - h.Sum(out2[:0]) - if out == out2 { - return nil - } - } - // Hash did not match. Fall through and rewrite file. - } - - // Copy file to cache directory. - mode := os.O_RDWR | os.O_CREATE - if err == nil && info.Size() > size { // shouldn't happen but fix in case - mode |= os.O_TRUNC - } - f, err := os.OpenFile(name, mode, 0666) - if err != nil { - return err - } - defer f.Close() - if size == 0 { - // File now exists with correct size. - // Only one possible zero-length file, so contents are OK too. - // Early return here makes sure there's a "last byte" for code below. - return nil - } - - // From here on, if any of the I/O writing the file fails, - // we make a best-effort attempt to truncate the file f - // before returning, to avoid leaving bad bytes in the file. - - // Copy file to f, but also into h to double-check hash. - if _, err := file.Seek(0, 0); err != nil { - f.Truncate(0) - return err - } - h := sha256.New() - w := io.MultiWriter(f, h) - if _, err := io.CopyN(w, file, size-1); err != nil { - f.Truncate(0) - return err - } - // Check last byte before writing it; writing it will make the size match - // what other processes expect to find and might cause them to start - // using the file. - buf := make([]byte, 1) - if _, err := file.Read(buf); err != nil { - f.Truncate(0) - return err - } - h.Write(buf) - sum := h.Sum(nil) - if !bytes.Equal(sum, out[:]) { - f.Truncate(0) - return fmt.Errorf("file content changed underfoot") - } - - // Commit cache file entry. - if _, err := f.Write(buf); err != nil { - f.Truncate(0) - return err - } - if err := f.Close(); err != nil { - // Data might not have been written, - // but file may look like it is the right size. - // To be extra careful, remove cached file. - os.Remove(name) - return err - } - os.Chtimes(name, c.now(), c.now()) // mainly for tests - - return nil -} diff --git a/vendor/honnef.co/go/tools/internal/cache/default.go b/vendor/honnef.co/go/tools/internal/cache/default.go deleted file mode 100644 index 3034f76a53..0000000000 --- a/vendor/honnef.co/go/tools/internal/cache/default.go +++ /dev/null @@ -1,85 +0,0 @@ -// 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 cache - -import ( - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - "sync" -) - -// Default returns the default cache to use. -func Default() (*Cache, error) { - defaultOnce.Do(initDefaultCache) - return defaultCache, defaultDirErr -} - -var ( - defaultOnce sync.Once - defaultCache *Cache -) - -// cacheREADME is a message stored in a README in the cache directory. -// Because the cache lives outside the normal Go trees, we leave the -// README as a courtesy to explain where it came from. -const cacheREADME = `This directory holds cached build artifacts from staticcheck. -` - -// initDefaultCache does the work of finding the default cache -// the first time Default is called. -func initDefaultCache() { - dir := DefaultDir() - if err := os.MkdirAll(dir, 0777); err != nil { - log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) - } - if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { - // Best effort. - ioutil.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) - } - - c, err := Open(dir) - if err != nil { - log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) - } - defaultCache = c -} - -var ( - defaultDirOnce sync.Once - defaultDir string - defaultDirErr error -) - -// DefaultDir returns the effective STATICCHECK_CACHE setting. -func DefaultDir() string { - // Save the result of the first call to DefaultDir for later use in - // initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that - // subprocesses will inherit it, but that means initDefaultCache can't - // otherwise distinguish between an explicit "off" and a UserCacheDir error. - - defaultDirOnce.Do(func() { - defaultDir = os.Getenv("STATICCHECK_CACHE") - if filepath.IsAbs(defaultDir) { - return - } - if defaultDir != "" { - defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not an absolute path") - return - } - - // Compute default location. - dir, err := os.UserCacheDir() - if err != nil { - defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not defined and %v", err) - return - } - defaultDir = filepath.Join(dir, "staticcheck") - }) - - return defaultDir -} diff --git a/vendor/honnef.co/go/tools/internal/cache/hash.go b/vendor/honnef.co/go/tools/internal/cache/hash.go deleted file mode 100644 index a53543ec50..0000000000 --- a/vendor/honnef.co/go/tools/internal/cache/hash.go +++ /dev/null @@ -1,176 +0,0 @@ -// 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 cache - -import ( - "bytes" - "crypto/sha256" - "fmt" - "hash" - "io" - "os" - "sync" -) - -var debugHash = false // set when GODEBUG=gocachehash=1 - -// HashSize is the number of bytes in a hash. -const HashSize = 32 - -// A Hash provides access to the canonical hash function used to index the cache. -// The current implementation uses salted SHA256, but clients must not assume this. -type Hash struct { - h hash.Hash - name string // for debugging - buf *bytes.Buffer // for verify -} - -// hashSalt is a salt string added to the beginning of every hash -// created by NewHash. Using the Staticcheck version makes sure that different -// versions of the command do not address the same cache -// entries, so that a bug in one version does not affect the execution -// of other versions. This salt will result in additional ActionID files -// in the cache, but not additional copies of the large output files, -// which are still addressed by unsalted SHA256. -var hashSalt []byte - -func SetSalt(b []byte) { - hashSalt = b -} - -// Subkey returns an action ID corresponding to mixing a parent -// action ID with a string description of the subkey. -func Subkey(parent ActionID, desc string) ActionID { - h := sha256.New() - h.Write([]byte("subkey:")) - h.Write(parent[:]) - h.Write([]byte(desc)) - var out ActionID - h.Sum(out[:0]) - if debugHash { - fmt.Fprintf(os.Stderr, "HASH subkey %x %q = %x\n", parent, desc, out) - } - if verify { - hashDebug.Lock() - hashDebug.m[out] = fmt.Sprintf("subkey %x %q", parent, desc) - hashDebug.Unlock() - } - return out -} - -// NewHash returns a new Hash. -// The caller is expected to Write data to it and then call Sum. -func NewHash(name string) *Hash { - h := &Hash{h: sha256.New(), name: name} - if debugHash { - fmt.Fprintf(os.Stderr, "HASH[%s]\n", h.name) - } - h.Write(hashSalt) - if verify { - h.buf = new(bytes.Buffer) - } - return h -} - -// Write writes data to the running hash. -func (h *Hash) Write(b []byte) (int, error) { - if debugHash { - fmt.Fprintf(os.Stderr, "HASH[%s]: %q\n", h.name, b) - } - if h.buf != nil { - h.buf.Write(b) - } - return h.h.Write(b) -} - -// Sum returns the hash of the data written previously. -func (h *Hash) Sum() [HashSize]byte { - var out [HashSize]byte - h.h.Sum(out[:0]) - if debugHash { - fmt.Fprintf(os.Stderr, "HASH[%s]: %x\n", h.name, out) - } - if h.buf != nil { - hashDebug.Lock() - if hashDebug.m == nil { - hashDebug.m = make(map[[HashSize]byte]string) - } - hashDebug.m[out] = h.buf.String() - hashDebug.Unlock() - } - return out -} - -// In GODEBUG=gocacheverify=1 mode, -// hashDebug holds the input to every computed hash ID, -// so that we can work backward from the ID involved in a -// cache entry mismatch to a description of what should be there. -var hashDebug struct { - sync.Mutex - m map[[HashSize]byte]string -} - -// reverseHash returns the input used to compute the hash id. -func reverseHash(id [HashSize]byte) string { - hashDebug.Lock() - s := hashDebug.m[id] - hashDebug.Unlock() - return s -} - -var hashFileCache struct { - sync.Mutex - m map[string][HashSize]byte -} - -// FileHash returns the hash of the named file. -// It caches repeated lookups for a given file, -// and the cache entry for a file can be initialized -// using SetFileHash. -// The hash used by FileHash is not the same as -// the hash used by NewHash. -func FileHash(file string) ([HashSize]byte, error) { - hashFileCache.Lock() - out, ok := hashFileCache.m[file] - hashFileCache.Unlock() - - if ok { - return out, nil - } - - h := sha256.New() - f, err := os.Open(file) - if err != nil { - if debugHash { - fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err) - } - return [HashSize]byte{}, err - } - _, err = io.Copy(h, f) - f.Close() - if err != nil { - if debugHash { - fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err) - } - return [HashSize]byte{}, err - } - h.Sum(out[:0]) - if debugHash { - fmt.Fprintf(os.Stderr, "HASH %s: %x\n", file, out) - } - - SetFileHash(file, out) - return out, nil -} - -// SetFileHash sets the hash returned by FileHash for file. -func SetFileHash(file string, sum [HashSize]byte) { - hashFileCache.Lock() - if hashFileCache.m == nil { - hashFileCache.m = make(map[string][HashSize]byte) - } - hashFileCache.m[file] = sum - hashFileCache.Unlock() -} diff --git a/vendor/honnef.co/go/tools/internal/go/gcimporter/exportdata.go b/vendor/honnef.co/go/tools/internal/go/gcimporter/exportdata.go deleted file mode 100644 index 512dc10516..0000000000 --- a/vendor/honnef.co/go/tools/internal/go/gcimporter/exportdata.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2011 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 is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go. - -// This file implements FindExportData. - -package gcimporter - -import ( - "bufio" - "fmt" - "io" - "io/ioutil" - "strconv" - "strings" -) - -func readGopackHeader(r io.Reader) (name string, size int, err error) { - // See $GOROOT/include/ar.h. - hdr := make([]byte, 16+12+6+6+8+10+2) - _, err = io.ReadFull(r, hdr) - if err != nil { - return - } - // leave for debugging - if false { - fmt.Printf("header: %s", hdr) - } - s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) - size, err = strconv.Atoi(s) - if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { - err = fmt.Errorf("invalid archive header") - return - } - name = strings.TrimSpace(string(hdr[:16])) - return -} - -// findExportData positions the reader r at the beginning of the -// export data section of an underlying GC-created object/archive -// file by reading from it. The reader must be positioned at the -// start of the file before calling this function. The hdr result -// is the string before the export data, either "$$" or "$$B". -// -func findExportData(r *bufio.Reader) (hdr string, length int, err error) { - // Read first line to make sure this is an object file. - line, err := r.ReadSlice('\n') - if err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - - if string(line) == "!\n" { - // Archive file. Scan to __.PKGDEF. - var name string - if name, length, err = readGopackHeader(r); err != nil { - return - } - - // First entry should be __.PKGDEF. - if name != "__.PKGDEF" { - err = fmt.Errorf("go archive is missing __.PKGDEF") - return - } - - // Read first line of __.PKGDEF data, so that line - // is once again the first line of the input. - if line, err = r.ReadSlice('\n'); err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - length -= len(line) - } - - // Now at __.PKGDEF in archive or still at beginning of file. - // Either way, line should begin with "go object ". - if !strings.HasPrefix(string(line), "go object ") { - err = fmt.Errorf("not a Go object file") - return - } - - // Skip over object header to export data. - // Begins after first line starting with $$. - for line[0] != '$' { - if line, err = r.ReadSlice('\n'); err != nil { - err = fmt.Errorf("can't find export data (%v)", err) - return - } - length -= len(line) - } - hdr = string(line) - - return -} - -func GetExportData(r io.ReadSeeker, b []byte) ([]byte, error) { - br := bufio.NewReader(r) - _, length, err := findExportData(br) - if err != nil { - return nil, err - } - if _, err := r.Seek(-int64(br.Buffered()), io.SeekCurrent); err != nil { - return nil, err - } - if length > 0 { - if cap(b) >= length { - b = b[:length] - } else { - b = make([]byte, length) - } - _, err := io.ReadFull(r, b) - return b, err - } else { - return ioutil.ReadAll(r) - } -} diff --git a/vendor/honnef.co/go/tools/internal/go/gcimporter/gcimporter.go b/vendor/honnef.co/go/tools/internal/go/gcimporter/gcimporter.go deleted file mode 100644 index 92a610a1b2..0000000000 --- a/vendor/honnef.co/go/tools/internal/go/gcimporter/gcimporter.go +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2011 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 is a modified copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go, -// but it also contains the original source-based importer code for Go1.6. -// Once we stop supporting 1.6, we can remove that code. - -// Package gcimporter provides various functions for reading -// gc-generated object files that can be used to implement the -// Importer interface defined by the Go 1.5 standard library package. -package gcimporter - -import ( - "bufio" - "fmt" - "go/build" - "go/token" - "go/types" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" -) - -var pkgExts = [...]string{".a", ".o"} - -// FindPkg returns the filename and unique package id for an import -// path based on package information provided by build.Import (using -// the build.Default build.Context). A relative srcDir is interpreted -// relative to the current working directory. -// If no file was found, an empty filename is returned. -// -func FindPkg(path, srcDir string) (filename, id string) { - if path == "" { - return - } - - var noext string - switch { - default: - // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" - // Don't require the source files to be present. - if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 - srcDir = abs - } - bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary) - if bp.PkgObj == "" { - id = path // make sure we have an id to print in error message - return - } - noext = strings.TrimSuffix(bp.PkgObj, ".a") - id = bp.ImportPath - - case build.IsLocalImport(path): - // "./x" -> "/this/directory/x.ext", "/this/directory/x" - noext = filepath.Join(srcDir, path) - id = noext - - case filepath.IsAbs(path): - // for completeness only - go/build.Import - // does not support absolute imports - // "/x" -> "/x.ext", "/x" - noext = path - id = path - } - - if false { // for debugging - if path != id { - fmt.Printf("%s -> %s\n", path, id) - } - } - - // try extensions - for _, ext := range pkgExts { - filename = noext + ext - if f, err := os.Stat(filename); err == nil && !f.IsDir() { - return - } - } - - filename = "" // not found - return -} - -// Import imports a gc-generated package given its import path and srcDir, adds -// the corresponding package object to the packages map, and returns the object. -// The packages map must contain all packages already imported. -// -func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) { - var rc io.ReadCloser - var filename, id string - if lookup != nil { - // With custom lookup specified, assume that caller has - // converted path to a canonical import path for use in the map. - if path == "unsafe" { - return types.Unsafe, nil - } - id = path - - // No need to re-import if the package was imported completely before. - if pkg = packages[id]; pkg != nil && pkg.Complete() { - return - } - f, err := lookup(path) - if err != nil { - return nil, err - } - rc = f - } else { - filename, id = FindPkg(path, srcDir) - if filename == "" { - if path == "unsafe" { - return types.Unsafe, nil - } - return nil, fmt.Errorf("can't find import: %q", id) - } - - // no need to re-import if the package was imported completely before - if pkg = packages[id]; pkg != nil && pkg.Complete() { - return - } - - // open file - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer func() { - if err != nil { - // add file name to error - err = fmt.Errorf("%s: %v", filename, err) - } - }() - rc = f - } - defer rc.Close() - - var hdr string - buf := bufio.NewReader(rc) - if hdr, _, err = findExportData(buf); err != nil { - return - } - - switch hdr { - case "$$B\n": - var data []byte - data, err = ioutil.ReadAll(buf) - if err != nil { - break - } - - // TODO(gri): allow clients of go/importer to provide a FileSet. - // Or, define a new standard go/types/gcexportdata package. - fset := token.NewFileSet() - - // The indexed export format starts with an 'i'. - if len(data) == 0 || data[0] != 'i' { - return nil, fmt.Errorf("unknown export data format %c", data[0]) - } - _, pkg, err = IImportData(fset, packages, data[1:], id) - - default: - err = fmt.Errorf("unknown export data header: %q", hdr) - } - - return -} - -type byPath []*types.Package - -func (a byPath) Len() int { return len(a) } -func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() } diff --git a/vendor/honnef.co/go/tools/internal/go/gcimporter/iimport.go b/vendor/honnef.co/go/tools/internal/go/gcimporter/iimport.go deleted file mode 100644 index 0db50ca0d9..0000000000 --- a/vendor/honnef.co/go/tools/internal/go/gcimporter/iimport.go +++ /dev/null @@ -1,764 +0,0 @@ -// 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. - -// Indexed package import. -// See cmd/compile/internal/gc/iexport.go for the export data format. - -// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go. - -package gcimporter - -import ( - "bytes" - "encoding/binary" - "fmt" - "go/constant" - "go/token" - "go/types" - "io" - "sort" - "sync" - "unsafe" -) - -type intReader struct { - *bytes.Reader - path string -} - -func errorf(format string, args ...interface{}) { - panic(fmt.Sprintf(format, args...)) -} - -func (r *intReader) uint64() uint64 { - i, err := binary.ReadUvarint(r.Reader) - if err != nil { - errorf("import %q: read varint error: %v", r.path, err) - } - return i -} - -const predeclReserved = 32 - -type itag uint64 - -const ( - // Types - definedType itag = iota - pointerType - sliceType - arrayType - chanType - mapType - signatureType - structType - interfaceType -) - -// IImportData imports a package from the serialized package data -// and returns the number of bytes consumed and a reference to the package. -// If the export data version is not recognized or the format is otherwise -// compromised, an error is returned. -func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { - const currentVersion = 1 - version := int64(-1) - defer func() { - if e := recover(); e != nil { - if version > currentVersion { - err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e) - } else { - err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e) - } - } - }() - - // OPT(dh): use a cheaper reader that does less state tracking. we - // don't need to be able to unread. - r := &intReader{bytes.NewReader(data), path} - - version = int64(r.uint64()) - switch version { - case currentVersion, 0: - default: - errorf("unknown iexport format version %d", version) - } - - sLen := int64(r.uint64()) - dLen := int64(r.uint64()) - - whence, _ := r.Seek(0, io.SeekCurrent) - stringData := data[whence : whence+sLen] - declData := data[whence+sLen : whence+sLen+dLen] - r.Seek(sLen+dLen, io.SeekCurrent) - - p := iimporter{ - ipath: path, - version: int(version), - - stringData: stringData, - stringCache: make(map[uint64]string), - pkgCache: make(map[uint64]*types.Package), - - declData: declData, - pkgIndex: make(map[*types.Package]map[string]uint64), - typCache: make(map[uint64]types.Type), - - fake: fakeFileSet{ - fset: fset, - files: make(map[string]*token.File), - }, - } - - for i, pt := range predeclared() { - p.typCache[uint64(i)] = pt - } - - pkgList := make([]*types.Package, r.uint64()) - for i := range pkgList { - pkgPathOff := r.uint64() - pkgPath := p.stringAt(pkgPathOff) - pkgName := p.stringAt(r.uint64()) - _ = r.uint64() // package height; unused by go/types - - if pkgPath == "" { - pkgPath = path - } - pkg := imports[pkgPath] - if pkg == nil { - pkg = types.NewPackage(pkgPath, pkgName) - imports[pkgPath] = pkg - } else if pkg.Name() != pkgName { - errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path) - } - - p.pkgCache[pkgPathOff] = pkg - - nameIndex := make(map[string]uint64) - for nSyms := r.uint64(); nSyms > 0; nSyms-- { - name := p.stringAt(r.uint64()) - nameIndex[name] = r.uint64() - } - - p.pkgIndex[pkg] = nameIndex - pkgList[i] = pkg - } - if len(pkgList) == 0 { - errorf("no packages found for %s", path) - panic("unreachable") - } - p.ipkg = pkgList[0] - names := make([]string, 0, len(p.pkgIndex[p.ipkg])) - for name := range p.pkgIndex[p.ipkg] { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { - p.doDecl(p.ipkg, name) - } - - for _, typ := range p.interfaceList { - typ.Complete() - } - - // record all referenced packages as imports - list := append(([]*types.Package)(nil), pkgList[1:]...) - sort.Sort(byPath(list)) - p.ipkg.SetImports(list) - - // package was imported completely and without errors - p.ipkg.MarkComplete() - - consumed, _ := r.Seek(0, io.SeekCurrent) - return int(consumed), p.ipkg, nil -} - -type iimporter struct { - ipath string - ipkg *types.Package - version int - - stringData []byte - stringCache map[uint64]string - pkgCache map[uint64]*types.Package - - declData []byte - pkgIndex map[*types.Package]map[string]uint64 - typCache map[uint64]types.Type - - fake fakeFileSet - interfaceList []*types.Interface -} - -func (p *iimporter) doDecl(pkg *types.Package, name string) { - // See if we've already imported this declaration. - if obj := pkg.Scope().Lookup(name); obj != nil { - return - } - - off, ok := p.pkgIndex[pkg][name] - if !ok { - errorf("%v.%v not in index", pkg, name) - } - - r := &importReader{p: p, currPkg: pkg} - r.declReader.Reset(p.declData[off:]) - - r.obj(name) -} - -func (p *iimporter) stringAt(off uint64) string { - if s, ok := p.stringCache[off]; ok { - return s - } - - slen, n := binary.Uvarint(p.stringData[off:]) - if n <= 0 { - errorf("varint failed") - } - spos := off + uint64(n) - s := string(p.stringData[spos : spos+slen]) - p.stringCache[off] = s - return s -} - -func (p *iimporter) pkgAt(off uint64) *types.Package { - if pkg, ok := p.pkgCache[off]; ok { - return pkg - } - path := p.stringAt(off) - if path == p.ipath { - return p.ipkg - } - errorf("missing package %q in %q", path, p.ipath) - return nil -} - -func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { - if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) { - return t - } - - if off < predeclReserved { - errorf("predeclared type missing from cache: %v", off) - } - - r := &importReader{p: p} - r.declReader.Reset(p.declData[off-predeclReserved:]) - t := r.doType(base) - - if base == nil || !isInterface(t) { - p.typCache[off] = t - } - return t -} - -type importReader struct { - p *iimporter - declReader bytes.Reader - currPkg *types.Package - prevFile string - prevLine int64 - prevColumn int64 -} - -func (r *importReader) obj(name string) { - tag := r.byte() - pos := r.pos() - - switch tag { - case 'A': - typ := r.typ() - - r.declare(types.NewTypeName(pos, r.currPkg, name, typ)) - - case 'C': - typ, val := r.value() - - r.declare(types.NewConst(pos, r.currPkg, name, typ, val)) - - case 'F': - sig := r.signature(nil) - - r.declare(types.NewFunc(pos, r.currPkg, name, sig)) - - case 'T': - // Types can be recursive. We need to setup a stub - // declaration before recursing. - obj := types.NewTypeName(pos, r.currPkg, name, nil) - named := types.NewNamed(obj, nil, nil) - r.declare(obj) - - underlying := r.p.typAt(r.uint64(), named).Underlying() - named.SetUnderlying(underlying) - - if !isInterface(underlying) { - for n := r.uint64(); n > 0; n-- { - mpos := r.pos() - mname := r.ident() - recv := r.param() - msig := r.signature(recv) - - named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig)) - } - } - - case 'V': - typ := r.typ() - - r.declare(types.NewVar(pos, r.currPkg, name, typ)) - - default: - errorf("unexpected tag: %v", tag) - } -} - -func (r *importReader) declare(obj types.Object) { - obj.Pkg().Scope().Insert(obj) -} - -func (r *importReader) value() (typ types.Type, val constant.Value) { - typ = r.typ() - - switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType { - case types.IsBoolean: - val = constant.MakeBool(r.bool()) - - case types.IsString: - val = constant.MakeString(r.string()) - - case types.IsInteger: - val = r.mpint(b) - - case types.IsFloat: - val = r.mpfloat(b) - - case types.IsComplex: - re := r.mpfloat(b) - im := r.mpfloat(b) - val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im)) - - default: - if b.Kind() == types.Invalid { - val = constant.MakeUnknown() - return - } - errorf("unexpected type %v", typ) // panics - panic("unreachable") - } - - return -} - -func intSize(b *types.Basic) (signed bool, maxBytes uint) { - if (b.Info() & types.IsUntyped) != 0 { - return true, 64 - } - - switch b.Kind() { - case types.Float32, types.Complex64: - return true, 3 - case types.Float64, types.Complex128: - return true, 7 - } - - signed = (b.Info() & types.IsUnsigned) == 0 - switch b.Kind() { - case types.Int8, types.Uint8: - maxBytes = 1 - case types.Int16, types.Uint16: - maxBytes = 2 - case types.Int32, types.Uint32: - maxBytes = 4 - default: - maxBytes = 8 - } - - return -} - -func (r *importReader) mpint(b *types.Basic) constant.Value { - signed, maxBytes := intSize(b) - - maxSmall := 256 - maxBytes - if signed { - maxSmall = 256 - 2*maxBytes - } - if maxBytes == 1 { - maxSmall = 256 - } - - n, _ := r.declReader.ReadByte() - if uint(n) < maxSmall { - v := int64(n) - if signed { - v >>= 1 - if n&1 != 0 { - v = ^v - } - } - return constant.MakeInt64(v) - } - - v := -n - if signed { - v = -(n &^ 1) >> 1 - } - if v < 1 || uint(v) > maxBytes { - errorf("weird decoding: %v, %v => %v", n, signed, v) - } - - buf := make([]byte, v) - io.ReadFull(&r.declReader, buf) - - // convert to little endian - // TODO(gri) go/constant should have a more direct conversion function - // (e.g., once it supports a big.Float based implementation) - for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 { - buf[i], buf[j] = buf[j], buf[i] - } - - x := constant.MakeFromBytes(buf) - if signed && n&1 != 0 { - x = constant.UnaryOp(token.SUB, x, 0) - } - return x -} - -func (r *importReader) mpfloat(b *types.Basic) constant.Value { - x := r.mpint(b) - if constant.Sign(x) == 0 { - return x - } - - exp := r.int64() - switch { - case exp > 0: - x = constant.Shift(x, token.SHL, uint(exp)) - case exp < 0: - d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) - x = constant.BinaryOp(x, token.QUO, d) - } - return x -} - -func (r *importReader) ident() string { - return r.string() -} - -func (r *importReader) qualifiedIdent() (*types.Package, string) { - name := r.string() - pkg := r.pkg() - return pkg, name -} - -func (r *importReader) pos() token.Pos { - if r.p.version >= 1 { - r.posv1() - } else { - r.posv0() - } - - if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { - return token.NoPos - } - return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) -} - -func (r *importReader) posv0() { - delta := r.int64() - if delta != deltaNewFile { - r.prevLine += delta - } else if l := r.int64(); l == -1 { - r.prevLine += deltaNewFile - } else { - r.prevFile = r.string() - r.prevLine = l - } -} - -func (r *importReader) posv1() { - delta := r.int64() - r.prevColumn += delta >> 1 - if delta&1 != 0 { - delta = r.int64() - r.prevLine += delta >> 1 - if delta&1 != 0 { - r.prevFile = r.string() - } - } -} - -func (r *importReader) typ() types.Type { - return r.p.typAt(r.uint64(), nil) -} - -func isInterface(t types.Type) bool { - _, ok := t.(*types.Interface) - return ok -} - -func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) } -func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } - -func (r *importReader) doType(base *types.Named) types.Type { - switch k := r.kind(); k { - default: - errorf("unexpected kind tag in %q: %v", r.p.ipath, k) - return nil - - case definedType: - pkg, name := r.qualifiedIdent() - r.p.doDecl(pkg, name) - return pkg.Scope().Lookup(name).(*types.TypeName).Type() - case pointerType: - return types.NewPointer(r.typ()) - case sliceType: - return types.NewSlice(r.typ()) - case arrayType: - n := r.uint64() - return types.NewArray(r.typ(), int64(n)) - case chanType: - dir := chanDir(int(r.uint64())) - return types.NewChan(dir, r.typ()) - case mapType: - return types.NewMap(r.typ(), r.typ()) - case signatureType: - r.currPkg = r.pkg() - return r.signature(nil) - - case structType: - r.currPkg = r.pkg() - - fields := make([]*types.Var, r.uint64()) - tags := make([]string, len(fields)) - for i := range fields { - fpos := r.pos() - fname := r.ident() - ftyp := r.typ() - emb := r.bool() - tag := r.string() - - fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb) - tags[i] = tag - } - return types.NewStruct(fields, tags) - - case interfaceType: - r.currPkg = r.pkg() - - embeddeds := make([]types.Type, r.uint64()) - for i := range embeddeds { - _ = r.pos() - embeddeds[i] = r.typ() - } - - methods := make([]*types.Func, r.uint64()) - for i := range methods { - mpos := r.pos() - mname := r.ident() - - // TODO(mdempsky): Matches bimport.go, but I - // don't agree with this. - var recv *types.Var - if base != nil { - recv = types.NewVar(token.NoPos, r.currPkg, "", base) - } - - msig := r.signature(recv) - methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig) - } - - typ := newInterface(methods, embeddeds) - r.p.interfaceList = append(r.p.interfaceList, typ) - return typ - } -} - -func (r *importReader) kind() itag { - return itag(r.uint64()) -} - -func (r *importReader) signature(recv *types.Var) *types.Signature { - params := r.paramList() - results := r.paramList() - variadic := params.Len() > 0 && r.bool() - return types.NewSignature(recv, params, results, variadic) -} - -func (r *importReader) paramList() *types.Tuple { - xs := make([]*types.Var, r.uint64()) - for i := range xs { - xs[i] = r.param() - } - return types.NewTuple(xs...) -} - -func (r *importReader) param() *types.Var { - pos := r.pos() - name := r.ident() - typ := r.typ() - return types.NewParam(pos, r.currPkg, name, typ) -} - -func (r *importReader) bool() bool { - return r.uint64() != 0 -} - -func (r *importReader) int64() int64 { - n, err := binary.ReadVarint(&r.declReader) - if err != nil { - errorf("readVarint: %v", err) - } - return n -} - -func (r *importReader) uint64() uint64 { - n, err := binary.ReadUvarint(&r.declReader) - if err != nil { - errorf("readUvarint: %v", err) - } - return n -} - -func (r *importReader) byte() byte { - x, err := r.declReader.ReadByte() - if err != nil { - errorf("declReader.ReadByte: %v", err) - } - return x -} - -const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go - -// Synthesize a token.Pos -type fakeFileSet struct { - fset *token.FileSet - files map[string]*token.File -} - -type unsafeFile struct { - _ uintptr - _ string - _ int - _ int - mutex sync.Mutex - lines []int -} - -func (f *unsafeFile) SetLines(lines []int) bool { - f.mutex.Lock() - f.lines = lines - f.mutex.Unlock() - return true -} - -func (s *fakeFileSet) pos(file string, line, column int) token.Pos { - // TODO(mdempsky): Make use of column. - - // Since we don't know the set of needed file positions, we - // reserve maxlines positions per file. - const maxlines = 64 * 1024 - f := s.files[file] - if f == nil { - f = s.fset.AddFile(file, -1, maxlines) - s.files[file] = f - // Allocate the fake linebreak indices on first use. - // TODO(adonovan): opt: save ~512KB using a more complex scheme? - fakeLinesOnce.Do(func() { - fakeLines = make([]int, maxlines) - for i := range fakeLines { - fakeLines[i] = i - } - }) - (*unsafeFile)(unsafe.Pointer(f)).SetLines(fakeLines) - } - - if line > maxlines { - line = 1 - } - - // Treat the file as if it contained only newlines - // and column=1: use the line number as the offset. - return f.Pos(line - 1) -} - -var ( - fakeLines []int - fakeLinesOnce sync.Once -) - -func chanDir(d int) types.ChanDir { - // tag values must match the constants in cmd/compile/internal/gc/go.go - switch d { - case 1 /* Crecv */ : - return types.RecvOnly - case 2 /* Csend */ : - return types.SendOnly - case 3 /* Cboth */ : - return types.SendRecv - default: - errorf("unexpected channel dir %d", d) - return 0 - } -} - -var predeclOnce sync.Once -var predecl []types.Type // initialized lazily - -func predeclared() []types.Type { - predeclOnce.Do(func() { - // initialize lazily to be sure that all - // elements have been initialized before - predecl = []types.Type{ // basic types - types.Typ[types.Bool], - types.Typ[types.Int], - types.Typ[types.Int8], - types.Typ[types.Int16], - types.Typ[types.Int32], - types.Typ[types.Int64], - types.Typ[types.Uint], - types.Typ[types.Uint8], - types.Typ[types.Uint16], - types.Typ[types.Uint32], - types.Typ[types.Uint64], - types.Typ[types.Uintptr], - types.Typ[types.Float32], - types.Typ[types.Float64], - types.Typ[types.Complex64], - types.Typ[types.Complex128], - types.Typ[types.String], - - // basic type aliases - types.Universe.Lookup("byte").Type(), - types.Universe.Lookup("rune").Type(), - - // error - types.Universe.Lookup("error").Type(), - - // untyped types - types.Typ[types.UntypedBool], - types.Typ[types.UntypedInt], - types.Typ[types.UntypedRune], - types.Typ[types.UntypedFloat], - types.Typ[types.UntypedComplex], - types.Typ[types.UntypedString], - types.Typ[types.UntypedNil], - - // package unsafe - types.Typ[types.UnsafePointer], - - // invalid type - types.Typ[types.Invalid], // only appears in packages with errors - - // used internally by gc; never used by this package or in .a files - anyType{}, - } - }) - return predecl -} - -type anyType struct{} - -func (t anyType) Underlying() types.Type { return t } -func (t anyType) String() string { return "any" } diff --git a/vendor/honnef.co/go/tools/internal/go/gcimporter/newInterface10.go b/vendor/honnef.co/go/tools/internal/go/gcimporter/newInterface10.go deleted file mode 100644 index 463f252271..0000000000 --- a/vendor/honnef.co/go/tools/internal/go/gcimporter/newInterface10.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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. - -// +build !go1.11 - -package gcimporter - -import "go/types" - -func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { - named := make([]*types.Named, len(embeddeds)) - for i, e := range embeddeds { - var ok bool - named[i], ok = e.(*types.Named) - if !ok { - panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11") - } - } - return types.NewInterface(methods, named) -} diff --git a/vendor/honnef.co/go/tools/internal/go/gcimporter/newInterface11.go b/vendor/honnef.co/go/tools/internal/go/gcimporter/newInterface11.go deleted file mode 100644 index ab28b95cbb..0000000000 --- a/vendor/honnef.co/go/tools/internal/go/gcimporter/newInterface11.go +++ /dev/null @@ -1,13 +0,0 @@ -// 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. - -// +build go1.11 - -package gcimporter - -import "go/types" - -func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { - return types.NewInterfaceType(methods, embeddeds) -} diff --git a/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go b/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go deleted file mode 100644 index 645e216a96..0000000000 --- a/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go +++ /dev/null @@ -1,117 +0,0 @@ -// 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 buildir defines an Analyzer that constructs the IR -// of an error-free package and returns the set of all -// functions within it. It does not report any diagnostics itself but -// may be used as an input to other analyzers. -// -// THIS INTERFACE IS EXPERIMENTAL AND MAY BE SUBJECT TO INCOMPATIBLE CHANGE. -package buildir - -import ( - "go/ast" - "go/types" - "reflect" - - "honnef.co/go/tools/go/ir" - - "golang.org/x/tools/go/analysis" -) - -type willExit struct{} -type willUnwind struct{} - -func (*willExit) AFact() {} -func (*willUnwind) AFact() {} - -func (*willExit) String() string { return "will exit" } -func (*willUnwind) String() string { return "will unwind" } - -var Analyzer = &analysis.Analyzer{ - Name: "buildir", - Doc: "build IR for later passes", - Run: run, - ResultType: reflect.TypeOf(new(IR)), - FactTypes: []analysis.Fact{new(willExit), new(willUnwind)}, -} - -// IR provides intermediate representation for all the -// non-blank source functions in the current package. -type IR struct { - Pkg *ir.Package - SrcFuncs []*ir.Function -} - -func run(pass *analysis.Pass) (interface{}, error) { - // Plundered from ssautil.BuildPackage. - - // We must create a new Program for each Package because the - // analysis API provides no place to hang a Program shared by - // all Packages. Consequently, IR Packages and Functions do not - // have a canonical representation across an analysis session of - // multiple packages. This is unlikely to be a problem in - // practice because the analysis API essentially forces all - // packages to be analysed independently, so any given call to - // Analysis.Run on a package will see only IR objects belonging - // to a single Program. - - mode := ir.GlobalDebug - - prog := ir.NewProgram(pass.Fset, mode) - - // Create IR packages for all imports. - // Order is not significant. - created := make(map[*types.Package]bool) - var createAll func(pkgs []*types.Package) - createAll = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !created[p] { - created[p] = true - irpkg := prog.CreatePackage(p, nil, nil, true) - for _, fn := range irpkg.Functions { - if ast.IsExported(fn.Name()) { - var exit willExit - var unwind willUnwind - if pass.ImportObjectFact(fn.Object(), &exit) { - fn.WillExit = true - } - if pass.ImportObjectFact(fn.Object(), &unwind) { - fn.WillUnwind = true - } - } - } - createAll(p.Imports()) - } - } - } - createAll(pass.Pkg.Imports()) - - // Create and build the primary package. - irpkg := prog.CreatePackage(pass.Pkg, pass.Files, pass.TypesInfo, false) - irpkg.Build() - - // Compute list of source functions, including literals, - // in source order. - var addAnons func(f *ir.Function) - funcs := make([]*ir.Function, len(irpkg.Functions)) - copy(funcs, irpkg.Functions) - addAnons = func(f *ir.Function) { - for _, anon := range f.AnonFuncs { - funcs = append(funcs, anon) - addAnons(anon) - } - } - for _, fn := range irpkg.Functions { - addAnons(fn) - if fn.WillExit { - pass.ExportObjectFact(fn.Object(), new(willExit)) - } - if fn.WillUnwind { - pass.ExportObjectFact(fn.Object(), new(willUnwind)) - } - } - - return &IR{Pkg: irpkg, SrcFuncs: funcs}, nil -} diff --git a/vendor/honnef.co/go/tools/internal/renameio/renameio.go b/vendor/honnef.co/go/tools/internal/renameio/renameio.go deleted file mode 100644 index 5e0dfa2f81..0000000000 --- a/vendor/honnef.co/go/tools/internal/renameio/renameio.go +++ /dev/null @@ -1,93 +0,0 @@ -// 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 renameio writes files atomically by renaming temporary files. -package renameio - -import ( - "bytes" - "io" - "math/rand" - "os" - "path/filepath" - "strconv" - - "honnef.co/go/tools/internal/robustio" -) - -const patternSuffix = ".tmp" - -// Pattern returns a glob pattern that matches the unrenamed temporary files -// created when writing to filename. -func Pattern(filename string) string { - return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix) -} - -// WriteFile is like ioutil.WriteFile, but first writes data to an arbitrary -// file in the same directory as filename, then renames it atomically to the -// final name. -// -// That ensures that the final location, if it exists, is always a complete file. -func WriteFile(filename string, data []byte, perm os.FileMode) (err error) { - return WriteToFile(filename, bytes.NewReader(data), perm) -} - -// WriteToFile is a variant of WriteFile that accepts the data as an io.Reader -// instead of a slice. -func WriteToFile(filename string, data io.Reader, perm os.FileMode) (err error) { - f, err := tempFile(filepath.Dir(filename), filepath.Base(filename), perm) - if err != nil { - return err - } - defer func() { - // Only call os.Remove on f.Name() if we failed to rename it: otherwise, - // some other process may have created a new file with the same name after - // that. - if err != nil { - f.Close() - os.Remove(f.Name()) - } - }() - - if _, err := io.Copy(f, data); err != nil { - return err - } - // Sync the file before renaming it: otherwise, after a crash the reader may - // observe a 0-length file instead of the actual contents. - // See https://golang.org/issue/22397#issuecomment-380831736. - if err := f.Sync(); err != nil { - return err - } - if err := f.Close(); err != nil { - return err - } - - return robustio.Rename(f.Name(), filename) -} - -// ReadFile is like ioutil.ReadFile, but on Windows retries spurious errors that -// may occur if the file is concurrently replaced. -// -// Errors are classified heuristically and retries are bounded, so even this -// function may occasionally return a spurious error on Windows. -// If so, the error will likely wrap one of: -// - syscall.ERROR_ACCESS_DENIED -// - syscall.ERROR_FILE_NOT_FOUND -// - internal/syscall/windows.ERROR_SHARING_VIOLATION -func ReadFile(filename string) ([]byte, error) { - return robustio.ReadFile(filename) -} - -// tempFile creates a new temporary file with given permission bits. -func tempFile(dir, prefix string, perm os.FileMode) (f *os.File, err error) { - for i := 0; i < 10000; i++ { - name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+patternSuffix) - f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm) - if os.IsExist(err) { - continue - } - break - } - return -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio.go b/vendor/honnef.co/go/tools/internal/robustio/robustio.go deleted file mode 100644 index 76e47ad1ff..0000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio.go +++ /dev/null @@ -1,53 +0,0 @@ -// 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. - -// Package robustio wraps I/O functions that are prone to failure on Windows, -// transparently retrying errors up to an arbitrary timeout. -// -// Errors are classified heuristically and retries are bounded, so the functions -// in this package do not completely eliminate spurious errors. However, they do -// significantly reduce the rate of failure in practice. -// -// If so, the error will likely wrap one of: -// The functions in this package do not completely eliminate spurious errors, -// but substantially reduce their rate of occurrence in practice. -package robustio - -// Rename is like os.Rename, but on Windows retries errors that may occur if the -// file is concurrently read or overwritten. -// -// (See golang.org/issue/31247 and golang.org/issue/32188.) -func Rename(oldpath, newpath string) error { - return rename(oldpath, newpath) -} - -// ReadFile is like ioutil.ReadFile, but on Windows retries errors that may -// occur if the file is concurrently replaced. -// -// (See golang.org/issue/31247 and golang.org/issue/32188.) -func ReadFile(filename string) ([]byte, error) { - return readFile(filename) -} - -// RemoveAll is like os.RemoveAll, but on Windows retries errors that may occur -// if an executable file in the directory has recently been executed. -// -// (See golang.org/issue/19491.) -func RemoveAll(path string) error { - return removeAll(path) -} - -// IsEphemeralError reports whether err is one of the errors that the functions -// in this package attempt to mitigate. -// -// Errors considered ephemeral include: -// - syscall.ERROR_ACCESS_DENIED -// - syscall.ERROR_FILE_NOT_FOUND -// - internal/syscall/windows.ERROR_SHARING_VIOLATION -// -// This set may be expanded in the future; programs must not rely on the -// non-ephemerality of any given error. -func IsEphemeralError(err error) bool { - return isEphemeralError(err) -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go deleted file mode 100644 index 99fd8ebc2f..0000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go +++ /dev/null @@ -1,21 +0,0 @@ -// 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. - -package robustio - -import ( - "errors" - "syscall" -) - -const errFileNotFound = syscall.ENOENT - -// isEphemeralError returns true if err may be resolved by waiting. -func isEphemeralError(err error) bool { - var errno syscall.Errno - if errors.As(err, &errno) { - return errno == errFileNotFound - } - return false -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go deleted file mode 100644 index d4cb7e6457..0000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go +++ /dev/null @@ -1,92 +0,0 @@ -// 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. - -// +build windows darwin - -package robustio - -import ( - "errors" - "io/ioutil" - "math/rand" - "os" - "syscall" - "time" -) - -const arbitraryTimeout = 2000 * time.Millisecond - -// retry retries ephemeral errors from f up to an arbitrary timeout -// to work around filesystem flakiness on Windows and Darwin. -func retry(f func() (err error, mayRetry bool)) error { - var ( - bestErr error - lowestErrno syscall.Errno - start time.Time - nextSleep time.Duration = 1 * time.Millisecond - ) - for { - err, mayRetry := f() - if err == nil || !mayRetry { - return err - } - - var errno syscall.Errno - if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) { - bestErr = err - lowestErrno = errno - } else if bestErr == nil { - bestErr = err - } - - if start.IsZero() { - start = time.Now() - } else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout { - break - } - time.Sleep(nextSleep) - nextSleep += time.Duration(rand.Int63n(int64(nextSleep))) - } - - return bestErr -} - -// rename is like os.Rename, but retries ephemeral errors. -// -// On Windows it wraps os.Rename, which (as of 2019-06-04) uses MoveFileEx with -// MOVEFILE_REPLACE_EXISTING. -// -// Windows also provides a different system call, ReplaceFile, -// that provides similar semantics, but perhaps preserves more metadata. (The -// documentation on the differences between the two is very sparse.) -// -// Empirical error rates with MoveFileEx are lower under modest concurrency, so -// for now we're sticking with what the os package already provides. -func rename(oldpath, newpath string) (err error) { - return retry(func() (err error, mayRetry bool) { - err = os.Rename(oldpath, newpath) - return err, isEphemeralError(err) - }) -} - -// readFile is like ioutil.ReadFile, but retries ephemeral errors. -func readFile(filename string) ([]byte, error) { - var b []byte - err := retry(func() (err error, mayRetry bool) { - b, err = ioutil.ReadFile(filename) - - // Unlike in rename, we do not retry errFileNotFound here: it can occur - // as a spurious error, but the file may also genuinely not exist, so the - // increase in robustness is probably not worth the extra latency. - return err, isEphemeralError(err) && !errors.Is(err, errFileNotFound) - }) - return b, err -} - -func removeAll(path string) error { - return retry(func() (err error, mayRetry bool) { - err = os.RemoveAll(path) - return err, isEphemeralError(err) - }) -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_other.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_other.go deleted file mode 100644 index 907b556858..0000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio_other.go +++ /dev/null @@ -1,28 +0,0 @@ -// 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. - -// +build !windows,!darwin - -package robustio - -import ( - "io/ioutil" - "os" -) - -func rename(oldpath, newpath string) error { - return os.Rename(oldpath, newpath) -} - -func readFile(filename string) ([]byte, error) { - return ioutil.ReadFile(filename) -} - -func removeAll(path string) error { - return os.RemoveAll(path) -} - -func isEphemeralError(err error) bool { - return false -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go deleted file mode 100644 index 200070a9e8..0000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -package robustio - -import ( - "errors" - "syscall" -) - -const ERROR_SHARING_VIOLATION = 32 -const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND - -// isEphemeralError returns true if err may be resolved by waiting. -func isEphemeralError(err error) bool { - var errno syscall.Errno - if errors.As(err, &errno) { - switch errno { - case syscall.ERROR_ACCESS_DENIED, - syscall.ERROR_FILE_NOT_FOUND, - ERROR_SHARING_VIOLATION: - return true - } - } - return false -} diff --git a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go b/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go deleted file mode 100644 index df6c82fb9b..0000000000 --- a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go +++ /dev/null @@ -1,74 +0,0 @@ -package sharedcheck - -import ( - "go/ast" - "go/types" - - "honnef.co/go/tools/go/ast/astutil" - "honnef.co/go/tools/go/ir" - "honnef.co/go/tools/go/ir/irutil" - "honnef.co/go/tools/internal/passes/buildir" - - "golang.org/x/tools/go/analysis" -) - -func CheckRangeStringRunes(pass *analysis.Pass) (interface{}, error) { - for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs { - cb := func(node ast.Node) bool { - rng, ok := node.(*ast.RangeStmt) - if !ok || !astutil.IsBlank(rng.Key) { - return true - } - - v, _ := fn.ValueForExpr(rng.X) - - // Check that we're converting from string to []rune - val, _ := v.(*ir.Convert) - if val == nil { - return true - } - Tsrc, ok := val.X.Type().Underlying().(*types.Basic) - if !ok || Tsrc.Kind() != types.String { - return true - } - Tdst, ok := val.Type().(*types.Slice) - if !ok { - return true - } - TdstElem, ok := Tdst.Elem().(*types.Basic) - if !ok || TdstElem.Kind() != types.Int32 { - return true - } - - // Check that the result of the conversion is only used to - // range over - refs := val.Referrers() - if refs == nil { - return true - } - - // Expect two refs: one for obtaining the length of the slice, - // one for accessing the elements - if len(irutil.FilterDebug(*refs)) != 2 { - // TODO(dh): right now, we check that only one place - // refers to our slice. This will miss cases such as - // ranging over the slice twice. Ideally, we'd ensure that - // the slice is only used for ranging over (without - // accessing the key), but that is harder to do because in - // IR form, ranging over a slice looks like an ordinary - // loop with index increments and slice accesses. We'd - // have to look at the associated AST node to check that - // it's a range statement. - return true - } - - pass.Reportf(rng.Pos(), "should range over string, not []rune(string)") - - return true - } - if source := fn.Source(); source != nil { - ast.Inspect(source, cb) - } - } - return nil, nil -} diff --git a/vendor/honnef.co/go/tools/internal/sync/sync.go b/vendor/honnef.co/go/tools/internal/sync/sync.go deleted file mode 100644 index e78ad50728..0000000000 --- a/vendor/honnef.co/go/tools/internal/sync/sync.go +++ /dev/null @@ -1,36 +0,0 @@ -package sync - -type Semaphore struct { - ch chan struct{} -} - -func NewSemaphore(size int) Semaphore { - return Semaphore{ - ch: make(chan struct{}, size), - } -} - -func (sem Semaphore) Acquire() { - sem.ch <- struct{}{} -} - -func (sem Semaphore) AcquireMaybe() bool { - select { - case sem.ch <- struct{}{}: - return true - default: - return false - } -} - -func (sem Semaphore) Release() { - <-sem.ch -} - -func (sem Semaphore) Len() int { - return len(sem.ch) -} - -func (sem Semaphore) Cap() int { - return cap(sem.ch) -} diff --git a/vendor/honnef.co/go/tools/knowledge/arg.go b/vendor/honnef.co/go/tools/knowledge/arg.go deleted file mode 100644 index c14ed73e4b..0000000000 --- a/vendor/honnef.co/go/tools/knowledge/arg.go +++ /dev/null @@ -1,48 +0,0 @@ -package knowledge - -var args = map[string]int{ - "(*encoding/json.Decoder).Decode.v": 0, - "(*encoding/json.Encoder).Encode.v": 0, - "(*encoding/xml.Decoder).Decode.v": 0, - "(*encoding/xml.Encoder).Encode.v": 0, - "(*sync.Pool).Put.x": 0, - "(*text/template.Template).Parse.text": 0, - "(io.Seeker).Seek.offset": 0, - "(time.Time).Sub.u": 0, - "append.elems": 1, - "append.slice": 0, - "bytes.Equal.a": 0, - "bytes.Equal.b": 1, - "encoding/binary.Write.data": 2, - "errors.New.text": 0, - "fmt.Fprintf.format": 1, - "fmt.Printf.format": 0, - "fmt.Sprintf.a[0]": 1, - "fmt.Sprintf.format": 0, - "json.Marshal.v": 0, - "json.Unmarshal.v": 1, - "len.v": 0, - "make.size[0]": 1, - "make.size[1]": 2, - "make.t": 0, - "net/url.Parse.rawurl": 0, - "os.OpenFile.flag": 1, - "os/exec.Command.name": 0, - "os/signal.Notify.c": 0, - "regexp.Compile.expr": 0, - "runtime.SetFinalizer.finalizer": 1, - "runtime.SetFinalizer.obj": 0, - "sort.Sort.data": 0, - "time.Parse.layout": 0, - "time.Sleep.d": 0, - "xml.Marshal.v": 0, - "xml.Unmarshal.v": 1, -} - -func Arg(name string) int { - n, ok := args[name] - if !ok { - panic("unknown argument " + name) - } - return n -} diff --git a/vendor/honnef.co/go/tools/knowledge/deprecated.go b/vendor/honnef.co/go/tools/knowledge/deprecated.go deleted file mode 100644 index ffed387c9f..0000000000 --- a/vendor/honnef.co/go/tools/knowledge/deprecated.go +++ /dev/null @@ -1,119 +0,0 @@ -package knowledge - -type Deprecation struct { - DeprecatedSince int - AlternativeAvailableSince int -} - -var StdlibDeprecations = map[string]Deprecation{ - // FIXME(dh): AllowBinary isn't being detected as deprecated - // because the comment has a newline right after "Deprecated:" - "go/build.AllowBinary": {7, 7}, - "(archive/zip.FileHeader).CompressedSize": {1, 1}, - "(archive/zip.FileHeader).UncompressedSize": {1, 1}, - "(archive/zip.FileHeader).ModifiedTime": {10, 10}, - "(archive/zip.FileHeader).ModifiedDate": {10, 10}, - "(*archive/zip.FileHeader).ModTime": {10, 10}, - "(*archive/zip.FileHeader).SetModTime": {10, 10}, - "(go/doc.Package).Bugs": {1, 1}, - "os.SEEK_SET": {7, 7}, - "os.SEEK_CUR": {7, 7}, - "os.SEEK_END": {7, 7}, - "(net.Dialer).Cancel": {7, 7}, - "runtime.CPUProfile": {9, 0}, - "compress/flate.ReadError": {6, 6}, - "compress/flate.WriteError": {6, 6}, - "path/filepath.HasPrefix": {0, 0}, - "(net/http.Transport).Dial": {7, 7}, - "(*net/http.Transport).CancelRequest": {6, 5}, - "net/http.ErrWriteAfterFlush": {7, 0}, - "net/http.ErrHeaderTooLong": {8, 0}, - "net/http.ErrShortBody": {8, 0}, - "net/http.ErrMissingContentLength": {8, 0}, - "net/http/httputil.ErrPersistEOF": {0, 0}, - "net/http/httputil.ErrClosed": {0, 0}, - "net/http/httputil.ErrPipeline": {0, 0}, - "net/http/httputil.ServerConn": {0, 0}, - "net/http/httputil.NewServerConn": {0, 0}, - "net/http/httputil.ClientConn": {0, 0}, - "net/http/httputil.NewClientConn": {0, 0}, - "net/http/httputil.NewProxyClientConn": {0, 0}, - "(net/http.Request).Cancel": {7, 7}, - "(text/template/parse.PipeNode).Line": {1, 1}, - "(text/template/parse.ActionNode).Line": {1, 1}, - "(text/template/parse.BranchNode).Line": {1, 1}, - "(text/template/parse.TemplateNode).Line": {1, 1}, - "database/sql/driver.ColumnConverter": {9, 9}, - "database/sql/driver.Execer": {8, 8}, - "database/sql/driver.Queryer": {8, 8}, - "(database/sql/driver.Conn).Begin": {8, 8}, - "(database/sql/driver.Stmt).Exec": {8, 8}, - "(database/sql/driver.Stmt).Query": {8, 8}, - "syscall.StringByteSlice": {1, 1}, - "syscall.StringBytePtr": {1, 1}, - "syscall.StringSlicePtr": {1, 1}, - "syscall.StringToUTF16": {1, 1}, - "syscall.StringToUTF16Ptr": {1, 1}, - "(*regexp.Regexp).Copy": {12, 12}, - "(archive/tar.Header).Xattrs": {10, 10}, - "archive/tar.TypeRegA": {11, 1}, - "go/types.NewInterface": {11, 11}, - "(*go/types.Interface).Embedded": {11, 11}, - "go/importer.For": {12, 12}, - "encoding/json.InvalidUTF8Error": {2, 2}, - "encoding/json.UnmarshalFieldError": {2, 2}, - "encoding/csv.ErrTrailingComma": {2, 2}, - "(encoding/csv.Reader).TrailingComma": {2, 2}, - "(net.Dialer).DualStack": {12, 12}, - "net/http.ErrUnexpectedTrailer": {12, 12}, - "net/http.CloseNotifier": {11, 7}, - "net/http.ProtocolError": {8, 8}, - "(crypto/x509.CertificateRequest).Attributes": {5, 3}, - // This function has no alternative, but also no purpose. - "(*crypto/rc4.Cipher).Reset": {12, 0}, - "(net/http/httptest.ResponseRecorder).HeaderMap": {11, 7}, - "image.ZP": {13, 0}, - "image.ZR": {13, 0}, - "(*debug/gosym.LineTable).LineToPC": {2, 2}, - "(*debug/gosym.LineTable).PCToLine": {2, 2}, - "crypto/tls.VersionSSL30": {13, 0}, - "(crypto/tls.Config).NameToCertificate": {14, 14}, - "(*crypto/tls.Config).BuildNameToCertificate": {14, 14}, - "image/jpeg.Reader": {4, 0}, - - // All of these have been deprecated in favour of external libraries - "syscall.AttachLsf": {7, 0}, - "syscall.DetachLsf": {7, 0}, - "syscall.LsfSocket": {7, 0}, - "syscall.SetLsfPromisc": {7, 0}, - "syscall.LsfJump": {7, 0}, - "syscall.LsfStmt": {7, 0}, - "syscall.BpfStmt": {7, 0}, - "syscall.BpfJump": {7, 0}, - "syscall.BpfBuflen": {7, 0}, - "syscall.SetBpfBuflen": {7, 0}, - "syscall.BpfDatalink": {7, 0}, - "syscall.SetBpfDatalink": {7, 0}, - "syscall.SetBpfPromisc": {7, 0}, - "syscall.FlushBpf": {7, 0}, - "syscall.BpfInterface": {7, 0}, - "syscall.SetBpfInterface": {7, 0}, - "syscall.BpfTimeout": {7, 0}, - "syscall.SetBpfTimeout": {7, 0}, - "syscall.BpfStats": {7, 0}, - "syscall.SetBpfImmediate": {7, 0}, - "syscall.SetBpf": {7, 0}, - "syscall.CheckBpfVersion": {7, 0}, - "syscall.BpfHeadercmpl": {7, 0}, - "syscall.SetBpfHeadercmpl": {7, 0}, - "syscall.RouteRIB": {8, 0}, - "syscall.RoutingMessage": {8, 0}, - "syscall.RouteMessage": {8, 0}, - "syscall.InterfaceMessage": {8, 0}, - "syscall.InterfaceAddrMessage": {8, 0}, - "syscall.ParseRoutingMessage": {8, 0}, - "syscall.ParseRoutingSockaddr": {8, 0}, - "syscall.InterfaceAnnounceMessage": {7, 0}, - "syscall.InterfaceMulticastAddrMessage": {7, 0}, - "syscall.FormatMessage": {5, 0}, -} diff --git a/vendor/honnef.co/go/tools/lintcmd/cmd.go b/vendor/honnef.co/go/tools/lintcmd/cmd.go deleted file mode 100644 index 4bda6e62d8..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/cmd.go +++ /dev/null @@ -1,814 +0,0 @@ -package lintcmd - -import ( - "crypto/sha256" - "flag" - "fmt" - "go/build" - "go/token" - "io" - "log" - "os" - "os/signal" - "path/filepath" - "regexp" - "runtime" - "runtime/pprof" - "runtime/trace" - "sort" - "strconv" - "strings" - "sync" - "time" - "unicode" - - "honnef.co/go/tools/analysis/lint" - "honnef.co/go/tools/config" - "honnef.co/go/tools/go/loader" - "honnef.co/go/tools/internal/cache" - "honnef.co/go/tools/lintcmd/runner" - "honnef.co/go/tools/lintcmd/version" - "honnef.co/go/tools/unused" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/buildutil" - "golang.org/x/tools/go/packages" -) - -type ignore interface { - Match(p problem) bool -} - -type lineIgnore struct { - File string - Line int - Checks []string - Matched bool - Pos token.Position -} - -func (li *lineIgnore) Match(p problem) bool { - pos := p.Position - if pos.Filename != li.File || pos.Line != li.Line { - return false - } - for _, c := range li.Checks { - if m, _ := filepath.Match(c, p.Category); m { - li.Matched = true - return true - } - } - return false -} - -func (li *lineIgnore) String() string { - matched := "not matched" - if li.Matched { - matched = "matched" - } - return fmt.Sprintf("%s:%d %s (%s)", li.File, li.Line, strings.Join(li.Checks, ", "), matched) -} - -type fileIgnore struct { - File string - Checks []string -} - -func (fi *fileIgnore) Match(p problem) bool { - if p.Position.Filename != fi.File { - return false - } - for _, c := range fi.Checks { - if m, _ := filepath.Match(c, p.Category); m { - return true - } - } - return false -} - -type severity uint8 - -const ( - severityError severity = iota - severityWarning - severityIgnored -) - -func (s severity) String() string { - switch s { - case severityError: - return "error" - case severityWarning: - return "warning" - case severityIgnored: - return "ignored" - default: - return fmt.Sprintf("Severity(%d)", s) - } -} - -// problem represents a problem in some source code. -type problem struct { - runner.Diagnostic - Severity severity -} - -func (p problem) equal(o problem) bool { - return p.Position == o.Position && - p.End == o.End && - p.Message == o.Message && - p.Category == o.Category && - p.Severity == o.Severity -} - -func (p *problem) String() string { - return fmt.Sprintf("%s (%s)", p.Message, p.Category) -} - -// A linter lints Go source code. -type linter struct { - Checkers []*analysis.Analyzer - Config config.Config - Runner *runner.Runner -} - -func failed(res runner.Result) []problem { - var problems []problem - - for _, e := range res.Errors { - switch e := e.(type) { - case packages.Error: - msg := e.Msg - if len(msg) != 0 && msg[0] == '\n' { - // TODO(dh): See https://github.com/golang/go/issues/32363 - msg = msg[1:] - } - - var posn token.Position - if e.Pos == "" { - // Under certain conditions (malformed package - // declarations, multiple packages in the same - // directory), go list emits an error on stderr - // instead of JSON. Those errors do not have - // associated position information in - // go/packages.Error, even though the output on - // stderr may contain it. - if p, n, err := parsePos(msg); err == nil { - if abs, err := filepath.Abs(p.Filename); err == nil { - p.Filename = abs - } - posn = p - msg = msg[n+2:] - } - } else { - var err error - posn, _, err = parsePos(e.Pos) - if err != nil { - panic(fmt.Sprintf("internal error: %s", e)) - } - } - p := problem{ - Diagnostic: runner.Diagnostic{ - Position: posn, - Message: msg, - Category: "compile", - }, - Severity: severityError, - } - problems = append(problems, p) - case error: - p := problem{ - Diagnostic: runner.Diagnostic{ - Position: token.Position{}, - Message: e.Error(), - Category: "compile", - }, - Severity: severityError, - } - problems = append(problems, p) - } - } - - return problems -} - -type unusedKey struct { - pkgPath string - base string - line int - name string -} - -type unusedPair struct { - key unusedKey - obj unused.SerializedObject -} - -func success(allowedChecks map[string]bool, res runner.ResultData) []problem { - diags := res.Diagnostics - var problems []problem - for _, diag := range diags { - if !allowedChecks[diag.Category] { - continue - } - problems = append(problems, problem{Diagnostic: diag}) - } - return problems -} - -func filterIgnored(problems []problem, res runner.ResultData, allowedAnalyzers map[string]bool) ([]problem, error) { - couldveMatched := func(ig *lineIgnore) bool { - for _, c := range ig.Checks { - if c == "U1000" { - // We never want to flag ignores for U1000, - // because U1000 isn't local to a single - // package. For example, an identifier may - // only be used by tests, in which case an - // ignore would only fire when not analyzing - // tests. To avoid spurious "useless ignore" - // warnings, just never flag U1000. - return false - } - - // Even though the runner always runs all analyzers, we - // still only flag unmatched ignores for the set of - // analyzers the user has expressed interest in. That way, - // `staticcheck -checks=SA1000` won't complain about an - // unmatched ignore for an unrelated check. - if allowedAnalyzers[c] { - return true - } - } - - return false - } - - ignores, moreProblems := parseDirectives(res.Directives) - - for _, ig := range ignores { - for i := range problems { - p := &problems[i] - if ig.Match(*p) { - p.Severity = severityIgnored - } - } - - if ig, ok := ig.(*lineIgnore); ok && !ig.Matched && couldveMatched(ig) { - p := problem{ - Diagnostic: runner.Diagnostic{ - Position: ig.Pos, - Message: "this linter directive didn't match anything; should it be removed?", - Category: "staticcheck", - }, - } - moreProblems = append(moreProblems, p) - } - } - - return append(problems, moreProblems...), nil -} - -func newLinter(cfg config.Config) (*linter, error) { - r, err := runner.New(cfg) - if err != nil { - return nil, err - } - return &linter{ - Config: cfg, - Runner: r, - }, nil -} - -func (l *linter) SetGoVersion(n int) { - l.Runner.GoVersion = n -} - -func (l *linter) Lint(cfg *packages.Config, patterns []string) (problems []problem, warnings []string, err error) { - results, err := l.Runner.Run(cfg, l.Checkers, patterns) - if err != nil { - return nil, nil, err - } - - if len(results) == 0 && err == nil { - // TODO(dh): emulate Go's behavior more closely once we have - // access to go list's Match field. - fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", patterns) - } - - analyzerNames := make([]string, len(l.Checkers)) - for i, a := range l.Checkers { - analyzerNames[i] = a.Name - } - - used := map[unusedKey]bool{} - var unuseds []unusedPair - for _, res := range results { - if len(res.Errors) > 0 && !res.Failed { - panic("package has errors but isn't marked as failed") - } - if res.Failed { - problems = append(problems, failed(res)...) - } else { - if res.Skipped { - warnings = append(warnings, fmt.Sprintf("skipped package %s because it is too large", res.Package)) - continue - } - - if !res.Initial { - continue - } - - allowedAnalyzers := filterAnalyzerNames(analyzerNames, res.Config.Checks) - resd, err := res.Load() - if err != nil { - return nil, nil, err - } - ps := success(allowedAnalyzers, resd) - filtered, err := filterIgnored(ps, resd, allowedAnalyzers) - if err != nil { - return nil, nil, err - } - problems = append(problems, filtered...) - - for _, obj := range resd.Unused.Used { - // FIXME(dh): pick the object whose filename does not include $GOROOT - key := unusedKey{ - pkgPath: res.Package.PkgPath, - base: filepath.Base(obj.Position.Filename), - line: obj.Position.Line, - name: obj.Name, - } - used[key] = true - } - - if allowedAnalyzers["U1000"] { - for _, obj := range resd.Unused.Unused { - key := unusedKey{ - pkgPath: res.Package.PkgPath, - base: filepath.Base(obj.Position.Filename), - line: obj.Position.Line, - name: obj.Name, - } - unuseds = append(unuseds, unusedPair{key, obj}) - if _, ok := used[key]; !ok { - used[key] = false - } - } - } - } - } - - for _, uo := range unuseds { - if used[uo.key] { - continue - } - if uo.obj.InGenerated { - continue - } - problems = append(problems, problem{ - Diagnostic: runner.Diagnostic{ - Position: uo.obj.DisplayPosition, - Message: fmt.Sprintf("%s %s is unused", uo.obj.Kind, uo.obj.Name), - Category: "U1000", - }, - }) - } - - if len(problems) == 0 { - return nil, warnings, nil - } - - sort.Slice(problems, func(i, j int) bool { - pi := problems[i].Position - pj := problems[j].Position - - if pi.Filename != pj.Filename { - return pi.Filename < pj.Filename - } - if pi.Line != pj.Line { - return pi.Line < pj.Line - } - if pi.Column != pj.Column { - return pi.Column < pj.Column - } - - return problems[i].Message < problems[j].Message - }) - - var out []problem - out = append(out, problems[0]) - for i, p := range problems[1:] { - // We may encounter duplicate problems because one file - // can be part of many packages. - if !problems[i].equal(p) { - out = append(out, p) - } - } - return out, warnings, nil -} - -func filterAnalyzerNames(analyzers []string, checks []string) map[string]bool { - allowedChecks := map[string]bool{} - - for _, check := range checks { - b := true - if len(check) > 1 && check[0] == '-' { - b = false - check = check[1:] - } - if check == "*" || check == "all" { - // Match all - for _, c := range analyzers { - allowedChecks[c] = b - } - } else if strings.HasSuffix(check, "*") { - // Glob - prefix := check[:len(check)-1] - isCat := strings.IndexFunc(prefix, func(r rune) bool { return unicode.IsNumber(r) }) == -1 - - for _, a := range analyzers { - idx := strings.IndexFunc(a, func(r rune) bool { return unicode.IsNumber(r) }) - if isCat { - // Glob is S*, which should match S1000 but not SA1000 - cat := a[:idx] - if prefix == cat { - allowedChecks[a] = b - } - } else { - // Glob is S1* - if strings.HasPrefix(a, prefix) { - allowedChecks[a] = b - } - } - } - } else { - // Literal check name - allowedChecks[check] = b - } - } - return allowedChecks -} - -var posRe = regexp.MustCompile(`^(.+?):(\d+)(?::(\d+)?)?`) - -func parsePos(pos string) (token.Position, int, error) { - if pos == "-" || pos == "" { - return token.Position{}, 0, nil - } - parts := posRe.FindStringSubmatch(pos) - if parts == nil { - return token.Position{}, 0, fmt.Errorf("internal error: malformed position %q", pos) - } - file := parts[1] - line, _ := strconv.Atoi(parts[2]) - col, _ := strconv.Atoi(parts[3]) - return token.Position{ - Filename: file, - Line: line, - Column: col, - }, len(parts[0]), nil -} - -func usage(name string, flags *flag.FlagSet) func() { - return func() { - fmt.Fprintf(os.Stderr, "Usage of %s:\n", name) - fmt.Fprintf(os.Stderr, "\t%s [flags] # runs on package in current directory\n", name) - fmt.Fprintf(os.Stderr, "\t%s [flags] packages\n", name) - fmt.Fprintf(os.Stderr, "\t%s [flags] directory\n", name) - fmt.Fprintf(os.Stderr, "\t%s [flags] files... # must be a single package\n", name) - fmt.Fprintf(os.Stderr, "Flags:\n") - flags.PrintDefaults() - } -} - -type list []string - -func (list *list) String() string { - return `"` + strings.Join(*list, ",") + `"` -} - -func (list *list) Set(s string) error { - if s == "" { - *list = nil - return nil - } - - *list = strings.Split(s, ",") - return nil -} - -func FlagSet(name string) *flag.FlagSet { - flags := flag.NewFlagSet("", flag.ExitOnError) - flags.Usage = usage(name, flags) - flags.String("tags", "", "List of `build tags`") - flags.Bool("tests", true, "Include tests") - flags.Bool("version", false, "Print version and exit") - flags.Bool("show-ignored", false, "Don't filter ignored problems") - flags.String("f", "text", "Output `format` (valid choices are 'stylish', 'text' and 'json')") - flags.String("explain", "", "Print description of `check`") - - flags.String("debug.cpuprofile", "", "Write CPU profile to `file`") - flags.String("debug.memprofile", "", "Write memory profile to `file`") - flags.Bool("debug.version", false, "Print detailed version information about this program") - flags.Bool("debug.no-compile-errors", false, "Don't print compile errors") - flags.String("debug.measure-analyzers", "", "Write analysis measurements to `file`. `file` will be opened for appending if it already exists.") - flags.String("debug.trace", "", "Write trace to `file`") - - checks := list{"inherit"} - fail := list{"all"} - flags.Var(&checks, "checks", "Comma-separated list of `checks` to enable.") - flags.Var(&fail, "fail", "Comma-separated list of `checks` that can cause a non-zero exit status.") - - tags := build.Default.ReleaseTags - v := tags[len(tags)-1][2:] - version := new(lint.VersionFlag) - if err := version.Set(v); err != nil { - panic(fmt.Sprintf("internal error: %s", err)) - } - - flags.Var(version, "go", "Target Go `version` in the format '1.x'") - return flags -} - -func findCheck(cs []*analysis.Analyzer, check string) (*analysis.Analyzer, bool) { - for _, c := range cs { - if c.Name == check { - return c, true - } - } - return nil, false -} - -func ProcessFlagSet(cs []*analysis.Analyzer, fs *flag.FlagSet) { - tags := fs.Lookup("tags").Value.(flag.Getter).Get().(string) - tests := fs.Lookup("tests").Value.(flag.Getter).Get().(bool) - goVersion := fs.Lookup("go").Value.(flag.Getter).Get().(int) - theFormatter := fs.Lookup("f").Value.(flag.Getter).Get().(string) - printVersion := fs.Lookup("version").Value.(flag.Getter).Get().(bool) - showIgnored := fs.Lookup("show-ignored").Value.(flag.Getter).Get().(bool) - explain := fs.Lookup("explain").Value.(flag.Getter).Get().(string) - - cpuProfile := fs.Lookup("debug.cpuprofile").Value.(flag.Getter).Get().(string) - memProfile := fs.Lookup("debug.memprofile").Value.(flag.Getter).Get().(string) - debugVersion := fs.Lookup("debug.version").Value.(flag.Getter).Get().(bool) - debugNoCompile := fs.Lookup("debug.no-compile-errors").Value.(flag.Getter).Get().(bool) - traceOut := fs.Lookup("debug.trace").Value.(flag.Getter).Get().(string) - - var measureAnalyzers func(analysis *analysis.Analyzer, pkg *loader.PackageSpec, d time.Duration) - if path := fs.Lookup("debug.measure-analyzers").Value.(flag.Getter).Get().(string); path != "" { - f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) - if err != nil { - log.Fatal(err) - } - - mu := &sync.Mutex{} - measureAnalyzers = func(analysis *analysis.Analyzer, pkg *loader.PackageSpec, d time.Duration) { - mu.Lock() - defer mu.Unlock() - // FIXME(dh): print pkg.ID - if _, err := fmt.Fprintf(f, "%s\t%s\t%d\n", analysis.Name, pkg, d.Nanoseconds()); err != nil { - log.Println("error writing analysis measurements:", err) - } - } - } - - cfg := config.Config{} - cfg.Checks = *fs.Lookup("checks").Value.(*list) - - exit := func(code int) { - if cpuProfile != "" { - pprof.StopCPUProfile() - } - if memProfile != "" { - f, err := os.Create(memProfile) - if err != nil { - panic(err) - } - runtime.GC() - pprof.WriteHeapProfile(f) - } - if traceOut != "" { - trace.Stop() - } - os.Exit(code) - } - if cpuProfile != "" { - f, err := os.Create(cpuProfile) - if err != nil { - log.Fatal(err) - } - pprof.StartCPUProfile(f) - } - if traceOut != "" { - f, err := os.Create(traceOut) - if err != nil { - log.Fatal(err) - } - trace.Start(f) - } - - if debugVersion { - version.Verbose() - exit(0) - } - - if printVersion { - version.Print() - exit(0) - } - - // Validate that the tags argument is well-formed. go/packages - // doesn't detect malformed build flags and returns unhelpful - // errors. - tf := buildutil.TagsFlag{} - if err := tf.Set(tags); err != nil { - fmt.Fprintln(os.Stderr, fmt.Errorf("invalid value %q for flag -tags: %s", tags, err)) - exit(1) - } - - if explain != "" { - var haystack []*analysis.Analyzer - haystack = append(haystack, cs...) - check, ok := findCheck(haystack, explain) - if !ok { - fmt.Fprintln(os.Stderr, "Couldn't find check", explain) - exit(1) - } - if check.Doc == "" { - fmt.Fprintln(os.Stderr, explain, "has no documentation") - exit(1) - } - fmt.Println(check.Doc) - exit(0) - } - - var f formatter - switch theFormatter { - case "text": - f = textFormatter{Diagnostics: os.Stdout, UI: os.Stderr} - case "stylish": - f = &stylishFormatter{Diagnostics: os.Stdout, UI: os.Stderr} - case "json": - f = jsonFormatter{W: os.Stdout} - case "null": - f = nullFormatter{} - default: - fmt.Fprintf(os.Stderr, "unsupported output format %q\n", theFormatter) - exit(2) - } - - ps, warnings, err := doLint(cs, fs.Args(), &options{ - Tags: tags, - LintTests: tests, - GoVersion: goVersion, - Config: cfg, - PrintAnalyzerMeasurement: measureAnalyzers, - }) - if err != nil { - fmt.Fprintln(os.Stderr, err) - exit(1) - } - - for _, w := range warnings { - fmt.Fprintln(os.Stderr, "warning:", w) - } - - var ( - numCompiles int - numErrors int - numWarnings int - numIgnored int - ) - - fail := *fs.Lookup("fail").Value.(*list) - analyzerNames := make([]string, len(cs)) - for i, a := range cs { - analyzerNames[i] = a.Name - } - shouldExit := filterAnalyzerNames(analyzerNames, fail) - shouldExit["staticcheck"] = true - - for _, p := range ps { - if p.Category == "compile" && debugNoCompile { - continue - } - if p.Severity == severityIgnored && !showIgnored { - numIgnored++ - continue - } - if p.Category == "compile" { - numCompiles++ - } else if shouldExit[p.Category] { - numErrors++ - } else { - p.Severity = severityWarning - numWarnings++ - } - f.Format(p) - } - if f, ok := f.(statter); ok { - f.Stats(len(ps), numErrors+numCompiles, numWarnings, numIgnored) - } - - if f, ok := f.(documentationMentioner); ok && (numErrors > 0 || numWarnings > 0) && len(os.Args) > 0 { - f.MentionCheckDocumentation(os.Args[0]) - } - - if numErrors > 0 || numCompiles > 0 { - exit(1) - } - exit(0) -} - -type options struct { - Config config.Config - - Tags string - LintTests bool - GoVersion int - PrintAnalyzerMeasurement func(analysis *analysis.Analyzer, pkg *loader.PackageSpec, d time.Duration) -} - -func computeSalt() ([]byte, error) { - if version.Version != "devel" { - return []byte(version.Version), nil - } - p, err := os.Executable() - if err != nil { - return nil, err - } - f, err := os.Open(p) - if err != nil { - return nil, err - } - defer f.Close() - h := sha256.New() - if _, err := io.Copy(h, f); err != nil { - return nil, err - } - return h.Sum(nil), nil -} - -func doLint(cs []*analysis.Analyzer, paths []string, opt *options) ([]problem, []string, error) { - salt, err := computeSalt() - if err != nil { - return nil, nil, fmt.Errorf("could not compute salt for cache: %s", err) - } - cache.SetSalt(salt) - - if opt == nil { - opt = &options{} - } - - l, err := newLinter(opt.Config) - if err != nil { - return nil, nil, err - } - l.Checkers = cs - l.SetGoVersion(opt.GoVersion) - l.Runner.Stats.PrintAnalyzerMeasurement = opt.PrintAnalyzerMeasurement - - cfg := &packages.Config{} - if opt.LintTests { - cfg.Tests = true - } - if opt.Tags != "" { - cfg.BuildFlags = append(cfg.BuildFlags, "-tags", opt.Tags) - } - - printStats := func() { - // Individual stats are read atomically, but overall there - // is no synchronisation. For printing rough progress - // information, this doesn't matter. - switch l.Runner.Stats.State() { - case runner.StateInitializing: - fmt.Fprintln(os.Stderr, "Status: initializing") - case runner.StateLoadPackageGraph: - fmt.Fprintln(os.Stderr, "Status: loading package graph") - case runner.StateBuildActionGraph: - fmt.Fprintln(os.Stderr, "Status: building action graph") - case runner.StateProcessing: - fmt.Fprintf(os.Stderr, "Packages: %d/%d initial, %d/%d total; Workers: %d/%d\n", - l.Runner.Stats.ProcessedInitialPackages(), - l.Runner.Stats.InitialPackages(), - l.Runner.Stats.ProcessedPackages(), - l.Runner.Stats.TotalPackages(), - l.Runner.ActiveWorkers(), - l.Runner.TotalWorkers(), - ) - case runner.StateFinalizing: - fmt.Fprintln(os.Stderr, "Status: finalizing") - } - } - if len(infoSignals) > 0 { - ch := make(chan os.Signal, 1) - signal.Notify(ch, infoSignals...) - defer signal.Stop(ch) - go func() { - for range ch { - printStats() - } - }() - } - return l.Lint(cfg, paths) -} diff --git a/vendor/honnef.co/go/tools/lintcmd/directives.go b/vendor/honnef.co/go/tools/lintcmd/directives.go deleted file mode 100644 index e35b9c7ae0..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/directives.go +++ /dev/null @@ -1,55 +0,0 @@ -package lintcmd - -import ( - "strings" - - "honnef.co/go/tools/lintcmd/runner" -) - -func parseDirectives(dirs []runner.SerializedDirective) ([]ignore, []problem) { - var ignores []ignore - var problems []problem - - for _, dir := range dirs { - cmd := dir.Command - args := dir.Arguments - switch cmd { - case "ignore", "file-ignore": - if len(args) < 2 { - p := problem{ - Diagnostic: runner.Diagnostic{ - Position: dir.NodePosition, - Message: "malformed linter directive; missing the required reason field?", - Category: "compile", - }, - Severity: severityError, - } - problems = append(problems, p) - continue - } - default: - // unknown directive, ignore - continue - } - checks := strings.Split(args[0], ",") - pos := dir.NodePosition - var ig ignore - switch cmd { - case "ignore": - ig = &lineIgnore{ - File: pos.Filename, - Line: pos.Line, - Checks: checks, - Pos: dir.DirectivePosition, - } - case "file-ignore": - ig = &fileIgnore{ - File: pos.Filename, - Checks: checks, - } - } - ignores = append(ignores, ig) - } - - return ignores, problems -} diff --git a/vendor/honnef.co/go/tools/lintcmd/format.go b/vendor/honnef.co/go/tools/lintcmd/format.go deleted file mode 100644 index 2d6afded02..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/format.go +++ /dev/null @@ -1,165 +0,0 @@ -package lintcmd - -import ( - "encoding/json" - "fmt" - "go/token" - "io" - "os" - "path/filepath" - "text/tabwriter" -) - -func shortPath(path string) string { - cwd, err := os.Getwd() - if err != nil { - return path - } - if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) { - return rel - } - return path -} - -func relativePositionString(pos token.Position) string { - s := shortPath(pos.Filename) - if pos.IsValid() { - if s != "" { - s += ":" - } - s += fmt.Sprintf("%d:%d", pos.Line, pos.Column) - } - if s == "" { - s = "-" - } - return s -} - -type statter interface { - Stats(total, errors, warnings, ignored int) -} - -type formatter interface { - Format(p problem) -} - -type documentationMentioner interface { - MentionCheckDocumentation(cmd string) -} - -type textFormatter struct { - Diagnostics io.Writer - UI io.Writer -} - -func (o textFormatter) Format(p problem) { - fmt.Fprintf(o.Diagnostics, "%s: %s\n", relativePositionString(p.Position), p.String()) - for _, r := range p.Related { - fmt.Fprintf(o.Diagnostics, "\t%s: %s\n", relativePositionString(r.Position), r.Message) - } -} - -func (o textFormatter) MentionCheckDocumentation(cmd string) { - fmt.Fprintf(o.UI, "\nRun '%s -explain ' or visit https://staticcheck.io/docs/checks for documentation on checks.\n", cmd) -} - -type nullFormatter struct{} - -func (nullFormatter) Format(problem) {} - -type jsonFormatter struct { - W io.Writer -} - -func (o jsonFormatter) Format(p problem) { - type location struct { - File string `json:"file"` - Line int `json:"line"` - Column int `json:"column"` - } - type related struct { - Location location `json:"location"` - End location `json:"end"` - Message string `json:"message"` - } - jp := struct { - Code string `json:"code"` - Severity string `json:"severity,omitempty"` - Location location `json:"location"` - End location `json:"end"` - Message string `json:"message"` - Related []related `json:"related,omitempty"` - }{ - Code: p.Category, - Severity: p.Severity.String(), - Location: location{ - File: p.Position.Filename, - Line: p.Position.Line, - Column: p.Position.Column, - }, - End: location{ - File: p.End.Filename, - Line: p.End.Line, - Column: p.End.Column, - }, - Message: p.Message, - } - for _, r := range p.Related { - jp.Related = append(jp.Related, related{ - Location: location{ - File: r.Position.Filename, - Line: r.Position.Line, - Column: r.Position.Column, - }, - End: location{ - File: r.End.Filename, - Line: r.End.Line, - Column: r.End.Column, - }, - Message: r.Message, - }) - } - _ = json.NewEncoder(o.W).Encode(jp) -} - -type stylishFormatter struct { - Diagnostics io.Writer - UI io.Writer - - prevFile string - tw *tabwriter.Writer -} - -func (o *stylishFormatter) Format(p problem) { - pos := p.Position - if pos.Filename == "" { - pos.Filename = "-" - } - - if pos.Filename != o.prevFile { - if o.prevFile != "" { - o.tw.Flush() - fmt.Fprintln(o.Diagnostics) - } - fmt.Fprintln(o.Diagnostics, pos.Filename) - o.prevFile = pos.Filename - o.tw = tabwriter.NewWriter(o.Diagnostics, 0, 4, 2, ' ', 0) - } - fmt.Fprintf(o.tw, " (%d, %d)\t%s\t%s\n", pos.Line, pos.Column, p.Category, p.Message) - for _, r := range p.Related { - fmt.Fprintf(o.tw, " (%d, %d)\t\t %s\n", r.Position.Line, r.Position.Column, r.Message) - } -} - -func (o *stylishFormatter) MentionCheckDocumentation(cmd string) { - textFormatter{UI: o.UI}.MentionCheckDocumentation(cmd) -} - -func (o *stylishFormatter) Stats(total, errors, warnings, ignored int) { - if o.tw != nil { - o.tw.Flush() - fmt.Fprintln(o.Diagnostics) - } - fmt.Fprintf(o.Diagnostics, " ✖ %d problems (%d errors, %d warnings, %d ignored)\n", - total, errors, warnings, ignored) -} diff --git a/vendor/honnef.co/go/tools/lintcmd/runner/runner.go b/vendor/honnef.co/go/tools/lintcmd/runner/runner.go deleted file mode 100644 index 867d192f0d..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/runner/runner.go +++ /dev/null @@ -1,1155 +0,0 @@ -// Package runner implements a go/analysis runner. It makes heavy use -// of on-disk caching to reduce overall memory usage and to speed up -// repeat runs. -// -// Public API -// -// A Runner maps a list of analyzers and package patterns to a list of -// results. Results provide access to diagnostics, directives, errors -// encountered, and information about packages. Results explicitly do -// not contain ASTs or type information. All position information is -// returned in the form of token.Position, not token.Pos. All work -// that requires access to the loaded representation of a package has -// to occur inside analyzers. -// -// Planning and execution -// -// Analyzing packages is split into two phases: planning and -// execution. -// -// During planning, a directed acyclic graph of package dependencies -// is computed. We materialize the full graph so that we can execute -// the graph from the bottom up, without keeping unnecessary data in -// memory during a DFS and with simplified parallel execution. -// -// During execution, leaf nodes (nodes with no outstanding -// dependencies) get executed in parallel, bounded by a semaphore -// sized according to the number of CPUs. Conceptually, this happens -// in a loop, processing new leaf nodes as they appear, until no more -// nodes are left. In the actual implementation, nodes know their -// dependents, and the last dependency of a node to be processed is -// responsible for scheduling its dependent. -// -// The graph is rooted at a synthetic root node. Upon execution of the -// root node, the algorithm terminates. -// -// Analyzing a package repeats the same planning + execution steps, -// but this time on a graph of analyzers for the package. Parallel -// execution of individual analyzers is bounded by the same semaphore -// as executing packages. -// -// Parallelism -// -// Actions are executed in parallel where the dependency graph allows. -// Overall parallelism is bounded by a semaphore, sized according to -// GOMAXPROCS. Each concurrently processed package takes up a -// token, as does each analyzer – but a package can always execute at -// least one analyzer, using the package's token. -// -// Depending on the overall shape of the graph, there may be GOMAXPROCS -// packages running a single analyzer each, a single package running -// GOMAXPROCS analyzers, or anything in between. -// -// Total memory consumption grows roughly linearly with the number of -// CPUs, while total execution time is inversely proportional to the -// number of CPUs. Overall, parallelism is affected by the shape of -// the dependency graph. A lot of inter-connected packages will see -// less parallelism than a lot of independent packages. -// -// Caching -// -// The runner caches facts, directives and diagnostics in a -// content-addressable cache that is designed after Go's own cache. -// Additionally, it makes use of Go's export data. -// -// This cache not only speeds up repeat runs, it also reduces peak -// memory usage. When we've analyzed a package, we cache the results -// and drop them from memory. When a dependent needs any of this -// information, or when analysis is complete and we wish to render the -// results, the data gets loaded from disk again. -// -// Data only exists in memory when it is immediately needed, not -// retained for possible future uses. This trades increased CPU usage -// for reduced memory usage. A single dependency may be loaded many -// times over, but it greatly reduces peak memory usage, as an -// arbitrary amount of time may pass between analyzing a dependency -// and its dependent, during which other packages will be processed. -package runner - -// OPT(dh): we could reduce disk storage usage of cached data by -// compressing it, either directly at the cache layer, or by feeding -// compressed data to the cache. Of course doing so may negatively -// affect CPU usage, and there are lower hanging fruit, such as -// needing to cache less data in the first place. - -// OPT(dh): right now, each package is analyzed completely -// independently. Each package loads all of its dependencies from -// export data and cached facts. If we have two packages A and B, -// which both depend on C, and which both get analyzed in parallel, -// then C will be loaded twice. This wastes CPU time and memory. It -// would be nice if we could reuse a single C for the analysis of both -// A and B. -// -// We can't reuse the actual types.Package or facts, because each -// package gets its own token.FileSet. Sharing a global FileSet has -// several drawbacks, including increased memory usage and running the -// risk of running out of FileSet address space. -// -// We could however avoid loading the same raw export data from disk -// twice, as well as deserializing gob data twice. One possible -// solution would be a duplicate-suppressing in-memory cache that -// caches data for a limited amount of time. When the same package -// needs to be loaded twice in close succession, we can reuse work, -// without holding unnecessary data in memory for an extended period -// of time. -// -// We would likely need to do extensive benchmarking to figure out how -// long to keep data around to find a sweetspot where we reduce CPU -// load without increasing memory usage. -// -// We can probably populate the cache after we've analyzed a package, -// on the assumption that it will have to be loaded again in the near -// future. - -import ( - "encoding/gob" - "fmt" - "go/token" - "go/types" - "io" - "io/ioutil" - "os" - "reflect" - "runtime" - "sort" - "strings" - "sync/atomic" - "time" - - "honnef.co/go/tools/analysis/lint" - "honnef.co/go/tools/analysis/report" - "honnef.co/go/tools/config" - "honnef.co/go/tools/go/loader" - "honnef.co/go/tools/internal/cache" - tsync "honnef.co/go/tools/internal/sync" - "honnef.co/go/tools/unused" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - "golang.org/x/tools/go/types/objectpath" -) - -type Diagnostic struct { - Position token.Position - End token.Position - Category string - Message string - - SuggestedFixed []SuggestedFix - Related []RelatedInformation -} - -// RelatedInformation provides additional context for a diagnostic. -type RelatedInformation struct { - Position token.Position - End token.Position - Message string -} - -type SuggestedFix struct { - Message string - TextEdits []TextEdit -} - -type TextEdit struct { - Position token.Position - End token.Position - NewText []byte -} - -// A Result describes the result of analyzing a single package. -// -// It holds references to cached diagnostics and directives. They can -// be loaded on demand with Diagnostics and Directives respectively. -type Result struct { - Package *loader.PackageSpec - Config config.Config - Initial bool - Skipped bool - - Failed bool - Errors []error - // Action results, paths to files - results string -} - -type SerializedDirective struct { - Command string - Arguments []string - // The position of the comment - DirectivePosition token.Position - // The position of the node that the comment is attached to - NodePosition token.Position -} - -func serializeDirective(dir lint.Directive, fset *token.FileSet) SerializedDirective { - return SerializedDirective{ - Command: dir.Command, - Arguments: dir.Arguments, - DirectivePosition: report.DisplayPosition(fset, dir.Directive.Pos()), - NodePosition: report.DisplayPosition(fset, dir.Node.Pos()), - } -} - -type ResultData struct { - Directives []SerializedDirective - Diagnostics []Diagnostic - Unused unused.SerializedResult -} - -func (r Result) Load() (ResultData, error) { - if r.Failed { - panic("Load called on failed Result") - } - if r.results == "" { - // this package was only a dependency - return ResultData{}, nil - } - f, err := os.Open(r.results) - if err != nil { - return ResultData{}, fmt.Errorf("failed loading result: %w", err) - } - defer f.Close() - var out ResultData - err = gob.NewDecoder(f).Decode(&out) - return out, err -} - -type action interface { - Deps() []action - Triggers() []action - DecrementPending() bool - MarkFailed() - IsFailed() bool - AddError(error) -} - -type baseAction struct { - // Action description - - deps []action - triggers []action - pending uint32 - - // Action results - - // failed is set to true if the action couldn't be processed. This - // may either be due to an error specific to this action, in - // which case the errors field will be populated, or due to a - // dependency being marked as failed, in which case errors will be - // empty. - failed bool - errors []error -} - -func (act *baseAction) Deps() []action { return act.deps } -func (act *baseAction) Triggers() []action { return act.triggers } -func (act *baseAction) DecrementPending() bool { - return atomic.AddUint32(&act.pending, ^uint32(0)) == 0 -} -func (act *baseAction) MarkFailed() { act.failed = true } -func (act *baseAction) IsFailed() bool { return act.failed } -func (act *baseAction) AddError(err error) { act.errors = append(act.errors, err) } - -// packageAction describes the act of loading a package, fully -// analyzing it, and storing the results. -type packageAction struct { - baseAction - - // Action description - - Package *loader.PackageSpec - factsOnly bool - hash cache.ActionID - - // Action results - - cfg config.Config - vetx string - results string - skipped bool -} - -func (act *packageAction) String() string { - return fmt.Sprintf("packageAction(%s)", act.Package) -} - -type objectFactKey struct { - Obj types.Object - Type reflect.Type -} - -type packageFactKey struct { - Pkg *types.Package - Type reflect.Type -} - -type gobFact struct { - PkgPath string - ObjPath string - Fact analysis.Fact -} - -// analyzerAction describes the act of analyzing a package with a -// single analyzer. -type analyzerAction struct { - baseAction - - // Action description - - Analyzer *analysis.Analyzer - - // Action results - - // We can store actual results here without worrying about memory - // consumption because analyzer actions get garbage collected once - // a package has been fully analyzed. - Result interface{} - Diagnostics []Diagnostic - ObjectFacts map[objectFactKey]analysis.Fact - PackageFacts map[packageFactKey]analysis.Fact - Pass *analysis.Pass -} - -func (act *analyzerAction) String() string { - return fmt.Sprintf("analyzerAction(%s)", act.Analyzer) -} - -// A Runner executes analyzers on packages. -type Runner struct { - Stats Stats - GoVersion int - - // Config that gets merged with per-package configs - cfg config.Config - cache *cache.Cache - semaphore tsync.Semaphore -} - -type subrunner struct { - *Runner - analyzers []*analysis.Analyzer - factAnalyzers []*analysis.Analyzer - analyzerNames string -} - -// New returns a new Runner. -func New(cfg config.Config) (*Runner, error) { - cache, err := cache.Default() - if err != nil { - return nil, err - } - - return &Runner{ - cfg: cfg, - cache: cache, - semaphore: tsync.NewSemaphore(runtime.GOMAXPROCS(0)), - }, nil -} - -func newSubrunner(r *Runner, analyzers []*analysis.Analyzer) *subrunner { - analyzerNames := make([]string, len(analyzers)) - for i, a := range analyzers { - analyzerNames[i] = a.Name - } - sort.Strings(analyzerNames) - - var factAnalyzers []*analysis.Analyzer - for _, a := range analyzers { - if len(a.FactTypes) > 0 { - factAnalyzers = append(factAnalyzers, a) - } - } - return &subrunner{ - Runner: r, - analyzers: analyzers, - factAnalyzers: factAnalyzers, - analyzerNames: strings.Join(analyzerNames, ","), - } -} - -func newPackageActionRoot(pkg *loader.PackageSpec, cache map[*loader.PackageSpec]*packageAction) *packageAction { - a := newPackageAction(pkg, cache) - a.factsOnly = false - return a -} - -func newPackageAction(pkg *loader.PackageSpec, cache map[*loader.PackageSpec]*packageAction) *packageAction { - if a, ok := cache[pkg]; ok { - return a - } - - a := &packageAction{ - Package: pkg, - factsOnly: true, // will be overwritten by any call to Action - } - cache[pkg] = a - - if len(pkg.Errors) > 0 { - a.errors = make([]error, len(pkg.Errors)) - for i, err := range pkg.Errors { - a.errors[i] = err - } - a.failed = true - - // We don't need to process our imports if this package is - // already broken. - return a - } - - a.deps = make([]action, 0, len(pkg.Imports)) - for _, dep := range pkg.Imports { - depa := newPackageAction(dep, cache) - depa.triggers = append(depa.triggers, a) - a.deps = append(a.deps, depa) - - if depa.failed { - a.failed = true - } - } - // sort dependencies because the list of dependencies is part of - // the cache key - sort.Slice(a.deps, func(i, j int) bool { - return a.deps[i].(*packageAction).Package.ID < a.deps[j].(*packageAction).Package.ID - }) - - a.pending = uint32(len(a.deps)) - - return a -} - -func newAnalyzerAction(an *analysis.Analyzer, cache map[*analysis.Analyzer]*analyzerAction) *analyzerAction { - if a, ok := cache[an]; ok { - return a - } - - a := &analyzerAction{ - Analyzer: an, - ObjectFacts: map[objectFactKey]analysis.Fact{}, - PackageFacts: map[packageFactKey]analysis.Fact{}, - } - cache[an] = a - for _, dep := range an.Requires { - depa := newAnalyzerAction(dep, cache) - depa.triggers = append(depa.triggers, a) - a.deps = append(a.deps, depa) - } - a.pending = uint32(len(a.deps)) - return a -} - -func getCachedFiles(cache *cache.Cache, ids []cache.ActionID, out []*string) error { - for i, id := range ids { - var err error - *out[i], _, err = cache.GetFile(id) - if err != nil { - return err - } - } - return nil -} - -func (r *subrunner) do(act action) error { - a := act.(*packageAction) - defer func() { - r.Stats.finishPackage() - if !a.factsOnly { - r.Stats.finishInitialPackage() - } - }() - - // compute hash of action - a.cfg = a.Package.Config.Merge(r.cfg) - h := cache.NewHash("staticcheck " + a.Package.PkgPath) - - // Note that we do not filter the list of analyzers by the - // package's configuration. We don't allow configuration to - // accidentally break dependencies between analyzers, and it's - // easier to always run all checks and filter the output. This - // also makes cached data more reusable. - - // OPT(dh): not all changes in configuration invalidate cached - // data. specifically, when a.factsOnly == true, we only care - // about checks that produce facts, and settings that affect those - // checks. - - // Config used for constructing the hash; this config doesn't have - // Checks populated, because we always run all checks. - hashCfg := a.cfg - hashCfg.Checks = nil - // note that we don't hash staticcheck's version; it is set as the - // salt by a package main. - fmt.Fprintf(h, "cfg %#v\n", hashCfg) - fmt.Fprintf(h, "pkg %x\n", a.Package.Hash) - fmt.Fprintf(h, "analyzers %s\n", r.analyzerNames) - fmt.Fprintf(h, "go 1.%d\n", r.GoVersion) - - // OPT(dh): do we actually need to hash vetx? can we not assume - // that for identical inputs, staticcheck will produce identical - // vetx? - for _, dep := range a.deps { - dep := dep.(*packageAction) - vetxHash, err := cache.FileHash(dep.vetx) - if err != nil { - return fmt.Errorf("failed computing hash: %w", err) - } - fmt.Fprintf(h, "vetout %q %x\n", dep.Package.PkgPath, vetxHash) - } - a.hash = cache.ActionID(h.Sum()) - - // try to fetch hashed data - ids := make([]cache.ActionID, 0, 2) - ids = append(ids, cache.Subkey(a.hash, "vetx")) - if !a.factsOnly { - ids = append(ids, cache.Subkey(a.hash, "results")) - } - if err := getCachedFiles(r.cache, ids, []*string{&a.vetx, &a.results}); err != nil { - result, err := r.doUncached(a) - if err != nil { - return err - } - if a.failed { - return nil - } - - a.skipped = result.skipped - - // OPT(dh) instead of collecting all object facts and encoding - // them after analysis finishes, we could encode them as we - // go. however, that would require some locking. - // - // OPT(dh): We could sort gobFacts for more consistent output, - // but it doesn't matter. The hash of a package includes all - // of its files, so whether the vetx hash changes or not, a - // change to a package requires re-analyzing all dependents, - // even if the vetx data stayed the same. See also the note at - // the top of loader/hash.go. - tf, err := ioutil.TempFile("", "staticcheck") - if err != nil { - return err - } - defer tf.Close() - os.Remove(tf.Name()) - - enc := gob.NewEncoder(tf) - for _, gf := range result.facts { - if err := enc.Encode(gf); err != nil { - return fmt.Errorf("failed gob encoding data: %w", err) - } - } - - if _, err := tf.Seek(0, io.SeekStart); err != nil { - return err - } - a.vetx, err = r.writeCacheReader(a, "vetx", tf) - if err != nil { - return err - } - - if a.factsOnly { - return nil - } - - var out ResultData - out.Directives = make([]SerializedDirective, len(result.dirs)) - for i, dir := range result.dirs { - out.Directives[i] = serializeDirective(dir, result.lpkg.Fset) - } - - out.Diagnostics = result.diags - out.Unused = result.unused - a.results, err = r.writeCacheGob(a, "results", out) - if err != nil { - return err - } - } - return nil -} - -// ActiveWorkers returns the number of currently running workers. -func (r *Runner) ActiveWorkers() int { - return r.semaphore.Len() -} - -// TotalWorkers returns the maximum number of possible workers. -func (r *Runner) TotalWorkers() int { - return r.semaphore.Cap() -} - -func (r *Runner) writeCacheReader(a *packageAction, kind string, rs io.ReadSeeker) (string, error) { - h := cache.Subkey(a.hash, kind) - out, _, err := r.cache.Put(h, rs) - if err != nil { - return "", fmt.Errorf("failed caching data: %w", err) - } - return r.cache.OutputFile(out), nil -} - -func (r *Runner) writeCacheGob(a *packageAction, kind string, data interface{}) (string, error) { - f, err := ioutil.TempFile("", "staticcheck") - if err != nil { - return "", err - } - defer f.Close() - os.Remove(f.Name()) - if err := gob.NewEncoder(f).Encode(data); err != nil { - return "", fmt.Errorf("failed gob encoding data: %w", err) - } - if _, err := f.Seek(0, io.SeekStart); err != nil { - return "", err - } - return r.writeCacheReader(a, kind, f) -} - -type packageActionResult struct { - facts []gobFact - diags []Diagnostic - unused unused.SerializedResult - dirs []lint.Directive - lpkg *loader.Package - skipped bool -} - -func (r *subrunner) doUncached(a *packageAction) (packageActionResult, error) { - // OPT(dh): for a -> b; c -> b; if both a and b are being - // processed concurrently, we shouldn't load b's export data - // twice. - - pkg, _, err := loader.Load(a.Package) - if err != nil { - return packageActionResult{}, err - } - - if len(pkg.Errors) > 0 { - // this handles errors that occured during type-checking the - // package in loader.Load - for _, err := range pkg.Errors { - a.errors = append(a.errors, err) - } - a.failed = true - return packageActionResult{}, nil - } - - if len(pkg.Syntax) == 0 && pkg.PkgPath != "unsafe" { - return packageActionResult{lpkg: pkg, skipped: true}, nil - } - - // OPT(dh): instead of parsing directives twice (twice because - // U1000 depends on the facts.Directives analyzer), reuse the - // existing result - var dirs []lint.Directive - if !a.factsOnly { - dirs = lint.ParseDirectives(pkg.Syntax, pkg.Fset) - } - res, err := r.runAnalyzers(a, pkg) - - return packageActionResult{ - facts: res.facts, - diags: res.diagnostics, - unused: res.unused, - dirs: dirs, - lpkg: pkg, - }, err -} - -func pkgPaths(root *types.Package) map[string]*types.Package { - out := map[string]*types.Package{} - var dfs func(*types.Package) - dfs = func(pkg *types.Package) { - if _, ok := out[pkg.Path()]; ok { - return - } - out[pkg.Path()] = pkg - for _, imp := range pkg.Imports() { - dfs(imp) - } - } - dfs(root) - return out -} - -func (r *Runner) loadFacts(root *types.Package, dep *packageAction, objFacts map[objectFactKey]analysis.Fact, pkgFacts map[packageFactKey]analysis.Fact) error { - // Load facts of all imported packages - vetx, err := os.Open(dep.vetx) - if err != nil { - return fmt.Errorf("failed loading cached facts: %w", err) - } - defer vetx.Close() - - pathToPkg := pkgPaths(root) - dec := gob.NewDecoder(vetx) - for { - var gf gobFact - err := dec.Decode(&gf) - if err != nil { - if err == io.EOF { - break - } - return fmt.Errorf("failed loading cached facts: %w", err) - } - - pkg, ok := pathToPkg[gf.PkgPath] - if !ok { - continue - } - if gf.ObjPath == "" { - pkgFacts[packageFactKey{ - Pkg: pkg, - Type: reflect.TypeOf(gf.Fact), - }] = gf.Fact - } else { - obj, err := objectpath.Object(pkg, objectpath.Path(gf.ObjPath)) - if err != nil { - continue - } - objFacts[objectFactKey{ - Obj: obj, - Type: reflect.TypeOf(gf.Fact), - }] = gf.Fact - } - } - return nil -} - -func genericHandle(a action, root action, queue chan action, sem *tsync.Semaphore, exec func(a action) error) { - if a == root { - close(queue) - if sem != nil { - sem.Release() - } - return - } - if !a.IsFailed() { - // the action may have already been marked as failed during - // construction of the action graph, for example because of - // unresolved imports. - - for _, dep := range a.Deps() { - if dep.IsFailed() { - // One of our dependencies failed, so mark this package as - // failed and bail. We don't need to record an error for - // this package, the relevant error will have been - // reported by the first package in the chain that failed. - a.MarkFailed() - break - } - } - } - - if !a.IsFailed() { - if err := exec(a); err != nil { - a.MarkFailed() - a.AddError(err) - } - } - if sem != nil { - sem.Release() - } - - for _, t := range a.Triggers() { - if t.DecrementPending() { - queue <- t - } - } -} - -type analyzerRunner struct { - pkg *loader.Package - // object facts of our dependencies; may contain facts of - // analyzers other than the current one - depObjFacts map[objectFactKey]analysis.Fact - // package facts of our dependencies; may contain facts of - // analyzers other than the current one - depPkgFacts map[packageFactKey]analysis.Fact - factsOnly bool - - stats *Stats -} - -func (ar *analyzerRunner) do(act action) error { - a := act.(*analyzerAction) - results := map[*analysis.Analyzer]interface{}{} - // TODO(dh): does this have to be recursive? - for _, dep := range a.deps { - dep := dep.(*analyzerAction) - results[dep.Analyzer] = dep.Result - } - // OPT(dh): cache factTypes, it is the same for all packages for a given analyzer - // - // OPT(dh): do we need the factTypes map? most analyzers have 0-1 - // fact types. iterating over the slice is probably faster than - // indexing a map. - factTypes := map[reflect.Type]struct{}{} - for _, typ := range a.Analyzer.FactTypes { - factTypes[reflect.TypeOf(typ)] = struct{}{} - } - filterFactType := func(typ reflect.Type) bool { - _, ok := factTypes[typ] - return ok - } - a.Pass = &analysis.Pass{ - Analyzer: a.Analyzer, - Fset: ar.pkg.Fset, - Files: ar.pkg.Syntax, - OtherFiles: ar.pkg.OtherFiles, - Pkg: ar.pkg.Types, - TypesInfo: ar.pkg.TypesInfo, - TypesSizes: ar.pkg.TypesSizes, - Report: func(diag analysis.Diagnostic) { - if !ar.factsOnly { - if diag.Category == "" { - diag.Category = a.Analyzer.Name - } - d := Diagnostic{ - Position: report.DisplayPosition(ar.pkg.Fset, diag.Pos), - End: report.DisplayPosition(ar.pkg.Fset, diag.End), - Category: diag.Category, - Message: diag.Message, - } - for _, sugg := range diag.SuggestedFixes { - s := SuggestedFix{ - Message: sugg.Message, - } - for _, edit := range sugg.TextEdits { - s.TextEdits = append(s.TextEdits, TextEdit{ - Position: report.DisplayPosition(ar.pkg.Fset, edit.Pos), - End: report.DisplayPosition(ar.pkg.Fset, edit.End), - NewText: edit.NewText, - }) - } - d.SuggestedFixed = append(d.SuggestedFixed, s) - } - for _, rel := range diag.Related { - d.Related = append(d.Related, RelatedInformation{ - Position: report.DisplayPosition(ar.pkg.Fset, rel.Pos), - End: report.DisplayPosition(ar.pkg.Fset, rel.End), - Message: rel.Message, - }) - } - a.Diagnostics = append(a.Diagnostics, d) - } - }, - ResultOf: results, - ImportObjectFact: func(obj types.Object, fact analysis.Fact) bool { - key := objectFactKey{ - Obj: obj, - Type: reflect.TypeOf(fact), - } - if f, ok := ar.depObjFacts[key]; ok { - reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f).Elem()) - return true - } else if f, ok := a.ObjectFacts[key]; ok { - reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f).Elem()) - return true - } - return false - }, - ImportPackageFact: func(pkg *types.Package, fact analysis.Fact) bool { - key := packageFactKey{ - Pkg: pkg, - Type: reflect.TypeOf(fact), - } - if f, ok := ar.depPkgFacts[key]; ok { - reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f).Elem()) - return true - } else if f, ok := a.PackageFacts[key]; ok { - reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f).Elem()) - return true - } - return false - }, - ExportObjectFact: func(obj types.Object, fact analysis.Fact) { - key := objectFactKey{ - Obj: obj, - Type: reflect.TypeOf(fact), - } - a.ObjectFacts[key] = fact - }, - ExportPackageFact: func(fact analysis.Fact) { - key := packageFactKey{ - Pkg: ar.pkg.Types, - Type: reflect.TypeOf(fact), - } - a.PackageFacts[key] = fact - }, - AllPackageFacts: func() []analysis.PackageFact { - out := make([]analysis.PackageFact, 0, len(ar.depPkgFacts)+len(a.PackageFacts)) - for key, fact := range ar.depPkgFacts { - out = append(out, analysis.PackageFact{ - Package: key.Pkg, - Fact: fact, - }) - } - for key, fact := range a.PackageFacts { - out = append(out, analysis.PackageFact{ - Package: key.Pkg, - Fact: fact, - }) - } - return out - }, - AllObjectFacts: func() []analysis.ObjectFact { - out := make([]analysis.ObjectFact, 0, len(ar.depObjFacts)+len(a.ObjectFacts)) - for key, fact := range ar.depObjFacts { - if filterFactType(key.Type) { - out = append(out, analysis.ObjectFact{ - Object: key.Obj, - Fact: fact, - }) - } - } - for key, fact := range a.ObjectFacts { - if filterFactType(key.Type) { - out = append(out, analysis.ObjectFact{ - Object: key.Obj, - Fact: fact, - }) - } - } - return out - }, - } - - t := time.Now() - res, err := a.Analyzer.Run(a.Pass) - ar.stats.measureAnalyzer(a.Analyzer, ar.pkg.PackageSpec, time.Since(t)) - if err != nil { - return err - } - a.Result = res - return nil -} - -type analysisResult struct { - facts []gobFact - diagnostics []Diagnostic - unused unused.SerializedResult -} - -func (r *subrunner) runAnalyzers(pkgAct *packageAction, pkg *loader.Package) (analysisResult, error) { - depObjFacts := map[objectFactKey]analysis.Fact{} - depPkgFacts := map[packageFactKey]analysis.Fact{} - - for _, dep := range pkgAct.deps { - if err := r.loadFacts(pkg.Types, dep.(*packageAction), depObjFacts, depPkgFacts); err != nil { - return analysisResult{}, err - } - } - - root := &analyzerAction{} - var analyzers []*analysis.Analyzer - if pkgAct.factsOnly { - // When analyzing non-initial packages, we only care about - // analyzers that produce facts. - analyzers = r.factAnalyzers - } else { - analyzers = r.analyzers - } - - all := map[*analysis.Analyzer]*analyzerAction{} - for _, a := range analyzers { - a := newAnalyzerAction(a, all) - root.deps = append(root.deps, a) - a.triggers = append(a.triggers, root) - } - root.pending = uint32(len(root.deps)) - - ar := &analyzerRunner{ - pkg: pkg, - factsOnly: pkgAct.factsOnly, - depObjFacts: depObjFacts, - depPkgFacts: depPkgFacts, - stats: &r.Stats, - } - queue := make(chan action, len(all)) - for _, a := range all { - if len(a.Deps()) == 0 { - queue <- a - } - } - - for item := range queue { - b := r.semaphore.AcquireMaybe() - if b { - go genericHandle(item, root, queue, &r.semaphore, ar.do) - } else { - // the semaphore is exhausted; run the analysis under the - // token we've acquired for analyzing the package. - genericHandle(item, root, queue, nil, ar.do) - } - } - - var unusedResult unused.SerializedResult - for _, a := range all { - if a != root && a.Analyzer.Name == "U1000" { - // TODO(dh): figure out a clean abstraction, instead of - // special-casing U1000. - unusedResult = unused.Serialize(a.Pass, a.Result.(unused.Result), pkg.Fset) - } - - for key, fact := range a.ObjectFacts { - depObjFacts[key] = fact - } - for key, fact := range a.PackageFacts { - depPkgFacts[key] = fact - } - } - - // OPT(dh): cull objects not reachable via the exported closure - gobFacts := make([]gobFact, 0, len(depObjFacts)+len(depPkgFacts)) - for key, fact := range depObjFacts { - objPath, err := objectpath.For(key.Obj) - if err != nil { - continue - } - gf := gobFact{ - PkgPath: key.Obj.Pkg().Path(), - ObjPath: string(objPath), - Fact: fact, - } - gobFacts = append(gobFacts, gf) - } - for key, fact := range depPkgFacts { - gf := gobFact{ - PkgPath: key.Pkg.Path(), - Fact: fact, - } - gobFacts = append(gobFacts, gf) - } - - var diags []Diagnostic - for _, a := range root.deps { - a := a.(*analyzerAction) - diags = append(diags, a.Diagnostics...) - } - return analysisResult{ - facts: gobFacts, - diagnostics: diags, - unused: unusedResult, - }, nil -} - -func registerGobTypes(analyzers []*analysis.Analyzer) { - for _, a := range analyzers { - for _, typ := range a.FactTypes { - // FIXME(dh): use RegisterName so we can work around collisions - // in names. For pointer-types, gob incorrectly qualifies - // type names with the package name, not the import path. - gob.Register(typ) - } - } -} - -func allAnalyzers(analyzers []*analysis.Analyzer) []*analysis.Analyzer { - seen := map[*analysis.Analyzer]struct{}{} - out := make([]*analysis.Analyzer, 0, len(analyzers)) - var dfs func(*analysis.Analyzer) - dfs = func(a *analysis.Analyzer) { - if _, ok := seen[a]; ok { - return - } - seen[a] = struct{}{} - out = append(out, a) - for _, dep := range a.Requires { - dfs(dep) - } - } - for _, a := range analyzers { - dfs(a) - } - return out -} - -// Run loads the packages specified by patterns, runs analyzers on -// them and returns the results. Each result corresponds to a single -// package. Results will be returned for all packages, including -// dependencies. Errors specific to packages will be reported in the -// respective results. -// -// If cfg is nil, a default config will be used. Otherwise, cfg will -// be used, with the exception of the Mode field. -// -// Run can be called multiple times on the same Runner and it is safe -// for concurrent use. All runs will share the same semaphore. -func (r *Runner) Run(cfg *packages.Config, analyzers []*analysis.Analyzer, patterns []string) ([]Result, error) { - analyzers = allAnalyzers(analyzers) - registerGobTypes(analyzers) - - for _, a := range analyzers { - flag := a.Flags.Lookup("go") - if flag == nil { - continue - } - // OPT(dh): this is terrible - flag.Value.Set(fmt.Sprintf("1.%d", r.GoVersion)) - } - - r.Stats.setState(StateLoadPackageGraph) - lpkgs, err := loader.Graph(cfg, patterns...) - if err != nil { - return nil, err - } - r.Stats.setInitialPackages(len(lpkgs)) - - if len(lpkgs) == 0 { - return nil, nil - } - - r.Stats.setState(StateBuildActionGraph) - all := map[*loader.PackageSpec]*packageAction{} - root := &packageAction{} - for _, lpkg := range lpkgs { - a := newPackageActionRoot(lpkg, all) - root.deps = append(root.deps, a) - a.triggers = append(a.triggers, root) - } - root.pending = uint32(len(root.deps)) - - queue := make(chan action) - r.Stats.setTotalPackages(len(all) - 1) - - r.Stats.setState(StateProcessing) - go func() { - for _, a := range all { - if len(a.Deps()) == 0 { - queue <- a - } - } - }() - - sr := newSubrunner(r, analyzers) - for item := range queue { - r.semaphore.Acquire() - go genericHandle(item, root, queue, &r.semaphore, func(act action) error { - return sr.do(act) - }) - } - - r.Stats.setState(StateFinalizing) - out := make([]Result, 0, len(all)) - for _, item := range all { - if item.Package == nil { - continue - } - out = append(out, Result{ - Package: item.Package, - Config: item.cfg, - Initial: !item.factsOnly, - Skipped: item.skipped, - Failed: item.failed, - Errors: item.errors, - results: item.results, - }) - } - return out, nil -} diff --git a/vendor/honnef.co/go/tools/lintcmd/runner/stats.go b/vendor/honnef.co/go/tools/lintcmd/runner/stats.go deleted file mode 100644 index fd7da2fa4d..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/runner/stats.go +++ /dev/null @@ -1,49 +0,0 @@ -package runner - -import ( - "sync/atomic" - "time" - - "honnef.co/go/tools/go/loader" - - "golang.org/x/tools/go/analysis" -) - -const ( - StateInitializing = iota - StateLoadPackageGraph - StateBuildActionGraph - StateProcessing - StateFinalizing -) - -type Stats struct { - state uint32 - initialPackages uint32 - totalPackages uint32 - processedPackages uint32 - processedInitialPackages uint32 - - // optional function to call every time an analyzer has finished analyzing a package. - PrintAnalyzerMeasurement func(*analysis.Analyzer, *loader.PackageSpec, time.Duration) -} - -func (s *Stats) setState(state uint32) { atomic.StoreUint32(&s.state, state) } -func (s *Stats) State() int { return int(atomic.LoadUint32(&s.state)) } -func (s *Stats) setInitialPackages(n int) { atomic.StoreUint32(&s.initialPackages, uint32(n)) } -func (s *Stats) InitialPackages() int { return int(atomic.LoadUint32(&s.initialPackages)) } -func (s *Stats) setTotalPackages(n int) { atomic.StoreUint32(&s.totalPackages, uint32(n)) } -func (s *Stats) TotalPackages() int { return int(atomic.LoadUint32(&s.totalPackages)) } - -func (s *Stats) finishPackage() { atomic.AddUint32(&s.processedPackages, 1) } -func (s *Stats) finishInitialPackage() { atomic.AddUint32(&s.processedInitialPackages, 1) } -func (s *Stats) ProcessedPackages() int { return int(atomic.LoadUint32(&s.processedPackages)) } -func (s *Stats) ProcessedInitialPackages() int { - return int(atomic.LoadUint32(&s.processedInitialPackages)) -} - -func (s *Stats) measureAnalyzer(analysis *analysis.Analyzer, pkg *loader.PackageSpec, d time.Duration) { - if s.PrintAnalyzerMeasurement != nil { - s.PrintAnalyzerMeasurement(analysis, pkg, d) - } -} diff --git a/vendor/honnef.co/go/tools/lintcmd/stats.go b/vendor/honnef.co/go/tools/lintcmd/stats.go deleted file mode 100644 index 198ef0ba72..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/stats.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !aix,!android,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris - -package lintcmd - -import "os" - -var infoSignals = []os.Signal{} diff --git a/vendor/honnef.co/go/tools/lintcmd/stats_bsd.go b/vendor/honnef.co/go/tools/lintcmd/stats_bsd.go deleted file mode 100644 index 0395a36d3d..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/stats_bsd.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build darwin dragonfly freebsd netbsd openbsd - -package lintcmd - -import ( - "os" - "syscall" -) - -var infoSignals = []os.Signal{syscall.SIGINFO} diff --git a/vendor/honnef.co/go/tools/lintcmd/stats_posix.go b/vendor/honnef.co/go/tools/lintcmd/stats_posix.go deleted file mode 100644 index 1737692b2f..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/stats_posix.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build aix android linux solaris - -package lintcmd - -import ( - "os" - "syscall" -) - -var infoSignals = []os.Signal{syscall.SIGUSR1} diff --git a/vendor/honnef.co/go/tools/lintcmd/version/buildinfo.go b/vendor/honnef.co/go/tools/lintcmd/version/buildinfo.go deleted file mode 100644 index b6034bb7dc..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/version/buildinfo.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build go1.12 - -package version - -import ( - "fmt" - "runtime/debug" -) - -func printBuildInfo() { - if info, ok := debug.ReadBuildInfo(); ok { - fmt.Println("Main module:") - printModule(&info.Main) - fmt.Println("Dependencies:") - for _, dep := range info.Deps { - printModule(dep) - } - } else { - fmt.Println("Built without Go modules") - } -} - -func buildInfoVersion() (string, bool) { - info, ok := debug.ReadBuildInfo() - if !ok { - return "", false - } - if info.Main.Version == "(devel)" { - return "", false - } - return info.Main.Version, true -} - -func printModule(m *debug.Module) { - fmt.Printf("\t%s", m.Path) - if m.Version != "(devel)" { - fmt.Printf("@%s", m.Version) - } - if m.Sum != "" { - fmt.Printf(" (sum: %s)", m.Sum) - } - if m.Replace != nil { - fmt.Printf(" (replace: %s)", m.Replace.Path) - } - fmt.Println() -} diff --git a/vendor/honnef.co/go/tools/lintcmd/version/buildinfo111.go b/vendor/honnef.co/go/tools/lintcmd/version/buildinfo111.go deleted file mode 100644 index 06aae1e65b..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/version/buildinfo111.go +++ /dev/null @@ -1,6 +0,0 @@ -// +build !go1.12 - -package version - -func printBuildInfo() {} -func buildInfoVersion() (string, bool) { return "", false } diff --git a/vendor/honnef.co/go/tools/lintcmd/version/version.go b/vendor/honnef.co/go/tools/lintcmd/version/version.go deleted file mode 100644 index a12f70fb4c..0000000000 --- a/vendor/honnef.co/go/tools/lintcmd/version/version.go +++ /dev/null @@ -1,42 +0,0 @@ -package version - -import ( - "fmt" - "os" - "path/filepath" - "runtime" -) - -const Version = "devel" - -// version returns a version descriptor and reports whether the -// version is a known release. -func version() (string, bool) { - if Version != "devel" { - return Version, true - } - v, ok := buildInfoVersion() - if ok { - return v, false - } - return "devel", false -} - -func Print() { - v, release := version() - - if release { - fmt.Printf("%s %s\n", filepath.Base(os.Args[0]), v) - } else if v == "devel" { - fmt.Printf("%s (no version)\n", filepath.Base(os.Args[0])) - } else { - fmt.Printf("%s (devel, %s)\n", filepath.Base(os.Args[0]), v) - } -} - -func Verbose() { - Print() - fmt.Println() - fmt.Println("Compiled with Go version:", runtime.Version()) - printBuildInfo() -} diff --git a/vendor/honnef.co/go/tools/pattern/convert.go b/vendor/honnef.co/go/tools/pattern/convert.go deleted file mode 100644 index dfcd1560d7..0000000000 --- a/vendor/honnef.co/go/tools/pattern/convert.go +++ /dev/null @@ -1,242 +0,0 @@ -package pattern - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" -) - -var astTypes = map[string]reflect.Type{ - "Ellipsis": reflect.TypeOf(ast.Ellipsis{}), - "RangeStmt": reflect.TypeOf(ast.RangeStmt{}), - "AssignStmt": reflect.TypeOf(ast.AssignStmt{}), - "IndexExpr": reflect.TypeOf(ast.IndexExpr{}), - "Ident": reflect.TypeOf(ast.Ident{}), - "ValueSpec": reflect.TypeOf(ast.ValueSpec{}), - "GenDecl": reflect.TypeOf(ast.GenDecl{}), - "BinaryExpr": reflect.TypeOf(ast.BinaryExpr{}), - "ForStmt": reflect.TypeOf(ast.ForStmt{}), - "ArrayType": reflect.TypeOf(ast.ArrayType{}), - "DeferStmt": reflect.TypeOf(ast.DeferStmt{}), - "MapType": reflect.TypeOf(ast.MapType{}), - "ReturnStmt": reflect.TypeOf(ast.ReturnStmt{}), - "SliceExpr": reflect.TypeOf(ast.SliceExpr{}), - "StarExpr": reflect.TypeOf(ast.StarExpr{}), - "UnaryExpr": reflect.TypeOf(ast.UnaryExpr{}), - "SendStmt": reflect.TypeOf(ast.SendStmt{}), - "SelectStmt": reflect.TypeOf(ast.SelectStmt{}), - "ImportSpec": reflect.TypeOf(ast.ImportSpec{}), - "IfStmt": reflect.TypeOf(ast.IfStmt{}), - "GoStmt": reflect.TypeOf(ast.GoStmt{}), - "Field": reflect.TypeOf(ast.Field{}), - "SelectorExpr": reflect.TypeOf(ast.SelectorExpr{}), - "StructType": reflect.TypeOf(ast.StructType{}), - "KeyValueExpr": reflect.TypeOf(ast.KeyValueExpr{}), - "FuncType": reflect.TypeOf(ast.FuncType{}), - "FuncLit": reflect.TypeOf(ast.FuncLit{}), - "FuncDecl": reflect.TypeOf(ast.FuncDecl{}), - "ChanType": reflect.TypeOf(ast.ChanType{}), - "CallExpr": reflect.TypeOf(ast.CallExpr{}), - "CaseClause": reflect.TypeOf(ast.CaseClause{}), - "CommClause": reflect.TypeOf(ast.CommClause{}), - "CompositeLit": reflect.TypeOf(ast.CompositeLit{}), - "EmptyStmt": reflect.TypeOf(ast.EmptyStmt{}), - "SwitchStmt": reflect.TypeOf(ast.SwitchStmt{}), - "TypeSwitchStmt": reflect.TypeOf(ast.TypeSwitchStmt{}), - "TypeAssertExpr": reflect.TypeOf(ast.TypeAssertExpr{}), - "TypeSpec": reflect.TypeOf(ast.TypeSpec{}), - "InterfaceType": reflect.TypeOf(ast.InterfaceType{}), - "BranchStmt": reflect.TypeOf(ast.BranchStmt{}), - "IncDecStmt": reflect.TypeOf(ast.IncDecStmt{}), - "BasicLit": reflect.TypeOf(ast.BasicLit{}), -} - -func ASTToNode(node interface{}) Node { - switch node := node.(type) { - case *ast.File: - panic("cannot convert *ast.File to Node") - case nil: - return Nil{} - case string: - return String(node) - case token.Token: - return Token(node) - case *ast.ExprStmt: - return ASTToNode(node.X) - case *ast.BlockStmt: - if node == nil { - return Nil{} - } - return ASTToNode(node.List) - case *ast.FieldList: - if node == nil { - return Nil{} - } - return ASTToNode(node.List) - case *ast.BasicLit: - if node == nil { - return Nil{} - } - case *ast.ParenExpr: - return ASTToNode(node.X) - } - - if node, ok := node.(ast.Node); ok { - name := reflect.TypeOf(node).Elem().Name() - T, ok := structNodes[name] - if !ok { - panic(fmt.Sprintf("internal error: unhandled type %T", node)) - } - - if reflect.ValueOf(node).IsNil() { - return Nil{} - } - v := reflect.ValueOf(node).Elem() - objs := make([]Node, T.NumField()) - for i := 0; i < T.NumField(); i++ { - f := v.FieldByName(T.Field(i).Name) - objs[i] = ASTToNode(f.Interface()) - } - - n, err := populateNode(name, objs, false) - if err != nil { - panic(fmt.Sprintf("internal error: %s", err)) - } - return n - } - - s := reflect.ValueOf(node) - if s.Kind() == reflect.Slice { - if s.Len() == 0 { - return List{} - } - if s.Len() == 1 { - return ASTToNode(s.Index(0).Interface()) - } - - tail := List{} - for i := s.Len() - 1; i >= 0; i-- { - head := ASTToNode(s.Index(i).Interface()) - l := List{ - Head: head, - Tail: tail, - } - tail = l - } - return tail - } - - panic(fmt.Sprintf("internal error: unhandled type %T", node)) -} - -func NodeToAST(node Node, state State) interface{} { - switch node := node.(type) { - case Binding: - v, ok := state[node.Name] - if !ok { - // really we want to return an error here - panic("XXX") - } - switch v := v.(type) { - case types.Object: - return &ast.Ident{Name: v.Name()} - default: - return v - } - case Builtin, Any, Object, Function, Not, Or: - panic("XXX") - case List: - if (node == List{}) { - return []ast.Node{} - } - x := []ast.Node{NodeToAST(node.Head, state).(ast.Node)} - x = append(x, NodeToAST(node.Tail, state).([]ast.Node)...) - return x - case Token: - return token.Token(node) - case String: - return string(node) - case Nil: - return nil - } - - name := reflect.TypeOf(node).Name() - T, ok := astTypes[name] - if !ok { - panic(fmt.Sprintf("internal error: unhandled type %T", node)) - } - v := reflect.ValueOf(node) - out := reflect.New(T) - for i := 0; i < T.NumField(); i++ { - fNode := v.FieldByName(T.Field(i).Name) - if (fNode == reflect.Value{}) { - continue - } - fAST := out.Elem().FieldByName(T.Field(i).Name) - switch fAST.Type().Kind() { - case reflect.Slice: - c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state)) - if c.Kind() != reflect.Slice { - // it's a single node in the pattern, we have to wrap - // it in a slice - slice := reflect.MakeSlice(fAST.Type(), 1, 1) - slice.Index(0).Set(c) - c = slice - } - switch fAST.Interface().(type) { - case []ast.Node: - switch cc := c.Interface().(type) { - case []ast.Node: - fAST.Set(c) - case []ast.Expr: - var slice []ast.Node - for _, el := range cc { - slice = append(slice, el) - } - fAST.Set(reflect.ValueOf(slice)) - default: - panic("XXX") - } - case []ast.Expr: - switch cc := c.Interface().(type) { - case []ast.Node: - var slice []ast.Expr - for _, el := range cc { - slice = append(slice, el.(ast.Expr)) - } - fAST.Set(reflect.ValueOf(slice)) - case []ast.Expr: - fAST.Set(c) - default: - panic("XXX") - } - default: - panic("XXX") - } - case reflect.Int: - c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state)) - switch c.Kind() { - case reflect.String: - tok, ok := tokensByString[c.Interface().(string)] - if !ok { - // really we want to return an error here - panic("XXX") - } - fAST.SetInt(int64(tok)) - case reflect.Int: - fAST.Set(c) - default: - panic(fmt.Sprintf("internal error: unexpected kind %s", c.Kind())) - } - default: - r := NodeToAST(fNode.Interface().(Node), state) - if r != nil { - fAST.Set(reflect.ValueOf(r)) - } - } - } - - return out.Interface().(ast.Node) -} diff --git a/vendor/honnef.co/go/tools/pattern/doc.go b/vendor/honnef.co/go/tools/pattern/doc.go deleted file mode 100644 index 05d86c2514..0000000000 --- a/vendor/honnef.co/go/tools/pattern/doc.go +++ /dev/null @@ -1,273 +0,0 @@ -/* -Package pattern implements a simple language for pattern matching Go ASTs. - -Design decisions and trade-offs - -The language is designed specifically for the task of filtering ASTs -to simplify the implementation of analyses in staticcheck. -It is also intended to be trivial to parse and execute. - -To that end, we make certain decisions that make the language more -suited to its task, while making certain queries infeasible. - -Furthermore, it is fully expected that the majority of analyses will still require ordinary Go code -to further process the filtered AST, to make use of type information and to enforce complex invariants. -It is not our goal to design a scripting language for writing entire checks in. - -The language - -At its core, patterns are a representation of Go ASTs, allowing for the use of placeholders to enable pattern matching. -Their syntax is inspired by LISP and Haskell, but unlike LISP, the core unit of patterns isn't the list, but the node. -There is a fixed set of nodes, identified by name, and with the exception of the Or node, all nodes have a fixed number of arguments. -In addition to nodes, there are atoms, which represent basic units such as strings or the nil value. - -Pattern matching is implemented via bindings, represented by the Binding node. -A Binding can match nodes and associate them with names, to later recall the nodes. -This allows for expressing "this node must be equal to that node" constraints. - -To simplify writing and reading patterns, a small amount of additional syntax exists on top of nodes and atoms. -This additional syntax doesn't add any new features of its own, it simply provides shortcuts to creating nodes and atoms. - -To show an example of a pattern, first consider this snippet of Go code: - - if x := fn(); x != nil { - for _, v := range x { - println(v, x) - } - } - -The corresponding AST expressed as an idiomatic pattern would look as follows: - - (IfStmt - (AssignStmt (Ident "x") ":=" (CallExpr (Ident "fn") [])) - (BinaryExpr (Ident "x") "!=" (Ident "nil")) - (RangeStmt - (Ident "_") (Ident "v") ":=" (Ident "x") - (CallExpr (Ident "println") [(Ident "v") (Ident "x")])) - nil) - -Two things are worth noting about this representation. -First, the [el1 el2 ...] syntax is a short-hand for creating lists. -It is a short-hand for el1:el2:[], which itself is a short-hand for (List el1 (List el2 (List nil nil)). -Second, note the absence of a lot of lists in places that normally accept lists. -For example, assignment assigns a number of right-hands to a number of left-hands, yet our AssignStmt is lacking any form of list. -This is due to the fact that a single node can match a list of exactly one element. -Thus, the two following forms have identical matching behavior: - - (AssignStmt (Ident "x") ":=" (CallExpr (Ident "fn") [])) - (AssignStmt [(Ident "x")] ":=" [(CallExpr (Ident "fn") [])]) - -This section serves as an overview of the language's syntax. -More in-depth explanations of the matching behavior as well as an exhaustive list of node types follows in the coming sections. - -Pattern matching - -TODO write about pattern matching - -- inspired by haskell syntax, but much, much simpler and naive - -Node types - -The language contains two kinds of nodes: those that map to nodes in the AST, and those that implement additional logic. - -Nodes that map directly to AST nodes are named identically to the types in the go/ast package. -What follows is an exhaustive list of these nodes: - - (ArrayType len elt) - (AssignStmt lhs tok rhs) - (BasicLit kind value) - (BinaryExpr x op y) - (BranchStmt tok label) - (CallExpr fun args) - (CaseClause list body) - (ChanType dir value) - (CommClause comm body) - (CompositeLit type elts) - (DeferStmt call) - (Ellipsis elt) - (EmptyStmt) - (Field names type tag) - (ForStmt init cond post body) - (FuncDecl recv name type body) - (FuncLit type body) - (FuncType params results) - (GenDecl specs) - (GoStmt call) - (Ident name) - (IfStmt init cond body else) - (ImportSpec name path) - (IncDecStmt x tok) - (IndexExpr x index) - (InterfaceType methods) - (KeyValueExpr key value) - (MapType key value) - (RangeStmt key value tok x body) - (ReturnStmt results) - (SelectStmt body) - (SelectorExpr x sel) - (SendStmt chan value) - (SliceExpr x low high max) - (StarExpr x) - (StructType fields) - (SwitchStmt init tag body) - (TypeAssertExpr) - (TypeSpec name type) - (TypeSwitchStmt init assign body) - (UnaryExpr op x) - (ValueSpec names type values) - -Additionally, there are the String, Token and nil atoms. -Strings are double-quoted string literals, as in (Ident "someName"). -Tokens are also represented as double-quoted string literals, but are converted to token.Token values in contexts that require tokens, -such as in (BinaryExpr x "<" y), where "<" is transparently converted to token.LSS during matching. -The keyword 'nil' denotes the nil value, which represents the absence of any value. - -We also defines the (List head tail) node, which is used to represent sequences of elements as a singly linked list. -The head is a single element, and the tail is the remainder of the list. -For example, - - (List "foo" (List "bar" (List "baz" (List nil nil)))) - -represents a list of three elements, "foo", "bar" and "baz". There is dedicated syntax for writing lists, which looks as follows: - - ["foo" "bar" "baz"] - -This syntax is itself syntactic sugar for the following form: - - "foo":"bar":"baz":[] - -This form is of particular interest for pattern matching, as it allows matching on the head and tail. For example, - - "foo":"bar":_ - -would match any list with at least two elements, where the first two elements are "foo" and "bar". This is equivalent to writing - - (List "foo" (List "bar" _)) - -Note that it is not possible to match from the end of the list. -That is, there is no way to express a query such as "a list of any length where the last element is foo". - -Note that unlike in LISP, nil and empty lists are distinct from one another. -In patterns, with respect to lists, nil is akin to Go's untyped nil. -It will match a nil ast.Node, but it will not match a nil []ast.Expr. Nil will, however, match pointers to named types such as *ast.Ident. -Similarly, lists are akin to Go's -slices. An empty list will match both a nil and an empty []ast.Expr, but it will not match a nil ast.Node. - -Due to the difference between nil and empty lists, an empty list is represented as (List nil nil), i.e. a list with no head or tail. -Similarly, a list of one element is represented as (List el (List nil nil)). Unlike in LISP, it cannot be represented by (List el nil). - -Finally, there are nodes that implement special logic or matching behavior. - -(Any) matches any value. The underscore (_) maps to this node, making the following two forms equivalent: - - (Ident _) - (Ident (Any)) - -(Builtin name) matches a built-in identifier or function by name. -This is a type-aware variant of (Ident name). -Instead of only comparing the name, it resolves the object behind the name and makes sure it's a pre-declared identifier. - -For example, in the following piece of code - - func fn() { - println(true) - true := false - println(true) - } - -the pattern - - (Builtin "true") - -will match exactly once, on the first use of 'true' in the function. -Subsequent occurrences of 'true' no longer refer to the pre-declared identifier. - -(Object name) matches an identifier by name, but yields the -types.Object it refers to. - -(Function name) matches ast.Idents and ast.SelectorExprs that refer to a function with a given fully qualified name. -For example, "net/url.PathEscape" matches the PathEscape function in the net/url package, -and "(net/url.EscapeError).Error" refers to the Error method on the net/url.EscapeError type, -either on an instance of the type, or on the type itself. - -For example, the following patterns match the following lines of code: - - (CallExpr (Function "fmt.Println") _) // pattern 1 - (CallExpr (Function "(net/url.EscapeError).Error") _) // pattern 2 - - fmt.Println("hello, world") // matches pattern 1 - var x url.EscapeError - x.Error() // matches pattern 2 - (url.EscapeError).Error(x) // also matches pattern 2 - -(Binding name node) creates or uses a binding. -Bindings work like variable assignments, allowing referring to already matched nodes. -As an example, bindings are necessary to match self-assignment of the form "x = x", -since we need to express that the right-hand side is identical to the left-hand side. - -If a binding's node is not nil, the matcher will attempt to match a node according to the pattern. -If a binding's node is nil, the binding will either recall an existing value, or match the Any node. -It is an error to provide a non-nil node to a binding that has already been bound. - -Referring back to the earlier example, the following pattern will match self-assignment of idents: - - (AssignStmt (Binding "lhs" (Ident _)) "=" (Binding "lhs" nil)) - -Because bindings are a crucial component of pattern matching, there is special syntax for creating and recalling bindings. -Lower-case names refer to bindings. If standing on its own, the name "foo" will be equivalent to (Binding "foo" nil). -If a name is followed by an at-sign (@) then it will create a binding for the node that follows. -Together, this allows us to rewrite the earlier example as follows: - - (AssignStmt lhs@(Ident _) "=" lhs) - -(Or nodes...) is a variadic node that tries matching each node until one succeeds. For example, the following pattern matches all idents of name "foo" or "bar": - - (Ident (Or "foo" "bar")) - -We could also have written - - (Or (Ident "foo") (Ident "bar")) - -and achieved the same result. We can also mix different kinds of nodes: - - (Or (Ident "foo") (CallExpr (Ident "bar") _)) - -When using bindings inside of nodes used inside Or, all or none of the bindings will be bound. -That is, partially matched nodes that ultimately failed to match will not produce any bindings observable outside of the matching attempt. -We can thus write - - (Or (Ident name) (CallExpr name)) - -and 'name' will either be a String if the first option matched, or an Ident or SelectorExpr if the second option matched. - -(Not node) - -The Not node negates a match. For example, (Not (Ident _)) will match all nodes that aren't identifiers. - -ChanDir(0) - -Automatic unnesting of AST nodes - -The Go AST has several types of nodes that wrap other nodes. -To simplify matching, we automatically unwrap some of these nodes. - -These nodes are ExprStmt (for using expressions in a statement context), -ParenExpr (for parenthesized expressions), -DeclStmt (for declarations in a statement context), -and LabeledStmt (for labeled statements). - -Thus, the query - - (FuncLit _ [(CallExpr _ _)] - -will match a function literal containing a single function call, -even though in the actual Go AST, the CallExpr is nested inside an ExprStmt, -as function bodies are made up of sequences of statements. - -On the flip-side, there is no way to specifically match these wrapper nodes. -For example, there is no way of searching for unnecessary parentheses, like in the following piece of Go code: - - ((x)) += 2 - -*/ -package pattern diff --git a/vendor/honnef.co/go/tools/pattern/fuzz.go b/vendor/honnef.co/go/tools/pattern/fuzz.go deleted file mode 100644 index 52e7df9742..0000000000 --- a/vendor/honnef.co/go/tools/pattern/fuzz.go +++ /dev/null @@ -1,50 +0,0 @@ -// +build gofuzz - -package pattern - -import ( - "go/ast" - goparser "go/parser" - "go/token" - "os" - "path/filepath" - "strings" -) - -var files []*ast.File - -func init() { - fset := token.NewFileSet() - filepath.Walk("/usr/lib/go/src", func(path string, info os.FileInfo, err error) error { - if err != nil { - // XXX error handling - panic(err) - } - if !strings.HasSuffix(path, ".go") { - return nil - } - f, err := goparser.ParseFile(fset, path, nil, 0) - if err != nil { - return nil - } - files = append(files, f) - return nil - }) -} - -func Fuzz(data []byte) int { - p := &Parser{} - pat, err := p.Parse(string(data)) - if err != nil { - if strings.Contains(err.Error(), "internal error") { - panic(err) - } - return 0 - } - _ = pat.Root.String() - - for _, f := range files { - Match(pat.Root, f) - } - return 1 -} diff --git a/vendor/honnef.co/go/tools/pattern/lexer.go b/vendor/honnef.co/go/tools/pattern/lexer.go deleted file mode 100644 index fb72e392bd..0000000000 --- a/vendor/honnef.co/go/tools/pattern/lexer.go +++ /dev/null @@ -1,221 +0,0 @@ -package pattern - -import ( - "fmt" - "go/token" - "unicode" - "unicode/utf8" -) - -type lexer struct { - f *token.File - - input string - start int - pos int - width int - items chan item -} - -type itemType int - -const eof = -1 - -const ( - itemError itemType = iota - itemLeftParen - itemRightParen - itemLeftBracket - itemRightBracket - itemTypeName - itemVariable - itemAt - itemColon - itemBlank - itemString - itemEOF -) - -func (typ itemType) String() string { - switch typ { - case itemError: - return "ERROR" - case itemLeftParen: - return "(" - case itemRightParen: - return ")" - case itemLeftBracket: - return "[" - case itemRightBracket: - return "]" - case itemTypeName: - return "TYPE" - case itemVariable: - return "VAR" - case itemAt: - return "@" - case itemColon: - return ":" - case itemBlank: - return "_" - case itemString: - return "STRING" - case itemEOF: - return "EOF" - default: - return fmt.Sprintf("itemType(%d)", typ) - } -} - -type item struct { - typ itemType - val string - pos int -} - -type stateFn func(*lexer) stateFn - -func (l *lexer) run() { - for state := lexStart; state != nil; { - state = state(l) - } - close(l.items) -} - -func (l *lexer) emitValue(t itemType, value string) { - l.items <- item{t, value, l.start} - l.start = l.pos -} - -func (l *lexer) emit(t itemType) { - l.items <- item{t, l.input[l.start:l.pos], l.start} - l.start = l.pos -} - -func lexStart(l *lexer) stateFn { - switch r := l.next(); { - case r == eof: - l.emit(itemEOF) - return nil - case unicode.IsSpace(r): - l.ignore() - case r == '(': - l.emit(itemLeftParen) - case r == ')': - l.emit(itemRightParen) - case r == '[': - l.emit(itemLeftBracket) - case r == ']': - l.emit(itemRightBracket) - case r == '@': - l.emit(itemAt) - case r == ':': - l.emit(itemColon) - case r == '_': - l.emit(itemBlank) - case r == '"': - l.backup() - return lexString - case unicode.IsUpper(r): - l.backup() - return lexType - case unicode.IsLower(r): - l.backup() - return lexVariable - default: - return l.errorf("unexpected character %c", r) - } - return lexStart -} - -func (l *lexer) next() (r rune) { - if l.pos >= len(l.input) { - l.width = 0 - return eof - } - r, l.width = utf8.DecodeRuneInString(l.input[l.pos:]) - - if r == '\n' { - l.f.AddLine(l.pos) - } - - l.pos += l.width - - return r -} - -func (l *lexer) ignore() { - l.start = l.pos -} - -func (l *lexer) backup() { - l.pos -= l.width -} - -func (l *lexer) errorf(format string, args ...interface{}) stateFn { - // TODO(dh): emit position information in errors - l.items <- item{ - itemError, - fmt.Sprintf(format, args...), - l.start, - } - return nil -} - -func isAlphaNumeric(r rune) bool { - return r >= '0' && r <= '9' || - r >= 'a' && r <= 'z' || - r >= 'A' && r <= 'Z' -} - -func lexString(l *lexer) stateFn { - l.next() // skip quote - escape := false - - var runes []rune - for { - switch r := l.next(); r { - case eof: - return l.errorf("unterminated string") - case '"': - if !escape { - l.emitValue(itemString, string(runes)) - return lexStart - } else { - runes = append(runes, '"') - escape = false - } - case '\\': - if escape { - runes = append(runes, '\\') - escape = false - } else { - escape = true - } - default: - runes = append(runes, r) - } - } -} - -func lexType(l *lexer) stateFn { - l.next() - for { - if !isAlphaNumeric(l.next()) { - l.backup() - l.emit(itemTypeName) - return lexStart - } - } -} - -func lexVariable(l *lexer) stateFn { - l.next() - for { - if !isAlphaNumeric(l.next()) { - l.backup() - l.emit(itemVariable) - return lexStart - } - } -} diff --git a/vendor/honnef.co/go/tools/pattern/match.go b/vendor/honnef.co/go/tools/pattern/match.go deleted file mode 100644 index 88c0818fb2..0000000000 --- a/vendor/honnef.co/go/tools/pattern/match.go +++ /dev/null @@ -1,535 +0,0 @@ -package pattern - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" -) - -var tokensByString = map[string]Token{ - "INT": Token(token.INT), - "FLOAT": Token(token.FLOAT), - "IMAG": Token(token.IMAG), - "CHAR": Token(token.CHAR), - "STRING": Token(token.STRING), - "+": Token(token.ADD), - "-": Token(token.SUB), - "*": Token(token.MUL), - "/": Token(token.QUO), - "%": Token(token.REM), - "&": Token(token.AND), - "|": Token(token.OR), - "^": Token(token.XOR), - "<<": Token(token.SHL), - ">>": Token(token.SHR), - "&^": Token(token.AND_NOT), - "+=": Token(token.ADD_ASSIGN), - "-=": Token(token.SUB_ASSIGN), - "*=": Token(token.MUL_ASSIGN), - "/=": Token(token.QUO_ASSIGN), - "%=": Token(token.REM_ASSIGN), - "&=": Token(token.AND_ASSIGN), - "|=": Token(token.OR_ASSIGN), - "^=": Token(token.XOR_ASSIGN), - "<<=": Token(token.SHL_ASSIGN), - ">>=": Token(token.SHR_ASSIGN), - "&^=": Token(token.AND_NOT_ASSIGN), - "&&": Token(token.LAND), - "||": Token(token.LOR), - "<-": Token(token.ARROW), - "++": Token(token.INC), - "--": Token(token.DEC), - "==": Token(token.EQL), - "<": Token(token.LSS), - ">": Token(token.GTR), - "=": Token(token.ASSIGN), - "!": Token(token.NOT), - "!=": Token(token.NEQ), - "<=": Token(token.LEQ), - ">=": Token(token.GEQ), - ":=": Token(token.DEFINE), - "...": Token(token.ELLIPSIS), - "IMPORT": Token(token.IMPORT), - "VAR": Token(token.VAR), - "TYPE": Token(token.TYPE), - "CONST": Token(token.CONST), -} - -func maybeToken(node Node) (Node, bool) { - if node, ok := node.(String); ok { - if tok, ok := tokensByString[string(node)]; ok { - return tok, true - } - return node, false - } - return node, false -} - -func isNil(v interface{}) bool { - if v == nil { - return true - } - if _, ok := v.(Nil); ok { - return true - } - return false -} - -type matcher interface { - Match(*Matcher, interface{}) (interface{}, bool) -} - -type State = map[string]interface{} - -type Matcher struct { - TypesInfo *types.Info - State State -} - -func (m *Matcher) fork() *Matcher { - state := make(State, len(m.State)) - for k, v := range m.State { - state[k] = v - } - return &Matcher{ - TypesInfo: m.TypesInfo, - State: state, - } -} - -func (m *Matcher) merge(mc *Matcher) { - m.State = mc.State -} - -func (m *Matcher) Match(a Node, b ast.Node) bool { - m.State = State{} - _, ok := match(m, a, b) - return ok -} - -func Match(a Node, b ast.Node) (*Matcher, bool) { - m := &Matcher{} - ret := m.Match(a, b) - return m, ret -} - -// Match two items, which may be (Node, AST) or (AST, AST) -func match(m *Matcher, l, r interface{}) (interface{}, bool) { - if _, ok := r.(Node); ok { - panic("Node mustn't be on right side of match") - } - - switch l := l.(type) { - case *ast.ParenExpr: - return match(m, l.X, r) - case *ast.ExprStmt: - return match(m, l.X, r) - case *ast.DeclStmt: - return match(m, l.Decl, r) - case *ast.LabeledStmt: - return match(m, l.Stmt, r) - case *ast.BlockStmt: - return match(m, l.List, r) - case *ast.FieldList: - return match(m, l.List, r) - } - - switch r := r.(type) { - case *ast.ParenExpr: - return match(m, l, r.X) - case *ast.ExprStmt: - return match(m, l, r.X) - case *ast.DeclStmt: - return match(m, l, r.Decl) - case *ast.LabeledStmt: - return match(m, l, r.Stmt) - case *ast.BlockStmt: - if r == nil { - return match(m, l, nil) - } - return match(m, l, r.List) - case *ast.FieldList: - if r == nil { - return match(m, l, nil) - } - return match(m, l, r.List) - case *ast.BasicLit: - if r == nil { - return match(m, l, nil) - } - } - - if l, ok := l.(matcher); ok { - return l.Match(m, r) - } - - if l, ok := l.(Node); ok { - // Matching of pattern with concrete value - return matchNodeAST(m, l, r) - } - - if l == nil || r == nil { - return nil, l == r - } - - { - ln, ok1 := l.(ast.Node) - rn, ok2 := r.(ast.Node) - if ok1 && ok2 { - return matchAST(m, ln, rn) - } - } - - { - obj, ok := l.(types.Object) - if ok { - switch r := r.(type) { - case *ast.Ident: - return obj, obj == m.TypesInfo.ObjectOf(r) - case *ast.SelectorExpr: - return obj, obj == m.TypesInfo.ObjectOf(r.Sel) - default: - return obj, false - } - } - } - - { - ln, ok1 := l.([]ast.Expr) - rn, ok2 := r.([]ast.Expr) - if ok1 || ok2 { - if ok1 && !ok2 { - rn = []ast.Expr{r.(ast.Expr)} - } else if !ok1 && ok2 { - ln = []ast.Expr{l.(ast.Expr)} - } - - if len(ln) != len(rn) { - return nil, false - } - for i, ll := range ln { - if _, ok := match(m, ll, rn[i]); !ok { - return nil, false - } - } - return r, true - } - } - - { - ln, ok1 := l.([]ast.Stmt) - rn, ok2 := r.([]ast.Stmt) - if ok1 || ok2 { - if ok1 && !ok2 { - rn = []ast.Stmt{r.(ast.Stmt)} - } else if !ok1 && ok2 { - ln = []ast.Stmt{l.(ast.Stmt)} - } - - if len(ln) != len(rn) { - return nil, false - } - for i, ll := range ln { - if _, ok := match(m, ll, rn[i]); !ok { - return nil, false - } - } - return r, true - } - } - - { - ln, ok1 := l.([]*ast.Field) - rn, ok2 := r.([]*ast.Field) - if ok1 || ok2 { - if ok1 && !ok2 { - rn = []*ast.Field{r.(*ast.Field)} - } else if !ok1 && ok2 { - ln = []*ast.Field{l.(*ast.Field)} - } - - if len(ln) != len(rn) { - return nil, false - } - for i, ll := range ln { - if _, ok := match(m, ll, rn[i]); !ok { - return nil, false - } - } - return r, true - } - } - - panic(fmt.Sprintf("unsupported comparison: %T and %T", l, r)) -} - -// Match a Node with an AST node -func matchNodeAST(m *Matcher, a Node, b interface{}) (interface{}, bool) { - switch b := b.(type) { - case []ast.Stmt: - // 'a' is not a List or we'd be using its Match - // implementation. - - if len(b) != 1 { - return nil, false - } - return match(m, a, b[0]) - case []ast.Expr: - // 'a' is not a List or we'd be using its Match - // implementation. - - if len(b) != 1 { - return nil, false - } - return match(m, a, b[0]) - case ast.Node: - ra := reflect.ValueOf(a) - rb := reflect.ValueOf(b).Elem() - - if ra.Type().Name() != rb.Type().Name() { - return nil, false - } - - for i := 0; i < ra.NumField(); i++ { - af := ra.Field(i) - fieldName := ra.Type().Field(i).Name - bf := rb.FieldByName(fieldName) - if (bf == reflect.Value{}) { - panic(fmt.Sprintf("internal error: could not find field %s in type %t when comparing with %T", fieldName, b, a)) - } - ai := af.Interface() - bi := bf.Interface() - if ai == nil { - return b, bi == nil - } - if _, ok := match(m, ai.(Node), bi); !ok { - return b, false - } - } - return b, true - case nil: - return nil, a == Nil{} - default: - panic(fmt.Sprintf("unhandled type %T", b)) - } -} - -// Match two AST nodes -func matchAST(m *Matcher, a, b ast.Node) (interface{}, bool) { - ra := reflect.ValueOf(a) - rb := reflect.ValueOf(b) - - if ra.Type() != rb.Type() { - return nil, false - } - if ra.IsNil() || rb.IsNil() { - return rb, ra.IsNil() == rb.IsNil() - } - - ra = ra.Elem() - rb = rb.Elem() - for i := 0; i < ra.NumField(); i++ { - af := ra.Field(i) - bf := rb.Field(i) - if af.Type() == rtTokPos || af.Type() == rtObject || af.Type() == rtCommentGroup { - continue - } - - switch af.Kind() { - case reflect.Slice: - if af.Len() != bf.Len() { - return nil, false - } - for j := 0; j < af.Len(); j++ { - if _, ok := match(m, af.Index(j).Interface().(ast.Node), bf.Index(j).Interface().(ast.Node)); !ok { - return nil, false - } - } - case reflect.String: - if af.String() != bf.String() { - return nil, false - } - case reflect.Int: - if af.Int() != bf.Int() { - return nil, false - } - case reflect.Bool: - if af.Bool() != bf.Bool() { - return nil, false - } - case reflect.Ptr, reflect.Interface: - if _, ok := match(m, af.Interface(), bf.Interface()); !ok { - return nil, false - } - default: - panic(fmt.Sprintf("internal error: unhandled kind %s (%T)", af.Kind(), af.Interface())) - } - } - return b, true -} - -func (b Binding) Match(m *Matcher, node interface{}) (interface{}, bool) { - if isNil(b.Node) { - v, ok := m.State[b.Name] - if ok { - // Recall value - return match(m, v, node) - } - // Matching anything - b.Node = Any{} - } - - // Store value - if _, ok := m.State[b.Name]; ok { - panic(fmt.Sprintf("binding already created: %s", b.Name)) - } - new, ret := match(m, b.Node, node) - if ret { - m.State[b.Name] = new - } - return new, ret -} - -func (Any) Match(m *Matcher, node interface{}) (interface{}, bool) { - return node, true -} - -func (l List) Match(m *Matcher, node interface{}) (interface{}, bool) { - v := reflect.ValueOf(node) - if v.Kind() == reflect.Slice { - if isNil(l.Head) { - return node, v.Len() == 0 - } - if v.Len() == 0 { - return nil, false - } - // OPT(dh): don't check the entire tail if head didn't match - _, ok1 := match(m, l.Head, v.Index(0).Interface()) - _, ok2 := match(m, l.Tail, v.Slice(1, v.Len()).Interface()) - return node, ok1 && ok2 - } - // Our empty list does not equal an untyped Go nil. This way, we can - // tell apart an if with no else and an if with an empty else. - return nil, false -} - -func (s String) Match(m *Matcher, node interface{}) (interface{}, bool) { - switch o := node.(type) { - case token.Token: - if tok, ok := maybeToken(s); ok { - return match(m, tok, node) - } - return nil, false - case string: - return o, string(s) == o - default: - return nil, false - } -} - -func (tok Token) Match(m *Matcher, node interface{}) (interface{}, bool) { - o, ok := node.(token.Token) - if !ok { - return nil, false - } - return o, token.Token(tok) == o -} - -func (Nil) Match(m *Matcher, node interface{}) (interface{}, bool) { - return nil, isNil(node) -} - -func (builtin Builtin) Match(m *Matcher, node interface{}) (interface{}, bool) { - ident, ok := node.(*ast.Ident) - if !ok { - return nil, false - } - obj := m.TypesInfo.ObjectOf(ident) - if obj != types.Universe.Lookup(ident.Name) { - return nil, false - } - return match(m, builtin.Name, ident.Name) -} - -func (obj Object) Match(m *Matcher, node interface{}) (interface{}, bool) { - ident, ok := node.(*ast.Ident) - if !ok { - return nil, false - } - - id := m.TypesInfo.ObjectOf(ident) - _, ok = match(m, obj.Name, ident.Name) - return id, ok -} - -func (fn Function) Match(m *Matcher, node interface{}) (interface{}, bool) { - var name string - var obj types.Object - switch node := node.(type) { - case *ast.Ident: - obj = m.TypesInfo.ObjectOf(node) - switch obj := obj.(type) { - case *types.Func: - // OPT(dh): optimize this similar to code.FuncName - name = obj.FullName() - case *types.Builtin: - name = obj.Name() - default: - return nil, false - } - case *ast.SelectorExpr: - var ok bool - obj, ok = m.TypesInfo.ObjectOf(node.Sel).(*types.Func) - if !ok { - return nil, false - } - // OPT(dh): optimize this similar to code.FuncName - name = obj.(*types.Func).FullName() - default: - return nil, false - } - _, ok := match(m, fn.Name, name) - return obj, ok -} - -func (or Or) Match(m *Matcher, node interface{}) (interface{}, bool) { - for _, opt := range or.Nodes { - mc := m.fork() - if ret, ok := match(mc, opt, node); ok { - m.merge(mc) - return ret, true - } - } - return nil, false -} - -func (not Not) Match(m *Matcher, node interface{}) (interface{}, bool) { - _, ok := match(m, not.Node, node) - if ok { - return nil, false - } - return node, true -} - -var ( - // Types of fields in go/ast structs that we want to skip - rtTokPos = reflect.TypeOf(token.Pos(0)) - rtObject = reflect.TypeOf((*ast.Object)(nil)) - rtCommentGroup = reflect.TypeOf((*ast.CommentGroup)(nil)) -) - -var ( - _ matcher = Binding{} - _ matcher = Any{} - _ matcher = List{} - _ matcher = String("") - _ matcher = Token(0) - _ matcher = Nil{} - _ matcher = Builtin{} - _ matcher = Object{} - _ matcher = Function{} - _ matcher = Or{} - _ matcher = Not{} -) diff --git a/vendor/honnef.co/go/tools/pattern/parser.go b/vendor/honnef.co/go/tools/pattern/parser.go deleted file mode 100644 index 009238b860..0000000000 --- a/vendor/honnef.co/go/tools/pattern/parser.go +++ /dev/null @@ -1,455 +0,0 @@ -package pattern - -import ( - "fmt" - "go/ast" - "go/token" - "reflect" -) - -type Pattern struct { - Root Node - // Relevant contains instances of ast.Node that could potentially - // initiate a successful match of the pattern. - Relevant []reflect.Type -} - -func MustParse(s string) Pattern { - p := &Parser{AllowTypeInfo: true} - pat, err := p.Parse(s) - if err != nil { - panic(err) - } - return pat -} - -func roots(node Node) []reflect.Type { - switch node := node.(type) { - case Or: - var out []reflect.Type - for _, el := range node.Nodes { - out = append(out, roots(el)...) - } - return out - case Not: - return roots(node.Node) - case Binding: - return roots(node.Node) - case Nil, nil: - // this branch is reached via bindings - return allTypes - default: - Ts, ok := nodeToASTTypes[reflect.TypeOf(node)] - if !ok { - panic(fmt.Sprintf("internal error: unhandled type %T", node)) - } - return Ts - } -} - -var allTypes = []reflect.Type{ - reflect.TypeOf((*ast.RangeStmt)(nil)), - reflect.TypeOf((*ast.AssignStmt)(nil)), - reflect.TypeOf((*ast.IndexExpr)(nil)), - reflect.TypeOf((*ast.Ident)(nil)), - reflect.TypeOf((*ast.ValueSpec)(nil)), - reflect.TypeOf((*ast.GenDecl)(nil)), - reflect.TypeOf((*ast.BinaryExpr)(nil)), - reflect.TypeOf((*ast.ForStmt)(nil)), - reflect.TypeOf((*ast.ArrayType)(nil)), - reflect.TypeOf((*ast.DeferStmt)(nil)), - reflect.TypeOf((*ast.MapType)(nil)), - reflect.TypeOf((*ast.ReturnStmt)(nil)), - reflect.TypeOf((*ast.SliceExpr)(nil)), - reflect.TypeOf((*ast.StarExpr)(nil)), - reflect.TypeOf((*ast.UnaryExpr)(nil)), - reflect.TypeOf((*ast.SendStmt)(nil)), - reflect.TypeOf((*ast.SelectStmt)(nil)), - reflect.TypeOf((*ast.ImportSpec)(nil)), - reflect.TypeOf((*ast.IfStmt)(nil)), - reflect.TypeOf((*ast.GoStmt)(nil)), - reflect.TypeOf((*ast.Field)(nil)), - reflect.TypeOf((*ast.SelectorExpr)(nil)), - reflect.TypeOf((*ast.StructType)(nil)), - reflect.TypeOf((*ast.KeyValueExpr)(nil)), - reflect.TypeOf((*ast.FuncType)(nil)), - reflect.TypeOf((*ast.FuncLit)(nil)), - reflect.TypeOf((*ast.FuncDecl)(nil)), - reflect.TypeOf((*ast.ChanType)(nil)), - reflect.TypeOf((*ast.CallExpr)(nil)), - reflect.TypeOf((*ast.CaseClause)(nil)), - reflect.TypeOf((*ast.CommClause)(nil)), - reflect.TypeOf((*ast.CompositeLit)(nil)), - reflect.TypeOf((*ast.EmptyStmt)(nil)), - reflect.TypeOf((*ast.SwitchStmt)(nil)), - reflect.TypeOf((*ast.TypeSwitchStmt)(nil)), - reflect.TypeOf((*ast.TypeAssertExpr)(nil)), - reflect.TypeOf((*ast.TypeSpec)(nil)), - reflect.TypeOf((*ast.InterfaceType)(nil)), - reflect.TypeOf((*ast.BranchStmt)(nil)), - reflect.TypeOf((*ast.IncDecStmt)(nil)), - reflect.TypeOf((*ast.BasicLit)(nil)), -} - -var nodeToASTTypes = map[reflect.Type][]reflect.Type{ - reflect.TypeOf(String("")): nil, - reflect.TypeOf(Token(0)): nil, - reflect.TypeOf(List{}): {reflect.TypeOf((*ast.BlockStmt)(nil)), reflect.TypeOf((*ast.FieldList)(nil))}, - reflect.TypeOf(Builtin{}): {reflect.TypeOf((*ast.Ident)(nil))}, - reflect.TypeOf(Object{}): {reflect.TypeOf((*ast.Ident)(nil))}, - reflect.TypeOf(Function{}): {reflect.TypeOf((*ast.Ident)(nil)), reflect.TypeOf((*ast.SelectorExpr)(nil))}, - reflect.TypeOf(Any{}): allTypes, - reflect.TypeOf(RangeStmt{}): {reflect.TypeOf((*ast.RangeStmt)(nil))}, - reflect.TypeOf(AssignStmt{}): {reflect.TypeOf((*ast.AssignStmt)(nil))}, - reflect.TypeOf(IndexExpr{}): {reflect.TypeOf((*ast.IndexExpr)(nil))}, - reflect.TypeOf(Ident{}): {reflect.TypeOf((*ast.Ident)(nil))}, - reflect.TypeOf(ValueSpec{}): {reflect.TypeOf((*ast.ValueSpec)(nil))}, - reflect.TypeOf(GenDecl{}): {reflect.TypeOf((*ast.GenDecl)(nil))}, - reflect.TypeOf(BinaryExpr{}): {reflect.TypeOf((*ast.BinaryExpr)(nil))}, - reflect.TypeOf(ForStmt{}): {reflect.TypeOf((*ast.ForStmt)(nil))}, - reflect.TypeOf(ArrayType{}): {reflect.TypeOf((*ast.ArrayType)(nil))}, - reflect.TypeOf(DeferStmt{}): {reflect.TypeOf((*ast.DeferStmt)(nil))}, - reflect.TypeOf(MapType{}): {reflect.TypeOf((*ast.MapType)(nil))}, - reflect.TypeOf(ReturnStmt{}): {reflect.TypeOf((*ast.ReturnStmt)(nil))}, - reflect.TypeOf(SliceExpr{}): {reflect.TypeOf((*ast.SliceExpr)(nil))}, - reflect.TypeOf(StarExpr{}): {reflect.TypeOf((*ast.StarExpr)(nil))}, - reflect.TypeOf(UnaryExpr{}): {reflect.TypeOf((*ast.UnaryExpr)(nil))}, - reflect.TypeOf(SendStmt{}): {reflect.TypeOf((*ast.SendStmt)(nil))}, - reflect.TypeOf(SelectStmt{}): {reflect.TypeOf((*ast.SelectStmt)(nil))}, - reflect.TypeOf(ImportSpec{}): {reflect.TypeOf((*ast.ImportSpec)(nil))}, - reflect.TypeOf(IfStmt{}): {reflect.TypeOf((*ast.IfStmt)(nil))}, - reflect.TypeOf(GoStmt{}): {reflect.TypeOf((*ast.GoStmt)(nil))}, - reflect.TypeOf(Field{}): {reflect.TypeOf((*ast.Field)(nil))}, - reflect.TypeOf(SelectorExpr{}): {reflect.TypeOf((*ast.SelectorExpr)(nil))}, - reflect.TypeOf(StructType{}): {reflect.TypeOf((*ast.StructType)(nil))}, - reflect.TypeOf(KeyValueExpr{}): {reflect.TypeOf((*ast.KeyValueExpr)(nil))}, - reflect.TypeOf(FuncType{}): {reflect.TypeOf((*ast.FuncType)(nil))}, - reflect.TypeOf(FuncLit{}): {reflect.TypeOf((*ast.FuncLit)(nil))}, - reflect.TypeOf(FuncDecl{}): {reflect.TypeOf((*ast.FuncDecl)(nil))}, - reflect.TypeOf(ChanType{}): {reflect.TypeOf((*ast.ChanType)(nil))}, - reflect.TypeOf(CallExpr{}): {reflect.TypeOf((*ast.CallExpr)(nil))}, - reflect.TypeOf(CaseClause{}): {reflect.TypeOf((*ast.CaseClause)(nil))}, - reflect.TypeOf(CommClause{}): {reflect.TypeOf((*ast.CommClause)(nil))}, - reflect.TypeOf(CompositeLit{}): {reflect.TypeOf((*ast.CompositeLit)(nil))}, - reflect.TypeOf(EmptyStmt{}): {reflect.TypeOf((*ast.EmptyStmt)(nil))}, - reflect.TypeOf(SwitchStmt{}): {reflect.TypeOf((*ast.SwitchStmt)(nil))}, - reflect.TypeOf(TypeSwitchStmt{}): {reflect.TypeOf((*ast.TypeSwitchStmt)(nil))}, - reflect.TypeOf(TypeAssertExpr{}): {reflect.TypeOf((*ast.TypeAssertExpr)(nil))}, - reflect.TypeOf(TypeSpec{}): {reflect.TypeOf((*ast.TypeSpec)(nil))}, - reflect.TypeOf(InterfaceType{}): {reflect.TypeOf((*ast.InterfaceType)(nil))}, - reflect.TypeOf(BranchStmt{}): {reflect.TypeOf((*ast.BranchStmt)(nil))}, - reflect.TypeOf(IncDecStmt{}): {reflect.TypeOf((*ast.IncDecStmt)(nil))}, - reflect.TypeOf(BasicLit{}): {reflect.TypeOf((*ast.BasicLit)(nil))}, -} - -var requiresTypeInfo = map[string]bool{ - "Function": true, - "Builtin": true, - "Object": true, -} - -type Parser struct { - // Allow nodes that rely on type information - AllowTypeInfo bool - - lex *lexer - cur item - last *item - items chan item -} - -func (p *Parser) Parse(s string) (Pattern, error) { - p.cur = item{} - p.last = nil - p.items = nil - - fset := token.NewFileSet() - p.lex = &lexer{ - f: fset.AddFile("