diff --git a/.github/codecov.yml b/.github/codecov.yml
deleted file mode 100644
index fb1653f3b..000000000
--- a/.github/codecov.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-ignore:
-- pkg/provider/**/fake
-coverage:
- round: down
- precision: 2
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 79538a6de..ddf43f263 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -12,9 +12,7 @@ env:
# Common versions
GO_VERSION: '1.17'
GOLANGCI_VERSION: 'v1.42.1'
- # list of available versions: https://storage.googleapis.com/kubebuilder-tools
- # TODO: 1.21.2 does not shut down properly with controller-runtime 0.9.2
- KUBEBUILDER_TOOLS_VERSION: '1.20.2'
+ KUBERNETES_VERSION: '1.23.x'
DOCKER_BUILDX_VERSION: 'v0.4.2'
# Common users. We can't run a step 'if secrets.GHCR_USERNAME != ""' but we can run
@@ -164,22 +162,22 @@ jobs:
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-pkg-
- - name: Add envtest binaries
- run: |
- curl -sSLo envtest-bins.tar.gz "https://storage.googleapis.com/kubebuilder-tools/kubebuilder-tools-${{env.KUBEBUILDER_TOOLS_VERSION}}-linux-amd64.tar.gz"
- sudo mkdir -p /usr/local/kubebuilder
- sudo tar -C /usr/local/kubebuilder --strip-components=1 -zvxf envtest-bins.tar.gz
+ - name: Add setup-envtest
+ run: |
+ go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
+ setup-envtest use ${{env.KUBERNETES_VERSION}} -p env --os $(go env GOOS) --arch $(go env GOARCH)
- name: Cache envtest binaries
uses: actions/cache@v2.1.7
with:
- path: /usr/local/kubebuilder
- key: ${{ runner.os }}-kubebuilder-${{env.KUBEBUILDER_TOOLS_VERSION}}
+ path: /home/runner/.local/share/kubebuilder-envtest/
+ key: ${{ runner.os }}-kubebuilder-${{env.KUBERNETES_VERSION}}
restore-keys: ${{ runner.os }}-kubebuilder-
- name: Run Unit Tests
run: |
export KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT=true
+ source <(setup-envtest use ${{env.KUBERNETES_VERSION}} -p env --os $(go env GOOS) --arch $(go env GOARCH))
make test
diff --git a/.github/workflows/e2e-managed.yml b/.github/workflows/e2e-managed.yml
index adf221f6f..623b0d296 100644
--- a/.github/workflows/e2e-managed.yml
+++ b/.github/workflows/e2e-managed.yml
@@ -1,6 +1,5 @@
# Run secret-dependent e2e tests only after /ok-to-test-managed approval
on:
- pull_request:
repository_dispatch:
types: [ok-to-test-managed-command]
@@ -49,6 +48,48 @@ jobs:
steps:
+ # create new status check for this specific provider
+ - uses: actions/github-script@v1
+ if: ${{ always() }}
+ env:
+ number: ${{ github.event.client_payload.pull_request.number }}
+ provider: ${{ github.event.client_payload.slash_command.args.named.provider }}
+ job: ${{ github.job }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { data: pull } = await github.pulls.get({
+ ...context.repo,
+ pull_number: process.env.number
+ });
+ const ref = pull.head.sha;
+ console.log("\n\nPR sha: " + ref)
+ const { data: checks } = await github.checks.listForRef({
+ ...context.repo,
+ ref
+ });
+ const job_name = process.env.job + "-" + process.env.provider
+ console.log("\n\nPR CHECKS: " + checks)
+ const check = checks.check_runs.filter(c => c.name === job_name);
+ console.log("\n\nPR Filtered CHECK: " + check)
+ console.log(check)
+ if(check && check.length > 0){
+ const { data: result } = await github.checks.update({
+ ...context.repo,
+ check_run_id: check[0].id,
+ status: 'in_progress',
+ });
+ return result;
+ }
+ const { data: result } = await github.checks.create({
+ ...context.repo,
+ name: job_name,
+ head_sha: pull.head.sha,
+ status: 'in_progress',
+ });
+ return result;
+
+
# Check out merge commit
- name: Fork based /ok-to-test-managed checkout
uses: actions/checkout@v2
@@ -164,6 +205,7 @@ jobs:
if: ${{ always() }}
env:
number: ${{ github.event.client_payload.pull_request.number }}
+ provider: ${{ github.event.client_payload.slash_command.args.named.provider }}
job: ${{ github.job }}
# Conveniently, job.status maps to https://developer.github.com/v3/checks/runs/#update-a-check-run
conclusion: ${{ job.status }}
@@ -180,8 +222,9 @@ jobs:
...context.repo,
ref
});
+ const job_name = process.env.job + "-" + process.env.provider
console.log("\n\nPR CHECKS: " + checks)
- const check = checks.check_runs.filter(c => c.name === process.env.job);
+ const check = checks.check_runs.filter(c => c.name === job_name);
console.log("\n\nPR Filtered CHECK: " + check)
console.log(check)
const { data: result } = await github.checks.update({
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index ed5b5d23e..15966c048 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -9,6 +9,8 @@ env:
GO_VERSION: '1.17'
GOLANGCI_VERSION: 'v1.33'
DOCKER_BUILDX_VERSION: 'v0.4.2'
+ KIND_VERSION: 'v0.11.1'
+ KIND_IMAGE: 'kindest/node:v1.23.3'
# Common users. We can't run a step 'if secrets.GHCR_USERNAME != ""' but we can run
# a step 'if env.GHCR_USERNAME' != ""', so we copy these to succinctly test whether
@@ -71,9 +73,9 @@ jobs:
- name: Setup kind
uses: engineerd/setup-kind@v0.5.0
with:
- version: "v0.11.1"
+ version: ${{env.KIND_VERSION}}
wait: 10m
- node_image: kindest/node:v1.20.7
+ node_image: ${{env.KIND_IMAGE}}
name: external-secrets
- name: Setup Docker Buildx
@@ -134,9 +136,9 @@ jobs:
- name: Setup kind
uses: engineerd/setup-kind@v0.5.0
with:
- version: "v0.11.1"
+ version: ${{env.KIND_VERSION}}
wait: 10m
- node_image: kindest/node:v1.20.7
+ node_image: ${{env.KIND_IMAGE}}
name: external-secrets
- name: Setup Docker Buildx
diff --git a/.github/workflows/helm.yml b/.github/workflows/helm.yml
index a0a91df30..0f82f9ed0 100644
--- a/.github/workflows/helm.yml
+++ b/.github/workflows/helm.yml
@@ -26,7 +26,7 @@ jobs:
make helm.generate
- name: Set up Helm
- uses: azure/setup-helm@v1.1
+ uses: azure/setup-helm@v2.0
with:
version: v3.4.2
@@ -62,7 +62,7 @@ jobs:
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Set up Helm
- uses: azure/setup-helm@v1.1
+ uses: azure/setup-helm@v2.0
with:
version: v3.4.2
diff --git a/apis/externalsecrets/v1alpha1/secretstore_fake_types.go b/apis/externalsecrets/v1alpha1/secretstore_fake_types.go
new file mode 100644
index 000000000..5c21b6fd0
--- /dev/null
+++ b/apis/externalsecrets/v1alpha1/secretstore_fake_types.go
@@ -0,0 +1,27 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+// FakeProvider configures a fake provider that returns static values.
+type FakeProvider struct {
+ Data []FakeProviderData `json:"data"`
+}
+
+type FakeProviderData struct {
+ Key string `json:"key"`
+ Value string `json:"value,omitempty"`
+ ValueMap map[string]string `json:"valueMap,omitempty"`
+ Version string `json:"version,omitempty"`
+}
diff --git a/apis/externalsecrets/v1alpha1/secretstore_types.go b/apis/externalsecrets/v1alpha1/secretstore_types.go
index 0018504ae..3f90a5ec3 100644
--- a/apis/externalsecrets/v1alpha1/secretstore_types.go
+++ b/apis/externalsecrets/v1alpha1/secretstore_types.go
@@ -81,6 +81,10 @@ type SecretStoreProvider struct {
// Webhook configures this store to sync secrets using a generic templated webhook
// +optional
Webhook *WebhookProvider `json:"webhook,omitempty"`
+
+ // Fake configures a store with static key/value pairs
+ // +optional
+ Fake *FakeProvider `json:"fake,omitempty"`
}
type SecretStoreRetrySettings struct {
diff --git a/apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go b/apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go
index 00e4e17c1..cf377f8b2 100644
--- a/apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go
+++ b/apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go
@@ -599,6 +599,50 @@ func (in *ExternalSecretTemplateMetadata) DeepCopy() *ExternalSecretTemplateMeta
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FakeProvider) DeepCopyInto(out *FakeProvider) {
+ *out = *in
+ if in.Data != nil {
+ in, out := &in.Data, &out.Data
+ *out = make([]FakeProviderData, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FakeProvider.
+func (in *FakeProvider) DeepCopy() *FakeProvider {
+ if in == nil {
+ return nil
+ }
+ out := new(FakeProvider)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FakeProviderData) DeepCopyInto(out *FakeProviderData) {
+ *out = *in
+ if in.ValueMap != nil {
+ in, out := &in.ValueMap, &out.ValueMap
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FakeProviderData.
+func (in *FakeProviderData) DeepCopy() *FakeProviderData {
+ if in == nil {
+ return nil
+ }
+ out := new(FakeProviderData)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GCPSMAuth) DeepCopyInto(out *GCPSMAuth) {
*out = *in
@@ -939,6 +983,11 @@ func (in *SecretStoreProvider) DeepCopyInto(out *SecretStoreProvider) {
*out = new(WebhookProvider)
(*in).DeepCopyInto(*out)
}
+ if in.Fake != nil {
+ in, out := &in.Fake, &out.Fake
+ *out = new(FakeProvider)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretStoreProvider.
diff --git a/deploy/crds/external-secrets.io_clustersecretstores.yaml b/deploy/crds/external-secrets.io_clustersecretstores.yaml
index a4fa020bb..8a71f2998 100644
--- a/deploy/crds/external-secrets.io_clustersecretstores.yaml
+++ b/deploy/crds/external-secrets.io_clustersecretstores.yaml
@@ -380,6 +380,29 @@ spec:
required:
- vaultUrl
type: object
+ fake:
+ description: Fake configures a store with static key/value pairs
+ properties:
+ data:
+ items:
+ properties:
+ key:
+ type: string
+ value:
+ type: string
+ valueMap:
+ additionalProperties:
+ type: string
+ type: object
+ version:
+ type: string
+ required:
+ - key
+ type: object
+ type: array
+ required:
+ - data
+ type: object
gcpsm:
description: GCPSM configures this store to sync secrets using
Google Cloud Platform Secret Manager provider
diff --git a/deploy/crds/external-secrets.io_secretstores.yaml b/deploy/crds/external-secrets.io_secretstores.yaml
index ac2da8e28..18a60f554 100644
--- a/deploy/crds/external-secrets.io_secretstores.yaml
+++ b/deploy/crds/external-secrets.io_secretstores.yaml
@@ -380,6 +380,29 @@ spec:
required:
- vaultUrl
type: object
+ fake:
+ description: Fake configures a store with static key/value pairs
+ properties:
+ data:
+ items:
+ properties:
+ key:
+ type: string
+ value:
+ type: string
+ valueMap:
+ additionalProperties:
+ type: string
+ type: object
+ version:
+ type: string
+ required:
+ - key
+ type: object
+ type: array
+ required:
+ - data
+ type: object
gcpsm:
description: GCPSM configures this store to sync secrets using
Google Cloud Platform Secret Manager provider
diff --git a/docs/contributing-process.md b/docs/contributing-process.md
index 1b875b0d1..f89a43f9e 100644
--- a/docs/contributing-process.md
+++ b/docs/contributing-process.md
@@ -31,6 +31,82 @@ 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.
+### Triggering e2e tests
+
+We have an extensive set of e2e tests that test the integration with *real* cloud provider APIs.
+Maintainers must trigger these kind of tests manually for PRs that come from forked repositories. These tests run inside a `kind` cluster in the GitHub Actions runner:
+
+```
+/ok-to-test sha=xxxxxx
+```
+
+#### Executing e2e tests locally
+
+You have to prepare your shell environment with the necessary variables so the e2e test
+runner knows what credentials to use. See `e2e/run.sh` for the variables that are passed in.
+If you e.g. want to test AWS integration make sure set all `AWS_*` variables mentioned
+in that file.
+
+Use [ginkgo labels](https://onsi.github.io/ginkgo/#spec-labels) to select the tests
+you want to execute. You have to specify `!managed` to ensure that you do not
+run managed tests.
+
+```
+make test.e2e GINKGO_LABELS='gcp&&!managed'
+```
+
+#### Managed Kubernetes e2e tests
+
+There's another suite of e2e tests that integrate with managed Kuberentes offerings.
+They create real infrastructure at a cloud provider and deploy the controller
+into that environment.
+This is necessary to test the authentication integration
+([GCP Worklaod Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity),
+[EKS IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)...).
+
+These tests are time intensive (~20-45min) and must be triggered manually by
+a maintainer when a particular provider or authentication mechanism was changed:
+
+```
+/ok-to-test-managed sha=xxxxxx provider=aws
+# or
+/ok-to-test-managed sha=xxxxxx provider=gcp
+```
+
+Both tests can run in parallel. Once started they add a dynamic GitHub check `integration-managed-(gcp|aws)` to the PR that triggered the test.
+
+
+### Executing Managed Kubernetes e2e tests locally
+
+You have to prepare your shell environment with the necessary variables so the e2e
+test runner knows what credentials to use. See `.github/workflows/e2e-managed.yml`
+for the variables that are passed in. If you e.g. want to test AWS integration make
+sure set all variables containing `AWS_*` and `TF_VAR_AWS_*` mentioned in that file.
+
+Then execute `tf.apply.aws` or `tf.apply.gcp` to create the infrastructure.
+
+```
+make tf.apply.aws
+```
+
+Then run the `managed` testsuite. You will need push permissions to the external-secrets ghcr repository. You can set `IMAGE_REGISTRY` to control which image registry is used to store the controller and e2e test images in.
+
+You also have to setup a proper Kubeconfig so the e2e test pod gets deployed into the managed cluster.
+
+```
+aws eks update-kubeconfig --name ${AWS_CLUSTER_NAME}
+or
+gcloud container clusters get-credentials ${GCP_GKE_CLUSTER} --region europe-west1-b
+```
+
+Use [ginkgo labels](https://onsi.github.io/ginkgo/#spec-labels) to select the tests
+you want to execute.
+
+```
+# you may have to set IMAGE_REGISTRY=docker.io/your-user/external-secrets
+make test.e2e.managed GINKGO_LABELS='gcp'
+```
+
## 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
diff --git a/docs/provider-fake.md b/docs/provider-fake.md
new file mode 100644
index 000000000..f538f9fd5
--- /dev/null
+++ b/docs/provider-fake.md
@@ -0,0 +1,26 @@
+We provide a `fake` implementation to help with testing. This provider returns static key/value pairs and nothing else.
+To use the `fake` provider simply create a `SecretStore` or `ClusterSecretStore` and configure it like in the following example:
+
+!!! note inline end
+ The provider returns static data configured in `value` or `valueMap`. You can define a `version`, too. If set the `remoteRef` from an ExternalSecret must match otherwise no value is returned.
+
+```yaml
+{% include 'fake-provider-store.yaml' %}
+```
+
+Please note that `value` is intended for exclusive use with `data` and `valueMap` for `dataFrom`.
+Here is an example `ExternalSecret` that displays this behavior:
+
+!!! warning inline end
+ This provider supports specifying different `data[].version` configurations. However, `data[].property` is ignored.
+
+```yaml
+{% include 'fake-provider-es.yaml' %}
+```
+
+This results in the following secret:
+
+
+```yaml
+{% include 'fake-provider-secret.yaml' %}
+```
diff --git a/docs/snippets/fake-provider-es.yaml b/docs/snippets/fake-provider-es.yaml
new file mode 100644
index 000000000..cb3498836
--- /dev/null
+++ b/docs/snippets/fake-provider-es.yaml
@@ -0,0 +1,18 @@
+apiVersion: external-secrets.io/v1alpha1
+kind: ExternalSecret
+metadata:
+ name: example
+spec:
+ refreshInterval: 1h
+ secretStoreRef:
+ name: fake
+ kind: ClusterSecretStore
+ target:
+ name: secret-to-be-created
+ data:
+ - secretKey: foo_bar
+ remoteRef:
+ key: /foo/bar
+ version: v1
+ dataFrom:
+ - key: /foo/baz
\ No newline at end of file
diff --git a/docs/snippets/fake-provider-secret.yaml b/docs/snippets/fake-provider-secret.yaml
new file mode 100644
index 000000000..ac4d40d57
--- /dev/null
+++ b/docs/snippets/fake-provider-secret.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: secret-to-be-created
+ namespace: default
+data:
+ foo_bar: SEVMTE8x # HELLO1 (via data)
+ foo: ZXhhbXBsZQ== # example (via dataFrom)
+ other: dGhpbmc= # thing (via dataFrom)
diff --git a/docs/snippets/fake-provider-store.yaml b/docs/snippets/fake-provider-store.yaml
new file mode 100644
index 000000000..6d429235e
--- /dev/null
+++ b/docs/snippets/fake-provider-store.yaml
@@ -0,0 +1,20 @@
+apiVersion: external-secrets.io/v1alpha1
+kind: ClusterSecretStore
+metadata:
+ name: fake
+spec:
+ provider:
+ fake:
+ data:
+ - key: "/foo/bar"
+ value: "HELLO1"
+ version: "v1"
+ - key: "/foo/bar"
+ value: "HELLO2"
+ version: "v2"
+ - key: "/foo/baz"
+ valueMap:
+ foo: example
+ other: thing
+
+
diff --git a/docs/spec.md b/docs/spec.md
index a1b3aa453..80483267a 100644
--- a/docs/spec.md
+++ b/docs/spec.md
@@ -714,6 +714,237 @@ string
|
+ClusterExternalSecret
+
+
+
ClusterExternalSecret is the Schema for the clusterexternalsecrets API.
+
+
+ClusterExternalSecretConditionType
+(string
alias)
+
+(Appears on:
+ClusterExternalSecretStatus)
+
+
+
+
+
+
+Value |
+Description |
+
+
+"NotReady" |
+ |
+
"PartiallyReady" |
+ |
+
"Ready" |
+ |
+
+
+ClusterExternalSecretSpec
+
+
+(Appears on:
+ClusterExternalSecret)
+
+
+
ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.
+
+
+
+
+Field |
+Description |
+
+
+
+
+
+externalSecretSpec
+
+
+ExternalSecretSpec
+
+
+ |
+
+ The spec for the ExternalSecrets to be created
+ |
+
+
+
+externalSecretName
+
+string
+
+ |
+
+(Optional)
+ The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
+ |
+
+
+
+namespaceSelector
+
+
+Kubernetes meta/v1.LabelSelector
+
+
+ |
+
+ The labels to select by to find the Namespaces to create the ExternalSecrets in.
+ |
+
+
+
+ClusterExternalSecretStatus
+
+
+(Appears on:
+ClusterExternalSecret)
+
+
+
ClusterExternalSecretStatus defines the observed state of ClusterExternalSecret.
+
+
ClusterSecretStore
@@ -1084,6 +1315,7 @@ string
(Appears on:
+ClusterExternalSecretSpec,
ExternalSecret)
@@ -1171,6 +1403,7 @@ If multiple entries are specified, the Secret keys are merged in the specified o
(Appears on:
+ClusterExternalSecretStatus,
ExternalSecret)
@@ -1486,6 +1719,95 @@ map[string]string
+
FakeProvider
+
+
+(Appears on:
+SecretStoreProvider)
+
+
+
FakeProvider configures a fake provider that returns static values
+
+
+FakeProviderData
+
+
+(Appears on:
+FakeProvider)
+
+
+
+
+
+
+Field |
+Description |
+
+
+
+
+
+key
+
+string
+
+ |
+
+ |
+
+
+
+value
+
+string
+
+ |
+
+ |
+
+
+
+valueMap
+
+map[string]string
+
+ |
+
+ |
+
+
+
+version
+
+string
+
+ |
+
+ |
+
+
+
GCPSMAuth
@@ -2310,6 +2632,20 @@ WebhookProvider
Webhook configures this store to sync secrets using a generic templated webhook
+
+
+fake
+
+
+FakeProvider
+
+
+ |
+
+(Optional)
+ Fake configures a store with static key/value pairs
+ |
+
SecretStoreRef
diff --git a/e2e/Makefile b/e2e/Makefile
index adaf57e59..b106d5676 100644
--- a/e2e/Makefile
+++ b/e2e/Makefile
@@ -2,7 +2,7 @@ MAKEFLAGS += --warn-undefined-variables
SHELL := /bin/bash
.SHELLFLAGS := -euo pipefail -c
-KIND_IMG = "kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6"
+KIND_IMG = "kindest/node:v1.23.3@sha256:0df8215895129c0d3221cda19847d1296c4f29ec93487339149333bd9d899e5a"
BUILD_ARGS ?=
export E2E_IMAGE_REGISTRY ?= ghcr.io/external-secrets/external-secrets-e2e
diff --git a/e2e/suite/aws/common.go b/e2e/suite/aws/common.go
new file mode 100644
index 000000000..b725b74a7
--- /dev/null
+++ b/e2e/suite/aws/common.go
@@ -0,0 +1,97 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package common
+
+import (
+ "context"
+
+ // nolint
+ . "github.com/onsi/gomega"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+ esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1"
+ "github.com/external-secrets/external-secrets/e2e/framework"
+)
+
+const (
+ WithReferencedIRSA = "with referenced IRSA"
+ WithMountedIRSA = "with mounted IRSA"
+ StaticCredentialsSecretName = "provider-secret"
+)
+
+func ReferencedIRSAStoreName(f *framework.Framework) string {
+ return "irsa-ref-" + f.Namespace.Name
+}
+
+func MountedIRSAStoreName(f *framework.Framework) string {
+ return "irsa-mounted-" + f.Namespace.Name
+}
+
+func UseClusterSecretStore(tc *framework.TestCase) {
+ tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.ClusterSecretStoreKind
+ tc.ExternalSecret.Spec.SecretStoreRef.Name = ReferencedIRSAStoreName(tc.Framework)
+}
+
+func UseMountedIRSAStore(tc *framework.TestCase) {
+ tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.SecretStoreKind
+ tc.ExternalSecret.Spec.SecretStoreRef.Name = MountedIRSAStoreName(tc.Framework)
+}
+
+// StaticStore is namespaced and references
+// static credentials from a secret.
+func SetupStaticStore(f *framework.Framework, kid, sak, region string, serviceType esv1alpha1.AWSServiceType) {
+ awsCreds := &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: StaticCredentialsSecretName,
+ Namespace: f.Namespace.Name,
+ },
+ StringData: map[string]string{
+ "kid": kid,
+ "sak": sak,
+ },
+ }
+ err := f.CRClient.Create(context.Background(), awsCreds)
+ Expect(err).ToNot(HaveOccurred())
+
+ secretStore := &esv1alpha1.SecretStore{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: f.Namespace.Name,
+ Namespace: f.Namespace.Name,
+ },
+ Spec: esv1alpha1.SecretStoreSpec{
+ Provider: &esv1alpha1.SecretStoreProvider{
+ AWS: &esv1alpha1.AWSProvider{
+ Service: serviceType,
+ Region: region,
+ Auth: esv1alpha1.AWSAuth{
+ SecretRef: &esv1alpha1.AWSAuthSecretRef{
+ AccessKeyID: esmetav1.SecretKeySelector{
+ Name: StaticCredentialsSecretName,
+ Key: "kid",
+ },
+ SecretAccessKey: esmetav1.SecretKeySelector{
+ Name: StaticCredentialsSecretName,
+ Key: "sak",
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ err = f.CRClient.Create(context.Background(), secretStore)
+ Expect(err).ToNot(HaveOccurred())
+}
diff --git a/e2e/suite/aws/parameterstore/parameterstore.go b/e2e/suite/aws/parameterstore/parameterstore.go
new file mode 100644
index 000000000..3337bf460
--- /dev/null
+++ b/e2e/suite/aws/parameterstore/parameterstore.go
@@ -0,0 +1,45 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES 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"
+
+ "github.com/external-secrets/external-secrets/e2e/framework"
+ "github.com/external-secrets/external-secrets/e2e/suite/common"
+)
+
+var _ = Describe("[aws] ", Label("aws", "parameterstore"), func() {
+ f := framework.New("eso-aws-ps")
+ prov := NewFromEnv(f)
+
+ DescribeTable("sync secrets",
+ framework.TableFunc(f,
+ prov),
+ Entry(common.SimpleDataSync(f)),
+ Entry(common.NestedJSONWithGJSON(f)),
+ Entry(common.JSONDataFromSync(f)),
+ Entry(common.JSONDataWithProperty(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)),
+ )
+})
diff --git a/e2e/suite/aws/parameterstore/parameterstore_managed.go b/e2e/suite/aws/parameterstore/parameterstore_managed.go
new file mode 100644
index 000000000..5b611cd65
--- /dev/null
+++ b/e2e/suite/aws/parameterstore/parameterstore_managed.go
@@ -0,0 +1,85 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES 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"
+
+ "github.com/external-secrets/external-secrets/e2e/framework"
+ "github.com/external-secrets/external-secrets/e2e/framework/addon"
+ awscommon "github.com/external-secrets/external-secrets/e2e/suite/aws"
+ "github.com/external-secrets/external-secrets/e2e/suite/common"
+)
+
+// 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", "parameterstore", "managed"), func() {
+ f := framework.New("eso-aws-ps-managed")
+ prov := NewFromEnv(f)
+
+ // nolint
+ DescribeTable("sync secrets",
+ framework.TableFunc(f,
+ prov),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.SimpleDataSync, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.NestedJSONWithGJSON, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataFromSync, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithProperty, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithTemplate, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.DockerJSONConfig, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.DataPropertyDockerconfigJSON, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.SSHKeySync, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.SSHKeySyncDataProperty, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.SyncWithoutTargetName, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithoutTargetName, awscommon.UseClusterSecretStore),
+ )
+})
+
+// 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", "parameterstore", "managed"), func() {
+ f := framework.New("eso-aws-ps-irsa-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"),
+ ))
+ })
+
+ // nolint
+ DescribeTable("sync secrets",
+ framework.TableFunc(f,
+ prov),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.SimpleDataSync, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.NestedJSONWithGJSON, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataFromSync, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithProperty, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithTemplate, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.DockerJSONConfig, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.DataPropertyDockerconfigJSON, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.SSHKeySync, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.SSHKeySyncDataProperty, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.SyncWithoutTargetName, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithoutTargetName, awscommon.UseMountedIRSAStore),
+ )
+})
diff --git a/e2e/suite/aws/parameterstore/provider.go b/e2e/suite/aws/parameterstore/provider.go
new file mode 100644
index 000000000..040309af3
--- /dev/null
+++ b/e2e/suite/aws/parameterstore/provider.go
@@ -0,0 +1,165 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES 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 (
+ "context"
+ "os"
+
+ "github.com/aws/aws-sdk-go/aws"
+ "github.com/aws/aws-sdk-go/aws/credentials"
+ "github.com/aws/aws-sdk-go/aws/session"
+ "github.com/aws/aws-sdk-go/service/ssm"
+
+ //nolint
+ . "github.com/onsi/ginkgo/v2"
+
+ // nolint
+ . "github.com/onsi/gomega"
+ 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"
+ esmetav1 "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"
+ common "github.com/external-secrets/external-secrets/e2e/suite/aws"
+)
+
+type Provider struct {
+ ServiceAccountName string
+ ServiceAccountNamespace string
+
+ region string
+ client *ssm.SSM
+ framework *framework.Framework
+}
+
+func NewProvider(f *framework.Framework, kid, sak, region, saName, saNamespace string) *Provider {
+ sess, err := session.NewSessionWithOptions(session.Options{
+ Config: aws.Config{
+ Credentials: credentials.NewStaticCredentials(kid, sak, ""),
+ Region: aws.String(region),
+ },
+ })
+ if err != nil {
+ Fail(err.Error())
+ }
+ sm := ssm.New(sess)
+ prov := &Provider{
+ ServiceAccountName: saName,
+ ServiceAccountNamespace: saNamespace,
+ region: region,
+ client: sm,
+ framework: f,
+ }
+
+ BeforeEach(func() {
+ common.SetupStaticStore(f, kid, sak, region, esv1alpha1.AWSServiceParameterStore)
+ prov.SetupReferencedIRSAStore()
+ prov.SetupMountedIRSAStore()
+ })
+
+ AfterEach(func() {
+ // Cleanup ClusterSecretStore
+ err := prov.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: common.ReferencedIRSAStoreName(f),
+ },
+ })
+ Expect(err).ToNot(HaveOccurred())
+ })
+
+ return prov
+}
+
+func NewFromEnv(f *framework.Framework) *Provider {
+ 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 NewProvider(f, kid, sak, region, saName, saNamespace)
+}
+
+// CreateSecret creates a secret at the provider.
+func (s *Provider) CreateSecret(key, val string) {
+ _, err := s.client.PutParameter(&ssm.PutParameterInput{
+ Name: aws.String(key),
+ Value: aws.String(val),
+ DataType: aws.String("text"),
+ Type: aws.String("String"),
+ })
+ Expect(err).ToNot(HaveOccurred())
+}
+
+// DeleteSecret deletes a secret at the provider.
+func (s *Provider) DeleteSecret(key string) {
+ _, err := s.client.DeleteParameter(&ssm.DeleteParameterInput{
+ Name: aws.String(key),
+ })
+ Expect(err).ToNot(HaveOccurred())
+}
+
+// MountedIRSAStore is a SecretStore without auth config
+// ESO relies on the pod-mounted ServiceAccount when using this store.
+func (s *Provider) SetupMountedIRSAStore() {
+ secretStore := &esv1alpha1.SecretStore{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: common.MountedIRSAStoreName(s.framework),
+ Namespace: s.framework.Namespace.Name,
+ },
+ Spec: esv1alpha1.SecretStoreSpec{
+ Provider: &esv1alpha1.SecretStoreProvider{
+ AWS: &esv1alpha1.AWSProvider{
+ Service: esv1alpha1.AWSServiceParameterStore,
+ Region: s.region,
+ Auth: esv1alpha1.AWSAuth{},
+ },
+ },
+ },
+ }
+ err := s.framework.CRClient.Create(context.Background(), secretStore)
+ Expect(err).ToNot(HaveOccurred())
+}
+
+// ReferncedIRSAStore is a ClusterStore
+// that references a (IRSA-) ServiceAccount in the default namespace.
+func (s *Provider) SetupReferencedIRSAStore() {
+ log.Logf("creating IRSA ClusterSecretStore %s", s.framework.Namespace.Name)
+ secretStore := &esv1alpha1.ClusterSecretStore{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: common.ReferencedIRSAStoreName(s.framework),
+ },
+ }
+ _, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, secretStore, func() error {
+ secretStore.Spec.Provider = &esv1alpha1.SecretStoreProvider{
+ AWS: &esv1alpha1.AWSProvider{
+ Service: esv1alpha1.AWSServiceParameterStore,
+ Region: s.region,
+ Auth: esv1alpha1.AWSAuth{
+ JWTAuth: &esv1alpha1.AWSJWTAuth{
+ ServiceAccountRef: &esmetav1.ServiceAccountSelector{
+ Name: s.ServiceAccountName,
+ Namespace: &s.ServiceAccountNamespace,
+ },
+ },
+ },
+ },
+ }
+ return nil
+ })
+ Expect(err).ToNot(HaveOccurred())
+}
diff --git a/e2e/suite/aws/provider.go b/e2e/suite/aws/secretsmanager/provider.go
similarity index 67%
rename from e2e/suite/aws/provider.go
rename to e2e/suite/aws/secretsmanager/provider.go
index 3e1bc0185..61ef9c1e8 100644
--- a/e2e/suite/aws/provider.go
+++ b/e2e/suite/aws/secretsmanager/provider.go
@@ -29,7 +29,6 @@ import (
// 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"
@@ -37,24 +36,19 @@ import (
esmetav1 "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"
+ common "github.com/external-secrets/external-secrets/e2e/suite/aws"
)
-type SMProvider struct {
+type Provider struct {
ServiceAccountName string
ServiceAccountNamespace string
- kid string
- sak string
region string
client *secretsmanager.SecretsManager
framework *framework.Framework
}
-const (
- staticCredentialsSecretName = "provider-secret"
-)
-
-func NewSMProvider(f *framework.Framework, kid, sak, region, saName, saNamespace string) *SMProvider {
+func NewProvider(f *framework.Framework, kid, sak, region, saName, saNamespace string) *Provider {
sess, err := session.NewSessionWithOptions(session.Options{
Config: aws.Config{
Credentials: credentials.NewStaticCredentials(kid, sak, ""),
@@ -65,18 +59,16 @@ func NewSMProvider(f *framework.Framework, kid, sak, region, saName, saNamespace
Fail(err.Error())
}
sm := secretsmanager.New(sess)
- prov := &SMProvider{
+ prov := &Provider{
ServiceAccountName: saName,
ServiceAccountNamespace: saNamespace,
- kid: kid,
- sak: sak,
region: region,
client: sm,
framework: f,
}
BeforeEach(func() {
- prov.SetupStaticStore()
+ common.SetupStaticStore(f, kid, sak, region, esv1alpha1.AWSServiceSecretsManager)
prov.SetupReferencedIRSAStore()
prov.SetupMountedIRSAStore()
})
@@ -85,7 +77,7 @@ func NewSMProvider(f *framework.Framework, kid, sak, region, saName, saNamespace
// Cleanup ClusterSecretStore
err := prov.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{
ObjectMeta: metav1.ObjectMeta{
- Name: prov.ReferencedIRSAStoreName(),
+ Name: common.ReferencedIRSAStoreName(f),
},
})
Expect(err).ToNot(HaveOccurred())
@@ -94,17 +86,17 @@ func NewSMProvider(f *framework.Framework, kid, sak, region, saName, saNamespace
return prov
}
-func NewFromEnv(f *framework.Framework) *SMProvider {
+func NewFromEnv(f *framework.Framework) *Provider {
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)
+ return NewProvider(f, kid, sak, region, saName, saNamespace)
}
// CreateSecret creates a secret at the provider.
-func (s *SMProvider) CreateSecret(key, val string) {
+func (s *Provider) 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
@@ -129,7 +121,7 @@ func (s *SMProvider) CreateSecret(key, val string) {
// 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) {
+func (s *Provider) DeleteSecret(key string) {
log.Logf("deleting secret %s", key)
_, err := s.client.DeleteSecret(&secretsmanager.DeleteSecretInput{
SecretId: aws.String(key),
@@ -140,10 +132,10 @@ func (s *SMProvider) DeleteSecret(key string) {
// MountedIRSAStore is a SecretStore without auth config
// ESO relies on the pod-mounted ServiceAccount when using this store.
-func (s *SMProvider) SetupMountedIRSAStore() {
+func (s *Provider) SetupMountedIRSAStore() {
secretStore := &esv1alpha1.SecretStore{
ObjectMeta: metav1.ObjectMeta{
- Name: s.MountedIRSAStoreName(),
+ Name: common.MountedIRSAStoreName(s.framework),
Namespace: s.framework.Namespace.Name,
},
Spec: esv1alpha1.SecretStoreSpec{
@@ -160,17 +152,13 @@ func (s *SMProvider) SetupMountedIRSAStore() {
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() {
+func (s *Provider) SetupReferencedIRSAStore() {
log.Logf("creating IRSA ClusterSecretStore %s", s.framework.Namespace.Name)
secretStore := &esv1alpha1.ClusterSecretStore{
ObjectMeta: metav1.ObjectMeta{
- Name: s.ReferencedIRSAStoreName(),
+ Name: common.ReferencedIRSAStoreName(s.framework),
},
}
_, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, secretStore, func() error {
@@ -192,53 +180,3 @@ func (s *SMProvider) SetupReferencedIRSAStore() {
})
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: staticCredentialsSecretName,
- Namespace: s.framework.Namespace.Name,
- },
- StringData: map[string]string{
- "kid": s.kid,
- "sak": s.sak,
- },
- }
- err := s.framework.CRClient.Create(context.Background(), awsCreds)
- Expect(err).ToNot(HaveOccurred())
-
- secretStore := &esv1alpha1.SecretStore{
- ObjectMeta: metav1.ObjectMeta{
- Name: s.framework.Namespace.Name,
- Namespace: s.framework.Namespace.Name,
- },
- Spec: esv1alpha1.SecretStoreSpec{
- Provider: &esv1alpha1.SecretStoreProvider{
- AWS: &esv1alpha1.AWSProvider{
- Service: esv1alpha1.AWSServiceSecretsManager,
- Region: s.region,
- Auth: esv1alpha1.AWSAuth{
- SecretRef: &esv1alpha1.AWSAuthSecretRef{
- AccessKeyID: esmetav1.SecretKeySelector{
- Name: staticCredentialsSecretName,
- Key: "kid",
- },
- SecretAccessKey: esmetav1.SecretKeySelector{
- Name: staticCredentialsSecretName,
- Key: "sak",
- },
- },
- },
- },
- },
- },
- }
- err = s.framework.CRClient.Create(context.Background(), secretStore)
- Expect(err).ToNot(HaveOccurred())
-}
diff --git a/e2e/suite/aws/secretsmanager.go b/e2e/suite/aws/secretsmanager/secretsmanager.go
similarity index 100%
rename from e2e/suite/aws/secretsmanager.go
rename to e2e/suite/aws/secretsmanager/secretsmanager.go
diff --git a/e2e/suite/aws/secretsmanager/secretsmanager_managed.go b/e2e/suite/aws/secretsmanager/secretsmanager_managed.go
new file mode 100644
index 000000000..84f2e9509
--- /dev/null
+++ b/e2e/suite/aws/secretsmanager/secretsmanager_managed.go
@@ -0,0 +1,85 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES 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"
+
+ "github.com/external-secrets/external-secrets/e2e/framework"
+ "github.com/external-secrets/external-secrets/e2e/framework/addon"
+ awscommon "github.com/external-secrets/external-secrets/e2e/suite/aws"
+ "github.com/external-secrets/external-secrets/e2e/suite/common"
+)
+
+// 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)
+
+ // nolint
+ DescribeTable("sync secretsmanager secrets",
+ framework.TableFunc(f,
+ prov),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.SimpleDataSync, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.NestedJSONWithGJSON, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataFromSync, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithProperty, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithTemplate, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.DockerJSONConfig, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.DataPropertyDockerconfigJSON, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.SSHKeySync, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.SSHKeySyncDataProperty, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.SyncWithoutTargetName, awscommon.UseClusterSecretStore),
+ framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithoutTargetName, awscommon.UseClusterSecretStore),
+ )
+})
+
+// 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"),
+ ))
+ })
+
+ // nolint
+ DescribeTable("sync secretsmanager secrets",
+ framework.TableFunc(f,
+ prov),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.SimpleDataSync, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.NestedJSONWithGJSON, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataFromSync, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithProperty, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithTemplate, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.DockerJSONConfig, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.DataPropertyDockerconfigJSON, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.SSHKeySync, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.SSHKeySyncDataProperty, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.SyncWithoutTargetName, awscommon.UseMountedIRSAStore),
+ framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithoutTargetName, awscommon.UseMountedIRSAStore),
+ )
+})
diff --git a/e2e/suite/aws/secretsmanager_managed.go b/e2e/suite/aws/secretsmanager_managed.go
deleted file mode 100644
index 6d83d3d73..000000000
--- a/e2e/suite/aws/secretsmanager_managed.go
+++ /dev/null
@@ -1,102 +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 aws
-
-import (
-
- // nolint
- . "github.com/onsi/ginkgo/v2"
-
- esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
- "github.com/external-secrets/external-secrets/e2e/framework"
- "github.com/external-secrets/external-secrets/e2e/framework/addon"
- "github.com/external-secrets/external-secrets/e2e/suite/common"
-)
-
-const (
- withReferencedIRSA = "with referenced IRSA"
- withMountedIRSA = "with mounted IRSA"
-)
-
-// here we use the global eso instance
-// that uses the service account in the default namespace
-// which was created by terraform.
-var _ = Describe("[awsmanaged] IRSA via referenced service account", Label("aws", "secretsmanager", "managed"), func() {
- f := framework.New("eso-aws-managed")
- prov := NewFromEnv(f)
-
- DescribeTable("sync secrets",
- framework.TableFunc(f,
- prov),
- framework.Compose(withReferencedIRSA, f, common.SimpleDataSync, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.NestedJSONWithGJSON, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.JSONDataFromSync, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.JSONDataWithProperty, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.JSONDataWithTemplate, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.DockerJSONConfig, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.DataPropertyDockerconfigJSON, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.SSHKeySync, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.SSHKeySyncDataProperty, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.SyncWithoutTargetName, useClusterSecretStore(prov)),
- framework.Compose(withReferencedIRSA, f, common.JSONDataWithoutTargetName, useClusterSecretStore(prov)),
- )
-})
-
-// here we create a central eso instance in the default namespace
-// that mounts the service account which was created by terraform.
-var _ = Describe("[awsmanaged] with mounted IRSA", Label("aws", "secretsmanager", "managed"), func() {
- f := framework.New("eso-aws-managed")
- prov := NewFromEnv(f)
-
- // each test case gets its own ESO instance
- BeforeEach(func() {
- f.Install(addon.NewESO(
- addon.WithControllerClass(f.BaseName),
- addon.WithServiceAccount(prov.ServiceAccountName),
- addon.WithReleaseName(f.Namespace.Name),
- addon.WithNamespace("default"),
- ))
- })
-
- DescribeTable("sync secrets",
- framework.TableFunc(f,
- prov),
- framework.Compose(withMountedIRSA, f, common.SimpleDataSync, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.NestedJSONWithGJSON, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.JSONDataFromSync, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.JSONDataWithProperty, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.JSONDataWithTemplate, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.DockerJSONConfig, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.DataPropertyDockerconfigJSON, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.SSHKeySync, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.SSHKeySyncDataProperty, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.SyncWithoutTargetName, useMountedIRSAStore(prov)),
- framework.Compose(withMountedIRSA, f, common.JSONDataWithoutTargetName, useMountedIRSAStore(prov)),
- )
-})
-
-func useClusterSecretStore(prov *SMProvider) func(*framework.TestCase) {
- return func(tc *framework.TestCase) {
- tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.ClusterSecretStoreKind
- tc.ExternalSecret.Spec.SecretStoreRef.Name = prov.ReferencedIRSAStoreName()
- }
-}
-
-func useMountedIRSAStore(prov *SMProvider) func(*framework.TestCase) {
- return func(tc *framework.TestCase) {
- tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.SecretStoreKind
- tc.ExternalSecret.Spec.SecretStoreRef.Name = prov.MountedIRSAStoreName()
- }
-}
diff --git a/e2e/suite/azure/azure_cert.go b/e2e/suite/azure/azure_cert.go
new file mode 100644
index 000000000..46ec353d1
--- /dev/null
+++ b/e2e/suite/azure/azure_cert.go
@@ -0,0 +1,66 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in 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 azure
+
+import (
+ "fmt"
+
+ // nolint
+ . "github.com/onsi/ginkgo/v2"
+ v1 "k8s.io/api/core/v1"
+
+ // nolint
+ esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+ "github.com/external-secrets/external-secrets/e2e/framework"
+)
+
+// azure keyvault type=cert should get a certificate from the api.
+var _ = Describe("[azure]", Label("azure", "keyvault", "cert"), func() {
+ f := framework.New("eso-azure-certtype")
+ prov := newFromEnv(f)
+ var certBytes []byte
+ var certName string
+
+ BeforeEach(func() {
+ certName = fmt.Sprintf("%s-%s", f.Namespace.Name, "certtest")
+ prov.CreateCertificate(certName)
+ certBytes = prov.GetCertificate(certName)
+ })
+
+ AfterEach(func() {
+ prov.DeleteCertificate(certName)
+ })
+
+ ff := framework.TableFunc(f, prov)
+ It("should sync keyvault objects with type=cert", func() {
+ ff(func(tc *framework.TestCase) {
+ secretKey := "azkv-cert"
+
+ tc.ExpectedSecret = &v1.Secret{
+ Type: v1.SecretTypeOpaque,
+ Data: map[string][]byte{
+ secretKey: certBytes,
+ },
+ }
+ tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+ {
+ SecretKey: secretKey,
+ RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+ Key: "cert/" + certName,
+ },
+ },
+ }
+ })
+ })
+
+})
diff --git a/e2e/suite/azure/azure_key.go b/e2e/suite/azure/azure_key.go
new file mode 100644
index 000000000..d9da2b501
--- /dev/null
+++ b/e2e/suite/azure/azure_key.go
@@ -0,0 +1,69 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in 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 azure
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/Azure/azure-sdk-for-go/profiles/latest/keyvault/keyvault"
+
+ // nolint
+ . "github.com/onsi/ginkgo/v2"
+ v1 "k8s.io/api/core/v1"
+
+ esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+ "github.com/external-secrets/external-secrets/e2e/framework"
+)
+
+// azure keyvault type=key should retrieve a jwk from the api.
+var _ = Describe("[azure]", Label("azure", "keyvault", "key"), func() {
+ f := framework.New("eso-azure-keytype")
+ prov := newFromEnv(f)
+ var jwk *keyvault.JSONWebKey
+ var keyName string
+
+ BeforeEach(func() {
+ keyName = fmt.Sprintf("%s-%s", f.Namespace.Name, "keytest")
+ jwk = prov.CreateKey(keyName)
+ })
+
+ AfterEach(func() {
+ prov.DeleteKey(keyName)
+ })
+
+ ff := framework.TableFunc(f, prov)
+
+ It("should sync keyvault objects with type=key", func() {
+ ff(func(tc *framework.TestCase) {
+ secretKey := "azkv-key"
+ keyBytes, _ := json.Marshal(jwk)
+
+ tc.ExpectedSecret = &v1.Secret{
+ Type: v1.SecretTypeOpaque,
+ Data: map[string][]byte{
+ secretKey: keyBytes,
+ },
+ }
+ tc.ExternalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{
+ {
+ SecretKey: secretKey,
+ RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
+ Key: "key/" + keyName,
+ },
+ },
+ }
+ })
+ })
+
+})
diff --git a/e2e/suite/azure/azure.go b/e2e/suite/azure/azure_secret.go
similarity index 89%
rename from e2e/suite/azure/azure.go
rename to e2e/suite/azure/azure_secret.go
index 79a96aef5..818ecb390 100644
--- a/e2e/suite/azure/azure.go
+++ b/e2e/suite/azure/azure_secret.go
@@ -21,7 +21,8 @@ import (
"github.com/external-secrets/external-secrets/e2e/suite/common"
)
-var _ = Describe("[azure]", Label("azure", "keyvault"), func() {
+// keyvault type=secret should behave just like any other secret store.
+var _ = Describe("[azure]", Label("azure", "keyvault", "secret"), func() {
f := framework.New("eso-azure")
prov := newFromEnv(f)
diff --git a/e2e/suite/azure/provider.go b/e2e/suite/azure/provider.go
index 7354176db..b035bc64e 100644
--- a/e2e/suite/azure/provider.go
+++ b/e2e/suite/azure/provider.go
@@ -15,16 +15,15 @@ package azure
import (
"context"
"os"
+ "time"
"github.com/Azure/azure-sdk-for-go/profiles/latest/keyvault/keyvault"
kvauth "github.com/Azure/go-autorest/autorest/azure/auth"
- // nolint
- . "github.com/onsi/gomega"
-
// nolint
. "github.com/onsi/ginkgo/v2"
-
+ // nolint
+ . "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilpointer "k8s.io/utils/pointer"
@@ -100,6 +99,83 @@ func (s *azureProvider) DeleteSecret(key string) {
Expect(err).ToNot(HaveOccurred())
}
+func (s *azureProvider) CreateKey(key string) *keyvault.JSONWebKey {
+ out, err := s.client.CreateKey(
+ context.Background(),
+ s.vaultURL,
+ key,
+ keyvault.KeyCreateParameters{
+ Kty: keyvault.RSA,
+ KeyAttributes: &keyvault.KeyAttributes{
+ RecoveryLevel: keyvault.Purgeable,
+ Enabled: utilpointer.BoolPtr(true),
+ },
+ },
+ )
+ Expect(err).ToNot(HaveOccurred())
+ return out.Key
+}
+
+func (s *azureProvider) DeleteKey(key string) {
+ _, err := s.client.DeleteKey(context.Background(), s.vaultURL, key)
+ Expect(err).ToNot(HaveOccurred())
+}
+
+func (s *azureProvider) CreateCertificate(key string) {
+ _, err := s.client.CreateCertificate(
+ context.Background(),
+ s.vaultURL,
+ key,
+ keyvault.CertificateCreateParameters{
+ CertificatePolicy: &keyvault.CertificatePolicy{
+ X509CertificateProperties: &keyvault.X509CertificateProperties{
+ Subject: utilpointer.String("CN=e2e.test"),
+ ValidityInMonths: utilpointer.Int32(42),
+ },
+ IssuerParameters: &keyvault.IssuerParameters{
+ Name: utilpointer.String("Self"),
+ },
+ Attributes: &keyvault.CertificateAttributes{
+ RecoveryLevel: keyvault.Purgeable,
+ Enabled: utilpointer.BoolPtr(true),
+ },
+ },
+ CertificateAttributes: &keyvault.CertificateAttributes{
+ RecoveryLevel: keyvault.Purgeable,
+ Enabled: utilpointer.BoolPtr(true),
+ },
+ },
+ )
+ Expect(err).ToNot(HaveOccurred())
+}
+
+func (s *azureProvider) GetCertificate(key string) []byte {
+ attempts := 20
+ for {
+ out, err := s.client.GetCertificate(
+ context.Background(),
+ s.vaultURL,
+ key,
+ "",
+ )
+ Expect(err).ToNot(HaveOccurred())
+ if out.Cer != nil {
+ return *out.Cer
+ }
+
+ attempts--
+ if attempts <= 0 {
+ Fail("failed fetching azkv certificate")
+ }
+ <-time.After(time.Second * 5)
+ }
+}
+
+func (s *azureProvider) DeleteCertificate(key string) {
+ _, err := s.client.DeleteCertificate(context.Background(), s.vaultURL, key)
+ Expect(err).ToNot(HaveOccurred())
+}
+
func (s *azureProvider) CreateSecretStore() {
azureCreds := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
diff --git a/e2e/suite/import.go b/e2e/suite/import.go
index fd9c332f8..6e5d5fdb6 100644
--- a/e2e/suite/import.go
+++ b/e2e/suite/import.go
@@ -16,7 +16,8 @@ package suite
import (
// import different e2e test suites.
- _ "github.com/external-secrets/external-secrets/e2e/suite/aws"
+ _ "github.com/external-secrets/external-secrets/e2e/suite/aws/parameterstore"
+ _ "github.com/external-secrets/external-secrets/e2e/suite/aws/secretsmanager"
_ "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/vault"
diff --git a/go.mod b/go.mod
index 9845e864f..f3239e312 100644
--- a/go.mod
+++ b/go.mod
@@ -33,7 +33,7 @@ replace (
)
require (
- cloud.google.com/go v0.99.0
+ cloud.google.com/go v0.100.2 // indirect
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
@@ -45,33 +45,33 @@ require (
github.com/PaesslerAG/jsonpath v0.1.1
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.1458
+ github.com/akeylesslabs/akeyless-go/v2 v2.15.25
+ github.com/aliyun/alibaba-cloud-sdk-go v1.61.1473
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.7
github.com/google/uuid v1.2.0
- github.com/googleapis/gax-go v1.0.3
+ github.com/googleapis/gax-go/v2 v2.1.1
github.com/hashicorp/vault/api v1.3.1
github.com/huandu/xstrings v1.3.2 // indirect
github.com/lestrrat-go/jwx v1.2.1
- github.com/onsi/ginkgo/v2 v2.0.0
+ github.com/onsi/ginkgo/v2 v2.1.1
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
github.com/prometheus/client_model v0.2.0
github.com/stretchr/testify v1.7.0
github.com/tidwall/gjson v1.12.1
- github.com/xanzy/go-gitlab v0.50.1
+ github.com/xanzy/go-gitlab v0.54.3
github.com/yandex-cloud/go-genproto v0.0.0-20210809082946-a97da516c588
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-20220112180741-5e0467b6c7ce
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
- google.golang.org/api v0.61.0
+ google.golang.org/api v0.64.0
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
@@ -85,7 +85,10 @@ require (
software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78
)
+require cloud.google.com/go/iam v0.1.1
+
require (
+ cloud.google.com/go/compute v0.1.0 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect
@@ -95,7 +98,6 @@ require (
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
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
@@ -103,16 +105,11 @@ require (
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
- github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
- 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.13.0 // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
@@ -131,10 +128,9 @@ require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
- github.com/google/go-querystring v1.0.0 // indirect
+ github.com/google/go-querystring v1.1.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.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
@@ -194,8 +190,6 @@ require (
go.opencensus.io v0.23.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-20220114011407-0dd24b26b47d // indirect
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
@@ -212,7 +206,6 @@ require (
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
k8s.io/component-base v0.23.0 // indirect
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c // indirect
diff --git a/go.sum b/go.sum
index e13b10d47..0da8eafef 100644
--- a/go.sum
+++ b/go.sum
@@ -25,17 +25,23 @@ cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aD
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
-cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
+cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U=
+cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
+cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/compute v0.1.0 h1:rSUBvAyVwNJ5uQCKNJFMwPtTvJkfN38b6Pvb9zZoqJ8=
+cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
+cloud.google.com/go/iam v0.1.1 h1:4CapQyNFjiksks1/x7jsvsygFPhihslYk5GptIrlX68=
+cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -78,7 +84,6 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
@@ -107,15 +112,15 @@ github.com/ahmetb/gen-crd-api-reference-docs v0.3.0 h1:+XfOU14S4bGuwyvCijJwhhBIj
github.com/ahmetb/gen-crd-api-reference-docs v0.3.0/go.mod h1:TdjdkYhlOifCQWPs1UdTma97kQQMozf5h26hTuG70u8=
github.com/akeylesslabs/akeyless-go-cloud-id v0.3.2 h1:1h4udX3Y5KgSG0m4Th2bHfaYxZB9fbngiij9PrKEp6c=
github.com/akeylesslabs/akeyless-go-cloud-id v0.3.2/go.mod h1:ionnWiARf5TYoFGuHS7syh51/7lYosZejpZbnECFJcU=
-github.com/akeylesslabs/akeyless-go/v2 v2.15.24 h1:q++f8n4l66kSptlo9cxrYq8fGHg25GdjqOsw0vbKUAE=
-github.com/akeylesslabs/akeyless-go/v2 v2.15.24/go.mod h1:uOdXD49NCCe4rexeSc2aBU5Qv4KZgJE6YlbtYalvb+I=
+github.com/akeylesslabs/akeyless-go/v2 v2.15.25 h1:9iztd2fXVfj4b3LRsyvGNRheFoz8IFs/+K4GaAshZc4=
+github.com/akeylesslabs/akeyless-go/v2 v2.15.25/go.mod h1:uOdXD49NCCe4rexeSc2aBU5Qv4KZgJE6YlbtYalvb+I=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
-github.com/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/aliyun/alibaba-cloud-sdk-go v1.61.1473 h1:rUoiu7Duq0hr4mjlQWZMORKaCbNXaYvYN2HFJQt228E=
+github.com/aliyun/alibaba-cloud-sdk-go v1.61.1473/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=
@@ -152,7 +157,6 @@ github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9cop
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=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
@@ -170,12 +174,10 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
@@ -222,9 +224,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
-github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
-github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
@@ -340,7 +340,6 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
@@ -391,8 +390,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
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/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
+github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
@@ -422,9 +421,6 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/gax-go v1.0.3 h1:9dMLqhaibYONnDRcnHdUs9P8Mw64jLlZTYlDe3leBtQ=
-github.com/googleapis/gax-go v1.0.3/go.mod h1:QyXYajJFdARxGzjwUfbDFIse7Spkw81SJ4LrBJXtlQ8=
-github.com/googleapis/gax-go/v2 v2.0.2/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
@@ -682,8 +678,8 @@ github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvw
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/ginkgo/v2 v2.1.1 h1:LCnPB85AvFNr91s0B2aDzEiiIg6MUwLYbryC1NSlWi8=
+github.com/onsi/ginkgo/v2 v2.1.1/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=
@@ -814,8 +810,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
-github.com/xanzy/go-gitlab v0.50.1 h1:eH1G0/ZV1j81rhGrtbcePjbM5Ern7mPA4Xjt+yE+2PQ=
-github.com/xanzy/go-gitlab v0.50.1/go.mod h1:Q+hQhV508bDPoBijv7YjK/Lvlb4PhVhJdKqXVQrUoAE=
+github.com/xanzy/go-gitlab v0.54.3 h1:fPfZ3Jcu5dPc3xyIYtAALZsEgoyKNFNuULD+TdJ7Zvk=
+github.com/xanzy/go-gitlab v0.54.3/go.mod h1:F0QEXwmqiBUxCgJm8fE9S+1veX4XC9Z4cfaAbqwk4YM=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
@@ -904,7 +900,6 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y
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=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
@@ -914,11 +909,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 h1:FR+oGxGfbQu1d+jglI3rCkjAjUnhRSZcUxr+DqlDLNo=
-golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -930,7 +922,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
@@ -1109,6 +1100,8 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc
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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 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=
@@ -1135,7 +1128,6 @@ golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxb
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=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1243,8 +1235,10 @@ google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
-google.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8=
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
+google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
+google.golang.org/api v0.64.0 h1:l3pi8ncrQgB9+ncFw3A716L8lWujnXniBYbxWqqy6tE=
+google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1319,10 +1313,13 @@ google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ6
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/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
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=
@@ -1348,6 +1345,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.40.1/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=
@@ -1413,7 +1411,6 @@ gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919 h1:tmXTu+dfa+d9Evp8NpJdgOy6+rt8/x4yG7qPBrtNfLY=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
-honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -1421,8 +1418,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.1.4 h1:SadWOkti5uVN1FAMgxn165+Mw00fuQKyk4Gyn/inxNQ=
-honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
k8s.io/api v0.23.0 h1:WrL1gb73VSC8obi8cuYETJGXEoFNEh3LU0Pt+Sokgro=
k8s.io/api v0.23.0/go.mod h1:8wmDdLBHBNxtOIytwLstXt5E9PddnZb0GaMcqsvDBpg=
k8s.io/apiextensions-apiserver v0.23.0 h1:uii8BYmHYiT2ZTAJxmvc3X8UhNYMxl2A0z0Xq3Pm+WY=
diff --git a/hack/api-docs/mkdocs.yml b/hack/api-docs/mkdocs.yml
index 3490cd1b5..35413fac1 100644
--- a/hack/api-docs/mkdocs.yml
+++ b/hack/api-docs/mkdocs.yml
@@ -61,6 +61,7 @@ nav:
- Oracle:
- Oracle Vault: provider-oracle-vault.md
- Webhook: provider-webhook.md
+ - Fake: provider-fake.md
- References:
- API specification: spec.md
- Contributing:
diff --git a/pkg/controllers/externalsecret/externalsecret_controller_template.go b/pkg/controllers/externalsecret/externalsecret_controller_template.go
index b20e416e4..a3d9463d8 100644
--- a/pkg/controllers/externalsecret/externalsecret_controller_template.go
+++ b/pkg/controllers/externalsecret/externalsecret_controller_template.go
@@ -64,9 +64,7 @@ func (r *Reconciler) applyTemplate(ctx context.Context, es *esv1alpha1.ExternalS
// if no data was provided by template fallback
// to value from the provider
if len(es.Spec.Target.Template.Data) == 0 {
- for k, v := range dataMap {
- secret.Data[k] = v
- }
+ secret.Data = dataMap
}
secret.Annotations[esv1alpha1.AnnotationDataHash] = utils.ObjectHash(secret.Data)
diff --git a/pkg/controllers/externalsecret/externalsecret_controller_test.go b/pkg/controllers/externalsecret/externalsecret_controller_test.go
index 151d63569..64e9a6b60 100644
--- a/pkg/controllers/externalsecret/externalsecret_controller_test.go
+++ b/pkg/controllers/externalsecret/externalsecret_controller_test.go
@@ -31,8 +31,8 @@ import (
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
"github.com/external-secrets/external-secrets/pkg/provider"
- "github.com/external-secrets/external-secrets/pkg/provider/fake"
"github.com/external-secrets/external-secrets/pkg/provider/schema"
+ "github.com/external-secrets/external-secrets/pkg/provider/testing/fake"
)
var (
@@ -654,6 +654,85 @@ var _ = Describe("ExternalSecret controller", func() {
}
}
+ // when a provider secret was deleted it must be deleted from
+ // the secret aswell
+ refreshSecretValueMap := func(tc *testCase) {
+ fakeProvider.WithGetSecretMap(map[string][]byte{
+ "foo": []byte("1111"),
+ "bar": []byte("2222"),
+ }, nil)
+ tc.externalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{}
+ tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
+ {
+ Key: remoteKey,
+ },
+ }
+ tc.externalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second}
+ tc.checkSecret = func(es *esv1alpha1.ExternalSecret, secret *v1.Secret) {
+ // check values
+ Expect(string(secret.Data["foo"])).To(Equal("1111"))
+ Expect(string(secret.Data["bar"])).To(Equal("2222"))
+
+ // update provider secret
+ sec := &v1.Secret{}
+ fakeProvider.WithGetSecretMap(map[string][]byte{
+ "foo": []byte("1111"),
+ }, nil)
+ secretLookupKey := types.NamespacedName{
+ Name: ExternalSecretTargetSecretName,
+ Namespace: ExternalSecretNamespace,
+ }
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(), secretLookupKey, sec)
+ if err != nil {
+ return false
+ }
+ return string(sec.Data["foo"]) == "1111" &&
+ sec.Data["bar"] == nil // must not be defined, it was deleted
+ }, timeout, interval).Should(BeTrue())
+ }
+ }
+
+ // when a provider secret was deleted it must be deleted from
+ // the secret aswell when using a template
+ refreshSecretValueMapTemplate := func(tc *testCase) {
+ fakeProvider.WithGetSecretMap(map[string][]byte{
+ "foo": []byte("1111"),
+ "bar": []byte("2222"),
+ }, nil)
+ tc.externalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{}
+ tc.externalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{}
+ tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
+ {
+ Key: remoteKey,
+ },
+ }
+ tc.externalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second}
+ tc.checkSecret = func(es *esv1alpha1.ExternalSecret, secret *v1.Secret) {
+ // check values
+ Expect(string(secret.Data["foo"])).To(Equal("1111"))
+ Expect(string(secret.Data["bar"])).To(Equal("2222"))
+
+ // update provider secret
+ sec := &v1.Secret{}
+ fakeProvider.WithGetSecretMap(map[string][]byte{
+ "foo": []byte("1111"),
+ }, nil)
+ secretLookupKey := types.NamespacedName{
+ Name: ExternalSecretTargetSecretName,
+ Namespace: ExternalSecretNamespace,
+ }
+ Eventually(func() bool {
+ err := k8sClient.Get(context.Background(), secretLookupKey, sec)
+ if err != nil {
+ return false
+ }
+ return string(sec.Data["foo"]) == "1111" &&
+ sec.Data["bar"] == nil // must not be defined, it was deleted
+ }, timeout, interval).Should(BeTrue())
+ }
+ }
+
refreshintervalZero := func(tc *testCase) {
const targetProp = "targetProperty"
const secretVal = "someValue"
@@ -971,6 +1050,8 @@ var _ = Describe("ExternalSecret controller", func() {
Entry("should refresh secret from template", refreshWithTemplate),
Entry("should be able to use only metadata from template", onlyMetadataFromTemplate),
Entry("should refresh secret value when provider secret changes", refreshSecretValue),
+ Entry("should refresh secret map when provider secret changes", refreshSecretValueMap),
+ Entry("should refresh secret map when provider secret changes when using a template", refreshSecretValueMapTemplate),
Entry("should not refresh secret value when provider secret changes but refreshInterval is zero", refreshintervalZero),
Entry("should fetch secret using dataFrom", syncWithDataFrom),
Entry("should fetch secret using dataFrom and a template", syncWithDataFromTemplate),
diff --git a/pkg/controllers/externalsecret/metrics.go b/pkg/controllers/externalsecret/metrics.go
index 75b69a306..721cb4b7e 100644
--- a/pkg/controllers/externalsecret/metrics.go
+++ b/pkg/controllers/externalsecret/metrics.go
@@ -16,6 +16,7 @@ package externalsecret
import (
"github.com/prometheus/client_golang/prometheus"
+ v1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/metrics"
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
@@ -50,6 +51,62 @@ var (
// updateExternalSecretCondition updates the ExternalSecret conditions.
func updateExternalSecretCondition(es *esv1alpha1.ExternalSecret, condition *esv1alpha1.ExternalSecretStatusCondition, value float64) {
+ switch condition.Type {
+ case esv1alpha1.ExternalSecretDeleted:
+ // Remove condition=Ready metrics when the object gets deleted.
+ externalSecretCondition.Delete(prometheus.Labels{
+ "name": es.Name,
+ "namespace": es.Namespace,
+ "condition": string(esv1alpha1.ExternalSecretReady),
+ "status": string(v1.ConditionFalse),
+ })
+ externalSecretCondition.Delete(prometheus.Labels{
+ "name": es.Name,
+ "namespace": es.Namespace,
+ "condition": string(esv1alpha1.ExternalSecretReady),
+ "status": string(v1.ConditionTrue),
+ })
+
+ case esv1alpha1.ExternalSecretReady:
+ // Remove condition=Deleted metrics when the object gets ready.
+ externalSecretCondition.Delete(prometheus.Labels{
+ "name": es.Name,
+ "namespace": es.Namespace,
+ "condition": string(esv1alpha1.ExternalSecretDeleted),
+ "status": string(v1.ConditionFalse),
+ })
+ externalSecretCondition.Delete(prometheus.Labels{
+ "name": es.Name,
+ "namespace": es.Namespace,
+ "condition": string(esv1alpha1.ExternalSecretDeleted),
+ "status": string(v1.ConditionTrue),
+ })
+ // Toggle opposite Status to 0
+ switch condition.Status {
+ case v1.ConditionFalse:
+ externalSecretCondition.With(prometheus.Labels{
+ "name": es.Name,
+ "namespace": es.Namespace,
+ "condition": string(esv1alpha1.ExternalSecretReady),
+ "status": string(v1.ConditionTrue),
+ }).Set(0)
+ case v1.ConditionTrue:
+ externalSecretCondition.With(prometheus.Labels{
+ "name": es.Name,
+ "namespace": es.Namespace,
+ "condition": string(esv1alpha1.ExternalSecretReady),
+ "status": string(v1.ConditionFalse),
+ }).Set(0)
+ case v1.ConditionUnknown:
+ break
+ default:
+ break
+ }
+
+ default:
+ break
+ }
+
externalSecretCondition.With(prometheus.Labels{
"name": es.Name,
"namespace": es.Namespace,
diff --git a/pkg/controllers/externalsecret/suite_test.go b/pkg/controllers/externalsecret/suite_test.go
index 011bbdcb2..169347dd6 100644
--- a/pkg/controllers/externalsecret/suite_test.go
+++ b/pkg/controllers/externalsecret/suite_test.go
@@ -15,6 +15,7 @@ limitations under the License.
package externalsecret
import (
+ "context"
"path/filepath"
"testing"
"time"
@@ -40,6 +41,7 @@ import (
var cfg *rest.Config
var k8sClient client.Client
var testEnv *envtest.Environment
+var cancel context.CancelFunc
func TestAPIs(t *testing.T) {
RegisterFailHandler(Fail)
@@ -56,6 +58,9 @@ var _ = BeforeSuite(func() {
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "deploy", "crds")},
}
+ var ctx context.Context
+ ctx, cancel = context.WithCancel(context.Background())
+
var err error
cfg, err = testEnv.Start()
Expect(err).ToNot(HaveOccurred())
@@ -87,12 +92,13 @@ var _ = BeforeSuite(func() {
go func() {
defer GinkgoRecover()
- Expect(k8sManager.Start(ctrl.SetupSignalHandler())).ToNot(HaveOccurred())
+ Expect(k8sManager.Start(ctx)).ToNot(HaveOccurred())
}()
})
var _ = AfterSuite(func() {
By("tearing down the test environment")
+ cancel() // stop manager
err := testEnv.Stop()
Expect(err).ToNot(HaveOccurred())
})
diff --git a/pkg/provider/fake/fake.go b/pkg/provider/fake/fake.go
index bbf66fd4b..384feeb7a 100644
--- a/pkg/provider/fake/fake.go
+++ b/pkg/provider/fake/fake.go
@@ -16,6 +16,7 @@ package fake
import (
"context"
+ "fmt"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -24,80 +25,72 @@ import (
"github.com/external-secrets/external-secrets/pkg/provider/schema"
)
-var _ provider.Provider = &Client{}
+var (
+ errNotFound = fmt.Errorf("secret value not found")
+ errMissingStore = fmt.Errorf("missing store provider")
+ errMissingFakeProvider = fmt.Errorf("missing store provider fake")
+)
-// Client is a fake client for testing.
-type Client struct {
- NewFn func(context.Context, esv1alpha1.GenericStore, client.Client,
- string) (provider.SecretsClient, error)
- GetSecretFn func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error)
- GetSecretMapFn func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error)
+type Provider struct {
+ config *esv1alpha1.FakeProvider
}
-// New returns a fake provider/client.
-func New() *Client {
- v := &Client{
- GetSecretFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
- return nil, nil
- },
- GetSecretMapFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
- return nil, nil
- },
- }
-
- v.NewFn = func(context.Context, esv1alpha1.GenericStore, client.Client, string) (provider.SecretsClient, error) {
- return v, nil
- }
-
- return v
-}
-
-// RegisterAs registers the fake client in the schema.
-func (v *Client) RegisterAs(provider *esv1alpha1.SecretStoreProvider) {
- schema.ForceRegister(v, provider)
-}
-
-// GetSecret implements the provider.Provider interface.
-func (v *Client) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
- return v.GetSecretFn(ctx, ref)
-}
-
-// WithGetSecret wraps secret data returned by this provider.
-func (v *Client) WithGetSecret(secData []byte, err error) *Client {
- v.GetSecretFn = func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
- return secData, err
- }
- return v
-}
-
-// GetSecretMap imeplements the provider.Provider interface.
-func (v *Client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
- return v.GetSecretMapFn(ctx, ref)
-}
-func (v *Client) Close(ctx context.Context) error {
- return nil
-}
-
-// WithGetSecretMap wraps the secret data map returned by this fake provider.
-func (v *Client) WithGetSecretMap(secData map[string][]byte, err error) *Client {
- v.GetSecretMapFn = func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
- return secData, err
- }
- return v
-}
-
-// WithNew wraps the fake provider factory function.
-func (v *Client) WithNew(f func(context.Context, esv1alpha1.GenericStore, client.Client,
- string) (provider.SecretsClient, error)) *Client {
- v.NewFn = f
- return v
-}
-
-// NewClient returns a new fake provider.
-func (v *Client) NewClient(ctx context.Context, store esv1alpha1.GenericStore, kube client.Client, namespace string) (provider.SecretsClient, error) {
- c, err := v.NewFn(ctx, store, kube, namespace)
+func (p *Provider) NewClient(ctx context.Context, store esv1alpha1.GenericStore, kube client.Client, namespace string) (provider.SecretsClient, error) {
+ cfg, err := getProvider(store)
if err != nil {
return nil, err
}
- return c, nil
+ return &Provider{
+ config: cfg,
+ }, nil
+}
+
+func getProvider(store esv1alpha1.GenericStore) (*esv1alpha1.FakeProvider, error) {
+ if store == nil {
+ return nil, errMissingStore
+ }
+ spc := store.GetSpec()
+ if spc == nil || spc.Provider == nil || spc.Provider.Fake == nil {
+ return nil, errMissingFakeProvider
+ }
+ return spc.Provider.Fake, nil
+}
+
+// GetSecret returns a single secret from the provider.
+func (p *Provider) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
+ for _, data := range p.config.Data {
+ if data.Key == ref.Key && data.Version == ref.Version {
+ return []byte(data.Value), nil
+ }
+ }
+ return nil, errNotFound
+}
+
+// GetSecretMap returns multiple k/v pairs from the provider.
+func (p *Provider) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
+ for _, data := range p.config.Data {
+ if data.Key != ref.Key || data.Version != ref.Version || data.ValueMap == nil {
+ continue
+ }
+ return convertMap(data.ValueMap), nil
+ }
+ return nil, errNotFound
+}
+
+func convertMap(in map[string]string) map[string][]byte {
+ m := make(map[string][]byte)
+ for k, v := range in {
+ m[k] = []byte(v)
+ }
+ return m
+}
+
+func (p *Provider) Close(ctx context.Context) error {
+ return nil
+}
+
+func init() {
+ schema.Register(&Provider{}, &esv1alpha1.SecretStoreProvider{
+ Fake: &esv1alpha1.FakeProvider{},
+ })
}
diff --git a/pkg/provider/fake/fake_test.go b/pkg/provider/fake/fake_test.go
new file mode 100644
index 000000000..7a88af5d5
--- /dev/null
+++ b/pkg/provider/fake/fake_test.go
@@ -0,0 +1,194 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package fake
+
+import (
+ "context"
+ "testing"
+
+ "github.com/onsi/gomega"
+
+ esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+)
+
+func TestNewClient(t *testing.T) {
+ p := &Provider{}
+ gomega.RegisterTestingT(t)
+
+ // nil store
+ _, err := p.NewClient(context.Background(), nil, nil, "")
+ gomega.Expect(err).To(gomega.HaveOccurred())
+
+ // missing provider
+ _, err = p.NewClient(context.Background(), &esv1alpha1.SecretStore{}, nil, "")
+ gomega.Expect(err).To(gomega.HaveOccurred())
+}
+
+func TestClose(t *testing.T) {
+ p := &Provider{}
+ gomega.RegisterTestingT(t)
+ err := p.Close(context.TODO())
+ gomega.Expect(err).ToNot(gomega.HaveOccurred())
+}
+
+type testCase struct {
+ name string
+ input []esv1alpha1.FakeProviderData
+ request esv1alpha1.ExternalSecretDataRemoteRef
+ expValue string
+ expErr string
+}
+
+func TestGetSecret(t *testing.T) {
+ gomega.RegisterTestingT(t)
+ p := &Provider{}
+ tbl := []testCase{
+ {
+ name: "return err when not found",
+ input: []esv1alpha1.FakeProviderData{},
+ request: esv1alpha1.ExternalSecretDataRemoteRef{
+ Key: "/foo",
+ Version: "v2",
+ },
+ expErr: "secret value not found",
+ },
+ {
+ name: "get correct value from multiple versions",
+ input: []esv1alpha1.FakeProviderData{
+ {
+ Key: "/foo",
+ Value: "bar2",
+ Version: "v2",
+ },
+ {
+ Key: "junk",
+ Value: "xxxxx",
+ },
+ {
+ Key: "/foo",
+ Value: "bar1",
+ Version: "v1",
+ },
+ },
+ request: esv1alpha1.ExternalSecretDataRemoteRef{
+ Key: "/foo",
+ Version: "v2",
+ },
+ expValue: "bar2",
+ },
+ }
+
+ for _, row := range tbl {
+ t.Run(row.name, func(t *testing.T) {
+ cl, err := p.NewClient(context.Background(), &esv1alpha1.SecretStore{
+ Spec: esv1alpha1.SecretStoreSpec{
+ Provider: &esv1alpha1.SecretStoreProvider{
+ Fake: &esv1alpha1.FakeProvider{
+ Data: row.input,
+ },
+ },
+ },
+ }, nil, "")
+ gomega.Expect(err).ToNot(gomega.HaveOccurred())
+ out, err := cl.GetSecret(context.Background(), row.request)
+ if row.expErr != "" {
+ gomega.Expect(err).To(gomega.MatchError(row.expErr))
+ } else {
+ gomega.Expect(err).ToNot(gomega.HaveOccurred())
+ }
+ gomega.Expect(string(out)).To(gomega.Equal(row.expValue))
+ })
+ }
+}
+
+type testMapCase struct {
+ name string
+ input []esv1alpha1.FakeProviderData
+ request esv1alpha1.ExternalSecretDataRemoteRef
+ expValue map[string][]byte
+ expErr string
+}
+
+func TestGetSecretMap(t *testing.T) {
+ gomega.RegisterTestingT(t)
+ p := &Provider{}
+ tbl := []testMapCase{
+ {
+ name: "return err when not found",
+ input: []esv1alpha1.FakeProviderData{},
+ request: esv1alpha1.ExternalSecretDataRemoteRef{
+ Key: "/foo",
+ Version: "v2",
+ },
+ expErr: "secret value not found",
+ },
+ {
+ name: "get correct value from multiple versions",
+ input: []esv1alpha1.FakeProviderData{
+ {
+ Key: "junk",
+ ValueMap: map[string]string{
+ "junk": "ok",
+ },
+ },
+ {
+ Key: "/foo",
+ ValueMap: map[string]string{
+ "foo": "bar",
+ "baz": "bang",
+ },
+ Version: "v1",
+ },
+ {
+ Key: "/foo",
+ ValueMap: map[string]string{
+ "foo": "bar",
+ "baz": "bang",
+ },
+ Version: "v2",
+ },
+ },
+ request: esv1alpha1.ExternalSecretDataRemoteRef{
+ Key: "/foo",
+ Version: "v2",
+ },
+ expValue: map[string][]byte{
+ "foo": []byte("bar"),
+ "baz": []byte("bang"),
+ },
+ },
+ }
+
+ for _, row := range tbl {
+ t.Run(row.name, func(t *testing.T) {
+ cl, err := p.NewClient(context.Background(), &esv1alpha1.SecretStore{
+ Spec: esv1alpha1.SecretStoreSpec{
+ Provider: &esv1alpha1.SecretStoreProvider{
+ Fake: &esv1alpha1.FakeProvider{
+ Data: row.input,
+ },
+ },
+ },
+ }, nil, "")
+ gomega.Expect(err).ToNot(gomega.HaveOccurred())
+ out, err := cl.GetSecretMap(context.Background(), row.request)
+ if row.expErr != "" {
+ gomega.Expect(err).To(gomega.MatchError(row.expErr))
+ } else {
+ gomega.Expect(err).ToNot(gomega.HaveOccurred())
+ }
+ gomega.Expect(out).To(gomega.Equal(row.expValue))
+ })
+ }
+}
diff --git a/pkg/provider/gcp/secretmanager/fake/fake.go b/pkg/provider/gcp/secretmanager/fake/fake.go
index ce1eb8695..0cb7c062d 100644
--- a/pkg/provider/gcp/secretmanager/fake/fake.go
+++ b/pkg/provider/gcp/secretmanager/fake/fake.go
@@ -19,7 +19,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- grpc "github.com/googleapis/gax-go"
+ grpc "github.com/googleapis/gax-go/v2"
secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
)
diff --git a/pkg/provider/gcp/secretmanager/secretsmanager.go b/pkg/provider/gcp/secretmanager/secretsmanager.go
index 2bd2d14e9..bc46a1c5a 100644
--- a/pkg/provider/gcp/secretmanager/secretsmanager.go
+++ b/pkg/provider/gcp/secretmanager/secretsmanager.go
@@ -19,7 +19,7 @@ import (
"fmt"
secretmanager "cloud.google.com/go/secretmanager/apiv1"
- "github.com/googleapis/gax-go"
+ "github.com/googleapis/gax-go/v2"
"github.com/tidwall/gjson"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
diff --git a/pkg/provider/gcp/secretmanager/secretsmanager_workload_identity.go b/pkg/provider/gcp/secretmanager/secretsmanager_workload_identity.go
index 4aa92bc30..9604871da 100644
--- a/pkg/provider/gcp/secretmanager/secretsmanager_workload_identity.go
+++ b/pkg/provider/gcp/secretmanager/secretsmanager_workload_identity.go
@@ -24,7 +24,7 @@ import (
iam "cloud.google.com/go/iam/credentials/apiv1"
secretmanager "cloud.google.com/go/secretmanager/apiv1"
- "github.com/googleapis/gax-go"
+ "github.com/googleapis/gax-go/v2"
"golang.org/x/oauth2"
"google.golang.org/api/option"
credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1"
diff --git a/pkg/provider/gcp/secretmanager/secretsmanager_workload_identity_test.go b/pkg/provider/gcp/secretmanager/secretsmanager_workload_identity_test.go
index d3f5f32bc..9409c9400 100644
--- a/pkg/provider/gcp/secretmanager/secretsmanager_workload_identity_test.go
+++ b/pkg/provider/gcp/secretmanager/secretsmanager_workload_identity_test.go
@@ -21,7 +21,7 @@ import (
"net/http/httptest"
"testing"
- "github.com/googleapis/gax-go"
+ "github.com/googleapis/gax-go/v2"
"github.com/stretchr/testify/assert"
"golang.org/x/oauth2"
credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1"
diff --git a/pkg/provider/register/register.go b/pkg/provider/register/register.go
index 10760941a..be69679ae 100644
--- a/pkg/provider/register/register.go
+++ b/pkg/provider/register/register.go
@@ -21,6 +21,7 @@ import (
_ "github.com/external-secrets/external-secrets/pkg/provider/alibaba"
_ "github.com/external-secrets/external-secrets/pkg/provider/aws"
_ "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault"
+ _ "github.com/external-secrets/external-secrets/pkg/provider/fake"
_ "github.com/external-secrets/external-secrets/pkg/provider/gcp/secretmanager"
_ "github.com/external-secrets/external-secrets/pkg/provider/gitlab"
_ "github.com/external-secrets/external-secrets/pkg/provider/ibm"
diff --git a/pkg/provider/testing/fake/fake.go b/pkg/provider/testing/fake/fake.go
new file mode 100644
index 000000000..bbf66fd4b
--- /dev/null
+++ b/pkg/provider/testing/fake/fake.go
@@ -0,0 +1,103 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package fake
+
+import (
+ "context"
+
+ "sigs.k8s.io/controller-runtime/pkg/client"
+
+ esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+ "github.com/external-secrets/external-secrets/pkg/provider"
+ "github.com/external-secrets/external-secrets/pkg/provider/schema"
+)
+
+var _ provider.Provider = &Client{}
+
+// Client is a fake client for testing.
+type Client struct {
+ NewFn func(context.Context, esv1alpha1.GenericStore, client.Client,
+ string) (provider.SecretsClient, error)
+ GetSecretFn func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error)
+ GetSecretMapFn func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error)
+}
+
+// New returns a fake provider/client.
+func New() *Client {
+ v := &Client{
+ GetSecretFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
+ return nil, nil
+ },
+ GetSecretMapFn: func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
+ return nil, nil
+ },
+ }
+
+ v.NewFn = func(context.Context, esv1alpha1.GenericStore, client.Client, string) (provider.SecretsClient, error) {
+ return v, nil
+ }
+
+ return v
+}
+
+// RegisterAs registers the fake client in the schema.
+func (v *Client) RegisterAs(provider *esv1alpha1.SecretStoreProvider) {
+ schema.ForceRegister(v, provider)
+}
+
+// GetSecret implements the provider.Provider interface.
+func (v *Client) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
+ return v.GetSecretFn(ctx, ref)
+}
+
+// WithGetSecret wraps secret data returned by this provider.
+func (v *Client) WithGetSecret(secData []byte, err error) *Client {
+ v.GetSecretFn = func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
+ return secData, err
+ }
+ return v
+}
+
+// GetSecretMap imeplements the provider.Provider interface.
+func (v *Client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
+ return v.GetSecretMapFn(ctx, ref)
+}
+func (v *Client) Close(ctx context.Context) error {
+ return nil
+}
+
+// WithGetSecretMap wraps the secret data map returned by this fake provider.
+func (v *Client) WithGetSecretMap(secData map[string][]byte, err error) *Client {
+ v.GetSecretMapFn = func(context.Context, esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
+ return secData, err
+ }
+ return v
+}
+
+// WithNew wraps the fake provider factory function.
+func (v *Client) WithNew(f func(context.Context, esv1alpha1.GenericStore, client.Client,
+ string) (provider.SecretsClient, error)) *Client {
+ v.NewFn = f
+ return v
+}
+
+// NewClient returns a new fake provider.
+func (v *Client) NewClient(ctx context.Context, store esv1alpha1.GenericStore, kube client.Client, namespace string) (provider.SecretsClient, error) {
+ c, err := v.NewFn(ctx, store, kube, namespace)
+ if err != nil {
+ return nil, err
+ }
+ return c, nil
+}
diff --git a/pkg/provider/webhook/webhook_test.go b/pkg/provider/webhook/webhook_test.go
index 98387dc70..8211d4069 100644
--- a/pkg/provider/webhook/webhook_test.go
+++ b/pkg/provider/webhook/webhook_test.go
@@ -298,7 +298,9 @@ func testGetSecret(tc testCase, t *testing.T, client provider.SecretsClient) {
Key: tc.Args.Key,
Version: tc.Args.Version,
}
- secret, err := client.GetSecret(context.Background(), testRef)
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+ defer cancel()
+ secret, err := client.GetSecret(ctx, testRef)
errStr := ""
if err != nil {
errStr = err.Error()
diff --git a/terraform/aws/modules/cluster/irsa.tf b/terraform/aws/modules/cluster/irsa.tf
index ba4a256a3..a4783f523 100644
--- a/terraform/aws/modules/cluster/irsa.tf
+++ b/terraform/aws/modules/cluster/irsa.tf
@@ -37,6 +37,25 @@ resource "aws_iam_role" "eso-e2e-irsa" {
"arn:aws:iam::aws:policy/SecretsManagerReadWrite"
]
+ inline_policy {
+ name = "aws_ssm_parameterstore"
+
+ policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [
+ {
+ Action = [
+ "ssm:GetParameter",
+ "ssm:PutParameter",
+ ]
+ Effect = "Allow"
+ Resource = "*"
+ },
+ ]
+ })
+ }
+
+
}
resource "null_resource" "apply_sa" {