-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
⭐️ vault subcommand to manage vaults (#337)
mondoohq/cnquery#893 to cnspec v7
- Loading branch information
1 parent
8859c4d
commit 5e41408
Showing
1 changed file
with
244 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
}, | ||
} |