github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/volume_delete.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/hashicorp/nomad/api" 8 "github.com/hashicorp/nomad/api/contexts" 9 flaghelper "github.com/hashicorp/nomad/helper/flags" 10 "github.com/posener/complete" 11 ) 12 13 type VolumeDeleteCommand struct { 14 Meta 15 Secrets string 16 } 17 18 func (c *VolumeDeleteCommand) Help() string { 19 helpText := ` 20 Usage: nomad volume delete [options] <vol id> 21 22 Delete a volume from an external storage provider. The volume must still be 23 registered with Nomad in order to be deleted. Deleting will fail if the 24 volume is still in use by an allocation or in the process of being 25 unpublished. If the volume no longer exists, this command will silently 26 return without an error. 27 28 When ACLs are enabled, this command requires a token with the 29 'csi-write-volume' and 'csi-read-volume' capabilities for the volume's 30 namespace. 31 32 General Options: 33 34 ` + generalOptionsUsage(usageOptsDefault) + ` 35 36 Delete Options: 37 38 -secret 39 Secrets to pass to the plugin to delete the snapshot. Accepts multiple 40 flags in the form -secret key=value 41 ` 42 return strings.TrimSpace(helpText) 43 } 44 45 func (c *VolumeDeleteCommand) AutocompleteFlags() complete.Flags { 46 return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), 47 complete.Flags{}) 48 } 49 50 func (c *VolumeDeleteCommand) AutocompleteArgs() complete.Predictor { 51 return complete.PredictFunc(func(a complete.Args) []string { 52 client, err := c.Meta.Client() 53 if err != nil { 54 return nil 55 } 56 57 resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Volumes, nil) 58 if err != nil { 59 return []string{} 60 } 61 matches := resp.Matches[contexts.Volumes] 62 63 resp, _, err = client.Search().PrefixSearch(a.Last, contexts.Nodes, nil) 64 if err != nil { 65 return []string{} 66 } 67 matches = append(matches, resp.Matches[contexts.Nodes]...) 68 return matches 69 }) 70 } 71 72 func (c *VolumeDeleteCommand) Synopsis() string { 73 return "Delete a volume" 74 } 75 76 func (c *VolumeDeleteCommand) Name() string { return "volume delete" } 77 78 func (c *VolumeDeleteCommand) Run(args []string) int { 79 var secretsArgs flaghelper.StringFlag 80 flags := c.Meta.FlagSet(c.Name(), FlagSetClient) 81 flags.Usage = func() { c.Ui.Output(c.Help()) } 82 flags.Var(&secretsArgs, "secret", "secrets for snapshot, ex. -secret key=value") 83 84 if err := flags.Parse(args); err != nil { 85 c.Ui.Error(fmt.Sprintf("Error parsing arguments %s", err)) 86 return 1 87 } 88 89 // Check that we get exactly two arguments 90 args = flags.Args() 91 if l := len(args); l < 1 { 92 c.Ui.Error("This command takes at least one argument: <vol id>") 93 c.Ui.Error(commandErrorText(c)) 94 return 1 95 } 96 volID := args[0] 97 98 // Get the HTTP client 99 client, err := c.Meta.Client() 100 if err != nil { 101 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 102 return 1 103 } 104 105 secrets := api.CSISecrets{} 106 for _, kv := range secretsArgs { 107 s := strings.Split(kv, "=") 108 if len(s) == 2 { 109 secrets[s[0]] = s[1] 110 } else { 111 c.Ui.Error("Secret must be in the format: -secret key=value") 112 return 1 113 } 114 } 115 116 err = client.CSIVolumes().DeleteOpts(&api.CSIVolumeDeleteRequest{ 117 ExternalVolumeID: volID, 118 Secrets: secrets, 119 }, nil) 120 if err != nil { 121 c.Ui.Error(fmt.Sprintf("Error deleting volume: %s", err)) 122 return 1 123 } 124 125 c.Ui.Output(fmt.Sprintf("Successfully deleted volume %q!", volID)) 126 return 0 127 }