github.com/influxdata/telegraf@v1.30.3/cmd/telegraf/cmd_secretstore.go (about) 1 // Command handling for secret-stores' "secrets" command 2 package main 3 4 import ( 5 "errors" 6 "fmt" 7 "os" 8 "sort" 9 "strings" 10 11 "github.com/awnumar/memguard" 12 "github.com/urfave/cli/v2" 13 "golang.org/x/term" 14 ) 15 16 func processFilterOnlySecretStoreFlags(ctx *cli.Context) Filters { 17 sectionFilters := []string{"inputs", "outputs", "processors", "aggregators"} 18 inputFilters := []string{"-"} 19 outputFilters := []string{"-"} 20 processorFilters := []string{"-"} 21 aggregatorFilters := []string{"-"} 22 23 // Only load the secret-stores 24 var secretstore string 25 if len(ctx.Lineage()) >= 2 { 26 parent := ctx.Lineage()[1] // ancestor contexts in order from child to parent 27 secretstore = parent.String("secretstore-filter") 28 } 29 30 // If both the parent and command filters are defined, append them together 31 secretstore = appendFilter(secretstore, ctx.String("secretstore-filter")) 32 secretstoreFilters := deleteEmpty(strings.Split(secretstore, ":")) 33 return Filters{sectionFilters, inputFilters, outputFilters, aggregatorFilters, processorFilters, secretstoreFilters} 34 } 35 36 func getSecretStoreCommands(m App) []*cli.Command { 37 return []*cli.Command{ 38 { 39 Name: "secrets", 40 Usage: "commands for listing, adding and removing secrets on all known secret-stores", 41 Subcommands: []*cli.Command{ 42 { 43 Name: "list", 44 Usage: "list known secrets and secret-stores", 45 Description: ` 46 The 'list' command requires passing in your configuration file 47 containing the secret-store definitions you want to access. To get a 48 list of available secret-store plugins, please have a look at 49 https://github.com/influxdata/telegraf/tree/master/plugins/secretstores. 50 51 For help on how to define secret-stores, check the documentation of the 52 different plugins. 53 54 Assuming you use the default configuration file location, you can run 55 the following command to list the keys of all known secrets in ALL 56 available stores 57 58 > telegraf secrets list 59 60 To get the keys of all known secrets in a particular store, you can run 61 62 > telegraf secrets list mystore 63 64 To also reveal the actual secret, i.e. the value, you can pass the 65 '--reveal-secret' flag. 66 `, 67 ArgsUsage: "[secret-store ID]...[secret-store ID]", 68 Flags: []cli.Flag{ 69 &cli.BoolFlag{ 70 Name: "reveal-secret", 71 Usage: "also print the secret value", 72 }, 73 }, 74 Action: func(cCtx *cli.Context) error { 75 // Only load the secret-stores 76 filters := processFilterOnlySecretStoreFlags(cCtx) 77 g := GlobalFlags{ 78 config: cCtx.StringSlice("config"), 79 configDir: cCtx.StringSlice("config-directory"), 80 plugindDir: cCtx.String("plugin-directory"), 81 password: cCtx.String("password"), 82 debug: cCtx.Bool("debug"), 83 } 84 w := WindowFlags{} 85 m.Init(nil, filters, g, w) 86 87 args := cCtx.Args() 88 var storeIDs []string 89 if args.Present() { 90 storeIDs = args.Slice() 91 } else { 92 ids, err := m.ListSecretStores() 93 if err != nil { 94 return fmt.Errorf("unable to determine secret-store IDs: %w", err) 95 } 96 storeIDs = ids 97 } 98 sort.Strings(storeIDs) 99 100 reveal := cCtx.Bool("reveal-secret") 101 for _, storeID := range storeIDs { 102 store, err := m.GetSecretStore(storeID) 103 if err != nil { 104 return fmt.Errorf("unable to get secret-store %q: %w", storeID, err) 105 } 106 keys, err := store.List() 107 if err != nil { 108 return fmt.Errorf("unable to get secrets from store %q: %w", storeID, err) 109 } 110 sort.Strings(keys) 111 112 fmt.Printf("Known secrets for store %q:\n", storeID) 113 for _, k := range keys { 114 var v []byte 115 if reveal { 116 if v, err = store.Get(k); err != nil { 117 return fmt.Errorf("unable to get value of secret %q from store %q: %w", k, storeID, err) 118 } 119 } 120 fmt.Printf(" %-30s %s\n", k, string(v)) 121 memguard.WipeBytes(v) 122 } 123 } 124 125 return nil 126 }, 127 }, 128 { 129 Name: "get", 130 Usage: "retrieves value of given secret from given store", 131 Description: ` 132 The 'get' command requires passing in your configuration file 133 containing the secret-store definitions you want to access. To get a 134 list of available secret-store plugins, please have a look at 135 https://github.com/influxdata/telegraf/tree/master/plugins/secretstores. 136 and use the 'secrets list' command to get the IDs of available stores and 137 key(s) of available secrets. 138 139 For help on how to define secret-stores, check the documentation of the 140 different plugins. 141 142 Assuming you use the default configuration file location, you can run 143 the following command to retrieve a secret from a secret store 144 available stores 145 146 > telegraf secrets get mystore mysecretkey 147 148 This will fetch the secret with the key 'mysecretkey' from the secret-store 149 with the ID 'mystore'. 150 `, 151 ArgsUsage: "<secret-store ID> <secret key>", 152 Action: func(cCtx *cli.Context) error { 153 // Only load the secret-stores 154 filters := processFilterOnlySecretStoreFlags(cCtx) 155 g := GlobalFlags{ 156 config: cCtx.StringSlice("config"), 157 configDir: cCtx.StringSlice("config-directory"), 158 plugindDir: cCtx.String("plugin-directory"), 159 password: cCtx.String("password"), 160 debug: cCtx.Bool("debug"), 161 } 162 w := WindowFlags{} 163 m.Init(nil, filters, g, w) 164 165 args := cCtx.Args() 166 if !args.Present() || args.Len() != 2 { 167 return errors.New("invalid number of arguments") 168 } 169 170 storeID := args.First() 171 key := args.Get(1) 172 173 store, err := m.GetSecretStore(storeID) 174 if err != nil { 175 return fmt.Errorf("unable to get secret-store: %w", err) 176 } 177 value, err := store.Get(key) 178 if err != nil { 179 return fmt.Errorf("unable to get secret: %w", err) 180 } 181 fmt.Printf("%s:%s = %s\n", storeID, key, value) 182 183 return nil 184 }, 185 }, 186 { 187 Name: "set", 188 Usage: "create or modify a secret in the given store", 189 Description: ` 190 The 'set' command requires passing in your configuration file 191 containing the secret-store definitions you want to access. To get a 192 list of available secret-store plugins, please have a look at 193 https://github.com/influxdata/telegraf/tree/master/plugins/secretstores. 194 and use the 'secrets list' command to get the IDs of available stores and keys. 195 196 For help on how to define secret-stores, check the documentation of the 197 different plugins. 198 199 Assuming you use the default configuration file location, you can run 200 the following command to create a secret in anm available secret-store 201 202 > telegraf secrets set mystore mysecretkey mysecretvalue 203 204 This will create a secret with the key 'mysecretkey' in the secret-store 205 with the ID 'mystore' with the value being set to 'mysecretvalue'. If a 206 secret with that key ('mysecretkey') already existed in that store, its 207 value will be modified. 208 209 When you leave out the value of the secret like 210 211 > telegraf secrets set mystore mysecretkey 212 213 you will be prompted to enter the value of the secret. 214 `, 215 ArgsUsage: "<secret-store ID> <secret key>", 216 Action: func(cCtx *cli.Context) error { 217 // Only load the secret-stores 218 filters := processFilterOnlySecretStoreFlags(cCtx) 219 g := GlobalFlags{ 220 config: cCtx.StringSlice("config"), 221 configDir: cCtx.StringSlice("config-directory"), 222 plugindDir: cCtx.String("plugin-directory"), 223 password: cCtx.String("password"), 224 debug: cCtx.Bool("debug"), 225 } 226 w := WindowFlags{} 227 m.Init(nil, filters, g, w) 228 229 args := cCtx.Args() 230 if !args.Present() || args.Len() < 2 { 231 return errors.New("invalid number of arguments") 232 } 233 234 storeID := args.First() 235 key := args.Get(1) 236 value := args.Get(2) 237 if value == "" { 238 fmt.Printf("Enter secret value: ") 239 b, err := term.ReadPassword(int(os.Stdin.Fd())) 240 if err != nil { 241 return err 242 } 243 fmt.Println() 244 value = string(b) 245 } 246 247 store, err := m.GetSecretStore(storeID) 248 if err != nil { 249 return fmt.Errorf("unable to get secret-store: %w", err) 250 } 251 if err := store.Set(key, value); err != nil { 252 return fmt.Errorf("unable to set secret: %w", err) 253 } 254 255 return nil 256 }, 257 }, 258 }, 259 }, 260 } 261 }