1
0
Fork 0
mirror of https://github.com/external-secrets/external-secrets.git synced 2024-12-14 11:57:59 +00:00

Merge branch 'main' into fix/docs

This commit is contained in:
Gustavo Carvalho 2022-01-25 09:15:07 -03:00
commit 7df28de2d8
75 changed files with 1743 additions and 871 deletions

View file

@ -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
@ -76,12 +83,6 @@ jobs:
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 }}

View file

@ -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"

View file

@ -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,13 +85,13 @@ 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
@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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".'

View file

@ -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:

View file

@ -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".'

61
design/000-template.md Normal file
View file

@ -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
<!-- toc -->
// autogen please
<!-- /toc -->
## 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?

View file

@ -4,7 +4,7 @@ title: External Secrets Operator CRD
version: v1alpha1
authors: all of us
creation-date: 2020-09-01
status: draft
status: accepted
---
```

View file

@ -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.

View file

@ -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)

View file

@ -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).

View file

@ -3207,6 +3207,36 @@ CAProvider
<p>The provider for the CA bundle to use to validate Vault server certificate.</p>
</td>
</tr>
<tr>
<td>
<code>readYourWrites</code></br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>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
<a href="https://www.vaultproject.io/docs/enterprise/consistency">https://www.vaultproject.io/docs/enterprise/consistency</a></p>
</td>
</tr>
<tr>
<td>
<code>forwardInconsistent</code></br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>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.
<a href="https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header">https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header</a></p>
</td>
</tr>
</tbody>
</table>
<h3 id="external-secrets.io/v1alpha1.WebhookCAProvider">WebhookCAProvider

View file

@ -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 && \

View file

@ -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)
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 \

View file

@ -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"))
}

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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"},
},
}
}

View file

@ -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")
}

View file

@ -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"

View file

@ -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

View file

@ -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
}

View file

@ -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)
}

View file

@ -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
}

View file

@ -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"

View file

@ -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"

View file

@ -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}

View file

@ -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)),

View file

@ -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()

View file

@ -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)),

View file

@ -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)

View file

@ -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,
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) {
// 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),
})
Expect(err).ToNot(HaveOccurred())
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),
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",
},
},

View file

@ -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)),

View file

@ -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()
}
}

View file

@ -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)),

View file

@ -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",

View file

@ -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,20 +29,31 @@ 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")
// 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
@ -143,19 +151,3 @@ x6HaRh+EUwU51von6M9lEF9/p5Q=
},
}
}
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),
)
})

View file

@ -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()
}
}

View file

@ -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"
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 {
ServiceAccountName string
ServiceAccountNamespace string
framework *framework.Framework
credentials string
projectID string
framework *framework.Framework
clusterLocation string
clusterName string
serviceAccountName string
serviceAccountNamespace 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 {
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{
clusterSecretStore := &esv1alpha1.ClusterSecretStore{
ObjectMeta: metav1.ObjectMeta{
Name: s.SAClusterSecretStoreName(),
},
}
_, 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),
Name: s.ServiceAccountName,
Namespace: utilpointer.StringPtr(s.ServiceAccountNamespace),
},
},
},
},
}
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)
return nil
})
Expect(err).ToNot(HaveOccurred())
} else {
log.Logf("%s CSStore already created", SpecifcSASecretStoreName)
}
// 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())
}

View file

@ -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
}

View file

@ -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)),

View file

@ -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)

View file

@ -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"
)

View file

@ -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)),

View file

@ -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)

View file

@ -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"

View file

@ -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),

77
go.mod
View file

@ -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

187
go.sum
View file

@ -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=

View file

@ -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

View file

@ -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)

View file

@ -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),

View file

@ -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")

View file

@ -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")

View file

@ -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)
}

View file

@ -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
}

8
terraform/aws/main.tf Normal file
View file

@ -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
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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
}

View file

@ -0,0 +1,10 @@
terraform {
required_version = ">= 0.13"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}

View file

@ -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
}

11
terraform/aws/outputs.tf Normal file
View file

@ -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
}

11
terraform/aws/provider.tf Normal file
View file

@ -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 {}
}

View file

@ -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
}

View file

@ -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"
}
}
}

View file

@ -1,9 +1,11 @@
resource "google_compute_network" "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

View file

@ -13,3 +13,6 @@ variable "ip_service_range" {
variable "region" {
default = "europe-west1"
}
variable "project_id" {
type = string
}

View file

@ -11,11 +11,12 @@ module "test-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
project_id = var.GCP_PROJECT_ID
env = var.env
region = var.region
network = module.test-network.vpc-object

View file

@ -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 }

View file

@ -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"
)