client_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. //
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. // */
  14. package github
  15. import (
  16. "context"
  17. "errors"
  18. "testing"
  19. github "github.com/google/go-github/v56/github"
  20. "github.com/stretchr/testify/assert"
  21. corev1 "k8s.io/api/core/v1"
  22. "k8s.io/utils/ptr"
  23. esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
  24. esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
  25. )
  26. type getSecretFn func(ctx context.Context, ref esv1beta1.PushSecretRemoteRef) (*github.Secret, *github.Response, error)
  27. func withGetSecretFn(secret *github.Secret, response *github.Response, err error) getSecretFn {
  28. return func(_ context.Context, _ esv1beta1.PushSecretRemoteRef) (*github.Secret, *github.Response, error) {
  29. return secret, response, err
  30. }
  31. }
  32. type getPublicKeyFn func(ctx context.Context) (*github.PublicKey, *github.Response, error)
  33. func withGetPublicKeyFn(key *github.PublicKey, response *github.Response, err error) getPublicKeyFn {
  34. return func(_ context.Context) (*github.PublicKey, *github.Response, error) {
  35. return key, response, err
  36. }
  37. }
  38. type createOrUpdateSecretFn func(ctx context.Context, encryptedSecret *github.EncryptedSecret) (*github.Response, error)
  39. func withCreateOrUpdateSecretFn(response *github.Response, err error) createOrUpdateSecretFn {
  40. return func(_ context.Context, _ *github.EncryptedSecret) (*github.Response, error) {
  41. return response, err
  42. }
  43. }
  44. func TestSecretExists(t *testing.T) {
  45. type testCase struct {
  46. name string
  47. prov *esv1beta1.GithubProvider
  48. remoteRef esv1beta1.PushSecretData
  49. getSecretFn getSecretFn
  50. wantErr error
  51. exists bool
  52. }
  53. tests := []testCase{
  54. {
  55. name: "getSecret fail",
  56. getSecretFn: withGetSecretFn(nil, nil, errors.New("boom")),
  57. exists: false,
  58. wantErr: errors.New("error fetching secret"),
  59. },
  60. {
  61. name: "no secret",
  62. getSecretFn: withGetSecretFn(nil, nil, nil),
  63. exists: false,
  64. },
  65. {
  66. name: "with secret",
  67. getSecretFn: withGetSecretFn(&github.Secret{}, nil, nil),
  68. exists: true,
  69. },
  70. }
  71. for _, test := range tests {
  72. t.Run(test.name, func(t *testing.T) {
  73. g := Client{
  74. provider: test.prov,
  75. }
  76. g.getSecretFn = test.getSecretFn
  77. ok, err := g.SecretExists(context.TODO(), test.remoteRef)
  78. assert.Equal(t, test.exists, ok)
  79. if test.wantErr == nil {
  80. assert.NoError(t, err)
  81. } else {
  82. assert.ErrorContains(t, err, test.wantErr.Error())
  83. }
  84. })
  85. }
  86. }
  87. func TestPushSecret(t *testing.T) {
  88. type testCase struct {
  89. name string
  90. prov *esv1beta1.GithubProvider
  91. secret *corev1.Secret
  92. remoteRef esv1beta1.PushSecretData
  93. getSecretFn getSecretFn
  94. getPublicKeyFn getPublicKeyFn
  95. createOrUpdateFn createOrUpdateSecretFn
  96. wantErr error
  97. }
  98. tests := []testCase{
  99. {
  100. name: "failGetSecretFn",
  101. getSecretFn: withGetSecretFn(nil, nil, errors.New("boom")),
  102. wantErr: errors.New("error fetching secret"),
  103. },
  104. {
  105. name: "failGetPublicKey",
  106. getSecretFn: withGetSecretFn(&github.Secret{
  107. Name: "foo",
  108. }, nil, nil),
  109. getPublicKeyFn: withGetPublicKeyFn(nil, nil, errors.New("boom")),
  110. wantErr: errors.New("error fetching public key"),
  111. },
  112. {
  113. name: "failDecodeKey",
  114. getSecretFn: withGetSecretFn(&github.Secret{
  115. Name: "foo",
  116. }, nil, nil),
  117. getPublicKeyFn: withGetPublicKeyFn(&github.PublicKey{
  118. Key: ptr.To("broken"),
  119. KeyID: ptr.To("123"),
  120. }, nil, nil),
  121. wantErr: errors.New("unable to decode public key"),
  122. },
  123. {
  124. name: "failSecretData",
  125. getSecretFn: withGetSecretFn(&github.Secret{
  126. Name: "foo",
  127. }, nil, nil),
  128. getPublicKeyFn: withGetPublicKeyFn(&github.PublicKey{
  129. Key: ptr.To("Cg=="),
  130. KeyID: ptr.To("123"),
  131. }, nil, nil),
  132. secret: &corev1.Secret{
  133. Data: map[string][]byte{
  134. "foo": []byte("bar"),
  135. },
  136. },
  137. remoteRef: esv1alpha1.PushSecretData{
  138. Match: esv1alpha1.PushSecretMatch{
  139. SecretKey: "bar",
  140. },
  141. },
  142. wantErr: errors.New("not found in secret"),
  143. },
  144. {
  145. name: "failSecretData",
  146. getSecretFn: withGetSecretFn(&github.Secret{
  147. Name: "foo",
  148. }, nil, nil),
  149. getPublicKeyFn: withGetPublicKeyFn(&github.PublicKey{
  150. Key: ptr.To("Zm9vYmFyCg=="),
  151. KeyID: ptr.To("123"),
  152. }, nil, nil),
  153. secret: &corev1.Secret{
  154. Data: map[string][]byte{
  155. "foo": []byte("bingg"),
  156. },
  157. },
  158. remoteRef: esv1alpha1.PushSecretData{
  159. Match: esv1alpha1.PushSecretMatch{
  160. SecretKey: "foo",
  161. },
  162. },
  163. createOrUpdateFn: withCreateOrUpdateSecretFn(nil, errors.New("boom")),
  164. wantErr: errors.New("failed to create secret"),
  165. },
  166. {
  167. name: "Success",
  168. getSecretFn: withGetSecretFn(&github.Secret{
  169. Name: "foo",
  170. }, nil, nil),
  171. getPublicKeyFn: withGetPublicKeyFn(&github.PublicKey{
  172. Key: ptr.To("Zm9vYmFyCg=="),
  173. KeyID: ptr.To("123"),
  174. }, nil, nil),
  175. secret: &corev1.Secret{
  176. Data: map[string][]byte{
  177. "foo": []byte("bingg"),
  178. },
  179. },
  180. remoteRef: esv1alpha1.PushSecretData{
  181. Match: esv1alpha1.PushSecretMatch{
  182. SecretKey: "foo",
  183. },
  184. },
  185. createOrUpdateFn: withCreateOrUpdateSecretFn(nil, nil),
  186. },
  187. }
  188. for _, test := range tests {
  189. t.Run(test.name, func(t *testing.T) {
  190. g := Client{
  191. provider: test.prov,
  192. }
  193. g.getSecretFn = test.getSecretFn
  194. g.getPublicKeyFn = test.getPublicKeyFn
  195. g.createOrUpdateFn = test.createOrUpdateFn
  196. err := g.PushSecret(context.TODO(), test.secret, test.remoteRef)
  197. if test.wantErr == nil {
  198. assert.NoError(t, err)
  199. } else {
  200. assert.ErrorContains(t, err, test.wantErr.Error())
  201. }
  202. })
  203. }
  204. }