provider_test.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. Copyright © 2025 ESO Maintainer Team
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. https://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package kubernetes
  14. import (
  15. "context"
  16. "testing"
  17. "github.com/stretchr/testify/assert"
  18. corev1 "k8s.io/api/core/v1"
  19. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  20. "k8s.io/client-go/kubernetes"
  21. clientgofake "k8s.io/client-go/kubernetes/fake"
  22. pointer "k8s.io/utils/ptr"
  23. kclient "sigs.k8s.io/controller-runtime/pkg/client"
  24. fclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
  25. esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
  26. v1 "github.com/external-secrets/external-secrets/apis/meta/v1"
  27. )
  28. const (
  29. testCertificate = `-----BEGIN CERTIFICATE-----
  30. MIIDHTCCAgWgAwIBAgIRAKC4yxy9QGocND+6avTf7BgwDQYJKoZIhvcNAQELBQAw
  31. EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0yMTAzMjAyMDA4MDhaFw0yMTAzMjAyMDM4
  32. MDhaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
  33. ggEKAoIBAQC3o6/JdZEqNbqNRkopHhJtJG5c4qS5d0tQ/kZYpfD/v/izAYum4Nzj
  34. aG15owr92/11W0pxPUliRLti3y6iScTs+ofm2D7p4UXj/Fnho/2xoWSOoWAodgvW
  35. Y8jh8A0LQALZiV/9QsrJdXZdS47DYZLsQ3z9yFC/CdXkg1l7AQ3fIVGKdrQBr9kE
  36. 1gEDqnKfRxXI8DEQKXr+CKPUwCAytegmy0SHp53zNAvY+kopHytzmJpXLoEhxq4e
  37. ugHe52vXHdh/HJ9VjNp0xOH1waAgAGxHlltCW0PVd5AJ0SXROBS/a3V9sZCbCrJa
  38. YOOonQSEswveSv6PcG9AHvpNPot2Xs6hAgMBAAGjbjBsMA4GA1UdDwEB/wQEAwIC
  39. pDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
  40. BBR00805mrpoonp95RmC3B6oLl+cGTAVBgNVHREEDjAMggpnb29ibGUuY29tMA0G
  41. CSqGSIb3DQEBCwUAA4IBAQAipc1b6JrEDayPjpz5GM5krcI8dCWVd8re0a9bGjjN
  42. ioWGlu/eTr5El0ffwCNZ2WLmL9rewfHf/bMvYz3ioFZJ2OTxfazqYXNggQz6cMfa
  43. lbedDCdt5XLVX2TyerGvFram+9Uyvk3l0uM7rZnwAmdirG4Tv94QRaD3q4xTj/c0
  44. mv+AggtK0aRFb9o47z/BypLdk5mhbf3Mmr88C8XBzEnfdYyf4JpTlZrYLBmDCu5d
  45. 9RLLsjXxhag8xqMtd1uLUM8XOTGzVWacw8iGY+CTtBKqyA+AE6/bDwZvEwVtsKtC
  46. QJ85ioEpy00NioqcF0WyMZH80uMsPycfpnl5uF7RkW8u
  47. -----END CERTIFICATE-----`
  48. testKubeConfig = `apiVersion: v1
  49. clusters:
  50. - cluster:
  51. server: https://api.my-domain.tld
  52. name: mycluster
  53. contexts:
  54. - context:
  55. cluster: mycluster
  56. user: myuser
  57. name: mycontext
  58. current-context: mycontext
  59. kind: Config
  60. preferences: {}
  61. users:
  62. - name: myuser
  63. user:
  64. token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE3MTkzOTY4OTksImV4cCI6MTc1MDkzMjg4NywiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.xXrfIl0akhfjWU_BDl7Ad54SXje0YlJdnugzwh96VmM
  65. `
  66. )
  67. func TestNewClient(t *testing.T) {
  68. type fields struct {
  69. Client KClient
  70. ReviewClient RClient
  71. Namespace string
  72. }
  73. type args struct {
  74. store esv1.GenericStore
  75. kube kclient.Client
  76. clientset kubernetes.Interface
  77. namespace string
  78. }
  79. tests := []struct {
  80. name string
  81. fields fields
  82. args args
  83. want bool
  84. wantErr bool
  85. }{
  86. {
  87. name: "invalid store",
  88. fields: fields{},
  89. args: args{
  90. store: &esv1.ClusterSecretStore{
  91. TypeMeta: metav1.TypeMeta{
  92. Kind: esv1.ClusterSecretStoreKind,
  93. },
  94. Spec: esv1.SecretStoreSpec{
  95. Provider: &esv1.SecretStoreProvider{},
  96. },
  97. },
  98. kube: fclient.NewClientBuilder().Build(),
  99. },
  100. wantErr: true,
  101. },
  102. {
  103. name: "test auth ref",
  104. fields: fields{},
  105. args: args{
  106. store: &esv1.ClusterSecretStore{
  107. TypeMeta: metav1.TypeMeta{
  108. Kind: esv1.ClusterSecretStoreKind,
  109. },
  110. Spec: esv1.SecretStoreSpec{
  111. Provider: &esv1.SecretStoreProvider{
  112. Kubernetes: &esv1.KubernetesProvider{
  113. AuthRef: &v1.SecretKeySelector{
  114. Name: "foo",
  115. Namespace: pointer.To("default"),
  116. Key: "config",
  117. },
  118. },
  119. },
  120. },
  121. },
  122. namespace: "",
  123. kube: fclient.NewClientBuilder().WithObjects(&corev1.Secret{
  124. ObjectMeta: metav1.ObjectMeta{
  125. Name: "foo",
  126. Namespace: "default",
  127. },
  128. Data: map[string][]byte{
  129. "config": []byte(testKubeConfig),
  130. },
  131. }).Build(),
  132. clientset: clientgofake.NewSimpleClientset(),
  133. },
  134. want: true,
  135. },
  136. {
  137. name: "test referent auth return",
  138. fields: fields{},
  139. args: args{
  140. store: &esv1.ClusterSecretStore{
  141. TypeMeta: metav1.TypeMeta{
  142. Kind: esv1.ClusterSecretStoreKind,
  143. },
  144. Spec: esv1.SecretStoreSpec{
  145. Provider: &esv1.SecretStoreProvider{
  146. Kubernetes: &esv1.KubernetesProvider{
  147. Server: esv1.KubernetesServer{
  148. URL: "https://my.test.tld",
  149. CABundle: []byte(testCertificate),
  150. },
  151. Auth: &esv1.KubernetesAuth{
  152. Token: &esv1.TokenAuth{
  153. BearerToken: v1.SecretKeySelector{
  154. Name: "foo",
  155. Key: "token",
  156. },
  157. },
  158. },
  159. },
  160. },
  161. },
  162. },
  163. namespace: "",
  164. kube: fclient.NewClientBuilder().Build(),
  165. clientset: clientgofake.NewSimpleClientset(),
  166. },
  167. want: true,
  168. },
  169. {
  170. name: "auth fail results in error",
  171. fields: fields{},
  172. args: args{
  173. store: &esv1.ClusterSecretStore{
  174. TypeMeta: metav1.TypeMeta{
  175. Kind: esv1.ClusterSecretStoreKind,
  176. },
  177. Spec: esv1.SecretStoreSpec{
  178. Provider: &esv1.SecretStoreProvider{
  179. Kubernetes: &esv1.KubernetesProvider{
  180. Server: esv1.KubernetesServer{
  181. URL: "https://my.test.tld",
  182. CABundle: []byte(testCertificate),
  183. },
  184. RemoteNamespace: "remote",
  185. Auth: &esv1.KubernetesAuth{
  186. Token: &esv1.TokenAuth{
  187. BearerToken: v1.SecretKeySelector{
  188. Name: "foo",
  189. Namespace: pointer.To("default"),
  190. Key: "token",
  191. },
  192. },
  193. },
  194. },
  195. },
  196. },
  197. },
  198. namespace: "foobarothernamespace",
  199. clientset: clientgofake.NewSimpleClientset(),
  200. kube: fclient.NewClientBuilder().Build(),
  201. },
  202. wantErr: true,
  203. },
  204. {
  205. name: "test auth",
  206. fields: fields{},
  207. args: args{
  208. store: &esv1.ClusterSecretStore{
  209. TypeMeta: metav1.TypeMeta{
  210. Kind: esv1.ClusterSecretStoreKind,
  211. },
  212. Spec: esv1.SecretStoreSpec{
  213. Provider: &esv1.SecretStoreProvider{
  214. Kubernetes: &esv1.KubernetesProvider{
  215. Server: esv1.KubernetesServer{
  216. URL: "https://my.test.tld",
  217. CABundle: []byte(testCertificate),
  218. },
  219. RemoteNamespace: "remote",
  220. Auth: &esv1.KubernetesAuth{
  221. Token: &esv1.TokenAuth{
  222. BearerToken: v1.SecretKeySelector{
  223. Name: "foo",
  224. Namespace: pointer.To("default"),
  225. Key: "token",
  226. },
  227. },
  228. },
  229. },
  230. },
  231. },
  232. },
  233. namespace: "foobarothernamespace",
  234. clientset: clientgofake.NewSimpleClientset(),
  235. kube: fclient.NewClientBuilder().WithObjects(&corev1.Secret{
  236. ObjectMeta: metav1.ObjectMeta{
  237. Name: "foo",
  238. Namespace: "default",
  239. },
  240. Data: map[string][]byte{
  241. "token": []byte("1234"),
  242. },
  243. }).Build(),
  244. },
  245. want: true,
  246. },
  247. }
  248. for _, tt := range tests {
  249. t.Run(tt.name, func(t *testing.T) {
  250. got, err := (&Provider{}).newClient(context.Background(), tt.args.store, tt.args.kube, tt.args.clientset, tt.args.namespace)
  251. if (err != nil) != tt.wantErr {
  252. t.Errorf("ProviderKubernetes.NewClient() error = %v, wantErr %v", err, tt.wantErr)
  253. return
  254. }
  255. if tt.want {
  256. assert.NotNil(t, got)
  257. } else {
  258. assert.Nil(t, got)
  259. }
  260. })
  261. }
  262. }