From aa95545322585d5f8d63d858073d02cbb26d3a65 Mon Sep 17 00:00:00 2001 From: click2cloud-ninja-vlogs Date: Tue, 20 Nov 2018 16:40:36 +0530 Subject: [PATCH 1/2] Fix cce cluster Endpoints field In OTC Cloud,cce Get and List cluster Endpoints field require struct type but not list of struct type ,contrary to other clouds, so this commit handles that. --- openstack/cce/v3/clusters/results.go | 53 ++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/openstack/cce/v3/clusters/results.go b/openstack/cce/v3/clusters/results.go index 09b2d6625..629451ae2 100644 --- a/openstack/cce/v3/clusters/results.go +++ b/openstack/cce/v3/clusters/results.go @@ -1,6 +1,8 @@ package clusters import ( + "encoding/json" + "github.com/huaweicloud/golangsdk" ) @@ -87,7 +89,7 @@ type Status struct { //The status of each component in the cluster Conditions Conditions `json:"conditions"` //Kube-apiserver access address in the cluster - Endpoints []Endpoints `json:"endpoints"` + Endpoints []Endpoints `json:"-"` } type Conditions struct { @@ -100,10 +102,55 @@ type Conditions struct { } type Endpoints struct { - //The address accessed within the user's subnet + //The address accessed within the user's subnet - Huawei Url string `json:"url"` - //Public network access address + //Public network access address - Huawei Type string `json:"type"` + //Internal network address - OTC + Internal string `json:"internal"` + //External network address - OTC + External string `json:"external"` + //Endpoint of the cluster to be accessed through API Gateway - OTC + ExternalOTC string `json:"external_otc"` +} + +// UnmarshalJSON helps to unmarshal Status fields into needed values. +//OTC and Huawei have different data types and child fields for `endpoints` field in Cluster Status. +//This function handles the unmarshal for both +func (r *Status) UnmarshalJSON(b []byte) error { + type tmp Status + var s struct { + tmp + Endpoints []Endpoints `json:"endpoints"` + } + + err := json.Unmarshal(b, &s) + + if err != nil { + switch err.(type) { + case *json.UnmarshalTypeError: //check if type error occurred (handles the different endpoint structure for huawei and otc) + var s struct { + tmp + Endpoints Endpoints `json:"endpoints"` + } + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = Status(s.tmp) + r.Endpoints = []Endpoints{{Internal: s.Endpoints.Internal, + External: s.Endpoints.External, + ExternalOTC: s.Endpoints.ExternalOTC}} + return nil + default: + return err + } + } + + *r = Status(s.tmp) + r.Endpoints = s.Endpoints + + return err } type commonResult struct { From ffb60c0dfa4cbd5b03d59c65ffbd327a8425efb4 Mon Sep 17 00:00:00 2001 From: click2cloud-ninja-vlogs Date: Tue, 20 Nov 2018 18:31:39 +0530 Subject: [PATCH 2/2] add unit tests for otc cce cluster get and list --- openstack/cce/v3/clusters/testing/fixtures.go | 119 ++++++++++++++++++ .../cce/v3/clusters/testing/requests_test.go | 47 +++++++ 2 files changed, 166 insertions(+) diff --git a/openstack/cce/v3/clusters/testing/fixtures.go b/openstack/cce/v3/clusters/testing/fixtures.go index 037533a62..384693657 100644 --- a/openstack/cce/v3/clusters/testing/fixtures.go +++ b/openstack/cce/v3/clusters/testing/fixtures.go @@ -36,6 +36,38 @@ const Output = ` } }` +const OutputOTC = ` +{ + "kind": "Cluster", + "apiVersion": "v3", + "metadata": { + "name": "test-cluster", + "uid": "daa97872-59d7-11e8-a787-0255ac101f54" + }, + "spec": { + "type": "VirtualMachine", + "flavor": "cce.s1.small", + "version": "v1.7.3-r10", + "hostNetwork": { + "vpc": "3305eb40-2707-4940-921c-9f335f84a2ca", + "subnet": "00e41db7-e56b-4946-bf91-27bb9effd664" + }, + "containerNetwork": { + "mode": "overlay_l2" + }, + "billingMode": 0 + }, + "status": { + "phase": "Available", + "endpoints": { + "internal": "https://192.168.0.68:5443", + "external": "https://10.34.56.78:5443", + "external_otc": "https://4d1ecb2c-229a-11e8-9c75-0255ac100ceb.container.eu-de.otc.t-systems.com" + } + + } +}` + var Expected = &clusters.Clusters{ Kind: "Cluster", ApiVersion: "v3", @@ -64,6 +96,35 @@ var Expected = &clusters.Clusters{ }, } +var ExpectedOTC = &clusters.Clusters{ + Kind: "Cluster", + ApiVersion: "v3", + Metadata: clusters.MetaData{ + Name: "test-cluster", + Id: "daa97872-59d7-11e8-a787-0255ac101f54", + }, + Spec: clusters.Spec{ + Type: "VirtualMachine", + Flavor: "cce.s1.small", + Version: "v1.7.3-r10", + HostNetwork: clusters.HostNetworkSpec{ + VpcId: "3305eb40-2707-4940-921c-9f335f84a2ca", + SubnetId: "00e41db7-e56b-4946-bf91-27bb9effd664", + }, + ContainerNetwork: clusters.ContainerNetworkSpec{ + Mode: "overlay_l2", + }, + BillingMode: 0, + }, + Status: clusters.Status{ + Phase: "Available", + Endpoints: []clusters.Endpoints{ + {Internal: "https://192.168.0.68:5443", External: "https://10.34.56.78:5443", + ExternalOTC: "https://4d1ecb2c-229a-11e8-9c75-0255ac100ceb.container.eu-de.otc.t-systems.com"}, + }, + }, +} + const ListOutput = ` { "items": [ @@ -101,6 +162,42 @@ const ListOutput = ` } ` +const ListOutputOTC = ` +{ + "items": [ + { + "kind": "Cluster", + "apiVersion": "v3", + "metadata": { + "name": "test123", + "uid": "daa97872-59d7-11e8-a787-0255ac101f54" + }, + "spec": { + "type": "VirtualMachine", + "flavor": "cce.s1.small", + "version": "v1.7.3-r10", + "hostNetwork": { + "vpc": "3305eb40-2707-4940-921c-9f335f84a2ca", + "subnet": "00e41db7-e56b-4946-bf91-27bb9effd664" + }, + "containerNetwork": { + "mode": "overlay_l2" + }, + "billingMode": 0 + }, + "status": { + "phase": "Available", + "endpoints": { + "internal": "https://192.168.0.68:5443", + "external": "https://10.34.56.78:5443", + "external_otc": "https://4d1ecb2c-229a-11e8-9c75-0255ac100ceb.container.eu-de.otc.t-systems.com" + } + } + } + ] +} +` + var ListExpected = []clusters.Clusters{ { Kind: "Cluster", @@ -116,3 +213,25 @@ var ListExpected = []clusters.Clusters{ Status: clusters.Status{Phase: "Available", Endpoints: []clusters.Endpoints{{Url: "https://192.168.0.68:5443", Type: "Internal"}}}, }, } + +var ListExpectedOTC = []clusters.Clusters{ + { + Kind: "Cluster", + ApiVersion: "v3", + Metadata: clusters.MetaData{Name: "test123", Id: "daa97872-59d7-11e8-a787-0255ac101f54"}, + Spec: clusters.Spec{Type: "VirtualMachine", + Flavor: "cce.s1.small", + HostNetwork: clusters.HostNetworkSpec{VpcId: "3305eb40-2707-4940-921c-9f335f84a2ca", SubnetId: "00e41db7-e56b-4946-bf91-27bb9effd664"}, + ContainerNetwork: clusters.ContainerNetworkSpec{Mode: "overlay_l2"}, + BillingMode: 0, + Version: "v1.7.3-r10", + }, + Status: clusters.Status{ + Phase: "Available", + Endpoints: []clusters.Endpoints{ + {Internal: "https://192.168.0.68:5443", External: "https://10.34.56.78:5443", + ExternalOTC: "https://4d1ecb2c-229a-11e8-9c75-0255ac100ceb.container.eu-de.otc.t-systems.com"}, + }, + }, + }, +} diff --git a/openstack/cce/v3/clusters/testing/requests_test.go b/openstack/cce/v3/clusters/testing/requests_test.go index e4f2a3d87..8cc22b551 100644 --- a/openstack/cce/v3/clusters/testing/requests_test.go +++ b/openstack/cce/v3/clusters/testing/requests_test.go @@ -29,6 +29,25 @@ func TestGetV3Cluster(t *testing.T) { } +func TestGetV3ClusterOTC(t *testing.T) { + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/api/v3/projects/c59fd21fd2a94963b822d8985b884673/clusters/daa97872-59d7-11e8-a787-0255ac101f54", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, OutputOTC) + }) + + actual, err := clusters.Get(fake.ServiceClient(), "daa97872-59d7-11e8-a787-0255ac101f54").Extract() + th.AssertNoErr(t, err) + expected := ExpectedOTC + th.AssertDeepEquals(t, expected, actual) + +} + func TestListV3Cluster(t *testing.T) { th.SetupHTTP() @@ -55,6 +74,34 @@ func TestListV3Cluster(t *testing.T) { th.AssertDeepEquals(t, expected, actual) } + +func TestListV3ClusterOTC(t *testing.T) { + + th.SetupHTTP() + defer th.TeardownHTTP() + + th.Mux.HandleFunc("/api/v3/projects/c59fd21fd2a94963b822d8985b884673/clusters", func(w http.ResponseWriter, r *http.Request) { + th.TestMethod(t, r, "GET") + th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) + + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + fmt.Fprintf(w, ListOutputOTC) + }) + + //count := 0 + + actual, err := clusters.List(fake.ServiceClient(), clusters.ListOpts{}) + if err != nil { + t.Errorf("Failed to extract clusters: %v", err) + } + + expected := ListExpectedOTC + + th.AssertDeepEquals(t, expected, actual) +} + func TestCreateV3Cluster(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP()