diff --git a/pkg/cloudprovider/providers/gce/BUILD b/pkg/cloudprovider/providers/gce/BUILD index d25739c9484..fd154be5e64 100644 --- a/pkg/cloudprovider/providers/gce/BUILD +++ b/pkg/cloudprovider/providers/gce/BUILD @@ -53,6 +53,7 @@ go_library( "//pkg/master/ports:go_default_library", "//pkg/util/net/sets:go_default_library", "//pkg/util/version:go_default_library", + "//pkg/version:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/util:go_default_library", "//vendor/cloud.google.com/go/compute/metadata:go_default_library", diff --git a/pkg/cloudprovider/providers/gce/gce.go b/pkg/cloudprovider/providers/gce/gce.go index cf30b96f6f9..169b05d6661 100644 --- a/pkg/cloudprovider/providers/gce/gce.go +++ b/pkg/cloudprovider/providers/gce/gce.go @@ -21,6 +21,7 @@ import ( "io" "net/http" "regexp" + "runtime" "strconv" "strings" "sync" @@ -42,6 +43,7 @@ import ( "k8s.io/client-go/util/flowcontrol" "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/controller" + "k8s.io/kubernetes/pkg/version" "github.com/golang/glog" "golang.org/x/oauth2" @@ -344,6 +346,13 @@ 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/. + 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. + userAgent := fmt.Sprintf("Kubernetes/%s (%s %s)", version, runtime.GOOS, runtime.GOARCH) + // Use ProjectID for NetworkProjectID, if it wasn't explicitly set. if config.NetworkProjectID == "" { config.NetworkProjectID = config.ProjectID @@ -357,6 +366,7 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { if err != nil { return nil, err } + service.UserAgent = userAgent client, err = newOauthClient(config.TokenSource) if err != nil { @@ -366,6 +376,7 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { if err != nil { return nil, err } + serviceBeta.UserAgent = userAgent client, err = newOauthClient(config.TokenSource) if err != nil { @@ -375,6 +386,7 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { if err != nil { return nil, err } + serviceAlpha.UserAgent = userAgent // Expect override api endpoint to always be v1 api and follows the same pattern as prod. // Generate alpha and beta api endpoints based on override v1 api endpoint. @@ -390,11 +402,13 @@ func CreateGCECloud(config *CloudConfig) (*GCECloud, error) { if err != nil { return nil, err } + containerService.UserAgent = userAgent cloudkmsService, err := cloudkms.New(client) if err != nil { return nil, err } + cloudkmsService.UserAgent = userAgent // ProjectID and.NetworkProjectID may be project number or name. projID, netProjID := tryConvertToProjectNames(config.ProjectID, config.NetworkProjectID, service)