1
0
Fork 0
mirror of https://github.com/external-secrets/external-secrets.git synced 2024-12-15 17:51:01 +00:00

Adding docs for v1beta1 vs v1alpha1. Added one test for v1alpha1 compatibility

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>
This commit is contained in:
Gustavo Carvalho 2022-03-23 06:31:52 -03:00
parent 2f0f97bf64
commit a2a4effa4a
15 changed files with 114 additions and 12 deletions

39
docs/guides-v1beta1.md Normal file
View file

@ -0,0 +1,39 @@
# Upgrading CRD versions
From version v0.5.0, `v1alpha1` version is deprecated, and `v1beta1` is in place. This guide will cover the main differences between the two versions, and a procedure on how to safely upgrade it.
## Differences between versions
Versions v1alpha1 and v1beta1 are fully-compatible for SecretStores and ClusterSecretStores. For ExternalSecrets, there is a difference on the `dataFrom` method.
While in v1alpha1, we could define a `dataFrom` with the following format:
```
spec:
dataFrom:
- key: my-key
- key: my-other-key
```
In v1beta1 is possible to use two methods. One of them is `Extract` and has the exact same behavior as `dataFrom` in v1alpha1. The other is `Find`, which allows finding multiple external secrets and map them into a single Kubernetes secret. Here is an example of `Find`:
```
spec:
dataFrom:
- find:
name: #matches any secret name ending in foo-bar
regexp: .*foo-bar$
- find:
tags: #matches any secrets with the following metadata.
env: dev
app: web
```
## Upgrading between versions
If you already have an installation of ESO using `v1alpha1`, we recommend you to upgrade to `v1beta1`. If you do not use `dataFrom` in your ExternalSecrets, or if you deploy the CRDs using official the official Helm charts, the upgrade can be done with no risk of losing data.
If you are installing CRDs manually, you will need to deploy the bundle CRD file available at `deploys/crds/bundle.yaml`. This bundle file contains `v1beta1` definition and a conversion webhook configuration. This configuration will ensure that new requests to handle any CRD object will only be valid after the upgrade is successfully complete - so there are no risks of losing data due to an incomplete upgrade.
Once the configuration is finished, at each reconcile, any `ExternalSecret`, `SecretStore`, and `ClusterSecretStore` stored in etcd in `v1alpha1` will be automatically converted to `v1beta1`.
Since `v1alpha1` is now deprecated, be sure to upgrade any resources you have to `v1beta1`.

View file

@ -26,6 +26,7 @@ import (
"k8s.io/client-go/rest"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
"github.com/external-secrets/external-secrets/e2e/framework/addon"
"github.com/external-secrets/external-secrets/e2e/framework/log"
@ -35,6 +36,7 @@ import (
func init() {
_ = kscheme.AddToScheme(util.Scheme)
_ = esv1beta1.AddToScheme(util.Scheme)
_ = esv1alpha1.AddToScheme(util.Scheme)
}
type Framework struct {

View file

@ -21,6 +21,7 @@ import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
"github.com/external-secrets/external-secrets/e2e/framework/log"
)
@ -31,6 +32,7 @@ var TargetSecretName = "target-secret"
type TestCase struct {
Framework *Framework
ExternalSecret *esv1beta1.ExternalSecret
ExternalSecretV1Alpha1 *esv1alpha1.ExternalSecret
Secrets map[string]SecretEntry
ExpectedSecret *v1.Secret
}
@ -68,10 +70,17 @@ func TableFunc(f *Framework, prov SecretStoreProvider) func(...func(*TestCase))
}()
}
// create external secret
// create v1alpha1 external secret, if provided
if tc.ExternalSecretV1Alpha1 != nil {
err = tc.Framework.CRClient.Create(context.Background(), tc.ExternalSecretV1Alpha1)
Expect(err).ToNot(HaveOccurred())
} else {
// create v1beta1 external secret otherwise
err = tc.Framework.CRClient.Create(context.Background(), tc.ExternalSecret)
Expect(err).ToNot(HaveOccurred())
}
// in case target name is empty
if tc.ExternalSecret.Spec.Target.Name == "" {
TargetSecretName = tc.ExternalSecret.ObjectMeta.Name

View file

@ -41,5 +41,6 @@ var _ = Describe("[akeyless]", Label("akeyless"), func() {
Entry(common.SSHKeySyncDataProperty(f)),
Entry(common.SyncWithoutTargetName(f)),
Entry(common.JSONDataWithoutTargetName(f)),
Entry(common.SyncV1Alpha1(f)),
)
})

View file

@ -41,5 +41,6 @@ var _ = Describe("[alibaba]", Label("alibaba"), func() {
Entry(common.SSHKeySyncDataProperty(f)),
Entry(common.SyncWithoutTargetName(f)),
Entry(common.JSONDataWithoutTargetName(f)),
Entry(common.SyncV1Alpha1(f)),
)
})

View file

