Skip to content

Commit

Permalink
CSI: Add secrets flag support for delete volume
Browse files Browse the repository at this point in the history
Signed-off-by: Grant Griffiths <ggriffiths@purestorage.com>
  • Loading branch information
Grant Griffiths committed Sep 30, 2021
1 parent d486e1d commit f1b1783
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .changelog/11245.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
csi: add flag for providing secrets as a set of key/value pairs to delete a volume
```
9 changes: 7 additions & 2 deletions api/csi.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,13 @@ func (v *CSIVolumes) Create(vol *CSIVolume, w *WriteOptions) ([]*CSIVolume, *Wri
// Delete deletes a CSI volume from an external storage provider. The ID
// passed as an argument here is for the storage provider's ID, so a volume
// that's already been deregistered can be deleted.
func (v *CSIVolumes) Delete(externalVolID string, w *WriteOptions) error {
_, err := v.client.delete(fmt.Sprintf("/v1/volume/csi/%v/delete", url.PathEscape(externalVolID)), nil, w)
func (v *CSIVolumes) Delete(externalVolID string, secrets string, w *WriteOptions) error {
qp := url.Values{}
if secrets != "" {
qp.Set("secrets", secrets)
}

_, err := v.client.delete(fmt.Sprintf("/v1/volume/csi/%v/delete?%s", url.PathEscape(externalVolID), qp.Encode()), nil, w)
return err
}

Expand Down
35 changes: 21 additions & 14 deletions command/agent/csi_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,10 @@ func (s *HTTPServer) csiVolumeDelete(id string, resp http.ResponseWriter, req *h
return nil, CodedError(405, ErrInvalidMethod)
}

query := req.URL.Query()
args := structs.CSIVolumeDeleteRequest{
VolumeIDs: []string{id},
Secrets: parseSecretsParam(query["secrets"]),
}
s.parseWriteRequest(req, &args.WriteRequest)

Expand Down Expand Up @@ -333,20 +335,7 @@ func (s *HTTPServer) csiSnapshotList(resp http.ResponseWriter, req *http.Request

query := req.URL.Query()
args.PluginID = query.Get("plugin_id")
querySecrets := query["secrets"]

// Parse comma separated secrets only when provided
if len(querySecrets) >= 1 {
secrets := strings.Split(querySecrets[0], ",")
args.Secrets = make(structs.CSISecrets)
for _, raw := range secrets {
secret := strings.Split(raw, "=")
if len(secret) == 2 {
args.Secrets[secret[0]] = secret[1]
}
}
}

args.Secrets = parseSecretsParam(query["secrets"])
var out structs.CSISnapshotListResponse
if err := s.agent.RPC("CSIVolume.ListSnapshots", &args, &out); err != nil {
return nil, err
Expand Down Expand Up @@ -763,3 +752,21 @@ func structsCSISecretsToApi(secrets structs.CSISecrets) api.CSISecrets {
}
return out
}

// parseSecretsParam parses a comma separated list of secrets
func parseSecretsParam(querySecrets []string) structs.CSISecrets {
csiSecrets := make(structs.CSISecrets)

// Parse comma separated secrets only when provided
if len(querySecrets) >= 1 {
secrets := strings.Split(querySecrets[0], ",")
for _, raw := range secrets {
secret := strings.Split(raw, "=")
if len(secret) == 2 {
csiSecrets[secret[0]] = secret[1]
}
}
}

return csiSecrets
}
11 changes: 8 additions & 3 deletions command/volume_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ General Options:
` + generalOptionsUsage(usageOptsDefault) + `
Delete Options:
-secrets: A set of key/value secrets to be used when deleting a volume.
`
return strings.TrimSpace(helpText)
}
Expand Down Expand Up @@ -70,6 +73,8 @@ func (c *VolumeDeleteCommand) Name() string { return "volume delete" }
func (c *VolumeDeleteCommand) Run(args []string) int {
flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
var secrets string
flags.StringVar(&secrets, "secrets", "", "")

if err := flags.Parse(args); err != nil {
c.Ui.Error(fmt.Sprintf("Error parsing arguments %s", err))
Expand All @@ -78,8 +83,8 @@ func (c *VolumeDeleteCommand) Run(args []string) int {

// Check that we get exactly two arguments
args = flags.Args()
if l := len(args); l != 1 {
c.Ui.Error("This command takes one argument: <vol id>")
if l := len(args); l < 1 {
c.Ui.Error("This command takes at least one argument: <vol id>")
c.Ui.Error(commandErrorText(c))
return 1
}
Expand All @@ -92,7 +97,7 @@ func (c *VolumeDeleteCommand) Run(args []string) int {
return 1
}

err = client.CSIVolumes().Delete(volID, nil)
err = client.CSIVolumes().Delete(volID, secrets, nil)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error deleting volume: %s", err))
return 1
Expand Down
14 changes: 11 additions & 3 deletions nomad/csi_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ func (v *CSIVolume) Delete(args *structs.CSIVolumeDeleteRequest, reply *structs.
// NOTE: deleting the volume in the external storage provider can't be
// made atomic with deregistration. We can't delete a volume that's
// not registered because we need to be able to lookup its plugin.
err = v.deleteVolume(vol, plugin)
err = v.deleteVolume(vol, plugin, args.Secrets)
if err != nil {
return err
}
Expand All @@ -993,12 +993,20 @@ func (v *CSIVolume) Delete(args *structs.CSIVolumeDeleteRequest, reply *structs.
return nil
}

func (v *CSIVolume) deleteVolume(vol *structs.CSIVolume, plugin *structs.CSIPlugin) error {
func (v *CSIVolume) deleteVolume(vol *structs.CSIVolume, plugin *structs.CSIPlugin, querySecrets structs.CSISecrets) error {
// Combine volume and query secrets into one map.
// Query secrets override any secrets stored with the volume.
combinedSecrets := vol.Secrets
if querySecrets != nil {
for k, v := range querySecrets {
combinedSecrets[k] = v
}
}

method := "ClientCSI.ControllerDeleteVolume"
cReq := &cstructs.ClientCSIControllerDeleteVolumeRequest{
ExternalVolumeID: vol.ExternalID,
Secrets: vol.Secrets,
Secrets: combinedSecrets,
}
cReq.PluginID = plugin.ID
cResp := &cstructs.ClientCSIControllerDeleteVolumeResponse{}
Expand Down
3 changes: 3 additions & 0 deletions nomad/csi_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,9 @@ func TestCSIVolumeEndpoint_Delete(t *testing.T) {
Region: "global",
Namespace: ns,
},
Secrets: structs.CSISecrets{
"secret-key-1": "secret-val-1",
},
}
resp1 := &structs.CSIVolumeCreateResponse{}
err = msgpackrpc.CallWithCodec(codec, "CSIVolume.Delete", req1, resp1)
Expand Down
1 change: 1 addition & 0 deletions nomad/structs/csi.go
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ type CSIVolumeCreateResponse struct {

type CSIVolumeDeleteRequest struct {
VolumeIDs []string
Secrets CSISecrets
WriteRequest
}

Expand Down
6 changes: 4 additions & 2 deletions website/content/api-docs/volumes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -459,14 +459,16 @@ The table below shows this endpoint's support for
- `:volume_id` `(string: <required>)` - Specifies the ID of the
volume. This must be the full ID. This is specified as part of the
path.

- `secrets` `(string: "")` - Specifies a list of key/value secrets for deleting a volume.
These key/value pairs are comma-separated and are passed directly to the CSI plugin.

### Sample Request

```shell-session
$ curl \
--request DELETE \
https://localhost:4646/v1/volume/csi/volume-id1/delete
https://localhost:4646/v1/volume/csi/volume-id1/delete? \
secrets=secret-key-1=secret-value-1,secret-key-2=secret-value-2
```


Expand Down
7 changes: 6 additions & 1 deletion website/content/docs/commands/volume/delete.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ deleted.
## Usage

```plaintext
nomad volume delete [options] [volume]
nomad volume delete [options] [volume] [-secrets key=value,key2=value2]
```

The `volume delete` command requires a single argument, specifying the ID of
Expand All @@ -36,3 +36,8 @@ When ACLs are enabled, this command requires a token with the
[csi_plugins_internals]: /docs/internals/plugins/csi#csi-plugins
[deregistered]: /docs/commands/volume/deregister
[registered]: /docs/commands/volume/register

## Delete Options

- `-secrets`: A list of comma separated secret key/value pairs to be passed
to the CSI driver.

0 comments on commit f1b1783

Please sign in to comment.