github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/io/secrets/secret_locations.go (about) 1 package secrets 2 3 import ( 4 "github.com/olli-ai/jx/v2/pkg/kube" 5 "github.com/pkg/errors" 6 v1 "k8s.io/api/core/v1" 7 "k8s.io/client-go/kubernetes" 8 ) 9 10 const ( 11 // SecretsLocationKey key in the config map which stored the location where the secrets are stored 12 SecretsLocationKey = "secretsLocation" 13 14 // VaultSecretPrefix is the key in the install config map which defines the secrets prefix under which to store secrets 15 // in the Vault KV engine. 16 VaultSecretPrefix = "vaultSecretsPrefix" 17 ) 18 19 // SecretsLocationKind type for secrets location kind 20 type SecretsLocationKind string 21 22 const ( 23 // FileSystemLocationKind indicates that secrets location is the file system 24 FileSystemLocationKind SecretsLocationKind = "local" 25 // VaultLocationKind indicates that secrets location is vault 26 VaultLocationKind SecretsLocationKind = "vault" 27 // KubeLocationKind indicates that secrets location is in Kubernetes 28 KubeLocationKind SecretsLocationKind = "kube" 29 // AutoLocationKind indicates that secrets location needs to be dynamically determine 30 AutoLocationKind SecretsLocationKind = "auto" 31 ) 32 33 // SecretLocation interfaces to identify where is the secrets location 34 type SecretLocation interface { 35 // Location returns the location where the secrets are stored 36 Location() SecretsLocationKind 37 // SecretLocation configure the secrets location. It will save the 38 // value in a config map if persist flag is set. 39 SetLocation(location SecretsLocationKind, persist bool) error 40 } 41 42 type secretLocation struct { 43 kubeClient kubernetes.Interface 44 namespace string 45 location SecretsLocationKind 46 } 47 48 // NewSecretLocation creates a SecretLocation 49 func NewSecretLocation(kubeClient kubernetes.Interface, namespace string) SecretLocation { 50 return &secretLocation{ 51 kubeClient: kubeClient, 52 namespace: namespace, 53 location: FileSystemLocationKind, 54 } 55 } 56 57 // Location returns the location of the secrets. It fetches the secrets location first 58 // for the config map, if not value is persisted there, it will just use the default location. 59 func (s *secretLocation) Location() SecretsLocationKind { 60 configMap, err := getInstallConfigMapData(s.kubeClient, s.namespace) 61 if err != nil { 62 return s.location 63 } 64 value, ok := configMap[SecretsLocationKey] 65 if ok && value == string(VaultLocationKind) { 66 return VaultLocationKind 67 } 68 return s.location 69 } 70 71 // SetLocation configures the secrets location. It will store the value in a config map 72 // if the persist flag is set 73 func (s *secretLocation) SetLocation(location SecretsLocationKind, persist bool) error { 74 s.location = location 75 if persist { 76 _, err := kube.DefaultModifyConfigMap(s.kubeClient, s.namespace, kube.ConfigMapNameJXInstallConfig, 77 func(configMap *v1.ConfigMap) error { 78 configMap.Data[SecretsLocationKey] = string(s.location) 79 return nil 80 }, nil) 81 if err != nil { 82 return errors.Wrapf(err, "saving secrets location in configmap %s", kube.ConfigMapNameJXInstallConfig) 83 } 84 } 85 return nil 86 } 87 88 func getInstallConfigMapData(kubeClient kubernetes.Interface, namespace string) (map[string]string, error) { 89 configMap, err := kube.GetConfigMapData(kubeClient, kube.ConfigMapNameJXInstallConfig, namespace) 90 if err != nil { 91 return nil, errors.Wrapf(err, "getting configmap %s", kube.ConfigMapNameJXInstallConfig) 92 } 93 return configMap, nil 94 } 95 96 // ToSecretsLocation converts a string to a SecretsLocationKind 97 func ToSecretsLocation(location string) SecretsLocationKind { 98 switch location { 99 case "local": 100 return FileSystemLocationKind 101 case "vault": 102 return VaultLocationKind 103 case "kube": 104 return KubeLocationKind 105 default: 106 return AutoLocationKind 107 } 108 }