kms_test.go 5.8 KB

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