diff --git a/.github/workflows/e2e-managed.yml b/.github/workflows/e2e-managed.yml index 3ff633828..adf221f6f 100644 --- a/.github/workflows/e2e-managed.yml +++ b/.github/workflows/e2e-managed.yml @@ -24,22 +24,29 @@ env: GCP_KSA_NAME: ${{ secrets.GCP_KSA_NAME}} # Kubernetes Service Account TF_VAR_GCP_GSA_NAME: ${{ secrets.GCP_GSA_NAME}} # Goolge Service Account for tf TF_VAR_GCP_KSA_NAME: ${{ secrets.GCP_KSA_NAME}} # Kubernetes Service Account for tf + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_SA_NAME: ${{ secrets.AWS_SA_NAME }} + AWS_SA_NAMESPACE: ${{ secrets.AWS_SA_NAMESPACE }} + AWS_REGION: "eu-west-1" + AWS_CLUSTER_NAME: "eso-e2e-managed" + TF_VAR_AWS_SA_NAME: ${{ secrets.AWS_SA_NAME }} + TF_VAR_AWS_SA_NAMESPACE: ${{ secrets.AWS_SA_NAMESPACE }} + TF_VAR_AWS_REGION: "eu-west-1" + TF_VAR_AWS_CLUSTER_NAME: "eso-e2e-managed" + AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID}} AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET}} TENANT_ID: ${{ secrets.TENANT_ID}} VAULT_URL: ${{ secrets.VAULT_URL}} - IMAGE_REGISTRY: ghcr.io/external-secrets/external-secrets - E2E_IMAGE_REGISTRY: ghcr.io/external-secrets/external-secrets-e2e - E2E_VERSION: test name: e2e tests jobs: - # Repo owner has commented /ok-to-test-managed on a (fork-based) pull request - integration-fork-managed: + integration-managed: runs-on: ubuntu-latest - if: - github.event_name == 'repository_dispatch' + if: github.event_name == 'repository_dispatch' + steps: # Check out merge commit @@ -75,13 +82,7 @@ jobs: path: ${{ steps.go.outputs.mod-cache }} key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }} restore-keys: ${{ runner.os }}-pkg- - - - name: Setup gcloud CLI - uses: google-github-actions/setup-gcloud@master - with: - service_account_key: ${{ env.GCP_SM_SA_GKE_JSON }} - project_id: ${{ env.GCP_PROJECT_ID }} - + - name: Setup TFLint uses: terraform-linters/setup-tflint@v1 with: @@ -91,40 +92,52 @@ jobs: run: find ${{ github.workspace }} | grep tf$ | xargs -n1 dirname | xargs -IXXX -n1 /bin/sh -c 'set -o errexit; cd XXX; pwd; tflint --loglevel=info .; cd - >/dev/null' - name: Setup TF Gcloud Provider + if: github.event.client_payload.slash_command.args.named.provider == 'gcp' run: |- mkdir -p terraform/gcp/secrets echo ${GCP_SM_SA_GKE_JSON} > terraform/gcp/secrets/gcloud-service-account-key.json - - name: Show TF GKE + - name: Show TF run: |- - make tf.show.gcp + PROVIDER=${{github.event.client_payload.slash_command.args.named.provider}} + make tf.show.${PROVIDER} - name: Setup Infracost uses: infracost/actions/setup@v1 with: api-key: ${{ secrets.INFRACOST_API_KEY }} - - name: Generate Infracost JSON for GKE - run: infracost breakdown --path terraform/gcp/plan.json --format json --out-file /tmp/infracost.json + - name: Generate Infracost JSON for provider + run: infracost breakdown --path terraform/${{github.event.client_payload.slash_command.args.named.provider}}/plan.json --format json --out-file /tmp/infracost.json - name: Post Infracost comment uses: infracost/actions/comment@v1 with: path: /tmp/infracost.json - # Choose the commenting behavior, 'update' is a good default: - behavior: update # Create a single comment and update it. The "quietest" option. - # behavior: delete-and-new # Delete previous comments and create a new one. - # behavior: hide-and-new # Minimize previous comments and create a new one. - # behavior: new # Create a new cost estimate comment on every push. + behavior: update - - name: Apply TF GKE + - name: Apply TF run: |- - make tf.apply.gcp + PROVIDER=${{github.event.client_payload.slash_command.args.named.provider}} + make tf.apply.${PROVIDER} + + - name: Setup gcloud CLI + if: github.event.client_payload.slash_command.args.named.provider == 'gcp' + uses: google-github-actions/setup-gcloud@master + with: + service_account_key: ${{ env.GCP_SM_SA_GKE_JSON }} + project_id: ${{ env.GCP_PROJECT_ID }} - name: Get the GKE credentials + if: github.event.client_payload.slash_command.args.named.provider == 'gcp' run: |- gcloud container clusters get-credentials "$GCP_GKE_CLUSTER" --zone "$GCP_GKE_ZONE" --project "$GCP_PROJECT_ID" + - name: Get the AWS credentials + if: github.event.client_payload.slash_command.args.named.provider == 'aws' + run: |- + aws --region $AWS_REGION eks update-kubeconfig --name $AWS_CLUSTER_NAME + - name: Login to Docker uses: docker/login-action@v1 if: env.GHCR_USERNAME != '' @@ -133,22 +146,21 @@ jobs: username: ${{ secrets.GHCR_USERNAME }} password: ${{ secrets.GHCR_TOKEN }} - - name: Run e2e Tests for GCP + - name: Run managed e2e Tests run: | - export E2E_VERSION=$GITHUB_SHA - export PR_IMG_TAG=$GITHUB_SHA export PATH=$PATH:$(go env GOPATH)/bin - go get github.com/onsi/ginkgo/ginkgo - make test.e2e.managed FOCUS="gcpmanaged" + PROVIDER=${{github.event.client_payload.slash_command.args.named.provider}} + go get github.com/onsi/ginkgo/v2/ginkgo + make test.e2e.managed GINKGO_LABELS="${PROVIDER}" - - name: Destroy TF GKE + - name: Destroy TF if: always() run: |- - make tf.destroy.gcp + PROVIDER=${{github.event.client_payload.slash_command.args.named.provider}} + make tf.destroy.${PROVIDER} - # Update check run called "integration-fork" + # set status=completed - uses: actions/github-script@v1 - id: update-check-run if: ${{ always() }} env: number: ${{ github.event.client_payload.pull_request.number }} diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 24c1c16b3..ed5b5d23e 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -19,12 +19,12 @@ env: GCP_GSA_NAME: ${{ secrets.GCP_GSA_NAME}} # Goolge Service Account GCP_KSA_NAME: ${{ secrets.GCP_KSA_NAME}} # Kubernetes Service Account GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID}} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID}} AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET}} TENANT_ID: ${{ secrets.TENANT_ID}} VAULT_URL: ${{ secrets.VAULT_URL}} - E2E_IMAGE_REGISTRY: local/external-secrets-e2e - E2E_VERSION: test name: e2e tests @@ -87,7 +87,7 @@ jobs: BUILD_ARGS: "--load" run: | export PATH=$PATH:$(go env GOPATH)/bin - go get github.com/onsi/ginkgo/ginkgo + go get github.com/onsi/ginkgo/v2/ginkgo make test.e2e # Repo owner has commented /ok-to-test on a (fork-based) pull request @@ -150,7 +150,7 @@ jobs: BUILD_ARGS: "--load" run: | export PATH=$PATH:$(go env GOPATH)/bin - go get github.com/onsi/ginkgo/ginkgo + go get github.com/onsi/ginkgo/v2/ginkgo make test.e2e # Update check run called "integration-fork" diff --git a/Makefile b/Makefile index 333e4b5c0..dd8383387 100644 --- a/Makefile +++ b/Makefile @@ -14,12 +14,8 @@ BUILD_ARGS ?= all: $(addprefix build-,$(ARCH)) # Image registry for build/push image targets -IMAGE_REGISTRY ?= ghcr.io/external-secrets/external-secrets +export IMAGE_REGISTRY ?= ghcr.io/external-secrets/external-secrets -PR_IMG_TAG ?= - -# Produce CRDs that work back to Kubernetes 1.11 (no version conversion) -CRD_OPTIONS ?= "crd:trivialVersions=true" CRD_DIR ?= deploy/crds HELM_DIR ?= deploy/charts/external-secrets @@ -37,10 +33,10 @@ endif # check if there are any existing `git tag` values ifeq ($(shell git tag),) # no tags found - default to initial tag `v0.0.0` -VERSION := $(shell echo "v0.0.0-$$(git rev-list HEAD --count)-g$$(git describe --dirty --always)" | sed 's/-/./2' | sed 's/-/./2') +export VERSION := $(shell echo "v0.0.0-$$(git rev-list HEAD --count)-g$$(git describe --dirty --always)" | sed 's/-/./2' | sed 's/-/./2') else # use tags -VERSION := $(shell git describe --dirty --always --tags --exclude 'helm*' | sed 's/-/./2' | sed 's/-/./2') +export VERSION := $(shell git describe --dirty --always --tags --exclude 'helm*' | sed 's/-/./2' | sed 's/-/./2') endif # ==================================================================================== @@ -89,16 +85,16 @@ test: generate ## Run tests test.e2e: generate ## Run e2e tests @$(INFO) go test e2e-tests $(MAKE) -C ./e2e test - @$(OK) go test unit-tests + @$(OK) go test e2e-tests .PHONY: test.e2e.managed -test.e2e.managed: generate ## Run e2e tests - @$(INFO) go test e2e-tests +test.e2e.managed: generate ## Run e2e tests managed + @$(INFO) go test e2e-tests-managed $(MAKE) -C ./e2e test.managed - @$(OK) go test unit-tests + @$(OK) go test e2e-tests-managed .PHONY: build -build: $(addprefix build-,$(ARCH)) ## Build binary +build: $(addprefix build-,$(ARCH)) ## Build binary .PHONY: build-% build-%: generate ## Build binary for the specified arch @@ -134,10 +130,10 @@ fmt: lint.check ## Ensure consistent code style generate: ## Generate code and crds @go run sigs.k8s.io/controller-tools/cmd/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..." - @go run sigs.k8s.io/controller-tools/cmd/controller-gen $(CRD_OPTIONS) paths="./..." output:crd:artifacts:config=$(CRD_DIR) + @go run sigs.k8s.io/controller-tools/cmd/controller-gen crd paths="./..." output:crd:artifacts:config=$(CRD_DIR) # Remove extra header lines in generated CRDs @for i in $(CRD_DIR)/*.yaml; do \ - tail -n +3 <"$$i" >"$$i.bkp" && \ + tail -n +2 <"$$i" >"$$i.bkp" && \ cp "$$i.bkp" "$$i" && \ rm "$$i.bkp"; \ done @@ -213,7 +209,7 @@ docker.push: ## Push the docker image to the registry @docker push $(IMAGE_REGISTRY):$(VERSION) @$(OK) docker push -# RELEASE_TAG is tag to promote. Default is promooting to main branch, but can be overriden +# RELEASE_TAG is tag to promote. Default is promoting to main branch, but can be overriden # to promote a tag to a specific version. RELEASE_TAG ?= main SOURCE_TAG ?= $(VERSION) @@ -232,29 +228,27 @@ docker.promote: ## Promote the docker image to the registry # ==================================================================================== # Terraform -tf.plan.gcp: ## Runs terrform plan for gcp provider bringing GKE up - @cd $(TF_DIR)/gcp; \ +tf.plan.%: ## Runs terrform plan for a provider + @cd $(TF_DIR)/$*; \ terraform init; \ - terraform plan -auto-approve + terraform plan -tf.apply.gcp: ## Runs terrform apply for gcp provider bringing GKE up - @cd $(TF_DIR)/gcp; \ +tf.apply.%: ## Runs terrform apply for a provider + @cd $(TF_DIR)/$*; \ terraform init; \ terraform apply -auto-approve -tf.destroy.gcp: ## Runs terrform destroy for gcp provider bringing GKE down - @cd $(TF_DIR)/gcp; \ +tf.destroy.%: ## Runs terrform destroy for a provider + @cd $(TF_DIR)/$*; \ terraform init; \ terraform destroy -auto-approve -tf.show.gcp: ## Runs terrform show for gcp and outputs to a file - @cd $(TF_DIR)/gcp; \ +tf.show.%: ## Runs terrform show for a provider and outputs to a file + @cd $(TF_DIR)/$*; \ terraform init; \ terraform plan -out tfplan.binary; \ terraform show -json tfplan.binary > plan.json - - # ==================================================================================== # Help diff --git a/README.md b/README.md index c8981d05a..729acf7aa 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,12 @@ Even though we have active maintainers and people assigned to this project, we k We welcome and encourage contributions to this project! Please read the [Developer](https://www.external-secrets.io/contributing-devguide/) and [Contribution process](https://www.external-secrets.io/contributing-process/) guides. Also make sure to check the [Code of Conduct](https://www.external-secrets.io/contributing-coc/) and adhere to its guidelines. +## Bi-weekly Development Meeting + +We host our development meeting every odd wednesday at [5:30 PM Berlin Time](https://dateful.com/time-zone-converter?t=17:30&tz=Europe/Berlin) on [Jitsi](https://meet.jit.si/SurroundingContentionsImportSubsequently). Meeting notes are recorded on [hackmd](https://hackmd.io/GSGEpTVdRZCP6LDxV3FHJA). + +Anyone is welcome to join. Feel free to ask questions, request feedback, raise awareness for an issue or just say hi ;) + ## Security Please report vulnerabilities by email to contact@external-secrets.io, also see our [security policy](SECURITY.md) for details. diff --git a/apis/externalsecrets/v1alpha1/secretstore_vault_types.go b/apis/externalsecrets/v1alpha1/secretstore_vault_types.go index 580832312..4cbe624c9 100644 --- a/apis/externalsecrets/v1alpha1/secretstore_vault_types.go +++ b/apis/externalsecrets/v1alpha1/secretstore_vault_types.go @@ -89,6 +89,20 @@ type VaultProvider struct { // The provider for the CA bundle to use to validate Vault server certificate. // +optional CAProvider *CAProvider `json:"caProvider,omitempty"` + + // ReadYourWrites ensures isolated read-after-write semantics by + // providing discovered cluster replication states in each request. + // More information about eventual consistency in Vault can be found here + // https://www.vaultproject.io/docs/enterprise/consistency + // +optional + ReadYourWrites bool `json:"readYourWrites,omitempty"` + + // ForwardInconsistent tells Vault to forward read-after-write requests to the Vault + // leader instead of simply retrying within a loop. This can increase performance if + // the option is enabled serverside. + // https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header + // +optional + ForwardInconsistent bool `json:"forwardInconsistent,omitempty"` } // VaultAuth is the configuration used to authenticate with a Vault server. diff --git a/deploy/crds/external-secrets.io_clustersecretstores.yaml b/deploy/crds/external-secrets.io_clustersecretstores.yaml index 507f74772..a4fa020bb 100644 --- a/deploy/crds/external-secrets.io_clustersecretstores.yaml +++ b/deploy/crds/external-secrets.io_clustersecretstores.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.5.0 + controller-gen.kubebuilder.io/version: v0.8.0 creationTimestamp: null name: clustersecretstores.external-secrets.io spec: @@ -900,6 +900,12 @@ spec: - name - type type: object + forwardInconsistent: + description: ForwardInconsistent tells Vault to forward read-after-write + requests to the Vault leader instead of simply retrying + within a loop. This can increase performance if the option + is enabled serverside. https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header + type: boolean namespace: description: 'Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault @@ -913,6 +919,12 @@ spec: is optional and will be appended if not present in specified path.' type: string + readYourWrites: + description: ReadYourWrites ensures isolated read-after-write + semantics by providing discovered cluster replication states + in each request. More information about eventual consistency + in Vault can be found here https://www.vaultproject.io/docs/enterprise/consistency + type: boolean server: description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' diff --git a/deploy/crds/external-secrets.io_externalsecrets.yaml b/deploy/crds/external-secrets.io_externalsecrets.yaml index 4d5599b24..3f560f1cd 100644 --- a/deploy/crds/external-secrets.io_externalsecrets.yaml +++ b/deploy/crds/external-secrets.io_externalsecrets.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.5.0 + controller-gen.kubebuilder.io/version: v0.8.0 creationTimestamp: null name: externalsecrets.external-secrets.io spec: diff --git a/deploy/crds/external-secrets.io_secretstores.yaml b/deploy/crds/external-secrets.io_secretstores.yaml index 17626bbae..ac2da8e28 100644 --- a/deploy/crds/external-secrets.io_secretstores.yaml +++ b/deploy/crds/external-secrets.io_secretstores.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.5.0 + controller-gen.kubebuilder.io/version: v0.8.0 creationTimestamp: null name: secretstores.external-secrets.io spec: @@ -900,6 +900,12 @@ spec: - name - type type: object + forwardInconsistent: + description: ForwardInconsistent tells Vault to forward read-after-write + requests to the Vault leader instead of simply retrying + within a loop. This can increase performance if the option + is enabled serverside. https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header + type: boolean namespace: description: 'Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault @@ -913,6 +919,12 @@ spec: is optional and will be appended if not present in specified path.' type: string + readYourWrites: + description: ReadYourWrites ensures isolated read-after-write + semantics by providing discovered cluster replication states + in each request. More information about eventual consistency + in Vault can be found here https://www.vaultproject.io/docs/enterprise/consistency + type: boolean server: description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' diff --git a/design/000-template.md b/design/000-template.md new file mode 100644 index 000000000..4a31a2200 --- /dev/null +++ b/design/000-template.md @@ -0,0 +1,61 @@ +```yaml +--- +title: My Shiny New Feature +version: v1alpha1 +authors: you, me +creation-date: 2020-09-01 +status: draft +--- +``` + +# My Shiny New Feature + +## Table of Contents + + +// autogen please + + + +## Summary +Please provide a summary of this proposal. + +## Motivation +What is the motivation of this proposal? Why is it useful and relevant? + +### Goals +What are the goals of this proposal, what's the problem we want to solve? + +### Non-Goals +What are explicit non-goals of this proposal? + +## Proposal +How does the proposal look like? + +### User Stories +How would users use this feature, what are their needs? + +### API +Please describe the API (CRD or other) and show some examples. + +### Behavior +How should the new CRD or feature behave? Are there edge cases? + +### Drawbacks +If we implement this feature, what are drawbacks and disadvantages of this approach? + +### Acceptance Criteria +What does it take to make this feature producation ready? Please take the time to think about: +* how would you rollout this feature and rollback if it causes harm? +* Test Roadmap: what kinds of tests do we want to ensure a good user experience? +* observability: Do users need to get insights into the inner workings of that feature? +* monitoring: How can users tell whether the feature is working as expected or not? + can we provide dashboards, metrics, reasonable SLIs/SLOs + or example alerts for this feature? +* troubleshooting: How would users want to troubleshoot this particular feature? + Think about different failure modes of this feature. + +## Alternatives +What alternatives do we have and what are their pros and cons? + + diff --git a/design/design-crd-spec.md b/design/design-crd-spec.md index 5b59ac681..addc58f3c 100644 --- a/design/design-crd-spec.md +++ b/design/design-crd-spec.md @@ -4,7 +4,7 @@ title: External Secrets Operator CRD version: v1alpha1 authors: all of us creation-date: 2020-09-01 -status: draft +status: accepted --- ``` diff --git a/docs/contributing-process.md b/docs/contributing-process.md index b0c1fbe71..1b875b0d1 100644 --- a/docs/contributing-process.md +++ b/docs/contributing-process.md @@ -26,9 +26,22 @@ be merged: * PR needs be reviewed and approved Once these steps are completed the PR will be merged by a code owner. +We're using the pull request `assignee` feature to track who is responsible +for the lifecycle of the PR: review, merging, ping on inactivity, close. +We close pull requests or issues if there is no response from the author for +a period of time. Feel free to reopen if you want to get back on it. +## Proposal Process +Before we introduce significant changes to the project we want to gather feedback +from the community to ensure that we progress in the right direction before we +develop and release big changes. Significant changes include for example: +* creating new custom resources +* proposing breaking changes +* changing the behavior of the controller significantly + +Please create a document in the `design/` directory based on the template `000-template.md` +and fill in your proposal. Open a pull request in draft mode and request feedback. Once the proposal is accepted and the pull request is merged we can create work packages and proceed with the implementation. ## Cutting Releases -As of now this project is in an early alpha phase. There is just the main branch -;) +The external-secrets project is released on a as-needed basis. Feel free to open a issue to request a release. Details on how to cut a release can be found in the `RELEASE.md` file in the repo. diff --git a/docs/index.md b/docs/index.md index 5976976c3..d8821d3c2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,8 +39,8 @@ even opinions matter! How to get involved: -- Monthly Meeting: we announce our meetings on slack - ([agenda](https://hackmd.io/GSGEpTVdRZCP6LDxV3FHJA)) +- Bi-weekly Development Meeting every odd week at [5:30 PM Berlin Time](https://dateful.com/time-zone-converter?t=17:30&tz=Europe/Berlin) + ([agenda](https://hackmd.io/GSGEpTVdRZCP6LDxV3FHJA), [jitsi call](https://meet.jit.si/SurroundingContentionsImportSubsequently)) - [Kubernetes Slack #external-secrets](https://kubernetes.slack.com/messages/external-secrets) - [Contributing Process](contributing-process.md) diff --git a/docs/provider-hashicorp-vault.md b/docs/provider-hashicorp-vault.md index 67a47d5af..97957363b 100644 --- a/docs/provider-hashicorp-vault.md +++ b/docs/provider-hashicorp-vault.md @@ -137,3 +137,32 @@ or `Kind=ClusterSecretStore` resource. ```yaml {% include 'vault-jwt-store.yaml' %} ``` + +### Vault Enterprise and Eventual Consistency + +When using Vault Enterprise with [performance standby nodes](https://www.vaultproject.io/docs/enterprise/consistency#performance-standby-nodes), +any follower can handle read requests immediately after the provider has +authenticated. Since Vault becomes eventually consistent in this mode, these +requests can fail if the login has not yet propagated to each server's local +state. + +Below are two different solutions to this scenario. You'll need to review them +and pick the best fit for your environment and Vault configuration. + +#### Read Your Writes + +The simplest method is simply utilizing the `X-Vault-Index` header returned on +all write requests (including logins). Passing this header back on subsequent +requests instructs the Vault client to retry the request until the server has an +index greater than or equal to that returned with the last write. + +Obviously though, this has a performance hit because the read is blocked until +the follower's local state has caught up. + +#### Forward Inconsistent + +In addition to the aforementioned `X-Vault-Index` header, Vault also supports +proxying inconsistent requests to the current cluster leader for immediate +read-after-write consistency. This is achieved by setting the `X-Vault-Inconsistent` +header to `forward-active-node`. By default, this behavior is disabled and must +be explicitly enabled in the server's [replication configuration](https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header). diff --git a/docs/spec.md b/docs/spec.md index a2f8a66ad..a1b3aa453 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -3207,6 +3207,36 @@ CAProvider

