Skip to content

Commit

Permalink
SnapshotCreate and SnapshotGet for FCD (#344)
Browse files Browse the repository at this point in the history
* Snapshot create for FCD

* SnapshotGet implementation

* Add more error check and test

* Nil check in conversion functions

* Make error messages consistent
  • Loading branch information
Hakan Memisoglu authored and mergify[bot] committed Oct 10, 2019
1 parent afdf547 commit d8d0d0b
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 4 deletions.
37 changes: 36 additions & 1 deletion pkg/blockstorage/vmware/conversion.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package vmware

import (
"strings"

"github.com/pkg/errors"
"github.com/vmware/govmomi/vim25/types"

"github.com/kanisterio/kanister/pkg/blockstorage"
)

func convertFromObjectToVolume(vso *types.VStorageObject) *blockstorage.Volume {
func convertFromObjectToVolume(vso *types.VStorageObject) (*blockstorage.Volume, error) {
if vso == nil {
return nil, errors.New("Empty object")
}
return &blockstorage.Volume{
Type: blockstorage.TypeFCD,
ID: vso.Config.Id.Id,
Expand All @@ -18,7 +24,21 @@ func convertFromObjectToVolume(vso *types.VStorageObject) *blockstorage.Volume {
VolumeType: "",
Tags: blockstorage.VolumeTags{},
Attributes: map[string]string{},
}, nil
}

func convertFromObjectToSnapshot(vso *types.VStorageObjectSnapshotInfoVStorageObjectSnapshot, volID string) (*blockstorage.Snapshot, error) {
if vso == nil {
return nil, errors.New("Empty opbject")
}
return &blockstorage.Snapshot{
Type: blockstorage.TypeFCD,
CreationTime: blockstorage.TimeStamp(vso.CreateTime),
ID: snapshotFullID(volID, vso.Id.Id),
Size: 0,
Region: "",
Encrypted: false,
}, nil
}

// vimID wraps ID string with vim25.ID struct.
Expand All @@ -28,6 +48,21 @@ func vimID(id string) types.ID {
}
}

func snapshotFullID(volID, snapshotID string) string {
return volID + ":" + snapshotID
}

func splitSnapshotFullID(fullID string) (volID string, snapshotID string, err error) {
split := strings.Split(fullID, ":")
if len(split) != 2 {
return "", "", errors.New("Malformed full ID for snapshot")
}
if len(split[0]) == 0 || len(split[1]) == 0 {
return "", "", errors.New("Malformed volume ID or snapshot ID")
}
return split[0], split[1], nil
}

func convertKeyValueToTags(kvs []types.KeyValue) []*blockstorage.KeyValue {
tags := make(map[string]string)
for _, kv := range kvs {
Expand Down
40 changes: 40 additions & 0 deletions pkg/blockstorage/vmware/conversion_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package vmware

import (
. "gopkg.in/check.v1"
)

type VMWareConversionSuite struct{}

var _ = Suite(&VMWareConversionSuite{})

func (s *VMWareConversionSuite) TestSnapshotIDConversion(c *C) {
for _, tc := range []struct {
fullID string
errCheck Checker
}{
{
fullID: "1234-abcd-5678-9213:3413-abcd-1234-1234",
errCheck: IsNil,
},
{
fullID: "1234-abcd-5678-9213:",
errCheck: NotNil,
},
{
fullID: ":3413-abcd-1234-1234",
errCheck: NotNil,
},
{
fullID: "1234-abcd-5678-9213",
errCheck: NotNil,
},
} {
volID, snapID, err := splitSnapshotFullID(tc.fullID)
c.Check(err, tc.errCheck)
if tc.errCheck == IsNil {
fullID := snapshotFullID(volID, snapID)
c.Check(tc.fullID, Equals, fullID)
}
}
}
50 changes: 47 additions & 3 deletions pkg/blockstorage/vmware/vmware.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package vmware

import (
"context"
"time"

"github.com/pkg/errors"
"github.com/vmware/govmomi/cns"
Expand All @@ -16,6 +17,11 @@ import (

var _ blockstorage.Provider = (*fcdProvider)(nil)

const (
noDescription = ""
defaultWaitTime = 10 * time.Minute
)

type fcdProvider struct {
gom *vslm.GlobalObjectManager
cns *cns.Client
Expand Down Expand Up @@ -80,7 +86,10 @@ func (p *fcdProvider) VolumeGet(ctx context.Context, id string, zone string) (*b
if err != nil {
return nil, errors.Wrap(err, "Failed to get volume metadata")
}
vol := convertFromObjectToVolume(obj)
vol, err := convertFromObjectToVolume(obj)
if err != nil {
return nil, errors.Wrap(err, "Failed to convert object to volume")
}
vol.Tags = convertKeyValueToTags(kvs)
return vol, nil
}
Expand All @@ -90,7 +99,19 @@ func (p *fcdProvider) SnapshotCopy(ctx context.Context, from blockstorage.Snapsh
}

func (p *fcdProvider) SnapshotCreate(ctx context.Context, volume blockstorage.Volume, tags map[string]string) (*blockstorage.Snapshot, error) {
return nil, errors.New("Not implemented")
task, err := p.gom.CreateSnapshot(ctx, vimID(volume.ID), noDescription)
if err != nil {
return nil, errors.Wrap(err, "Failed to create snapshot")
}
res, err := task.Wait(ctx, defaultWaitTime)
if err != nil {
return nil, errors.Wrap(err, "Failed to wait on task")
}
id, ok := res.(types.ID)
if !ok {
return nil, errors.New("Unexpected type")
}
return p.SnapshotGet(ctx, snapshotFullID(volume.ID, id.Id))
}

func (p *fcdProvider) SnapshotCreateWaitForCompletion(ctx context.Context, snapshot *blockstorage.Snapshot) error {
Expand All @@ -102,7 +123,30 @@ func (p *fcdProvider) SnapshotDelete(ctx context.Context, snapshot *blockstorage
}

func (p *fcdProvider) SnapshotGet(ctx context.Context, id string) (*blockstorage.Snapshot, error) {
return nil, errors.New("Not implemented")
volID, snapshotID, err := splitSnapshotFullID(id)
if err != nil {
return nil, errors.Wrap(err, "Cannot infer volume ID from full snapshot ID")
}
results, err := p.gom.RetrieveSnapshotInfo(ctx, vimID(volID))
if err != nil {
return nil, errors.Wrap(err, "Failed to get snapshot info")
}
for _, result := range results {
if result.Id.Id == snapshotID {
snapshot, err := convertFromObjectToSnapshot(&result, volID)
if err != nil {
return nil, errors.Wrap(err, "Failed to convert object to snapshot")
}
snapID := vimID(snapshotID)
kvs, err := p.gom.RetrieveMetadata(ctx, vimID(volID), &snapID, "")
if err != nil {
return nil, errors.Wrap(err, "Failed to get snapshot metadata")
}
snapshot.Tags = convertKeyValueToTags(kvs)
return snapshot, nil
}
}
return nil, errors.New("Failed to find snapshot")
}

func (p *fcdProvider) SetTags(ctx context.Context, resource interface{}, tags map[string]string) error {
Expand Down
9 changes: 9 additions & 0 deletions pkg/blockstorage/vmware/vmware_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package vmware

import (
"testing"

. "gopkg.in/check.v1"
)

func Test(t *testing.T) { TestingT(t) }

0 comments on commit d8d0d0b

Please sign in to comment.