kms_test.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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 alibaba
  13. import (
  14. "context"
  15. "fmt"
  16. "reflect"
  17. "strings"
  18. "testing"
  19. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
  20. kmssdk "github.com/aliyun/alibaba-cloud-sdk-go/services/kms"
  21. esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
  22. fakesm "github.com/external-secrets/external-secrets/pkg/provider/alibaba/fake"
  23. )
  24. const (
  25. secretName = "test-example"
  26. secretValue = "value"
  27. )
  28. type keyManagementServiceTestCase struct {
  29. mockClient *fakesm.AlibabaMockClient
  30. apiInput *kmssdk.GetSecretValueRequest
  31. apiOutput *kmssdk.GetSecretValueResponse
  32. ref *esv1alpha1.ExternalSecretDataRemoteRef
  33. apiErr error
  34. expectError string
  35. expectedSecret string
  36. // for testing secretmap
  37. expectedData map[string][]byte
  38. }
  39. func makeValidKMSTestCase() *keyManagementServiceTestCase {
  40. kmstc := keyManagementServiceTestCase{
  41. mockClient: &fakesm.AlibabaMockClient{},
  42. apiInput: makeValidAPIInput(),
  43. ref: makeValidRef(),
  44. apiOutput: makeValidAPIOutput(),
  45. apiErr: nil,
  46. expectError: "",
  47. expectedSecret: "",
  48. expectedData: make(map[string][]byte),
  49. }
  50. kmstc.mockClient.WithValue(kmstc.apiInput, kmstc.apiOutput, kmstc.apiErr)
  51. return &kmstc
  52. }
  53. func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
  54. return &esv1alpha1.ExternalSecretDataRemoteRef{
  55. Extract: esv1alpha1.ExternalSecretExtract{
  56. Key: secretName,
  57. },
  58. }
  59. }
  60. func makeValidAPIInput() *kmssdk.GetSecretValueRequest {
  61. return &kmssdk.GetSecretValueRequest{
  62. SecretName: secretName,
  63. }
  64. }
  65. func makeValidAPIOutput() *kmssdk.GetSecretValueResponse {
  66. kmsresponse := &kmssdk.GetSecretValueResponse{
  67. BaseResponse: &responses.BaseResponse{},
  68. RequestId: "",
  69. SecretName: secretName,
  70. VersionId: "",
  71. CreateTime: "",
  72. SecretData: secretValue,
  73. SecretDataType: "",
  74. AutomaticRotation: "",
  75. RotationInterval: "",
  76. NextRotationDate: "",
  77. ExtendedConfig: "",
  78. LastRotationDate: "",
  79. SecretType: "",
  80. VersionStages: kmssdk.VersionStagesInGetSecretValue{},
  81. }
  82. return kmsresponse
  83. }
  84. func makeValidKMSTestCaseCustom(tweaks ...func(kmstc *keyManagementServiceTestCase)) *keyManagementServiceTestCase {
  85. kmstc := makeValidKMSTestCase()
  86. for _, fn := range tweaks {
  87. fn(kmstc)
  88. }
  89. kmstc.mockClient.WithValue(kmstc.apiInput, kmstc.apiOutput, kmstc.apiErr)
  90. return kmstc
  91. }
  92. var setAPIErr = func(kmstc *keyManagementServiceTestCase) {
  93. kmstc.apiErr = fmt.Errorf("oh no")
  94. kmstc.expectError = "oh no"
  95. }
  96. var setNilMockClient = func(kmstc *keyManagementServiceTestCase) {
  97. kmstc.mockClient = nil
  98. kmstc.expectError = errUninitalizedAlibabaProvider
  99. }
  100. func TestAlibabaKMSGetSecret(t *testing.T) {
  101. secretData := make(map[string]interface{})
  102. secretValue := "changedvalue"
  103. secretData["payload"] = secretValue
  104. // good case: default version is set
  105. // key is passed in, output is sent back
  106. setSecretString := func(kmstc *keyManagementServiceTestCase) {
  107. kmstc.apiOutput.SecretName = secretName
  108. kmstc.apiOutput.SecretData = secretValue
  109. kmstc.expectedSecret = secretValue
  110. }
  111. // good case: custom version set
  112. setCustomKey := func(kmstc *keyManagementServiceTestCase) {
  113. kmstc.apiOutput.SecretName = "test-example-other"
  114. kmstc.ref.Extract.Key = "test-example-other"
  115. kmstc.apiOutput.SecretData = secretValue
  116. kmstc.expectedSecret = secretValue
  117. }
  118. successCases := []*keyManagementServiceTestCase{
  119. makeValidKMSTestCaseCustom(setSecretString),
  120. makeValidKMSTestCaseCustom(setCustomKey),
  121. makeValidKMSTestCaseCustom(setAPIErr),
  122. makeValidKMSTestCaseCustom(setNilMockClient),
  123. }
  124. sm := KeyManagementService{}
  125. for k, v := range successCases {
  126. sm.Client = v.mockClient
  127. out, err := sm.GetSecret(context.Background(), *v.ref)
  128. if !ErrorContains(err, v.expectError) {
  129. t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
  130. }
  131. if string(out) != v.expectedSecret {
  132. t.Errorf("[%d] unexpected secret: expected %s, got %s", k, v.expectedSecret, string(out))
  133. }
  134. }
  135. }
  136. func TestGetSecretMap(t *testing.T) {
  137. // good case: default version & deserialization
  138. setDeserialization := func(kmstc *keyManagementServiceTestCase) {
  139. kmstc.apiOutput.SecretName = "foo"
  140. kmstc.expectedData["foo"] = []byte("bar")
  141. kmstc.apiOutput.SecretData = `{"foo":"bar"}`
  142. }
  143. // bad case: invalid json
  144. setInvalidJSON := func(kmstc *keyManagementServiceTestCase) {
  145. kmstc.apiOutput.SecretData = "-----------------"
  146. kmstc.expectError = "unable to unmarshal secret"
  147. }
  148. successCases := []*keyManagementServiceTestCase{
  149. makeValidKMSTestCaseCustom(setDeserialization),
  150. makeValidKMSTestCaseCustom(setInvalidJSON),
  151. makeValidKMSTestCaseCustom(setNilMockClient),
  152. makeValidKMSTestCaseCustom(setAPIErr),
  153. }
  154. sm := KeyManagementService{}
  155. for k, v := range successCases {
  156. sm.Client = v.mockClient
  157. out, err := sm.GetSecretMap(context.Background(), *v.ref)
  158. if !ErrorContains(err, v.expectError) {
  159. t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
  160. }
  161. if err == nil && !reflect.DeepEqual(out, v.expectedData) {
  162. t.Errorf("[%d] unexpected secret data: expected %#v, got %#v", k, v.expectedData, out)
  163. }
  164. }
  165. }
  166. func ErrorContains(out error, want string) bool {
  167. if out == nil {
  168. return want == ""
  169. }
  170. if want == "" {
  171. return false
  172. }
  173. return strings.Contains(out.Error(), want)
  174. }