From 2f79a260fe2a86312c3624167ed5e59409913ee1 Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Fri, 11 Feb 2022 08:53:03 -0500 Subject: [PATCH] csi: volume cli prefix matching should accept exact match (#12051) 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 000000000..9ea9d0592 --- /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 512f8426b..5dc067d50 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 b88047ad9..2de8e1d97 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 9b17e6cda..bce7379cc 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