|
|
@@ -36,6 +36,11 @@ import (
|
|
|
"github.com/external-secrets/external-secrets/pkg/provider/vault/fake"
|
|
|
)
|
|
|
|
|
|
+const (
|
|
|
+ tokenSecretName = "example-secret-token"
|
|
|
+ secretDataString = "some-creds"
|
|
|
+)
|
|
|
+
|
|
|
func makeValidSecretStore() *esv1alpha1.SecretStore {
|
|
|
return &esv1alpha1.SecretStore{
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
@@ -93,6 +98,23 @@ func makeValidSecretStoreWithCerts() *esv1alpha1.SecretStore {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func makeValidSecretStoreWithK8sCerts(isSecret bool) *esv1alpha1.SecretStore {
|
|
|
+ store := makeSecretStore()
|
|
|
+ caProvider := &esv1alpha1.CAProvider{
|
|
|
+ Name: "vault-cert",
|
|
|
+ Key: "cert",
|
|
|
+ }
|
|
|
+
|
|
|
+ if isSecret {
|
|
|
+ caProvider.Type = "Secret"
|
|
|
+ } else {
|
|
|
+ caProvider.Type = "ConfigMap"
|
|
|
+ }
|
|
|
+
|
|
|
+ store.Spec.Provider.Vault.CAProvider = caProvider
|
|
|
+ return store
|
|
|
+}
|
|
|
+
|
|
|
type secretStoreTweakFn func(s *esv1alpha1.SecretStore)
|
|
|
|
|
|
func makeSecretStore(tweaks ...secretStoreTweakFn) *esv1alpha1.SecretStore {
|
|
|
@@ -139,9 +161,35 @@ type testCase struct {
|
|
|
want want
|
|
|
}
|
|
|
|
|
|
+func clientWithLoginMock(c *vault.Config) (Client, error) {
|
|
|
+ return &fake.VaultClient{
|
|
|
+ MockNewRequest: fake.NewMockNewRequestFn(&vault.Request{}),
|
|
|
+ MockRawRequestWithContext: fake.NewMockRawRequestWithContextFn(
|
|
|
+ newVaultTokenIDResponse("test-token"), nil, func(got *vault.Request) error { return nil }),
|
|
|
+ MockSetToken: fake.NewSetTokenFn(),
|
|
|
+ }, nil
|
|
|
+}
|
|
|
+
|
|
|
+func kubeMockWithSecretTokenAndServiceAcc(obj kclient.Object) error {
|
|
|
+ if o, ok := obj.(*corev1.ServiceAccount); ok {
|
|
|
+ o.Secrets = []corev1.ObjectReference{
|
|
|
+ {
|
|
|
+ Name: tokenSecretName,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if o, ok := obj.(*corev1.Secret); ok {
|
|
|
+ o.Data = map[string][]byte{
|
|
|
+ "token": []byte(secretDataString),
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
func TestNewVault(t *testing.T) {
|
|
|
errBoom := errors.New("boom")
|
|
|
- secretData := []byte("some-creds")
|
|
|
secretClientKey := []byte(`-----BEGIN RSA PRIVATE KEY-----
|
|
|
MIIEpAIBAAKCAQEArfZ4HV1obFVlVNiA24tX/UOakqRnEtWXpIvaOsMaPGvvODgGe4XnyJGO32idPv85sIr7vDH9p+OhactVlJV1fu5SZoZ7pg4jTCLqVDCb3IRD++yik2Sw58YayNe3HiaCTsJQWeMXLzfaqOeyk6bEpBCJo09+3QxUWxijgJ7YZCb+Gi8pf3ZWeSZG+rGNNvXHmTs1Yu1H849SYXu+uJOd/R3ZSTw8CxFe4eTLgbCnPf6tgA8Sg2hc+CAZxunPP2JLZWbiJXxjNRoypso6MAJ1FRkx5sTJiLg6UoLvd95/S/lCVOR2PDlM1hg7ox8VEd4QHky7tLx7gji/5hHQKJQSTwIDAQABAoIBAQCYPICQ8hVX+MNcpLrfZenycR7sBYNOMC0silbH5cUn6yzFfgHuRxi3pOnrCJnTb3cE0BvMbdMVAVdYReD2znSsR9NEdZvvjZ/GGSgH1SIQsI7t//+mDQ/jRLJb4KsXb4vJcLLwdpLrd22bMmhMXjzndrF8gSz8NLX9omozPM8RlLxjzPzYOdlX/Zw8V68qQH2Ic04KbtnCwyAUIgAJxYtn/uYB8lzILBkyzQqwhQKkDDZQ0wbZT0hP6z+HgsdifwQvHG1GZAgCuzzyXrL/4TgDaDhYdMVoBA4+HPmzqm5MkBvjH4oqroxjRofUroVix0OGXZJMI1OJ0z/ubzmwCq5BAoGBANqbwzAydUJs0P+GFL94K/Y6tXULKA2c9N0crbxoxheobRpuJvhpW1ZE/9UGpaYX1Rw3nW4x+Jwvt83YkgHAlR4LgEwDvdJPZobybfqifQDiraUO0t62Crn8mSxOsFCugtRIFniwnX67w3uKxiSdCZYbJGs9JEDTpxRG/PSWq3QlAoGBAMu3zOv1PJAhOky7VcxFxWQPEMY+t2PA/sneD01/qgGuhlTwL4QlpywmBqXcI070dcvcBkP0flnWI7y5cnuE1+55twmsrvfaS8s1+AYje0b35DsaF2vtKuJrXC0AGKP+/eiycd9cbvVW2GWOxE7Ui76Mj95MARK8ZNjt0wJagQhjAoGASm9dD80uhhadN1RFPkjB1054OMk6sx/tdFhug8e9I5MSyzwUguME2aQW5EcmIh7dToVVUo8rUqsgz7NdS8FyRM+vuLJRcQneJDbp4bxwCdwlOh2JCZI8psVutlp4yJATNgrxs9iXV+7BChDflNnvyK+nP+iKrpQiwNHHEdU3vg0CgYEAvEpwD4+loJn1psJn9NxwK6F5IaMKIhtZ4/9pKXpcCh3jb1JouL2MnFOxRVAJGor87aW57Mlol2RDt8W4OM56PqMlOL3xIokUEQka66GT6e5pdu8QwuJ9BrWwhq9WFw4yZQe6FHb836qbbJLegvYVC9QjjZW2UDjtBUwcAkrghH0CgYBUMmMOCwIfMEtMaWxZRGdxRabazLhn7TXhBpVTuv7WouPaXYd7ZGjCTMKAuVa/E4afBlxgemnqBuX90gHpK/dDmn9l+lp8GZey0grJ7G0x5HEMiKziaX5PrgAcKbQ70m9ZNZ1deYhsC05X8rHNexZB6ns7Yms9L7qnlAy51ZH2zw==
|
|
|
-----END RSA PRIVATE KEY-----`)
|
|
|
@@ -149,6 +197,7 @@ MIIEpAIBAAKCAQEArfZ4HV1obFVlVNiA24tX/UOakqRnEtWXpIvaOsMaPGvvODgGe4XnyJGO32idPv85
|
|
|
MIICsTCCAZkCFEJJ4daz5sxkFlzq9n1djLEuG7bmMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCHZhdWx0LWNhMB4XDTIxMDcyMDA4MTQxM1oXDTIyMDcyMDA4MTQxM1owFzEVMBMGA1UEAwwMdmF1bHQtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArfZ4HV1obFVlVNiA24tX/UOakqRnEtWXpIvaOsMaPGvvODgGe4XnyJGO32idPv85sIr7vDH9p+OhactVlJV1fu5SZoZ7pg4jTCLqVDCb3IRD++yik2Sw58YayNe3HiaCTsJQWeMXLzfaqOeyk6bEpBCJo09+3QxUWxijgJ7YZCb+Gi8pf3ZWeSZG+rGNNvXHmTs1Yu1H849SYXu+uJOd/R3ZSTw8CxFe4eTLgbCnPf6tgA8Sg2hc+CAZxunPP2JLZWbiJXxjNRoypso6MAJ1FRkx5sTJiLg6UoLvd95/S/lCVOR2PDlM1hg7ox8VEd4QHky7tLx7gji/5hHQKJQSTwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAsDYKtzScIA7bqIOmqF8rr+oLSjRhPt5OfT+KGNdXk8G3VAy1ED2tyCHaRNC7dPLq4EvcxbIXQnXPy1iZMofriGbFPAcQ2fyWUesAD6bYSpI+bYxwz6Ebb93hU5nc/FyXg8yh0kgiGbY3MrACPjxqP2+z5kcOC3u3hx3SZylgW7TeOXDTdqSbNfH1b+1rR/bVNgQQshjhU9d+c4Yv/t0u07uykBhHLWZDSnYiAeOZ8+mWuOSDkcZHE1zznx74fWgtN0zRDtr0L0w9evT9R2CnNSZGxXcEQxAlQ7SL/Jyw82TFCGEw0L4jj7jjvx0N5J8KX/DulUDE9vuVyQEJ88Epe
|
|
|
-----END CERTIFICATE-----
|
|
|
`)
|
|
|
+ secretData := []byte(secretDataString)
|
|
|
|
|
|
cases := map[string]testCase{
|
|
|
"InvalidVaultStore": {
|
|
|
@@ -217,23 +266,7 @@ MIICsTCCAZkCFEJJ4daz5sxkFlzq9n1djLEuG7bmMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCHZh
|
|
|
args: args{
|
|
|
store: makeSecretStore(),
|
|
|
kube: &test.MockClient{
|
|
|
- MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
|
|
|
- if o, ok := obj.(*corev1.ServiceAccount); ok {
|
|
|
- o.Secrets = []corev1.ObjectReference{
|
|
|
- {
|
|
|
- Name: "example-secret-token",
|
|
|
- },
|
|
|
- }
|
|
|
- return nil
|
|
|
- }
|
|
|
- if o, ok := obj.(*corev1.Secret); ok {
|
|
|
- o.Data = map[string][]byte{
|
|
|
- "token": secretData,
|
|
|
- }
|
|
|
- return nil
|
|
|
- }
|
|
|
- return nil
|
|
|
- }),
|
|
|
+ MockGet: test.NewMockGetFn(nil, kubeMockWithSecretTokenAndServiceAcc),
|
|
|
},
|
|
|
newClientFunc: func(c *vault.Config) (Client, error) {
|
|
|
return &fake.VaultClient{
|
|
|
@@ -248,7 +281,9 @@ MIICsTCCAZkCFEJJ4daz5sxkFlzq9n1djLEuG7bmMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCHZh
|
|
|
|
|
|
return nil
|
|
|
}),
|
|
|
- MockSetToken: fake.NewSetTokenFn(),
|
|
|
+ MockSetToken: fake.NewSetTokenFn(),
|
|
|
+ MockToken: fake.NewTokenFn(""),
|
|
|
+ MockClearToken: fake.NewClearTokenFn(),
|
|
|
}, nil
|
|
|
},
|
|
|
},
|
|
|
@@ -272,19 +307,125 @@ MIICsTCCAZkCFEJJ4daz5sxkFlzq9n1djLEuG7bmMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCHZh
|
|
|
return nil
|
|
|
}),
|
|
|
},
|
|
|
- newClientFunc: func(c *vault.Config) (Client, error) {
|
|
|
- return &fake.VaultClient{
|
|
|
- MockNewRequest: fake.NewMockNewRequestFn(&vault.Request{}),
|
|
|
- MockRawRequestWithContext: fake.NewMockRawRequestWithContextFn(
|
|
|
- newVaultTokenIDResponse("test-token"), nil, func(got *vault.Request) error { return nil }),
|
|
|
- MockSetToken: fake.NewSetTokenFn(),
|
|
|
- }, nil
|
|
|
+ newClientFunc: clientWithLoginMock,
|
|
|
+ },
|
|
|
+ want: want{
|
|
|
+ err: nil,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ "SuccessfulVaultStoreWithK8sCertSecret": {
|
|
|
+ reason: "Should return a Vault prodvider with the cert from k8s",
|
|
|
+ args: args{
|
|
|
+ store: makeValidSecretStoreWithK8sCerts(true),
|
|
|
+ kube: &test.MockClient{
|
|
|
+ MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
|
|
|
+ if o, ok := obj.(*corev1.Secret); ok {
|
|
|
+ o.Data = map[string][]byte{
|
|
|
+ "cert": clientCrt,
|
|
|
+ "token": secretData,
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if o, ok := obj.(*corev1.ServiceAccount); ok {
|
|
|
+ o.Secrets = []corev1.ObjectReference{
|
|
|
+ {
|
|
|
+ Name: tokenSecretName,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }),
|
|
|
},
|
|
|
+ newClientFunc: clientWithLoginMock,
|
|
|
},
|
|
|
want: want{
|
|
|
err: nil,
|
|
|
},
|
|
|
},
|
|
|
+ "GetCertSecretKeyMissingError": {
|
|
|
+ reason: "Should return an error if the secret key is missing",
|
|
|
+ args: args{
|
|
|
+ store: makeValidSecretStoreWithK8sCerts(true),
|
|
|
+ kube: &test.MockClient{
|
|
|
+ MockGet: test.NewMockGetFn(nil, kubeMockWithSecretTokenAndServiceAcc),
|
|
|
+ },
|
|
|
+ newClientFunc: clientWithLoginMock,
|
|
|
+ },
|
|
|
+ want: want{
|
|
|
+ err: fmt.Errorf(errVaultCert, errors.New(`cannot find secret data for key: "cert"`)),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ "SuccessfulVaultStoreWithK8sCertConfigMap": {
|
|
|
+ reason: "Should return a Vault prodvider with the cert from k8s",
|
|
|
+ args: args{
|
|
|
+ store: makeValidSecretStoreWithK8sCerts(false),
|
|
|
+ kube: &test.MockClient{
|
|
|
+ MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
|
|
|
+ if o, ok := obj.(*corev1.ConfigMap); ok {
|
|
|
+ o.Data = map[string]string{
|
|
|
+ "cert": string(clientCrt),
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if o, ok := obj.(*corev1.ServiceAccount); ok {
|
|
|
+ o.Secrets = []corev1.ObjectReference{
|
|
|
+ {
|
|
|
+ Name: tokenSecretName,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if o, ok := obj.(*corev1.Secret); ok {
|
|
|
+ o.Data = map[string][]byte{
|
|
|
+ "token": secretData,
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ newClientFunc: clientWithLoginMock,
|
|
|
+ },
|
|
|
+ want: want{
|
|
|
+ err: nil,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ "GetCertConfigMapMissingError": {
|
|
|
+ reason: "Should return an error if the config map key is missing",
|
|
|
+ args: args{
|
|
|
+ store: makeValidSecretStoreWithK8sCerts(false),
|
|
|
+ kube: &test.MockClient{
|
|
|
+ MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
|
|
|
+ if o, ok := obj.(*corev1.ServiceAccount); ok {
|
|
|
+ o.Secrets = []corev1.ObjectReference{
|
|
|
+ {
|
|
|
+ Name: tokenSecretName,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if o, ok := obj.(*corev1.Secret); ok {
|
|
|
+ o.Data = map[string][]byte{
|
|
|
+ "token": secretData,
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ newClientFunc: clientWithLoginMock,
|
|
|
+ },
|
|
|
+ want: want{
|
|
|
+ err: fmt.Errorf(errConfigMapFmt, "cert"),
|
|
|
+ },
|
|
|
+ },
|
|
|
"GetCertificateFormatError": {
|
|
|
reason: "Should return error if client certificate is in wrong format.",
|
|
|
args: args{
|
|
|
@@ -301,14 +442,7 @@ MIICsTCCAZkCFEJJ4daz5sxkFlzq9n1djLEuG7bmMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCHZh
|
|
|
return nil
|
|
|
}),
|
|
|
},
|
|
|
- newClientFunc: func(c *vault.Config) (Client, error) {
|
|
|
- return &fake.VaultClient{
|
|
|
- MockNewRequest: fake.NewMockNewRequestFn(&vault.Request{}),
|
|
|
- MockRawRequestWithContext: fake.NewMockRawRequestWithContextFn(
|
|
|
- newVaultTokenIDResponse("test-token"), nil, func(got *vault.Request) error { return nil }),
|
|
|
- MockSetToken: fake.NewSetTokenFn(),
|
|
|
- }, nil
|
|
|
- },
|
|
|
+ newClientFunc: clientWithLoginMock,
|
|
|
},
|
|
|
want: want{
|
|
|
err: fmt.Errorf(errClientTLSAuth, "tls: failed to find any PEM data in certificate input"),
|
|
|
@@ -330,14 +464,7 @@ MIICsTCCAZkCFEJJ4daz5sxkFlzq9n1djLEuG7bmMA0GCSqGSIb3DQEBCwUAMBMxETAPBgNVBAMMCHZh
|
|
|
return nil
|
|
|
}),
|
|
|
},
|
|
|
- newClientFunc: func(c *vault.Config) (Client, error) {
|
|
|
- return &fake.VaultClient{
|
|
|
- MockNewRequest: fake.NewMockNewRequestFn(&vault.Request{}),
|
|
|
- MockRawRequestWithContext: fake.NewMockRawRequestWithContextFn(
|
|
|
- newVaultTokenIDResponse("test-token"), nil, func(got *vault.Request) error { return nil }),
|
|
|
- MockSetToken: fake.NewSetTokenFn(),
|
|
|
- }, nil
|
|
|
- },
|
|
|
+ newClientFunc: clientWithLoginMock,
|
|
|
},
|
|
|
want: want{
|
|
|
err: fmt.Errorf(errClientTLSAuth, "tls: failed to find any PEM data in key input"),
|