github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/secreturl/localvault/client.go (about) 1 package localvault 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "regexp" 8 "strings" 9 10 "github.com/olli-ai/jx/v2/pkg/helm" 11 "github.com/olli-ai/jx/v2/pkg/secreturl" 12 "github.com/olli-ai/jx/v2/pkg/util" 13 "github.com/pkg/errors" 14 ) 15 16 var localURIRegex = regexp.MustCompile(`:[\s"]*local:[-_.\w\/:]*`) 17 18 // CanonicalClusterPath this is the path where the client will fall back when secrets are not found at the standard path 19 const CanonicalClusterPath = "currentCluster" 20 21 // FileSystemClient a local file system based client loading/saving content from the given URL 22 type FileSystemClient struct { 23 Dir string 24 } 25 26 // NewFileSystemClient create a new local file system based client loading content from the given URL 27 func NewFileSystemClient(dir string) secreturl.Client { 28 return &FileSystemClient{ 29 Dir: dir, 30 } 31 } 32 33 // Read reads a named secret from the vault 34 func (c *FileSystemClient) Read(secretName string) (map[string]interface{}, error) { 35 name := c.fileName(secretName) 36 exists, err := util.FileExists(name) 37 if err != nil { 38 return nil, errors.Wrapf(err, "failed to check if file exists %s", name) 39 } 40 if !exists { 41 parts := strings.Split(secretName, "/") 42 if len(parts) == 2 { 43 // secrets will be mounted in this path because we have no way to get the cluster name at that point 44 secretName = filepath.Join(CanonicalClusterPath, parts[1]) 45 name = c.fileName(secretName) 46 exists, err = util.FileExists(name) 47 if err != nil { 48 return nil, errors.Wrapf(err, "failed to check if file exists %s", name) 49 } 50 if !exists { 51 return nil, errors.Wrapf(err, "the canonical path %s doesn't exist", name) 52 } 53 return helm.LoadValuesFile(name) 54 } 55 return nil, fmt.Errorf("local vault file does not exist: %s", name) 56 } 57 return helm.LoadValuesFile(name) 58 } 59 60 // ReadObject reads a generic named object from vault. 61 // The secret _must_ be serializable to JSON. 62 func (c *FileSystemClient) ReadObject(secretName string, secret interface{}) error { 63 m, err := c.Read(secretName) 64 if err != nil { 65 return errors.Wrapf(err, "reading the secret %q from vault", secretName) 66 } 67 err = util.ToStructFromMapStringInterface(m, &secret) 68 if err != nil { 69 return errors.Wrapf(err, "deserializing the secret %q from vault", secretName) 70 } 71 return nil 72 } 73 74 // Write writes a named secret to the vault with the data provided. Data can be a generic map of stuff, but at all points 75 // in the map, keys _must_ be strings (not bool, int or even interface{}) otherwise you'll get an error 76 func (c *FileSystemClient) Write(secretName string, data map[string]interface{}) (map[string]interface{}, error) { 77 path := c.fileName(secretName) 78 dir, _ := filepath.Split(path) 79 err := os.MkdirAll(dir, util.DefaultWritePermissions) 80 if err != nil { 81 return nil, errors.Wrapf(err, "failed to ensure that parent directory exists %s", dir) 82 } 83 err = helm.SaveFile(path, data) 84 if err != nil { 85 return nil, err 86 } 87 return c.Read(secretName) 88 } 89 90 // WriteObject writes a generic named object to the vault. 91 // The secret _must_ be serializable to JSON. 92 func (c *FileSystemClient) WriteObject(secretName string, secret interface{}) (map[string]interface{}, error) { 93 path := c.fileName(secretName) 94 dir, _ := filepath.Split(path) 95 err := os.MkdirAll(dir, util.DefaultWritePermissions) 96 if err != nil { 97 return nil, errors.Wrapf(err, "failed to ensure that parent directory exists %s", dir) 98 } 99 err = helm.SaveFile(path, secret) 100 if err != nil { 101 return nil, err 102 } 103 return c.Read(secretName) 104 } 105 106 // ReplaceURIs will replace any local: URIs in a string 107 func (c *FileSystemClient) ReplaceURIs(s string) (string, error) { 108 return secreturl.ReplaceURIs(s, c, localURIRegex, "local:") 109 } 110 111 func (c *FileSystemClient) fileName(secretName string) string { 112 return filepath.Join(c.Dir, secretName+".yaml") 113 }