From ac48b1b075efa31f2109f818159bcaff95947609 Mon Sep 17 00:00:00 2001 From: Bowei Du Date: Wed, 10 Jan 2018 12:15:44 -0800 Subject: [PATCH] Add `cloud` for the generated GCE interfaces, support structs Note: this does not wire the generated code. --- pkg/cloudprovider/providers/gce/BUILD | 3 + pkg/cloudprovider/providers/gce/gce.go | 35 ++++++++---- pkg/cloudprovider/providers/gce/support.go | 66 ++++++++++++++++++++++ 3 files changed, 92 insertions(+), 12 deletions(-) create mode 100644 pkg/cloudprovider/providers/gce/support.go diff --git a/pkg/cloudprovider/providers/gce/BUILD b/pkg/cloudprovider/providers/gce/BUILD index b112c95912c..c6583798dc8 100644 --- a/pkg/cloudprovider/providers/gce/BUILD +++ b/pkg/cloudprovider/providers/gce/BUILD @@ -41,12 +41,15 @@ go_library( "gce_util.go", "gce_zones.go", "metrics.go", + "support.go", "token_source.go", ], importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/gce", deps = [ "//pkg/api/v1/service:go_default_library", "//pkg/cloudprovider:go_default_library", + "//pkg/cloudprovider/providers/gce/cloud:go_default_library", + "//pkg/cloudprovider/providers/gce/cloud/meta:go_default_library", "//pkg/controller:go_default_library", "//pkg/kubelet/apis:go_default_library", "//pkg/master/ports:go_default_library", diff --git a/pkg/cloudprovider/providers/gce/gce.go b/pkg/cloudprovider/providers/gce/gce.go index b515c8ff67a..b734a9b8d8e 100644 --- a/pkg/cloudprovider/providers/gce/gce.go +++ b/pkg/cloudprovider/providers/gce/gce.go @@ -30,6 +30,13 @@ import ( gcfg "gopkg.in/gcfg.v1" "cloud.google.com/go/compute/metadata" + "github.com/golang/glog" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + computealpha "google.golang.org/api/compute/v0.alpha" + computebeta "google.golang.org/api/compute/v0.beta" + compute "google.golang.org/api/compute/v1" + container "google.golang.org/api/container/v1" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" @@ -41,18 +48,12 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" "k8s.io/client-go/util/flowcontrol" + "k8s.io/kubernetes/pkg/cloudprovider" + "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud" "k8s.io/kubernetes/pkg/controller" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" "k8s.io/kubernetes/pkg/version" - - "github.com/golang/glog" - "golang.org/x/oauth2" - "golang.org/x/oauth2/google" - computealpha "google.golang.org/api/compute/v0.alpha" - computebeta "google.golang.org/api/compute/v0.beta" - compute "google.golang.org/api/compute/v1" - container "google.golang.org/api/container/v1" ) const ( @@ -147,6 +148,9 @@ type GCECloud struct { // the corresponding api is enabled. // If not enabled, it should return error. AlphaFeatureGate *AlphaFeatureGate + + // New code generated interface to the GCE compute library. + c cloud.Cloud } // TODO: replace gcfg with json @@ -243,7 +247,6 @@ func newGCECloud(config io.Reader) (gceCloud *GCECloud, err error) { return nil, err } return CreateGCECloud(cloudConfig) - } func readConfig(reader io.Reader) (*ConfigFile, error) { @@ -363,11 +366,12 @@ func generateCloudConfig(configFile *ConfigFile) (cloudConfig *CloudConfig, err // If no tokenSource is specified, uses oauth2.DefaultTokenSource. // If managedZones is nil / empty all zones in the region will be managed. func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { - // Remove any pre-release version and build metadata from the semver, leaving only the MAJOR.MINOR.PATCH portion. - // See http://semver.org/. + // Remove any pre-release version and build metadata from the semver, + // leaving only the MAJOR.MINOR.PATCH portion. See http://semver.org/. version := strings.TrimLeft(strings.Split(strings.Split(version.Get().GitVersion, "-")[0], "+")[0], "v") - // Create a user-agent header append string to supply to the Google API clients, to identify Kubernetes as the origin of the GCP API calls. + // Create a user-agent header append string to supply to the Google API + // clients, to identify Kubernetes as the origin of the GCP API calls. userAgent := fmt.Sprintf("Kubernetes/%s (%s %s)", version, runtime.GOOS, runtime.GOARCH) // Use ProjectID for NetworkProjectID, if it wasn't explicitly set. @@ -506,6 +510,13 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { } gce.manager = &gceServiceManager{gce} + gce.c = cloud.NewGCE(&cloud.Service{ + GA: service, + Alpha: serviceAlpha, + Beta: serviceBeta, + ProjectRouter: &gceProjectRouter{gce}, + RateLimiter: &gceRateLimiter{gce}, + }) return gce, nil } diff --git a/pkg/cloudprovider/providers/gce/support.go b/pkg/cloudprovider/providers/gce/support.go new file mode 100644 index 00000000000..42903af4579 --- /dev/null +++ b/pkg/cloudprovider/providers/gce/support.go @@ -0,0 +1,66 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package gce + +import ( + "context" + + "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud" + "k8s.io/kubernetes/pkg/cloudprovider/providers/gce/cloud/meta" +) + +// gceProjectRouter sends requests to the appropriate project ID. +type gceProjectRouter struct { + gce *GCECloud +} + +// ProjectID returns the project ID to be used for the given operation. +func (r *gceProjectRouter) ProjectID(ctx context.Context, version meta.Version, service string) string { + switch service { + case "Firewalls", "Routes": + return r.gce.NetworkProjectID() + default: + return r.gce.projectID + } +} + +// gceRateLimiter implements cloud.RateLimiter. +type gceRateLimiter struct { + gce *GCECloud +} + +// Accept blocks until the operation can be performed. +// +// TODO: the current cloud provider policy doesn't seem to be correct as it +// only rate limits the polling operations, but not the /submission/ of +// operations. +func (l *gceRateLimiter) Accept(ctx context.Context, key *cloud.RateLimitKey) error { + if key.Operation == "Get" && key.Service == "Operations" { + ch := make(chan struct{}) + go func() { + l.gce.operationPollRateLimiter.Accept() + close(ch) + }() + select { + case <-ch: + break + case <-ctx.Done(): + return ctx.Err() + } + } + return nil +}