From 0167c6eb2282a3ca4ba06a0aa387dc9639c70f6b Mon Sep 17 00:00:00 2001 From: Walter Fender Date: Tue, 29 Aug 2017 14:51:07 -0700 Subject: [PATCH] Implement GetZoneByProviderID & GetZoneByNodeName Adding an implementation of GetZoneByProviderID & GetZoneByNodeName for GCE. This is related to ticket 50926. This was tested as part of the ongoing separate GCE cloud provider work. Added unit test. Fix for wojtek-t (borrowed from FengyunPan) --- pkg/cloudprovider/providers/gce/gce_test.go | 58 +++++++++++++++++++- pkg/cloudprovider/providers/gce/gce_zones.go | 22 +++++++- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/pkg/cloudprovider/providers/gce/gce_test.go b/pkg/cloudprovider/providers/gce/gce_test.go index cc8a70300b7..14d4e703418 100644 --- a/pkg/cloudprovider/providers/gce/gce_test.go +++ b/pkg/cloudprovider/providers/gce/gce_test.go @@ -27,6 +27,7 @@ import ( computealpha "google.golang.org/api/compute/v0.alpha" computebeta "google.golang.org/api/compute/v0.beta" computev1 "google.golang.org/api/compute/v1" + "k8s.io/kubernetes/pkg/cloudprovider" ) func TestReadConfigFile(t *testing.T) { @@ -281,7 +282,7 @@ func TestSplitProviderID(t *testing.T) { for _, test := range providers { project, zone, instance, err := splitProviderID(test.providerID) if (err != nil) != test.fail { - t.Errorf("Expected to failt=%t, with pattern %v", test.fail, test) + t.Errorf("Expected to fail=%t, with pattern %v", test.fail, test) } if test.fail { @@ -300,6 +301,61 @@ func TestSplitProviderID(t *testing.T) { } } +func TestGetZoneByProviderID(t *testing.T) { + tests := []struct { + providerID string + + expectedZone cloudprovider.Zone + + fail bool + description string + }{ + { + providerID: ProviderName + "://project-example-164317/us-central1-f/kubernetes-node-fhx1", + expectedZone: cloudprovider.Zone{FailureDomain: "us-central1-f", Region: "us-central1"}, + fail: false, + description: "standard gce providerID", + }, + { + providerID: ProviderName + "://project-example-164317/us-central1-f/kubernetes-node-fhx1/", + expectedZone: cloudprovider.Zone{}, + fail: true, + description: "too many slashes('/') trailing", + }, + { + providerID: ProviderName + "://project-example.164317//kubernetes-node-fhx1", + expectedZone: cloudprovider.Zone{}, + fail: true, + description: "too many slashes('/') embedded", + }, + { + providerID: ProviderName + "://project-example-164317/uscentral1f/kubernetes-node-fhx1", + expectedZone: cloudprovider.Zone{}, + fail: true, + description: "invalid name of the GCE zone", + }, + } + + gce := &GCECloud{ + localZone: "us-central1-f", + region: "us-central1", + } + for _, test := range tests { + zone, err := gce.GetZoneByProviderID(test.providerID) + if (err != nil) != test.fail { + t.Errorf("Expected to fail=%t, provider ID %v, tests %s", test.fail, test, test.description) + } + + if test.fail { + continue + } + + if zone != test.expectedZone { + t.Errorf("Expected %v, but got %v", test.expectedZone, zone) + } + } +} + func TestGenerateCloudConfigs(t *testing.T) { configBoilerplate := ConfigGlobal{ TokenURL: "", diff --git a/pkg/cloudprovider/providers/gce/gce_zones.go b/pkg/cloudprovider/providers/gce/gce_zones.go index 107bb878f54..26ccc37740c 100644 --- a/pkg/cloudprovider/providers/gce/gce_zones.go +++ b/pkg/cloudprovider/providers/gce/gce_zones.go @@ -17,7 +17,6 @@ limitations under the License. package gce import ( - "errors" "fmt" "strings" @@ -43,14 +42,31 @@ func (gce *GCECloud) GetZone() (cloudprovider.Zone, error) { // This is particularly useful in external cloud providers where the kubelet // does not initialize node data. func (gce *GCECloud) GetZoneByProviderID(providerID string) (cloudprovider.Zone, error) { - return cloudprovider.Zone{}, errors.New("GetZoneByProviderID not implemented") + _, zone, _, err := splitProviderID(providerID) + if err != nil { + return cloudprovider.Zone{}, err + } + region, err := GetGCERegion(zone) + if err != nil { + return cloudprovider.Zone{}, err + } + return cloudprovider.Zone{FailureDomain: zone, Region: region}, nil } // GetZoneByNodeName implements Zones.GetZoneByNodeName // This is particularly useful in external cloud providers where the kubelet // does not initialize node data. func (gce *GCECloud) GetZoneByNodeName(nodeName types.NodeName) (cloudprovider.Zone, error) { - return cloudprovider.Zone{}, errors.New("GetZoneByNodeName not imeplemented") + instanceName := mapNodeNameToInstanceName(nodeName) + instance, err := gce.getInstanceByName(instanceName) + if err != nil { + return cloudprovider.Zone{}, err + } + region, err := GetGCERegion(instance.Zone) + if err != nil { + return cloudprovider.Zone{}, err + } + return cloudprovider.Zone{FailureDomain: instance.Zone, Region: region}, nil } // ListZonesInRegion returns all zones in a GCP region