vault_test.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. /*
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License.
  11. */
  12. package vault
  13. import (
  14. "bytes"
  15. "context"
  16. "encoding/json"
  17. "errors"
  18. "fmt"
  19. "io/ioutil"
  20. "net/http"
  21. "testing"
  22. "github.com/crossplane/crossplane-runtime/pkg/test"
  23. "github.com/google/go-cmp/cmp"
  24. vault "github.com/hashicorp/vault/api"
  25. corev1 "k8s.io/api/core/v1"
  26. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  27. kclient "sigs.k8s.io/controller-runtime/pkg/client"
  28. esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
  29. esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
  30. "github.com/external-secrets/external-secrets/pkg/provider/vault/fake"
  31. )
  32. const (
  33. tokenSecretName = "example-secret-token"
  34. secretDataString = "some-creds"
  35. )
  36. func makeValidSecretStore() *esv1alpha1.SecretStore {
  37. return &esv1alpha1.SecretStore{
  38. ObjectMeta: metav1.ObjectMeta{
  39. Name: "vault-store",
  40. Namespace: "default",
  41. },
  42. Spec: esv1alpha1.SecretStoreSpec{
  43. Provider: &esv1alpha1.SecretStoreProvider{
  44. Vault: &esv1alpha1.VaultProvider{
  45. Server: "vault.example.com",
  46. Path: "secret",
  47. Version: esv1alpha1.VaultKVStoreV2,
  48. Auth: esv1alpha1.VaultAuth{
  49. Kubernetes: &esv1alpha1.VaultKubernetesAuth{
  50. Path: "kubernetes",
  51. Role: "kubernetes-auth-role",
  52. ServiceAccountRef: &esmeta.ServiceAccountSelector{
  53. Name: "example-sa",
  54. },
  55. },
  56. },
  57. },
  58. },
  59. },
  60. }
  61. }
  62. func makeValidSecretStoreWithCerts() *esv1alpha1.SecretStore {
  63. return &esv1alpha1.SecretStore{
  64. ObjectMeta: metav1.ObjectMeta{
  65. Name: "vault-store",
  66. Namespace: "default",
  67. },
  68. Spec: esv1alpha1.SecretStoreSpec{
  69. Provider: &esv1alpha1.SecretStoreProvider{
  70. Vault: &esv1alpha1.VaultProvider{
  71. Server: "vault.example.com",
  72. Path: "secret",
  73. Version: esv1alpha1.VaultKVStoreV2,
  74. Auth: esv1alpha1.VaultAuth{
  75. Cert: &esv1alpha1.VaultCertAuth{
  76. ClientCert: esmeta.SecretKeySelector{
  77. Name: "tls-auth-certs",
  78. Key: "tls.crt",
  79. },
  80. SecretRef: esmeta.SecretKeySelector{
  81. Name: "tls-auth-certs",
  82. Key: "tls.key",
  83. },
  84. },
  85. },
  86. },
  87. },
  88. },
  89. }
  90. }
  91. func makeValidSecretStoreWithK8sCerts(isSecret bool) *esv1alpha1.SecretStore {
  92. store := makeSecretStore()
  93. caProvider := &esv1alpha1.CAProvider{
  94. Name: "vault-cert",
  95. Key: "cert",
  96. }
  97. if isSecret {
  98. caProvider.Type = "Secret"
  99. } else {
  100. caProvider.Type = "ConfigMap"
  101. }
  102. store.Spec.Provider.Vault.CAProvider = caProvider
  103. return store
  104. }
  105. type secretStoreTweakFn func(s *esv1alpha1.SecretStore)
  106. func makeSecretStore(tweaks ...secretStoreTweakFn) *esv1alpha1.SecretStore {
  107. store := makeValidSecretStore()
  108. for _, fn := range tweaks {
  109. fn(store)
  110. }
  111. return store
  112. }
  113. func newVaultResponse(data *vault.Secret) *vault.Response {
  114. jsonData, _ := json.Marshal(data)
  115. return &vault.Response{
  116. Response: &http.Response{
  117. Body: ioutil.NopCloser(bytes.NewReader(jsonData)),
  118. },
  119. }
  120. }
  121. func newVaultTokenIDResponse(token string) *vault.Response {
  122. return newVaultResponse(&vault.Secret{
  123. Data: map[string]interface{}{
  124. "id": token,
  125. },
  126. })
  127. }
  128. type args struct {
  129. newClientFunc func(c *vault.Config) (Client, error)
  130. store esv1alpha1.GenericStore
  131. kube kclient.Client
  132. ns string
  133. }
  134. type want struct {
  135. err error
  136. }
  137. type testCase struct {
  138. reason string
  139. args args
  140. want want
  141. }
  142. func clientWithLoginMock(c *vault.Config) (Client, error) {
  143. return &fake.VaultClient{
  144. MockNewRequest: fake.NewMockNewRequestFn(&vault.Request{}),
  145. MockRawRequestWithContext: fake.NewMockRawRequestWithContextFn(
  146. newVaultTokenIDResponse("test-token"), nil, func(got *vault.Request) error { return nil }),
  147. MockSetToken: fake.NewSetTokenFn(),
  148. }, nil
  149. }
  150. func kubeMockWithSecretTokenAndServiceAcc(obj kclient.Object) error {
  151. if o, ok := obj.(*corev1.ServiceAccount); ok {
  152. o.Secrets = []corev1.ObjectReference{
  153. {
  154. Name: tokenSecretName,
  155. },
  156. }
  157. return nil
  158. }
  159. if o, ok := obj.(*corev1.Secret); ok {
  160. o.Data = map[string][]byte{
  161. "token": []byte(secretDataString),
  162. }
  163. return nil
  164. }
  165. return nil
  166. }
  167. func TestNewVault(t *testing.T) {
  168. errBoom := errors.New("boom")
  169. secretClientKey := []byte(`-----BEGIN RSA PRIVATE KEY-----
  170. 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==
  171. -----END RSA PRIVATE KEY-----`)
  172. clientCrt := []byte(`-----BEGIN CERTIFICATE-----
  173. 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
  174. -----END CERTIFICATE-----
  175. `)
  176. secretData := []byte(secretDataString)
  177. cases := map[string]testCase{
  178. "InvalidVaultStore": {
  179. reason: "Should return error if given an invalid vault store.",
  180. args: args{
  181. store: &esv1alpha1.SecretStore{},
  182. },
  183. want: want{
  184. err: errors.New(errVaultStore),
  185. },
  186. },
  187. "AddVaultStoreCertsError": {
  188. reason: "Should return error if given an invalid CA certificate.",
  189. args: args{
  190. store: makeSecretStore(func(s *esv1alpha1.SecretStore) {
  191. s.Spec.Provider.Vault.CABundle = []byte("badcertdata")
  192. }),
  193. },
  194. want: want{
  195. err: errors.New(errVaultCert),
  196. },
  197. },
  198. "VaultAuthFormatError": {
  199. reason: "Should return error if no valid authentication method is given.",
  200. args: args{
  201. store: makeSecretStore(func(s *esv1alpha1.SecretStore) {
  202. s.Spec.Provider.Vault.Auth = esv1alpha1.VaultAuth{}
  203. }),
  204. },
  205. want: want{
  206. err: errors.New(errAuthFormat),
  207. },
  208. },
  209. "GetKubeServiceAccountError": {
  210. reason: "Should return error if fetching kubernetes secret fails.",
  211. args: args{
  212. store: makeSecretStore(),
  213. kube: &test.MockClient{
  214. MockGet: test.NewMockGetFn(errBoom),
  215. },
  216. },
  217. want: want{
  218. err: fmt.Errorf(errGetKubeSA, "example-sa", errBoom),
  219. },
  220. },
  221. "GetKubeSecretError": {
  222. reason: "Should return error if fetching kubernetes secret fails.",
  223. args: args{
  224. store: makeSecretStore(func(s *esv1alpha1.SecretStore) {
  225. s.Spec.Provider.Vault.Auth.Kubernetes.ServiceAccountRef = nil
  226. s.Spec.Provider.Vault.Auth.Kubernetes.SecretRef = &esmeta.SecretKeySelector{
  227. Name: "vault-secret",
  228. Key: "key",
  229. }
  230. }),
  231. kube: &test.MockClient{
  232. MockGet: test.NewMockGetFn(errBoom),
  233. },
  234. },
  235. want: want{
  236. err: fmt.Errorf(errGetKubeSecret, "vault-secret", errBoom),
  237. },
  238. },
  239. "SuccessfulVaultStore": {
  240. reason: "Should return a Vault provider successfully",
  241. args: args{
  242. store: makeSecretStore(),
  243. kube: &test.MockClient{
  244. MockGet: test.NewMockGetFn(nil, kubeMockWithSecretTokenAndServiceAcc),
  245. },
  246. newClientFunc: func(c *vault.Config) (Client, error) {
  247. return &fake.VaultClient{
  248. MockNewRequest: fake.NewMockNewRequestFn(&vault.Request{}),
  249. MockRawRequestWithContext: fake.NewMockRawRequestWithContextFn(
  250. newVaultTokenIDResponse("test-token"), nil, func(got *vault.Request) error {
  251. kubeRole := makeValidSecretStore().Spec.Provider.Vault.Auth.Kubernetes.Role
  252. want := kubeParameters(kubeRole, string(secretData))
  253. if diff := cmp.Diff(want, got.Obj); diff != "" {
  254. t.Errorf("RawRequestWithContext(...): -want, +got:\n%s", diff)
  255. }
  256. return nil
  257. }),
  258. MockSetToken: fake.NewSetTokenFn(),
  259. MockToken: fake.NewTokenFn(""),
  260. MockClearToken: fake.NewClearTokenFn(),
  261. }, nil
  262. },
  263. },
  264. want: want{
  265. err: nil,
  266. },
  267. },
  268. "SuccessfulVaultStoreWithCertAuth": {
  269. reason: "Should return a Vault provider successfully",
  270. args: args{
  271. store: makeValidSecretStoreWithCerts(),
  272. kube: &test.MockClient{
  273. MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
  274. if o, ok := obj.(*corev1.Secret); ok {
  275. o.Data = map[string][]byte{
  276. "tls.key": secretClientKey,
  277. "tls.crt": clientCrt,
  278. }
  279. return nil
  280. }
  281. return nil
  282. }),
  283. },
  284. newClientFunc: clientWithLoginMock,
  285. },
  286. want: want{
  287. err: nil,
  288. },
  289. },
  290. "SuccessfulVaultStoreWithK8sCertSecret": {
  291. reason: "Should return a Vault prodvider with the cert from k8s",
  292. args: args{
  293. store: makeValidSecretStoreWithK8sCerts(true),
  294. kube: &test.MockClient{
  295. MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
  296. if o, ok := obj.(*corev1.Secret); ok {
  297. o.Data = map[string][]byte{
  298. "cert": clientCrt,
  299. "token": secretData,
  300. }
  301. return nil
  302. }
  303. if o, ok := obj.(*corev1.ServiceAccount); ok {
  304. o.Secrets = []corev1.ObjectReference{
  305. {
  306. Name: tokenSecretName,
  307. },
  308. }
  309. return nil
  310. }
  311. return nil
  312. }),
  313. },
  314. newClientFunc: clientWithLoginMock,
  315. },
  316. want: want{
  317. err: nil,
  318. },
  319. },
  320. "GetCertSecretKeyMissingError": {
  321. reason: "Should return an error if the secret key is missing",
  322. args: args{
  323. store: makeValidSecretStoreWithK8sCerts(true),
  324. kube: &test.MockClient{
  325. MockGet: test.NewMockGetFn(nil, kubeMockWithSecretTokenAndServiceAcc),
  326. },
  327. newClientFunc: clientWithLoginMock,
  328. },
  329. want: want{
  330. err: fmt.Errorf(errVaultCert, errors.New(`cannot find secret data for key: "cert"`)),
  331. },
  332. },
  333. "SuccessfulVaultStoreWithK8sCertConfigMap": {
  334. reason: "Should return a Vault prodvider with the cert from k8s",
  335. args: args{
  336. store: makeValidSecretStoreWithK8sCerts(false),
  337. kube: &test.MockClient{
  338. MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
  339. if o, ok := obj.(*corev1.ConfigMap); ok {
  340. o.Data = map[string]string{
  341. "cert": string(clientCrt),
  342. }
  343. return nil
  344. }
  345. if o, ok := obj.(*corev1.ServiceAccount); ok {
  346. o.Secrets = []corev1.ObjectReference{
  347. {
  348. Name: tokenSecretName,
  349. },
  350. }
  351. return nil
  352. }
  353. if o, ok := obj.(*corev1.Secret); ok {
  354. o.Data = map[string][]byte{
  355. "token": secretData,
  356. }
  357. return nil
  358. }
  359. return nil
  360. }),
  361. },
  362. newClientFunc: clientWithLoginMock,
  363. },
  364. want: want{
  365. err: nil,
  366. },
  367. },
  368. "GetCertConfigMapMissingError": {
  369. reason: "Should return an error if the config map key is missing",
  370. args: args{
  371. store: makeValidSecretStoreWithK8sCerts(false),
  372. kube: &test.MockClient{
  373. MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
  374. if o, ok := obj.(*corev1.ServiceAccount); ok {
  375. o.Secrets = []corev1.ObjectReference{
  376. {
  377. Name: tokenSecretName,
  378. },
  379. }
  380. return nil
  381. }
  382. if o, ok := obj.(*corev1.Secret); ok {
  383. o.Data = map[string][]byte{
  384. "token": secretData,
  385. }
  386. return nil
  387. }
  388. return nil
  389. }),
  390. },
  391. newClientFunc: clientWithLoginMock,
  392. },
  393. want: want{
  394. err: fmt.Errorf(errConfigMapFmt, "cert"),
  395. },
  396. },
  397. "GetCertificateFormatError": {
  398. reason: "Should return error if client certificate is in wrong format.",
  399. args: args{
  400. store: makeValidSecretStoreWithCerts(),
  401. kube: &test.MockClient{
  402. MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
  403. if o, ok := obj.(*corev1.Secret); ok {
  404. o.Data = map[string][]byte{
  405. "tls.key": secretClientKey,
  406. "tls.crt": []byte("cert with mistak"),
  407. }
  408. return nil
  409. }
  410. return nil
  411. }),
  412. },
  413. newClientFunc: clientWithLoginMock,
  414. },
  415. want: want{
  416. err: fmt.Errorf(errClientTLSAuth, "tls: failed to find any PEM data in certificate input"),
  417. },
  418. },
  419. "GetKeyFormatError": {
  420. reason: "Should return error if client key is in wrong format.",
  421. args: args{
  422. store: makeValidSecretStoreWithCerts(),
  423. kube: &test.MockClient{
  424. MockGet: test.NewMockGetFn(nil, func(obj kclient.Object) error {
  425. if o, ok := obj.(*corev1.Secret); ok {
  426. o.Data = map[string][]byte{
  427. "tls.key": []byte("key with mistake"),
  428. "tls.crt": clientCrt,
  429. }
  430. return nil
  431. }
  432. return nil
  433. }),
  434. },
  435. newClientFunc: clientWithLoginMock,
  436. },
  437. want: want{
  438. err: fmt.Errorf(errClientTLSAuth, "tls: failed to find any PEM data in key input"),
  439. },
  440. },
  441. }
  442. for name, tc := range cases {
  443. t.Run(name, func(t *testing.T) {
  444. vaultTest(t, name, tc)
  445. })
  446. }
  447. }
  448. func vaultTest(t *testing.T, name string, tc testCase) {
  449. conn := &connector{
  450. newVaultClient: tc.args.newClientFunc,
  451. }
  452. if tc.args.newClientFunc == nil {
  453. conn.newVaultClient = newVaultClient
  454. }
  455. _, err := conn.NewClient(context.Background(), tc.args.store, tc.args.kube, tc.args.ns)
  456. if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
  457. t.Errorf("\n%s\nvault.New(...): -want error, +got error:\n%s", tc.reason, diff)
  458. }
  459. }
  460. func TestGetSecretMap(t *testing.T) {
  461. errBoom := errors.New("boom")
  462. type args struct {
  463. store *esv1alpha1.VaultProvider
  464. kube kclient.Client
  465. vClient Client
  466. ns string
  467. data esv1alpha1.ExternalSecretDataRemoteRef
  468. }
  469. type want struct {
  470. err error
  471. }
  472. cases := map[string]struct {
  473. reason string
  474. args args
  475. want want
  476. }{
  477. "ReadSecretError": {
  478. reason: "Should return error if vault client fails to read secret.",
  479. args: args{
  480. store: makeSecretStore().Spec.Provider.Vault,
  481. vClient: &fake.VaultClient{
  482. MockNewRequest: fake.NewMockNewRequestFn(&vault.Request{}),
  483. MockRawRequestWithContext: fake.NewMockRawRequestWithContextFn(nil, errBoom),
  484. },
  485. },
  486. want: want{
  487. err: fmt.Errorf(errReadSecret, errBoom),
  488. },
  489. },
  490. }
  491. for name, tc := range cases {
  492. t.Run(name, func(t *testing.T) {
  493. vStore := &client{
  494. kube: tc.args.kube,
  495. client: tc.args.vClient,
  496. store: tc.args.store,
  497. namespace: tc.args.ns,
  498. }
  499. _, err := vStore.GetSecretMap(context.Background(), tc.args.data)
  500. if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
  501. t.Errorf("\n%s\nvault.GetSecretMap(...): -want error, +got error:\n%s", tc.reason, diff)
  502. }
  503. })
  504. }
  505. }