|
|
@@ -15,9 +15,9 @@ package kubernetes
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
- "encoding/base64"
|
|
|
"errors"
|
|
|
"reflect"
|
|
|
+ "strings"
|
|
|
"testing"
|
|
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
@@ -102,112 +102,68 @@ func (fk *fakeClient) Update(_ context.Context, secret *v1.Secret, _ metav1.Upda
|
|
|
var binaryTestData = []byte{0x00, 0xff, 0x00, 0xff, 0xac, 0xab, 0x28, 0x21}
|
|
|
|
|
|
func TestGetSecret(t *testing.T) {
|
|
|
- type fields struct {
|
|
|
- Client KClient
|
|
|
- ReviewClient RClient
|
|
|
- Namespace string
|
|
|
- }
|
|
|
tests := []struct {
|
|
|
- name string
|
|
|
- fields fields
|
|
|
- ref esv1beta1.ExternalSecretDataRemoteRef
|
|
|
-
|
|
|
- want []byte
|
|
|
- wantErr bool
|
|
|
+ desc string
|
|
|
+ secrets map[string]*v1.Secret
|
|
|
+ clientErr error
|
|
|
+ ref esv1beta1.ExternalSecretDataRemoteRef
|
|
|
+ want []byte
|
|
|
+ wantErr string
|
|
|
}{
|
|
|
{
|
|
|
- name: "secretNotFound",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- Data: map[string][]byte{
|
|
|
- "token": []byte(`foobar`),
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret data with correct property",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ Data: map[string][]byte{
|
|
|
+ "token": []byte(`foobar`),
|
|
|
},
|
|
|
- err: apierrors.NewNotFound(schema.GroupResource{Group: "", Resource: "Secret"}, "secret"),
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
Key: "mysec",
|
|
|
Property: "token",
|
|
|
},
|
|
|
- wantErr: true,
|
|
|
- },
|
|
|
- {
|
|
|
- name: "err GetSecretMap",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{},
|
|
|
- },
|
|
|
- Namespace: "default",
|
|
|
- },
|
|
|
- ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
- Key: "mysec",
|
|
|
- Property: "token",
|
|
|
- },
|
|
|
- wantErr: true,
|
|
|
+ want: []byte(`foobar`),
|
|
|
},
|
|
|
{
|
|
|
- name: "wrong property",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- Data: map[string][]byte{
|
|
|
- "token": []byte(`foobar`),
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret data with multi level property",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ Data: map[string][]byte{
|
|
|
+ "foo": []byte(`{"huga":{"bar":"val"}}`),
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
Key: "mysec",
|
|
|
- Property: "not-the-token",
|
|
|
+ Property: "foo.huga.bar",
|
|
|
},
|
|
|
- wantErr: true,
|
|
|
+ want: []byte(`val`),
|
|
|
},
|
|
|
{
|
|
|
- name: "successful case",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- Data: map[string][]byte{
|
|
|
- "token": []byte(`foobar`),
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret data with property containing .",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ Data: map[string][]byte{
|
|
|
+ "foo.png": []byte(`correct`),
|
|
|
+ "foo": []byte(`{"png":"wrong"}`),
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
Key: "mysec",
|
|
|
- Property: "token",
|
|
|
+ Property: "foo.png",
|
|
|
},
|
|
|
- want: []byte(`foobar`),
|
|
|
+ want: []byte(`correct`),
|
|
|
},
|
|
|
{
|
|
|
- name: "successful case with html chars",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- Data: map[string][]byte{
|
|
|
- "html": []byte(`<foobar>`),
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret data contains html characters",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ Data: map[string][]byte{
|
|
|
+ "html": []byte(`<foobar>`),
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
Key: "mysec",
|
|
|
@@ -215,20 +171,14 @@ func TestGetSecret(t *testing.T) {
|
|
|
want: []byte(`{"html":"<foobar>"}`),
|
|
|
},
|
|
|
{
|
|
|
- name: "successful case metadata with html special chars and without property",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- ObjectMeta: metav1.ObjectMeta{
|
|
|
- Annotations: map[string]string{"date": "today"},
|
|
|
- Labels: map[string]string{"dev": "<seb>"},
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret metadata contains html characters",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ ObjectMeta: metav1.ObjectMeta{
|
|
|
+ Annotations: map[string]string{"date": "today"},
|
|
|
+ Labels: map[string]string{"dev": "<seb>"},
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
|
|
|
@@ -237,40 +187,28 @@ func TestGetSecret(t *testing.T) {
|
|
|
want: []byte(`{"annotations":{"date":"today"},"labels":{"dev":"<seb>"}}`),
|
|
|
},
|
|
|
{
|
|
|
- name: "successful case with binary data",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- Data: map[string][]byte{
|
|
|
- "bindata": binaryTestData,
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret data contains binary",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ Data: map[string][]byte{
|
|
|
+ "bindata": binaryTestData,
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
Key: "mysec",
|
|
|
Property: "bindata",
|
|
|
},
|
|
|
- want: []byte(base64.StdEncoding.EncodeToString(binaryTestData)),
|
|
|
+ want: binaryTestData,
|
|
|
},
|
|
|
{
|
|
|
- name: "successful case without property",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- Data: map[string][]byte{
|
|
|
- "token": []byte(`foobar`),
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret data without property",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ Data: map[string][]byte{
|
|
|
+ "token": []byte(`foobar`),
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
Key: "mysec",
|
|
|
@@ -278,20 +216,14 @@ func TestGetSecret(t *testing.T) {
|
|
|
want: []byte(`{"token":"foobar"}`),
|
|
|
},
|
|
|
{
|
|
|
- name: "successful case metadata without property",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- ObjectMeta: metav1.ObjectMeta{
|
|
|
- Annotations: map[string]string{"date": "today"},
|
|
|
- Labels: map[string]string{"dev": "seb"},
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret metadata without property",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ ObjectMeta: metav1.ObjectMeta{
|
|
|
+ Annotations: map[string]string{"date": "today"},
|
|
|
+ Labels: map[string]string{"dev": "seb"},
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
|
|
|
@@ -300,20 +232,14 @@ func TestGetSecret(t *testing.T) {
|
|
|
want: []byte(`{"annotations":{"date":"today"},"labels":{"dev":"seb"}}`),
|
|
|
},
|
|
|
{
|
|
|
- name: "successful case metadata with single property",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- ObjectMeta: metav1.ObjectMeta{
|
|
|
- Annotations: map[string]string{"date": "today"},
|
|
|
- Labels: map[string]string{"dev": "seb"},
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret metadata with single level property",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ ObjectMeta: metav1.ObjectMeta{
|
|
|
+ Annotations: map[string]string{"date": "today"},
|
|
|
+ Labels: map[string]string{"dev": "seb"},
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
|
|
|
@@ -323,20 +249,14 @@ func TestGetSecret(t *testing.T) {
|
|
|
want: []byte(`{"dev":"seb"}`),
|
|
|
},
|
|
|
{
|
|
|
- name: "successful case metadata with multiple properties",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- ObjectMeta: metav1.ObjectMeta{
|
|
|
- Annotations: map[string]string{"date": "today"},
|
|
|
- Labels: map[string]string{"dev": "seb"},
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret metadata with multiple level property",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ ObjectMeta: metav1.ObjectMeta{
|
|
|
+ Annotations: map[string]string{"date": "today"},
|
|
|
+ Labels: map[string]string{"dev": "seb"},
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
|
|
|
@@ -346,43 +266,72 @@ func TestGetSecret(t *testing.T) {
|
|
|
want: []byte(`seb`),
|
|
|
},
|
|
|
{
|
|
|
- name: "error case metadata with wrong property",
|
|
|
- fields: fields{
|
|
|
- Client: &fakeClient{
|
|
|
- t: t,
|
|
|
- secretMap: map[string]*v1.Secret{
|
|
|
- "mysec": {
|
|
|
- ObjectMeta: metav1.ObjectMeta{
|
|
|
- Annotations: map[string]string{"date": "today"},
|
|
|
- Labels: map[string]string{"dev": "seb"},
|
|
|
- },
|
|
|
- },
|
|
|
+ desc: "secret is not found",
|
|
|
+ clientErr: apierrors.NewNotFound(schema.GroupResource{Group: "", Resource: "Secret"}, "secret"),
|
|
|
+ ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
+ Key: "mysec",
|
|
|
+ Property: "token",
|
|
|
+ },
|
|
|
+ wantErr: `Secret "secret" not found`,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ desc: "secret data with wrong property",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ Data: map[string][]byte{
|
|
|
+ "token": []byte(`foobar`),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
+ Key: "mysec",
|
|
|
+ Property: "not-the-token",
|
|
|
+ },
|
|
|
+ wantErr: "property not-the-token does not exist in data of secret",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ desc: "secret metadata with wrong property",
|
|
|
+ secrets: map[string]*v1.Secret{
|
|
|
+ "mysec": {
|
|
|
+ ObjectMeta: metav1.ObjectMeta{
|
|
|
+ Annotations: map[string]string{"date": "today"},
|
|
|
+ Labels: map[string]string{"dev": "seb"},
|
|
|
},
|
|
|
},
|
|
|
- Namespace: "default",
|
|
|
},
|
|
|
ref: esv1beta1.ExternalSecretDataRemoteRef{
|
|
|
MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
|
|
|
Key: "mysec",
|
|
|
Property: "foo",
|
|
|
},
|
|
|
- wantErr: true,
|
|
|
+ wantErr: "property foo does not exist in metadata of secret",
|
|
|
},
|
|
|
}
|
|
|
for _, tt := range tests {
|
|
|
- t.Run(tt.name, func(t *testing.T) {
|
|
|
+ t.Run(tt.desc, func(t *testing.T) {
|
|
|
p := &Client{
|
|
|
- userSecretClient: tt.fields.Client,
|
|
|
- userReviewClient: tt.fields.ReviewClient,
|
|
|
- namespace: tt.fields.Namespace,
|
|
|
+ userSecretClient: &fakeClient{t: t, secretMap: tt.secrets, err: tt.clientErr},
|
|
|
+ namespace: "default",
|
|
|
}
|
|
|
got, err := p.GetSecret(context.Background(), tt.ref)
|
|
|
- if (err != nil) != tt.wantErr {
|
|
|
- t.Errorf("ProviderKubernetes.GetSecret() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
+ if err != nil {
|
|
|
+ if tt.wantErr == "" {
|
|
|
+ t.Fatalf("failed to call GetSecret: %v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ if !strings.Contains(err.Error(), tt.wantErr) {
|
|
|
+ t.Fatalf("received an unexpected error: %q should have contained %q", err.Error(), tt.wantErr)
|
|
|
+ }
|
|
|
+
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+ if tt.wantErr != "" {
|
|
|
+ t.Fatalf("expected to receive an error but got nil")
|
|
|
+ }
|
|
|
+
|
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
|
- t.Errorf("ProviderKubernetes.GetSecret() = %s, want %s", got, tt.want)
|
|
|
+ t.Fatalf("received an unexpected secret: got: %s, want %s", got, tt.want)
|
|
|
}
|
|
|
})
|
|
|
}
|