auth_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. "context"
  15. "testing"
  16. "github.com/google/go-cmp/cmp"
  17. "github.com/google/go-cmp/cmp/cmpopts"
  18. corev1 "k8s.io/api/core/v1"
  19. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  20. "k8s.io/utils/ptr"
  21. clientfake "sigs.k8s.io/controller-runtime/pkg/client/fake"
  22. esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
  23. esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
  24. "github.com/external-secrets/external-secrets/pkg/provider/vault/fake"
  25. )
  26. // Test Vault Namespace logic.
  27. func TestSetAuthNamespace(t *testing.T) {
  28. store := makeValidSecretStore()
  29. kube := clientfake.NewClientBuilder().WithObjects(&corev1.Secret{
  30. ObjectMeta: metav1.ObjectMeta{
  31. Name: "vault-secret",
  32. Namespace: "default",
  33. },
  34. Data: map[string][]byte{
  35. "key": []byte("token"),
  36. },
  37. }).Build()
  38. store.Spec.Provider.Vault.Auth.Kubernetes.ServiceAccountRef = nil
  39. store.Spec.Provider.Vault.Auth.Kubernetes.SecretRef = &esmeta.SecretKeySelector{
  40. Name: "vault-secret",
  41. Namespace: ptr.To("default"),
  42. Key: "key",
  43. }
  44. adminNS := "admin"
  45. teamNS := "admin/team-a"
  46. type result struct {
  47. Before string
  48. During string
  49. After string
  50. }
  51. type args struct {
  52. store *esv1beta1.SecretStore
  53. expected result
  54. }
  55. cases := map[string]struct {
  56. reason string
  57. args args
  58. }{
  59. "StoreNoNamespace": {
  60. reason: "no namespace should ever be set",
  61. args: args{
  62. store: store,
  63. expected: result{Before: "", During: "", After: ""},
  64. },
  65. },
  66. "StoreWithNamespace": {
  67. reason: "use the team namespace throughout",
  68. args: args{
  69. store: func(store *esv1beta1.SecretStore) *esv1beta1.SecretStore {
  70. s := store.DeepCopy()
  71. s.Spec.Provider.Vault.Namespace = ptr.To(teamNS)
  72. return s
  73. }(store),
  74. expected: result{Before: teamNS, During: teamNS, After: teamNS},
  75. },
  76. },
  77. "StoreWithAuthNamespace": {
  78. reason: "switch to the auth namespace during login then revert",
  79. args: args{
  80. store: func(store *esv1beta1.SecretStore) *esv1beta1.SecretStore {
  81. s := store.DeepCopy()
  82. s.Spec.Provider.Vault.Auth.Namespace = ptr.To(adminNS)
  83. return s
  84. }(store),
  85. expected: result{Before: "", During: adminNS, After: ""},
  86. },
  87. },
  88. "StoreWithSameNamespace": {
  89. reason: "the admin namespace throughout",
  90. args: args{
  91. store: func(store *esv1beta1.SecretStore) *esv1beta1.SecretStore {
  92. s := store.DeepCopy()
  93. s.Spec.Provider.Vault.Namespace = ptr.To(adminNS)
  94. s.Spec.Provider.Vault.Auth.Namespace = ptr.To(adminNS)
  95. return s
  96. }(store),
  97. expected: result{Before: adminNS, During: adminNS, After: adminNS},
  98. },
  99. },
  100. "StoreWithDistinctNamespace": {
  101. reason: "switch from team namespace, to admin, then back",
  102. args: args{
  103. store: func(store *esv1beta1.SecretStore) *esv1beta1.SecretStore {
  104. s := store.DeepCopy()
  105. s.Spec.Provider.Vault.Namespace = ptr.To(teamNS)
  106. s.Spec.Provider.Vault.Auth.Namespace = ptr.To(adminNS)
  107. return s
  108. }(store),
  109. expected: result{Before: teamNS, During: adminNS, After: teamNS},
  110. },
  111. },
  112. }
  113. for name, tc := range cases {
  114. t.Run(name, func(t *testing.T) {
  115. prov := &Provider{
  116. NewVaultClient: fake.ClientWithLoginMock,
  117. }
  118. c, cfg, err := prov.prepareConfig(context.Background(), kube, nil, tc.args.store.Spec.Provider.Vault, nil, "default", store.GetObjectKind().GroupVersionKind().Kind)
  119. if err != nil {
  120. t.Errorf(err.Error())
  121. }
  122. client, err := getVaultClient(prov, tc.args.store, cfg)
  123. if err != nil {
  124. t.Errorf("vault.useAuthNamespace: failed to create client: %s", err.Error())
  125. }
  126. _, err = prov.initClient(context.Background(), c, client, cfg, tc.args.store.Spec.Provider.Vault)
  127. if err != nil {
  128. t.Errorf("vault.useAuthNamespace: failed to init client: %s", err.Error())
  129. }
  130. c.client = client
  131. // before auth
  132. actual := result{
  133. Before: c.client.Namespace(),
  134. }
  135. // during authentication (getting a token)
  136. resetNS := c.useAuthNamespace(context.Background())
  137. actual.During = c.client.Namespace()
  138. resetNS()
  139. // after getting the token
  140. actual.After = c.client.Namespace()
  141. if diff := cmp.Diff(tc.args.expected, actual, cmpopts.EquateComparable()); diff != "" {
  142. t.Errorf("\n%s\nvault.useAuthNamepsace(...): -want namespace, +got namespace:\n%s", tc.reason, diff)
  143. }
  144. })
  145. }
  146. }