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  }