1package command 2 3import ( 4 "fmt" 5 "io" 6 "os" 7 "strings" 8 9 "github.com/mitchellh/cli" 10 "github.com/posener/complete" 11) 12 13var ( 14 _ cli.Command = (*DeleteCommand)(nil) 15 _ cli.CommandAutocomplete = (*DeleteCommand)(nil) 16) 17 18type DeleteCommand struct { 19 *BaseCommand 20 21 testStdin io.Reader // for tests 22} 23 24func (c *DeleteCommand) Synopsis() string { 25 return "Delete secrets and configuration" 26} 27 28func (c *DeleteCommand) Help() string { 29 helpText := ` 30Usage: vault delete [options] PATH 31 32 Deletes secrets and configuration from Vault at the given path. The behavior 33 of "delete" is delegated to the backend corresponding to the given path. 34 35 Remove data in the status secret backend: 36 37 $ vault delete secret/my-secret 38 39 Uninstall an encryption key in the transit backend: 40 41 $ vault delete transit/keys/my-key 42 43 Delete an IAM role: 44 45 $ vault delete aws/roles/ops 46 47 For a full list of examples and paths, please see the documentation that 48 corresponds to the secret backend in use. 49 50` + c.Flags().Help() 51 52 return strings.TrimSpace(helpText) 53} 54 55func (c *DeleteCommand) Flags() *FlagSets { 56 return c.flagSet(FlagSetHTTP | FlagSetOutputField | FlagSetOutputFormat) 57} 58 59func (c *DeleteCommand) AutocompleteArgs() complete.Predictor { 60 return c.PredictVaultFiles() 61} 62 63func (c *DeleteCommand) AutocompleteFlags() complete.Flags { 64 return c.Flags().Completions() 65} 66 67func (c *DeleteCommand) Run(args []string) int { 68 f := c.Flags() 69 70 if err := f.Parse(args); err != nil { 71 c.UI.Error(err.Error()) 72 return 1 73 } 74 75 args = f.Args() 76 switch { 77 case len(args) < 1: 78 c.UI.Error(fmt.Sprintf("Not enough arguments (expected at least 1, got %d)", len(args))) 79 return 1 80 } 81 82 client, err := c.Client() 83 if err != nil { 84 c.UI.Error(err.Error()) 85 return 2 86 } 87 88 // Pull our fake stdin if needed 89 stdin := (io.Reader)(os.Stdin) 90 if c.testStdin != nil { 91 stdin = c.testStdin 92 } 93 94 path := sanitizePath(args[0]) 95 96 data, err := parseArgsDataStringLists(stdin, args[1:]) 97 if err != nil { 98 c.UI.Error(fmt.Sprintf("Failed to parse string list data: %s", err)) 99 return 1 100 } 101 102 secret, err := client.Logical().DeleteWithData(path, data) 103 if err != nil { 104 c.UI.Error(fmt.Sprintf("Error deleting %s: %s", path, err)) 105 if secret != nil { 106 OutputSecret(c.UI, secret) 107 } 108 return 2 109 } 110 111 if secret == nil { 112 // Don't output anything unless using the "table" format 113 if Format(c.UI) == "table" { 114 c.UI.Info(fmt.Sprintf("Success! Data deleted (if it existed) at: %s", path)) 115 } 116 return 0 117 } 118 119 // Handle single field output 120 if c.flagField != "" { 121 return PrintRawField(c.UI, secret, c.flagField) 122 } 123 124 return OutputSecret(c.UI, secret) 125} 126