The provider for the CA bundle to use to validate Vault server certificate.

+ + +readYourWrites
+ +bool + + + +(Optional) +

ReadYourWrites ensures isolated read-after-write semantics by +providing discovered cluster replication states in each request. +More information about eventual consistency in Vault can be found here +https://www.vaultproject.io/docs/enterprise/consistency

+ + + + +forwardInconsistent
+ +bool + + + +(Optional) +

ForwardInconsistent tells Vault to forward read-after-write requests to the Vault +leader instead of simply retrying within a loop. This can increase performance if +the option is enabled serverside. +https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header

+ +

WebhookCAProvider diff --git a/e2e/Dockerfile b/e2e/Dockerfile index 7b5d8ec61..fc7468b30 100644 --- a/e2e/Dockerfile +++ b/e2e/Dockerfile @@ -4,7 +4,7 @@ FROM golang:$GO_VERSION-buster as builder ENV KUBECTL_VERSION="v1.21.2" ENV HELM_VERSION="v3.7.1" -RUN go get -u github.com/onsi/ginkgo/ginkgo +RUN go get -u github.com/onsi/ginkgo/v2/ginkgo RUN wget -q https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl && \ chmod +x /usr/local/bin/kubectl && \ wget -q https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz -O - | tar -xzO linux-amd64/helm > /usr/local/bin/helm && \ diff --git a/e2e/Makefile b/e2e/Makefile index 149ce26b4..adaf57e59 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -2,15 +2,11 @@ MAKEFLAGS += --warn-undefined-variables SHELL := /bin/bash .SHELLFLAGS := -euo pipefail -c -IMG_TAG = test -IMG = local/external-secrets-e2e:$(IMG_TAG) -KIND_IMG = "kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6" -BUILD_ARGS ?= -IMAGE_REGISTRY ?= -export FOCUS := $(FOCUS) +KIND_IMG = "kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6" +BUILD_ARGS ?= -export E2E_IMAGE_REGISTRY ?= -export E2E_VERSION ?= +export E2E_IMAGE_REGISTRY ?= ghcr.io/external-secrets/external-secrets-e2e +export GINKGO_LABELS ?= !managed start-kind: ## Start kind cluster kind create cluster \ @@ -21,49 +17,35 @@ start-kind: ## Start kind cluster test: e2e-image ## Run e2e tests against current kube context $(MAKE) -C ../ docker.build \ - IMAGE_REGISTRY=local/external-secrets \ - VERSION=$(IMG_TAG) \ + IMAGE_REGISTRY=$(IMAGE_REGISTRY) \ + VERSION=$(VERSION) \ ARCH=amd64 \ BUILD_ARGS="${BUILD_ARGS} --build-arg TARGETARCH=amd64 --build-arg TARGETOS=linux" - kind load docker-image --name="external-secrets" local/external-secrets:$(IMG_TAG) - kind load docker-image --name="external-secrets" $(IMG) + kind load docker-image --name="external-secrets" $(IMAGE_REGISTRY):$(VERSION) + kind load docker-image --name="external-secrets" $(E2E_IMAGE_REGISTRY):$(VERSION) ./run.sh -test.managed: e2e-remote-values e2e-image.managed ## Run e2e tests against current kube context +test.managed: e2e-image ## Run e2e tests against current kube context $(MAKE) -C ../ docker.build \ - VERSION=$(PR_IMG_TAG) \ + VERSION=$(VERSION) \ ARCH=amd64 \ BUILD_ARGS="${BUILD_ARGS} --build-arg TARGETARCH=amd64 --build-arg TARGETOS=linux" $(MAKE) -C ../ docker.push \ - VERSION=$(PR_IMG_TAG) + VERSION=$(VERSION) $(MAKE) -C ../ docker.push \ IMAGE_REGISTRY=$(E2E_IMAGE_REGISTRY) \ - VERSION=$(E2E_VERSION) + VERSION=$(VERSION) ./run.sh -e2e-remote-values: - sed -i "s|repository: [^ ]*|repository: $(IMAGE_REGISTRY)|g" k8s/eso.values.yaml - sed -i "s|tag: [^ ]*|tag: $(PR_IMG_TAG)|g" k8s/eso.values.yaml - sed -i "s|repository: [^ ]*|repository: $(IMAGE_REGISTRY)|g" k8s/eso.scoped.values.yaml - sed -i "s|tag: [^ ]*|tag: $(PR_IMG_TAG)|g" k8s/eso.scoped.values.yaml - - e2e-bin: - CGO_ENABLED=0 go run github.com/onsi/ginkgo/ginkgo build . + CGO_ENABLED=0 go run github.com/onsi/ginkgo/v2/ginkgo build . e2e-image: e2e-bin -rm -rf ./k8s/deploy mkdir -p k8s $(MAKE) -C ../ helm.generate cp -r ../deploy ./k8s - docker build $(BUILD_ARGS) -t $(IMG) . - -e2e-image.managed: e2e-bin - -rm -rf ./k8s/deploy - mkdir -p k8s - $(MAKE) -C ../ helm.generate - cp -r ../deploy ./k8s - docker build $(BUILD_ARGS) -t ghcr.io/external-secrets/external-secrets-e2e:$(E2E_VERSION) . + docker build $(BUILD_ARGS) -t $(E2E_IMAGE_REGISTRY):$(VERSION) . stop-kind: ## Stop kind cluster kind delete cluster \ diff --git a/e2e/e2e_test.go b/e2e/e2e_test.go index c3de5343a..3464e403e 100644 --- a/e2e/e2e_test.go +++ b/e2e/e2e_test.go @@ -17,7 +17,7 @@ import ( "testing" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint . "github.com/onsi/gomega" @@ -30,25 +30,16 @@ var _ = SynchronizedBeforeSuite(func() []byte { cfg := &addon.Config{} cfg.KubeConfig, cfg.KubeClientSet, cfg.CRClient = util.NewConfig() - By("installing localstack") - addon.InstallGlobalAddon(addon.NewLocalstack(), cfg) - - By("waiting for localstack") - err := util.WaitForURL("http://localstack.default/health") - Expect(err).ToNot(HaveOccurred()) - By("installing eso") addon.InstallGlobalAddon(addon.NewESO(), cfg) - By("installing scoped eso") - addon.InstallGlobalAddon(addon.NewScopedESO(), cfg) return nil }, func([]byte) {}) var _ = SynchronizedAfterSuite(func() {}, func() { By("Cleaning up global addons") addon.UninstallGlobalAddons() - if CurrentGinkgoTestDescription().Failed { + if CurrentSpecReport().Failed() { addon.PrintLogs() } }) @@ -56,5 +47,5 @@ var _ = SynchronizedAfterSuite(func() {}, func() { func TestE2E(t *testing.T) { NewWithT(t) RegisterFailHandler(Fail) - RunSpecs(t, "external-secrets e2e suite") + RunSpecs(t, "external-secrets e2e suite", Label("e2e")) } diff --git a/e2e/entrypoint.sh b/e2e/entrypoint.sh index e1591d967..b3291dba3 100755 --- a/e2e/entrypoint.sh +++ b/e2e/entrypoint.sh @@ -19,8 +19,6 @@ set -euo pipefail NC='\e[0m' BGREEN='\e[32m' -SLOW_E2E_THRESHOLD=${SLOW_E2E_THRESHOLD:-50} -FOCUS=${FOCUS:-.*} E2E_NODES=${E2E_NODES:-5} if [ ! -f "${HOME}/.kube/config" ]; then @@ -31,13 +29,13 @@ if [ ! -f "${HOME}/.kube/config" ]; then fi ginkgo_args=( - "-randomizeSuites" - "-randomizeAllSpecs" - "-flakeAttempts=2" + "--randomize-suites" + "--randomize-all" + "--flake-attempts=2" "-p" "-progress" "-trace" - "-slowSpecThreshold=${SLOW_E2E_THRESHOLD}" + "--slow-spec-threshold=5m" "-r" "-v" "-timeout=45m" @@ -45,9 +43,8 @@ ginkgo_args=( kubectl apply -f /k8s/deploy/crds -echo -e "${BGREEN}Running e2e test suite (FOCUS=${FOCUS})...${NC}" +echo -e "${BGREEN}Running e2e test suite (LABELS=${GINKGO_LABELS})...${NC}" ACK_GINKGO_RC=true ginkgo "${ginkgo_args[@]}" \ - -focus="${FOCUS}" \ - -skip="\[Serial\]|\[MemoryLeak\]" \ + -label-filter="${GINKGO_LABELS}" \ -nodes="${E2E_NODES}" \ /e2e.test diff --git a/e2e/framework/addon/addon.go b/e2e/framework/addon/addon.go index eb5292793..2722a83f1 100644 --- a/e2e/framework/addon/addon.go +++ b/e2e/framework/addon/addon.go @@ -14,7 +14,7 @@ limitations under the License. package addon import ( - "github.com/onsi/ginkgo" + "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" diff --git a/e2e/framework/addon/chart.go b/e2e/framework/addon/chart.go index cdd0909f2..1067dcbdd 100644 --- a/e2e/framework/addon/chart.go +++ b/e2e/framework/addon/chart.go @@ -62,8 +62,10 @@ func (c *HelmChart) Install() error { } args := []string{"install", c.ReleaseName, c.Chart, + "--debug", "--wait", "--timeout", "600s", + "-o", "yaml", "--namespace", c.Namespace, } @@ -80,7 +82,7 @@ func (c *HelmChart) Install() error { } var sout, serr bytes.Buffer - log.Logf("installing chart %s", c.ReleaseName) + log.Logf("installing chart with args: %+q", args) cmd := exec.Command("helm", args...) cmd.Stdout = &sout cmd.Stderr = &serr diff --git a/e2e/framework/addon/eso.go b/e2e/framework/addon/eso.go index 71e42711d..ccf56771d 100644 --- a/e2e/framework/addon/eso.go +++ b/e2e/framework/addon/eso.go @@ -14,92 +14,99 @@ limitations under the License. package addon import ( - "fmt" "os" // nolint - . "github.com/onsi/ginkgo" - // nolint - . "github.com/onsi/gomega" - - // nolint - "github.com/external-secrets/external-secrets/e2e/framework/util" + . "github.com/onsi/ginkgo/v2" ) type ESO struct { - Addon + *HelmChart } -func NewESO() *ESO { - return &ESO{ +func NewESO(mutators ...MutationFunc) *ESO { + eso := &ESO{ &HelmChart{ Namespace: "default", ReleaseName: "eso", Chart: "/k8s/deploy/charts/external-secrets", - Values: []string{"/k8s/eso.values.yaml"}, + Vars: []StringTuple{ + { + Key: "image.repository", + Value: os.Getenv("IMAGE_REGISTRY"), + }, + { + Key: "image.tag", + Value: os.Getenv("VERSION"), + }, + { + Key: "installCRDs", + Value: "false", + }, + }, }, } + + for _, f := range mutators { + f(eso) + } + + return eso +} + +type MutationFunc func(eso *ESO) + +func WithReleaseName(name string) MutationFunc { + return func(eso *ESO) { + eso.HelmChart.ReleaseName = name + } +} + +func WithNamespace(namespace string) MutationFunc { + return func(eso *ESO) { + eso.HelmChart.Namespace = namespace + } +} + +func WithNamespaceScope(namespace string) MutationFunc { + return func(eso *ESO) { + eso.HelmChart.Vars = append(eso.HelmChart.Vars, StringTuple{ + Key: "scopedNamespace", + Value: namespace, + }) + } +} + +func WithServiceAccount(saName string) MutationFunc { + return func(eso *ESO) { + eso.HelmChart.Vars = append(eso.HelmChart.Vars, []StringTuple{ + { + Key: "serviceAccount.create", + Value: "false", + }, + { + Key: "serviceAccount.name", + Value: saName, + }, + }...) + } +} + +func WithControllerClass(class string) MutationFunc { + return func(eso *ESO) { + eso.HelmChart.Vars = append(eso.HelmChart.Vars, StringTuple{ + Key: "extraArgs.controller-class", + Value: class, + }) + } } func (l *ESO) Install() error { By("Installing eso\n") - err := l.Addon.Install() - if err != nil { - return err - } - - By("afterInstall eso\n") - err = l.afterInstall() + err := l.HelmChart.Install() if err != nil { return err } return nil } - -func (l *ESO) afterInstall() error { - err := gcpPreparation() - Expect(err).NotTo(HaveOccurred()) - err = awsPreparation() - Expect(err).NotTo(HaveOccurred()) - if err != nil { - return err - } - return nil -} - -func gcpPreparation() error { - gcpProjectID := os.Getenv("GCP_PROJECT_ID") - gcpGSAName := os.Getenv("GCP_GSA_NAME") - gcpKSAName := os.Getenv("GCP_KSA_NAME") - _, kubeClientSet, _ := util.NewConfig() - - annotations := make(map[string]string) - annotations["iam.gke.io/gcp-service-account"] = fmt.Sprintf("%s@%s.iam.gserviceaccount.com", gcpGSAName, gcpProjectID) - _, err := util.UpdateKubeSA(gcpKSAName, kubeClientSet, "default", annotations) - Expect(err).NotTo(HaveOccurred()) - - _, err = util.UpdateKubeSA("external-secrets-e2e", kubeClientSet, "default", annotations) - Expect(err).NotTo(HaveOccurred()) - - if err != nil { - return err - } - - return nil -} - -func awsPreparation() error { - return nil -} - -func NewScopedESO() *ESO { - return &ESO{ - &HelmChart{ - Namespace: "default", - ReleaseName: "eso-aws-sm", - Chart: "/k8s/deploy/charts/external-secrets", - Values: []string{"/k8s/eso.scoped.values.yaml"}, - }, - } -} diff --git a/e2e/framework/addon/localstack.go b/e2e/framework/addon/localstack.go deleted file mode 100644 index b893cf4b9..000000000 --- a/e2e/framework/addon/localstack.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -package addon - -import "github.com/external-secrets/external-secrets/e2e/framework/util" - -type Localstack struct { - Addon -} - -func NewLocalstack() *Localstack { - return &Localstack{ - &HelmChart{ - Namespace: "default", - ReleaseName: "localstack", - Chart: "localstack-charts/localstack", - ChartVersion: "0.2.0", - Repo: ChartRepo{ - Name: "localstack-charts", - URL: "https://localstack.github.io/helm-charts", - }, - Values: []string{"/k8s/localstack.values.yaml"}, - }, - } -} - -func (l *Localstack) Install() error { - err := l.Addon.Install() - if err != nil { - return err - } - return util.WaitForURL("http://localstack.default/health") -} diff --git a/e2e/framework/addon/vault.go b/e2e/framework/addon/vault.go index 07d8837f5..55b8c61c8 100644 --- a/e2e/framework/addon/vault.go +++ b/e2e/framework/addon/vault.go @@ -32,7 +32,7 @@ import ( vault "github.com/hashicorp/vault/api" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/e2e/framework/eso.go b/e2e/framework/eso.go index 11fc82ee2..b4bd3e1cd 100644 --- a/e2e/framework/eso.go +++ b/e2e/framework/eso.go @@ -26,20 +26,18 @@ import ( "k8s.io/apimachinery/pkg/util/wait" esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1" - "github.com/external-secrets/external-secrets/e2e/framework/log" ) // WaitForSecretValue waits until a secret comes into existence and compares the secret.Data // with the provided values. func (f *Framework) WaitForSecretValue(namespace, name string, expected *v1.Secret) (*v1.Secret, error) { secret := &v1.Secret{} - err := wait.PollImmediate(time.Second*2, time.Minute*2, func() (bool, error) { + err := wait.PollImmediate(time.Second*10, time.Minute, func() (bool, error) { err := f.CRClient.Get(context.Background(), types.NamespacedName{ Namespace: namespace, Name: name, }, secret) if apierrors.IsNotFound(err) { - log.Logf("Secret Not Found. Expected: %+v, Got: %+v", expected, secret) return false, nil } return equalSecrets(expected, secret), nil diff --git a/e2e/framework/framework.go b/e2e/framework/framework.go index 138214616..04943d11f 100644 --- a/e2e/framework/framework.go +++ b/e2e/framework/framework.go @@ -16,12 +16,10 @@ package framework import ( // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint . "github.com/onsi/gomega" - // nolint - . "github.com/onsi/ginkgo/extensions/table" api "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" kscheme "k8s.io/client-go/kubernetes/scheme" @@ -30,6 +28,7 @@ import ( esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1" "github.com/external-secrets/external-secrets/e2e/framework/addon" + "github.com/external-secrets/external-secrets/e2e/framework/log" "github.com/external-secrets/external-secrets/e2e/framework/util" ) @@ -72,22 +71,24 @@ func New(baseName string) *Framework { // BeforeEach creates a namespace. func (f *Framework) BeforeEach() { var err error - By("Building a namespace api object") f.Namespace, err = util.CreateKubeNamespace(f.BaseName, f.KubeClientSet) - Expect(err).NotTo(HaveOccurred()) - - By("Using the namespace " + f.Namespace.Name) + log.Logf("created test namespace %s", f.Namespace.Name) + Expect(err).ToNot(HaveOccurred()) } // AfterEach deletes the namespace and cleans up the registered addons. func (f *Framework) AfterEach() { for _, a := range f.Addons { + if CurrentSpecReport().Failed() { + err := a.Logs() + Expect(err).ToNot(HaveOccurred()) + } err := a.Uninstall() Expect(err).ToNot(HaveOccurred()) } // reset addons to default once the run is done f.Addons = []addon.Addon{} - By("deleting test namespace") + log.Logf("deleting test namespace %s", f.Namespace.Name) err := util.DeleteKubeNamespace(f.Namespace.Name, f.KubeClientSet) Expect(err).NotTo(HaveOccurred()) } @@ -111,13 +112,13 @@ func (f *Framework) Install(a addon.Addon) { func Compose(descAppend string, f *Framework, fn func(f *Framework) (string, func(*TestCase)), tweaks ...func(*TestCase)) TableEntry { desc, tfn := fn(f) tweaks = append(tweaks, tfn) - te := Entry(desc + " " + descAppend) // need to convert []func to []interface{} ifs := make([]interface{}, len(tweaks)) for i := 0; i < len(tweaks); i++ { ifs[i] = tweaks[i] } - te.Parameters = ifs + te := Entry(desc+" "+descAppend, ifs...) + return te } diff --git a/e2e/framework/log/log.go b/e2e/framework/log/log.go index b35f682e1..77c645428 100644 --- a/e2e/framework/log/log.go +++ b/e2e/framework/log/log.go @@ -14,12 +14,10 @@ limitations under the License. package log import ( - "fmt" - - "github.com/onsi/ginkgo" + "github.com/onsi/ginkgo/v2" ) // Logf logs the format string to ginkgo stdout. func Logf(format string, args ...interface{}) { - fmt.Fprintf(ginkgo.GinkgoWriter, format, args...) + ginkgo.GinkgoWriter.Printf(format, args) } diff --git a/e2e/framework/util/util.go b/e2e/framework/util/util.go index c4a25f515..c29a90752 100644 --- a/e2e/framework/util/util.go +++ b/e2e/framework/util/util.go @@ -22,9 +22,7 @@ import ( "time" // nolint - . "github.com/onsi/ginkgo" - // nolint - . "github.com/onsi/gomega" + . "github.com/onsi/ginkgo/v2" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -242,19 +240,25 @@ func NewConfig() (*restclient.Config, *kubernetes.Clientset, crclient.Client) { kcPath := os.Getenv("KUBECONFIG") if kcPath != "" { kubeConfig, err = clientcmd.BuildConfigFromFlags("", kcPath) - Expect(err).NotTo(HaveOccurred()) + if err != nil { + Fail(err.Error()) + } } else { kubeConfig, err = restclient.InClusterConfig() - Expect(err).NotTo(HaveOccurred()) + if err != nil { + Fail(err.Error()) + } } - By("creating a kubernetes client") kubeClientSet, err := kubernetes.NewForConfig(kubeConfig) - Expect(err).NotTo(HaveOccurred()) + if err != nil { + Fail(err.Error()) + } - By("creating a controller-runtime client") CRClient, err := crclient.New(kubeConfig, crclient.Options{Scheme: Scheme}) - Expect(err).NotTo(HaveOccurred()) + if err != nil { + Fail(err.Error()) + } return kubeConfig, kubeClientSet, CRClient } diff --git a/e2e/k8s/eso.scoped.values.yaml b/e2e/k8s/eso.scoped.values.yaml deleted file mode 100644 index cfe52f1ce..000000000 --- a/e2e/k8s/eso.scoped.values.yaml +++ /dev/null @@ -1,12 +0,0 @@ -installCRDs: false -image: - repository: local/external-secrets - tag: test -scopedNamespace: test -extraEnv: - - name: AWS_SECRETSMANAGER_ENDPOINT - value: "http://localstack.default" - - name: AWS_STS_ENDPOINT - value: "http://localstack.default" - - name: AWS_SSM_ENDPOINT - value: "http://localstack.default" diff --git a/e2e/k8s/eso.values.yaml b/e2e/k8s/eso.values.yaml deleted file mode 100644 index cd5c4540a..000000000 --- a/e2e/k8s/eso.values.yaml +++ /dev/null @@ -1,11 +0,0 @@ -installCRDs: false -image: - repository: local/external-secrets - tag: test -extraEnv: - - name: AWS_SECRETSMANAGER_ENDPOINT - value: "http://localstack.default" - - name: AWS_STS_ENDPOINT - value: "http://localstack.default" - - name: AWS_SSM_ENDPOINT - value: "http://localstack.default" diff --git a/e2e/run.sh b/e2e/run.sh index f396d8239..34570e3aa 100755 --- a/e2e/run.sh +++ b/e2e/run.sh @@ -42,20 +42,23 @@ done kubectl apply -f ${DIR}/k8s/deploy/crds -echo -e "Starting the e2e test pod" +echo -e "Starting the e2e test pod ${E2E_IMAGE_REGISTRY}:${VERSION}" kubectl run --rm \ --attach \ --restart=Never \ - --pod-running-timeout=10m \ - --env="FOCUS=${FOCUS:-.*}" \ + --pod-running-timeout=5m \ + --env="GINKGO_LABELS=${GINKGO_LABELS:-.*}" \ --env="GCP_SM_SA_JSON=${GCP_SM_SA_JSON:-}" \ --env="GCP_PROJECT_ID=${GCP_PROJECT_ID:-}" \ - --env="TF_VAR_GCP_PROJECT_ID=${TF_VAR_GCP_PROJECT_ID:-}" \ --env="GCP_GSA_NAME=${GCP_GSA_NAME:-}" \ --env="GCP_KSA_NAME=${GCP_KSA_NAME:-}" \ - --env="TF_VAR_GCP_GSA_NAME=${TF_VAR_GCP_GSA_NAME:-}" \ - --env="TF_VAR_GCP_KSA_NAME=${TF_VAR_GCP_KSA_NAME:-}" \ + --env="GCP_GKE_ZONE=${GCP_GKE_ZONE:-}" \ + --env="GCP_GKE_CLUSTER=${GCP_GKE_CLUSTER:-}" \ + --env="AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-}" \ + --env="AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-}" \ + --env="AWS_SA_NAME=${AWS_SA_NAME:-}" \ + --env="AWS_SA_NAMESPACE=${AWS_SA_NAMESPACE:-}" \ --env="AZURE_CLIENT_ID=${AZURE_CLIENT_ID:-}" \ --env="AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET:-}" \ --env="AKEYLESS_ACCESS_ID=${AKEYLESS_ACCESS_ID:-}" \ @@ -70,5 +73,7 @@ kubectl run --rm \ --env="ORACLE_REGION=${ORACLE_REGION:-}" \ --env="ORACLE_FINGERPRINT=${ORACLE_FINGERPRINT:-}" \ --env="ORACLE_KEY=${ORACLE_KEY:-}" \ + --env="IMAGE_REGISTRY=${IMAGE_REGISTRY}" \ + --env="VERSION=${VERSION}" \ --overrides='{ "apiVersion": "v1", "spec":{"serviceAccountName": "external-secrets-e2e"}}' \ - e2e --image=${E2E_IMAGE_REGISTRY}:${E2E_VERSION} + e2e --image=${E2E_IMAGE_REGISTRY}:${VERSION} diff --git a/e2e/suite/akeyless/akeyless.go b/e2e/suite/akeyless/akeyless.go index de8ad93b6..998026d00 100644 --- a/e2e/suite/akeyless/akeyless.go +++ b/e2e/suite/akeyless/akeyless.go @@ -15,23 +15,19 @@ limitations under the License. package akeyless import ( - "os" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint - . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/ginkgo/v2/extensions/table" "github.com/external-secrets/external-secrets/e2e/framework" "github.com/external-secrets/external-secrets/e2e/suite/common" ) -var _ = Describe("[akeyless] ", func() { +var _ = Describe("[akeyless]", Label("akeyless"), func() { f := framework.New("eso-akeyless") - accessID := os.Getenv("AKEYLESS_ACCESS_ID") - accessType := os.Getenv("AKEYLESS_ACCESS_TYPE") - accessTypeParam := os.Getenv("AKEYLESS_ACCESS_TYPE_PARAM") - prov := newAkeylessProvider(f, accessID, accessType, accessTypeParam) + prov := newFromEnv(f) DescribeTable("sync secrets", framework.TableFunc(f, prov), Entry(common.SimpleDataSync(f)), diff --git a/e2e/suite/akeyless/provider.go b/e2e/suite/akeyless/provider.go index 8528c41db..56c1d8d2b 100644 --- a/e2e/suite/akeyless/provider.go +++ b/e2e/suite/akeyless/provider.go @@ -29,7 +29,7 @@ import ( "github.com/akeylesslabs/akeyless-go/v2" //nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" //nolint . "github.com/onsi/gomega" @@ -75,6 +75,13 @@ func newAkeylessProvider(f *framework.Framework, accessID, accessType, accessTyp return prov } +func newFromEnv(f *framework.Framework) *akeylessProvider { + accessID := os.Getenv("AKEYLESS_ACCESS_ID") + accessType := os.Getenv("AKEYLESS_ACCESS_TYPE") + accessTypeParam := os.Getenv("AKEYLESS_ACCESS_TYPE_PARAM") + return newAkeylessProvider(f, accessID, accessType, accessTypeParam) +} + // CreateSecret creates a secret. func (a *akeylessProvider) CreateSecret(key, val string) { token, err := a.GetToken() diff --git a/e2e/suite/alibaba/alibaba.go b/e2e/suite/alibaba/alibaba.go index a540ec8c5..d8e6d170f 100644 --- a/e2e/suite/alibaba/alibaba.go +++ b/e2e/suite/alibaba/alibaba.go @@ -15,27 +15,19 @@ limitations under the License. package alibaba import ( - "os" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint - . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/ginkgo/v2/extensions/table" "github.com/external-secrets/external-secrets/e2e/framework" "github.com/external-secrets/external-secrets/e2e/suite/common" ) -var _ = Describe("[alibaba] ", func() { +var _ = Describe("[alibaba]", Label("alibaba"), func() { f := framework.New("eso-alibaba") - accessKeyID := os.Getenv("ACCESS_KEY_ID") - accessKeySecret := os.Getenv("ACCESS_KEY_SECRET") - regionID := os.Getenv("REGION_ID") - prov := &alibabaProvider{} - - if accessKeyID != "" && accessKeySecret != "" && regionID != "" { - prov = newAlibabaProvider(f, accessKeyID, accessKeySecret, regionID) - } + prov := newFromEnv(f) DescribeTable("sync secrets", framework.TableFunc(f, prov), Entry(common.SimpleDataSync(f)), diff --git a/e2e/suite/alibaba/provider.go b/e2e/suite/alibaba/provider.go index 64bc97eab..5199f7502 100644 --- a/e2e/suite/alibaba/provider.go +++ b/e2e/suite/alibaba/provider.go @@ -16,11 +16,12 @@ package alibaba import ( "context" + "os" "github.com/aliyun/alibaba-cloud-sdk-go/services/kms" //nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" //nolint . "github.com/onsi/gomega" @@ -54,6 +55,13 @@ func newAlibabaProvider(f *framework.Framework, accessKeyID, accessKeySecret, re return prov } +func newFromEnv(f *framework.Framework) *alibabaProvider { + accessKeyID := os.Getenv("ACCESS_KEY_ID") + accessKeySecret := os.Getenv("ACCESS_KEY_SECRET") + regionID := os.Getenv("REGION_ID") + return newAlibabaProvider(f, accessKeyID, accessKeySecret, regionID) +} + // CreateSecret creates a secret in both kv v1 and v2 provider. func (s *alibabaProvider) CreateSecret(key, val string) { client, err := kms.NewClientWithAccessKey(s.regionID, s.accessKeyID, s.accessKeySecret) diff --git a/e2e/suite/aws/provider.go b/e2e/suite/aws/provider.go index c2413e58e..3e1bc0185 100644 --- a/e2e/suite/aws/provider.go +++ b/e2e/suite/aws/provider.go @@ -16,6 +16,8 @@ package aws import ( "context" + "os" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" @@ -23,79 +25,194 @@ import ( "github.com/aws/aws-sdk-go/service/secretsmanager" //nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint . "github.com/onsi/gomega" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1" - esmeta "github.com/external-secrets/external-secrets/apis/meta/v1" + esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1" "github.com/external-secrets/external-secrets/e2e/framework" - "github.com/external-secrets/external-secrets/pkg/provider/aws/auth" + "github.com/external-secrets/external-secrets/e2e/framework/log" ) type SMProvider struct { - url string + ServiceAccountName string + ServiceAccountNamespace string + + kid string + sak string + region string client *secretsmanager.SecretsManager framework *framework.Framework } -const secretName = "provider-secret" +const ( + staticCredentialsSecretName = "provider-secret" +) -func newSMProvider(f *framework.Framework, url string) *SMProvider { +func NewSMProvider(f *framework.Framework, kid, sak, region, saName, saNamespace string) *SMProvider { sess, err := session.NewSessionWithOptions(session.Options{ Config: aws.Config{ - Credentials: credentials.NewStaticCredentials("foobar", "foobar", "secret-manager"), - EndpointResolver: auth.ResolveEndpointWithServiceMap(map[string]string{ - "secretsmanager": url, - }), - Region: aws.String("eu-east-1"), + Credentials: credentials.NewStaticCredentials(kid, sak, ""), + Region: aws.String(region), }, }) - Expect(err).ToNot(HaveOccurred()) + if err != nil { + Fail(err.Error()) + } sm := secretsmanager.New(sess) prov := &SMProvider{ - url: url, - client: sm, - framework: f, + ServiceAccountName: saName, + ServiceAccountNamespace: saNamespace, + kid: kid, + sak: sak, + region: region, + client: sm, + framework: f, } - BeforeEach(prov.BeforeEach) + + BeforeEach(func() { + prov.SetupStaticStore() + prov.SetupReferencedIRSAStore() + prov.SetupMountedIRSAStore() + }) + + AfterEach(func() { + // Cleanup ClusterSecretStore + err := prov.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: prov.ReferencedIRSAStoreName(), + }, + }) + Expect(err).ToNot(HaveOccurred()) + }) + return prov } +func NewFromEnv(f *framework.Framework) *SMProvider { + kid := os.Getenv("AWS_ACCESS_KEY_ID") + sak := os.Getenv("AWS_SECRET_ACCESS_KEY") + region := "eu-west-1" + saName := os.Getenv("AWS_SA_NAME") + saNamespace := os.Getenv("AWS_SA_NAMESPACE") + return NewSMProvider(f, kid, sak, region, saName, saNamespace) +} + +// CreateSecret creates a secret at the provider. func (s *SMProvider) CreateSecret(key, val string) { - _, err := s.client.CreateSecret(&secretsmanager.CreateSecretInput{ - Name: aws.String(key), - SecretString: aws.String(val), - }) - Expect(err).ToNot(HaveOccurred()) + // we re-use some secret names throughout our test suite + // due to the fact that there is a short delay before the secret is actually deleted + // we have to retry creating the secret + attempts := 20 + for { + log.Logf("creating secret %s / attempts left: %d", key, attempts) + _, err := s.client.CreateSecret(&secretsmanager.CreateSecretInput{ + Name: aws.String(key), + SecretString: aws.String(val), + }) + if err == nil { + return + } + attempts-- + if attempts < 0 { + Fail("unable to create secret: " + err.Error()) + } + <-time.After(time.Second * 5) + } } +// DeleteSecret deletes a secret at the provider. +// There may be a short delay between calling this function +// and the removal of the secret on the provider side. func (s *SMProvider) DeleteSecret(key string) { + log.Logf("deleting secret %s", key) _, err := s.client.DeleteSecret(&secretsmanager.DeleteSecretInput{ - SecretId: aws.String(key), + SecretId: aws.String(key), + ForceDeleteWithoutRecovery: aws.Bool(true), }) Expect(err).ToNot(HaveOccurred()) } -func (s *SMProvider) BeforeEach() { - By("creating a AWS SM credentials secret") +// MountedIRSAStore is a SecretStore without auth config +// ESO relies on the pod-mounted ServiceAccount when using this store. +func (s *SMProvider) SetupMountedIRSAStore() { + secretStore := &esv1alpha1.SecretStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.MountedIRSAStoreName(), + Namespace: s.framework.Namespace.Name, + }, + Spec: esv1alpha1.SecretStoreSpec{ + Provider: &esv1alpha1.SecretStoreProvider{ + AWS: &esv1alpha1.AWSProvider{ + Service: esv1alpha1.AWSServiceSecretsManager, + Region: s.region, + Auth: esv1alpha1.AWSAuth{}, + }, + }, + }, + } + err := s.framework.CRClient.Create(context.Background(), secretStore) + Expect(err).ToNot(HaveOccurred()) +} + +func (s *SMProvider) MountedIRSAStoreName() string { + return "irsa-mounted-" + s.framework.Namespace.Name +} + +// ReferncedIRSAStore is a ClusterStore +// that references a (IRSA-) ServiceAccount in the default namespace. +func (s *SMProvider) SetupReferencedIRSAStore() { + log.Logf("creating IRSA ClusterSecretStore %s", s.framework.Namespace.Name) + secretStore := &esv1alpha1.ClusterSecretStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.ReferencedIRSAStoreName(), + }, + } + _, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, secretStore, func() error { + secretStore.Spec.Provider = &esv1alpha1.SecretStoreProvider{ + AWS: &esv1alpha1.AWSProvider{ + Service: esv1alpha1.AWSServiceSecretsManager, + Region: s.region, + Auth: esv1alpha1.AWSAuth{ + JWTAuth: &esv1alpha1.AWSJWTAuth{ + ServiceAccountRef: &esmetav1.ServiceAccountSelector{ + Name: s.ServiceAccountName, + Namespace: &s.ServiceAccountNamespace, + }, + }, + }, + }, + } + return nil + }) + Expect(err).ToNot(HaveOccurred()) +} + +func (s *SMProvider) ReferencedIRSAStoreName() string { + return "irsa-ref-" + s.framework.Namespace.Name +} + +// StaticStore is namespaced and references +// static credentials from a secret. +func (s *SMProvider) SetupStaticStore() { awsCreds := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: secretName, + Name: staticCredentialsSecretName, Namespace: s.framework.Namespace.Name, }, StringData: map[string]string{ - "kid": "foobar", - "sak": "foobar", + "kid": s.kid, + "sak": s.sak, }, } err := s.framework.CRClient.Create(context.Background(), awsCreds) Expect(err).ToNot(HaveOccurred()) - By("creating a AWS SM secret store") secretStore := &esv1alpha1.SecretStore{ ObjectMeta: metav1.ObjectMeta{ Name: s.framework.Namespace.Name, @@ -105,15 +222,15 @@ func (s *SMProvider) BeforeEach() { Provider: &esv1alpha1.SecretStoreProvider{ AWS: &esv1alpha1.AWSProvider{ Service: esv1alpha1.AWSServiceSecretsManager, - Region: "us-east-1", + Region: s.region, Auth: esv1alpha1.AWSAuth{ SecretRef: &esv1alpha1.AWSAuthSecretRef{ - AccessKeyID: esmeta.SecretKeySelector{ - Name: secretName, + AccessKeyID: esmetav1.SecretKeySelector{ + Name: staticCredentialsSecretName, Key: "kid", }, - SecretAccessKey: esmeta.SecretKeySelector{ - Name: secretName, + SecretAccessKey: esmetav1.SecretKeySelector{ + Name: staticCredentialsSecretName, Key: "sak", }, }, diff --git a/e2e/suite/aws/secretsmanager.go b/e2e/suite/aws/secretsmanager.go index feafa029f..f51fbd58c 100644 --- a/e2e/suite/aws/secretsmanager.go +++ b/e2e/suite/aws/secretsmanager.go @@ -15,103 +15,17 @@ limitations under the License. package aws import ( - "context" - "fmt" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" - // nolint - . "github.com/onsi/ginkgo/extensions/table" - - // nolint - . "github.com/onsi/gomega" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - - esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1" - esmeta "github.com/external-secrets/external-secrets/apis/meta/v1" "github.com/external-secrets/external-secrets/e2e/framework" "github.com/external-secrets/external-secrets/e2e/suite/common" ) -var _ = Describe("[aws] ", func() { - f := framework.New("eso-aws") - prov := newSMProvider(f, "http://localstack.default") - - jwt := func(tc *framework.TestCase) { - saName := "my-sa" - err := f.CRClient.Create(context.Background(), &v1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: saName, - Namespace: f.Namespace.Name, - Annotations: map[string]string{ - "eks.amazonaws.com/role-arn": "arn:aws:iam::account:role/my-example-role", - }, - }, - }) - Expect(err).ToNot(HaveOccurred()) - - // create secret store - secretStore := &esv1alpha1.SecretStore{ - TypeMeta: metav1.TypeMeta{ - Kind: esv1alpha1.SecretStoreKind, - APIVersion: esv1alpha1.SchemeGroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{ - Name: f.Namespace.Name, - Namespace: f.Namespace.Name, - }, - Spec: esv1alpha1.SecretStoreSpec{ - Provider: &esv1alpha1.SecretStoreProvider{ - AWS: &esv1alpha1.AWSProvider{ - Service: esv1alpha1.AWSServiceSecretsManager, - Region: "us-east-1", - Auth: esv1alpha1.AWSAuth{ - JWTAuth: &esv1alpha1.AWSJWTAuth{ - ServiceAccountRef: &esmeta.ServiceAccountSelector{ - Name: saName, - Namespace: &f.Namespace.Name, - }, - }, - }, - }, - }, - }, - } - err = f.CRClient.Patch(context.Background(), secretStore, client.Apply, client.FieldOwner("e2e-case"), client.ForceOwnership) - Expect(err).ToNot(HaveOccurred()) - - secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one") - secretKey2 := fmt.Sprintf("%s-%s", f.Namespace.Name, "other") - secretValue := "bar" - tc.Secrets = map[string]string{ - secretKey1: secretValue, - secretKey2: secretValue, - } - tc.ExpectedSecret = &v1.Secret{ - Type: v1.SecretTypeOpaque, - Data: map[string][]byte{ - secretKey1: []byte(secretValue), - secretKey2: []byte(secretValue), - }, - } - tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{ - { - SecretKey: secretKey1, - RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{ - Key: secretKey1, - }, - }, - { - SecretKey: secretKey2, - RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{ - Key: secretKey2, - }, - }, - } - } +var _ = Describe("[aws] ", Label("aws", "secretsmanager"), func() { + f := framework.New("eso-aws-sm") + prov := NewFromEnv(f) DescribeTable("sync secrets", framework.TableFunc(f, @@ -121,7 +35,6 @@ var _ = Describe("[aws] ", func() { Entry(common.JSONDataFromSync(f)), Entry(common.JSONDataWithProperty(f)), Entry(common.JSONDataWithTemplate(f)), - Entry("should sync secrets with jwt auth", jwt), Entry(common.DockerJSONConfig(f)), Entry(common.DataPropertyDockerconfigJSON(f)), Entry(common.SSHKeySync(f)), diff --git a/e2e/suite/aws/secretsmanager_managed.go b/e2e/suite/aws/secretsmanager_managed.go new file mode 100644 index 000000000..6d83d3d73 --- /dev/null +++ b/e2e/suite/aws/secretsmanager_managed.go @@ -0,0 +1,102 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package aws + +import ( + + // nolint + . "github.com/onsi/ginkgo/v2" + + esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1" + "github.com/external-secrets/external-secrets/e2e/framework" + "github.com/external-secrets/external-secrets/e2e/framework/addon" + "github.com/external-secrets/external-secrets/e2e/suite/common" +) + +const ( + withReferencedIRSA = "with referenced IRSA" + withMountedIRSA = "with mounted IRSA" +) + +// here we use the global eso instance +// that uses the service account in the default namespace +// which was created by terraform. +var _ = Describe("[awsmanaged] IRSA via referenced service account", Label("aws", "secretsmanager", "managed"), func() { + f := framework.New("eso-aws-managed") + prov := NewFromEnv(f) + + DescribeTable("sync secrets", + framework.TableFunc(f, + prov), + framework.Compose(withReferencedIRSA, f, common.SimpleDataSync, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.NestedJSONWithGJSON, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.JSONDataFromSync, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.JSONDataWithProperty, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.JSONDataWithTemplate, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.DockerJSONConfig, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.DataPropertyDockerconfigJSON, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.SSHKeySync, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.SSHKeySyncDataProperty, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.SyncWithoutTargetName, useClusterSecretStore(prov)), + framework.Compose(withReferencedIRSA, f, common.JSONDataWithoutTargetName, useClusterSecretStore(prov)), + ) +}) + +// here we create a central eso instance in the default namespace +// that mounts the service account which was created by terraform. +var _ = Describe("[awsmanaged] with mounted IRSA", Label("aws", "secretsmanager", "managed"), func() { + f := framework.New("eso-aws-managed") + prov := NewFromEnv(f) + + // each test case gets its own ESO instance + BeforeEach(func() { + f.Install(addon.NewESO( + addon.WithControllerClass(f.BaseName), + addon.WithServiceAccount(prov.ServiceAccountName), + addon.WithReleaseName(f.Namespace.Name), + addon.WithNamespace("default"), + )) + }) + + DescribeTable("sync secrets", + framework.TableFunc(f, + prov), + framework.Compose(withMountedIRSA, f, common.SimpleDataSync, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.NestedJSONWithGJSON, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.JSONDataFromSync, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.JSONDataWithProperty, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.JSONDataWithTemplate, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.DockerJSONConfig, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.DataPropertyDockerconfigJSON, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.SSHKeySync, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.SSHKeySyncDataProperty, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.SyncWithoutTargetName, useMountedIRSAStore(prov)), + framework.Compose(withMountedIRSA, f, common.JSONDataWithoutTargetName, useMountedIRSAStore(prov)), + ) +}) + +func useClusterSecretStore(prov *SMProvider) func(*framework.TestCase) { + return func(tc *framework.TestCase) { + tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.ClusterSecretStoreKind + tc.ExternalSecret.Spec.SecretStoreRef.Name = prov.ReferencedIRSAStoreName() + } +} + +func useMountedIRSAStore(prov *SMProvider) func(*framework.TestCase) { + return func(tc *framework.TestCase) { + tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.SecretStoreKind + tc.ExternalSecret.Spec.SecretStoreRef.Name = prov.MountedIRSAStoreName() + } +} diff --git a/e2e/suite/azure/azure.go b/e2e/suite/azure/azure.go index d1c57b1e8..79a96aef5 100644 --- a/e2e/suite/azure/azure.go +++ b/e2e/suite/azure/azure.go @@ -13,28 +13,17 @@ limitations under the License. package azure import ( - "os" // nolint - . "github.com/onsi/ginkgo" - // nolint - . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/ginkgo/v2" "github.com/external-secrets/external-secrets/e2e/framework" "github.com/external-secrets/external-secrets/e2e/suite/common" ) -var _ = Describe("[azure] ", func() { +var _ = Describe("[azure]", Label("azure", "keyvault"), func() { f := framework.New("eso-azure") - vaultURL := os.Getenv("VAULT_URL") - tenantID := os.Getenv("TENANT_ID") - clientID := os.Getenv("AZURE_CLIENT_ID") - clientSecret := os.Getenv("AZURE_CLIENT_SECRET") - prov := &azureProvider{} - - if vaultURL != "" && tenantID != "" && clientID != "" && clientSecret != "" { - prov = newazureProvider(f, clientID, clientSecret, tenantID, vaultURL) - } + prov := newFromEnv(f) DescribeTable("sync secrets", framework.TableFunc(f, prov), Entry(common.SimpleDataSync(f)), diff --git a/e2e/suite/azure/provider.go b/e2e/suite/azure/provider.go index a3d312303..7354176db 100644 --- a/e2e/suite/azure/provider.go +++ b/e2e/suite/azure/provider.go @@ -14,15 +14,17 @@ package azure import ( "context" + "os" "github.com/Azure/azure-sdk-for-go/profiles/latest/keyvault/keyvault" kvauth "github.com/Azure/go-autorest/autorest/azure/auth" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" // nolint - . "github.com/onsi/gomega" + . "github.com/onsi/ginkgo/v2" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilpointer "k8s.io/utils/pointer" @@ -45,7 +47,9 @@ func newazureProvider(f *framework.Framework, clientID, clientSecret, tenantID, clientCredentialsConfig := kvauth.NewClientCredentialsConfig(clientID, clientSecret, tenantID) clientCredentialsConfig.Resource = "https://vault.azure.net" authorizer, err := clientCredentialsConfig.Authorizer() - Expect(err).ToNot(HaveOccurred()) + if err != nil { + Fail(err.Error()) + } basicClient := keyvault.New() basicClient.Authorizer = authorizer @@ -57,10 +61,22 @@ func newazureProvider(f *framework.Framework, clientID, clientSecret, tenantID, vaultURL: vaultURL, client: &basicClient, } - BeforeEach(prov.BeforeEach) + + BeforeEach(func() { + prov.CreateSecretStore() + }) + return prov } +func newFromEnv(f *framework.Framework) *azureProvider { + vaultURL := os.Getenv("VAULT_URL") + tenantID := os.Getenv("TENANT_ID") + clientID := os.Getenv("AZURE_CLIENT_ID") + clientSecret := os.Getenv("AZURE_CLIENT_SECRET") + return newazureProvider(f, clientID, clientSecret, tenantID, vaultURL) +} + func (s *azureProvider) CreateSecret(key, val string) { _, err := s.client.SetSecret( context.Background(), @@ -84,7 +100,7 @@ func (s *azureProvider) DeleteSecret(key string) { Expect(err).ToNot(HaveOccurred()) } -func (s *azureProvider) BeforeEach() { +func (s *azureProvider) CreateSecretStore() { azureCreds := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "provider-secret", diff --git a/e2e/suite/gcp/gcp.go b/e2e/suite/gcp/gcp.go index 2f274c8d2..82c1caead 100644 --- a/e2e/suite/gcp/gcp.go +++ b/e2e/suite/gcp/gcp.go @@ -17,12 +17,9 @@ import ( "crypto/x509" "encoding/pem" "fmt" - "os" // nolint - . "github.com/onsi/ginkgo" - // nolint - . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/ginkgo/v2" v1 "k8s.io/api/core/v1" p12 "software.sslmate.com/src/go-pkcs12" @@ -32,21 +29,32 @@ import ( "github.com/external-secrets/external-secrets/e2e/suite/common" ) -var _ = Describe("[gcp] ", func() { +// This test uses the global ESO. +var _ = Describe("[gcp]", Label("gcp", "secretsmanager"), func() { f := framework.New("eso-gcp") - credentials := os.Getenv("GCP_SM_SA_JSON") - projectID := os.Getenv("GCP_PROJECT_ID") - prov := &GcpProvider{} + prov := NewFromEnv(f, "") - if credentials != "" && projectID != "" { - prov = NewgcpProvider(f, credentials, projectID, "", "", "", "") - } + DescribeTable("sync secrets", framework.TableFunc(f, prov), + Entry(common.SimpleDataSync(f)), + Entry(common.JSONDataWithProperty(f)), + Entry(common.JSONDataFromSync(f)), + Entry(common.NestedJSONWithGJSON(f)), + Entry(common.JSONDataWithTemplate(f)), + Entry(common.DockerJSONConfig(f)), + Entry(common.DataPropertyDockerconfigJSON(f)), + Entry(common.SSHKeySync(f)), + Entry(common.SSHKeySyncDataProperty(f)), + Entry(common.SyncWithoutTargetName(f)), + Entry(common.JSONDataWithoutTargetName(f)), + Entry("should sync p12 encoded cert secret", p12Cert), + ) +}) - // P12Cert case creates a secret with a p12 cert containing a privkey and cert bundled together. - // It uses templating to generate a k8s secret of type tls with pem values - p12Cert := func(tc *framework.TestCase) { - cloudSecretName := fmt.Sprintf("%s-%s", f.Namespace.Name, "p12-cert-example") - certPEM := `-----BEGIN CERTIFICATE----- +// P12Cert case creates a secret with a p12 cert containing a privkey and cert bundled together. +// It uses templating to generate a k8s secret of type tls with pem values. +var p12Cert = func(tc *framework.TestCase) { + cloudSecretName := fmt.Sprintf("%s-%s", tc.Framework.Namespace.Name, "p12-cert-example") + certPEM := `-----BEGIN CERTIFICATE----- MIIFQjCCBCqgAwIBAgISBHszg5W2maz/7CIxGrf7mqukMA0GCSqGSIb3DQEBCwUA MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD EwJSMzAeFw0yMTA3MjQxMjQyMzNaFw0yMTEwMjIxMjQyMzFaMCgxJjAkBgNVBAMT @@ -78,7 +86,7 @@ XMYitHfpGhc+DTTiTWMQ13J0b1j4yv8A7ZaG2366aa28oSTD6eQFhmVCBwa54j++ IOwzHn5R -----END CERTIFICATE----- ` - privkeyPEM := `-----BEGIN PRIVATE KEY----- + privkeyPEM := `-----BEGIN PRIVATE KEY----- MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDJFE51myQDyqca egyBDlHLkxVj+WCjcfOWEqrTa7bcnbDXjD4uIRTaFxIkpi/k5fKxt+rszna7bNdh lezqSuRBmVg2kXDul5nQm1RtWRKlJP9fhvUYkoNKRGzt9OL6/6lv05P2tNu13yN8 @@ -107,55 +115,39 @@ Jdx0ECYawviQoreDAyIXV6HouoeRbDtLZ9AJvxMoIjGcjAR2FQHc3yx4h/lf3Tfx x6HaRh+EUwU51von6M9lEF9/p5Q= -----END PRIVATE KEY----- ` - blockCert, _ := pem.Decode([]byte(certPEM)) - cert, _ := x509.ParseCertificate(blockCert.Bytes) - blockPrivKey, _ := pem.Decode([]byte(privkeyPEM)) - privkey, _ := x509.ParsePKCS8PrivateKey(blockPrivKey.Bytes) - emptyCACerts := []*x509.Certificate{} - p12Cert, _ := p12.Encode(rand.Reader, privkey, cert, emptyCACerts, "") + blockCert, _ := pem.Decode([]byte(certPEM)) + cert, _ := x509.ParseCertificate(blockCert.Bytes) + blockPrivKey, _ := pem.Decode([]byte(privkeyPEM)) + privkey, _ := x509.ParsePKCS8PrivateKey(blockPrivKey.Bytes) + emptyCACerts := []*x509.Certificate{} + p12Cert, _ := p12.Encode(rand.Reader, privkey, cert, emptyCACerts, "") - tc.Secrets = map[string]string{ - cloudSecretName: string(p12Cert), - } - - tc.ExpectedSecret = &v1.Secret{ - Type: v1.SecretTypeTLS, - Data: map[string][]byte{ - "tls.crt": []byte(certPEM), - "tls.key": []byte(privkeyPEM), - }, - } - - tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{ - { - SecretKey: "mysecret", - RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{ - Key: cloudSecretName, - }, - }, - } - - tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{ - Type: v1.SecretTypeTLS, - Data: map[string]string{ - "tls.crt": "{{ .mysecret | pkcs12cert | pemCertificate }}", - "tls.key": "{{ .mysecret | pkcs12key | pemPrivateKey }}", - }, - } + tc.Secrets = map[string]string{ + cloudSecretName: string(p12Cert), } - DescribeTable("sync secrets", framework.TableFunc(f, prov), - Entry(common.SimpleDataSync(f)), - Entry(common.JSONDataWithProperty(f)), - Entry(common.JSONDataFromSync(f)), - Entry(common.NestedJSONWithGJSON(f)), - Entry(common.JSONDataWithTemplate(f)), - Entry(common.DockerJSONConfig(f)), - Entry(common.DataPropertyDockerconfigJSON(f)), - Entry(common.SSHKeySync(f)), - Entry(common.SSHKeySyncDataProperty(f)), - Entry(common.SyncWithoutTargetName(f)), - Entry(common.JSONDataWithoutTargetName(f)), - Entry("should sync p12 encoded cert secret", p12Cert), - ) -}) + tc.ExpectedSecret = &v1.Secret{ + Type: v1.SecretTypeTLS, + Data: map[string][]byte{ + "tls.crt": []byte(certPEM), + "tls.key": []byte(privkeyPEM), + }, + } + + tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{ + { + SecretKey: "mysecret", + RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{ + Key: cloudSecretName, + }, + }, + } + + tc.ExternalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{ + Type: v1.SecretTypeTLS, + Data: map[string]string{ + "tls.crt": "{{ .mysecret | pkcs12cert | pemCertificate }}", + "tls.key": "{{ .mysecret | pkcs12key | pemPrivateKey }}", + }, + } +} diff --git a/e2e/suite/gcp/gcp_managed.go b/e2e/suite/gcp/gcp_managed.go new file mode 100644 index 000000000..7dea4dab6 --- /dev/null +++ b/e2e/suite/gcp/gcp_managed.go @@ -0,0 +1,111 @@ +/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +limitations under the License. +*/ +package gcp + +import ( + + // nolint + . "github.com/onsi/ginkgo/v2" + + // nolint + // . "github.com/onsi/gomega" + esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1" + "github.com/external-secrets/external-secrets/e2e/framework" + "github.com/external-secrets/external-secrets/e2e/framework/addon" + "github.com/external-secrets/external-secrets/e2e/suite/common" +) + +const ( + withPodID = "sync secrets with pod identity" + withSpecifcSA = "sync secrets with specificSA identity" +) + +// Deploys eso to the default namespace +// that uses the service account provisioned by terraform +// to test pod-identity authentication. +var _ = Describe("[gcpmanaged] with pod identity", Label("gcp", "secretsmanager", "managed", "pod-identity"), func() { + f := framework.New("eso-gcpmanaged") + prov := NewFromEnv(f, f.BaseName) + + // each test case gets its own ESO instance + BeforeEach(func() { + f.Install(addon.NewESO( + addon.WithControllerClass(f.BaseName), + addon.WithServiceAccount(prov.ServiceAccountName), + addon.WithReleaseName(f.Namespace.Name), + addon.WithNamespace("default"), + )) + }) + + DescribeTable("sync secrets", + framework.TableFunc(f, + prov), + // uses pod id + framework.Compose(withPodID, f, common.SimpleDataSync, usePodIDESReference), + framework.Compose(withPodID, f, common.JSONDataWithProperty, usePodIDESReference), + framework.Compose(withPodID, f, common.JSONDataFromSync, usePodIDESReference), + framework.Compose(withPodID, f, common.NestedJSONWithGJSON, usePodIDESReference), + framework.Compose(withPodID, f, common.JSONDataWithTemplate, usePodIDESReference), + framework.Compose(withPodID, f, common.DockerJSONConfig, usePodIDESReference), + framework.Compose(withPodID, f, common.DataPropertyDockerconfigJSON, usePodIDESReference), + framework.Compose(withPodID, f, common.SSHKeySync, usePodIDESReference), + framework.Compose(withPodID, f, common.SSHKeySyncDataProperty, usePodIDESReference), + framework.Compose(withPodID, f, common.SyncWithoutTargetName, usePodIDESReference), + framework.Compose(withPodID, f, common.JSONDataWithoutTargetName, usePodIDESReference), + ) +}) + +// We're using a namespace scoped ESO +// that runs WITHOUT pod identity (with default sa) +// It uses a specific service account defined in the ClusterSecretStore spec +// to authenticate against cloud provider APIs. +var _ = Describe("[gcpmanaged] with service account", Label("gcp", "secretsmanager", "managed", "service-account"), func() { + f := framework.New("eso-gcpmanaged") + prov := NewFromEnv(f, f.BaseName) + + BeforeEach(func() { + f.Install(addon.NewESO( + addon.WithControllerClass(f.BaseName), + addon.WithReleaseName(f.Namespace.Name), + addon.WithNamespace(f.Namespace.Name), + )) + }) + + DescribeTable("sync secrets", + framework.TableFunc(f, + prov), + // uses specific sa + framework.Compose(withSpecifcSA, f, common.JSONDataFromSync, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.JSONDataWithProperty, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.JSONDataFromSync, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.NestedJSONWithGJSON, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.JSONDataWithTemplate, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.DockerJSONConfig, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.DataPropertyDockerconfigJSON, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.SSHKeySync, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.SSHKeySyncDataProperty, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.SyncWithoutTargetName, useSpecifcSAESReference(prov)), + framework.Compose(withSpecifcSA, f, common.JSONDataWithoutTargetName, useSpecifcSAESReference(prov)), + ) +}) + +func usePodIDESReference(tc *framework.TestCase) { + tc.ExternalSecret.Spec.SecretStoreRef.Name = PodIDSecretStoreName +} + +func useSpecifcSAESReference(prov *GcpProvider) func(*framework.TestCase) { + return func(tc *framework.TestCase) { + tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.ClusterSecretStoreKind + tc.ExternalSecret.Spec.SecretStoreRef.Name = prov.SAClusterSecretStoreName() + } +} diff --git a/e2e/suite/gcp/provider.go b/e2e/suite/gcp/provider.go index bb5ef5d71..7e20b16b2 100644 --- a/e2e/suite/gcp/provider.go +++ b/e2e/suite/gcp/provider.go @@ -15,116 +15,97 @@ package gcp import ( "context" "fmt" + "os" secretmanager "cloud.google.com/go/secretmanager/apiv1" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint . "github.com/onsi/gomega" - "golang.org/x/oauth2" "golang.org/x/oauth2/google" "golang.org/x/oauth2/jwt" "google.golang.org/api/option" secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1" v1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" utilpointer "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1" esmeta "github.com/external-secrets/external-secrets/apis/meta/v1" "github.com/external-secrets/external-secrets/e2e/framework" - "github.com/external-secrets/external-secrets/e2e/framework/log" gcpsm "github.com/external-secrets/external-secrets/pkg/provider/gcp/secretmanager" ) const ( - PodIDSecretStoreName = "pod-identity" - SpecifcSASecretStoreName = "specific-sa" + PodIDSecretStoreName = "pod-identity" + staticCredentialsSecretName = "provider-secret" ) -func makeStore(s *GcpProvider) *esv1alpha1.SecretStore { - return &esv1alpha1.SecretStore{ - ObjectMeta: metav1.ObjectMeta{ - Name: s.framework.Namespace.Name, - Namespace: s.framework.Namespace.Name, - }, - Spec: esv1alpha1.SecretStoreSpec{ - Provider: &esv1alpha1.SecretStoreProvider{ - GCPSM: &esv1alpha1.GCPSMProvider{ - ProjectID: s.projectID, - }, - }, - }, - } -} - -func makeCStore(s *GcpProvider) *esv1alpha1.ClusterSecretStore { - return &esv1alpha1.ClusterSecretStore{ - ObjectMeta: metav1.ObjectMeta{ - Name: s.framework.Namespace.Name, - Namespace: s.framework.Namespace.Name, - }, - Spec: esv1alpha1.SecretStoreSpec{ - Provider: &esv1alpha1.SecretStoreProvider{ - GCPSM: &esv1alpha1.GCPSMProvider{ - ProjectID: s.projectID, - }, - }, - }, - } -} - // nolint // Better to keep names consistent even if it stutters; type GcpProvider struct { - credentials string - projectID string - framework *framework.Framework - clusterLocation string - clusterName string - serviceAccountName string - serviceAccountNamespace string + ServiceAccountName string + ServiceAccountNamespace string + + framework *framework.Framework + credentials string + projectID string + clusterLocation string + clusterName string + controllerClass string } -func NewgcpProvider(f *framework.Framework, credentials, projectID string, - clusterLocation string, clusterName string, serviceAccountName string, serviceAccountNamespace string) *GcpProvider { +func NewGCPProvider(f *framework.Framework, credentials, projectID string, + clusterLocation string, clusterName string, serviceAccountName string, serviceAccountNamespace string, controllerClass string) *GcpProvider { prov := &GcpProvider{ credentials: credentials, projectID: projectID, framework: f, clusterLocation: clusterLocation, clusterName: clusterName, - serviceAccountName: serviceAccountName, - serviceAccountNamespace: serviceAccountNamespace, + ServiceAccountName: serviceAccountName, + ServiceAccountNamespace: serviceAccountNamespace, + controllerClass: controllerClass, } - BeforeEach(prov.BeforeEach) + + BeforeEach(func() { + prov.CreateSAKeyStore(f.Namespace.Name) + prov.CreateSpecifcSASecretStore(f.Namespace.Name) + prov.CreatePodIDStore(f.Namespace.Name) + }) + + AfterEach(func() { + prov.DeleteSpecifcSASecretStore() + }) + return prov } -func (s *GcpProvider) getClient(ctx context.Context, credentials string) (client *secretmanager.Client, err error) { - if credentials == "" { - var ts oauth2.TokenSource - ts, err = google.DefaultTokenSource(ctx, gcpsm.CloudPlatformRole) - Expect(err).ToNot(HaveOccurred()) - client, err = secretmanager.NewClient(ctx, option.WithTokenSource(ts)) - Expect(err).ToNot(HaveOccurred()) - } else { - var config *jwt.Config - config, err = google.JWTConfigFromJSON([]byte(s.credentials), gcpsm.CloudPlatformRole) - Expect(err).ToNot(HaveOccurred()) - ts := config.TokenSource(ctx) - client, err = secretmanager.NewClient(ctx, option.WithTokenSource(ts)) - Expect(err).ToNot(HaveOccurred()) - } +func NewFromEnv(f *framework.Framework, controllerClass string) *GcpProvider { + projectID := os.Getenv("GCP_PROJECT_ID") + credentials := os.Getenv("GCP_SM_SA_JSON") + serviceAccountName := os.Getenv("GCP_KSA_NAME") + serviceAccountNamespace := "default" + clusterLocation := os.Getenv("GCP_GKE_ZONE") + clusterName := os.Getenv("GCP_GKE_CLUSTER") + return NewGCPProvider(f, credentials, projectID, clusterLocation, clusterName, serviceAccountName, serviceAccountNamespace, controllerClass) +} + +func (s *GcpProvider) getClient(ctx context.Context) (client *secretmanager.Client, err error) { + var config *jwt.Config + config, err = google.JWTConfigFromJSON([]byte(s.credentials), gcpsm.CloudPlatformRole) + Expect(err).ToNot(HaveOccurred()) + ts := config.TokenSource(ctx) + client, err = secretmanager.NewClient(ctx, option.WithTokenSource(ts)) + Expect(err).ToNot(HaveOccurred()) return client, err } func (s *GcpProvider) CreateSecret(key, val string) { ctx := context.Background() - client, err := s.getClient(ctx, s.credentials) + client, err := s.getClient(ctx) Expect(err).ToNot(HaveOccurred()) defer client.Close() // Create the request to create the secret. @@ -153,7 +134,7 @@ func (s *GcpProvider) CreateSecret(key, val string) { func (s *GcpProvider) DeleteSecret(key string) { ctx := context.Background() - client, err := s.getClient(ctx, s.credentials) + client, err := s.getClient(ctx) Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred()) defer client.Close() @@ -164,11 +145,27 @@ func (s *GcpProvider) DeleteSecret(key string) { Expect(err).ToNot(HaveOccurred()) } -func (s *GcpProvider) BeforeEach() { - By("creating a gcp secret") +func makeStore(s *GcpProvider) *esv1alpha1.SecretStore { + return &esv1alpha1.SecretStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.framework.Namespace.Name, + Namespace: s.framework.Namespace.Name, + }, + Spec: esv1alpha1.SecretStoreSpec{ + Controller: s.controllerClass, + Provider: &esv1alpha1.SecretStoreProvider{ + GCPSM: &esv1alpha1.GCPSMProvider{ + ProjectID: s.projectID, + }, + }, + }, + } +} + +func (s *GcpProvider) CreateSAKeyStore(ns string) { gcpCreds := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: "provider-secret", + Name: staticCredentialsSecretName, Namespace: s.framework.Namespace.Name, }, StringData: map[string]string{ @@ -180,23 +177,16 @@ func (s *GcpProvider) BeforeEach() { err = s.framework.CRClient.Update(context.Background(), gcpCreds) Expect(err).ToNot(HaveOccurred()) } - By("creating an secret stores gcp") - s.CreateSAKeyStore(s.framework.Namespace.Name) - s.CreatePodIDStore(s.framework.Namespace.Name) - s.CreateSpecifcSASecretStore(s.framework.Namespace.Name) -} - -func (s *GcpProvider) CreateSAKeyStore(ns string) { secretStore := makeStore(s) secretStore.Spec.Provider.GCPSM.Auth = esv1alpha1.GCPSMAuth{ SecretRef: &esv1alpha1.GCPSMAuthSecretRef{ SecretAccessKey: esmeta.SecretKeySelector{ - Name: "provider-secret", + Name: staticCredentialsSecretName, Key: "secret-access-credentials", }, }, } - err := s.framework.CRClient.Create(context.Background(), secretStore) + err = s.framework.CRClient.Create(context.Background(), secretStore) Expect(err).ToNot(HaveOccurred()) } @@ -207,29 +197,45 @@ func (s *GcpProvider) CreatePodIDStore(ns string) { Expect(err).ToNot(HaveOccurred()) } +func (s *GcpProvider) SAClusterSecretStoreName() string { + return "gcpsa-" + s.framework.Namespace.Name +} + func (s *GcpProvider) CreateSpecifcSASecretStore(ns string) { - clusterSecretStore := makeCStore(s) - clusterSecretStore.ObjectMeta.Name = SpecifcSASecretStoreName - clusterSecretStore.Spec.Provider.GCPSM.Auth = esv1alpha1.GCPSMAuth{ - WorkloadIdentity: &esv1alpha1.GCPWorkloadIdentity{ - ClusterLocation: s.clusterLocation, - ClusterName: s.clusterName, - ServiceAccountRef: esmeta.ServiceAccountSelector{ - Name: s.serviceAccountName, - Namespace: utilpointer.StringPtr(s.serviceAccountNamespace), - }, + clusterSecretStore := &esv1alpha1.ClusterSecretStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.SAClusterSecretStoreName(), }, } - - var cSS esv1alpha1.ClusterSecretStore - - err := s.framework.CRClient.Get(context.Background(), types.NamespacedName{ - Name: SpecifcSASecretStoreName, - }, &cSS) - if apierrors.IsNotFound(err) { - err := s.framework.CRClient.Create(context.Background(), clusterSecretStore) - Expect(err).ToNot(HaveOccurred()) - } else { - log.Logf("%s CSStore already created", SpecifcSASecretStoreName) - } + _, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, clusterSecretStore, func() error { + clusterSecretStore.Spec.Controller = s.controllerClass + clusterSecretStore.Spec.Provider = &esv1alpha1.SecretStoreProvider{ + GCPSM: &esv1alpha1.GCPSMProvider{ + ProjectID: s.projectID, + Auth: esv1alpha1.GCPSMAuth{ + WorkloadIdentity: &esv1alpha1.GCPWorkloadIdentity{ + ClusterLocation: s.clusterLocation, + ClusterName: s.clusterName, + ServiceAccountRef: esmeta.ServiceAccountSelector{ + Name: s.ServiceAccountName, + Namespace: utilpointer.StringPtr(s.ServiceAccountNamespace), + }, + }, + }, + }, + } + return nil + }) + Expect(err).ToNot(HaveOccurred()) +} + +// Cleanup removes global resources that may have been +// created by this provider. +func (s *GcpProvider) DeleteSpecifcSASecretStore() { + err := s.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{ + ObjectMeta: metav1.ObjectMeta{ + Name: s.SAClusterSecretStoreName(), + }, + }) + Expect(err).ToNot(HaveOccurred()) } diff --git a/e2e/suite/gcpmanaged/gcpmanaged.go b/e2e/suite/gcpmanaged/gcpmanaged.go deleted file mode 100644 index 67001af16..000000000 --- a/e2e/suite/gcpmanaged/gcpmanaged.go +++ /dev/null @@ -1,86 +0,0 @@ -/* -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -limitations under the License. -*/ -package gcpmanaged - -import ( - "os" - - // nolint - . "github.com/onsi/ginkgo" - // nolint - . "github.com/onsi/ginkgo/extensions/table" - - // nolint - // . "github.com/onsi/gomega" - esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1" - "github.com/external-secrets/external-secrets/e2e/framework" - "github.com/external-secrets/external-secrets/e2e/suite/common" - "github.com/external-secrets/external-secrets/e2e/suite/gcp" -) - -const ( - withPodID = "sync secrets with pod identity" - withSpecifcSA = "sync secrets with specificSA identity" -) - -var _ = Describe("[gcpmanaged] ", func() { - if os.Getenv("FOCUS") == "gcpmanaged" { - f := framework.New("eso-gcp-managed") - projectID := os.Getenv("GCP_PROJECT_ID") - clusterLocation := "europe-west1-b" - clusterName := "test-cluster" - serviceAccountName := os.Getenv("GCP_KSA_NAME") - serviceAccountNamespace := "default" - prov := &gcp.GcpProvider{} - if projectID != "" { - prov = gcp.NewgcpProvider(f, "", projectID, clusterLocation, clusterName, serviceAccountName, serviceAccountNamespace) - } - DescribeTable("sync secrets", - framework.TableFunc(f, - prov), - // uses pod id - framework.Compose(withPodID, f, common.SimpleDataSync, usePodIDESReference), - framework.Compose(withPodID, f, common.JSONDataWithProperty, usePodIDESReference), - framework.Compose(withPodID, f, common.JSONDataFromSync, usePodIDESReference), - framework.Compose(withPodID, f, common.NestedJSONWithGJSON, usePodIDESReference), - framework.Compose(withPodID, f, common.JSONDataWithTemplate, usePodIDESReference), - framework.Compose(withPodID, f, common.DockerJSONConfig, usePodIDESReference), - framework.Compose(withPodID, f, common.DataPropertyDockerconfigJSON, usePodIDESReference), - framework.Compose(withPodID, f, common.SSHKeySync, usePodIDESReference), - framework.Compose(withPodID, f, common.SSHKeySyncDataProperty, usePodIDESReference), - framework.Compose(withPodID, f, common.SyncWithoutTargetName, usePodIDESReference), - framework.Compose(withPodID, f, common.JSONDataWithoutTargetName, usePodIDESReference), - // uses specific sa - framework.Compose(withSpecifcSA, f, common.JSONDataFromSync, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.JSONDataWithProperty, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.JSONDataFromSync, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.NestedJSONWithGJSON, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.JSONDataWithTemplate, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.DockerJSONConfig, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.DataPropertyDockerconfigJSON, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.SSHKeySync, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.SSHKeySyncDataProperty, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.SyncWithoutTargetName, useSpecifcSAESReference), - framework.Compose(withSpecifcSA, f, common.JSONDataWithoutTargetName, useSpecifcSAESReference), - ) - } -}) - -func usePodIDESReference(tc *framework.TestCase) { - tc.ExternalSecret.Spec.SecretStoreRef.Name = gcp.PodIDSecretStoreName -} - -func useSpecifcSAESReference(tc *framework.TestCase) { - tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.ClusterSecretStoreKind - tc.ExternalSecret.Spec.SecretStoreRef.Name = gcp.SpecifcSASecretStoreName -} diff --git a/e2e/suite/gitlab/gitlab.go b/e2e/suite/gitlab/gitlab.go index 0f643eb84..a80b1f5b7 100644 --- a/e2e/suite/gitlab/gitlab.go +++ b/e2e/suite/gitlab/gitlab.go @@ -18,27 +18,19 @@ package gitlab // and in e2e/suite/common/common.go, but this breaks Azure provider. import ( - "os" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint - . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/ginkgo/v2/extensions/table" "github.com/external-secrets/external-secrets/e2e/framework" "github.com/external-secrets/external-secrets/e2e/suite/common" ) -var _ = Describe("[gitlab] ", func() { - f := framework.New("esogitlab") - credentials := os.Getenv("GITLAB_TOKEN") - projectID := os.Getenv("GITLAB_PROJECT_ID") - - prov := &gitlabProvider{} - - if credentials != "" && projectID != "" { - prov = newGitlabProvider(f, credentials, projectID) - } +var _ = Describe("[gitlab]", Label("gitlab"), func() { + f := framework.New("eso-gitlab") + prov := newFromEnv(f) DescribeTable("sync secrets", framework.TableFunc(f, prov), Entry(common.SimpleDataSync(f)), diff --git a/e2e/suite/gitlab/provider.go b/e2e/suite/gitlab/provider.go index deff8c6ff..4dde4bb17 100644 --- a/e2e/suite/gitlab/provider.go +++ b/e2e/suite/gitlab/provider.go @@ -15,10 +15,11 @@ package gitlab import ( "context" + "os" "strings" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint . "github.com/onsi/gomega" @@ -47,6 +48,12 @@ func newGitlabProvider(f *framework.Framework, credentials, projectID string) *g return prov } +func newFromEnv(f *framework.Framework) *gitlabProvider { + credentials := os.Getenv("GITLAB_TOKEN") + projectID := os.Getenv("GITLAB_PROJECT_ID") + return newGitlabProvider(f, credentials, projectID) +} + func (s *gitlabProvider) CreateSecret(key, val string) { // **Open the client client, err := gitlab.NewClient(s.credentials) diff --git a/e2e/suite/import.go b/e2e/suite/import.go index eb53c7b28..fd9c332f8 100644 --- a/e2e/suite/import.go +++ b/e2e/suite/import.go @@ -19,6 +19,5 @@ import ( _ "github.com/external-secrets/external-secrets/e2e/suite/aws" _ "github.com/external-secrets/external-secrets/e2e/suite/azure" _ "github.com/external-secrets/external-secrets/e2e/suite/gcp" - _ "github.com/external-secrets/external-secrets/e2e/suite/gcpmanaged" _ "github.com/external-secrets/external-secrets/e2e/suite/vault" ) diff --git a/e2e/suite/oracle/oracle.go b/e2e/suite/oracle/oracle.go index 91f2f7568..36bb425c3 100644 --- a/e2e/suite/oracle/oracle.go +++ b/e2e/suite/oracle/oracle.go @@ -13,25 +13,19 @@ limitations under the License. package oracle import ( - "os" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint - . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/ginkgo/v2/extensions/table" "github.com/external-secrets/external-secrets/e2e/framework" "github.com/external-secrets/external-secrets/e2e/suite/common" ) -var _ = Describe("[oracle] ", func() { +var _ = Describe("[oracle]", Label("oracle"), func() { f := framework.New("eso-oracle") - tenancy := os.Getenv("OCI_TENANCY_OCID") - user := os.Getenv("OCI_USER_OCID") - region := os.Getenv("OCI_REGION") - fingerprint := os.Getenv("OCI_FINGERPRINT") - privateKey := os.Getenv("OCI_PRIVATE_KEY") - prov := newOracleProvider(f, tenancy, user, region, fingerprint, privateKey) + prov := newFromEnv(f) DescribeTable("sync secrets", framework.TableFunc(f, prov), Entry(common.SimpleDataSync(f)), diff --git a/e2e/suite/oracle/provider.go b/e2e/suite/oracle/provider.go index 243ca3e5a..66d4d5b5c 100644 --- a/e2e/suite/oracle/provider.go +++ b/e2e/suite/oracle/provider.go @@ -14,9 +14,10 @@ package oracle import ( "context" + "os" // nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" // nolint . "github.com/onsi/gomega" @@ -58,6 +59,15 @@ func newOracleProvider(f *framework.Framework, tenancy, user, region, fingerprin return prov } +func newFromEnv(f *framework.Framework) *oracleProvider { + tenancy := os.Getenv("OCI_TENANCY_OCID") + user := os.Getenv("OCI_USER_OCID") + region := os.Getenv("OCI_REGION") + fingerprint := os.Getenv("OCI_FINGERPRINT") + privateKey := os.Getenv("OCI_PRIVATE_KEY") + return newOracleProvider(f, tenancy, user, region, fingerprint, privateKey) +} + func (p *oracleProvider) CreateSecret(key, val string) { configurationProvider := common.NewRawConfigurationProvider(p.tenancy, p.user, p.region, p.fingerprint, p.privateKey, nil) client, err := vault.NewVaultsClientWithConfigurationProvider(configurationProvider) diff --git a/e2e/suite/vault/provider.go b/e2e/suite/vault/provider.go index b5fbef3ee..262302ae6 100644 --- a/e2e/suite/vault/provider.go +++ b/e2e/suite/vault/provider.go @@ -21,7 +21,7 @@ import ( vault "github.com/hashicorp/vault/api" //nolint - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" //nolint . "github.com/onsi/gomega" diff --git a/e2e/suite/vault/vault.go b/e2e/suite/vault/vault.go index 4fafd1c22..b42167aec 100644 --- a/e2e/suite/vault/vault.go +++ b/e2e/suite/vault/vault.go @@ -15,9 +15,7 @@ package vault import ( // nolint - . "github.com/onsi/ginkgo" - // nolint - . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/ginkgo/v2" "github.com/external-secrets/external-secrets/e2e/framework" "github.com/external-secrets/external-secrets/e2e/suite/common" @@ -32,12 +30,12 @@ const ( withK8s = "with kubernetes provider" ) -var _ = Describe("[vault] ", func() { +var _ = Describe("[vault]", Label("vault"), func() { f := framework.New("eso-vault") + prov := newVaultProvider(f) DescribeTable("sync secrets", - framework.TableFunc(f, - newVaultProvider(f)), + framework.TableFunc(f, prov), // uses token auth framework.Compose(withTokenAuth, f, common.JSONDataFromSync, useTokenAuth), framework.Compose(withTokenAuth, f, common.JSONDataWithProperty, useTokenAuth), diff --git a/go.mod b/go.mod index 3a22bd5b2..9845e864f 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( cloud.google.com/go/secretmanager v1.0.0 github.com/Azure/azure-sdk-for-go v61.1.0+incompatible github.com/Azure/go-autorest/autorest/azure/auth v0.5.7 - github.com/IBM/go-sdk-core/v5 v5.8.0 + github.com/IBM/go-sdk-core/v5 v5.9.1 github.com/IBM/secrets-manager-go-sdk v1.0.31 github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect @@ -46,19 +46,18 @@ require ( github.com/ahmetb/gen-crd-api-reference-docs v0.3.0 github.com/akeylesslabs/akeyless-go-cloud-id v0.3.2 github.com/akeylesslabs/akeyless-go/v2 v2.15.24 - github.com/aliyun/alibaba-cloud-sdk-go v1.61.1192 + github.com/aliyun/alibaba-cloud-sdk-go v1.61.1458 github.com/aws/aws-sdk-go v1.38.6 github.com/crossplane/crossplane-runtime v0.15.1 github.com/go-logr/logr v1.2.2 github.com/golang-jwt/jwt/v4 v4.2.0 - github.com/google/go-cmp v0.5.6 + github.com/google/go-cmp v0.5.7 github.com/google/uuid v1.2.0 github.com/googleapis/gax-go v1.0.3 - github.com/hashicorp/vault/api v1.0.5-0.20210224012239-b540be4b7ec4 + github.com/hashicorp/vault/api v1.3.1 github.com/huandu/xstrings v1.3.2 // indirect - github.com/kr/pretty v0.2.1 // indirect github.com/lestrrat-go/jwx v1.2.1 - github.com/onsi/ginkgo v1.16.5 + github.com/onsi/ginkgo/v2 v2.0.0 github.com/onsi/gomega v1.17.0 github.com/oracle/oci-go-sdk/v45 v45.2.0 github.com/prometheus/client_golang v1.11.0 @@ -70,10 +69,10 @@ require ( github.com/yandex-cloud/go-sdk v0.0.0-20210809100642-c13c40a429fa github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a go.uber.org/zap v1.20.0 - golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 + golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 google.golang.org/api v0.61.0 - google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 + google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5 google.golang.org/grpc v1.43.0 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b grpc.go4.org v0.0.0-20170609214715-11d0a25b4919 @@ -82,7 +81,7 @@ require ( k8s.io/client-go v0.23.0 k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b sigs.k8s.io/controller-runtime v0.11.0 - sigs.k8s.io/controller-tools v0.5.0 + sigs.k8s.io/controller-tools v0.8.0 software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78 ) @@ -98,9 +97,12 @@ require ( github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/BurntSushi/toml v0.3.1 // indirect github.com/PaesslerAG/gval v1.0.0 // indirect + github.com/armon/go-metrics v0.3.10 // indirect + github.com/armon/go-radix v1.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect github.com/aws/aws-sdk-go-v2 v0.23.0 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v3 v3.2.2 // indirect github.com/census-instrumentation/opencensus-proto v0.2.1 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect @@ -112,37 +114,46 @@ require ( github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 // indirect github.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/fatih/color v1.10.0 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect - github.com/frankban/quicktest v1.10.0 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-logr/zapr v1.2.0 // indirect github.com/go-openapi/errors v0.19.8 // indirect - github.com/go-openapi/strfmt v0.20.2 // indirect + github.com/go-openapi/strfmt v0.21.1 // indirect github.com/go-playground/locales v0.13.0 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect - github.com/gobuffalo/flect v0.2.2 // indirect + github.com/gobuffalo/flect v0.2.3 // indirect github.com/goccy/go-json v0.4.8 // 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.2 // indirect - github.com/golang/snappy v0.0.3 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/go-querystring v1.0.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect github.com/googleapis/gax-go/v2 v2.1.1 // indirect github.com/googleapis/gnostic v0.5.5 // indirect - github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v0.14.1 // indirect + github.com/hashicorp/go-hclog v1.1.0 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-plugin v1.4.3 // indirect github.com/hashicorp/go-retryablehttp v0.7.0 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-secure-stdlib/mlock v0.1.2 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.2 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect - github.com/hashicorp/hcl v1.0.1-vault // indirect - github.com/hashicorp/vault/sdk v0.1.14-0.20200519221838-e0cfd64bc267 // indirect + github.com/hashicorp/go-uuid v1.0.2 // indirect + github.com/hashicorp/go-version v1.4.0 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/hcl v1.0.1-vault-3 // indirect + github.com/hashicorp/vault/sdk v0.3.0 // indirect + github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect @@ -153,19 +164,20 @@ require ( github.com/lestrrat-go/httpcc v1.0.0 // indirect github.com/lestrrat-go/iter v1.0.1 // indirect github.com/lestrrat-go/option v1.0.0 // indirect - github.com/mattn/go-colorable v0.1.8 // indirect - github.com/mattn/go-isatty v0.0.12 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect - github.com/mitchellh/copystructure v1.0.0 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.4.1 // indirect - github.com/mitchellh/reflectwalk v1.0.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/nxadm/tail v1.4.8 // indirect + github.com/oklog/run v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/pierrec/lz4 v2.5.2+incompatible // indirect + github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/common v0.28.0 // indirect @@ -178,18 +190,18 @@ require ( github.com/stretchr/objx v0.2.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect - go.mongodb.org/mongo-driver v1.5.1 // indirect + go.mongodb.org/mongo-driver v1.7.5 // indirect go.opencensus.io v0.23.0 // indirect - go.uber.org/atomic v1.7.0 // indirect + go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.4.2 // indirect - golang.org/x/net v0.0.0-20210825183410-e898025ed96a // indirect - golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect + golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect golang.org/x/tools v0.1.7 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect @@ -197,9 +209,8 @@ require ( google.golang.org/protobuf v1.27.1 // indirect gopkg.in/go-playground/validator.v9 v9.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.62.0 // indirect - gopkg.in/square/go-jose.v2 v2.5.1 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/ini.v1 v1.66.2 // indirect + gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect honnef.co/go/tools v0.1.4 // indirect k8s.io/apiextensions-apiserver v0.23.0 // indirect diff --git a/go.sum b/go.sum index f1f5ab25b..e13b10d47 100644 --- a/go.sum +++ b/go.sum @@ -82,8 +82,9 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/IBM/go-sdk-core/v5 v5.8.0 h1:Bn9BxTaKYKWpd+BDpVsL6XOOJl4QDgxux4gSdWi31vE= github.com/IBM/go-sdk-core/v5 v5.8.0/go.mod h1:+YbdhrjCHC84ls4MeBp+Hj4NZCni+tDAc0XQUqRO9Jc= +github.com/IBM/go-sdk-core/v5 v5.9.1 h1:06pXbD9Rgmqqe2HA5YAeQbB4eYRRFgIoOT+Kh3cp1zo= +github.com/IBM/go-sdk-core/v5 v5.9.1/go.mod h1:axE2JrRq79gIJTjKPBwV6gWHswvVptBjbcvvCPIxARM= github.com/IBM/secrets-manager-go-sdk v1.0.31 h1:KRRyeEvlKkkZb90njgReOrK92+IyS6L19vpkzk27300= github.com/IBM/secrets-manager-go-sdk v1.0.31/go.mod h1:0Juj6ER/LpDqJ49nw705MNyXSHsHodgztFdkXz5ttxs= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -113,20 +114,23 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aliyun/alibaba-cloud-sdk-go v1.61.1192 h1:rRuMCkcoxoQ/kWSBN190JmD292PrYnpl7KyRWhYrjnY= -github.com/aliyun/alibaba-cloud-sdk-go v1.61.1192/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1458 h1:pMdm+s6k9yeAYJNqgZIpZcDBuh2SNR3Q137G9rpxDZc= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.1458/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= 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-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= +github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo= +github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= -github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.38.6 h1:h0AKIaz/A1kEJ50HxCv7tL1GW+KbxYbp75+lZ/nvFOI= github.com/aws/aws-sdk-go v1.38.6/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= @@ -145,6 +149,9 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= +github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M= +github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= @@ -223,17 +230,20 @@ github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMi github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/frankban/quicktest v1.10.0 h1:Gfh+GAJZOAoKZsIZeZbdn2JF10kN1XHNvjsvQK8gVkE= github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= +github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= +github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= @@ -249,7 +259,7 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-ldap/ldap/v3 v3.1.3/go.mod h1:3rbOH3jRS2u6jg2rJnKAMLE/xQyCKIveG2Sa/Cohzb8= +github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= @@ -268,8 +278,9 @@ github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34 github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/strfmt v0.20.2 h1:6XZL+fF4VZYFxKQGLAUB358hOrRh/wS51uWEtlONADE= github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= +github.com/go-openapi/strfmt v0.21.1 h1:G6s2t5V5kGCHLVbSdZ/6lI8Wm4OzoPFkc3/cjAsKQrM= +github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= @@ -281,7 +292,6 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= 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-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= @@ -293,8 +303,8 @@ github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598 github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= -github.com/gobuffalo/flect v0.2.2 h1:PAVD7sp0KOdfswjAw9BpLCU9hXo7wFSzgpQ+zNeks/A= -github.com/gobuffalo/flect v0.2.2/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= +github.com/gobuffalo/flect v0.2.3 h1:f/ZukRnSNA/DUpSNDadko7Qc0PhGvsew35p/2tu+CRY= +github.com/gobuffalo/flect v0.2.3/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= @@ -359,8 +369,9 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= @@ -377,8 +388,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -400,8 +412,10 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -419,7 +433,6 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0 github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -431,26 +444,29 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 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 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= -github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.1.0 h1:QsGcniKx5/LuX2eYoeL+Np3UKYPNaN7YKpTh29h8rbw= +github.com/hashicorp/go-hclog v1.1.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= 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-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-plugin v1.4.3 h1:DXmvivbWD5qdiBts9TpBC7BYL1Aia5sxbRgQB+v6UZM= +github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= @@ -460,30 +476,49 @@ github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= +github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= +github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/mlock v0.1.2 h1:p4AKXPPS24tO8Wc8i1gLvSKdmkiSY5xuju57czJ/IJQ= +github.com/hashicorp/go-secure-stdlib/mlock v0.1.2/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.2 h1:Tz6v3Jb2DRnDCfifRSjYKG0m8dLdNq6bcDkB41en7nw= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.2/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= 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-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= +github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl v1.0.1-vault h1:UiJeEzCWAYdVaJr8Xo4lBkTozlW1+1yxVUnpbS1xVEk= -github.com/hashicorp/hcl v1.0.1-vault/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl v1.0.1-vault-3 h1:V95v5KSTu6DB5huDSKiq4uAfILEuNigK/+qPET6H/Mg= +github.com/hashicorp/hcl v1.0.1-vault-3/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= 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/hashicorp/vault/api v1.0.5-0.20210224012239-b540be4b7ec4 h1:/N4wXZdB+zZfs0OtrJA1p0H1swAJmvdqa9e7sALMLaY= -github.com/hashicorp/vault/api v1.0.5-0.20210224012239-b540be4b7ec4/go.mod h1:R3Umvhlxi2TN7Ex2hzOowyeNb+SfbVWI973N+ctaFMk= -github.com/hashicorp/vault/sdk v0.1.14-0.20200519221838-e0cfd64bc267 h1:e1ok06zGrWJW91rzRroyl5nRNqraaBe4d5hiKcVZuHM= -github.com/hashicorp/vault/sdk v0.1.14-0.20200519221838-e0cfd64bc267/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10= +github.com/hashicorp/vault/api v1.3.1 h1:pkDkcgTh47PRjY1NEFeofqR4W/HkNUi9qIakESO2aRM= +github.com/hashicorp/vault/api v1.3.1/go.mod h1:QeJoWxMFt+MsuWcYhmwRLwKEXrjwAFFywzhptMsTIUw= +github.com/hashicorp/vault/sdk v0.3.0 h1:kR3dpxNkhh/wr6ycaJYqp6AFT/i2xaftbfnwZduTKEY= +github.com/hashicorp/vault/sdk v0.3.0/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -495,6 +530,8 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -508,13 +545,13 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/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.11/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 v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= @@ -525,6 +562,7 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +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/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= @@ -567,40 +605,47 @@ github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kN 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.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-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 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= 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/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/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= @@ -623,6 +668,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -630,17 +677,17 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= @@ -650,14 +697,15 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/oracle/oci-go-sdk/v45 v45.2.0 h1:vCPoQlE+DOrM2heJn66rvPU6fbsc/0Cxtzs2jnFut6U= github.com/oracle/oci-go-sdk/v45 v45.2.0/go.mod h1:ZM6LGiRO5TPQJxTlrXbcHMbClE775wnGD5U/EerCsRw= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -668,9 +716,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= 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.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= @@ -680,17 +728,17 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 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.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.28.0 h1:vGVfV9KrDTvWt5boZO0I19g2E3CsWfpPPKZM9dt3mEw= github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= @@ -718,10 +766,7 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= 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/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= @@ -733,7 +778,6 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 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.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1 h1:+KmjbUw1hriSNMF55oPrkZcb27aECyrj8V2ytv7kWDw= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= @@ -799,8 +843,9 @@ go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lL go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= -go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI= go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= +go.mongodb.org/mongo-driver v1.7.5 h1:ny3p0reEpgsR2cfA5cjgwFZg3Cv/ofFh/8jbhGtz9VI= +go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= 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= @@ -822,8 +867,9 @@ go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4 go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= @@ -842,7 +888,6 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf 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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= 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= @@ -854,8 +899,10 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= +golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190221220918-438050ddec5e/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -897,6 +944,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180530234432-1e491301e022/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= @@ -929,7 +977,6 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/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-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -946,8 +993,10 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a h1:bRuuGXV8wwSdGTB+CtJf+FjgO1APK1CoO39T4BN/XBw= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d h1:1n1fc535VhN8SYtD4cDUyNlfpAF2ROMM9+11equK3hs= +golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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= @@ -988,7 +1037,6 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h 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-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/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= @@ -1058,9 +1106,11 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= @@ -1081,8 +1131,9 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/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-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1131,7 +1182,6 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -1204,6 +1254,7 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1267,14 +1318,14 @@ google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5 h1:zzNejm+EgrbLfDZ6lu9Uud2IVvHySPl8vQzf04laR5Q= +google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1297,6 +1348,7 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -1329,15 +1381,16 @@ gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+a gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= 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.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= @@ -1407,8 +1460,8 @@ sigs.k8s.io/controller-runtime v0.9.2/go.mod h1:TxzMCHyEUpaeuOiZx/bIdc2T81vfs/aK sigs.k8s.io/controller-runtime v0.11.0 h1:DqO+c8mywcZLFJWILq4iktoECTyn30Bkj0CwgqMpZWQ= sigs.k8s.io/controller-runtime v0.11.0/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA= sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA= -sigs.k8s.io/controller-tools v0.5.0 h1:3u2RCwOlp0cjCALAigpOcbAf50pE+kHSdueUosrC/AE= -sigs.k8s.io/controller-tools v0.5.0/go.mod h1:JTsstrMpxs+9BUj6eGuAaEb6SDSPTeVtUyp0jmnAM/I= +sigs.k8s.io/controller-tools v0.8.0 h1:uUkfTGEwrguqYYfcI2RRGUnC8mYdCFDqfwPKUcNJh1o= +sigs.k8s.io/controller-tools v0.8.0/go.mod h1:qE2DXhVOiEq5ijmINcFbqi9GZrrUjzB1TuJU0xa6eoY= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= diff --git a/main.go b/main.go index 0286e3009..efcb2b566 100644 --- a/main.go +++ b/main.go @@ -56,7 +56,7 @@ func main() { "Enabling this will ensure there is only one active controller manager.") flag.IntVar(&concurrent, "concurrent", 1, "The number of concurrent ExternalSecret reconciles.") flag.StringVar(&loglevel, "loglevel", "info", "loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal") - flag.StringVar(&namespace, "namespace", "", "watch external secrets scoped in the provided namespace only") + flag.StringVar(&namespace, "namespace", "", "watch external secrets scoped in the provided namespace only. ClusterSecretStore can be used but only work if it doesn't reference resources from other namespaces") flag.Parse() var lvl zapcore.Level diff --git a/pkg/controllers/externalsecret/externalsecret_controller.go b/pkg/controllers/externalsecret/externalsecret_controller.go index 6867868e0..30609b319 100644 --- a/pkg/controllers/externalsecret/externalsecret_controller.go +++ b/pkg/controllers/externalsecret/externalsecret_controller.go @@ -22,6 +22,7 @@ import ( "github.com/go-logr/logr" "github.com/prometheus/client_golang/prometheus" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -263,10 +264,13 @@ func patchSecret(ctx context.Context, c client.Client, scheme *runtime.Scheme, s if err != nil { return fmt.Errorf(errPolicyMergeGetSecret, secret.Name, err) } + existing := secret.DeepCopyObject() + err = mutationFunc() if err != nil { return fmt.Errorf(errPolicyMergeMutate, secret.Name, err) } + // GVK is missing in the Secret, see: // https://github.com/kubernetes-sigs/controller-runtime/issues/526 // https://github.com/kubernetes-sigs/controller-runtime/issues/1517 @@ -279,6 +283,11 @@ func patchSecret(ctx context.Context, c client.Client, scheme *runtime.Scheme, s if !unversioned && len(gvks) == 1 { secret.SetGroupVersionKind(gvks[0]) } + + if equality.Semantic.DeepEqual(existing, secret) { + return nil + } + // we're not able to resolve conflicts so we force ownership // see: https://kubernetes.io/docs/reference/using-api/server-side-apply/#using-server-side-apply-in-a-controller err = c.Patch(ctx, secret, client.Apply, client.FieldOwner("external-secrets"), client.ForceOwnership) diff --git a/pkg/controllers/externalsecret/externalsecret_controller_test.go b/pkg/controllers/externalsecret/externalsecret_controller_test.go index 693271882..151d63569 100644 --- a/pkg/controllers/externalsecret/externalsecret_controller_test.go +++ b/pkg/controllers/externalsecret/externalsecret_controller_test.go @@ -20,8 +20,7 @@ import ( "strconv" "time" - . "github.com/onsi/ginkgo" - . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" dto "github.com/prometheus/client_model/go" v1 "k8s.io/api/core/v1" @@ -318,6 +317,47 @@ var _ = Describe("ExternalSecret controller", func() { } } + // should not update if no changes + mergeWithSecretNoChange := func(tc *testCase) { + const existingKey = "pre-existing-key" + existingVal := "someValue" + tc.externalSecret.Spec.Target.CreationPolicy = esv1alpha1.Merge + + // create secret beforehand + Expect(k8sClient.Create(context.Background(), &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: ExternalSecretTargetSecretName, + Namespace: ExternalSecretNamespace, + }, + Data: map[string][]byte{ + existingKey: []byte(existingVal), + }, + }, client.FieldOwner(FakeManager))).To(Succeed()) + + tc.checkSecret = func(es *esv1alpha1.ExternalSecret, secret *v1.Secret) { + oldResourceVersion := secret.ResourceVersion + + cleanSecret := secret.DeepCopy() + Expect(k8sClient.Patch(context.Background(), secret, client.MergeFrom(cleanSecret))).To(Succeed()) + + newSecret := &v1.Secret{} + + Eventually(func() bool { + secretLookupKey := types.NamespacedName{ + Name: ExternalSecretTargetSecretName, + Namespace: ExternalSecretNamespace, + } + + err := k8sClient.Get(context.Background(), secretLookupKey, newSecret) + if err != nil { + return false + } + return oldResourceVersion == newSecret.ResourceVersion + }, timeout, interval).Should(Equal(true)) + + } + } + // should not merge with secret if it doesn't exist mergeWithSecretErr := func(tc *testCase) { const secretVal = "someValue" @@ -925,6 +965,7 @@ var _ = Describe("ExternalSecret controller", func() { Entry("should merge with existing secret using creationPolicy=Merge", mergeWithSecret), Entry("should error if secret doesn't exist when using creationPolicy=Merge", mergeWithSecretErr), Entry("should not resolve conflicts with creationPolicy=Merge", mergeWithConflict), + Entry("should not update unchanged secret using creationPolicy=Merge", mergeWithSecretNoChange), Entry("should sync with template", syncWithTemplate), Entry("should sync template with correct value precedence", syncWithTemplatePrecedence), Entry("should refresh secret from template", refreshWithTemplate), diff --git a/pkg/controllers/externalsecret/suite_test.go b/pkg/controllers/externalsecret/suite_test.go index 4fc46b655..011bbdcb2 100644 --- a/pkg/controllers/externalsecret/suite_test.go +++ b/pkg/controllers/externalsecret/suite_test.go @@ -19,7 +19,7 @@ import ( "testing" "time" - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.uber.org/zap/zapcore" "k8s.io/client-go/kubernetes/scheme" @@ -89,7 +89,7 @@ var _ = BeforeSuite(func() { defer GinkgoRecover() Expect(k8sManager.Start(ctrl.SetupSignalHandler())).ToNot(HaveOccurred()) }() -}, 60) +}) var _ = AfterSuite(func() { By("tearing down the test environment") diff --git a/pkg/controllers/secretstore/suite_test.go b/pkg/controllers/secretstore/suite_test.go index c3173275d..be41bd75c 100644 --- a/pkg/controllers/secretstore/suite_test.go +++ b/pkg/controllers/secretstore/suite_test.go @@ -18,7 +18,7 @@ import ( "path/filepath" "testing" - . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" @@ -65,7 +65,7 @@ var _ = BeforeSuite(func() { k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) Expect(err).ToNot(HaveOccurred()) Expect(k8sClient).ToNot(BeNil()) -}, 60) +}) var _ = AfterSuite(func() { By("tearing down the test environment") diff --git a/pkg/provider/vault/fake/vault.go b/pkg/provider/vault/fake/vault.go index df1fc29bb..ff1f49a8a 100644 --- a/pkg/provider/vault/fake/vault.go +++ b/pkg/provider/vault/fake/vault.go @@ -32,6 +32,8 @@ type MockClearTokenFn func() type MockSetNamespaceFn func(namespace string) +type MockAddHeaderFn func(key, value string) + func NewMockNewRequestFn(req *vault.Request) MockNewRequestFn { return func(method, requestPath string) *vault.Request { return req @@ -75,6 +77,10 @@ func NewSetNamespaceFn() MockSetNamespaceFn { return func(namespace string) {} } +func NewAddHeaderFn() MockAddHeaderFn { + return func(key, value string) {} +} + type VaultClient struct { MockNewRequest MockNewRequestFn MockRawRequestWithContext MockRawRequestWithContextFn @@ -82,6 +88,7 @@ type VaultClient struct { MockToken MockTokenFn MockClearToken MockClearTokenFn MockSetNamespace MockSetNamespaceFn + MockAddHeader MockAddHeaderFn } func (c *VaultClient) NewRequest(method, requestPath string) *vault.Request { @@ -107,3 +114,7 @@ func (c *VaultClient) ClearToken() { func (c *VaultClient) SetNamespace(namespace string) { c.MockSetNamespace(namespace) } + +func (c *VaultClient) AddHeader(key, value string) { + c.MockAddHeader(key, value) +} diff --git a/pkg/provider/vault/vault.go b/pkg/provider/vault/vault.go index bd3d945dd..25787fec7 100644 --- a/pkg/provider/vault/vault.go +++ b/pkg/provider/vault/vault.go @@ -83,6 +83,7 @@ type Client interface { Token() string ClearToken() SetNamespace(namespace string) + AddHeader(key, value string) } type client struct { @@ -139,6 +140,10 @@ func (c *connector) NewClient(ctx context.Context, store esv1alpha1.GenericStore client.SetNamespace(*vaultSpec.Namespace) } + if vaultSpec.ReadYourWrites && vaultSpec.ForwardInconsistent { + client.AddHeader("X-Vault-Inconsistent", "forward-active-node") + } + if err := vStore.setAuth(ctx, client, cfg); err != nil { return nil, err } @@ -304,6 +309,9 @@ func (v *client) newConfig() (*vault.Config, error) { transport.TLSClientConfig.RootCAs = caCertPool } + // If either read-after-write consistency feature is enabled, enable ReadYourWrites + cfg.ReadYourWrites = v.store.ReadYourWrites || v.store.ForwardInconsistent + return cfg, nil } diff --git a/terraform/aws/main.tf b/terraform/aws/main.tf new file mode 100644 index 000000000..ca514658c --- /dev/null +++ b/terraform/aws/main.tf @@ -0,0 +1,8 @@ +module "cluster" { + source = "./modules/cluster" + + cluster_name = var.AWS_CLUSTER_NAME + cluster_region = var.AWS_REGION + irsa_sa_name = var.AWS_SA_NAME + irsa_sa_namespace = var.AWS_SA_NAMESPACE +} diff --git a/terraform/aws/modules/cluster/auth.tf b/terraform/aws/modules/cluster/auth.tf new file mode 100644 index 000000000..0dce6e3ab --- /dev/null +++ b/terraform/aws/modules/cluster/auth.tf @@ -0,0 +1,60 @@ + +data "aws_eks_cluster_auth" "this" { + name = module.eks.cluster_id +} + +data "aws_caller_identity" "current" {} + +locals { + kubeconfig = yamlencode({ + apiVersion = "v1" + kind = "Config" + current-context = "terraform" + clusters = [{ + name = module.eks.cluster_id + cluster = { + certificate-authority-data = module.eks.cluster_certificate_authority_data + server = module.eks.cluster_endpoint + } + }] + contexts = [{ + name = "terraform" + context = { + cluster = module.eks.cluster_id + user = "terraform" + } + }] + users = [{ + name = "terraform" + user = { + token = data.aws_eks_cluster_auth.this.token + } + }] + }) + + # we have to allow the root account to access the api + aws_auth_configmap_yaml = <<-EOT + ${chomp(module.eks.aws_auth_configmap_yaml)} + - rolearn: arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/admin + username: system:aws:root + groups: + - system:masters + EOT +} + +resource "null_resource" "patch_cm" { + triggers = { + kubeconfig = base64encode(local.kubeconfig) + cmd_patch = <<-EOT + kubectl patch configmap/aws-auth --patch "${local.aws_auth_configmap_yaml}" -n kube-system --kubeconfig <(echo $KUBECONFIG | base64 --decode) + EOT + } + + provisioner "local-exec" { + interpreter = ["/bin/bash", "-c"] + environment = { + KUBECONFIG = self.triggers.kubeconfig + } + command = self.triggers.cmd_patch + } +} diff --git a/terraform/aws/modules/cluster/irsa.tf b/terraform/aws/modules/cluster/irsa.tf new file mode 100644 index 000000000..ba4a256a3 --- /dev/null +++ b/terraform/aws/modules/cluster/irsa.tf @@ -0,0 +1,57 @@ +locals { + sa_manifest = <<-EOT + apiVersion: v1 + kind: ServiceAccount + metadata: + name: ${local.serviceaccount_name} + namespace: ${local.serviceaccount_namespace} + annotations: + eks.amazonaws.com/role-arn: "${aws_iam_role.eso-e2e-irsa.arn}" + EOT +} + +data "aws_iam_policy_document" "assume-policy" { + statement { + actions = ["sts:AssumeRoleWithWebIdentity"] + condition { + test = "StringEquals" + variable = "${trimprefix(module.eks.cluster_oidc_issuer_url, "https://")}:sub" + + values = [ + "system:serviceaccount:${local.serviceaccount_namespace}:${local.serviceaccount_name}" + ] + } + + principals { + type = "Federated" + identifiers = [module.eks.oidc_provider_arn] + } + } +} + +resource "aws_iam_role" "eso-e2e-irsa" { + name = "eso-e2e-irsa" + path = "/" + assume_role_policy = data.aws_iam_policy_document.assume-policy.json + managed_policy_arns = [ + "arn:aws:iam::aws:policy/SecretsManagerReadWrite" + ] + +} + +resource "null_resource" "apply_sa" { + triggers = { + kubeconfig = base64encode(local.kubeconfig) + cmd_patch = <<-EOT + echo '${local.sa_manifest}' | kubectl --kubeconfig <(echo $KUBECONFIG | base64 --decode) apply -f - + EOT + } + + provisioner "local-exec" { + interpreter = ["/bin/bash", "-c"] + environment = { + KUBECONFIG = self.triggers.kubeconfig + } + command = self.triggers.cmd_patch + } +} diff --git a/terraform/aws/modules/cluster/main.tf b/terraform/aws/modules/cluster/main.tf new file mode 100644 index 000000000..a4004445c --- /dev/null +++ b/terraform/aws/modules/cluster/main.tf @@ -0,0 +1,127 @@ +provider "aws" { + region = local.region +} + +locals { + name = var.cluster_name + cluster_version = "1.21" + region = var.cluster_region + + serviceaccount_name = var.irsa_sa_name + serviceaccount_namespace = var.irsa_sa_namespace + + tags = { + Example = local.name + GithubRepo = "external-secrets" + GithubOrg = "external-secrets" + } +} + +module "eks" { + source = "git::https://github.com/terraform-aws-modules/terraform-aws-eks?ref=v18.2.0" + + cluster_name = local.name + cluster_version = local.cluster_version + cluster_endpoint_private_access = true + cluster_endpoint_public_access = true + + cluster_addons = { + coredns = { + resolve_conflicts = "OVERWRITE" + } + kube-proxy = {} + vpc-cni = { + resolve_conflicts = "OVERWRITE" + } + + } + + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.private_subnets + enable_irsa = true + + # EKS Managed Node Group(s) + eks_managed_node_group_defaults = { + ami_type = "AL2_x86_64" + disk_size = 50 + instance_types = ["m6i.large", "m5.large", "m5n.large", "m5zn.large"] + vpc_security_group_ids = [aws_security_group.additional.id] + } + + + eks_managed_node_groups = { + example = { + desired_size = 2 + + instance_types = ["t3.large"] + tags = local.tags + } + } + + tags = local.tags +} + +################################################################################ +# Supporting resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + name = local.name + cidr = "10.0.0.0/16" + + azs = ["${local.region}a", "${local.region}b", "${local.region}c"] + private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] + public_subnets = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"] + + enable_nat_gateway = true + single_nat_gateway = true + enable_dns_hostnames = true + + enable_flow_log = true + create_flow_log_cloudwatch_iam_role = true + create_flow_log_cloudwatch_log_group = true + + public_subnet_tags = { + "kubernetes.io/cluster/${local.name}" = "shared" + "kubernetes.io/role/elb" = 1 + } + + private_subnet_tags = { + "kubernetes.io/cluster/${local.name}" = "shared" + "kubernetes.io/role/internal-elb" = 1 + } + + tags = local.tags +} + +resource "aws_security_group" "additional" { + name_prefix = "${local.name}-additional" + vpc_id = module.vpc.vpc_id + + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = [ + "10.0.0.0/8", + "172.16.0.0/12", + "192.168.0.0/16", + ] + } + + # 443, 53, 123 is already allowed + egress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + + tags = local.tags +} + diff --git a/terraform/aws/modules/cluster/outputs.tf b/terraform/aws/modules/cluster/outputs.tf new file mode 100644 index 000000000..d35b94356 --- /dev/null +++ b/terraform/aws/modules/cluster/outputs.tf @@ -0,0 +1,135 @@ +################################################################################ +# Cluster +################################################################################ + +output "cluster_arn" { + description = "The Amazon Resource Name (ARN) of the cluster" + value = module.eks.cluster_arn +} + +output "cluster_certificate_authority_data" { + description = "Base64 encoded certificate data required to communicate with the cluster" + value = module.eks.cluster_certificate_authority_data +} + +output "cluster_endpoint" { + description = "Endpoint for your Kubernetes API server" + value = module.eks.cluster_endpoint +} + +output "cluster_id" { + description = "The name/id of the EKS cluster. Will block on cluster creation until the cluster is really ready" + value = module.eks.cluster_id +} + +output "cluster_oidc_issuer_url" { + description = "The URL on the EKS cluster for the OpenID Connect identity provider" + value = module.eks.cluster_oidc_issuer_url +} + +output "cluster_platform_version" { + description = "Platform version for the cluster" + value = module.eks.cluster_platform_version +} + +output "cluster_status" { + description = "Status of the EKS cluster. One of `CREATING`, `ACTIVE`, `DELETING`, `FAILED`" + value = module.eks.cluster_status +} + +output "cluster_security_group_id" { + description = "Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console" + value = module.eks.cluster_security_group_id +} + +################################################################################ +# Security Group +################################################################################ + +output "cluster_security_group_arn" { + description = "Amazon Resource Name (ARN) of the cluster security group" + value = module.eks.cluster_security_group_arn +} + +################################################################################ +# IRSA +################################################################################ + +output "oidc_provider_arn" { + description = "The ARN of the OIDC Provider if `enable_irsa = true`" + value = module.eks.oidc_provider_arn +} + +################################################################################ +# IAM Role +################################################################################ + +output "cluster_iam_role_name" { + description = "IAM role name of the EKS cluster" + value = module.eks.cluster_iam_role_name +} + +output "cluster_iam_role_arn" { + description = "IAM role ARN of the EKS cluster" + value = module.eks.cluster_iam_role_arn +} + +output "cluster_iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = module.eks.cluster_iam_role_unique_id +} + +################################################################################ +# EKS Addons +################################################################################ + +output "cluster_addons" { + description = "Map of attribute maps for all EKS cluster addons enabled" + value = module.eks.cluster_addons +} + +################################################################################ +# EKS Identity Provider +################################################################################ + +output "cluster_identity_providers" { + description = "Map of attribute maps for all EKS identity providers enabled" + value = module.eks.cluster_identity_providers +} + +################################################################################ +# CloudWatch Log Group +################################################################################ + +output "cloudwatch_log_group_name" { + description = "Name of cloudwatch log group created" + value = module.eks.cloudwatch_log_group_name +} + +output "cloudwatch_log_group_arn" { + description = "Arn of cloudwatch log group created" + value = module.eks.cloudwatch_log_group_arn +} + +################################################################################ +# Fargate Profile +################################################################################ + +output "fargate_profiles" { + description = "Map of attribute maps for all EKS Fargate Profiles created" + value = module.eks.fargate_profiles +} + +################################################################################ +# Additional +################################################################################ + +output "aws_auth_configmap_yaml" { + description = "Formatted yaml output for base aws-auth configmap containing roles used in cluster node groups/fargate profiles" + value = module.eks.aws_auth_configmap_yaml +} + +output "eks_cluster_auth_token" { + value = data.aws_eks_cluster_auth.this.token + sensitive = true +} diff --git a/terraform/aws/modules/cluster/provider.tf b/terraform/aws/modules/cluster/provider.tf new file mode 100644 index 000000000..fc1d45ab8 --- /dev/null +++ b/terraform/aws/modules/cluster/provider.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 0.13" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 3.0" + } + } +} diff --git a/terraform/aws/modules/cluster/variables.tf b/terraform/aws/modules/cluster/variables.tf new file mode 100644 index 000000000..093f1e33e --- /dev/null +++ b/terraform/aws/modules/cluster/variables.tf @@ -0,0 +1,16 @@ +variable "cluster_name" { + type = string + default = "eso-e2e-managed" +} + +variable "irsa_sa_name" { + type = string +} + +variable "irsa_sa_namespace" { + type = string +} + +variable "cluster_region" { + type = string +} diff --git a/terraform/aws/outputs.tf b/terraform/aws/outputs.tf new file mode 100644 index 000000000..2a8c30f85 --- /dev/null +++ b/terraform/aws/outputs.tf @@ -0,0 +1,11 @@ +output "cluster_arn" { + value = module.cluster.cluster_arn +} + +output "cluster_iam_role_arn" { + value = module.cluster.cluster_iam_role_arn +} + +output "aws_auth_configmap_yaml" { + value = module.cluster.aws_auth_configmap_yaml +} diff --git a/terraform/aws/provider.tf b/terraform/aws/provider.tf new file mode 100644 index 000000000..5c278a048 --- /dev/null +++ b/terraform/aws/provider.tf @@ -0,0 +1,11 @@ +terraform { + required_version = ">= 0.13" + + backend "s3" { + bucket = "eso-e2e-aws-tfstate" + key = "aws-tfstate" + region = "eu-west-1" + } + + required_providers {} +} diff --git a/terraform/aws/variables.tf b/terraform/aws/variables.tf new file mode 100644 index 000000000..62eff34d1 --- /dev/null +++ b/terraform/aws/variables.tf @@ -0,0 +1,15 @@ +variable "AWS_SA_NAME" { + type = string +} + +variable "AWS_SA_NAMESPACE" { + type = string +} + +variable "AWS_REGION" { + type = string +} + +variable "AWS_CLUSTER_NAME" { + type = string +} diff --git a/terraform/gcp/eso_gcp_modules/gke/main.tf b/terraform/gcp/eso_gcp_modules/gke/main.tf index 4a7510f4d..bb47fdcca 100644 --- a/terraform/gcp/eso_gcp_modules/gke/main.tf +++ b/terraform/gcp/eso_gcp_modules/gke/main.tf @@ -1,4 +1,5 @@ resource "google_service_account" "default" { + project = var.project_id account_id = var.GCP_GSA_NAME } @@ -27,6 +28,7 @@ resource "google_service_account_iam_member" "pod_identity_e2e" { } resource "google_container_cluster" "primary" { + project = var.project_id name = "${var.env}-cluster" location = var.zone remove_default_node_pool = true @@ -43,6 +45,7 @@ resource "google_container_cluster" "primary" { } resource "google_container_node_pool" "nodes" { + project = var.project_id name = "${google_container_cluster.primary.name}-node-pool" location = google_container_cluster.primary.location cluster = google_container_cluster.primary.name @@ -57,3 +60,20 @@ resource "google_container_node_pool" "nodes" { ] } } + +provider "kubernetes" { + host = "https://${google_container_cluster.primary.endpoint}" + token = data.google_client_config.default.access_token + cluster_ca_certificate = base64decode(google_container_cluster.primary.master_auth.0.cluster_ca_certificate) +} + +data "google_client_config" "default" {} + +resource "kubernetes_service_account" "test" { + metadata { + name = var.GCP_KSA_NAME + annotations = { + "iam.gke.io/gcp-service-account" : "${var.GCP_GSA_NAME}@${var.project_id}.iam.gserviceaccount.com" + } + } +} diff --git a/terraform/gcp/eso_gcp_modules/network/main.tf b/terraform/gcp/eso_gcp_modules/network/main.tf index a7dadae0b..2a77fe0f1 100644 --- a/terraform/gcp/eso_gcp_modules/network/main.tf +++ b/terraform/gcp/eso_gcp_modules/network/main.tf @@ -1,9 +1,11 @@ resource "google_compute_network" "env-vpc" { - name = "${var.env}-vpc" + project = var.project_id + name = "${var.env}-vpc" auto_create_subnetworks = false } resource "google_compute_subnetwork" "env-subnet" { + project = var.project_id name = "${google_compute_network.env-vpc.name}-subnet" region = var.region network = google_compute_network.env-vpc.name diff --git a/terraform/gcp/eso_gcp_modules/network/variable.tf b/terraform/gcp/eso_gcp_modules/network/variable.tf index 6f35274e1..81a11ac92 100644 --- a/terraform/gcp/eso_gcp_modules/network/variable.tf +++ b/terraform/gcp/eso_gcp_modules/network/variable.tf @@ -13,3 +13,6 @@ variable "ip_service_range" { variable "region" { default = "europe-west1" } +variable "project_id" { + type = string +} diff --git a/terraform/gcp/main.tf b/terraform/gcp/main.tf index d00e21477..691ad9141 100644 --- a/terraform/gcp/main.tf +++ b/terraform/gcp/main.tf @@ -1,28 +1,29 @@ terraform { backend "gcs" { - bucket = "eso-infra-state" - prefix = "eso-infra-state/state" + bucket = "eso-infra-state" + prefix = "eso-infra-state/state" credentials = "secrets/gcloud-service-account-key.json" } } module "test-network" { - source = "./eso_gcp_modules/network" - env = var.env - region = var.region + source = "./eso_gcp_modules/network" + env = var.env + region = var.region ip_cidr_range = var.ip_cidr_range + project_id = var.GCP_PROJECT_ID } module "test-cluster" { - source = "./eso_gcp_modules/gke" - project_id = var.project_id - env = var.env - region = var.region - network = module.test-network.vpc-object - subnetwork = module.test-network.subnet-name - node_count = var.node_count + source = "./eso_gcp_modules/gke" + project_id = var.GCP_PROJECT_ID + env = var.env + region = var.region + network = module.test-network.vpc-object + subnetwork = module.test-network.subnet-name + node_count = var.node_count initial_node_count = var.initial_node_count - preemptible = true - GCP_GSA_NAME = var.GCP_GSA_NAME - GCP_KSA_NAME = var.GCP_KSA_NAME + preemptible = true + GCP_GSA_NAME = var.GCP_GSA_NAME + GCP_KSA_NAME = var.GCP_KSA_NAME } diff --git a/terraform/gcp/variable.tf b/terraform/gcp/variable.tf index b3b07978b..5656467ee 100644 --- a/terraform/gcp/variable.tf +++ b/terraform/gcp/variable.tf @@ -1,7 +1,6 @@ variable "env" { default = "test" } variable "region" { default = "europe-west1" } variable "zone" { default = "europe-west1-b" } -variable "project_id" { default = "external-secrets-operator" } variable "horizontal_pod_autoscaling" { default = false } variable "node_count" { default = 2 } variable "node_min_count" { default = 2 } diff --git a/tools.go b/tools.go index ce786904b..7d68ab319 100644 --- a/tools.go +++ b/tools.go @@ -5,6 +5,6 @@ package tools import ( _ "github.com/ahmetb/gen-crd-api-reference-docs" - _ "github.com/onsi/ginkgo/ginkgo" + _ "github.com/onsi/ginkgo/v2/ginkgo" _ "sigs.k8s.io/controller-tools/cmd/controller-gen" )