From 427affbb43879fe0db3259c78a8bb35e0eb59f37 Mon Sep 17 00:00:00 2001 From: Zhenguo Niu Date: Mon, 17 Sep 2018 17:22:33 +0800 Subject: [PATCH 1/3] Add ELB certificates support --- .../elbaas/certificates/requests.go | 104 ++++++++++++++++++ .../extensions/elbaas/certificates/results.go | 63 +++++++++++ .../v2/extensions/elbaas/certificates/urls.go | 16 +++ 3 files changed, 183 insertions(+) create mode 100644 openstack/networking/v2/extensions/elbaas/certificates/requests.go create mode 100644 openstack/networking/v2/extensions/elbaas/certificates/results.go create mode 100644 openstack/networking/v2/extensions/elbaas/certificates/urls.go diff --git a/openstack/networking/v2/extensions/elbaas/certificates/requests.go b/openstack/networking/v2/extensions/elbaas/certificates/requests.go new file mode 100644 index 000000000..3f1946e71 --- /dev/null +++ b/openstack/networking/v2/extensions/elbaas/certificates/requests.go @@ -0,0 +1,104 @@ +package certificates + +import ( + "log" + + "github.com/huaweicloud/golangsdk" +) + +// CreateOptsBuilder is the interface options structs have to satisfy in order +// to be used in the main Create operation in this package. Since many +// extensions decorate or modify the common logic, it is useful for them to +// satisfy a basic interface in order for them to be used. +type CreateOptsBuilder interface { + ToCertificateCreateMap() (map[string]interface{}, error) +} + +// CreateOpts is the common options struct used in this package's Create +// operation. +type CreateOpts struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Domain string `json:"domain,omitempty"` + Certificate string `json:"certificate" required:"true"` + PrivateKey string `json:"private_key" required:"true"` +} + +// ToCertificateCreateMap casts a CreateOpts struct to a map. +func (opts CreateOpts) ToCertificateCreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +// Create is an operation which provisions a new loadbalancer based on the +// configuration defined in the CreateOpts struct. Once the request is +// validated and progress has started on the provisioning process, a +// CreateResult will be returned. +// +// Users with an admin role can create loadbalancers on behalf of other tenants by +// specifying a TenantID attribute different than their own. +func Create(c *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToCertificateCreateMap() + if err != nil { + r.Err = err + return + } + log.Printf("[DEBUG] create url:%q, body=%#v", rootURL(c), b) + reqOpt := &golangsdk.RequestOpts{OkCodes: []int{200}} + _, r.Err = c.Post(rootURL(c), b, &r.Body, reqOpt) + return +} + +// Get retrieves a particular Loadbalancer based on its unique ID. +func Get(c *golangsdk.ServiceClient, id string) (r GetResult) { + r.ID = id + _, r.Err = c.Get(rootURL(c), &r.Body, nil) + return +} + +// UpdateOptsBuilder is the interface options structs have to satisfy in order +// to be used in the main Update operation in this package. Since many +// extensions decorate or modify the common logic, it is useful for them to +// satisfy a basic interface in order for them to be used. +type UpdateOptsBuilder interface { + ToCertificateUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts is the common options struct used in this package's Update +// operation. +type UpdateOpts struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` +} + +func (u UpdateOpts) IsNeedUpdate() (bool, error) { + d, e := u.ToCertificateUpdateMap() + if e == nil { + return len(d) != 0, nil + } + return false, e +} + +// ToCertificateUpdateMap casts a UpdateOpts struct to a map. +func (opts UpdateOpts) ToCertificateUpdateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +// Update is an operation which modifies the attributes of the specified Certificate. +func Update(c *golangsdk.ServiceClient, id string, opts UpdateOpts) (r UpdateResult) { + b, err := opts.ToCertificateUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// Delete will permanently delete a particular Certificate based on its unique ID. +func Delete(c *golangsdk.ServiceClient, id string) (r DeleteResult) { + reqOpt := &golangsdk.RequestOpts{OkCodes: []int{204}} + _, r.Err = c.Delete(resourceURL(c, id), reqOpt) + return +} diff --git a/openstack/networking/v2/extensions/elbaas/certificates/results.go b/openstack/networking/v2/extensions/elbaas/certificates/results.go new file mode 100644 index 000000000..4bc7fbdc1 --- /dev/null +++ b/openstack/networking/v2/extensions/elbaas/certificates/results.go @@ -0,0 +1,63 @@ +package certificates + +import ( + "github.com/huaweicloud/golangsdk" +) + +type Certificate struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Domain string `json:"domain"` + Certificate string `json:"certificate"` + PrivateKey string `json:"private_key"` + CreateTime string `json:"create_time"` + UpdateTime string `json:"update_time"` +} + +type commonResult struct { + golangsdk.Result +} + +func (r commonResult) Extract() (*Certificate, error) { + s := &Certificate{} + return s, r.ExtractInto(s) +} + +type CreateResult struct { + commonResult +} + +// DeleteResult represents the result of a delete operation. +type DeleteResult struct { + golangsdk.ErrResult +} + +type getResponse struct { + Certificates []Certificate `json:"certificates"` + InstanceNum string `json:"instance_num"` +} + +// GetResult represents the result of a get operation. +type GetResult struct { + ID string + golangsdk.Result +} + +func (r GetResult) Extract() (*Certificate, error) { + s := &getResponse{} + err := r.ExtractInto(s) + if err == nil { + for _, c := range s.Certificates { + if c.ID == r.ID { + return &c, nil + } + } + return nil, golangsdk.ErrDefault404{} + } + return nil, err +} + +type UpdateResult struct { + commonResult +} diff --git a/openstack/networking/v2/extensions/elbaas/certificates/urls.go b/openstack/networking/v2/extensions/elbaas/certificates/urls.go new file mode 100644 index 000000000..7da33522e --- /dev/null +++ b/openstack/networking/v2/extensions/elbaas/certificates/urls.go @@ -0,0 +1,16 @@ +package certificates + +import "github.com/huaweicloud/golangsdk" + +const ( + rootPath = "elbaas" + resourcePath = "certificate" +) + +func rootURL(c *golangsdk.ServiceClient) string { + return c.ServiceURL(c.ProjectID, rootPath, resourcePath) +} + +func resourceURL(c *golangsdk.ServiceClient, id string) string { + return c.ServiceURL(c.ProjectID, rootPath, resourcePath, id) +} From e1dbd096db13b7bb90eb1d39a046f5addb557665 Mon Sep 17 00:00:00 2001 From: Zhenguo Niu Date: Mon, 17 Sep 2018 20:02:51 +0800 Subject: [PATCH 2/3] Add NewElbV2 client --- openstack/client.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/openstack/client.go b/openstack/client.go index adfb52706..cad7b63ae 100644 --- a/openstack/client.go +++ b/openstack/client.go @@ -521,17 +521,24 @@ func NewLoadBalancerV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOp return sc, err } -// NewOtcV1 creates a ServiceClient that may be used with the v1 network package. +// NewElbV1 creates a ServiceClient that may be used with the v1 network package. func NewElbV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts, otctype string) (*golangsdk.ServiceClient, error) { sc, err := initClientOpts(client, eo, "compute") - //fmt.Printf("client=%+v.\n", sc) sc.Endpoint = strings.Replace(strings.Replace(sc.Endpoint, "ecs", otctype, 1), "/v2/", "/v1.0/", 1) - //fmt.Printf("url=%s.\n", sc.Endpoint) sc.ResourceBase = sc.Endpoint sc.Type = otctype return sc, err } +// NewElbV2 creates a ServiceClient that may be used with the v1 network package. +func NewElbV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "compute") + sc.Endpoint = strings.Replace(strings.Replace(sc.Endpoint, "ecs", "elb", 1), "/v2/", "/v2.0/", 1) + sc.ResourceBase = sc.Endpoint + sc.Type = "elb" + return sc, err +} + // NewSmnServiceV2 creates a ServiceClient that may be used to access the v2 Simple Message Notification service. func NewSmnServiceV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { From 6b09557de3bae8252a5d8df12b714219db8c250e Mon Sep 17 00:00:00 2001 From: Zhenguo Niu Date: Mon, 17 Sep 2018 20:26:48 +0800 Subject: [PATCH 3/3] Update ELB UpdateOpts --- .../networking/v2/extensions/elbaas/certificates/requests.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openstack/networking/v2/extensions/elbaas/certificates/requests.go b/openstack/networking/v2/extensions/elbaas/certificates/requests.go index 3f1946e71..0f0011b31 100644 --- a/openstack/networking/v2/extensions/elbaas/certificates/requests.go +++ b/openstack/networking/v2/extensions/elbaas/certificates/requests.go @@ -68,6 +68,9 @@ type UpdateOptsBuilder interface { type UpdateOpts struct { Name string `json:"name,omitempty"` Description string `json:"description,omitempty"` + Domain string `json:"domain,omitempty"` + Certificate string `json:"certificate" required:"true"` + PrivateKey string `json:"private_key" required:"true"` } func (u UpdateOpts) IsNeedUpdate() (bool, error) {