diff --git a/api/csi.go b/api/csi.go index 836d37d04e42..120c239fde8f 100644 --- a/api/csi.go +++ b/api/csi.go @@ -137,7 +137,7 @@ func (v *CSIVolumes) DeleteSnapshot(snap *CSISnapshot, w *WriteOptions) error { } // ListSnapshots lists external storage volume snapshots. -func (v *CSIVolumes) ListSnapshots(pluginID string, q *QueryOptions) (*CSISnapshotListResponse, *QueryMeta, error) { +func (v *CSIVolumes) ListSnapshots(pluginID string, secrets string, q *QueryOptions) (*CSISnapshotListResponse, *QueryMeta, error) { var resp *CSISnapshotListResponse qp := url.Values{} @@ -150,6 +150,9 @@ func (v *CSIVolumes) ListSnapshots(pluginID string, q *QueryOptions) (*CSISnapsh if q.PerPage != 0 { qp.Set("per_page", fmt.Sprint(q.PerPage)) } + if secrets != "" { + qp.Set("secrets", secrets) + } qm, err := v.client.query("/v1/volumes/snapshot?"+qp.Encode(), &resp, q) if err != nil { @@ -406,6 +409,7 @@ type CSISnapshotCreateResponse struct { // fields type CSISnapshotListRequest struct { PluginID string + Secrets CSISecrets QueryOptions } diff --git a/client/csi_endpoint.go b/client/csi_endpoint.go index 029c91ede62a..bd75bd529c98 100644 --- a/client/csi_endpoint.go +++ b/client/csi_endpoint.go @@ -402,6 +402,7 @@ func (c *CSI) ControllerListSnapshots(req *structs.ClientCSIControllerListSnapsh defer plugin.Close() csiReq := req.ToCSIRequest() + fmt.Println("CSI REQ", *csiReq) ctx, cancelFn := c.requestContext() defer cancelFn() diff --git a/client/structs/csi.go b/client/structs/csi.go index d4846f7e95cc..ca7f88d41deb 100644 --- a/client/structs/csi.go +++ b/client/structs/csi.go @@ -362,6 +362,7 @@ type ClientCSIControllerListSnapshotsRequest struct { // not Nomad's own fields, for clarity when mapping between the two RPCs MaxEntries int32 StartingToken string + Secrets structs.CSISecrets CSIControllerQuery } @@ -370,6 +371,7 @@ func (req *ClientCSIControllerListSnapshotsRequest) ToCSIRequest() *csi.Controll return &csi.ControllerListSnapshotsRequest{ MaxEntries: req.MaxEntries, StartingToken: req.StartingToken, + Secrets: req.Secrets, } } diff --git a/command/agent/csi_endpoint.go b/command/agent/csi_endpoint.go index 9184bfe0794e..30290612900b 100644 --- a/command/agent/csi_endpoint.go +++ b/command/agent/csi_endpoint.go @@ -1,6 +1,7 @@ package agent import ( + "fmt" "net/http" "strconv" "strings" @@ -333,6 +334,15 @@ func (s *HTTPServer) csiSnapshotList(resp http.ResponseWriter, req *http.Request query := req.URL.Query() args.PluginID = query.Get("plugin_id") + secrets := query["secrets"] + args.Secrets = make(structs.CSISecrets) + for _, raw := range secrets { + fmt.Println("**RAW SEC", raw) + secret := strings.Split(raw, "=") + if len(secret) == 2 { + args.Secrets[secret[0]] = secret[1] + } + } var out structs.CSISnapshotListResponse if err := s.agent.RPC("CSIVolume.ListSnapshots", &args, &out); err != nil { diff --git a/command/volume_snapshot_list.go b/command/volume_snapshot_list.go index 65ea484ca279..b88bdd838adb 100644 --- a/command/volume_snapshot_list.go +++ b/command/volume_snapshot_list.go @@ -35,6 +35,7 @@ List Options: -plugin: Display only snapshots managed by a particular plugin. By default this command will query all plugins for their snapshots. + -secrets: A set of key/value secrets to be used when listing snapshots. ` return strings.TrimSpace(helpText) } @@ -68,11 +69,13 @@ func (c *VolumeSnapshotListCommand) Name() string { return "volume snapshot list func (c *VolumeSnapshotListCommand) Run(args []string) int { var pluginID string var verbose bool + var secrets string flags := c.Meta.FlagSet(c.Name(), FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.StringVar(&pluginID, "plugin", "", "") flags.BoolVar(&verbose, "verbose", false, "") + flags.StringVar(&secrets, "secrets", "", "") if err := flags.Parse(args); err != nil { c.Ui.Error(fmt.Sprintf("Error parsing arguments %s", err)) @@ -121,7 +124,7 @@ func (c *VolumeSnapshotListCommand) Run(args []string) int { q := &api.QueryOptions{PerPage: 30} // TODO: tune page size for { - resp, _, err := client.CSIVolumes().ListSnapshots(pluginID, q) + resp, _, err := client.CSIVolumes().ListSnapshots(pluginID, secrets, q) if err != nil && !errors.Is(err, io.EOF) { c.Ui.Error(fmt.Sprintf( "Error querying CSI external snapshots for plugin %q: %s", pluginID, err)) diff --git a/nomad/structs/csi.go b/nomad/structs/csi.go index 1c7845c0a61e..e0f35aeaca36 100644 --- a/nomad/structs/csi.go +++ b/nomad/structs/csi.go @@ -897,6 +897,7 @@ type CSISnapshotDeleteResponse struct { // fields type CSISnapshotListRequest struct { PluginID string + Secrets CSISecrets QueryOptions } diff --git a/plugins/csi/plugin.go b/plugins/csi/plugin.go index 7019127c54e7..6c85db7a8e09 100644 --- a/plugins/csi/plugin.go +++ b/plugins/csi/plugin.go @@ -756,12 +756,14 @@ func (r *ControllerDeleteSnapshotRequest) Validate() error { type ControllerListSnapshotsRequest struct { MaxEntries int32 StartingToken string + Secrets structs.CSISecrets } func (r *ControllerListSnapshotsRequest) ToCSIRepresentation() *csipbv1.ListSnapshotsRequest { return &csipbv1.ListSnapshotsRequest{ MaxEntries: r.MaxEntries, StartingToken: r.StartingToken, + Secrets: r.Secrets, } } diff --git a/vendor/github.com/hashicorp/nomad/api/csi.go b/vendor/github.com/hashicorp/nomad/api/csi.go index 836d37d04e42..120c239fde8f 100644 --- a/vendor/github.com/hashicorp/nomad/api/csi.go +++ b/vendor/github.com/hashicorp/nomad/api/csi.go @@ -137,7 +137,7 @@ func (v *CSIVolumes) DeleteSnapshot(snap *CSISnapshot, w *WriteOptions) error { } // ListSnapshots lists external storage volume snapshots. -func (v *CSIVolumes) ListSnapshots(pluginID string, q *QueryOptions) (*CSISnapshotListResponse, *QueryMeta, error) { +func (v *CSIVolumes) ListSnapshots(pluginID string, secrets string, q *QueryOptions) (*CSISnapshotListResponse, *QueryMeta, error) { var resp *CSISnapshotListResponse qp := url.Values{} @@ -150,6 +150,9 @@ func (v *CSIVolumes) ListSnapshots(pluginID string, q *QueryOptions) (*CSISnapsh if q.PerPage != 0 { qp.Set("per_page", fmt.Sprint(q.PerPage)) } + if secrets != "" { + qp.Set("secrets", secrets) + } qm, err := v.client.query("/v1/volumes/snapshot?"+qp.Encode(), &resp, q) if err != nil { @@ -406,6 +409,7 @@ type CSISnapshotCreateResponse struct { // fields type CSISnapshotListRequest struct { PluginID string + Secrets CSISecrets QueryOptions }