Skip to content

Commit

Permalink
Merge pull request #1 from narkarum/v2
Browse files Browse the repository at this point in the history
v2 changes
  • Loading branch information
narkarum authored Oct 7, 2019
2 parents 600232f + 9dac91c commit 87f3e12
Show file tree
Hide file tree
Showing 12 changed files with 345 additions and 41 deletions.
4 changes: 2 additions & 2 deletions volume-providers/vpc/iks/provider/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ var _ provider.Session = &IksVpcSession{}

const (
// Provider storage provider
Provider = provider.VolumeProvider("IKS-VPC-BLOCK")
Provider = provider.VolumeProvider("IKS-VPC-Block")
// VolumeType ...
VolumeType = provider.VolumeType("vpc-block")
VolumeType = provider.VolumeType("VPC-Block")
)

// Close at present does nothing
Expand Down
2 changes: 1 addition & 1 deletion volume-providers/vpc/provider/get_volume_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (vpcs *VPCSession) GetVolumeAttachment(volumeAttachmentRequest provider.Vol
var volumeAttachmentResponse *provider.VolumeAttachmentResponse
volumeAttachment := models.NewVolumeAttachment(volumeAttachmentRequest)
if len(volumeAttachment.ID) > 0 {
//Get volume attachmet by ID if its specified
//Get volume attachmet by ID if it is specified
volumeAttachmentResponse, err = vpcs.getVolumeAttachmentByID(volumeAttachment)
} else {
// Get volume attachment by Volume ID. This is inefficient operation which requires iteration over volume attachment list
Expand Down
30 changes: 23 additions & 7 deletions volume-providers/vpc/vpcclient/instances/attach_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,35 @@ func (vs *VolumeAttachService) AttachVolume(volumeAttachmentTemplate *models.Vol
defer util.TimeTracker("AttachVolume", time.Now())

operation := &client.Operation{
Name: "AttachVolume",
Method: "POST",
PathPattern: vs.pathPrefix + instanceIDvolumeAttachmentPath,
Name: "AttachVolume",
Method: "POST",
}
if vs.isIKSENabled {
operation.PathPattern = vs.pathPrefix + "createAttachment"
} else {
operation.PathPattern = vs.pathPrefix + instanceIDvolumeAttachmentPath
}

var volumeAttachment models.VolumeAttachment
apiErr := vs.receiverError

request := vs.client.NewRequest(operation)
ctxLogger.Info("Equivalent curl command and payload details", zap.Reflect("URL", request.URL()), zap.Reflect("Payload", volumeAttachmentTemplate), zap.Reflect("Operation", operation), zap.Reflect("PathParameters", volumeAttachmentTemplate.InstanceID))
_, err := vs.populatePathPrefixParameters(request, volumeAttachmentTemplate).JSONBody(volumeAttachmentTemplate).JSONSuccess(&volumeAttachment).JSONError(apiErr).Invoke()
if err != nil {
return nil, err
if vs.isIKSENabled {
request = request.AddQueryValue(IksClusterQuery, *volumeAttachmentTemplate.ClusterID)
request = request.AddQueryValue(IksWorkerQuery, *volumeAttachmentTemplate.InstanceID)
vol := *volumeAttachmentTemplate.Volume
request = request.AddQueryValue(IksVolumeQuery, vol.ID)
ctxLogger.Info("Equivalent curl command details and query parameters", zap.Reflect("URL", request.URL()), zap.Reflect("Payload", volumeAttachmentTemplate), zap.Reflect("Operation", operation), zap.Reflect(IksClusterQuery, volumeAttachmentTemplate.InstanceID), zap.Reflect(IksWorkerQuery, volumeAttachmentTemplate.InstanceID), zap.Reflect(IksVolumeQuery, vol.ID))
_, err := request.JSONBody(volumeAttachmentTemplate).JSONSuccess(&volumeAttachment).JSONError(apiErr).Invoke()
if err != nil {
return nil, err
}
} else {
ctxLogger.Info("Equivalent curl command and payload details", zap.Reflect("URL", request.URL()), zap.Reflect("Payload", volumeAttachmentTemplate), zap.Reflect("Operation", operation), zap.Reflect("PathParameters", volumeAttachmentTemplate.InstanceID))
_, err := vs.populatePathPrefixParameters(request, volumeAttachmentTemplate).JSONBody(volumeAttachmentTemplate).JSONSuccess(&volumeAttachment).JSONError(apiErr).Invoke()
if err != nil {
return nil, err
}
}

return &volumeAttachment, nil
Expand Down
40 changes: 40 additions & 0 deletions volume-providers/vpc/vpcclient/instances/attach_volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,50 @@ func TestAttachVolume(t *testing.T) {
assert.NoError(t, err)
assert.NotNil(t, volumeAttachment)
}

})
}
}

