Repository: hashicorp/nomad
File: api/csi.go (Go)

Code before:
		return nil, nil, err
	}

	sort.Sort(CSIVolumeExternalStubSort(resp.Volumes))
	return resp, qm, nil
}

// PluginList returns all CSI volumes for the specified plugin id
func (v *CSIVolumes) PluginList(pluginID string) ([]*CSIVolumeListStub, *QueryMeta, error) {
	return v.List(&QueryOptions{Prefix: pluginID})
}

// Info is used to retrieve a single CSIVolume
func (v *CSIVolumes) Info(id string, q *QueryOptions) (*CSIVolume, *QueryMeta, error) {
	var resp CSIVolume
	qm, err := v.client.query("/v1/volume/csi/"+id, &resp, q)
	if err != nil {
		return nil, nil, err
	}

	return &resp, qm, nil
}

// Register registers a single CSIVolume with Nomad. The volume must already
// exist in the external storage provider.
func (v *CSIVolumes) Register(vol *CSIVolume, w *WriteOptions, override bool) (*WriteMeta, string, error) {
	req := CSIVolumeRegisterRequest{
		Volumes:        []*CSIVolume{vol},
		PolicyOverride: override,
	}
	resp := &CSIVolumeRegisterResponse{}
	meta, err := v.client.put("/v1/volume/csi/"+vol.ID, req, resp, w)
	return meta, resp.Warnings, err
}

// Deregister deregisters a single CSIVolume from Nomad. The volume will not be deleted from the external storage provider.
func (v *CSIVolumes) Deregister(id string, force bool, w *WriteOptions) error {
	_, err := v.client.delete(fmt.Sprintf("/v1/volume/csi/%v?force=%t", url.PathEscape(id), force), nil, nil, w)
	return err
}

// Create creates a single CSIVolume in an external storage provider and
// registers it with Nomad. You do not need to call Register if this call is
// successful.
func (v *CSIVolumes) Create(vol *CSIVolume, override bool, w *WriteOptions) (*CSIVolumeCreateResponse, *WriteMeta, error) {
	req := CSIVolumeCreateRequest{
		Volumes:        []*CSIVolume{vol},
		PolicyOverride: override,
	}

	resp := &CSIVolumeCreateResponse{}

Review comment (suggestion):
This `api` package is the public Go API for Nomad, and this is a breaking change in the signature. It took us an unfortunately long time to learn that every API ends up needing extra options and not just the object ( :facepalm: ) so we have a bunch of alternate versions of functions that include a richer options object. At some point we want to do a `/v2` API that fixes all these rough edges but in the meantime we don't want to break third party tools or the Terraform provider.

So we'll want a new method like `func (v *CSIVolumes) RegisterOpts(reg *CSIVolumeRegisterRequest, w *WriteOptions) (*CSIVolumeRegisterResponse, *WriteMeta, error)` and then the existing `Register` method will wrap that. (_edited_)

Code after:
		return nil, nil, err
	}

	sort.Sort(CSIVolumeExternalStubSort(resp.Volumes))
	return resp, qm, nil
}

// PluginList returns all CSI volumes for the specified plugin id
func (v *CSIVolumes) PluginList(pluginID string) ([]*CSIVolumeListStub, *QueryMeta, error) {
	return v.List(&QueryOptions{Prefix: pluginID})
}

// Info is used to retrieve a single CSIVolume
func (v *CSIVolumes) Info(id string, q *QueryOptions) (*CSIVolume, *QueryMeta, error) {
	var resp CSIVolume
	qm, err := v.client.query("/v1/volume/csi/"+id, &resp, q)
	if err != nil {
		return nil, nil, err
	}

	return &resp, qm, nil
}

// Register registers a single CSIVolume with Nomad. The volume must already
// exist in the external storage provider.
func (v *CSIVolumes) Register(vol *CSIVolume, w *WriteOptions) (*WriteMeta, error) {
	req := &CSIVolumeRegisterRequest{
		Volumes: []*CSIVolume{vol},
	}
	_, meta, err := v.RegisterOpts(req, w)
	return meta, err
}

// RegisterOpts registers a single CSIVolume with Nomad. The volume must already
// exist in the external storage provider. It expects a single volume in the
// request.
func (v *CSIVolumes) RegisterOpts(req *CSIVolumeRegisterRequest, w *WriteOptions) (*CSIVolumeRegisterResponse, *WriteMeta, error) {
	if w == nil {
		w = &WriteOptions{}
	}
	vol := req.Volumes[0]
	resp := &CSIVolumeRegisterResponse{}
	meta, err := v.client.put("/v1/volume/csi/"+vol.ID, req, resp, w)

	return resp, meta, err
}

// Deregister deregisters a single CSIVolume from Nomad. The volume will not be deleted from the external storage provider.
func (v *CSIVolumes) Deregister(id string, force bool, w *WriteOptions) error {
	_, err := v.client.delete(fmt.Sprintf("/v1/volume/csi/%v?force=%t", url.PathEscape(id), force), nil, nil, w)
	return err