go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/apps/cnquery/cmd/vault.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package cmd
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"strings"
    10  
    11  	"github.com/rs/zerolog/log"
    12  	"github.com/spf13/cobra"
    13  	"github.com/spf13/viper"
    14  	"go.mondoo.com/cnquery/providers-sdk/v1/vault"
    15  	"go.mondoo.com/cnquery/providers-sdk/v1/vault/config"
    16  )
    17  
    18  func init() {
    19  	vaultListCmd.Flags().Bool("show-options", false, "displays configured options")
    20  	VaultCmd.AddCommand(vaultListCmd)
    21  
    22  	vaultConfigureCmd.Flags().String("type", "", "possible values: "+strings.Join(vault.TypeIds(), " | "))
    23  	vaultConfigureCmd.Flags().StringToString("option", nil, "addition vault connection options, multiple options via --option key=value")
    24  	VaultCmd.AddCommand(vaultConfigureCmd)
    25  
    26  	VaultCmd.AddCommand(vaultRemoveCmd)
    27  	VaultCmd.AddCommand(vaultResetCmd)
    28  
    29  	VaultCmd.AddCommand(vaultAddSecretCmd)
    30  
    31  	rootCmd.AddCommand(VaultCmd)
    32  }
    33  
    34  func emptyVaultConfigSecret() *vault.Secret {
    35  	return &vault.Secret{
    36  		Key:   config.VaultConfigStoreKey,
    37  		Label: "User Vault Settings",
    38  		Data:  config.ClientVaultConfig{}.SecretData(),
    39  	}
    40  }
    41  
    42  // VaultCmd represents the vault command
    43  var VaultCmd = &cobra.Command{
    44  	Use:   "vault",
    45  	Short: "Manage vault environments.",
    46  	Long:  ``,
    47  }
    48  
    49  var vaultListCmd = &cobra.Command{
    50  	Use:   "list",
    51  	Short: "List vault environments.",
    52  	Long:  ``,
    53  	PreRun: func(cmd *cobra.Command, args []string) {
    54  		viper.BindPFlag("show-options", cmd.Flags().Lookup("show-options"))
    55  	},
    56  	Run: func(cmd *cobra.Command, args []string) {
    57  		v := config.GetInternalVault()
    58  		ctx := context.Background()
    59  		secret, err := v.Get(ctx, &vault.SecretID{
    60  			Key: config.VaultConfigStoreKey,
    61  		})
    62  		if err != nil {
    63  			log.Fatal().Msg("no vault configured")
    64  		}
    65  
    66  		showOptions := viper.GetBool("show-options")
    67  
    68  		vCfgs, err := config.NewClientVaultConfig(secret)
    69  		if err != nil {
    70  			log.Fatal().Err(err).Msg("could not unmarshal credential")
    71  		}
    72  
    73  		for k, vCfg := range vCfgs {
    74  			// print configured vault
    75  			fmt.Printf("vault  : %s (%s)\n", k, vCfg.Type.Value())
    76  			// print options if requested
    77  			if showOptions {
    78  				fmt.Printf("options:\n")
    79  				for ko, vo := range vCfg.Options {
    80  					fmt.Printf("  %s = %s\n", ko, vo)
    81  				}
    82  			}
    83  		}
    84  	},
    85  }
    86  
    87  var vaultConfigureCmd = &cobra.Command{
    88  	Use:     "configure VAULTNAME",
    89  	Aliases: []string{"set"},
    90  	Short:   "Configure a vault environment.",
    91  	Long: `
    92  
    93  cnquery vault set mondoo-client-vault --type linux-kernel-keyring
    94  
    95  `,
    96  	Args: cobra.ExactArgs(1),
    97  	PreRun: func(cmd *cobra.Command, args []string) {
    98  		viper.BindPFlag("type", cmd.Flags().Lookup("type"))
    99  		viper.BindPFlag("option", cmd.Flags().Lookup("option"))
   100  	},
   101  	Run: func(cmd *cobra.Command, args []string) {
   102  		v := config.GetInternalVault()
   103  		ctx := context.Background()
   104  
   105  		secret, err := v.Get(ctx, &vault.SecretID{
   106  			Key: config.VaultConfigStoreKey,
   107  		})
   108  		// error happens on initial use, create a new configuration
   109  		if err != nil {
   110  			secret = emptyVaultConfigSecret()
   111  		}
   112  
   113  		vCfgs, err := config.NewClientVaultConfig(secret)
   114  		if err != nil {
   115  			log.Fatal().Err(err).Msg("could not load vault configuration")
   116  		}
   117  
   118  		// overwrite existing / set vault config
   119  		// field name = vault name
   120  		vt, err := vault.NewVaultType(viper.GetString("type"))
   121  		if err != nil {
   122  			log.Fatal().Err(err).Msg("could not load vault configuration")
   123  		}
   124  
   125  		vaultName := args[0]
   126  		cfg := vault.VaultConfiguration{
   127  			Name:    vaultName,
   128  			Type:    vt,
   129  			Options: viper.GetStringMapString("option"),
   130  		}
   131  
   132  		vCfgs.Set(vaultName, cfg)
   133  		secret.Data = vCfgs.SecretData()
   134  
   135  		log.Info().Str("name", vaultName).Msg("set new vault configuration")
   136  		_, err = v.Set(ctx, secret)
   137  		if err != nil {
   138  			log.Fatal().Err(err).Msg("could not store update into vault")
   139  		}
   140  
   141  		log.Info().Msg("stored vault configuration successfully")
   142  	},
   143  }
   144  
   145  var vaultRemoveCmd = &cobra.Command{
   146  	Use:   "remove VAULTNAME",
   147  	Short: "Remove a configured vault environment.",
   148  	Long:  ``,
   149  	Args:  cobra.ExactArgs(1),
   150  	Run: func(cmd *cobra.Command, args []string) {
   151  		v := config.GetInternalVault()
   152  		ctx := context.Background()
   153  
   154  		secret, err := v.Get(ctx, &vault.SecretID{
   155  			Key: config.VaultConfigStoreKey,
   156  		})
   157  		if err != nil {
   158  			log.Fatal().Err(err).Msg("could not retrieve vault configuration")
   159  		}
   160  
   161  		vCfgs, err := config.NewClientVaultConfig(secret)
   162  		if err != nil {
   163  			log.Fatal().Err(err).Msg("could not load vault configuration")
   164  		}
   165  
   166  		vaultName := args[0]
   167  		vCfgs.Delete(vaultName)
   168  		secret.Data = vCfgs.SecretData()
   169  
   170  		log.Info().Str("name", vaultName).Msg("set new vault configuration")
   171  		_, err = v.Set(ctx, secret)
   172  		if err != nil {
   173  			log.Fatal().Err(err).Msg("could not update vault configuration")
   174  		}
   175  
   176  		log.Info().Msg("removed vault configuration successfully")
   177  	},
   178  }
   179  
   180  var vaultResetCmd = &cobra.Command{
   181  	Use:   "reset",
   182  	Short: "Reset the vault configuration to defaults.",
   183  	Long:  ``,
   184  	Args:  cobra.ExactArgs(0),
   185  	Run: func(cmd *cobra.Command, args []string) {
   186  		v := config.GetInternalVault()
   187  		ctx := context.Background()
   188  
   189  		_, err := v.Set(ctx, emptyVaultConfigSecret())
   190  		if err != nil {
   191  			log.Fatal().Err(err).Msg("could not retrieve vault configuration")
   192  		}
   193  
   194  		log.Info().Msg("removed vault configuration successfully")
   195  	},
   196  }
   197  
   198  var vaultAddSecretCmd = &cobra.Command{
   199  	Use:   "add-secret VAULTNAME SECRETID SECRETVALUE",
   200  	Short: "Store a secret in a vault.",
   201  	Args:  cobra.ExactArgs(3),
   202  	PreRun: func(cmd *cobra.Command, args []string) {
   203  	},
   204  	Run: func(cmd *cobra.Command, args []string) {
   205  		v := config.GetInternalVault()
   206  		ctx := context.Background()
   207  
   208  		secret, err := v.Get(ctx, &vault.SecretID{
   209  			Key: config.VaultConfigStoreKey,
   210  		})
   211  		// error happens on initial use, create a new configuration
   212  		if err != nil {
   213  			secret = emptyVaultConfigSecret()
   214  		}
   215  
   216  		vCfgs, err := config.NewClientVaultConfig(secret)
   217  		if err != nil {
   218  			log.Fatal().Err(err).Msg("could not load vault configuration")
   219  		}
   220  
   221  		// search for vault
   222  		var selectedVaultCfg *vault.VaultConfiguration
   223  		for k, vCfg := range vCfgs {
   224  			if k != args[0] {
   225  				continue
   226  			}
   227  			selectedVaultCfg = &vCfg
   228  		}
   229  		if selectedVaultCfg == nil {
   230  			log.Fatal().Str("vault", args[0]).Msg("could not find vault")
   231  		}
   232  
   233  		selectedVault, err := config.New(selectedVaultCfg)
   234  		if err != nil {
   235  			log.Fatal().Msg("could not open vault")
   236  		}
   237  
   238  		_, err = selectedVault.Set(ctx, &vault.Secret{
   239  			Key:  args[1],
   240  			Data: []byte(args[2]),
   241  		})
   242  		if err != nil {
   243  			log.Fatal().Msg("could not store secret")
   244  		}
   245  		log.Info().Msg("stored secret successfully")
   246  	},
   247  }