diff --git a/Makefile b/Makefile index e3971cc8a..a9548bb9b 100644 --- a/Makefile +++ b/Makefile @@ -225,7 +225,7 @@ docker.tag: ## Emit IMAGE_TAG docker.build: $(addprefix build-,$(ARCH)) ## Build the docker image @$(INFO) docker build echo docker build -f $(DOCKERFILE) . $(DOCKER_BUILD_ARGS) -t $(IMAGE_NAME):$(IMAGE_TAG) - docker build -f $(DOCKERFILE) . $(DOCKER_BUILD_ARGS) -t $(IMAGE_NAME):$(IMAGE_TAG) + DOCKER_BUILDKIT=1 docker build -f $(DOCKERFILE) . $(DOCKER_BUILD_ARGS) -t $(IMAGE_NAME):$(IMAGE_TAG) @$(OK) docker build .PHONY: docker.push diff --git a/docs/contributing/devguide.md b/docs/contributing/devguide.md index f63612e28..3ed5964ed 100644 --- a/docs/contributing/devguide.md +++ b/docs/contributing/devguide.md @@ -25,7 +25,7 @@ Building the operator binary and docker image: ```shell make build -make docker.build IMG=external-secrets:latest +make docker.build IMAGE_NAME=external-secrets IMAGE_TAG=latest ``` Run tests and lint the code: diff --git a/docs/snippets/full-secret-store.yaml b/docs/snippets/full-secret-store.yaml index dacb717bd..2292754e9 100644 --- a/docs/snippets/full-secret-store.yaml +++ b/docs/snippets/full-secret-store.yaml @@ -14,7 +14,7 @@ spec: # You can specify retry settings for the http connection # these fields allow you to set a maxRetries before failure, and # an interval between the retries. - # Current supported providers: AWS, IBM + # Current supported providers: AWS, Hashicorp Vault, IBM retrySettings: maxRetries: 5 retryInterval: "10s" @@ -42,6 +42,7 @@ spec: name: awssm-secret key: secret-access-key + # (2) Hashicorp Vault vault: server: "https://vault.acme.org" # Path is the mount path of the Vault KV backend endpoint @@ -89,7 +90,7 @@ spec: name: "my-secret" key: "vault" - # (2): GCP Secret Manager + # (3): GCP Secret Manager gcpsm: # Auth defines the information necessary to authenticate against GCP by getting # the credentials from an already created Kubernetes Secret. diff --git a/pkg/provider/vault/vault.go b/pkg/provider/vault/vault.go index 2f6790bb7..3801badb8 100644 --- a/pkg/provider/vault/vault.go +++ b/pkg/provider/vault/vault.go @@ -27,6 +27,7 @@ import ( "reflect" "strconv" "strings" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" @@ -233,7 +234,7 @@ func (c *Connector) newClient(ctx context.Context, store esv1beta1.GenericStore, } vaultSpec := storeSpec.Provider.Vault - vStore, cfg, err := c.prepareConfig(kube, corev1, vaultSpec, namespace, store.GetObjectKind().GroupVersionKind().Kind) + vStore, cfg, err := c.prepareConfig(kube, corev1, vaultSpec, storeSpec.RetrySettings, namespace, store.GetObjectKind().GroupVersionKind().Kind) if err != nil { return nil, err } @@ -247,7 +248,7 @@ func (c *Connector) newClient(ctx context.Context, store esv1beta1.GenericStore, } func (c *Connector) NewGeneratorClient(ctx context.Context, kube kclient.Client, corev1 typedcorev1.CoreV1Interface, vaultSpec *esv1beta1.VaultProvider, namespace string) (util.Client, error) { - vStore, cfg, err := c.prepareConfig(kube, corev1, vaultSpec, namespace, "Generator") + vStore, cfg, err := c.prepareConfig(kube, corev1, vaultSpec, nil, namespace, "Generator") if err != nil { return nil, err } @@ -265,7 +266,7 @@ func (c *Connector) NewGeneratorClient(ctx context.Context, kube kclient.Client, return client, nil } -func (c *Connector) prepareConfig(kube kclient.Client, corev1 typedcorev1.CoreV1Interface, vaultSpec *esv1beta1.VaultProvider, namespace, storeKind string) (*client, *vault.Config, error) { +func (c *Connector) prepareConfig(kube kclient.Client, corev1 typedcorev1.CoreV1Interface, vaultSpec *esv1beta1.VaultProvider, retrySettings *esv1beta1.SecretStoreRetrySettings, namespace, storeKind string) (*client, *vault.Config, error) { vStore := &client{ kube: kube, corev1: corev1, @@ -279,6 +280,26 @@ func (c *Connector) prepareConfig(kube kclient.Client, corev1 typedcorev1.CoreV1 if err != nil { return nil, nil, err } + + // Setup retry options if present + if retrySettings != nil { + if retrySettings.MaxRetries != nil { + cfg.MaxRetries = int(*retrySettings.MaxRetries) + } else { + // By default we rely only on the reconciliation process for retrying + cfg.MaxRetries = 0 + } + + if retrySettings.RetryInterval != nil { + retryWait, err := time.ParseDuration(*retrySettings.RetryInterval) + if err != nil { + return nil, nil, err + } + cfg.MinRetryWait = retryWait + cfg.MaxRetryWait = retryWait + } + } + return vStore, cfg, nil } @@ -998,8 +1019,6 @@ func (v *client) readSecret(ctx context.Context, path, version string) (map[stri func (v *client) newConfig() (*vault.Config, error) { cfg := vault.DefaultConfig() cfg.Address = v.store.Server - // In a controller-runtime context, we rely on the reconciliation process for retrying - cfg.MaxRetries = 0 if len(v.store.CABundle) == 0 && v.store.CAProvider == nil { return cfg, nil diff --git a/pkg/provider/vault/vault_test.go b/pkg/provider/vault/vault_test.go index 8e9b487c6..e6e1211c2 100644 --- a/pkg/provider/vault/vault_test.go +++ b/pkg/provider/vault/vault_test.go @@ -250,6 +250,38 @@ MIIFkTCCA3mgAwIBAgIUBEUg3m/WqAsWHG4Q/II3IePFfuowDQYJKoZIhvcNAQELBQAwWDELMAkGA1UE err: errors.New(errVaultStore), }, }, + "InvalidRetrySettings": { + reason: "Should return error if given an invalid Retry Interval.", + args: args{ + store: makeSecretStore(func(s *esv1beta1.SecretStore) { + s.Spec.RetrySettings = &esv1beta1.SecretStoreRetrySettings{ + MaxRetries: pointer.To(int32(3)), + RetryInterval: pointer.To("not-an-interval"), + } + }), + }, + want: want{ + err: errors.New("time: invalid duration \"not-an-interval\""), + }, + }, + "ValidRetrySettings": { + reason: "Should return a Vault provider with custom retry settings", + args: args{ + store: makeSecretStore(func(s *esv1beta1.SecretStore) { + s.Spec.RetrySettings = &esv1beta1.SecretStoreRetrySettings{ + MaxRetries: pointer.To(int32(3)), + RetryInterval: pointer.To("10m"), + } + }), + ns: "default", + kube: clientfake.NewClientBuilder().Build(), + corev1: utilfake.NewCreateTokenMock().WithToken("ok"), + newClientFunc: fake.ClientWithLoginMock, + }, + want: want{ + err: nil, + }, + }, "AddVaultStoreCertsError": { reason: "Should return error if given an invalid CA certificate.", args: args{