github.com/jenkins-x/jx/v2@v2.1.155/pkg/vault/fake/client.go (about) 1 package fake 2 3 import ( 4 "encoding/base64" 5 "fmt" 6 "net/url" 7 "regexp" 8 9 "github.com/jenkins-x/jx/v2/pkg/secreturl" 10 11 "github.com/jenkins-x/jx/v2/pkg/util" 12 "github.com/pkg/errors" 13 ) 14 15 const ( 16 yamlDataKey = "yaml" 17 ) 18 19 var vaultURIRegex = regexp.MustCompile(`vault:[-_.\w\/:]*`) 20 21 // FakeVaultClient is an in memory implementation of vault, useful for testing 22 type FakeVaultClient struct { 23 Data map[string]map[string]interface{} 24 } 25 26 //NewFakeVaultClient creates a new FakeVaultClient 27 func NewFakeVaultClient() FakeVaultClient { 28 return FakeVaultClient{ 29 Data: make(map[string]map[string]interface{}), 30 } 31 } 32 33 // Write a secret to vault 34 func (f FakeVaultClient) Write(secretName string, data map[string]interface{}) (map[string]interface{}, error) { 35 fmt.Printf("fakeClient: storing key at %s data: %#v\n", secretName, data) 36 f.Data[secretName] = data 37 return data, nil 38 } 39 40 // WriteObject a secret to vault 41 func (f FakeVaultClient) WriteObject(secretName string, secret interface{}) (map[string]interface{}, error) { 42 payload, err := util.ToMapStringInterfaceFromStruct(secret) 43 if err != nil { 44 return nil, errors.WithStack(err) 45 } 46 return f.Write(secretName, payload) 47 } 48 49 // WriteYaml a secret to vault 50 func (f FakeVaultClient) WriteYaml(secretName string, y string) (map[string]interface{}, error) { 51 data := base64.StdEncoding.EncodeToString([]byte(y)) 52 secretMap := map[string]interface{}{ 53 yamlDataKey: data, 54 } 55 return f.Write(secretName, secretMap) 56 } 57 58 // List the secrets in vault 59 func (f FakeVaultClient) List(path string) ([]string, error) { 60 secretNames := make([]string, 0) 61 for _, s := range f.Data[path] { 62 if orig, ok := s.(string); ok { 63 secretNames = append(secretNames, orig) 64 } 65 } 66 return secretNames, nil 67 } 68 69 // Read a secret from vault 70 func (f FakeVaultClient) Read(secretName string) (map[string]interface{}, error) { 71 if answer, ok := f.Data[secretName]; !ok { 72 return nil, errors.Errorf("secret does not exist at key %s", secretName) 73 } else { 74 return answer, nil 75 } 76 } 77 78 // ReadObject a secret from vault 79 func (f FakeVaultClient) ReadObject(secretName string, secret interface{}) error { 80 m, err := f.Read(secretName) 81 if err != nil { 82 return errors.Wrapf(err, "reading the secret %q from vault", secretName) 83 } 84 err = util.ToStructFromMapStringInterface(m, &secret) 85 if err != nil { 86 return errors.Wrapf(err, "deserializing the secret %q from vault", secretName) 87 } 88 89 return nil 90 } 91 92 // ReadYaml a secret from vault 93 func (f FakeVaultClient) ReadYaml(secretName string) (string, error) { 94 secretMap, err := f.Read(secretName) 95 if err != nil { 96 return "", errors.Wrapf(err, "reading secret %q from vault", secretName) 97 } 98 data, ok := secretMap[yamlDataKey] 99 if !ok { 100 return "", nil 101 } 102 strData, ok := data.(string) 103 if !ok { 104 return "", fmt.Errorf("data stored at secret key %s/%s is not a valid string", secretName, yamlDataKey) 105 } 106 decodedData, err := base64.StdEncoding.DecodeString(strData) 107 if err != nil { 108 return "", errors.Wrapf(err, "decoding base64 data stored at secret key %s/%s", secretName, yamlDataKey) 109 } 110 return string(decodedData), nil 111 } 112 113 // Config shows the vault config 114 func (f FakeVaultClient) Config() (vaultURL url.URL, vaultToken string, err error) { 115 u, err := url.Parse("https://fake.vault") 116 if err != nil { 117 return *u, "", errors.WithStack(err) 118 } 119 return *u, "fakevault", nil 120 } 121 122 // ReplaceURIs corrects the URIs 123 func (f FakeVaultClient) ReplaceURIs(text string) (string, error) { 124 return secreturl.ReplaceURIs(text, f, vaultURIRegex, "vault:") 125 }