func TestIKSAttachVolume(t *testing.T) {
// Setup new style zap logger
logger, _ := GetTestContextLogger()
defer logger.Sync()

instanceID := "testinstance"
clusterID := "testcluster"
// IKS tests
mux, client, teardown := test.SetupServer(t)

content := "{\"id\":\"volume attachment id\", \"name\":\"volume attachment\", \"device\": {\"id\":\"xvdc\"}, \"volume\": {\"id\":\"volume-id\",\"name\":\"volume-name\",\"capacity\":10,\"iops\":3000,\"status\":\"pending\"}}"

test.SetupMuxResponse(t, mux, "/v2/storage/createAttachment", http.MethodPost, nil, http.StatusOK, content, nil)
volumeAttachService := instances.NewIKSVolumeAttachmentManager(client)

template := &models.VolumeAttachment{
Name: "volume attachment",
ClusterID: &clusterID,
InstanceID: &instanceID,
Volume: &models.Volume{
ID: "volume-id",
Name: "volume-name",
Capacity: 10,
ResourceGroup: &models.ResourceGroup{
ID: "rg1",
},
Generation: models.GenerationType("gc"),
Zone: &models.Zone{Name: "test-1"},
},
}
defer teardown()

volumeAttachment, err := volumeAttachService.AttachVolume(template, logger)
logger.Info("Volume attachment details", zap.Reflect("volumeAttachment", volumeAttachment))

assert.NoError(t, err)
assert.NotNil(t, volumeAttachment)
}

