Skip to content

Commit

Permalink
Code changes for SC parameters - zone and region (#67)
Browse files Browse the repository at this point in the history
* Changes to accomodate region in sc

* changes for region sc parameter

* cleanup comment

* Review comments

* Review comments
  • Loading branch information
ambiknai committed Feb 15, 2022
1 parent 9c48652 commit 11716e6
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 6 deletions.
18 changes: 14 additions & 4 deletions pkg/ibmcsidriver/controller_helper.go
Expand Up @@ -251,16 +251,26 @@ func getVolumeParameters(logger *zap.Logger, req *csi.CreateVolumeRequest, confi
volume.Iops = nil
}

//If the zone is not provided in storage class parameters then we pick from the Topology
if len(strings.TrimSpace(volume.Az)) == 0 {
//if zone is not given in SC parameters, but region is given, error out
if len(strings.TrimSpace(volume.Az)) == 0 && len(strings.TrimSpace(volume.Region)) != 0 {
err = fmt.Errorf("zone parameter is empty in storage class for region %s", strings.TrimSpace(volume.Region))
return volume, err
}

//If both zone and region not provided in storage class parameters then we pick from the Topology
//if zone is provided but region is not provided, fetch region for specified zone
if len(strings.TrimSpace(volume.Region)) == 0 {
zones, err := pickTargetTopologyParams(req.GetAccessibilityRequirements())
if err != nil {
err = fmt.Errorf("unable to fetch zone information: '%v'", err)
err = fmt.Errorf("unable to fetch zone information from topology: '%v'", err)
logger.Error("getVolumeParameters", zap.NamedError("InvalidParameter", err))
return volume, err
}
volume.Region = zones[utils.NodeRegionLabel]
volume.Az = zones[utils.NodeZoneLabel]
if len(strings.TrimSpace(volume.Az)) == 0 {
volume.Az = zones[utils.NodeZoneLabel]
}

}

return volume, nil
Expand Down
69 changes: 67 additions & 2 deletions pkg/ibmcsidriver/controller_helper_test.go
Expand Up @@ -135,15 +135,14 @@ func TestAreVolumeCapabilitiesSupported(t *testing.T) {
}
}

func isVolumeSame(actual *provider.Volume, expected *provider.Volume) bool {
func isVolumeSame(expected *provider.Volume, actual *provider.Volume) bool {
if actual == nil && expected == nil {
return true
}

if actual == nil || expected == nil {
return false
}

return *actual.Name == *expected.Name &&
*actual.Capacity == *expected.Capacity &&
actual.Az == expected.Az &&
Expand Down Expand Up @@ -301,6 +300,72 @@ func TestGetVolumeParameters(t *testing.T) {
expectedStatus: true,
expectedError: fmt.Errorf("volume capabilities are empty"),
},
{
testCaseName: "Region present but zone not given as parameter",
request: &csi.CreateVolumeRequest{Name: volumeName, CapacityRange: &csi.CapacityRange{RequiredBytes: 11811160064, LimitBytes: utils.MinimumVolumeSizeInBytes + utils.MinimumVolumeSizeInBytes},
VolumeCapabilities: []*csi.VolumeCapability{{AccessMode: &csi.VolumeCapability_AccessMode{Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER}}},
Parameters: map[string]string{Profile: "general-purpose",
Region: "us-south-test",
Tag: "test-tag",
ResourceGroup: "myresourcegroups",
Encrypted: "false",
EncryptionKey: "key",
ClassVersion: "",
Generation: "generation",
IOPS: noIops,
},
},
expectedVolume: &provider.Volume{Name: &volumeName,
Capacity: &volumeSize,
VPCVolume: provider.VPCVolume{VPCBlockVolume: provider.VPCBlockVolume{
Tags: []string{createdByIBM},
},
Profile: &provider.Profile{Name: "general-purpose"},
ResourceGroup: &provider.ResourceGroup{ID: "myresourcegroups"},
},
Region: "us-south-test",
Iops: &noIops,
Az: "testzone",
},
expectedStatus: true,
expectedError: fmt.Errorf("zone parameter is empty in storage class for region us-south-test"),
},
{
testCaseName: "Region and Zone not given as parameter from SC",
request: &csi.CreateVolumeRequest{Name: volumeName, CapacityRange: &csi.CapacityRange{RequiredBytes: 11811160064, LimitBytes: utils.MinimumVolumeSizeInBytes + utils.MinimumVolumeSizeInBytes},
VolumeCapabilities: []*csi.VolumeCapability{{AccessMode: &csi.VolumeCapability_AccessMode{Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER}}},
Parameters: map[string]string{Profile: "general-purpose",
Tag: "test-tag",
ResourceGroup: "myresourcegroups",
Encrypted: "false",
EncryptionKey: "key",
ClassVersion: "",
Generation: "generation",
IOPS: noIops,
},
AccessibilityRequirements: &csi.TopologyRequirement{Preferred: []*csi.Topology{{Segments: map[string]string{
utils.NodeRegionLabel: "myregion",
utils.NodeZoneLabel: "myzone",
},
},
},
},
},
expectedVolume: &provider.Volume{Name: &volumeName,
Capacity: &volumeSize,
VPCVolume: provider.VPCVolume{VPCBlockVolume: provider.VPCBlockVolume{
Tags: []string{createdByIBM},
},
Profile: &provider.Profile{Name: "general-purpose"},
ResourceGroup: &provider.ResourceGroup{ID: "myresourcegroups"},
},
Region: "myregion",
Iops: &noIops,
Az: "myzone",
},
expectedStatus: true,
expectedError: nil,
},
}

// Set up
Expand Down
58 changes: 58 additions & 0 deletions pkg/ibmcsidriver/controller_test.go
Expand Up @@ -196,6 +196,64 @@ func TestCreateVolumeArguments(t *testing.T) {
libVolumeResponse: nil,
libVolumeError: providerError.Message{Code: "FailedToPlaceOrder", Description: "Volume creation failed", Type: providerError.Unauthenticated},
},
{
name: "Zone provided but region not provided as parameter",
req: &csi.CreateVolumeRequest{
Name: volName,
CapacityRange: stdCapRange,
VolumeCapabilities: stdVolCap,
Parameters: map[string]string{
//"type": "ext2",
Profile: "general-purpose",
Zone: "myzone",
},
AccessibilityRequirements: &csi.TopologyRequirement{Preferred: []*csi.Topology{{Segments: map[string]string{
utils.NodeRegionLabel: "myregion",
utils.NodeZoneLabel: "myzone",
},
},
},
},
},
expVol: &csi.Volume{
CapacityBytes: 20 * 1024 * 1024 * 1024, // In byte
VolumeId: "testVolumeId",
VolumeContext: map[string]string{utils.NodeRegionLabel: "myregion", utils.NodeZoneLabel: "myzone", VolumeIDLabel: "testVolumeId", Tag: "", VolumeCRNLabel: "", ClusterIDLabel: ""},
AccessibleTopology: stdTopology,
},
libVolumeResponse: &provider.Volume{Capacity: &cap, Name: &volName, VolumeID: "testVolumeId", Iops: &iopsStr, Az: "myzone", Region: "myregion"},
expErrCode: codes.OK,
libVolumeError: nil,
},

{
name: "Zone and region not provided as parameter",
req: &csi.CreateVolumeRequest{
Name: volName,
CapacityRange: stdCapRange,
VolumeCapabilities: stdVolCap,
Parameters: map[string]string{
//"type": "ext2",
Profile: "general-purpose",
},
AccessibilityRequirements: &csi.TopologyRequirement{Preferred: []*csi.Topology{{Segments: map[string]string{
utils.NodeRegionLabel: "myregion",
utils.NodeZoneLabel: "myzone",
},
},
},
},
},
expVol: &csi.Volume{
CapacityBytes: 20 * 1024 * 1024 * 1024, // In byte
VolumeId: "testVolumeId",
VolumeContext: map[string]string{utils.NodeRegionLabel: "myregion", utils.NodeZoneLabel: "myzone", VolumeIDLabel: "testVolumeId", Tag: "", VolumeCRNLabel: "", ClusterIDLabel: ""},
AccessibleTopology: stdTopology,
},
libVolumeResponse: &provider.Volume{Capacity: &cap, Name: &volName, VolumeID: "testVolumeId", Iops: &iopsStr, Az: "myzone", Region: "myregion"},
expErrCode: codes.OK,
libVolumeError: nil,
},
}

// Creating test logger
Expand Down

0 comments on commit 11716e6

Please sign in to comment.