github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/get/vault/get_vault.go (about)

     1  package vault
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/olli-ai/jx/v2/pkg/cmd/helper"
     7  	"github.com/olli-ai/jx/v2/pkg/io/secrets"
     8  	"github.com/olli-ai/jx/v2/pkg/kube"
     9  	"github.com/olli-ai/jx/v2/pkg/kube/cluster"
    10  	kubeVault "github.com/olli-ai/jx/v2/pkg/kube/vault"
    11  	"github.com/olli-ai/jx/v2/pkg/vault"
    12  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    13  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    14  
    15  	"github.com/olli-ai/jx/v2/pkg/cmd/opts"
    16  	"github.com/olli-ai/jx/v2/pkg/cmd/templates"
    17  	"github.com/pkg/errors"
    18  	"github.com/spf13/cobra"
    19  )
    20  
    21  type GetVaultOptions struct {
    22  	*opts.CommonOptions
    23  
    24  	Namespace           string
    25  	DisableURLDiscovery bool
    26  }
    27  
    28  var (
    29  	getVaultLong = templates.LongDesc(`
    30  		Display Jenkins X system Vault as well as Vault instances created by 'jx create vault'.
    31  	`)
    32  
    33  	getVaultExample = templates.Examples(`
    34  		# List all vaults 
    35  		jx get vaults
    36  	`)
    37  )
    38  
    39  // NewCmdGetVault creates a new command for 'jx get vaults'
    40  func NewCmdGetVault(commonOpts *opts.CommonOptions) *cobra.Command {
    41  	options := &GetVaultOptions{
    42  		CommonOptions: commonOpts,
    43  	}
    44  
    45  	cmd := &cobra.Command{
    46  		Use:     "vault",
    47  		Aliases: []string{"vaults"},
    48  		Short:   "Display one or more Vaults",
    49  		Long:    getVaultLong,
    50  		Example: getVaultExample,
    51  		Run: func(cmd *cobra.Command, args []string) {
    52  			options.Cmd = cmd
    53  			options.Args = args
    54  			err := options.Run()
    55  			helper.CheckErr(err)
    56  		},
    57  	}
    58  
    59  	cmd.Flags().StringVarP(&options.Namespace, "namespace", "n", "", "Namespace from where to list the vaults")
    60  	cmd.Flags().BoolVarP(&options.DisableURLDiscovery, "disableURLDiscovery", "", false, "Disables the automatic Vault URL discovery")
    61  	return cmd
    62  }
    63  
    64  // Run implements the command
    65  func (o *GetVaultOptions) Run() error {
    66  	client, ns, err := o.KubeClientAndNamespace()
    67  	if err != nil {
    68  		return errors.Wrap(err, "creating kubernetes client")
    69  	}
    70  
    71  	if o.Namespace == "" {
    72  		o.Namespace = ns
    73  	}
    74  	vaultOperatorClient, err := o.VaultOperatorClient()
    75  	if err != nil {
    76  		return errors.Wrap(err, "creating vault operator client")
    77  	}
    78  
    79  	var useIngressURL bool
    80  	if o.DisableURLDiscovery {
    81  		useIngressURL = true
    82  	} else {
    83  		useIngressURL = cluster.IsInCluster()
    84  	}
    85  
    86  	vaults, err := kubeVault.GetVaults(client, vaultOperatorClient, o.Namespace, useIngressURL)
    87  	if err != nil {
    88  		return errors.Wrap(err, "error retrieving Jenkins X managed Vault instances")
    89  	}
    90  
    91  	systemVault, err := o.systemVault(o.Namespace)
    92  	if err != nil {
    93  		return errors.Wrap(err, "error retrieving system Vault")
    94  	}
    95  	if systemVault != nil {
    96  		vaults = o.appendUniq(vaults, systemVault)
    97  	}
    98  
    99  	table := o.CreateTable()
   100  	table.AddRow("NAME", "URL", "AUTH-SERVICE-ACCOUNT")
   101  	for _, v := range vaults {
   102  		table.AddRow(v.Name, v.URL, v.ServiceAccountName)
   103  	}
   104  	table.Render()
   105  
   106  	return nil
   107  }
   108  
   109  // systemVault gets the system vault
   110  func (o *GetVaultOptions) systemVault(namespace string) (*vault.Vault, error) {
   111  	kubeClient, devNamespace, err := o.CommonOptions.KubeClientAndDevNamespace()
   112  	if err != nil {
   113  		return nil, errors.Wrap(err, "unable to create Kube client for Vault client creation")
   114  	}
   115  
   116  	if namespace != devNamespace {
   117  		return nil, nil
   118  	}
   119  
   120  	installConfigMap, err := kubeClient.CoreV1().ConfigMaps(devNamespace).Get(kube.ConfigMapNameJXInstallConfig, metav1.GetOptions{})
   121  	if err != nil {
   122  		if k8serrors.IsNotFound(err) {
   123  			return nil, errors.Errorf("unable to determine Vault type since ConfigMap %s not found in namespace %s", kube.ConfigMapNameJXInstallConfig, devNamespace)
   124  		}
   125  		return nil, errors.Wrapf(err, "error retrieving ConfigMap %s in namespace %s", kube.ConfigMapNameJXInstallConfig, devNamespace)
   126  	}
   127  
   128  	installValues := installConfigMap.Data
   129  
   130  	if installValues[secrets.SecretsLocationKey] != string(secrets.VaultLocationKind) {
   131  		return nil, errors.Errorf("unable to create Vault client for secret location kind '%s'", installValues[secrets.SecretsLocationKey])
   132  	}
   133  
   134  	vault, err := vault.FromMap(installValues, devNamespace)
   135  	return &vault, err
   136  }
   137  
   138  func (o *GetVaultOptions) appendUniq(vaults []*vault.Vault, newVault *vault.Vault) []*vault.Vault {
   139  	for _, v := range vaults {
   140  		if reflect.DeepEqual(v, newVault) {
   141  			return vaults
   142  		}
   143  	}
   144  
   145  	vaults = append(vaults, newVault)
   146  	return vaults
   147  }