From 1c5597a8c6e4ffb68e20155a76eb38f597cb8f32 Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Thu, 10 Feb 2022 16:34:32 -0500 Subject: [PATCH] csi: volume cli prefix matching should accept exact match The `volume detach`, `volume deregister`, and `volume status` commands accept a prefix argument for the volume ID. Update the behavior on exact matches so that if there is more than one volume that matches the prefix, we should only return an error if one of the volume IDs is not an exact match. Otherwise we won't be able to use these commands at all on those volumes. This also makes the behavior of these commands consistent with `job stop`. --- .changelog/12051.txt | 3 +++ command/volume_deregister.go | 22 ++++++++++++---------- command/volume_detach.go | 22 ++++++++++++---------- command/volume_status_csi.go | 20 +++++++++++--------- 4 files changed, 38 insertions(+), 29 deletions(-) create mode 100644 .changelog/12051.txt diff --git a/.changelog/12051.txt b/.changelog/12051.txt new file mode 100644 index 0000000000..9ea9d05920 --- /dev/null +++ b/.changelog/12051.txt @@ -0,0 +1,3 @@ +```release-note:bug +csi: fixed a bug where `volume detach`, `volume deregister`, and `volume status` commands did not accept an exact ID if multiple volumes matched the prefix +``` diff --git a/command/volume_deregister.go b/command/volume_deregister.go index 512f8426b6..5dc067d50d 100644 --- a/command/volume_deregister.go +++ b/command/volume_deregister.go @@ -99,20 +99,22 @@ func (c *VolumeDeregisterCommand) Run(args []string) int { c.Ui.Error(fmt.Sprintf("Error querying volumes: %s", err)) return 1 } - if len(vols) > 1 { - sort.Slice(vols, func(i, j int) bool { return vols[i].ID < vols[j].ID }) - out, err := csiFormatSortedVolumes(vols, fullId) - if err != nil { - c.Ui.Error(fmt.Sprintf("Error formatting: %s", err)) - return 1 - } - c.Ui.Error(fmt.Sprintf("Prefix matched multiple volumes\n\n%s", out)) - return 1 - } if len(vols) == 0 { c.Ui.Error(fmt.Sprintf("No volumes(s) with prefix or ID %q found", volID)) return 1 } + if len(vols) > 1 { + if (volID != vols[0].ID) || (c.allNamespaces() && vols[0].ID == vols[1].ID) { + sort.Slice(vols, func(i, j int) bool { return vols[i].ID < vols[j].ID }) + out, err := csiFormatSortedVolumes(vols, fullId) + if err != nil { + c.Ui.Error(fmt.Sprintf("Error formatting: %s", err)) + return 1 + } + c.Ui.Error(fmt.Sprintf("Prefix matched multiple volumes\n\n%s", out)) + return 1 + } + } volID = vols[0].ID // Confirm the -force flag diff --git a/command/volume_detach.go b/command/volume_detach.go index b88047ad9e..2de8e1d970 100644 --- a/command/volume_detach.go +++ b/command/volume_detach.go @@ -121,20 +121,22 @@ func (c *VolumeDetachCommand) Run(args []string) int { c.Ui.Error(fmt.Sprintf("Error querying volumes: %s", err)) return 1 } - if len(vols) > 1 { - sort.Slice(vols, func(i, j int) bool { return vols[i].ID < vols[j].ID }) - out, err := csiFormatSortedVolumes(vols, fullId) - if err != nil { - c.Ui.Error(fmt.Sprintf("Error formatting: %s", err)) - return 1 - } - c.Ui.Error(fmt.Sprintf("Prefix matched multiple volumes\n\n%s", out)) - return 1 - } if len(vols) == 0 { c.Ui.Error(fmt.Sprintf("No volumes(s) with prefix or ID %q found", volID)) return 1 } + if len(vols) > 1 { + if (volID != vols[0].ID) || (c.allNamespaces() && vols[0].ID == vols[1].ID) { + sort.Slice(vols, func(i, j int) bool { return vols[i].ID < vols[j].ID }) + out, err := csiFormatSortedVolumes(vols, fullId) + if err != nil { + c.Ui.Error(fmt.Sprintf("Error formatting: %s", err)) + return 1 + } + c.Ui.Error(fmt.Sprintf("Prefix matched multiple volumes\n\n%s", out)) + return 1 + } + } volID = vols[0].ID vol, _, err := client.CSIVolumes().Info(volID, nil) diff --git a/command/volume_status_csi.go b/command/volume_status_csi.go index 9b17e6cda4..bce7379cc2 100644 --- a/command/volume_status_csi.go +++ b/command/volume_status_csi.go @@ -29,19 +29,21 @@ func (c *VolumeStatusCommand) csiStatus(client *api.Client, id string) int { c.Ui.Error(fmt.Sprintf("Error querying volumes: %s", err)) return 1 } - if len(vols) > 1 { - out, err := c.csiFormatVolumes(vols) - if err != nil { - c.Ui.Error(fmt.Sprintf("Error formatting: %s", err)) - return 1 - } - c.Ui.Error(fmt.Sprintf("Prefix matched multiple volumes\n\n%s", out)) - return 1 - } if len(vols) == 0 { c.Ui.Error(fmt.Sprintf("No volumes(s) with prefix or ID %q found", id)) return 1 } + if len(vols) > 1 { + if (id != vols[0].ID) || (c.allNamespaces() && vols[0].ID == vols[1].ID) { + out, err := c.csiFormatVolumes(vols) + if err != nil { + c.Ui.Error(fmt.Sprintf("Error formatting: %s", err)) + return 1 + } + c.Ui.Error(fmt.Sprintf("Prefix matched multiple volumes\n\n%s", out)) + return 1 + } + } id = vols[0].ID // Try querying the volume