Skip to content

Commit

Permalink
Merge pull request #154 from dell/repl-get-capabilities
Browse files Browse the repository at this point in the history
Add GetReplicationCapabilities
  • Loading branch information
falfaroc authored Jan 30, 2023
2 parents 3240747 + ec14606 commit 2f4c263
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 6 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ require (
github.com/cucumber/godog v0.12.1
github.com/dell/dell-csi-extensions/common v1.1.1-0.20221019160525-ed5b353790e7
github.com/dell/dell-csi-extensions/podmon v1.1.2-0.20221019160525-ed5b353790e7
github.com/dell/dell-csi-extensions/replication v1.2.2-0.20230112201116-67291a77b976
github.com/dell/dell-csi-extensions/volumeGroupSnapshot v1.2.2-0.20221019160525-ed5b353790e7
github.com/dell/gocsi v1.6.0
github.com/dell/gofsutil v1.11.0
github.com/dell/goscaleio v1.9.0
github.com/dell/goscaleio v1.9.1-0.20230124143340-90401f5fd8ec
github.com/fsnotify/fsnotify v1.5.1
github.com/golang/protobuf v1.5.2
github.com/gorilla/mux v1.8.0
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,16 @@ github.com/dell/dell-csi-extensions/common v1.1.1-0.20221019160525-ed5b353790e7
github.com/dell/dell-csi-extensions/common v1.1.1-0.20221019160525-ed5b353790e7/go.mod h1:x68COjv2yqphSmGWZDPV9WcBENA9+e8v21aGFO5i3PQ=
github.com/dell/dell-csi-extensions/podmon v1.1.2-0.20221019160525-ed5b353790e7 h1:ewGOvjhqZPjqx5ORQ//OtS1mh+sToALeo8RxadcsVxg=
github.com/dell/dell-csi-extensions/podmon v1.1.2-0.20221019160525-ed5b353790e7/go.mod h1:J4VNEmXV6sz40QviNF1B+Ov+KNQmzFtJw0YNUpq6ncs=
github.com/dell/dell-csi-extensions/replication v1.2.2-0.20230112201116-67291a77b976 h1:+7blNqXuHA7KxnDF54hPntUiTOaZNE5Bd3f/e2Zt8hg=
github.com/dell/dell-csi-extensions/replication v1.2.2-0.20230112201116-67291a77b976/go.mod h1:FU2kzS8/29GlK9iCdS+E70cyeWun63eNP44aHwg7jW8=
github.com/dell/dell-csi-extensions/volumeGroupSnapshot v1.2.2-0.20221019160525-ed5b353790e7 h1:xl9qR/Bjv8GR7gCybqoYkfB39TcSLGcYJqjMAG6qCdc=
github.com/dell/dell-csi-extensions/volumeGroupSnapshot v1.2.2-0.20221019160525-ed5b353790e7/go.mod h1:etLWwS1G2IqHDuArHqB0OWQvpdcztuBxopWrRE+mpk0=
github.com/dell/gocsi v1.6.0 h1:ZmoMi17v1jK0RE0OGEivu52/RqHbOhP5cqs9SHExqa0=
github.com/dell/gocsi v1.6.0/go.mod h1:+ihwgNYeFTv69Ym2X2Ij1idK72JYoNR8CeiWYJrrbho=
github.com/dell/gofsutil v1.11.0 h1:HHLQVdoWF9xjI0/sLGTzX7i8aAGdZwJG/s7nzKwHLbw=
github.com/dell/gofsutil v1.11.0/go.mod h1:j639KWtc61yK9oPBZSZrSEDqhFKe446XK9etJpk/KtI=
github.com/dell/goscaleio v1.9.0 h1:7A43HVUIYdIt0o0r3wlDVeZDOUlrVEjX+A+IAseGsSs=
github.com/dell/goscaleio v1.9.0/go.mod h1:f+OsYKdKJc8j/a0uHI6nJZpiMfx7wDd6yq78dAeBHsg=
github.com/dell/goscaleio v1.9.1-0.20230124143340-90401f5fd8ec h1:cC0kw5cFFSMdBWt28rR5y3wUDruUuDd8PthtkJujARs=
github.com/dell/goscaleio v1.9.1-0.20230124143340-90401f5fd8ec/go.mod h1:f+OsYKdKJc8j/a0uHI6nJZpiMfx7wDd6yq78dAeBHsg=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
Expand Down
18 changes: 18 additions & 0 deletions service/features/array-config/replication-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
{
"endpoint": "http://127.0.0.1",
"username": "admin",
"password": "Password123",
"insecure": true,
"isDefault": true,
"systemID": "14dbbf5617523654"
},
{
"endpoint": "http://127.0.0.1",
"username": "admin",
"password": "Password123",
"skipCertificateValidation": true,
"isDefault": false,
"systemID": "15dbbf5617523655-system-name"
}
]
2 changes: 1 addition & 1 deletion service/features/list_volumes.feature
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Feature: VxFlex OS CSI interface
And a valid ListSnapshotsResponse is returned with listed "1" and next_token ""

Scenario: List snapshots with 50000 entries
Given a VxFlexOS service
Given a VxFlexOS service with timeout 120000 milliseconds
And there are 50000 valid snapshots of "default" volume
When I call Probe
Then I call ListSnapshots with max_entries "9999" and starting_token ""
Expand Down
16 changes: 16 additions & 0 deletions service/features/replication.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Feature: PowerFlex replication
As a powerflex user, I want to test powerflex replication
So that replication is known to work

@replication
Scenario Outline: Test GetReplicationCapabilities
Given a VxFlexOS service
And I use config "replication-config"
And I induce error <error>
When I call GetReplicationCapabilities
Then the error contains <errormsg>
And a <valid> replication capabilities structure is returned
Examples:
| error | errormsg | valid |
| "none" | "none" | "true" |

3 changes: 2 additions & 1 deletion service/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var (
connectedSystemID = make([]string, 0)
publishGetMappedVolMaxRetry = 30
unpublishGetMappedVolMaxRetry = 5
getMappedVolDelay = (1 * time.Second)
)

func (s *service) NodeStageVolume(
Expand Down Expand Up @@ -315,7 +316,7 @@ func (s *service) getSDCMappedVol(volumeID string, systemID string, maxRetry int
break
}
Log.Printf("Node publish getMappedVol retry: %d", i)
time.Sleep(1 * time.Second)
time.Sleep(getMappedVolDelay)
}
if err != nil {
Log.Printf("SDC returned volume %s on system %s not published to node", volumeID, systemID)
Expand Down
90 changes: 90 additions & 0 deletions service/replication.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package service

import (
"github.com/dell/dell-csi-extensions/replication"
"golang.org/x/net/context"
)

func (s *service) GetReplicationCapabilities(ctx context.Context, req *replication.GetReplicationCapabilityRequest) (*replication.GetReplicationCapabilityResponse, error) {
var rep = new(replication.GetReplicationCapabilityResponse)
rep.Capabilities = []*replication.ReplicationCapability{
{
Type: &replication.ReplicationCapability_Rpc{
Rpc: &replication.ReplicationCapability_RPC{
Type: replication.ReplicationCapability_RPC_CREATE_REMOTE_VOLUME,
},
},
},
{
Type: &replication.ReplicationCapability_Rpc{
Rpc: &replication.ReplicationCapability_RPC{
Type: replication.ReplicationCapability_RPC_CREATE_PROTECTION_GROUP,
},
},
},
{
Type: &replication.ReplicationCapability_Rpc{
Rpc: &replication.ReplicationCapability_RPC{
Type: replication.ReplicationCapability_RPC_DELETE_PROTECTION_GROUP,
},
},
},
{
Type: &replication.ReplicationCapability_Rpc{
Rpc: &replication.ReplicationCapability_RPC{
Type: replication.ReplicationCapability_RPC_REPLICATION_ACTION_EXECUTION,
},
},
},
{
Type: &replication.ReplicationCapability_Rpc{
Rpc: &replication.ReplicationCapability_RPC{
Type: replication.ReplicationCapability_RPC_MONITOR_PROTECTION_GROUP,
},
},
},
}
rep.Actions = []*replication.SupportedActions{
{
Actions: &replication.SupportedActions_Type{
Type: replication.ActionTypes_FAILOVER_REMOTE,
},
},
{
Actions: &replication.SupportedActions_Type{
Type: replication.ActionTypes_UNPLANNED_FAILOVER_LOCAL,
},
},
{
Actions: &replication.SupportedActions_Type{
Type: replication.ActionTypes_REPROTECT_LOCAL,
},
},
{
Actions: &replication.SupportedActions_Type{
Type: replication.ActionTypes_SUSPEND,
},
},
{
Actions: &replication.SupportedActions_Type{
Type: replication.ActionTypes_RESUME,
},
},
{
Actions: &replication.SupportedActions_Type{
Type: replication.ActionTypes_SYNC,
},
},
{
Actions: &replication.SupportedActions_Type{
Type: replication.ActionTypes_CREATE_SNAPSHOT,
},
},
{
Actions: &replication.SupportedActions_Type{
Type: replication.ActionTypes_ABORT_SNAPSHOT,
},
},
}
return rep, nil
}
111 changes: 110 additions & 1 deletion service/step_defs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (

"github.com/cucumber/godog"
"github.com/dell/dell-csi-extensions/podmon"
"github.com/dell/dell-csi-extensions/replication"
volGroupSnap "github.com/dell/dell-csi-extensions/volumeGroupSnapshot"
"github.com/dell/gofsutil"
"github.com/dell/goscaleio"
Expand Down Expand Up @@ -87,6 +88,7 @@ var setupGetSystemIDtoFail bool
type feature struct {
nGoRoutines int
server *httptest.Server
server2 *httptest.Server
service *service
adminClient *goscaleio.Client
system *goscaleio.System
Expand Down Expand Up @@ -134,6 +136,7 @@ type feature struct {
snapshotIndex int
volumeID string
VolumeGroupSnapshot *volGroupSnap.CreateVolumeGroupSnapshotResponse
replicationCapabilitiesResponse *replication.GetReplicationCapabilityResponse
}

func (f *feature) checkGoRoutines(tag string) {
Expand All @@ -143,7 +146,13 @@ func (f *feature) checkGoRoutines(tag string) {
}

func (f *feature) aVxFlexOSService() error {
return f.aVxFlexOSServiceWithTimeoutMilliseconds(50)
}

func (f *feature) aVxFlexOSServiceWithTimeoutMilliseconds(millis int) error {
f.checkGoRoutines("start aVxFlexOSService")
goscaleio.ClientConnectTimeout = time.Duration(millis) * time.Millisecond

// Save off the admin client and the system
if f.service != nil {
adminClient := f.service.adminClients[arrayID]
Expand Down Expand Up @@ -223,6 +232,7 @@ func (f *feature) aVxFlexOSService() error {

// configure variables in the driver
publishGetMappedVolMaxRetry = 2
getMappedVolDelay = 10 * time.Millisecond

// Get or reuse the cached service
f.getService()
Expand All @@ -235,10 +245,13 @@ func (f *feature) aVxFlexOSService() error {
if handler != nil {
if f.server == nil {
f.server = httptest.NewServer(handler)
f.server2 = httptest.NewServer(handler)
}
if f.service.opts.arrays != nil {
f.service.opts.arrays[arrayID].Endpoint = f.server.URL
f.service.opts.arrays[arrayID2].Endpoint = f.server.URL
if f.service.opts.arrays[arrayID2] != nil {
f.service.opts.arrays[arrayID2].Endpoint = f.server2.URL
}
}
} else {
f.server = nil
Expand Down Expand Up @@ -3264,9 +3277,102 @@ func (f *feature) iCallSetQoSParameters(systemID string, sdcID string, bandwidth
return nil
}

func (f *feature) iUseConfig(filename string) error {
ArrayConfigFile = "./features/array-config/" + filename
var err error
f.service.opts.arrays, err = getArrayConfig(context.Background())
if err != nil {
return fmt.Errorf("invalid array config: %s", err.Error())
}
if f.service.opts.arrays != nil {
f.service.opts.arrays[arrayID].Endpoint = f.server.URL
if f.service.opts.arrays[arrayID2] != nil {
f.service.opts.arrays[arrayID2].Endpoint = f.server2.URL
}
}

fmt.Printf("****************************************************** s.opts.arrays %v\n", f.service.opts.arrays)
f.service.systemProbeAll(context.Background())
f.adminClient = f.service.adminClients[arrayID]
f.adminClient2 = f.service.adminClients[arrayID2]
if f.adminClient == nil {
return fmt.Errorf("adminClient nil")
}
if f.adminClient2 == nil {
return fmt.Errorf("adminClient2 nil")
}
return nil
}

func (f *feature) iCallGetReplicationCapabilities() error {
req := &replication.GetReplicationCapabilityRequest{}
ctx := new(context.Context)
f.replicationCapabilitiesResponse, f.err = f.service.GetReplicationCapabilities(*ctx, req)
log.Printf("GetReplicationCapabilities returned %+v", f.replicationCapabilitiesResponse)
return nil
}

func (f *feature) aReplicationCapabilitiesStructureIsReturned(arg1 string) error {
if f.err != nil {
return f.err
}
var createRemoteVolume, createProtectionGroup, deleteProtectionGroup, monitorProtectionGroup, replicationActionExecution bool
for _, cap := range f.replicationCapabilitiesResponse.GetCapabilities() {
if cap == nil {
continue
}
rpc := cap.GetRpc()
if rpc == nil {
continue
}
ty := rpc.GetType()
switch ty {
case replication.ReplicationCapability_RPC_CREATE_REMOTE_VOLUME:
createRemoteVolume = true
case replication.ReplicationCapability_RPC_CREATE_PROTECTION_GROUP:
createProtectionGroup = true
case replication.ReplicationCapability_RPC_DELETE_PROTECTION_GROUP:
deleteProtectionGroup = true
case replication.ReplicationCapability_RPC_MONITOR_PROTECTION_GROUP:
monitorProtectionGroup = true
case replication.ReplicationCapability_RPC_REPLICATION_ACTION_EXECUTION:
replicationActionExecution = true
}
}
var failoverRemote, unplannedFailoverLocal, reprotectLocal, suspend, resume, sync bool
for _, act := range f.replicationCapabilitiesResponse.GetActions() {
if act == nil {
continue
}
ty := act.GetType()
switch ty {
case replication.ActionTypes_FAILOVER_REMOTE:
failoverRemote = true
case replication.ActionTypes_UNPLANNED_FAILOVER_LOCAL:
unplannedFailoverLocal = true
case replication.ActionTypes_REPROTECT_LOCAL:
reprotectLocal = true
case replication.ActionTypes_SUSPEND:
suspend = true
case replication.ActionTypes_RESUME:
resume = true
case replication.ActionTypes_SYNC:
sync = true
}
}
if !createRemoteVolume || !createProtectionGroup || !deleteProtectionGroup || !replicationActionExecution || !monitorProtectionGroup {
return fmt.Errorf("Not all expected ReplicationCapability_RPC capabilities were returned")
}
if !failoverRemote || !unplannedFailoverLocal || !reprotectLocal || !suspend || !resume || !sync {
return fmt.Errorf("Not all expected ReplicationCapbility_RPC actions were returned")
}
return nil
}

func FeatureContext(s *godog.ScenarioContext) {
f := &feature{}
s.Step(`^a VxFlexOS service$`, f.aVxFlexOSService)
s.Step(`^a VxFlexOS service with timeout (\d+) milliseconds$`, f.aVxFlexOSServiceWithTimeoutMilliseconds)
s.Step(`^I call GetPluginInfo$`, f.iCallGetPluginInfo)
s.Step(`^I call DynamicArrayChange$`, f.iCallDynamicArrayChange)
s.Step(`^a valid DynamicArrayChange occurs$`, f.aValidDynamicArrayChange)
Expand Down Expand Up @@ -3419,6 +3525,9 @@ func FeatureContext(s *godog.ScenarioContext) {
s.Step(`^I call getProtectionDomainIDFromName "([^"]*)" "([^"]*)"$`, f.iCallgetProtectionDomainIDFromName)
s.Step(`^I call getArrayInstallationID "([^"]*)"$`, f.iCallgetArrayInstallationID)
s.Step(`^I call setQoSParameters with systemID "([^"]*)" sdcID "([^"]*)" bandwidthLimit "([^"]*)" iopsLimit "([^"]*)" volumeName "([^"]*)" csiVolID "([^"]*)" nodeID "([^"]*)"$`, f.iCallSetQoSParameters)
s.Step(`^I use config "([^"]*)"$`, f.iUseConfig)
s.Step(`^I call GetReplicationCapabilities$`, f.iCallGetReplicationCapabilities)
s.Step(`^a "([^"]*)" replication capabilities structure is returned$`, f.aReplicationCapabilitiesStructureIsReturned)

s.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) {
if f.server != nil {
Expand Down

0 comments on commit 2f4c263

Please sign in to comment.