func GetTestContextLogger() (*zap.Logger, zap.AtomicLevel) {
consoleDebugging := zapcore.Lock(os.Stdout)
consoleErrors := zapcore.Lock(os.Stderr)
Expand Down
14 changes: 14 additions & 0 deletions volume-providers/vpc/vpcclient/instances/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,18 @@ const (
volumeAttachmentPath = "volume_attachments"
instanceIDvolumeAttachmentPath = instanceIDPath + "/" + volumeAttachmentPath
instanceIDattachmentIDPath = instanceIDvolumeAttachmentPath + "/{" + attachmentIDParam + "}"

// VpcPathPrefix VPC URL path prefix
VpcPathPrefix = "v1/instances"

// IksPathPrefix IKS URL path prefix
IksPathPrefix = "v2/storage/"
// IksClusterQuery ...
IksClusterQuery = "cluster"
// IksWorkerQuery ...
IksWorkerQuery = "worker"
// IksVolumeQuery ...
IksVolumeQuery = "volume"
// IksVolumeAttachmentIDQuery ...
IksVolumeAttachmentIDQuery = "volumeattachmentid"
)
27 changes: 20 additions & 7 deletions volume-providers/vpc/vpcclient/instances/detach_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,39 @@ func (vs *VolumeAttachService) DetachVolume(volumeAttachmentTemplate *models.Vol
defer util.TimeTracker("DetachVolume", time.Now())

operation := &client.Operation{
Name: "DetachVolume",
Method: "DELETE",
PathPattern: vs.pathPrefix + instanceIDattachmentIDPath,
Name: "DetachVolume",
Method: "DELETE",
}

if vs.isIKSENabled {
operation.PathPattern = vs.pathPrefix + "deleteAttachment"
} else {
operation.PathPattern = vs.pathPrefix + instanceIDattachmentIDPath
}

apiErr := vs.receiverError

request := vs.client.NewRequest(operation)
ctxLogger.Info("Equivalent curl command details", zap.Reflect("URL", request.URL()), zap.Reflect("volumeAttachmentTemplate", volumeAttachmentTemplate), zap.Reflect("Operation", operation))
ctxLogger.Info("Pathparameters", zap.Reflect(instanceIDParam, volumeAttachmentTemplate.InstanceID), zap.Reflect(attachmentIDParam, volumeAttachmentTemplate.ID))
req := vs.populatePathPrefixParameters(request, volumeAttachmentTemplate)
req = request.PathParameter(attachmentIDParam, volumeAttachmentTemplate.ID)
resp, err := req.JSONError(apiErr).Invoke()
if vs.isIKSENabled {
ctxLogger.Info("Equivalent curl command details and query parameters", zap.Reflect(IksClusterQuery, *volumeAttachmentTemplate.ClusterID), zap.Reflect(clusterIDParam, *volumeAttachmentTemplate.InstanceID), zap.Reflect(IksVolumeAttachmentIDQuery, volumeAttachmentTemplate.ID))
request = request.AddQueryValue(IksClusterQuery, *volumeAttachmentTemplate.ClusterID)
request = request.AddQueryValue(clusterIDParam, *volumeAttachmentTemplate.InstanceID)
request = request.AddQueryValue(IksVolumeAttachmentIDQuery, volumeAttachmentTemplate.ID)
} else {
ctxLogger.Info("Pathparameters", zap.Reflect(instanceIDParam, volumeAttachmentTemplate.InstanceID), zap.Reflect(attachmentIDParam, volumeAttachmentTemplate.ID))
request = vs.populatePathPrefixParameters(request, volumeAttachmentTemplate)
request = request.PathParameter(attachmentIDParam, volumeAttachmentTemplate.ID)
}
resp, err := request.JSONError(apiErr).Invoke()
if err != nil {
ctxLogger.Error("Error occured while deleting volume attachment", zap.Error(err))
if resp != nil && resp.StatusCode == http.StatusNotFound {
// volume Attachment is deleted. So do not want to retry
return resp, apiErr
}
}

ctxLogger.Info("Successfuly deleted the volume attachment")
return resp, err
}
37 changes: 37 additions & 0 deletions volume-providers/vpc/vpcclient/instances/detach_volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,40 @@ func TestDetachVolume(t *testing.T) {
})
}
}

func TestIKSDetachVolume(t *testing.T) {
// Setup new style zap logger
logger, _ := GetTestContextLogger()
defer logger.Sync()

instanceID := "testinstance"
clusterID := "testcluster"
// IKS tests
mux, client, teardown := test.SetupServer(t)

test.SetupMuxResponse(t, mux, "/v2/storage/deleteAttachment", http.MethodDelete, nil, http.StatusOK, "", nil)
volumeAttachService := instances.NewIKSVolumeAttachmentManager(client)

template := &models.VolumeAttachment{
ID: "volume attachment id",
Name: "volume attachment",
ClusterID: &clusterID,
InstanceID: &instanceID,
Volume: &models.Volume{
ID: "volume-id",
Name: "volume-name",
Capacity: 10,
ResourceGroup: &models.ResourceGroup{
ID: "rg1",
},
Generation: models.GenerationType("gc"),
Zone: &models.Zone{Name: "test-1"},
},
}
defer teardown()

response, err := volumeAttachService.DetachVolume(template, logger)

assert.NoError(t, err)
assert.NotNil(t, response)
}
26 changes: 20 additions & 6 deletions volume-providers/vpc/vpcclient/instances/get_volume_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,36 @@ import (

// GetVolumeAttachment retrives the volume attach status with given volume attachment details
func (vs *VolumeAttachService) GetVolumeAttachment(volumeAttachmentTemplate *models.VolumeAttachment, ctxLogger *zap.Logger) (*models.VolumeAttachment, error) {
defer util.TimeTracker("DetachVolume", time.Now())
defer util.TimeTracker("GetVolumeAttachment", time.Now())

operation := &client.Operation{
Name: "GetVolumeAttachment",
Method: "GET",
PathPattern: vs.pathPrefix + instanceIDattachmentIDPath,
}

if vs.isIKSENabled {
operation.PathPattern = vs.pathPrefix + "getAttachment"
} else {
operation.PathPattern = vs.pathPrefix + instanceIDattachmentIDPath
}

apiErr := vs.receiverError
var volumeAttachment models.VolumeAttachment
request := vs.client.NewRequest(operation)
ctxLogger.Info("Equivalent curl command details", zap.Reflect("URL", request.URL()), zap.Reflect("volumeAttachmentTemplate", volumeAttachmentTemplate), zap.Reflect("Operation", operation))
ctxLogger.Info("Pathparameters", zap.Reflect(instanceIDParam, volumeAttachmentTemplate.InstanceID), zap.Reflect(attachmentIDParam, volumeAttachmentTemplate.ID))
req := vs.populatePathPrefixParameters(request, volumeAttachmentTemplate)
req = request.PathParameter(attachmentIDParam, volumeAttachmentTemplate.ID)
_, err := req.JSONSuccess(&volumeAttachment).JSONError(apiErr).Invoke()
if vs.isIKSENabled {
ctxLogger.Info("Equivalent curl command details and query parameters", zap.Reflect(IksClusterQuery, *volumeAttachmentTemplate.ClusterID), zap.Reflect(clusterIDParam, *volumeAttachmentTemplate.InstanceID), zap.Reflect(IksVolumeAttachmentIDQuery, volumeAttachmentTemplate.ID))
request = request.AddQueryValue(IksClusterQuery, *volumeAttachmentTemplate.ClusterID)
request = request.AddQueryValue(clusterIDParam, *volumeAttachmentTemplate.InstanceID)
request = request.AddQueryValue(IksVolumeAttachmentIDQuery, volumeAttachmentTemplate.ID)
} else {
ctxLogger.Info("Equivalent curl command details", zap.Reflect("URL", request.URL()), zap.Reflect("volumeAttachmentTemplate", volumeAttachmentTemplate), zap.Reflect("Operation", operation))
ctxLogger.Info("Pathparameters", zap.Reflect(instanceIDParam, volumeAttachmentTemplate.InstanceID), zap.Reflect(attachmentIDParam, volumeAttachmentTemplate.ID))
request = vs.populatePathPrefixParameters(request, volumeAttachmentTemplate)
request = request.PathParameter(attachmentIDParam, volumeAttachmentTemplate.ID)
}

_, err := request.JSONSuccess(&volumeAttachment).JSONError(apiErr).Invoke()
if err != nil {
ctxLogger.Error("Error occured while getting volume attachment", zap.Error(err))
return nil, err
Expand Down
130 changes: 130 additions & 0 deletions volume-providers/vpc/vpcclient/instances/get_volume_attachment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*******************************************************************************
* IBM Confidential
* OCO Source Materials
* IBM Cloud Container Service, 5737-D43
* (C) Copyright IBM Corp. 2018 All Rights Reserved.
* The source code for this program is not published or otherwise divested of
* its trade secrets, irrespective of what has been deposited with
* the U.S. Copyright Office.
******************************************************************************/

package instances_test

import (
"github.com/IBM/ibmcloud-storage-volume-lib/volume-providers/vpc/vpcclient/instances"
"github.com/IBM/ibmcloud-storage-volume-lib/volume-providers/vpc/vpcclient/models"
"github.com/IBM/ibmcloud-storage-volume-lib/volume-providers/vpc/vpcclient/riaas/test"
"github.com/stretchr/testify/assert"
"go.uber.org/zap"
"net/http"
"testing"
)

func TestGetVolumeAttachment(t *testing.T) {
// Setup new style zap logger
logger, _ := GetTestContextLogger()
defer logger.Sync()

instanceID := "testinstance"

testCases := []struct {
name string

// Response
status int
content string

// Expected return
expectErr string
verify func(*testing.T, *http.Response, error)
}{
{
name: "Verify that the get volume attachment is done correctly",
status: http.StatusOK,
content: "{\"id\":\"volumeattachmentid\", \"name\":\"volume attachment\", \"device\": {\"id\":\"xvdc\"}, \"volume\": {\"id\":\"volume-id\",\"name\":\"volume-name\",\"capacity\":10,\"iops\":3000,\"status\":\"pending\"}}",
verify: func(t *testing.T, httpResponse *http.Response, err error) {
if assert.Nil(t, err) {
assert.Nil(t, httpResponse)
}
},
},
}

for _, testcase := range testCases {
t.Run(testcase.name, func(t *testing.T) {

template := &models.VolumeAttachment{
ID: "volumeattachmentid",
Name: "volumeattachment",
InstanceID: &instanceID,
Volume: &models.Volume{
ID: "volume-id",
Name: "volume-name",
Capacity: 10,
ResourceGroup: &models.ResourceGroup{
ID: "rg1",
},
Generation: models.GenerationType("gc"),
Zone: &models.Zone{Name: "test-1"},
},
}

mux, client, teardown := test.SetupServer(t)
test.SetupMuxResponse(t, mux, "/v1/instances/testinstance/volume_attachments/volumeattachmentid", http.MethodGet, nil, testcase.status, testcase.content, nil)

defer teardown()

logger.Info("Test case being executed", zap.Reflect("testcase", testcase.name))

volumeAttachService := instances.New(client)

response, err := volumeAttachService.GetVolumeAttachment(template, logger)

if testcase.expectErr != "" && assert.Error(t, err) {
assert.Equal(t, testcase.expectErr, err.Error())
assert.NotNil(t, response)
} else {
assert.NoError(t, err)
assert.NotNil(t, response)
}
})
}
}

func TestIKSGetVolumeAttachment(t *testing.T) {
// Setup new style zap logger
logger, _ := GetTestContextLogger()
defer logger.Sync()

instanceID := "testinstance"
clusterID := "testcluster"
// IKS tests
mux, client, teardown := test.SetupServer(t)
content := "{\"id\":\"volumeattachmentid\", \"name\":\"volume attachment\", \"device\": {\"id\":\"xvdc\"}, \"volume\": {\"id\":\"volume-id\",\"name\":\"volume-name\",\"capacity\":10,\"iops\":3000,\"status\":\"pending\"}}"

test.SetupMuxResponse(t, mux, "/v2/storage/getAttachment", http.MethodGet, nil, http.StatusOK, content, nil)
volumeAttachService := instances.NewIKSVolumeAttachmentManager(client)

template := &models.VolumeAttachment{
ID: "volumeattachmentid",
Name: "volume attachment",
ClusterID: &clusterID,
InstanceID: &instanceID,
Volume: &models.Volume{
ID: "volume-id",
Name: "volume-name",
Capacity: 10,
ResourceGroup: &models.ResourceGroup{
ID: "rg1",
},
Generation: models.GenerationType("gc"),
Zone: &models.Zone{Name: "test-1"},
},
}
defer teardown()

response, err := volumeAttachService.GetVolumeAttachment(template, logger)

assert.NoError(t, err)
assert.NotNil(t, response)
}
Loading

0 comments on commit 87f3e12

Please sign in to comment.