From 48427280835114c01ac577684849084c10aac934 Mon Sep 17 00:00:00 2001 From: edisonxiang Date: Tue, 6 Mar 2018 10:43:32 +0800 Subject: [PATCH 1/3] add replication resource --- openstack/client.go | 6 ++ openstack/drs/v2/replications/requests.go | 110 ++++++++++++++++++++++ openstack/drs/v2/replications/results.go | 92 ++++++++++++++++++ openstack/drs/v2/replications/urls.go | 26 +++++ 4 files changed, 234 insertions(+) create mode 100644 openstack/drs/v2/replications/requests.go create mode 100644 openstack/drs/v2/replications/results.go create mode 100644 openstack/drs/v2/replications/urls.go diff --git a/openstack/client.go b/openstack/client.go index d419f6c1e..53df48f11 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -407,3 +407,9 @@ func NewCESClient(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) ( sc.ResourceBase = sc.Endpoint return sc, err } + +// NewDRSServiceV2 creates a ServiceClient that may be used to access the v2 Data Replication Service. +func NewDRSServiceV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "volumev2") + return sc, err +} diff --git a/openstack/drs/v2/replications/requests.go b/openstack/drs/v2/replications/requests.go new file mode 100644 index 000000000..23d7a33fc --- /dev/null +++ b/openstack/drs/v2/replications/requests.go @@ -0,0 +1,110 @@ +package replications + +import ( + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/pagination" +) + +// CreateOpsBuilder is used for creating replication parameters. +// any struct providing the parameters should implement this interface +type CreateOpsBuilder interface { + ToReplicationCreateMap() (map[string]interface{}, error) +} + +// CreateOps is a struct that contains all the parameters. +type CreateOps struct { + // The name of the EVS replication pair. + // The name can contain a maximum of 255 bytes. + Name string `json:"name,omitempty"` + + // The description of the EVS replication pair. + // The description can contain a maximum of 255 bytes. + Description string `json:"description,omitempty"` + + // The IDs of the EVS disks used to create the EVS replication pair. + VolumeIDs []string `json:"volume_ids" required:"true"` + + // The primary AZ of the EVS replication pair. + // That is the AZ where the production disk belongs. + PriorityStation string `json:"priority_station" required:"true"` + + // The type of the EVS replication pair. + // Currently only type hypermetro is supported. + ReplicationModel string `json:"replication_model" required:"true"` +} + +// ToReplicationCreateMap is used for type convert +func (ops CreateOps) ToReplicationCreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(ops, "replication") +} + +// Create a replication with given parameters. +func Create(client *golangsdk.ServiceClient, ops CreateOpsBuilder) (r CreateResult) { + b, err := ops.ToReplicationCreateMap() + if err != nil { + r.Err = err + return + } + + _, r.Err = client.Post(createURL(client), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{202}, + }) + + return +} + +// Delete a replication by id +func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) { + _, r.Err = client.Delete(deleteURL(client, id), nil) + return +} + +// Get a replication with detailed information by id +func Get(client *golangsdk.ServiceClient, id string) (r GetResult) { + _, r.Err = client.Get(getURL(client, id), &r.Body, nil) + return +} + +// ListOptsBuilder is an interface by which can be able to +// build the query string of the list function +type ListOptsBuilder interface { + ToReplicationListQuery() (string, error) +} + +// ListOpts is a struct that contains all the parameters. +type ListOpts struct { + Marker string `q:"marker"` + Limit int `q:"limit"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` + Offset int `q:"offset"` + ChangesSince string `q:"changes-since"` + Name string `q:"name"` + Status string `q:"status"` + ReplicationConsistencyGroupID string `q:"replication_consistency_group_id"` + VolumeIDs string `q:"volume_ids"` + VolumeID string `q:"volume_id"` + PriorityStation string `q:"priority_station"` +} + +// ToReplicationListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToReplicationListQuery() (string, error) { + q, err := golangsdk.BuildQueryString(opts) + return q.String(), err +} + +// List all the replications +func List(client *golangsdk.ServiceClient, ops ListOptsBuilder) pagination.Pager { + url := listURL(client) + if ops != nil { + q, err := ops.ToReplicationListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += q + } + + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return ReplicationPage{pagination.SinglePageBase(r)} + }) +} diff --git a/openstack/drs/v2/replications/results.go b/openstack/drs/v2/replications/results.go new file mode 100644 index 000000000..9de6816de --- /dev/null +++ b/openstack/drs/v2/replications/results.go @@ -0,0 +1,92 @@ +package replications + +import ( + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/pagination" +) + +// ReplicationCreate response +type ReplicationCreate struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Status string `json:"status"` + ReplicationConsistencyGroupID string `json:"replication_consistency_group_id"` + VolumeIDs string `json:"volume_ids"` + PriorityStation string `json:"priority_station"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +// CreateResult is a struct that contains all the return parameters of creation +type CreateResult struct { + golangsdk.Result +} + +// Extract from CreateResult +func (r CreateResult) Extract() (*ReplicationCreate, error) { + var s struct { + Replication *ReplicationCreate `json:"replication"` + } + err := r.Result.ExtractInto(&s) + return s.Replication, err +} + +// DeleteResult is a struct which contains the result of deletion +type DeleteResult struct { + golangsdk.ErrResult +} + +// Replication response +type Replication struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Status string `json:"status"` + ReplicationConsistencyGroupID string `json:"replication_consistency_group_id"` + VolumeIDs string `json:"volume_ids"` + PriorityStation string `json:"priority_station"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ReplicationModel string `json:"replication_model"` + ReplicationStatus string `json:"replication_status"` + Progress string `json:"progress"` + FailureDetail string `json:"failure_detail"` + // RecordMetadata includes volume_type and multiattach currently. + RecordMetadata map[string]string `json:"record_metadata"` +} + +// GetResult contains the body of getting detailed +type GetResult struct { + golangsdk.Result +} + +// Extract from GetResult +func (r GetResult) Extract() (*Replication, error) { + var s struct { + Replication *Replication `json:"replication"` + } + err := r.Result.ExtractInto(&s) + return s.Replication, err +} + +// ReplicationPage may be embedded in a Page +// that contains all of the results from an operation at once. +type ReplicationPage struct { + pagination.SinglePageBase +} + +// IsEmpty returns true if a ListResult contains no replications. +func (r ReplicationPage) IsEmpty() (bool, error) { + rs, err := ExtractReplications(r) + return len(rs) == 0, err +} + +// ExtractReplications from List +func ExtractReplications(r pagination.Page) ([]Replication, error) { + var s struct { + Replications []Replication `json:"replications"` + } + err := (r.(ReplicationPage)).ExtractInto(&s) + return s.Replications, err +} diff --git a/openstack/drs/v2/replications/urls.go b/openstack/drs/v2/replications/urls.go new file mode 100644 index 000000000..3aab280bf --- /dev/null +++ b/openstack/drs/v2/replications/urls.go @@ -0,0 +1,26 @@ +package replications + +import "github.com/huaweicloud/golangsdk" + +// endpoint/os-vendor-replications +const resourcePath = "os-vendor-replications" + +// createURL will build the rest query url of creation +func createURL(client *golangsdk.ServiceClient) string { + return client.ServiceURL(resourcePath) +} + +// deleteURL will build the url of deletion +func deleteURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id) +} + +// getURL will build the get url of get function +func getURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id) +} + +// listURL will build the list url of list function +func listURL(client *golangsdk.ServiceClient) string { + return client.ServiceURL(resourcePath) +} From 0de8ec4a23b98cd0622c7fe491629d0e4b5dc174 Mon Sep 17 00:00:00 2001 From: edisonxiang Date: Tue, 6 Mar 2018 15:07:34 +0800 Subject: [PATCH 2/3] add replicationconsistencygroup resource --- .../replicationconsistencygroups/requests.go | 155 ++++++++++++++++++ .../replicationconsistencygroups/results.go | 100 +++++++++++ .../v2/replicationconsistencygroups/urls.go | 31 ++++ 3 files changed, 286 insertions(+) create mode 100644 openstack/drs/v2/replicationconsistencygroups/requests.go create mode 100644 openstack/drs/v2/replicationconsistencygroups/results.go create mode 100644 openstack/drs/v2/replicationconsistencygroups/urls.go diff --git a/openstack/drs/v2/replicationconsistencygroups/requests.go b/openstack/drs/v2/replicationconsistencygroups/requests.go new file mode 100644 index 000000000..57afba66c --- /dev/null +++ b/openstack/drs/v2/replicationconsistencygroups/requests.go @@ -0,0 +1,155 @@ +package replicationconsistencygroups + +import ( + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/pagination" +) + +// CreateOpsBuilder is used for creating replication consistency group parameters. +// any struct providing the parameters should implement this interface +type CreateOpsBuilder interface { + ToReplicationConsistencyGroupCreateMap() (map[string]interface{}, error) +} + +// CreateOps is a struct that contains all the parameters. +type CreateOps struct { + // The name of the replication consistency group. + // The name can contain a maximum of 255 bytes. + Name string `json:"name,omitempty"` + + // The description of the replication consistency group. + // The description can contain a maximum of 255 bytes. + Description string `json:"description,omitempty"` + + // The IDs of the EVS replication pairs used to + // create the replication consistency group. + ReplicationIDs []string `json:"replication_ids" required:"true"` + + // The primary AZ of the replication consistency group. + // That is the AZ where the production disk belongs. + PriorityStation string `json:"priority_station" required:"true"` + + // The type of the created replication consistency group. + // Currently only type hypermetro is supported. + ReplicationModel string `json:"replication_model" required:"true"` +} + +// ToReplicationConsistencyGroupCreateMap is used for type convert +func (ops CreateOps) ToReplicationConsistencyGroupCreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(ops, "replication_consistency_group") +} + +// Create a replication consistency group with given parameters. +func Create(client *golangsdk.ServiceClient, ops CreateOpsBuilder) (r CreateResult) { + b, err := ops.ToReplicationConsistencyGroupCreateMap() + if err != nil { + r.Err = err + return + } + + _, r.Err = client.Post(createURL(client), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{202}, + }) + + return +} + +// Delete a replication consistency group by id +func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) { + _, r.Err = client.Delete(deleteURL(client, id), nil) + return +} + +// Get a replication consistency group with detailed information by id +func Get(client *golangsdk.ServiceClient, id string) (r GetResult) { + _, r.Err = client.Get(getURL(client, id), &r.Body, nil) + return +} + +// ListOptsBuilder is an interface by which can be able to +// build the query string of the list function +type ListOptsBuilder interface { + ToReplicationConsistencyGroupListQuery() (string, error) +} + +// ListOpts is a struct that contains all the parameters. +type ListOpts struct { + Marker string `q:"marker"` + Limit int `q:"limit"` + SortKey string `q:"sort_key"` + SortDir string `q:"sort_dir"` + Offset int `q:"offset"` + ChangesSince string `q:"changes-since"` + Name string `q:"name"` + Status string `q:"status"` + PriorityStation string `q:"priority_station"` + VolumeID string `q:"volume_id"` +} + +// ToReplicationConsistencyGroupListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToReplicationConsistencyGroupListQuery() (string, error) { + q, err := golangsdk.BuildQueryString(opts) + return q.String(), err +} + +// List all the replication consistency groups +func List(client *golangsdk.ServiceClient, ops ListOptsBuilder) pagination.Pager { + url := listURL(client) + if ops != nil { + q, err := ops.ToReplicationConsistencyGroupListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += q + } + + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return ReplicationConsistencyGroupPage{pagination.SinglePageBase(r)} + }) +} + +//UpdateOptsBuilder is an interface which can build the map paramter of update function +type UpdateOptsBuilder interface { + ToReplicationConsistencyGroupUpdateMap() (map[string]interface{}, error) +} + +//UpdateOpts is a struct which represents the parameters of update function +type UpdateOpts struct { + // The name of the replication consistency group. + // The name can contain a maximum of 255 bytes. + Name string `json:"name,omitempty"` + + // The description of the replication consistency group. + // The description can contain a maximum of 255 bytes. + Description string `json:"description,omitempty"` + + // The type of the created replication consistency group. + // Currently only type hypermetro is supported. + ReplicationModel string `json:"replication_model,omitempty"` + + // The IDs of the EVS replication pairs to be added. + AddReplicationIDs []string `json:"add_replication_ids,omitempty"` + + // The IDs of the EVS replication pairs to be removeed. + RemoveReplicationIDs []string `json:"remove_replication_ids,omitempty"` +} + +// ToReplicationConsistencyGroupUpdateMap is used for type convert +func (opts UpdateOpts) ToReplicationConsistencyGroupUpdateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "replication_consistency_group") +} + +// Update is a method which can be able to update the replication consistency group +// via accessing to the service with Put method and parameters +func Update(client *golangsdk.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + body, err := opts.ToReplicationConsistencyGroupUpdateMap() + if err != nil { + r.Err = err + return + } + + _, r.Err = client.Put(updateURL(client, id), body, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{202}, + }) + return +} diff --git a/openstack/drs/v2/replicationconsistencygroups/results.go b/openstack/drs/v2/replicationconsistencygroups/results.go new file mode 100644 index 000000000..33a6a08ca --- /dev/null +++ b/openstack/drs/v2/replicationconsistencygroups/results.go @@ -0,0 +1,100 @@ +package replicationconsistencygroups + +import ( + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/pagination" +) + +// ReplicationConsistencyGroupCreateorUpdate response +type ReplicationConsistencyGroupCreateorUpdate struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Status string `json:"status"` + PriorityStation string `json:"priority_station"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +// CreateResult is a struct that contains all the return parameters of creation +type CreateResult struct { + golangsdk.Result +} + +// Extract from CreateResult +func (r CreateResult) Extract() (*ReplicationConsistencyGroupCreateorUpdate, error) { + var s struct { + ReplicationConsistencyGroup *ReplicationConsistencyGroupCreateorUpdate `json:"replication_consistency_group"` + } + err := r.Result.ExtractInto(&s) + return s.ReplicationConsistencyGroup, err +} + +// DeleteResult is a struct which contains the result of deletion +type DeleteResult struct { + golangsdk.ErrResult +} + +// ReplicationConsistencyGroup response +type ReplicationConsistencyGroup struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Status string `json:"status"` + PriorityStation string `json:"priority_station"` + ReplicationModel string `json:"replication_model"` + ReplicationStatus string `json:"replication_status"` + ReplicationIDs string `json:"replication_ids"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + FailureDetail string `json:"failure_detail"` +} + +// GetResult contains the body of getting detailed +type GetResult struct { + golangsdk.Result +} + +// Extract from GetResult +func (r GetResult) Extract() (*ReplicationConsistencyGroup, error) { + var s struct { + ReplicationConsistencyGroup *ReplicationConsistencyGroup `json:"replication_consistency_group"` + } + err := r.Result.ExtractInto(&s) + return s.ReplicationConsistencyGroup, err +} + +// ReplicationConsistencyGroupPage may be embedded in a Page +// that contains all of the results from an operation at once. +type ReplicationConsistencyGroupPage struct { + pagination.SinglePageBase +} + +// IsEmpty returns true if a ListResult contains no replications. +func (r ReplicationConsistencyGroupPage) IsEmpty() (bool, error) { + rs, err := ExtractReplicationConsistencyGroups(r) + return len(rs) == 0, err +} + +// ExtractReplicationConsistencyGroups from List +func ExtractReplicationConsistencyGroups(r pagination.Page) ([]ReplicationConsistencyGroup, error) { + var s struct { + ReplicationConsistencyGroups []ReplicationConsistencyGroup `json:"replication_consistency_groups"` + } + err := (r.(ReplicationConsistencyGroupPage)).ExtractInto(&s) + return s.ReplicationConsistencyGroups, err +} + +// UpdateResult is a struct from which can get the result of update method +type UpdateResult struct { + golangsdk.Result +} + +// Extract from UpdateResult +func (r UpdateResult) Extract() (*ReplicationConsistencyGroupCreateorUpdate, error) { + var s struct { + ReplicationConsistencyGroup *ReplicationConsistencyGroupCreateorUpdate `json:"replication_consistency_group"` + } + err := r.Result.ExtractInto(&s) + return s.ReplicationConsistencyGroup, err +} diff --git a/openstack/drs/v2/replicationconsistencygroups/urls.go b/openstack/drs/v2/replicationconsistencygroups/urls.go new file mode 100644 index 000000000..f954639da --- /dev/null +++ b/openstack/drs/v2/replicationconsistencygroups/urls.go @@ -0,0 +1,31 @@ +package replicationconsistencygroups + +import "github.com/huaweicloud/golangsdk" + +// endpoint/os-vendor-replication-consistency-groups +const resourcePath = "os-vendor-replication-consistency-groups" + +// createURL will build the rest query url of creation +func createURL(client *golangsdk.ServiceClient) string { + return client.ServiceURL(resourcePath) +} + +// deleteURL will build the url of deletion +func deleteURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id) +} + +// getURL will build the get url of get function +func getURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id) +} + +// listURL will build the list url of list function +func listURL(client *golangsdk.ServiceClient) string { + return client.ServiceURL(resourcePath) +} + +// updateURL will build the url of update +func updateURL(c *golangsdk.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id) +} From 48c46dca14718e57ebaedeecb94c25cb5601e2da Mon Sep 17 00:00:00 2001 From: edisonxiang Date: Tue, 6 Mar 2018 17:59:35 +0800 Subject: [PATCH 3/3] add replicationconsistencygroup resource action --- .../replicationconsistencygroups/requests.go | 129 ++++++++++++++++++ .../replicationconsistencygroups/results.go | 5 + .../v2/replicationconsistencygroups/urls.go | 5 + 3 files changed, 139 insertions(+) diff --git a/openstack/drs/v2/replicationconsistencygroups/requests.go b/openstack/drs/v2/replicationconsistencygroups/requests.go index 57afba66c..592cabcbf 100644 --- a/openstack/drs/v2/replicationconsistencygroups/requests.go +++ b/openstack/drs/v2/replicationconsistencygroups/requests.go @@ -153,3 +153,132 @@ func Update(client *golangsdk.ServiceClient, id string, opts UpdateOptsBuilder) }) return } + +const ( + // OsFailoverReplicationConsistencyGroup is performing a failover for a replication consistency group. + OsFailoverReplicationConsistencyGroup = "os-failover-replication-consistency-group" + + // OsSyncReplicationConsistencyGroup is synchronizing a replication consistency group. + OsSyncReplicationConsistencyGroup = "os-sync-replication-consistency-group" + + // OsReverseReplicationConsistencyGroup is performing a primary/secondary switchover for a replication consistency group. + OsReverseReplicationConsistencyGroup = "os-reverse-replication-consistency-group" + + // OsStopReplicationConsistencyGroup is pausing a replication consistency group. + OsStopReplicationConsistencyGroup = "os-stop-replication-consistency-group" + + // OsReprotectReplicationConsistencyGroup is reprotecting a replication consistency group. + OsReprotectReplicationConsistencyGroup = "os-reprotect-replication-consistency-group" + + // OsExtendReplicationVolume is expanding EVS disks in a replication consistency group. + OsExtendReplicationVolume = "os-extend-replication-volumes" +) + +// FailOver is performing a failover for a replication consistency group. +func FailOver(client *golangsdk.ServiceClient, id string) (r ActionResult) { + _, r.Err = client.Post( + actionURL(client, id), + map[string]interface{}{OsFailoverReplicationConsistencyGroup: nil}, + &r.Body, + &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + + return +} + +// Sync is synchronizing a replication consistency group. +func Sync(client *golangsdk.ServiceClient, id string) (r ActionResult) { + _, r.Err = client.Post( + actionURL(client, id), + map[string]interface{}{OsSyncReplicationConsistencyGroup: nil}, + &r.Body, + &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + + return +} + +// Reverse is performing a primary/secondary switchover for a replication consistency group. +func Reverse(client *golangsdk.ServiceClient, id string) (r ActionResult) { + _, r.Err = client.Post( + actionURL(client, id), + map[string]interface{}{OsReverseReplicationConsistencyGroup: nil}, + &r.Body, + &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + + return +} + +// Stop is pausing a replication consistency group. +func Stop(client *golangsdk.ServiceClient, id string) (r ActionResult) { + _, r.Err = client.Post( + actionURL(client, id), + map[string]interface{}{OsStopReplicationConsistencyGroup: nil}, + &r.Body, + &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + + return +} + +// Reprotect is reprotecting a replication consistency group. +func Reprotect(client *golangsdk.ServiceClient, id string) (r ActionResult) { + _, r.Err = client.Post( + actionURL(client, id), + map[string]interface{}{OsReprotectReplicationConsistencyGroup: nil}, + &r.Body, + &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + + return +} + +// ExtendReplicationVolumesOpsBuilder is used for expanding +// EVS disks in a replication consistency group parameters. +// any struct providing the parameters should implement this interface +type ExtendReplicationVolumesOpsBuilder interface { + ToExtendReplicationVolumesMap() (map[string]interface{}, error) +} + +// ReplicationsOps specifies the expansion information +// of one or multiple EVS replication pairs. +type ReplicationsOps struct { + // The IDs of EVS replication pairs + ID string `json:"id" required:"true"` + + // The disk capacity after expansion in the EVS replication pair. + // The unit is GB. + NewSize int `json:"new_size" required:"true"` +} + +// ExtendReplicationVolumesOps is a struct that contains all the parameters. +type ExtendReplicationVolumesOps struct { + // The expansion information of one or multiple EVS replication pairs. + Replications []ReplicationsOps `json:"replications" required:"true"` +} + +// ToExtendReplicationVolumesMap is used for type convert +func (ops ReplicationsOps) ToExtendReplicationVolumesMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(ops, OsExtendReplicationVolume) +} + +// Extend is expanding EVS disks in a replication consistency group. +func Extend(client *golangsdk.ServiceClient, id string, ops ExtendReplicationVolumesOpsBuilder) (r ActionResult) { + b, err := ops.ToExtendReplicationVolumesMap() + if err != nil { + r.Err = err + return + } + + _, r.Err = client.Post(actionURL(client, id), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + + return +} diff --git a/openstack/drs/v2/replicationconsistencygroups/results.go b/openstack/drs/v2/replicationconsistencygroups/results.go index 33a6a08ca..1da637aad 100644 --- a/openstack/drs/v2/replicationconsistencygroups/results.go +++ b/openstack/drs/v2/replicationconsistencygroups/results.go @@ -98,3 +98,8 @@ func (r UpdateResult) Extract() (*ReplicationConsistencyGroupCreateorUpdate, err err := r.Result.ExtractInto(&s) return s.ReplicationConsistencyGroup, err } + +// ActionResult is the result of action operations +type ActionResult struct { + golangsdk.ErrResult +} diff --git a/openstack/drs/v2/replicationconsistencygroups/urls.go b/openstack/drs/v2/replicationconsistencygroups/urls.go index f954639da..8163f4c13 100644 --- a/openstack/drs/v2/replicationconsistencygroups/urls.go +++ b/openstack/drs/v2/replicationconsistencygroups/urls.go @@ -29,3 +29,8 @@ func listURL(client *golangsdk.ServiceClient) string { func updateURL(c *golangsdk.ServiceClient, id string) string { return c.ServiceURL(resourcePath, id) } + +// actionURL will build the url of action +func actionURL(c *golangsdk.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id, "action") +}