client_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  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 kubernetes
  13. import (
  14. "context"
  15. "errors"
  16. "reflect"
  17. "strings"
  18. "testing"
  19. "github.com/google/go-cmp/cmp"
  20. "github.com/stretchr/testify/assert"
  21. v1 "k8s.io/api/core/v1"
  22. apierrors "k8s.io/apimachinery/pkg/api/errors"
  23. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  24. "k8s.io/apimachinery/pkg/runtime/schema"
  25. "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
  26. esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
  27. )
  28. const (
  29. errSomethingWentWrong = "Something went wrong"
  30. )
  31. type fakeClient struct {
  32. t *testing.T
  33. secretMap map[string]*v1.Secret
  34. expectedListOptions metav1.ListOptions
  35. err error
  36. }
  37. func (fk *fakeClient) Get(_ context.Context, name string, _ metav1.GetOptions) (*v1.Secret, error) {
  38. if fk.err != nil {
  39. return nil, fk.err
  40. }
  41. secret, ok := fk.secretMap[name]
  42. if !ok {
  43. return nil, apierrors.NewNotFound(schema.GroupResource{Group: "", Resource: "Secret"}, "secret")
  44. }
  45. // return inmutable to simulate external system and avoid accidental side effects
  46. sCopy := secret.DeepCopy()
  47. // update operation requires to relate names
  48. sCopy.Name = name
  49. return sCopy, nil
  50. }
  51. func (fk *fakeClient) List(_ context.Context, opts metav1.ListOptions) (*v1.SecretList, error) {
  52. assert.Equal(fk.t, fk.expectedListOptions, opts)
  53. list := &v1.SecretList{}
  54. for _, v := range fk.secretMap {
  55. list.Items = append(list.Items, *v)
  56. }
  57. return list, nil
  58. }
  59. func (fk *fakeClient) Delete(_ context.Context, name string, _ metav1.DeleteOptions) error {
  60. if fk.err != nil {
  61. return fk.err
  62. }
  63. _, ok := fk.secretMap[name]
  64. if !ok {
  65. return apierrors.NewNotFound(schema.GroupResource{Group: "", Resource: "Secret"}, "secret")
  66. }
  67. delete(fk.secretMap, name)
  68. return nil
  69. }
  70. func (fk *fakeClient) Create(_ context.Context, secret *v1.Secret, _ metav1.CreateOptions) (*v1.Secret, error) {
  71. s := &v1.Secret{
  72. Data: secret.Data,
  73. }
  74. fk.secretMap[secret.Name] = s
  75. return s, nil
  76. }
  77. func (fk *fakeClient) Update(_ context.Context, secret *v1.Secret, _ metav1.UpdateOptions) (*v1.Secret, error) {
  78. s, ok := fk.secretMap[secret.Name]
  79. if !ok {
  80. return nil, errors.New("error while updating secret")
  81. }
  82. s.Data = secret.Data
  83. return s, nil
  84. }
  85. var binaryTestData = []byte{0x00, 0xff, 0x00, 0xff, 0xac, 0xab, 0x28, 0x21}
  86. func TestGetSecret(t *testing.T) {
  87. tests := []struct {
  88. desc string
  89. secrets map[string]*v1.Secret
  90. clientErr error
  91. ref esv1beta1.ExternalSecretDataRemoteRef
  92. want []byte
  93. wantErr string
  94. }{
  95. {
  96. desc: "secret data with correct property",
  97. secrets: map[string]*v1.Secret{
  98. "mysec": {
  99. Data: map[string][]byte{
  100. "token": []byte(`foobar`),
  101. },
  102. },
  103. },
  104. ref: esv1beta1.ExternalSecretDataRemoteRef{
  105. Key: "mysec",
  106. Property: "token",
  107. },
  108. want: []byte(`foobar`),
  109. },
  110. {
  111. desc: "secret data with multi level property",
  112. secrets: map[string]*v1.Secret{
  113. "mysec": {
  114. Data: map[string][]byte{
  115. "foo": []byte(`{"huga":{"bar":"val"}}`),
  116. },
  117. },
  118. },
  119. ref: esv1beta1.ExternalSecretDataRemoteRef{
  120. Key: "mysec",
  121. Property: "foo.huga.bar",
  122. },
  123. want: []byte(`val`),
  124. },
  125. {
  126. desc: "secret data with property containing .",
  127. secrets: map[string]*v1.Secret{
  128. "mysec": {
  129. Data: map[string][]byte{
  130. "foo.png": []byte(`correct`),
  131. "foo": []byte(`{"png":"wrong"}`),
  132. },
  133. },
  134. },
  135. ref: esv1beta1.ExternalSecretDataRemoteRef{
  136. Key: "mysec",
  137. Property: "foo.png",
  138. },
  139. want: []byte(`correct`),
  140. },
  141. {
  142. desc: "secret data contains html characters",
  143. secrets: map[string]*v1.Secret{
  144. "mysec": {
  145. Data: map[string][]byte{
  146. "html": []byte(`<foobar>`),
  147. },
  148. },
  149. },
  150. ref: esv1beta1.ExternalSecretDataRemoteRef{
  151. Key: "mysec",
  152. },
  153. want: []byte(`{"html":"<foobar>"}`),
  154. },
  155. {
  156. desc: "secret metadata contains html characters",
  157. secrets: map[string]*v1.Secret{
  158. "mysec": {
  159. ObjectMeta: metav1.ObjectMeta{
  160. Annotations: map[string]string{"date": "today"},
  161. Labels: map[string]string{"dev": "<seb>"},
  162. },
  163. },
  164. },
  165. ref: esv1beta1.ExternalSecretDataRemoteRef{
  166. MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
  167. Key: "mysec",
  168. },
  169. want: []byte(`{"annotations":{"date":"today"},"labels":{"dev":"<seb>"}}`),
  170. },
  171. {
  172. desc: "secret data contains binary",
  173. secrets: map[string]*v1.Secret{
  174. "mysec": {
  175. Data: map[string][]byte{
  176. "bindata": binaryTestData,
  177. },
  178. },
  179. },
  180. ref: esv1beta1.ExternalSecretDataRemoteRef{
  181. Key: "mysec",
  182. Property: "bindata",
  183. },
  184. want: binaryTestData,
  185. },
  186. {
  187. desc: "secret data without property",
  188. secrets: map[string]*v1.Secret{
  189. "mysec": {
  190. Data: map[string][]byte{
  191. "token": []byte(`foobar`),
  192. },
  193. },
  194. },
  195. ref: esv1beta1.ExternalSecretDataRemoteRef{
  196. Key: "mysec",
  197. },
  198. want: []byte(`{"token":"foobar"}`),
  199. },
  200. {
  201. desc: "secret metadata without property",
  202. secrets: map[string]*v1.Secret{
  203. "mysec": {
  204. ObjectMeta: metav1.ObjectMeta{
  205. Annotations: map[string]string{"date": "today"},
  206. Labels: map[string]string{"dev": "seb"},
  207. },
  208. },
  209. },
  210. ref: esv1beta1.ExternalSecretDataRemoteRef{
  211. MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
  212. Key: "mysec",
  213. },
  214. want: []byte(`{"annotations":{"date":"today"},"labels":{"dev":"seb"}}`),
  215. },
  216. {
  217. desc: "secret metadata with single level property",
  218. secrets: map[string]*v1.Secret{
  219. "mysec": {
  220. ObjectMeta: metav1.ObjectMeta{
  221. Annotations: map[string]string{"date": "today"},
  222. Labels: map[string]string{"dev": "seb"},
  223. },
  224. },
  225. },
  226. ref: esv1beta1.ExternalSecretDataRemoteRef{
  227. MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
  228. Key: "mysec",
  229. Property: "labels",
  230. },
  231. want: []byte(`{"dev":"seb"}`),
  232. },
  233. {
  234. desc: "secret metadata with multiple level property",
  235. secrets: map[string]*v1.Secret{
  236. "mysec": {
  237. ObjectMeta: metav1.ObjectMeta{
  238. Annotations: map[string]string{"date": "today"},
  239. Labels: map[string]string{"dev": "seb"},
  240. },
  241. },
  242. },
  243. ref: esv1beta1.ExternalSecretDataRemoteRef{
  244. MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
  245. Key: "mysec",
  246. Property: "labels.dev",
  247. },
  248. want: []byte(`seb`),
  249. },
  250. {
  251. desc: "secret is not found",
  252. clientErr: apierrors.NewNotFound(schema.GroupResource{Group: "", Resource: "Secret"}, "secret"),
  253. ref: esv1beta1.ExternalSecretDataRemoteRef{
  254. Key: "mysec",
  255. Property: "token",
  256. },
  257. wantErr: `Secret "secret" not found`,
  258. },
  259. {
  260. desc: "secret data with wrong property",
  261. secrets: map[string]*v1.Secret{
  262. "mysec": {
  263. Data: map[string][]byte{
  264. "token": []byte(`foobar`),
  265. },
  266. },
  267. },
  268. ref: esv1beta1.ExternalSecretDataRemoteRef{
  269. Key: "mysec",
  270. Property: "not-the-token",
  271. },
  272. wantErr: "property not-the-token does not exist in data of secret",
  273. },
  274. {
  275. desc: "secret metadata with wrong property",
  276. secrets: map[string]*v1.Secret{
  277. "mysec": {
  278. ObjectMeta: metav1.ObjectMeta{
  279. Annotations: map[string]string{"date": "today"},
  280. Labels: map[string]string{"dev": "seb"},
  281. },
  282. },
  283. },
  284. ref: esv1beta1.ExternalSecretDataRemoteRef{
  285. MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
  286. Key: "mysec",
  287. Property: "foo",
  288. },
  289. wantErr: "property foo does not exist in metadata of secret",
  290. },
  291. }
  292. for _, tt := range tests {
  293. t.Run(tt.desc, func(t *testing.T) {
  294. p := &Client{
  295. userSecretClient: &fakeClient{t: t, secretMap: tt.secrets, err: tt.clientErr},
  296. namespace: "default",
  297. }
  298. got, err := p.GetSecret(context.Background(), tt.ref)
  299. if err != nil {
  300. if tt.wantErr == "" {
  301. t.Fatalf("failed to call GetSecret: %v", err)
  302. }
  303. if !strings.Contains(err.Error(), tt.wantErr) {
  304. t.Fatalf("received an unexpected error: %q should have contained %q", err.Error(), tt.wantErr)
  305. }
  306. return
  307. }
  308. if tt.wantErr != "" {
  309. t.Fatalf("expected to receive an error but got nil")
  310. }
  311. if !reflect.DeepEqual(got, tt.want) {
  312. t.Fatalf("received an unexpected secret: got: %s, want %s", got, tt.want)
  313. }
  314. })
  315. }
  316. }
  317. func TestGetSecretMap(t *testing.T) {
  318. type fields struct {
  319. Client KClient
  320. ReviewClient RClient
  321. Namespace string
  322. }
  323. tests := []struct {
  324. name string
  325. fields fields
  326. ref esv1beta1.ExternalSecretDataRemoteRef
  327. want map[string][]byte
  328. wantErr bool
  329. }{
  330. {
  331. name: "successful case metadata without property",
  332. fields: fields{
  333. Client: &fakeClient{
  334. t: t,
  335. secretMap: map[string]*v1.Secret{
  336. "mysec": {
  337. ObjectMeta: metav1.ObjectMeta{
  338. Annotations: map[string]string{"date": "today"},
  339. Labels: map[string]string{"dev": "seb"},
  340. },
  341. },
  342. },
  343. },
  344. Namespace: "default",
  345. },
  346. ref: esv1beta1.ExternalSecretDataRemoteRef{
  347. MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
  348. Key: "mysec",
  349. },
  350. want: map[string][]byte{"annotations": []byte("{\"date\":\"today\"}"), "labels": []byte("{\"dev\":\"seb\"}")},
  351. },
  352. {
  353. name: "successful case metadata with single property",
  354. fields: fields{
  355. Client: &fakeClient{
  356. t: t,
  357. secretMap: map[string]*v1.Secret{
  358. "mysec": {
  359. ObjectMeta: metav1.ObjectMeta{
  360. Annotations: map[string]string{"date": "today"},
  361. Labels: map[string]string{"dev": "seb"},
  362. },
  363. },
  364. },
  365. },
  366. Namespace: "default",
  367. },
  368. ref: esv1beta1.ExternalSecretDataRemoteRef{
  369. MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
  370. Key: "mysec",
  371. Property: "labels",
  372. },
  373. want: map[string][]byte{"dev": []byte("\"seb\"")},
  374. },
  375. {
  376. name: "error case metadata with wrong property",
  377. fields: fields{
  378. Client: &fakeClient{
  379. t: t,
  380. secretMap: map[string]*v1.Secret{
  381. "mysec": {
  382. ObjectMeta: metav1.ObjectMeta{
  383. Annotations: map[string]string{"date": "today"},
  384. Labels: map[string]string{"dev": "seb"},
  385. },
  386. },
  387. },
  388. },
  389. Namespace: "default",
  390. },
  391. ref: esv1beta1.ExternalSecretDataRemoteRef{
  392. MetadataPolicy: esv1beta1.ExternalSecretMetadataPolicyFetch,
  393. Key: "mysec",
  394. Property: "foo",
  395. },
  396. wantErr: true,
  397. },
  398. }
  399. for _, tt := range tests {
  400. t.Run(tt.name, func(t *testing.T) {
  401. p := &Client{
  402. userSecretClient: tt.fields.Client,
  403. userReviewClient: tt.fields.ReviewClient,
  404. namespace: tt.fields.Namespace,
  405. }
  406. got, err := p.GetSecretMap(context.Background(), tt.ref)
  407. if (err != nil) != tt.wantErr {
  408. t.Errorf("ProviderKubernetes.GetSecretMap() error = %v, wantErr %v", err, tt.wantErr)
  409. return
  410. }
  411. if !reflect.DeepEqual(got, tt.want) {
  412. t.Errorf("ProviderKubernetes.GetSecretMap() = %v, want %v", got, tt.want)
  413. }
  414. })
  415. }
  416. }
  417. func TestGetAllSecrets(t *testing.T) {
  418. type fields struct {
  419. Client KClient
  420. ReviewClient RClient
  421. Namespace string
  422. }
  423. type args struct {
  424. ctx context.Context
  425. ref esv1beta1.ExternalSecretFind
  426. }
  427. tests := []struct {
  428. name string
  429. fields fields
  430. args args
  431. want map[string][]byte
  432. wantErr bool
  433. }{
  434. {
  435. name: "use regex",
  436. fields: fields{
  437. Client: &fakeClient{
  438. t: t,
  439. secretMap: map[string]*v1.Secret{
  440. "mysec": {
  441. ObjectMeta: metav1.ObjectMeta{
  442. Name: "mysec",
  443. },
  444. Data: map[string][]byte{
  445. "token": []byte(`foo`),
  446. },
  447. },
  448. "other": {
  449. ObjectMeta: metav1.ObjectMeta{
  450. Name: "other",
  451. },
  452. Data: map[string][]byte{
  453. "token": []byte(`bar`),
  454. },
  455. },
  456. },
  457. },
  458. },
  459. args: args{
  460. ref: esv1beta1.ExternalSecretFind{
  461. Name: &esv1beta1.FindName{
  462. RegExp: "other",
  463. },
  464. },
  465. },
  466. want: map[string][]byte{
  467. "other": []byte(`{"token":"bar"}`),
  468. },
  469. },
  470. {
  471. name: "use tags/labels",
  472. fields: fields{
  473. Client: &fakeClient{
  474. t: t,
  475. expectedListOptions: metav1.ListOptions{
  476. LabelSelector: "app=foobar",
  477. },
  478. secretMap: map[string]*v1.Secret{
  479. "mysec": {
  480. ObjectMeta: metav1.ObjectMeta{
  481. Name: "mysec",
  482. },
  483. Data: map[string][]byte{
  484. "token": []byte(`foo`),
  485. },
  486. },
  487. "other": {
  488. ObjectMeta: metav1.ObjectMeta{
  489. Name: "other",
  490. },
  491. Data: map[string][]byte{
  492. "token": []byte(`bar`),
  493. },
  494. },
  495. },
  496. },
  497. },
  498. args: args{
  499. ref: esv1beta1.ExternalSecretFind{
  500. Tags: map[string]string{
  501. "app": "foobar",
  502. },
  503. },
  504. },
  505. want: map[string][]byte{
  506. "mysec": []byte(`{"token":"foo"}`),
  507. "other": []byte(`{"token":"bar"}`),
  508. },
  509. },
  510. }
  511. for _, tt := range tests {
  512. t.Run(tt.name, func(t *testing.T) {
  513. p := &Client{
  514. userSecretClient: tt.fields.Client,
  515. userReviewClient: tt.fields.ReviewClient,
  516. namespace: tt.fields.Namespace,
  517. }
  518. got, err := p.GetAllSecrets(tt.args.ctx, tt.args.ref)
  519. if (err != nil) != tt.wantErr {
  520. t.Errorf("ProviderKubernetes.GetAllSecrets() error = %v, wantErr %v", err, tt.wantErr)
  521. return
  522. }
  523. if !reflect.DeepEqual(got, tt.want) {
  524. t.Errorf("ProviderKubernetes.GetAllSecrets() = %v, want %v", got, tt.want)
  525. }
  526. })
  527. }
  528. }
  529. func TestDeleteSecret(t *testing.T) {
  530. type fields struct {
  531. Client KClient
  532. }
  533. tests := []struct {
  534. name string
  535. fields fields
  536. ref esv1beta1.PushRemoteRef
  537. wantSecretMap map[string]*v1.Secret
  538. wantErr bool
  539. }{
  540. {
  541. name: "refuse to delete without property",
  542. fields: fields{
  543. Client: &fakeClient{
  544. t: t,
  545. secretMap: map[string]*v1.Secret{
  546. "mysec": {
  547. Data: map[string][]byte{
  548. "token": []byte(`foobar`),
  549. },
  550. },
  551. },
  552. },
  553. },
  554. ref: v1alpha1.PushSecretRemoteRef{
  555. RemoteKey: "mysec",
  556. },
  557. wantErr: true,
  558. wantSecretMap: map[string]*v1.Secret{
  559. "mysec": {
  560. Data: map[string][]byte{
  561. "token": []byte(`foobar`),
  562. },
  563. },
  564. },
  565. },
  566. {
  567. name: "gracefully ignore not found secret",
  568. fields: fields{
  569. Client: &fakeClient{
  570. t: t,
  571. secretMap: map[string]*v1.Secret{},
  572. },
  573. },
  574. ref: v1alpha1.PushSecretRemoteRef{
  575. RemoteKey: "mysec",
  576. Property: "token",
  577. },
  578. wantErr: false,
  579. wantSecretMap: map[string]*v1.Secret{},
  580. },
  581. {
  582. name: "gracefully ignore not found property",
  583. fields: fields{
  584. Client: &fakeClient{
  585. t: t,
  586. secretMap: map[string]*v1.Secret{
  587. "mysec": {
  588. Data: map[string][]byte{
  589. "token": []byte(`foobar`),
  590. },
  591. },
  592. },
  593. },
  594. },
  595. ref: v1alpha1.PushSecretRemoteRef{
  596. RemoteKey: "mysec",
  597. Property: "secret",
  598. },
  599. wantErr: false,
  600. wantSecretMap: map[string]*v1.Secret{
  601. "mysec": {
  602. Data: map[string][]byte{
  603. "token": []byte(`foobar`),
  604. },
  605. },
  606. },
  607. },
  608. {
  609. name: "unexpected lookup error",
  610. fields: fields{
  611. Client: &fakeClient{
  612. t: t,
  613. secretMap: map[string]*v1.Secret{
  614. "mysec": {
  615. Data: map[string][]byte{
  616. "token": []byte(`foobar`),
  617. },
  618. },
  619. },
  620. err: errors.New(errSomethingWentWrong),
  621. },
  622. },
  623. ref: v1alpha1.PushSecretRemoteRef{
  624. RemoteKey: "mysec",
  625. },
  626. wantErr: true,
  627. wantSecretMap: map[string]*v1.Secret{
  628. "mysec": {
  629. Data: map[string][]byte{
  630. "token": []byte(`foobar`),
  631. },
  632. },
  633. },
  634. },
  635. {
  636. name: "delete whole secret if only property should be removed",
  637. fields: fields{
  638. Client: &fakeClient{
  639. t: t,
  640. secretMap: map[string]*v1.Secret{
  641. "mysec": {
  642. Data: map[string][]byte{
  643. "token": []byte(`foobar`),
  644. },
  645. },
  646. },
  647. },
  648. },
  649. ref: v1alpha1.PushSecretRemoteRef{
  650. RemoteKey: "mysec",
  651. Property: "token",
  652. },
  653. wantErr: false,
  654. wantSecretMap: map[string]*v1.Secret{},
  655. },
  656. {
  657. name: "multiple properties, just remove that one",
  658. fields: fields{
  659. Client: &fakeClient{
  660. t: t,
  661. secretMap: map[string]*v1.Secret{
  662. "mysec": {
  663. Data: map[string][]byte{
  664. "token": []byte(`foo`),
  665. "secret": []byte(`bar`),
  666. },
  667. },
  668. },
  669. },
  670. },
  671. ref: v1alpha1.PushSecretRemoteRef{
  672. RemoteKey: "mysec",
  673. Property: "token",
  674. },
  675. wantErr: false,
  676. wantSecretMap: map[string]*v1.Secret{
  677. "mysec": {
  678. Data: map[string][]byte{
  679. "secret": []byte(`bar`),
  680. },
  681. },
  682. },
  683. },
  684. }
  685. for _, tt := range tests {
  686. t.Run(tt.name, func(t *testing.T) {
  687. p := &Client{
  688. userSecretClient: tt.fields.Client,
  689. }
  690. err := p.DeleteSecret(context.Background(), tt.ref)
  691. if (err != nil) != tt.wantErr {
  692. t.Errorf("ProviderKubernetes.DeleteSecret() error = %v, wantErr %v", err, tt.wantErr)
  693. return
  694. }
  695. fClient := tt.fields.Client.(*fakeClient)
  696. if diff := cmp.Diff(tt.wantSecretMap, fClient.secretMap); diff != "" {
  697. t.Errorf("Unexpected resulting secrets map: -want, +got :\n%s\n", diff)
  698. }
  699. })
  700. }
  701. }
  702. func TestPushSecret(t *testing.T) {
  703. type fields struct {
  704. Client KClient
  705. PushValue string
  706. }
  707. tests := []struct {
  708. name string
  709. fields fields
  710. ref esv1beta1.PushRemoteRef
  711. wantSecretMap map[string]*v1.Secret
  712. wantErr bool
  713. }{
  714. {
  715. name: "refuse to work without property",
  716. fields: fields{
  717. Client: &fakeClient{
  718. t: t,
  719. secretMap: map[string]*v1.Secret{
  720. "mysec": {
  721. Data: map[string][]byte{
  722. "token": []byte(`foo`),
  723. },
  724. },
  725. },
  726. },
  727. PushValue: "bar",
  728. },
  729. ref: v1alpha1.PushSecretRemoteRef{
  730. RemoteKey: "mysec",
  731. },
  732. wantErr: true,
  733. wantSecretMap: map[string]*v1.Secret{
  734. "mysec": {
  735. Data: map[string][]byte{
  736. "token": []byte(`foo`),
  737. },
  738. },
  739. },
  740. },
  741. {
  742. name: "add missing property to existing secret",
  743. fields: fields{
  744. Client: &fakeClient{
  745. t: t,
  746. secretMap: map[string]*v1.Secret{
  747. "mysec": {
  748. Data: map[string][]byte{
  749. "token": []byte(`foo`),
  750. },
  751. },
  752. },
  753. },
  754. PushValue: "bar",
  755. },
  756. ref: v1alpha1.PushSecretRemoteRef{
  757. RemoteKey: "mysec",
  758. Property: "secret",
  759. },
  760. wantErr: false,
  761. wantSecretMap: map[string]*v1.Secret{
  762. "mysec": {
  763. Data: map[string][]byte{
  764. "token": []byte(`foo`),
  765. "secret": []byte(`bar`),
  766. },
  767. },
  768. },
  769. },
  770. {
  771. name: "replace existing property in existing secret",
  772. fields: fields{
  773. Client: &fakeClient{
  774. t: t,
  775. secretMap: map[string]*v1.Secret{
  776. "mysec": {
  777. Data: map[string][]byte{
  778. "token": []byte(`foo`),
  779. },
  780. },
  781. },
  782. },
  783. PushValue: "bar",
  784. },
  785. ref: v1alpha1.PushSecretRemoteRef{
  786. RemoteKey: "mysec",
  787. Property: "token",
  788. },
  789. wantErr: false,
  790. wantSecretMap: map[string]*v1.Secret{
  791. "mysec": {
  792. Data: map[string][]byte{
  793. "token": []byte(`bar`),
  794. },
  795. },
  796. },
  797. },
  798. {
  799. name: "create new secret",
  800. fields: fields{
  801. Client: &fakeClient{
  802. t: t,
  803. secretMap: map[string]*v1.Secret{
  804. "yoursec": {
  805. Data: map[string][]byte{
  806. "token": []byte(`foo`),
  807. },
  808. },
  809. },
  810. },
  811. PushValue: "bar",
  812. },
  813. ref: v1alpha1.PushSecretRemoteRef{
  814. RemoteKey: "mysec",
  815. Property: "secret",
  816. },
  817. wantErr: false,
  818. wantSecretMap: map[string]*v1.Secret{
  819. "yoursec": {
  820. Data: map[string][]byte{
  821. "token": []byte(`foo`),
  822. },
  823. },
  824. "mysec": {
  825. Data: map[string][]byte{
  826. "secret": []byte(`bar`),
  827. },
  828. },
  829. },
  830. },
  831. }
  832. for _, tt := range tests {
  833. t.Run(tt.name, func(t *testing.T) {
  834. p := &Client{
  835. userSecretClient: tt.fields.Client,
  836. store: &esv1beta1.KubernetesProvider{},
  837. }
  838. err := p.PushSecret(context.Background(), []byte(tt.fields.PushValue), nil, tt.ref)
  839. if (err != nil) != tt.wantErr {
  840. t.Errorf("ProviderKubernetes.DeleteSecret() error = %v, wantErr %v", err, tt.wantErr)
  841. return
  842. }
  843. fClient := tt.fields.Client.(*fakeClient)
  844. if diff := cmp.Diff(tt.wantSecretMap, fClient.secretMap); diff != "" {
  845. t.Errorf("Unexpected resulting secrets map: -want, +got :\n%s\n", diff)
  846. }
  847. })
  848. }
  849. }