@ -41,6 +41,7 @@ var _ = Describe("[aws] ", Label("aws", "parameterstore"), func() {
Entry(common.SSHKeySyncDataProperty(f)),
Entry(common.SyncWithoutTargetName(f)),
Entry(common.JSONDataWithoutTargetName(f)),
Entry(common.SyncV1Alpha1(f)),
// These are specific to parameterstore
Entry(FindByName(f)),

View file

@ -45,5 +45,6 @@ var _ = Describe("[aws] ", Label("aws", "secretsmanager"), func() {
Entry(common.FindByNameWithPath(f)),
Entry(common.FindByTag(f)),
Entry(common.FindByTagWithPath(f)),
Entry(common.SyncV1Alpha1(f)),
)
})

View file

@ -38,5 +38,6 @@ var _ = Describe("[azure]", Label("azure", "keyvault", "secret"), func() {
Entry(common.SSHKeySyncDataProperty(f)),
Entry(common.SyncWithoutTargetName(f)),
Entry(common.JSONDataWithoutTargetName(f)),
Entry(common.SyncV1Alpha1(f)),
)
})

View file

@ -18,6 +18,7 @@ import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
"github.com/external-secrets/external-secrets/e2e/framework"
)
@ -33,6 +34,47 @@ const (
secretValue2 = "{\"foo2\":\"foo2-val\",\"bar2\":\"bar2-val\"}"
)
// This case creates one secret with json values and syncs them using a single .Spec.DataFrom block.
func SyncV1Alpha1(f *framework.Framework) (string, func(*framework.TestCase)) {
return "[common] should sync secrets from v1alpha1 spec", func(tc *framework.TestCase) {
secretKey1 := fmt.Sprintf("%s-%s", f.Namespace.Name, "one")
targetSecretKey1 := "name"
targetSecretValue1 := "great-name"
targetSecretKey2 := "surname"
targetSecretValue2 := "great-surname"
secretValue := fmt.Sprintf("{ %q: %q, %q: %q }", targetSecretKey1, targetSecretValue1, targetSecretKey2, targetSecretValue2)
tc.Secrets = map[string]string{
secretKey1: secretValue,
}
tc.ExpectedSecret = &v1.Secret{
Type: v1.SecretTypeOpaque,
Data: map[string][]byte{
targetSecretKey1: []byte(targetSecretValue1),
targetSecretKey2: []byte(targetSecretValue2),
},
}
tc.ExternalSecretV1Alpha1 = &esv1alpha1.ExternalSecret{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-es",
Namespace: f.Namespace.Name,
},
Spec: esv1alpha1.ExternalSecretSpec{
SecretStoreRef: esv1alpha1.SecretStoreRef{
Name: f.Namespace.Name,
},
Target: esv1alpha1.ExternalSecretTarget{
Name: framework.TargetSecretName,
},
DataFrom: []esv1alpha1.ExternalSecretDataRemoteRef{
{
Key: secretKey1,
},
},
},
}
}
}
// This case creates multiple secrets with simple key/value pairs and syncs them using multiple .Spec.Data blocks.
// Not supported by: vault.
func SimpleDataSync(f *framework.Framework) (string, func(*framework.TestCase)) {

View file

@ -46,6 +46,7 @@ var _ = Describe("[gcp]", Label("gcp", "secretsmanager"), func() {
Entry(common.SSHKeySyncDataProperty(f)),
Entry(common.SyncWithoutTargetName(f)),
Entry(common.JSONDataWithoutTargetName(f)),
Entry(common.SyncV1Alpha1(f)),
Entry("should sync p12 encoded cert secret", p12Cert),
)
})

View file

@ -40,5 +40,6 @@ var _ = Describe("[gitlab]", Label("gitlab"), func() {
Entry(common.JSONDataWithTemplate(f)),
Entry(common.SyncWithoutTargetName(f)),
Entry(common.JSONDataWithoutTargetName(f)),
Entry(common.SyncV1Alpha1(f)),
)
})

View file

@ -16,10 +16,10 @@ package suite
import (
// import different e2e test suites.
_ "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/template"
// _ "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/template"
_ "github.com/external-secrets/external-secrets/e2e/suite/vault"
)

View file

@ -39,5 +39,6 @@ var _ = Describe("[oracle]", Label("oracle"), func() {
Entry(common.SSHKeySyncDataProperty(f)),
Entry(common.SyncWithoutTargetName(f)),
Entry(common.JSONDataWithoutTargetName(f)),
Entry(common.SyncV1Alpha1(f)),
)
})

View file

@ -46,6 +46,7 @@ var _ = Describe("[vault]", Label("vault"), func() {
framework.Compose(withTokenAuth, f, common.JSONDataWithTemplate, useTokenAuth),
framework.Compose(withTokenAuth, f, common.DataPropertyDockerconfigJSON, useTokenAuth),
framework.Compose(withTokenAuth, f, common.JSONDataWithoutTargetName, useTokenAuth),
framework.Compose(withTokenAuth, f, common.SyncV1Alpha1, useTokenAuth),
// use cert auth
framework.Compose(withCertAuth, f, common.FindByName, useCertAuth),
framework.Compose(withCertAuth, f, common.JSONDataFromSync, useCertAuth),

View file

@ -35,6 +35,7 @@ nav:
- Guides:
- Introduction: guides-introduction.md
- Getting started: guides-getting-started.md
- Upgrading to v1beta1: guides-v1beta1.md
- Advanced Templating:
v2: guides-templating.md
v1: guides-templating-v1.md