Skip to content

Commit

Permalink
⭐️ vault subcommand to manage vaults (#337)
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-rock authored Feb 7, 2023
1 parent 8859c4d commit 5e41408
Showing 1 changed file with 244 additions and 0 deletions.
244 changes: 244 additions & 0 deletions apps/cnspec/cmd/vault.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
package cmd

import (
"context"
"fmt"
"strings"

"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.mondoo.com/cnquery/motor/vault"
"go.mondoo.com/cnquery/motor/vault/config"
)

func init() {
vaultListCmd.Flags().Bool("show-options", false, "displays configured options")
vaultCmd.AddCommand(vaultListCmd)

vaultConfigureCmd.Flags().String("type", "", "possible values: "+strings.Join(vault.TypeIds(), " | "))
vaultConfigureCmd.Flags().StringToString("option", nil, "addition vault connection options, multiple options via --option key=value")
vaultCmd.AddCommand(vaultConfigureCmd)

vaultCmd.AddCommand(vaultRemoveCmd)
vaultCmd.AddCommand(vaultResetCmd)

vaultCmd.AddCommand(vaultAddSecretCmd)

rootCmd.AddCommand(vaultCmd)
}

func emptyVaultConfigSecret() *vault.Secret {
return &vault.Secret{
Key: config.VaultConfigStoreKey,
Label: "User Vault Settings",
Data: config.ClientVaultConfig{}.SecretData(),
}
}

// vaultCmd represents the vault command
var vaultCmd = &cobra.Command{
Use: "vault",
Short: "Manages vault environments",
Long: ``,
}

var vaultListCmd = &cobra.Command{
Use: "list",
Short: "list vault environments",
Long: ``,
PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlag("show-options", cmd.Flags().Lookup("show-options"))
},
Run: func(cmd *cobra.Command, args []string) {
v := config.GetInternalVault()
ctx := context.Background()
secret, err := v.Get(ctx, &vault.SecretID{
Key: config.VaultConfigStoreKey,
})
if err != nil {
log.Fatal().Msg("no vault configured")
}

showOptions := viper.GetBool("show-options")

vCfgs, err := config.NewClientVaultConfig(secret)
if err != nil {
log.Fatal().Err(err).Msg("could not unmarshal credential")
}

for k, vCfg := range vCfgs {
// print configured vault
fmt.Printf("vault : %s (%s)\n", k, vCfg.Type.Value())
// print options if requested
if showOptions {
fmt.Printf("options:\n")
for ko, vo := range vCfg.Options {
fmt.Printf(" %s = %s\n", ko, vo)
}
}
}
},
}

var vaultConfigureCmd = &cobra.Command{
Use: "configure VAULTNAME",
Aliases: []string{"set"},
Short: "configures a vault environment",
Long: `
cnquery vault set mondoo-client-vault --type linux-kernel-keyring
`,
Args: cobra.ExactArgs(1),
PreRun: func(cmd *cobra.Command, args []string) {
viper.BindPFlag("type", cmd.Flags().Lookup("type"))
viper.BindPFlag("option", cmd.Flags().Lookup("option"))
},
Run: func(cmd *cobra.Command, args []string) {
v := config.GetInternalVault()
ctx := context.Background()

secret, err := v.Get(ctx, &vault.SecretID{
Key: config.VaultConfigStoreKey,
})
// error happens on initial use, create a new configuration
if err != nil {
secret = emptyVaultConfigSecret()
}

vCfgs, err := config.NewClientVaultConfig(secret)
if err != nil {
log.Fatal().Err(err).Msg("could not load vault configuration")
}

// overwrite existing / set vault config
// field name = vault name
vt, err := vault.NewVaultType(viper.GetString("type"))
if err != nil {
log.Fatal().Err(err).Msg("could not load vault configuration")
}

vaultName := args[0]
cfg := vault.VaultConfiguration{
Name: vaultName,
Type: vt,
Options: viper.GetStringMapString("option"),
}

vCfgs.Set(vaultName, cfg)
secret.Data = vCfgs.SecretData()

log.Info().Str("name", vaultName).Msg("set new vault configuration")
_, err = v.Set(ctx, secret)
if err != nil {
log.Fatal().Err(err).Msg("could not store update into vault")
}

log.Info().Msg("stored vault configuration successfully")
},
}

var vaultRemoveCmd = &cobra.Command{
Use: "remove VAULTNAME",
Short: "removes an configured vault environment",
Long: ``,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
v := config.GetInternalVault()
ctx := context.Background()

secret, err := v.Get(ctx, &vault.SecretID{
Key: config.VaultConfigStoreKey,
})
if err != nil {
log.Fatal().Err(err).Msg("could not retrieve vault configuration")
}

vCfgs, err := config.NewClientVaultConfig(secret)
if err != nil {
log.Fatal().Err(err).Msg("could not load vault configuration")
}

vaultName := args[0]
vCfgs.Delete(vaultName)
secret.Data = vCfgs.SecretData()

log.Info().Str("name", vaultName).Msg("set new vault configuration")
_, err = v.Set(ctx, secret)
if err != nil {
log.Fatal().Err(err).Msg("could not update vault configuration")
}

log.Info().Msg("removed vault configuration successfully")
},
}

var vaultResetCmd = &cobra.Command{
Use: "reset",
Short: "resets the vault configuration to defaults",
Long: ``,
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
v := config.GetInternalVault()
ctx := context.Background()

_, err := v.Set(ctx, emptyVaultConfigSecret())
if err != nil {
log.Fatal().Err(err).Msg("could not retrieve vault configuration")
}

log.Info().Msg("removed vault configuration successfully")
},
}

var vaultAddSecretCmd = &cobra.Command{
Use: "add-secret VAULTNAME SECRETID SECRETVALUE",
Short: "stores a secret into vault",
Args: cobra.ExactArgs(3),
PreRun: func(cmd *cobra.Command, args []string) {
},
Run: func(cmd *cobra.Command, args []string) {
v := config.GetInternalVault()
ctx := context.Background()

secret, err := v.Get(ctx, &vault.SecretID{
Key: config.VaultConfigStoreKey,
})
// error happens on initial use, create a new configuration
if err != nil {
secret = emptyVaultConfigSecret()
}

vCfgs, err := config.NewClientVaultConfig(secret)
if err != nil {
log.Fatal().Err(err).Msg("could not load vault configuration")
}

// search for vault
var selectedVaultCfg *vault.VaultConfiguration
for k, vCfg := range vCfgs {
if k != args[0] {
continue
}
selectedVaultCfg = &vCfg
}
if selectedVaultCfg == nil {
log.Fatal().Str("vault", args[0]).Msg("could not find vault")
}

selectedVault, err := config.New(selectedVaultCfg)
if err != nil {
log.Fatal().Msg("could not open vault")
}

_, err = selectedVault.Set(ctx, &vault.Secret{
Key: args[1],
Data: []byte(args[2]),
})
if err != nil {
log.Fatal().Msg("could not store secret")
}
log.Info().Msg("stored secret successfully")
},
}

0 comments on commit 5e41408

Please sign in to comment.