From 23281d57d6e7f159f4414e7f006a02856690ff32 Mon Sep 17 00:00:00 2001 From: Zhenguo Niu Date: Tue, 2 Jul 2019 19:04:02 +0800 Subject: [PATCH 1/2] Add SDRS protection group support --- openstack/client.go | 15 +++ .../sdrs/v1/protectiongroups/requests.go | 93 +++++++++++++++++++ openstack/sdrs/v1/protectiongroups/results.go | 51 ++++++++++ .../sdrs/v1/protectiongroups/results_job.go | 80 ++++++++++++++++ openstack/sdrs/v1/protectiongroups/urls.go | 11 +++ service_client.go | 9 ++ 6 files changed, 259 insertions(+) create mode 100644 openstack/sdrs/v1/protectiongroups/requests.go create mode 100644 openstack/sdrs/v1/protectiongroups/results.go create mode 100644 openstack/sdrs/v1/protectiongroups/results_job.go create mode 100644 openstack/sdrs/v1/protectiongroups/urls.go diff --git a/openstack/client.go b/openstack/client.go index 1859686ee..e0c97d6b0 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -964,6 +964,21 @@ func NewRDSV3(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*gol return sc, err } +// SDRSV1 creates a ServiceClient that may be used with the v1 SDRS service. +func SDRSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "network") + sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "sdrs", 1) + sc.Endpoint = sc.Endpoint + "v1/" + client.ProjectID + "/" + sc.ResourceBase = sc.Endpoint + return sc, err +} + +// NewSDRSV1 creates a ServiceClient that may be used to access the SDRS service. +func NewSDRSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "sdrs") + return sc, err +} + func NewSDKClient(c *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, serviceType string) (*golangsdk.ServiceClient, error) { switch serviceType { case "mls": diff --git a/openstack/sdrs/v1/protectiongroups/requests.go b/openstack/sdrs/v1/protectiongroups/requests.go new file mode 100644 index 000000000..3b5249fee --- /dev/null +++ b/openstack/sdrs/v1/protectiongroups/requests.go @@ -0,0 +1,93 @@ +package protectiongroups + +import ( + "github.com/huaweicloud/golangsdk" +) + +var RequestOpts golangsdk.RequestOpts = golangsdk.RequestOpts{ + MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en-us"}, +} + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToGroupCreateMap() (map[string]interface{}, error) +} + +// CreateOpts contains all the values needed to create a new group. +type CreateOpts struct { + //Group Name + Name string `json:"name" required:"true"` + //Group Description + Description string `json:"description,omitempty"` + //The source AZ of a protection group + SourceAZ string `json:"source_availability_zone" required:"true"` + //The target AZ of a protection group + TargetAZ string `json:"target_availability_zone" required:"true"` + //An active-active domain + DomainID string `json:"domain_id" required:"true"` + //ID of the source VPC + SourceVpcID string `json:"source_vpc_id" required:"true"` + //Deployment model + DrType string `json:"dr_type,omitempty"` +} + +// ToGroupCreateMap builds a create request body from CreateOpts. +func (opts CreateOpts) ToGroupCreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "server_group") +} + +// Create will create a new Group based on the values in CreateOpts. +func Create(c *golangsdk.ServiceClient, opts CreateOptsBuilder) (r JobResult) { + b, err := opts.ToGroupCreateMap() + if err != nil { + r.Err = err + return + } + reqOpt := &golangsdk.RequestOpts{OkCodes: []int{200}} + _, r.Err = c.Post(rootURL(c), b, &r.Body, reqOpt) + return +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToGroupUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts contains all the values needed to update a Group. +type UpdateOpts struct { + //Group name + Name string `json:"name" required:"true"` +} + +// ToGroupUpdateMap builds a update request body from UpdateOpts. +func (opts UpdateOpts) ToGroupUpdateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "server_group") +} + +// Update accepts a UpdateOpts struct and uses the values to update a Group.The response code from api is 200 +func Update(c *golangsdk.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToGroupUpdateMap() + if err != nil { + r.Err = err + return + } + reqOpt := &golangsdk.RequestOpts{OkCodes: []int{200}} + _, r.Err = c.Put(resourceURL(c, id), b, nil, reqOpt) + return +} + +// Get retrieves a particular Group based on its unique ID. +func Get(c *golangsdk.ServiceClient, id string) (r GetResult) { + _, r.Err = c.Get(resourceURL(c, id), &r.Body, &RequestOpts) + return +} + +// Delete will permanently delete a particular Group based on its unique ID. +func Delete(c *golangsdk.ServiceClient, id string) (r JobResult) { + reqOpt := &golangsdk.RequestOpts{OkCodes: []int{200}, + MoreHeaders: RequestOpts.MoreHeaders} + _, r.Err = c.DeleteWithResponse(resourceURL(c, &r.Body, id), reqOpt) + return +} diff --git a/openstack/sdrs/v1/protectiongroups/results.go b/openstack/sdrs/v1/protectiongroups/results.go new file mode 100644 index 000000000..50d556378 --- /dev/null +++ b/openstack/sdrs/v1/protectiongroups/results.go @@ -0,0 +1,51 @@ +package protectiongroups + +import ( + "github.com/huaweicloud/golangsdk" +) + +type Group struct { + //Group ID + Id string `json:"id"` + //Group Name + Name string `json:"name"` + //Group Description + Description string `json:"description"` + //The source AZ of a protection group + SourceAZ string `json:"source_availability_zone"` + //The target AZ of a protection group + TargetAZ string `json:"target_availability_zone"` + //An active-active domain + DomainID string `json:"domain_id"` + //ID of the source VPC + SourceVpcID string `json:"source_vpc_id"` + //Deployment model + DrType string `json:"dr_type"` +} + +type commonResult struct { + golangsdk.Result +} + +// Extract is a function that accepts a result and extracts a group. +func (r commonResult) Extract() (*Group, error) { + var response Group + err := r.ExtractInto(&response) + return &response, err +} + +func (r commonResult) ExtractInto(v interface{}) error { + return r.Result.ExtractIntoStructPtr(v, "server_group") +} + +// UpdateResult represents the result of a update operation. Call its Extract +// method to interpret it as a Group. +type UpdateResult struct { + commonResult +} + +// GetResult represents the result of a get operation. Call its Extract +// method to interpret it as a Group. +type GetResult struct { + commonResult +} diff --git a/openstack/sdrs/v1/protectiongroups/results_job.go b/openstack/sdrs/v1/protectiongroups/results_job.go new file mode 100644 index 000000000..06c870645 --- /dev/null +++ b/openstack/sdrs/v1/protectiongroups/results_job.go @@ -0,0 +1,80 @@ +package protectiongroups + +import ( + "fmt" + + "github.com/huaweicloud/golangsdk" +) + +type JobResponse struct { + JobID string `json:"job_id"` +} + +type JobStatus struct { + Status string `json:"status"` + Entities map[string]string `json:"entities"` + JobID string `json:"job_id"` + JobType string `json:"job_type"` + BeginTime string `json:"begin_time"` + EndTime string `json:"end_time"` + ErrorCode string `json:"error_code"` + FailReason string `json:"fail_reason"` +} + +type JobResult struct { + golangsdk.Result +} + +func (r JobResult) ExtractJobResponse() (*JobResponse, error) { + job := new(JobResponse) + err := r.ExtractInto(job) + return job, err +} + +func (r JobResult) ExtractJobStatus() (*JobStatus, error) { + job := new(JobStatus) + err := r.ExtractInto(job) + return job, err +} + +func WaitForJobSuccess(client *golangsdk.ServiceClient, secs int, jobID string) error { + + jobClient := *client + jobClient.ResourceBase = jobClient.Endpoint + return golangsdk.WaitFor(secs, func() (bool, error) { + job := new(JobStatus) + _, err := jobClient.Get(jobClient.ServiceURL("jobs", jobID), &job, nil) + if err != nil { + return false, err + } + + if job.Status == "SUCCESS" { + return true, nil + } + if job.Status == "FAIL" { + err = fmt.Errorf("Job failed with code %s: %s.\n", job.ErrorCode, job.FailReason) + return false, err + } + + return false, nil + }) +} + +func GetJobEntity(client *golangsdk.ServiceClient, jobId string, label string) (interface{}, error) { + + jobClient := *client + jobClient.ResourceBase = jobClient.Endpoint + job := new(JobStatus) + _, err := jobClient.Get(jobClient.ServiceURL("jobs", jobId), &job, nil) + if err != nil { + return nil, err + } + + if job.Status == "SUCCESS" { + if e := job.Entities[label]; e != "" { + return e, nil + } + } + + return nil, fmt.Errorf("Unexpected conversion error in GetJobEntity.") +} diff --git a/openstack/sdrs/v1/protectiongroups/urls.go b/openstack/sdrs/v1/protectiongroups/urls.go new file mode 100644 index 000000000..bd36d4dee --- /dev/null +++ b/openstack/sdrs/v1/protectiongroups/urls.go @@ -0,0 +1,11 @@ +package protectiongroups + +import "github.com/huaweicloud/golangsdk" + +func rootURL(c *golangsdk.ServiceClient) string { + return c.ServiceURL("server-groups") +} + +func resourceURL(c *golangsdk.ServiceClient, id string) string { + return c.ServiceURL("server-groups", id) +} diff --git a/service_client.go b/service_client.go index db12a9d67..f030bd79e 100644 --- a/service_client.go +++ b/service_client.go @@ -117,6 +117,15 @@ func (client *ServiceClient) DeleteWithBody(url string, JSONBody interface{}, op return client.Request("DELETE", url, opts) } +// Delete calls `Request` with the "DELETE" HTTP verb. +func (client *ServiceClient) DeleteWithResponse(url string, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = new(RequestOpts) + } + client.initReqOpts(url, nil, JSONResponse, opts) + return client.Request("DELETE", url, opts) +} + func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) { switch client.Type { case "compute": From 4c27b0df5332def8d90a39496ca3d9fa814861d1 Mon Sep 17 00:00:00 2001 From: Zhenguo Niu Date: Tue, 2 Jul 2019 19:15:24 +0800 Subject: [PATCH 2/2] Fix Delete issue --- openstack/sdrs/v1/protectiongroups/requests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstack/sdrs/v1/protectiongroups/requests.go b/openstack/sdrs/v1/protectiongroups/requests.go index 3b5249fee..efa59baf1 100644 --- a/openstack/sdrs/v1/protectiongroups/requests.go +++ b/openstack/sdrs/v1/protectiongroups/requests.go @@ -88,6 +88,6 @@ func Get(c *golangsdk.ServiceClient, id string) (r GetResult) { func Delete(c *golangsdk.ServiceClient, id string) (r JobResult) { reqOpt := &golangsdk.RequestOpts{OkCodes: []int{200}, MoreHeaders: RequestOpts.MoreHeaders} - _, r.Err = c.DeleteWithResponse(resourceURL(c, &r.Body, id), reqOpt) + _, r.Err = c.DeleteWithResponse(resourceURL(c, id), &r.Body, reqOpt) return }