From 04d6db02205f6901183e4cfa0b64a2eebb50c140 Mon Sep 17 00:00:00 2001 From: akutz Date: Tue, 1 Nov 2016 17:41:10 -0500 Subject: [PATCH] Attachments Bitmask & Updated Docs This patch updates the "attachments" parameter used when retrieving volumes from a boolean flag to a more discreet bitmask. This patch also includes updated APIB documentation. --- api/client/client_api_funcs.go | 6 +- api/server/router/volume/volume_routes.go | 35 +- api/types/types_clients.go | 6 +- api/types/types_drivers_client.go | 4 +- api/types/types_drivers_storage.go | 131 +++- api/types/types_drivers_storage_test.go | 85 +++ api/types/types_store.go | 8 + api/utils/utils_store.go | 9 + c/libstor-c/libstor-c_exported.go | 3 +- drivers/integration/docker/docker.go | 12 +- drivers/integration/docker/docker_utils.go | 18 +- drivers/storage/ebs/storage/ebs_storage.go | 18 +- drivers/storage/ebs/tests/ebs_test.go | 16 +- drivers/storage/efs/storage/efs_storage.go | 8 +- drivers/storage/efs/tests/efs_test.go | 10 +- .../storage/isilon/storage/isilon_storage.go | 25 +- drivers/storage/isilon/tests/isilon_test.go | 13 +- .../libstorage/libstorage_client_api.go | 6 +- .../rackspace/storage/rackspace_storage.go | 29 +- .../storage/rackspace/tests/rackspace_test.go | 15 +- .../scaleio/storage/scaleio_storage.go | 29 +- drivers/storage/scaleio/tests/scaleio_test.go | 15 +- drivers/storage/vbox/storage/vbox_storage.go | 15 +- drivers/storage/vbox/tests/vbox_test.go | 15 +- drivers/storage/vfs/client/vfs_client.go | 3 +- drivers/storage/vfs/tests/vfs_test.go | 33 +- libstorage.apib | 565 +++++++++++------- 27 files changed, 769 insertions(+), 363 deletions(-) create mode 100644 api/types/types_drivers_storage_test.go diff --git a/api/client/client_api_funcs.go b/api/client/client_api_funcs.go index 403a1f89..4e3ed795 100644 --- a/api/client/client_api_funcs.go +++ b/api/client/client_api_funcs.go @@ -84,7 +84,7 @@ func (c *client) ServiceInspect( func (c *client) Volumes( ctx types.Context, - attachments bool) (types.ServiceVolumeMap, error) { + attachments types.VolumeAttachmentsTypes) (types.ServiceVolumeMap, error) { reply := types.ServiceVolumeMap{} url := fmt.Sprintf("/volumes?attachments=%v", attachments) @@ -97,7 +97,7 @@ func (c *client) Volumes( func (c *client) VolumesByService( ctx types.Context, service string, - attachments bool) (types.VolumeMap, error) { + attachments types.VolumeAttachmentsTypes) (types.VolumeMap, error) { reply := types.VolumeMap{} url := fmt.Sprintf("/volumes/%s?attachments=%v", service, attachments) @@ -110,7 +110,7 @@ func (c *client) VolumesByService( func (c *client) VolumeInspect( ctx types.Context, service, volumeID string, - attachments bool) (*types.Volume, error) { + attachments types.VolumeAttachmentsTypes) (*types.Volume, error) { reply := types.Volume{} url := fmt.Sprintf( diff --git a/api/server/router/volume/volume_routes.go b/api/server/router/volume/volume_routes.go index ed071fe3..05da1446 100644 --- a/api/server/router/volume/volume_routes.go +++ b/api/server/router/volume/volume_routes.go @@ -34,7 +34,7 @@ func (r *router) volumes( tasks = map[string]*types.Task{} taskIDs []int opts = &types.VolumesOpts{ - Attachments: store.GetBool("attachments"), + Attachments: store.GetAttachments(), Opts: store, } reply = types.ServiceVolumeMap{} @@ -107,7 +107,7 @@ func (r *router) volumesForService( service := context.MustService(ctx) opts := &types.VolumesOpts{ - Attachments: store.GetBool("attachments"), + Attachments: store.GetAttachments(), Opts: store, } @@ -143,7 +143,7 @@ func getFilteredVolumes( ) iid, iidOK := context.InstanceID(ctx) - if opts.Attachments && !iidOK { + if opts.Attachments.RequiresInstanceID() && !iidOK { return nil, utils.NewMissingInstanceIDError(storSvc.Name()) } @@ -152,11 +152,6 @@ func getFilteredVolumes( return nil, err } - lcaseIID := "" - if iid != nil { - lcaseIID = strings.ToLower(iid.ID) - } - if filter != nil { filterOp = filter.Op filterLeft = strings.ToLower(filter.Left) @@ -166,22 +161,29 @@ func getFilteredVolumes( for _, obj := range objs { if filterOp == types.FilterEqualityMatch && filterLeft == "name" { - if strings.ToLower(obj.Name) != filterRight { + if !strings.EqualFold(obj.Name, filterRight) { continue } } - if opts.Attachments { + // if only the requesting instance's attachments are requested then + // filter the volume's attachments list + if opts.Attachments.Mine() { atts := []*types.VolumeAttachment{} for _, a := range obj.Attachments { - if lcaseIID == strings.ToLower(a.InstanceID.ID) { + if strings.EqualFold(iid.ID, a.InstanceID.ID) { atts = append(atts, a) } } obj.Attachments = atts - if len(obj.Attachments) == 0 { - continue - } + } + + if opts.Attachments.Attached() && len(obj.Attachments) == 0 { + continue + } + + if opts.Attachments.Unattached() && len(obj.Attachments) > 0 { + continue } if OnVolume != nil { @@ -207,10 +209,11 @@ func (r *router) volumeInspect( req *http.Request, store types.Store) error { - attachments := store.GetBool("attachments") + attachments := store.GetAttachments() service := context.MustService(ctx) - if _, ok := context.InstanceID(ctx); !ok && attachments { + if _, ok := context.InstanceID(ctx); !ok && + attachments.RequiresInstanceID() { return utils.NewMissingInstanceIDError(service.Name()) } diff --git a/api/types/types_clients.go b/api/types/types_clients.go index 9df3af4e..cca1943f 100644 --- a/api/types/types_clients.go +++ b/api/types/types_clients.go @@ -106,19 +106,19 @@ type APIClient interface { // Volumes returns a list of all Volumes for all Services. Volumes( ctx Context, - attachments bool) (ServiceVolumeMap, error) + attachments VolumeAttachmentsTypes) (ServiceVolumeMap, error) // VolumesByService returns a list of all Volumes for a service. VolumesByService( ctx Context, service string, - attachments bool) (VolumeMap, error) + attachments VolumeAttachmentsTypes) (VolumeMap, error) // VolumeInspect gets information about a single volume. VolumeInspect( ctx Context, service, volumeID string, - attachments bool) (*Volume, error) + attachments VolumeAttachmentsTypes) (*Volume, error) // VolumeCreate creates a single volume. VolumeCreate( diff --git a/api/types/types_drivers_client.go b/api/types/types_drivers_client.go index 2c19cc63..7b6eaf4e 100644 --- a/api/types/types_drivers_client.go +++ b/api/types/types_drivers_client.go @@ -32,7 +32,9 @@ type ClientDriver interface { // VolumeInspectBefore may return an error, preventing the operation. VolumeInspectBefore( - ctx *Context, service, volumeID string, attachments bool) error + ctx *Context, + service, volumeID string, + attachments VolumeAttachmentsTypes) error // VolumeInspectAfter provides an opportunity to inspect/mutate the result. VolumeInspectAfter(ctx Context, result *Volume) diff --git a/api/types/types_drivers_storage.go b/api/types/types_drivers_storage.go index 6f00e2a1..5627a28f 100644 --- a/api/types/types_drivers_storage.go +++ b/api/types/types_drivers_storage.go @@ -1,20 +1,147 @@ package types +import "strconv" + // LibStorageDriverName is the name of the libStorage storage driver. const LibStorageDriverName = "libstorage" // NewStorageDriver is a function that constructs a new StorageDriver. type NewStorageDriver func() StorageDriver +// VolumeAttachmentsTypes is the type of the volume attachments bitmask. +type VolumeAttachmentsTypes int + +const ( + + // VolumeAttachmentsRequested indicates attachment information is requested. + VolumeAttachmentsRequested VolumeAttachmentsTypes = 1 << iota // 1 + + // VolumeAttachmentsMine indicates attachment information should + // be returned for volumes attached to the instance specified in the + // instance ID request header. If this bit is set then the instance ID + // header is required. + VolumeAttachmentsMine // 2 + + // VolumeAttachmentsDevices indicates an attempt should made to map devices + // provided via the local devices request header to the appropriate + // attachment information. If this bit is set then the instance ID and + // local device headers are required. + VolumeAttachmentsDevices // 4 + + // VolumeAttachmentsAttached indicates only volumes that are attached + // should be returned. + VolumeAttachmentsAttached // 8 + + // VolumeAttachmentsUnattached indicates only volumes that are unattached + // should be returned. + VolumeAttachmentsUnattached // 16 +) + +const ( + // VolumeAttachmentsNone specifies no attachment information is requested. + // This is the default value and the same as omitting this parameter + // altogether. + VolumeAttachmentsNone VolumeAttachmentsTypes = 0 + + // VolumeAttachmentsFalse is an alias for VolumeAttachmentsNone. + VolumeAttachmentsFalse = VolumeAttachmentsNone + + // VolumeAttachmentsTrue is a mask of + // VolumeAttachmentsRequested | VolumeAttachmentsDevices + VolumeAttachmentsTrue = VolumeAttachmentsRequested | + VolumeAttachmentsDevices +) + +// ParseVolumeAttachmentTypes parses a value into a VolumeAttachmentsTypes +// value. +func ParseVolumeAttachmentTypes(v interface{}) VolumeAttachmentsTypes { + switch tv := v.(type) { + case VolumeAttachmentsTypes: + return tv + case bool: + if tv { + return VolumeAttachmentsTypes(14) + } + return VolumeAttachmentsNone + case int: + return VolumeAttachmentsTypes(tv) + case uint: + return VolumeAttachmentsTypes(tv) + case int8: + return VolumeAttachmentsTypes(tv) + case uint8: + return VolumeAttachmentsTypes(tv) + case int16: + return VolumeAttachmentsTypes(tv) + case uint16: + return VolumeAttachmentsTypes(tv) + case int32: + return VolumeAttachmentsTypes(tv) + case uint32: + return VolumeAttachmentsTypes(tv) + case int64: + return VolumeAttachmentsTypes(tv) + case uint64: + return VolumeAttachmentsTypes(tv) + case string: + if i, err := strconv.ParseInt(tv, 10, 64); err == nil { + return ParseVolumeAttachmentTypes(i) + } + if b, err := strconv.ParseBool(tv); err == nil { + return ParseVolumeAttachmentTypes(b) + } + } + return VolumeAttachmentsNone +} + +// RequiresInstanceID returns a flag that indicates whether the attachment +// bit requires an instance ID to perform successfully. +func (v VolumeAttachmentsTypes) RequiresInstanceID() bool { + return v.Mine() || v.Devices() +} + +// Requested returns a flag that indicates attachment information is requested. +func (v VolumeAttachmentsTypes) Requested() bool { + return v&VolumeAttachmentsRequested > 0 +} + +// Mine returns a flag that indicates attachment information should +// be returned for volumes attached to the instance specified in the +// instance ID request header. If this bit is set then the instance ID +// header is required. +func (v VolumeAttachmentsTypes) Mine() bool { + return v&VolumeAttachmentsMine > 0 +} + +// Devices returns a flag that indicates an attempt should made to map devices +// provided via the local devices request header to the appropriate +// attachment information. If this bit is set then the instance ID and +// local device headers are required. +func (v VolumeAttachmentsTypes) Devices() bool { + return v&VolumeAttachmentsDevices > 0 +} + +// Attached returns a flag that indicates only volumes that are attached should +// be returned. +func (v VolumeAttachmentsTypes) Attached() bool { + return v&VolumeAttachmentsAttached > 0 +} + +// Unattached returns a flag that indicates only volumes that are unattached +// should be returned. +func (v VolumeAttachmentsTypes) Unattached() bool { + return v&VolumeAttachmentsUnattached > 0 +} + // VolumesOpts are options when inspecting a volume. type VolumesOpts struct { - Attachments bool + Attachments VolumeAttachmentsTypes Opts Store } // VolumeInspectOpts are options when inspecting a volume. type VolumeInspectOpts struct { - Attachments bool + Attachments VolumeAttachmentsTypes Opts Store } diff --git a/api/types/types_drivers_storage_test.go b/api/types/types_drivers_storage_test.go new file mode 100644 index 00000000..2c32d33b --- /dev/null +++ b/api/types/types_drivers_storage_test.go @@ -0,0 +1,85 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestVolumeAttachmentsTypes(t *testing.T) { + var a VolumeAttachmentsTypes + assert.False(t, a.Requested()) + assert.False(t, a.Mine()) + assert.False(t, a.Devices()) + assert.False(t, a.Attached()) + + a = VolumeAttachmentsTypes(5) + assert.True(t, a.Requested()) + assert.False(t, a.Mine()) + assert.True(t, a.Devices()) + assert.False(t, a.Attached()) + + a = VolumeAttachmentsTypes(9) + assert.True(t, a.Requested()) + assert.False(t, a.Mine()) + assert.False(t, a.Devices()) + assert.True(t, a.Attached()) + + a = VolumeAttachmentsTypes(13) + assert.True(t, a.Requested()) + assert.False(t, a.Mine()) + assert.True(t, a.Devices()) + assert.True(t, a.Attached()) +} + +func TestParseVolumeAttachmentsTypes(t *testing.T) { + var a VolumeAttachmentsTypes + assert.False(t, a.Requested()) + assert.False(t, a.Mine()) + assert.False(t, a.Devices()) + assert.False(t, a.Attached()) + + a = ParseVolumeAttachmentTypes("true") + assert.False(t, a.Requested()) + assert.True(t, a.Mine()) + assert.True(t, a.Devices()) + assert.True(t, a.Attached()) + a = ParseVolumeAttachmentTypes(true) + assert.False(t, a.Requested()) + assert.True(t, a.Mine()) + assert.True(t, a.Devices()) + assert.True(t, a.Attached()) + + a = ParseVolumeAttachmentTypes("5") + assert.True(t, a.Requested()) + assert.False(t, a.Mine()) + assert.True(t, a.Devices()) + assert.False(t, a.Attached()) + a = ParseVolumeAttachmentTypes(5) + assert.True(t, a.Requested()) + assert.False(t, a.Mine()) + assert.True(t, a.Devices()) + assert.False(t, a.Attached()) + + a = ParseVolumeAttachmentTypes("9") + assert.True(t, a.Requested()) + assert.False(t, a.Mine()) + assert.False(t, a.Devices()) + assert.True(t, a.Attached()) + a = ParseVolumeAttachmentTypes(9) + assert.True(t, a.Requested()) + assert.False(t, a.Mine()) + assert.False(t, a.Devices()) + assert.True(t, a.Attached()) + + a = ParseVolumeAttachmentTypes("13") + assert.True(t, a.Requested()) + assert.False(t, a.Mine()) + assert.True(t, a.Devices()) + assert.True(t, a.Attached()) + a = ParseVolumeAttachmentTypes(13) + assert.True(t, a.Requested()) + assert.False(t, a.Mine()) + assert.True(t, a.Devices()) + assert.True(t, a.Attached()) +} diff --git a/api/types/types_store.go b/api/types/types_store.go index 41e201a2..d2591e23 100644 --- a/api/types/types_store.go +++ b/api/types/types_store.go @@ -15,6 +15,14 @@ type Store interface { // Get returns a value for the key; a nil value if the key does not exist. Get(k string) interface{} + // GetAttachments returns a VolumeAttachmentsTypes value for the key + // "attachments" or a zero value if the key does not exist. + GetAttachments() VolumeAttachmentsTypes + + // GetVolumeAttachmentsTypes returns a VolumeAttachmentsTypes value for a + // key; a zero value if the key does not exist. + GetVolumeAttachmentsTypes(k string) VolumeAttachmentsTypes + // GetString returns a string value for a key; an empty string if the key // does not exist. GetString(k string) string diff --git a/api/utils/utils_store.go b/api/utils/utils_store.go index 6f0180a9..6558abea 100644 --- a/api/utils/utils_store.go +++ b/api/utils/utils_store.go @@ -192,6 +192,15 @@ func (s *keyValueStore) GetStore(k string) types.Store { } } +func (s *keyValueStore) GetAttachments() types.VolumeAttachmentsTypes { + return s.GetVolumeAttachmentsTypes("attachments") +} + +func (s *keyValueStore) GetVolumeAttachmentsTypes( + k string) types.VolumeAttachmentsTypes { + return types.ParseVolumeAttachmentTypes(s.Get(k)) +} + func (s *keyValueStore) GetString(k string) string { v := s.Get(k) switch tv := v.(type) { diff --git a/c/libstor-c/libstor-c_exported.go b/c/libstor-c/libstor-c_exported.go index e0352ca5..eee573a9 100644 --- a/c/libstor-c/libstor-c_exported.go +++ b/c/libstor-c/libstor-c_exported.go @@ -57,7 +57,8 @@ func volumes(clientID C.h, attachments C.short) C.result { return result } - svcToVolMap, err := c.API().Volumes(nil, attachments > 0) + svcToVolMap, err := c.API().Volumes( + nil, types.VolumeAttachmentsTypes(attachments)) if err != nil { result.err = C.CString(err.Error()) return result diff --git a/drivers/integration/docker/docker.go b/drivers/integration/docker/docker.go index f25224e4..6f2fe352 100644 --- a/drivers/integration/docker/docker.go +++ b/drivers/integration/docker/docker.go @@ -83,7 +83,7 @@ func (d *driver) List( vols, err := client.Storage().Volumes( ctx, &types.VolumesOpts{ - Attachments: opts.GetBool("attachments"), + Attachments: opts.GetAttachments(), Opts: opts, }, ) @@ -168,7 +168,7 @@ func (d *driver) Mount( "opts": opts}).Info("mounting volume") vol, err := d.volumeInspectByIDOrName( - ctx, volumeID, volumeName, true, opts.Opts) + ctx, volumeID, volumeName, types.VolumeAttachmentsTrue, opts.Opts) if isErrNotFound(err) && d.volumeCreateImplicit() { var err error if vol, err = d.Create(ctx, volumeName, &types.VolumeCreateOpts{ @@ -223,7 +223,7 @@ func (d *driver) Mount( } vol, err = d.volumeInspectByIDOrName( - ctx, vol.ID, "", true, opts.Opts) + ctx, vol.ID, "", types.VolumeAttachmentsTrue, opts.Opts) if err != nil { return "", nil, err } @@ -322,7 +322,7 @@ func (d *driver) Unmount( } vol, err := d.volumeInspectByIDOrName( - ctx, volumeID, volumeName, true, opts) + ctx, volumeID, volumeName, types.VolumeAttachmentsTrue, opts) if err != nil { return err } @@ -400,7 +400,7 @@ func (d *driver) Path( "opts": opts}).Info("getting path to volume") vol, err := d.volumeInspectByIDOrName( - ctx, volumeID, volumeName, true, opts) + ctx, volumeID, volumeName, types.VolumeAttachmentsTrue, opts) if err != nil { return "", err } else if vol == nil { @@ -505,7 +505,7 @@ func (d *driver) Remove( } vol, err := d.volumeInspectByIDOrName( - ctx, "", volumeName, false, opts) + ctx, "", volumeName, 0, opts) if err != nil { return err } diff --git a/drivers/integration/docker/docker_utils.go b/drivers/integration/docker/docker_utils.go index 305b9389..0118d827 100644 --- a/drivers/integration/docker/docker_utils.go +++ b/drivers/integration/docker/docker_utils.go @@ -21,7 +21,8 @@ func (d *driver) getVolumeMountPath(volumeName string) (string, error) { func (d *driver) volumeInspectByID( ctx types.Context, - volumeID string, attachments bool, + volumeID string, + attachments types.VolumeAttachmentsTypes, opts types.Store) (*types.Volume, error) { client := context.MustClient(ctx) vol, err := client.Storage().VolumeInspect(ctx, volumeID, @@ -35,7 +36,8 @@ func (d *driver) volumeInspectByID( func (d *driver) volumeInspectByIDOrName( ctx types.Context, - volumeID, volumeName string, attachments bool, + volumeID, volumeName string, + attachments types.VolumeAttachmentsTypes, opts types.Store) (*types.Volume, error) { if volumeID != "" && volumeName != "" { @@ -47,20 +49,22 @@ func (d *driver) volumeInspectByIDOrName( var obj *types.Volume if volumeID != "" { var err error - obj, err = d.volumeInspectByID(ctx, volumeID, true, opts) + obj, err = d.volumeInspectByID( + ctx, volumeID, types.VolumeAttachmentsTrue, opts) if err != nil { return nil, err } } else { objs, err := client.Storage().Volumes(ctx, &types.VolumesOpts{ - Attachments: false}) + Attachments: 0}) if err != nil { return nil, err } for _, o := range objs { - if strings.ToLower(volumeName) == strings.ToLower(o.Name) { - if attachments { - obj, err = d.volumeInspectByID(ctx, o.ID, true, opts) + if strings.EqualFold(volumeName, o.Name) { + if attachments.Requested() { + obj, err = d.volumeInspectByID( + ctx, o.ID, types.VolumeAttachmentsTrue, opts) if err != nil { return nil, err } diff --git a/drivers/storage/ebs/storage/ebs_storage.go b/drivers/storage/ebs/storage/ebs_storage.go index 720bffcd..993039ea 100644 --- a/drivers/storage/ebs/storage/ebs_storage.go +++ b/drivers/storage/ebs/storage/ebs_storage.go @@ -293,7 +293,7 @@ func (d *driver) VolumeCreate(ctx types.Context, volumeName string, if err != nil { return nil, goof.WithFieldsE(fields, "error getting volume", err) } - volumes, convErr := d.toTypesVolume(ctx, ec2vols, false) + volumes, convErr := d.toTypesVolume(ctx, ec2vols, 0) if convErr != nil { return nil, goof.WithFieldsE( fields, "error converting to types.Volume", convErr) @@ -329,7 +329,7 @@ func (d *driver) VolumeCreate(ctx types.Context, volumeName string, } // Return the volume created return d.VolumeInspect(ctx, *vol.VolumeId, &types.VolumeInspectOpts{ - Attachments: true, + Attachments: types.VolumeAttachmentsTrue, }) } @@ -579,7 +579,8 @@ func (d *driver) VolumeAttach( if err != nil { return nil, "", goof.WithError("error getting volume", err) } - volumes, convErr := d.toTypesVolume(ctx, ec2vols, true) + volumes, convErr := d.toTypesVolume( + ctx, ec2vols, types.VolumeAttachmentsTrue) if convErr != nil { return nil, "", goof.WithError( "error converting to types.Volume", convErr) @@ -631,7 +632,7 @@ func (d *driver) VolumeAttach( // Check if successful attach attachedVol, err := d.VolumeInspect( ctx, volumeID, &types.VolumeInspectOpts{ - Attachments: true, + Attachments: types.VolumeAttachmentsTrue, Opts: opts.Opts, }) if err != nil { @@ -655,7 +656,8 @@ func (d *driver) VolumeDetach( if err != nil { return nil, goof.WithError("error getting volume", err) } - volumes, convErr := d.toTypesVolume(ctx, ec2vols, true) + volumes, convErr := d.toTypesVolume( + ctx, ec2vols, types.VolumeAttachmentsTrue) if convErr != nil { return nil, goof.WithError("error converting to types.Volume", convErr) } @@ -692,7 +694,7 @@ func (d *driver) VolumeDetach( // check if successful detach detachedVol, err := d.VolumeInspect( ctx, volumeID, &types.VolumeInspectOpts{ - Attachments: true, + Attachments: types.VolumeAttachmentsTrue, Opts: opts.Opts, }) if err != nil { @@ -917,7 +919,7 @@ var errGetLocDevs = goof.New("error getting local devices from context") func (d *driver) toTypesVolume( ctx types.Context, ec2vols []*awsec2.Volume, - attachments bool) ([]*types.Volume, error) { + attachments types.VolumeAttachmentsTypes) ([]*types.Volume, error) { // Get local devices map from context ld, ldOK := context.LocalDevices(ctx) if !ldOK { @@ -930,7 +932,7 @@ func (d *driver) toTypesVolume( // Leave attachment's device name blank if attachments is false for _, attachment := range volume.Attachments { deviceName := "" - if attachments { + if attachments.Devices() { // Compensate for kernel volume mapping i.e. change "/dev/sda" // to "/dev/xvda" deviceName = strings.Replace( diff --git a/drivers/storage/ebs/tests/ebs_test.go b/drivers/storage/ebs/tests/ebs_test.go index 22036520..7d477f6b 100644 --- a/drivers/storage/ebs/tests/ebs_test.go +++ b/drivers/storage/ebs/tests/ebs_test.go @@ -348,7 +348,7 @@ func volumeByName( t *testing.T, client types.Client, volumeName, tag string) *types.Volume { log.WithField("volumeName", volumeName).Info("get volume by ebs.Name") // Retrieve all volumes - vols, err := client.API().Volumes(nil, false) + vols, err := client.API().Volumes(nil, 0) assert.NoError(t, err) if err != nil { t.FailNow() @@ -379,7 +379,7 @@ func volumeByID( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("get volume by ebs.Name using ID") // Retrieve all volumes - vols, err := client.API().Volumes(nil, false) + vols, err := client.API().Volumes(nil, 0) assert.NoError(t, err) if err != nil { t.FailNow() @@ -447,7 +447,7 @@ func volumeAttach( func volumeInspect( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, ebs.Name, volumeID, false) + reply, err := client.API().VolumeInspect(nil, ebs.Name, volumeID, 0) assert.NoError(t, err) if err != nil { @@ -462,7 +462,9 @@ func volumeInspect( func volumeInspectAttached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, ebs.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, ebs.Name, volumeID, + types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -478,7 +480,9 @@ func volumeInspectAttached( func volumeInspectDetached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, ebs.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, ebs.Name, volumeID, + types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -498,7 +502,7 @@ func volumeInspectDetachedFail( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, ebs.Name, volumeID, false) + reply, err := client.API().VolumeInspect(nil, ebs.Name, volumeID, 0) assert.NoError(t, err) if err != nil { diff --git a/drivers/storage/efs/storage/efs_storage.go b/drivers/storage/efs/storage/efs_storage.go index 2567236e..fef324dc 100644 --- a/drivers/storage/efs/storage/efs_storage.go +++ b/drivers/storage/efs/storage/efs_storage.go @@ -153,7 +153,7 @@ func (d *driver) Volumes( } var atts []*types.VolumeAttachment - if opts.Attachments { + if opts.Attachments.Requested() { atts, err = d.getVolumeAttachments(ctx, *fileSystem.FileSystemId) if err != nil { return nil, err @@ -207,7 +207,7 @@ func (d *driver) VolumeInspect( var atts []*types.VolumeAttachment - if opts.Attachments { + if opts.Attachments.Requested() { atts, err = d.getVolumeAttachments(ctx, *fileSystem.FileSystemId) if err != nil { return nil, err @@ -292,7 +292,7 @@ func (d *driver) VolumeCreate( } return d.VolumeInspect(ctx, *fileSystem.FileSystemId, - &types.VolumeInspectOpts{Attachments: false}) + &types.VolumeInspectOpts{Attachments: 0}) } // VolumeRemove removes a volume. @@ -389,7 +389,7 @@ func (d *driver) VolumeAttach( opts *types.VolumeAttachOpts) (*types.Volume, string, error) { vol, err := d.VolumeInspect(ctx, volumeID, - &types.VolumeInspectOpts{Attachments: true}) + &types.VolumeInspectOpts{Attachments: types.VolumeAttachmentsTrue}) if err != nil { return nil, "", err } diff --git a/drivers/storage/efs/tests/efs_test.go b/drivers/storage/efs/tests/efs_test.go index 83080eec..e7268f55 100644 --- a/drivers/storage/efs/tests/efs_test.go +++ b/drivers/storage/efs/tests/efs_test.go @@ -165,7 +165,7 @@ func volumeByName( t *testing.T, client types.Client, volumeName string) *types.Volume { log.WithField("volumeName", volumeName).Info("get volume name") - vols, err := client.API().Volumes(nil, false) + vols, err := client.API().Volumes(nil, 0) assert.NoError(t, err) if err != nil { t.FailNow() @@ -244,7 +244,9 @@ func volumeInspectAttached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, efs.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, efs.Name, volumeID, + types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -261,7 +263,9 @@ func volumeInspectDetached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, efs.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, efs.Name, volumeID, + types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { diff --git a/drivers/storage/isilon/storage/isilon_storage.go b/drivers/storage/isilon/storage/isilon_storage.go index 554ab58e..1145dfb0 100644 --- a/drivers/storage/isilon/storage/isilon_storage.go +++ b/drivers/storage/isilon/storage/isilon_storage.go @@ -215,7 +215,7 @@ func (d *driver) Volumes( opts *types.VolumesOpts) ([]*types.Volume, error) { // always return attachments to align against other drivers for now - return d.getVolume(ctx, "", "", true) + return d.getVolume(ctx, "", "", opts.Attachments) } func (d *driver) VolumeInspect( @@ -240,7 +240,7 @@ func (d *driver) VolumeCreate(ctx types.Context, volumeName string, opts *types.VolumeCreateOpts) (*types.Volume, error) { vol, err := d.VolumeInspect(ctx, volumeName, - &types.VolumeInspectOpts{Attachments: false}) + &types.VolumeInspectOpts{Attachments: types.VolumeAttachmentsTrue}) if err != nil { return nil, err } @@ -281,7 +281,7 @@ func (d *driver) VolumeCreate(ctx types.Context, volumeName string, } return d.VolumeInspect(ctx, volumeName, - &types.VolumeInspectOpts{Attachments: false}) + &types.VolumeInspectOpts{Attachments: 0}) } // VolumeRemove removes a volume. @@ -329,7 +329,7 @@ func (d *driver) VolumeAttach( // ensure the volume exists and is exported vol, err := d.VolumeInspect(ctx, volumeID, - &types.VolumeInspectOpts{Attachments: true}) + &types.VolumeInspectOpts{Attachments: types.VolumeAttachmentsTrue}) if err != nil { return nil, "", err } @@ -390,7 +390,7 @@ func (d *driver) VolumeAttach( } vol, err = d.VolumeInspect(ctx, volumeID, - &types.VolumeInspectOpts{Attachments: true}) + &types.VolumeInspectOpts{Attachments: types.VolumeAttachmentsTrue}) if err != nil { return nil, "", err } @@ -408,9 +408,7 @@ func (d *driver) VolumeDetach( defer d.Unlock() vol, err := d.VolumeInspect(ctx, volumeID, - &types.VolumeInspectOpts{ - Attachments: false, - }) + &types.VolumeInspectOpts{Attachments: 0}) if err != nil { return nil, err } @@ -454,7 +452,7 @@ func (d *driver) VolumeDetach( } return d.VolumeInspect(ctx, volumeID, &types.VolumeInspectOpts{ - Attachments: true, + Attachments: types.VolumeAttachmentsTrue, }) } @@ -517,8 +515,11 @@ func (d *driver) SnapshotRemove( return nil } -func (d *driver) getVolume(ctx types.Context, volumeID, volumeName string, - attachments bool) ([]*types.Volume, error) { +func (d *driver) getVolume( + ctx types.Context, + volumeID, volumeName string, + attachments types.VolumeAttachmentsTypes) ([]*types.Volume, error) { + var volumes []isi.Volume if volumeID != "" || volumeName != "" { volume, err := d.client.GetVolume(ctx, volumeID, volumeName) @@ -542,7 +543,7 @@ func (d *driver) getVolume(ctx types.Context, volumeID, volumeName string, } var atts []*types.VolumeAttachment - if attachments { + if attachments.Requested() { var err error atts, err = d.getVolumeAttachments(ctx) if err != nil { diff --git a/drivers/storage/isilon/tests/isilon_test.go b/drivers/storage/isilon/tests/isilon_test.go index 3059837e..806a9b02 100644 --- a/drivers/storage/isilon/tests/isilon_test.go +++ b/drivers/storage/isilon/tests/isilon_test.go @@ -134,7 +134,7 @@ func volumeByName( t *testing.T, client types.Client, volumeName string) *types.Volume { log.WithField("volumeName", volumeName).Info("get volume name") - vols, err := client.API().Volumes(nil, false) + vols, err := client.API().Volumes(nil, 0) assert.NoError(t, err) if err != nil { t.FailNow() @@ -214,7 +214,7 @@ func volumeInspect( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, isilon.Name, volumeID, false) + reply, err := client.API().VolumeInspect(nil, isilon.Name, volumeID, 0) assert.NoError(t, err) if err != nil { @@ -229,7 +229,8 @@ func volumeInspectAttached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, isilon.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, isilon.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -246,7 +247,8 @@ func volumeInspectAttachedFail( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, isilon.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, isilon.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -262,7 +264,8 @@ func volumeInspectDetached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, isilon.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, isilon.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { diff --git a/drivers/storage/libstorage/libstorage_client_api.go b/drivers/storage/libstorage/libstorage_client_api.go index aa303201..4193902d 100644 --- a/drivers/storage/libstorage/libstorage_client_api.go +++ b/drivers/storage/libstorage/libstorage_client_api.go @@ -66,7 +66,7 @@ func (c *client) ServiceInspect( func (c *client) Volumes( ctx types.Context, - attachments bool) (types.ServiceVolumeMap, error) { + attachments types.VolumeAttachmentsTypes) (types.ServiceVolumeMap, error) { ctx = c.requireCtx(ctx) @@ -82,7 +82,7 @@ func (c *client) Volumes( func (c *client) VolumesByService( ctx types.Context, service string, - attachments bool) (types.VolumeMap, error) { + attachments types.VolumeAttachmentsTypes) (types.VolumeMap, error) { ctx = c.withInstanceID(c.requireCtx(ctx), service) ctxA, err := c.withAllLocalDevices(ctx) @@ -97,7 +97,7 @@ func (c *client) VolumesByService( func (c *client) VolumeInspect( ctx types.Context, service, volumeID string, - attachments bool) (*types.Volume, error) { + attachments types.VolumeAttachmentsTypes) (*types.Volume, error) { ctx = c.withInstanceID(c.requireCtx(ctx), service) ctxA, err := c.withAllLocalDevices(ctx) diff --git a/drivers/storage/rackspace/storage/rackspace_storage.go b/drivers/storage/rackspace/storage/rackspace_storage.go index 1cd70c32..f4bd4250 100644 --- a/drivers/storage/rackspace/storage/rackspace_storage.go +++ b/drivers/storage/rackspace/storage/rackspace_storage.go @@ -138,7 +138,7 @@ func (d *driver) Volumes( ctx types.Context, opts *types.VolumesOpts) ([]*types.Volume, error) { // always return attachments to align against other drivers for now - return d.getVolume(ctx, "", "", true) + return d.getVolume(ctx, "", "", types.VolumeAttachmentsTrue) } // // VolumeInspect inspects a single volume. @@ -311,7 +311,7 @@ func (d *driver) VolumeDetach( if volumeID == "" { return nil, goof.WithFields(fields, "volumeId is required for VolumeDetach") } - vols, err := d.getVolume(ctx, volumeID, "", true) + vols, err := d.getVolume(ctx, volumeID, "", types.VolumeAttachmentsTrue) if err != nil { return nil, err } @@ -465,8 +465,11 @@ func (d *driver) getInstanceRegion() (string, error) { return region, nil } -func (d *driver) getVolume(ctx types.Context, volumeID, volumeName string, - attachments bool) ([]*types.Volume, error) { +func (d *driver) getVolume( + ctx types.Context, + volumeID, volumeName string, + attachments types.VolumeAttachmentsTypes) ([]*types.Volume, error) { + var volumesRet []volumes.Volume fields := eff(goof.Fields{ "moduleName": ctx, @@ -583,13 +586,16 @@ func (d *driver) createVolume( "error waiting for volume creation to complete", err) } log.WithFields(fields).Debug("created volume") - return translateVolume(resp, true), nil + return translateVolume(resp, types.VolumeAttachmentsTrue), nil } //Reformats from volumes.Volume to types.Volume credit to github.com/MatMaul -func translateVolume(volume *volumes.Volume, includeAttachments bool) *types.Volume { +func translateVolume( + volume *volumes.Volume, + includeAttachments types.VolumeAttachmentsTypes) *types.Volume { + var attachments []*types.VolumeAttachment - if includeAttachments { + if includeAttachments.Requested() { for _, attachment := range volume.Attachments { libstorageAttachment := &types.VolumeAttachment{ VolumeID: attachment["volume_id"].(string), @@ -652,7 +658,9 @@ func (d *driver) volumeAttached(ctx types.Context, if volumeID == "" { return true, goof.WithFields(fields, "volumeId is required") } - volume, err := d.VolumeInspect(ctx, volumeID, &types.VolumeInspectOpts{Attachments: true}) + volume, err := d.VolumeInspect( + ctx, volumeID, &types.VolumeInspectOpts{ + Attachments: types.VolumeAttachmentsTrue}) if err != nil { return true, goof.WithFieldsE(fields, "error getting volume when waiting", err) } @@ -701,7 +709,9 @@ func (d *driver) waitVolumeAttachStatus( } for { - volume, err := d.VolumeInspect(ctx, volumeID, &types.VolumeInspectOpts{Attachments: true}) + volume, err := d.VolumeInspect( + ctx, volumeID, + &types.VolumeInspectOpts{Attachments: types.VolumeAttachmentsTrue}) if err != nil { return nil, goof.WithFieldsE(fields, "error getting volume when waiting", err) } @@ -717,7 +727,6 @@ func (d *driver) waitVolumeAttachStatus( } time.Sleep(1 * time.Second) } - return nil, nil } //error reporting diff --git a/drivers/storage/rackspace/tests/rackspace_test.go b/drivers/storage/rackspace/tests/rackspace_test.go index b9992497..8f4283cd 100644 --- a/drivers/storage/rackspace/tests/rackspace_test.go +++ b/drivers/storage/rackspace/tests/rackspace_test.go @@ -118,7 +118,7 @@ func volumeByName( t *testing.T, client types.Client, volumeName string) *types.Volume { log.WithField("volumeName", volumeName).Info("get volume byrackspace.Name") - vols, err := client.API().Volumes(nil, false) + vols, err := client.API().Volumes(nil, 0) assert.NoError(t, err) if err != nil { t.FailNow() @@ -226,7 +226,7 @@ func volumeInspect( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, rackspace.Name, volumeID, false) + reply, err := client.API().VolumeInspect(nil, rackspace.Name, volumeID, 0) assert.NoError(t, err) if err != nil { @@ -241,7 +241,8 @@ func volumeInspectAttached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, rackspace.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, rackspace.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -257,7 +258,8 @@ func volumeInspectAttachedFail( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, rackspace.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, rackspace.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -273,7 +275,8 @@ func volumeInspectDetached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, rackspace.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, rackspace.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -290,7 +293,7 @@ func volumeInspectDetachedFail( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, rackspace.Name, volumeID, false) + reply, err := client.API().VolumeInspect(nil, rackspace.Name, volumeID, 0) assert.NoError(t, err) if err != nil { diff --git a/drivers/storage/scaleio/storage/scaleio_storage.go b/drivers/storage/scaleio/storage/scaleio_storage.go index 16649ae2..3053b1c6 100644 --- a/drivers/storage/scaleio/storage/scaleio_storage.go +++ b/drivers/storage/scaleio/storage/scaleio_storage.go @@ -163,7 +163,7 @@ func (d *driver) Volumes( opts *types.VolumesOpts) ([]*types.Volume, error) { sdcMappedVolumes := make(map[string]string) - if opts.Attachments { + if opts.Attachments.Requested() { if ld, ok := context.LocalDevices(ctx); ok { sdcMappedVolumes = ld.DeviceMap } @@ -200,7 +200,7 @@ func (d *driver) Volumes( return "" } - volumes, err := d.getVolume("", "", false) + volumes, err := d.getVolume("", "", 0) if err != nil { return []*types.Volume{}, err } @@ -256,7 +256,7 @@ func (d *driver) VolumeInspect( } sdcMappedVolumes := make(map[string]string) - if opts.Attachments { + if opts.Attachments.Requested() { if ld, ok := context.LocalDevices(ctx); ok { sdcMappedVolumes = ld.DeviceMap } @@ -374,7 +374,7 @@ func (d *driver) VolumeCreate(ctx types.Context, volumeName string, } return d.VolumeInspect(ctx, vol.ID, &types.VolumeInspectOpts{ - Attachments: true, + Attachments: types.VolumeAttachmentsTrue, }) } @@ -389,7 +389,7 @@ func (d *driver) VolumeCreateFromSnapshot( return nil, goof.New("no volume name specified") } - volumes, err := d.getVolume("", volumeName, false) + volumes, err := d.getVolume("", volumeName, 0) if err != nil { return nil, err } @@ -406,7 +406,7 @@ func (d *driver) VolumeCreateFromSnapshot( } volumeInspectOpts := &types.VolumeInspectOpts{ - Attachments: true, + Attachments: types.VolumeAttachmentsTrue, Opts: opts.Opts, } @@ -448,7 +448,7 @@ func (d *driver) VolumeRemove( var err error var volumes []*siotypes.Volume - if volumes, err = d.getVolume(volumeID, "", false); err != nil { + if volumes, err = d.getVolume(volumeID, "", 0); err != nil { return goof.WithFieldsE(fields, "error getting volume", err) } @@ -478,7 +478,7 @@ func (d *driver) VolumeAttach( vol, err := d.VolumeInspect( ctx, volumeID, &types.VolumeInspectOpts{ - Attachments: true, + Attachments: types.VolumeAttachmentsTrue, }) if err != nil { return nil, "", goof.WithError("error getting volume", err) @@ -505,7 +505,7 @@ func (d *driver) VolumeAttach( attachedVol, err := d.VolumeInspect( ctx, volumeID, &types.VolumeInspectOpts{ - Attachments: true, + Attachments: types.VolumeAttachmentsTrue, Opts: opts.Opts, }) if err != nil { @@ -522,7 +522,7 @@ func (d *driver) VolumeDetach( iid := context.MustInstanceID(ctx) - volumes, err := d.getVolume(volumeID, "", false) + volumes, err := d.getVolume(volumeID, "", 0) if err != nil { return nil, goof.WithError("error getting volume", err) } @@ -551,7 +551,7 @@ func (d *driver) VolumeDetach( } vol, err := d.VolumeInspect(ctx, volumeID, &types.VolumeInspectOpts{ - Attachments: true, + Attachments: types.VolumeAttachmentsTrue, }) if err != nil { return nil, err @@ -636,12 +636,15 @@ func (d *driver) getProtectionDomainIDs() ( } func (d *driver) getVolume( - volumeID, volumeName string, getSnapshots bool) ( + volumeID, volumeName string, attachments types.VolumeAttachmentsTypes) ( + []*siotypes.Volume, error) { volumeName = shrink(volumeName) - volumes, err := d.client.GetVolume("", volumeID, "", volumeName, getSnapshots) + volumes, err := d.client.GetVolume( + "", volumeID, "", volumeName, attachments.Requested()) + if err != nil { return nil, err } diff --git a/drivers/storage/scaleio/tests/scaleio_test.go b/drivers/storage/scaleio/tests/scaleio_test.go index 8a4af14d..e93099e1 100644 --- a/drivers/storage/scaleio/tests/scaleio_test.go +++ b/drivers/storage/scaleio/tests/scaleio_test.go @@ -127,7 +127,7 @@ func volumeByName( t *testing.T, client types.Client, volumeName string) *types.Volume { log.WithField("volumeName", volumeName).Info("get volume bysio.Name") - vols, err := client.API().Volumes(nil, false) + vols, err := client.API().Volumes(nil, 0) assert.NoError(t, err) if err != nil { t.FailNow() @@ -206,7 +206,7 @@ func volumeInspect( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, sio.Name, volumeID, false) + reply, err := client.API().VolumeInspect(nil, sio.Name, volumeID, 0) assert.NoError(t, err) if err != nil { @@ -221,7 +221,8 @@ func volumeInspectAttached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, sio.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, sio.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -237,7 +238,8 @@ func volumeInspectAttachedFail( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, sio.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, sio.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -253,7 +255,8 @@ func volumeInspectDetached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, sio.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, sio.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -270,7 +273,7 @@ func volumeInspectDetachedFail( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, sio.Name, volumeID, false) + reply, err := client.API().VolumeInspect(nil, sio.Name, volumeID, 0) assert.NoError(t, err) if err != nil { diff --git a/drivers/storage/vbox/storage/vbox_storage.go b/drivers/storage/vbox/storage/vbox_storage.go index 718e7c17..1860ca9b 100644 --- a/drivers/storage/vbox/storage/vbox_storage.go +++ b/drivers/storage/vbox/storage/vbox_storage.go @@ -233,7 +233,7 @@ func (d *driver) VolumeCreate(ctx types.Context, volumeName string, size := *opts.Size * 1024 * 1024 * 1024 - vol, err := d.getVolume(ctx, "", volumeName, false) + vol, err := d.getVolume(ctx, "", volumeName, 0) if err != nil { return nil, err } @@ -327,7 +327,7 @@ func (d *driver) VolumeAttach( } // review volume with attachments to any host - volumes, err := d.getVolume(ctx, volumeID, "", false) + volumes, err := d.getVolume(ctx, volumeID, "", 0) if err != nil { return nil, "", err } @@ -356,7 +356,7 @@ func (d *driver) VolumeAttach( ) } - volumes, err = d.getVolume(ctx, volumeID, "", true) + volumes, err = d.getVolume(ctx, volumeID, "", types.VolumeAttachmentsTrue) if err != nil { return nil, "", err } @@ -384,7 +384,7 @@ func (d *driver) VolumeDetach( return nil, goof.New("missing volume id") } - volumes, err := d.getVolume(ctx, volumeID, "", false) + volumes, err := d.getVolume(ctx, volumeID, "", 0) if err != nil { return nil, err } @@ -402,7 +402,8 @@ func (d *driver) VolumeDetach( ctx.Info("detached volume", volumeID) return d.VolumeInspect( - ctx, volumeID, &types.VolumeInspectOpts{Attachments: true}) + ctx, volumeID, &types.VolumeInspectOpts{ + Attachments: types.VolumeAttachmentsTrue}) } func (d *driver) VolumeDetachAll( @@ -477,7 +478,7 @@ func (d *driver) VolumeInspect( func (d *driver) getVolume( ctx types.Context, volumeID string, volumeName string, - attachments bool) ([]*types.Volume, error) { + attachments types.VolumeAttachmentsTypes) ([]*types.Volume, error) { if err := d.refreshSession(ctx); err != nil { return nil, err @@ -493,7 +494,7 @@ func (d *driver) getVolume( } var mapDN map[string]string - if attachments { + if attachments.Requested() { volumeMapping, err := d.getVolumeMapping(ctx) if err != nil { return nil, err diff --git a/drivers/storage/vbox/tests/vbox_test.go b/drivers/storage/vbox/tests/vbox_test.go index 35e70e6b..87e658fa 100644 --- a/drivers/storage/vbox/tests/vbox_test.go +++ b/drivers/storage/vbox/tests/vbox_test.go @@ -126,7 +126,7 @@ func volumeByName( t *testing.T, client types.Client, volumeName string) *types.Volume { log.WithField("volumeName", volumeName).Info("get volume byvbox.Name") - vols, err := client.API().Volumes(nil, false) + vols, err := client.API().Volumes(nil, 0) assert.NoError(t, err) if err != nil { t.FailNow() @@ -205,7 +205,7 @@ func volumeInspect( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, vbox.Name, volumeID, false) + reply, err := client.API().VolumeInspect(nil, vbox.Name, volumeID, 0) assert.NoError(t, err) if err != nil { @@ -220,7 +220,8 @@ func volumeInspectAttached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, vbox.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, vbox.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -236,7 +237,8 @@ func volumeInspectAttachedFail( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, vbox.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, vbox.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -252,7 +254,8 @@ func volumeInspectDetached( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, vbox.Name, volumeID, true) + reply, err := client.API().VolumeInspect( + nil, vbox.Name, volumeID, types.VolumeAttachmentsTrue) assert.NoError(t, err) if err != nil { @@ -269,7 +272,7 @@ func volumeInspectDetachedFail( t *testing.T, client types.Client, volumeID string) *types.Volume { log.WithField("volumeID", volumeID).Info("inspecting volume") - reply, err := client.API().VolumeInspect(nil, vbox.Name, volumeID, false) + reply, err := client.API().VolumeInspect(nil, vbox.Name, volumeID, 0) assert.NoError(t, err) if err != nil { diff --git a/drivers/storage/vfs/client/vfs_client.go b/drivers/storage/vfs/client/vfs_client.go index 331f28f4..b8a3c45b 100644 --- a/drivers/storage/vfs/client/vfs_client.go +++ b/drivers/storage/vfs/client/vfs_client.go @@ -60,7 +60,8 @@ func (d *driver) VolumesByServiceAfter( func (d *driver) VolumeInspectBefore( ctx *types.Context, - service, volumeID string, attachments bool) error { + service, volumeID string, + attachments types.VolumeAttachmentsTypes) error { return nil } diff --git a/drivers/storage/vfs/tests/vfs_test.go b/drivers/storage/vfs/tests/vfs_test.go index c33e04f2..0cf27976 100644 --- a/drivers/storage/vfs/tests/vfs_test.go +++ b/drivers/storage/vfs/tests/vfs_test.go @@ -121,7 +121,9 @@ func TestStorageDriverVolumes(t *testing.T) { vols, err := client.Storage().Volumes( context.Background().WithValue( context.ServiceKey, vfs.Name), - &types.VolumesOpts{Attachments: true, Opts: utils.NewStore()}) + &types.VolumesOpts{ + Attachments: types.VolumeAttachmentsTrue, + Opts: utils.NewStore()}) assert.NoError(t, err) assert.Len(t, vols, 2) }) @@ -130,7 +132,7 @@ func TestStorageDriverVolumes(t *testing.T) { func TestVolumes(t *testing.T) { tc, _, vols, _ := newTestConfigAll(t) tf := func(config gofig.Config, client types.Client, t *testing.T) { - reply, err := client.API().Volumes(nil, false) + reply, err := client.API().Volumes(nil, 0) if err != nil { t.Fatal(err) } @@ -146,7 +148,7 @@ func TestVolumes(t *testing.T) { func TestVolumesWithAttachments(t *testing.T) { tc, _, vols, _ := newTestConfigAll(t) tf := func(config gofig.Config, client types.Client, t *testing.T) { - reply, err := client.API().Volumes(nil, true) + reply, err := client.API().Volumes(nil, types.VolumeAttachmentsTrue) if err != nil { t.Fatal(err) } @@ -164,7 +166,7 @@ func TestVolumesWithAttachmentsWithControllerClient(t *testing.T) { tc, _, _, _ := newTestConfigAll(t) tf := func(config gofig.Config, client types.Client, t *testing.T) { - _, err := client.API().Volumes(nil, true) + _, err := client.API().Volumes(nil, types.VolumeAttachmentsTrue) assert.Error(t, err) assert.Equal(t, "batch processing error", err.Error()) } @@ -175,7 +177,7 @@ func TestVolumesWithAttachmentsWithControllerClient(t *testing.T) { func TestVolumesByService(t *testing.T) { tc, _, vols, _ := newTestConfigAll(t) tf := func(config gofig.Config, client types.Client, t *testing.T) { - reply, err := client.API().VolumesByService(nil, "vfs", false) + reply, err := client.API().VolumesByService(nil, "vfs", 0) if err != nil { t.Fatal(err) } @@ -190,7 +192,8 @@ func TestVolumesByService(t *testing.T) { func TestVolumesByServiceWithAttachments(t *testing.T) { tc, _, vols, _ := newTestConfigAll(t) tf := func(config gofig.Config, client types.Client, t *testing.T) { - reply, err := client.API().VolumesByService(nil, "vfs", true) + reply, err := client.API().VolumesByService( + nil, "vfs", types.VolumeAttachmentsTrue) if err != nil { t.Fatal(err) } @@ -206,7 +209,7 @@ func TestVolumesByServiceWithAttachments(t *testing.T) { func TestVolumeInspect(t *testing.T) { tc, _, vols, _ := newTestConfigAll(t) tf := func(config gofig.Config, client types.Client, t *testing.T) { - reply, err := client.API().VolumeInspect(nil, "vfs", "vfs-000", false) + reply, err := client.API().VolumeInspect(nil, "vfs", "vfs-000", 0) if err != nil { t.Fatal(err) } @@ -219,7 +222,8 @@ func TestVolumeInspect(t *testing.T) { func TestVolumeInspectWithAttachments(t *testing.T) { tc, _, vols, _ := newTestConfigAll(t) tf := func(config gofig.Config, client types.Client, t *testing.T) { - reply, err := client.API().VolumeInspect(nil, "vfs", "vfs-000", true) + reply, err := client.API().VolumeInspect( + nil, "vfs", "vfs-000", types.VolumeAttachmentsTrue) if err != nil { t.Fatal(err) } @@ -402,7 +406,8 @@ func TestVolumeSnapshot(t *testing.T) { func TestVolumeCreateFromSnapshot(t *testing.T) { tf := func(config gofig.Config, client types.Client, t *testing.T) { - ogVol, err := client.API().VolumeInspect(nil, "vfs", "vfs-000", true) + ogVol, err := client.API().VolumeInspect( + nil, "vfs", "vfs-000", types.VolumeAttachmentsTrue) assert.NoError(t, err) volumeName := "Volume 003" @@ -497,7 +502,7 @@ func TestVolumeDetach(t *testing.T) { assert.Equal(t, 0, len(reply.Attachments)) reply, err = client.API().VolumeInspect( - nil, vfs.Name, "vfs-001", false) + nil, vfs.Name, "vfs-001", 0) assert.NoError(t, err) assert.Equal(t, "vfs-001", reply.ID) assert.Equal(t, 0, len(reply.Attachments)) @@ -530,12 +535,12 @@ func TestVolumeDetachAllForService(t *testing.T) { assert.EqualValues(t, vols, reply) reply, err = client.API().VolumesByService( - nil, vfs.Name, true) + nil, vfs.Name, types.VolumeAttachmentsTrue) assert.NoError(t, err) assert.Equal(t, 0, len(reply)) reply, err = client.API().VolumesByService( - nil, vfs.Name, false) + nil, vfs.Name, 0) assert.NoError(t, err) assert.Equal(t, 3, len(reply)) assert.EqualValues(t, vols, reply) @@ -568,12 +573,12 @@ func TestVolumeDetachAll(t *testing.T) { assert.Equal(t, 3, len(reply[vfs.Name])) assert.EqualValues(t, vols, reply[vfs.Name]) - reply, err = client.API().Volumes(nil, true) + reply, err = client.API().Volumes(nil, types.VolumeAttachmentsTrue) assert.NoError(t, err) assert.Equal(t, 1, len(reply)) assert.Equal(t, 0, len(reply[vfs.Name])) - reply, err = client.API().Volumes(nil, false) + reply, err = client.API().Volumes(nil, 0) assert.NoError(t, err) assert.Equal(t, 1, len(reply)) assert.Equal(t, 3, len(reply[vfs.Name])) diff --git a/libstorage.apib b/libstorage.apib index 300532aa..363d684e 100644 --- a/libstorage.apib +++ b/libstorage.apib @@ -6,84 +6,159 @@ reference client and server implementations. ## Headers The libStorage API supports custom headers for sending information -about a client's instance ID and local devices. +about a client's instance ID and local devices as well as other +pieces of data. -### Instance ID Header +### Request Headers +libStorage supports the following request headers: + +Name | Description +-----|------------ +`Libstorage-Instanceid` | A client's instance ID +`Libstorage-Localdevices` | The client's local device map +`Libstorage-Txid` | A transaction ID +`Libstorage-Txcr` | The timestamp (epoch) at which the transaction was created. + +Please note the header names are case sensitive and must comply with the above, +listed values. This is in adherence to the +[canonical header](https://golang.org/pkg/net/http/#CanonicalHeaderKey) format. + + +#### Instance ID A client's instance ID must be provided to the remote libStorage server in order for certain storage operations to succeed. Because there are API operations using the GET method, a header is the only logical choice for encapsulating the instance ID. -There are actually two instance ID headers, one for simple, -plain-text strings, and one for more complex instance ID -information. - -#### libStorage-InstanceID -The header `libStorage-InstanceID` is used for drivers that have -instance IDs that are simple strings, such as ScaleIO or -VFS. The following is an example of headers for sending -instance ID information generated by ScaleIO and VFS: - - libStorage-InstanceID: scaleio=12345abcde - libStorage-InstanceID: vfs=pax,true - -The second instance ID listed above is not the same as the first. -In the second example the format is -`DRIVER`=`INSTANCEID`,`FORMATTED` -where `FORMATTED` is a boolean flag that indicates the instance -ID has already been formatted by a previous server-side call to -the driver's InstanceInspect function. This flag indicates to -the driver that it is not necessary to format the instance ID -again. - -The `FORMATTED` flag is not required, however. Omitting it means -the value default to `false`. - -#### libStorage-InstanceID64 -The header `libStorage-InstanceID64` is used for drivers that -have instance IDs that are not simple strings, but rather -compound structures best represented as JSON documents. The -libStorage mock driver uses such an instance ID, as does the -Amazon EC2 driver. The following is an example of headers for -sending instance ID information generated by the mock driver: - - libStorage-InstanceID64: mock=eyJpZCI6IjEyMzQ1IiwibWV0YWRhdGEiOnsibWF4IjoxMCwibWluIjowLCJyYWQiOiJjb29sIiwidG90YWxseSI6InR1YnVsYXIifX0= - -The above value may look like gibberish, but it's just the -mock driver's instance ID encoded first as a JSON string and -then as base64. Decoding the above test renders a JSON object -like this one: - - { - "id": "12345", - "metadata": { - "max": 10, - "min": 0, - "rad": "cool", - "totally": "tubular" - } - } - -### Local Devices Header -The client must also transmit information about its local devices -and to which paths they are mounted. This is accomplished by using -the header `libStorage-LocalDevices`. Here is an example of the -header in action: - - libStorage-LocalDevices: mock=/dev/xvda=/var/log, /dev/xvdb=/home, /dev/xvdc=/net/share, /dev/xvdd=/var/lib/backup - -### Transaction ID +The name of the header is `Libstorage-Instanceid` and it adheres to +the following format: + +``` +Libstorage-Instanceid: DRIVER=ID,FIELDS,METADATA +``` + +The header's value is made up of several pieces of information, as +illustrated in the above example format: + + Name | Description +------|------------ +`DRIVER` | The driver for which the instance ID is intended. +`ID` | The instance ID. This is a string value. +`FIELDS` | A URL-encoded string of key-value pairs. +`METADATA` | A base-64 encoded buffer that can be used to transport temporary "seed" data to a driver's `InstanceInspect` function in order to generate the real instance ID. + +The following is an example of headers for sending +instance ID information generated by EBS and EFS: + +``` +Libstorage-Instanceid: ebs=i-1234,region=west +Libstorage-Instanceid: efs=i-1234,region%3Deast%2Czone%3D2 +``` + +Notice that the instance ID for the EFS driver contains +encoded characters. That's because the `FIELDS` component +of an instance ID is URL encoded like a query string in +order to escape `=` and `,` characters. + +The instance ID's `METADATA` component is temporary and +used only by storage platforms that are not able to fully +generate an instance ID on the client-side. For example, +the ScaleIO platform generates the client's ScaleIO GUID +and uses the libStorage server's `InstanceInspect` API +to build the actual instance ID. Thus the initial instance +ID might be sent as : + +``` +Libstorage-Instanceid: scaleio=,,MWJiOTFmMDctODU2ZC00YWY5LWFjZWQtM2UzZmMzOTY0MDU5 +``` + +The above instance ID lacks an actual ID and any fields. The only data +present is the `METADATA`, a base-64 encoded value that the remote +storage driver knows how to unmarshal. + +On the server-side the ScaleIO driver would take the metadata and use +it to generate the actual instance ID, responding to the client with +a response header: + +``` +Libstorage-Instanceid: scaleio=client-123 +``` + +Subsequent calls from the client to the server would then use the +fully-formed instance ID where required. + +Please note that the `InstanceInspect` call will also return any +`FIELD` data in the response header. Only the `METADATA` is stripped. + + +#### Local Devices +The client must also transmit information about its local devices. The +header adheres to the following format: + +``` +Libstorage-Localdevices: DRIVER=VOLUME_ID::DEVICE_PATH[,VOLUME_ID::DEVICE_PATH,...] +``` + +Name | Description +------|------------ +`DRIVER` | The driver for which the local devices map is intended. +`VOLUME_ID` | A piece of information obtainable on the client that can be used on the server-side to identify a volume. +`DEVICE_PATH` | The path to the device on the client at which the volume is attached. + +The following is an example of headers for sending +local device maps generated by EBS and ScaleIO: + +``` +Libstorage-Localdevices: ebs=/dev/xvdf::/dev/xvdf,/dev/xvdg::/dev/xvdg +Libstorage-Localdevices: scaleio=vol-1235::/dev/scini1,vol-8973::/dev/scini2 +``` + +Note that the EBS driver's local device map appears to be incorrect with +the `DEVICE_PATH` used as the `VOLUME_ID` key. Some drivers, such as EBS, +actually provide a device path at the time a volume is attached, meaning +that the remote storage platform can map a volume based on a provided +device path. Thus for the EBS platform the device path is the piece of +information used to map to a remote volume as well as the path to which +said volume is attached as a device on a given client. + +This is in contrast to to the ScaleIO local devices map which uses +volume IDs unrelated to the device at which a volume is attached. + +#### Transaction ID The transaction ID is a UUID/GUID that is used to track an operation from the time it originates on a client, through the server, and back -to the client again. The header name is `libStorage-txID`: +to the client again. The header name is `Libstorage-Txid`: - libStorage-txID: 959716fa-6a76-4e48-6243-1dd328c0f313 +``` +Libstorage-Txid: 959716fa-6a76-4e48-6243-1dd328c0f313 +``` -### Transaction Created -The header `libStorage-txCR` is a UTC epoch timestamp that notes when +#### Transaction Created +The header `Libstorage-Txcr` is a UTC epoch timestamp that notes when the original client-side operation was created: - libStorage-txCR: 1461644872 +``` +Libstorage-Txcr: 1461644872 +``` + +### Response Headers +libStorage supports the following response headers: + +Name | Description +-----|------------ +`Libstorage-Instanceid` | A client's instance ID. +`Libstorage-Servername` | The server's name. + +Please note the header names are case sensitive and must comply with the above, +listed values. This is in adherence to the +[canonical header](https://golang.org/pkg/net/http/#CanonicalHeaderKey) format. + +#### Instance ID (Response) +Please see [this section](#def-instance-id) for more information. + +#### Server Name +The `Libstorage-Servername` header is returned with every response for +clients that use it for logging purposes. # Group Root @@ -124,24 +199,18 @@ Gets information about all of the configured services. + Body { - "ec2-00": { - "name": "ec2-00", + "ebs-00": { + "name": "ebs-00", "driver": { - "name": "ec2", - "type": "nas", - "executors": [ - { - "name": "ec2-linux-executor.sh", - "md5checksum": "d2794c0df5b907fdace235a619d80314" - } - ] + "name": "ebs", + "type": "block" } } } + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/serviceInfoMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/serviceInfoMap" } + Response 401 (application/json) Unauthorized request @@ -156,7 +225,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 500 (application/json) Internal server error @@ -171,13 +240,13 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } # Service Inspector [/services/{service}?{instance}] + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) + instance: `false` (boolean, optional) When the instance query string is specified the instance ID header @@ -194,22 +263,16 @@ Gets information about the service with the specified name. + Body { - "name": "ec2-00", + "name": "ebs-00", "driver": { - "name": "ec2", - "type": "nas", - "executors": [ - { - "name": "ec2-linux-executor.sh", - "md5checksum": "d2794c0df5b907fdace235a619d80314" - } - ] + "name": "ebs", + "type": "block" } } + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/serviceInfo" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/serviceInfo" } + Response 401 (application/json) Unauthorized request @@ -224,7 +287,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -239,7 +302,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -254,7 +317,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } # Group Executors A collection of resources and actions related to libStorage's client-side @@ -289,7 +352,7 @@ Gets the executors collection. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/executorInfoMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/executorInfoMap" } + Response 401 (application/json) Unauthorized request @@ -304,7 +367,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } ## Download [GET /executors/{executor}] Downloads an executor. @@ -336,7 +399,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -351,7 +414,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -366,7 +429,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ## Inspect [HEAD /executors/{executor}] Inspects an executor. This operation is functionally equivalent to downloading an executor, except the body is not returned, only the headers. @@ -403,7 +466,7 @@ Gets a list of Volume resources for all configured services. + Body { - "ec2-00": { + "ebs-00": { "vol-000": { "id": "vol-000", "name": "Volume-000", @@ -423,7 +486,7 @@ Gets a list of Volume resources for all configured services. } } }, - "ec2-01": { + "ebs-01": { "vol-000": { "id": "vol-000", "name": "Volume-000", @@ -438,7 +501,7 @@ Gets a list of Volume resources for all configured services. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + Response 401 (application/json) Unauthorized request @@ -453,7 +516,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 500 (application/json) Internal server error @@ -468,7 +531,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ## Get with Attachments [GET /volumes?{attachments}] Gets a list of Volume resources and their attached resources for all configured @@ -476,25 +539,43 @@ services. + Parameters - + attachments (required) - - A flag that indicates that volume attachments should be retrieved. - If this flag is provided then the `LibStorage-InstanceID` header must - be set -- a comma-delimited list of service name/instance ID, - colon-delimited pairs. + + attachments (string,optional) + + A value that indicates how and if volume attachments should be retrieved. +

+ The `attachments` parameter can be any of the following values: +
+ Value | Description + ------|------------ + 0 | No attachment information is requested. This is the default value and the same as omitting this parameter altogether. + 1 | Attachment information is requested. This value indicates attachment information should be returned for all volumes. + 2 | _My_ attachment information is requested. This value indicates attachment information should be returned for volumes attached to the instance specified in the [instance ID request header](#def-instance-id). If this bit is set then the instance ID header is required. + 4 | Attempt to map devices provided via the [local devices](#def-local-devices) request header to the appropriate attachment information. If this bit is set then the instance ID and local device headers are required. + 8 | Return only volumes that are attached. + 16 | Return only volumes that are unattached. +

+ The use of a bitmask for the `attachments` parameter means that + different combinations of the above values can be used to + indicate different results: +
+ Mask | Description + -----|------------ + 5 | A mask of `1|4` that indicates to return all volumes with their attachment data (if any) and perform a device mapping where possible. + 9 | A mask of `1|8` that indicates to return only volumes that are attached to some instance. + 10 | A mask of `2|8` that indicates to return only volumes attached to the instance provided via the instance ID header. + Request + Headers - libStorage-InstanceID: ec2-00:eyJpZCI6ImlpZC0wMDAiLCJtZXRhZGF0YSI6eyJtYXgiOjEwLCJtaW4iOjAsInJhZCI6ImNvb2wiLCJ0b3RhbGx5IjoidHVidWxhciJ9fQ==,ec2-01:eyJpZCI6ImlpZC0wMDEiLCJtZXRhZGF0YSI6eyJtYXgiOjIwLCJtaW4iOjUsInJhZCI6ImhvdCJ9fQ== + Libstorage-Instanceid: ebs-00=i-123,region%3Dwest,ebs-01:eyJpZCI6ImlpZC0wMDEiLCJtZXRhZGF0YSI6eyJtYXgiOjIwLCJtaW4iOjUsInJhZCI6ImhvdCJ9fQ== + Response 200 (application/json) + Body { - "ec2-00": { + "ebs-00": { "vol-000": { "id": "vol-000", "name": "Volume-000", @@ -532,7 +613,7 @@ services. } } }, - "ec2-01": { + "ebs-01": { "vol-000": { "id": "vol-000", "name": "Volume-000", @@ -556,7 +637,7 @@ services. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + Response 401 (application/json) Unauthorized request @@ -571,7 +652,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 500 (application/json) Internal server error @@ -586,7 +667,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ## Detach All [POST /volumes?{detach}] Detaches all volumes for all services. @@ -602,14 +683,14 @@ Detaches all volumes for all services. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volumeDetachAllRequest" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volumeDetachAllRequest" } + Response 200 (application/json) A list of the detached volumes. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + Response 400 (application/json) Invalid request @@ -624,7 +705,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -639,7 +720,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 500 (application/json) Internal server error @@ -654,13 +735,13 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } # Volumes by Service Collection [/volumes/{service}] + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The service name @@ -694,7 +775,7 @@ Gets a list of Volume objects for a single Service resource. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volumeMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volumeMap" } + Response 401 (application/json) Unauthorized request @@ -709,7 +790,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 500 (application/json) Internal server error @@ -724,7 +805,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ## Get with Attachments [GET /volumes/{service}?{attachments}] Gets a list of Volume resources and their attached resources for a single @@ -732,22 +813,40 @@ service. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The service name - + attachments (required) - - A flag that indicates that volume attachments should be retrieved. - If this flag is provided then the `LibStorage-InstanceID` header must - be set -- a comma-delimited list of service name/instance ID, - colon-delimited pairs. + + attachments (string,optional) + + A value that indicates how and if volume attachments should be retrieved. +

+ The `attachments` parameter can be any of the following values: +
+ Value | Description + ------|------------ + 0 | No attachment information is requested. This is the default value and the same as omitting this parameter altogether. + 1 | Attachment information is requested. This value indicates attachment information should be returned for all volumes. + 2 | _My_ attachment information is requested. This value indicates attachment information should be returned for volumes attached to the instance specified in the [instance ID request header](#def-instance-id). If this bit is set then the instance ID header is required. + 4 | Attempt to map devices provided via the [local devices](#def-local-devices) request header to the appropriate attachment information. If this bit is set then the instance ID and local device headers are required. + 8 | Return only volumes that are attached. + 16 | Return only volumes that are unattached. +

+ The use of a bitmask for the `attachments` parameter means that + different combinations of the above values can be used to + indicate different results: +
+ Mask | Description + -----|------------ + 5 | A mask of `1|4` that indicates to return all volumes with their attachment data (if any) and perform a device mapping where possible. + 9 | A mask of `1|8` that indicates to return only volumes that are attached to some instance. + 10 | A mask of `2|8` that indicates to return only volumes attached to the instance provided via the instance ID header. + Request + Headers - libStorage-InstanceID: ec2-00:eyJpZCI6ImlpZC0wMDAiLCJtZXRhZGF0YSI6eyJtYXgiOjEwLCJtaW4iOjAsInJhZCI6ImNvb2wiLCJ0b3RhbGx5IjoidHVidWxhciJ9fQ== + Libstorage-Instanceid: ebs-00=i-123,region%3Dwest + Response 200 (application/json) @@ -794,7 +893,7 @@ service. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + Response 401 (application/json) Unauthorized request @@ -809,7 +908,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 500 (application/json) Internal server error @@ -824,7 +923,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ## Create [POST] Create a new volume. @@ -853,7 +952,7 @@ Create a new volume. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volumeCreateRequest" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volumeCreateRequest" } + Response 200 (application/json) The newly created volume object. @@ -862,7 +961,7 @@ The newly created volume object. + Headers - Location: /volumes/ec2-00/vol-001 + Location: /volumes/ebs-00/vol-001 + Body @@ -878,7 +977,7 @@ The newly created volume object. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volume" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volume" } + Response 400 (application/json) Invalid request @@ -893,7 +992,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -908,7 +1007,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -923,7 +1022,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -938,14 +1037,14 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ## Detach All [POST /volumes/{service}?{detach}] Detaches all volumes for all services. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The service name @@ -958,14 +1057,14 @@ Detaches all volumes for all services. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volumeDetachAllRequest" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volumeDetachAllRequest" } + Response 200 (application/json) A list of the detached volumes. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/serviceVolumeMap" } + Response 400 (application/json) Invalid request @@ -980,7 +1079,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -995,7 +1094,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 500 (application/json) Internal server error @@ -1010,15 +1109,15 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } -## Volume Inspector [/volumes/{service}/{volumeID}] +## Volume Inspector [/volumes/{service}/{volumeID}?{attachments}] A single Volume object. A central part of the libStorage API, a Volume resource represents a storage volume. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The name of the service to which the Volume belongs @@ -1026,10 +1125,36 @@ API, a Volume resource represents a storage volume. The volume's unique ID + + attachments (string,optional) + + A value that indicates how and if volume attachments should be retrieved. +

+ The `attachments` parameter can be any of the following values: +
+ Value | Description + ------|------------ + 0 | No attachment information is requested. This is the default value and the same as omitting this parameter altogether. + 1 | Attachment information is requested. This value indicates attachment information should be returned for all volumes. + 2 | _My_ attachment information is requested. This value indicates attachment information should be returned for volumes attached to the instance specified in the [instance ID request header](#def-instance-id). If this bit is set then the instance ID header is required. + 4 | Attempt to map devices provided via the [local devices](#def-local-devices) request header to the appropriate attachment information. If this bit is set then the instance ID and local device headers are required. + 8 | Return only volumes that are attached. + 16 | Return only volumes that are unattached. +

+ The use of a bitmask for the `attachments` parameter means that + different combinations of the above values can be used to + indicate different results: +
+ Mask | Description + -----|------------ + 5 | A mask of `1|4` that indicates to return all volumes with their attachment data (if any) and perform a device mapping where possible. + 9 | A mask of `1|8` that indicates to return only volumes that are attached to some instance. + 10 | A mask of `2|8` that indicates to return only volumes attached to the instance provided via the instance ID header. + + ### Get [GET] Retrieves a single volume. -If the `libStorage-InstanceID` header is provided the volume's attachments are +If the `Libstorage-Instanceid` header is provided the volume's attachments are also retrieved. Unlike when retrieving Volume collections, there's no need to specify the `attachments` query parameter to request their retrieval. @@ -1037,7 +1162,7 @@ specify the `attachments` query parameter to request their retrieval. + Headers - libStorage-InstanceID: ec2-00:eyJpZCI6ImlpZC0wMDAiLCJtZXRhZGF0YSI6eyJtYXgiOjEwLCJtaW4iOjAsInJhZCI6ImNvb2wiLCJ0b3RhbGx5IjoidHVidWxhciJ9fQ== + Libstorage-Instanceid: ebs-00=i-123,region%3Dwest + Response 200 (application/json) @@ -1067,7 +1192,7 @@ specify the `attachments` query parameter to request their retrieval. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volume" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volume" } + Response 400 (application/json) Invalid request @@ -1082,7 +1207,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -1097,7 +1222,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -1112,7 +1237,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -1127,14 +1252,14 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ### Copy [POST /volumes/{service}/{volumeID}?{copy}] Copies the volume. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The name of the service to which the Volume belongs @@ -1156,7 +1281,7 @@ Copies the volume. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volumeCopyRequest" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volumeCopyRequest" } + Response 200 (application/json) @@ -1176,7 +1301,7 @@ Copies the volume. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volume" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volume" } + Response 400 (application/json) Invalid request @@ -1191,7 +1316,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -1206,7 +1331,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -1221,7 +1346,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -1236,14 +1361,14 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ### Snapshot [POST /volumes/{service}/{volumeID}?{snapshot}] Takes a snapshot of the volume. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The name of the service to which the Volume belongs @@ -1289,7 +1414,7 @@ Takes a snapshot of the volume. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/snapshot" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/snapshot" } + Response 400 (application/json) Invalid request @@ -1304,7 +1429,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -1319,7 +1444,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -1334,7 +1459,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -1349,14 +1474,14 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ### Attach [POST /volumes/{service}/{volumeID}?{attach}] Attaches the volume to an instance. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The name of the service to which the Volume belongs @@ -1377,7 +1502,7 @@ Attaches the volume to an instance. + Headers - libStorage-InstanceID: ec2-00:eyJpZCI6ImlpZC0wMDAiLCJtZXRhZGF0YSI6eyJtYXgiOjEwLCJtaW4iOjAsInJhZCI6ImNvb2wiLCJ0b3RhbGx5IjoidHVidWxhciJ9fQ== + Libstorage-Instanceid: ebs-00=i-123,region%3Dwest + Body @@ -1403,7 +1528,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -1418,7 +1543,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -1433,7 +1558,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -1448,7 +1573,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ### Detach [POST /volumes/{service}/{volumeID}?{detach}] @@ -1456,7 +1581,7 @@ Detaches the volume. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The name of the service to which the Volume belongs @@ -1479,7 +1604,7 @@ The volume that was just detached. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volume" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volume" } + Response 400 (application/json) Invalid request @@ -1494,7 +1619,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -1509,7 +1634,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -1524,7 +1649,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -1539,7 +1664,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ## Remove [DELETE] Removes the volume. @@ -1548,7 +1673,7 @@ Removes the volume. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/volumeRemoveRequest" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/volumeRemoveRequest" } + Response 205 Reset the view of the modified resource @@ -1568,7 +1693,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -1583,7 +1708,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -1598,7 +1723,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -1613,7 +1738,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } # Group Snapshots A collection of resources and actions related to libStorage Snapshots. @@ -1629,7 +1754,7 @@ Gets a list of Snapshot resources for all configured services. + Body { - "ec2-00": { + "ebs-00": { "snap-000": { "id": "snap-000", "name": "Snapshot-000", @@ -1655,7 +1780,7 @@ Gets a list of Snapshot resources for all configured services. } } }, - "ec2-01": { + "ebs-01": { "snap-000": { "id": "snap-000", "name": "Snapshot-000", @@ -1673,7 +1798,7 @@ Gets a list of Snapshot resources for all configured services. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/serviceSnapshotMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/serviceSnapshotMap" } + Response 401 (application/json) Unauthorized request @@ -1688,7 +1813,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 500 (application/json) Internal server error @@ -1703,14 +1828,14 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } # Snapshots by Service Collection [/snapshots/{service}] A collection of Snapshot resources that belong to Volumes for a specifc service. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The service name @@ -1750,7 +1875,7 @@ Gets a list of Snapshot objects for a single Service resource. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/snapshotMap" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/snapshotMap" } + Response 401 (application/json) Unauthorized request @@ -1765,7 +1890,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -1780,7 +1905,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -1795,7 +1920,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ## Create [POST] Please note, that the Snapshot Collection resource is not used for the creation @@ -1817,7 +1942,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -1832,7 +1957,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -1847,7 +1972,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -1862,7 +1987,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } # Snapshot Inspector [/snapshots/{service}/{snapshotID}] A single Snapshot object. A central part of the libStorage API, a Snapshot @@ -1870,7 +1995,7 @@ resource represents a snapshot of a storage volume. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The service name @@ -1900,7 +2025,7 @@ Retrieves a single snapshot. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/snapshot" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/snapshot" } + Response 400 (application/json) Invalid request @@ -1915,7 +2040,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -1930,7 +2055,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -1945,7 +2070,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -1960,14 +2085,14 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ### Copy [POST /snapshots/{service}/{snapshotID}?{copy}] Copies the snapshot. + Parameters - + service: `ec2-00` (string, required) + + service: `ebs-00` (string, required) The name of the service to which the Volume belongs @@ -1985,12 +2110,12 @@ Copies the snapshot. { "snapshotName": "Copy of Snapshot-000", - "destinationID": "ec2-01" + "destinationID": "ebs-01" } + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/snapshotCopyRequest" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/snapshotCopyRequest" } + Response 200 (application/json) @@ -2013,7 +2138,7 @@ Copies the snapshot. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/snapshot" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/snapshot" } + Response 400 (application/json) Invalid request @@ -2028,7 +2153,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -2043,7 +2168,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -2058,7 +2183,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -2073,7 +2198,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } ## Remove [DELETE] Removes the snapshot. @@ -2082,7 +2207,7 @@ Removes the snapshot. + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/snapshotRemoveRequest" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/snapshotRemoveRequest" } + Response 205 Reset the view of the modified resource @@ -2102,7 +2227,7 @@ Invalid request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/invalidRequestError" } + Response 401 (application/json) Unauthorized request @@ -2117,7 +2242,7 @@ Unauthorized request + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/unauthorizedRequestError" } + Response 404 (application/json) The specified resource was not found @@ -2132,7 +2257,7 @@ The specified resource was not found + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/resourceNotFoundError" } + Response 500 (application/json) Internal server error @@ -2147,7 +2272,7 @@ Internal server error + Schema - { "$ref": "https://raw.githubusercontent.com/emccode/libstorage/master/libstorage.json#/definitions/internalServerError" } + { "$ref": "https://raw.githubusercontent.com/codedellemc/libstorage/master/libstorage.json#/definitions/internalServerError" } # Data Structures