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 }