From 78bf6c3a1503fd46d31949e31352cf829b0762b5 Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Wed, 14 Apr 2021 15:58:28 +0800 Subject: [PATCH] enhance the sdk of cce addon to support listing addon instances --- openstack/cce/v3/addons/requests.go | 89 +++++++++++++++++++++++++---- openstack/cce/v3/addons/results.go | 67 ++++++++++++++++++---- openstack/cce/v3/addons/urls.go | 9 ++- 3 files changed, 143 insertions(+), 22 deletions(-) diff --git a/openstack/cce/v3/addons/requests.go b/openstack/cce/v3/addons/requests.go index 56a83ec11..1b54457b2 100644 --- a/openstack/cce/v3/addons/requests.go +++ b/openstack/cce/v3/addons/requests.go @@ -1,11 +1,85 @@ package addons import ( + "reflect" + "github.com/huaweicloud/golangsdk" ) -var RequestOpts golangsdk.RequestOpts = golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json"}, +// ListOpts allows the filtering of list data using given parameters. +type ListOpts struct { + AddonTemplateName string `json:"addonTemplateName"` + Uid string `json:"uid"` + Version string `json:"version"` + Status string `json:"status"` +} + +// List returns collection of addons. +func List(client *golangsdk.ServiceClient, clusterID string, opts ListOpts) ([]Addon, error) { + var r ListResult + _, r.Err = client.Get(resourceListURL(client, clusterID), &r.Body, nil) + + allAddons, err := r.ExtractAddon() + + if err != nil { + return nil, err + } + + return FilterAddons(allAddons, opts), nil +} + +func FilterAddons(addons []Addon, opts ListOpts) []Addon { + + var refinedAddons []Addon + var matched bool + + m := map[string]FilterStruct{} + + if opts.AddonTemplateName != "" { + m["AddonTemplateName"] = FilterStruct{Value: opts.AddonTemplateName, Driller: []string{"Spec"}} + } + if opts.Version != "" { + m["Version"] = FilterStruct{Value: opts.Version, Driller: []string{"Spec"}} + } + if opts.Uid != "" { + m["Id"] = FilterStruct{Value: opts.Uid, Driller: []string{"Metadata"}} + } + if opts.Status != "" { + m["Status"] = FilterStruct{Value: opts.Status, Driller: []string{"Status"}} + } + + if len(m) > 0 && len(addons) > 0 { + for _, addon := range addons { + matched = true + + for key, value := range m { + if sVal := GetStructNestedField(&addon, key, value.Driller); sVal != value.Value { + matched = false + break + } + } + if matched { + refinedAddons = append(refinedAddons, addon) + } + } + } + + return refinedAddons +} + +func GetStructNestedField(v *Addon, field string, structDriller []string) string { + r := reflect.ValueOf(v) + for _, drillField := range structDriller { + f := reflect.Indirect(r).FieldByName(drillField).Interface() + r = reflect.ValueOf(f) + } + f1 := reflect.Indirect(r).FieldByName(field) + return string(f1.String()) +} + +type FilterStruct struct { + Value string + Driller []string } // CreateOptsBuilder allows extensions to add additional parameters to the @@ -71,18 +145,13 @@ func Create(c *golangsdk.ServiceClient, opts CreateOptsBuilder, cluster_id strin // Get retrieves a particular addon based on its unique ID. func Get(c *golangsdk.ServiceClient, id, cluster_id string) (r GetResult) { - _, r.Err = c.Get(resourceURL(c, id, cluster_id), &r.Body, &golangsdk.RequestOpts{ - OkCodes: []int{200}, - MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, - }) + _, r.Err = c.Get(resourceURL(c, id, cluster_id), &r.Body, nil) return } // Delete will permanently delete a particular addon based on its unique ID. func Delete(c *golangsdk.ServiceClient, id, cluster_id string) (r DeleteResult) { - _, r.Err = c.Delete(resourceURL(c, id, cluster_id), &golangsdk.RequestOpts{ - OkCodes: []int{200}, - MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, - }) + reqOpt := &golangsdk.RequestOpts{OkCodes: []int{200}} + _, r.Err = c.Delete(resourceURL(c, id, cluster_id), reqOpt) return } diff --git a/openstack/cce/v3/addons/results.go b/openstack/cce/v3/addons/results.go index f59ca6ddb..8edc5d1a6 100644 --- a/openstack/cce/v3/addons/results.go +++ b/openstack/cce/v3/addons/results.go @@ -4,15 +4,24 @@ import ( "github.com/huaweicloud/golangsdk" ) +type ListAddon struct { + // API type, fixed value "List" + Kind string `json:"kind"` + // API version, fixed value "v3" + Apiversion string `json:"apiVersion"` + // all Node Pools + Addons []Addon `json:"items"` +} + type Addon struct { // API type, fixed value Addon - Kind string `json:"kind" required:"true"` + Kind string `json:"kind"` // API version, fixed value v3 - ApiVersion string `json:"apiVersion" required:"true"` + ApiVersion string `json:"apiVersion"` // Metadata of an Addon - Metadata MetaData `json:"metadata" required:"true"` + Metadata MetaData `json:"metadata"` // Specifications of an Addon - Spec Spec `json:"spec" required:"true"` + Spec Spec `json:"spec"` // Status of an Addon Status Status `json:"status"` } @@ -32,19 +41,19 @@ type MetaData struct { //Specifications to create an addon type Spec struct { // For the addon version. - Version string `json:"version" required:"true"` + Version string `json:"version"` // Cluster ID. - ClusterID string `json:"clusterID" required:"true"` + ClusterID string `json:"clusterID"` // Addon Template Name. - AddonTemplateName string `json:"addonTemplateName" required:"true"` + AddonTemplateName string `json:"addonTemplateName"` // Addon Template Type. - AddonTemplateType string `json:"addonTemplateType" required:"true"` + AddonTemplateType string `json:"addonTemplateType"` // Addon Template Labels. - AddonTemplateLables []string `json:"addonTemplateLables,omitempty"` + AddonTemplateLables []string `json:"addonTemplateLables"` // Addon Description. - Description string `json:"description" required:"true"` + Description string `json:"description"` // Addon Parameters - Values Values `json:"values" required:"true"` + Values Values `json:"values"` } type Status struct { @@ -56,8 +65,27 @@ type Status struct { Message string `json:"message"` //The target versions of the addon TargetVersions []string `json:"targetVersions"` + //Current version of the addon + CurrentVersion Versions `json:"currentVersion"` +} + +type Versions struct { + // Version of the addon + Version string `json:"version"` + // The installing param of the addon + Input map[string]interface{} `json:"input"` + // Wether it is a stable version + Stable bool `json:"stable"` + // Translate information + Translate map[string]interface{} `json:"translate"` + // Supported versions + SupportVersions []SupportVersions `json:"supportVersions"` } +type SupportVersions struct { + ClusterType string `json:"clusterType"` + ClusterVersion []string `json:"clusterVersion"` +} type commonResult struct { golangsdk.Result } @@ -69,6 +97,23 @@ func (r commonResult) Extract() (*Addon, error) { return &s, err } +// ExtractAddon is a function that accepts a ListOpts struct, which allows you to filter and sort +// the returned collection for greater efficiency. +func (r commonResult) ExtractAddon() ([]Addon, error) { + var s ListAddon + err := r.ExtractInto(&s) + if err != nil { + return nil, err + } + return s.Addons, nil +} + +// ListResult represents the result of a list operation. Call its ExtractAddon +// method to interpret it as a Addon. +type ListResult struct { + commonResult +} + // CreateResult represents the result of a create operation. Call its Extract // method to interpret it as an Addon. type CreateResult struct { diff --git a/openstack/cce/v3/addons/urls.go b/openstack/cce/v3/addons/urls.go index 4e4b0fee4..888216127 100644 --- a/openstack/cce/v3/addons/urls.go +++ b/openstack/cce/v3/addons/urls.go @@ -1,6 +1,7 @@ package addons import ( + "net/url" "strings" "github.com/huaweicloud/golangsdk" @@ -18,7 +19,13 @@ func resourceURL(client *golangsdk.ServiceClient, id, cluster_id string) string return CCEServiceURL(client, cluster_id, rootPath, id+"?cluster_id="+cluster_id) } +func resourceListURL(client *golangsdk.ServiceClient, cluster_id string) string { + return CCEServiceURL(client, cluster_id, rootPath+"?cluster_id="+cluster_id) +} + func CCEServiceURL(client *golangsdk.ServiceClient, cluster_id string, parts ...string) string { - rbUrl := "https://" + cluster_id + "." + client.ResourceBaseURL()[8:] + u, _ := url.Parse(client.ResourceBaseURL()) + u.Host = cluster_id + "." + u.Host + rbUrl := u.String() return rbUrl + strings.Join(parts, "/") }