in providers/gce/gce.go [418:563]
func CreateGCECloud(config *CloudConfig) (*Cloud, 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
}
service, err := compute.NewService(context.Background(), option.WithTokenSource(config.TokenSource))
if err != nil {
return nil, err
}
service.UserAgent = userAgent
serviceBeta, err := computebeta.NewService(context.Background(), option.WithTokenSource(config.TokenSource))
if err != nil {
return nil, err
}
serviceBeta.UserAgent = userAgent
serviceAlpha, err := computealpha.NewService(context.Background(), option.WithTokenSource(config.TokenSource))
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.
// For example,
// staging API endpoint: https://www.googleapis.com/compute/staging_v1/
if config.APIEndpoint != "" {
service.BasePath = config.APIEndpoint
serviceBeta.BasePath = strings.Replace(config.APIEndpoint, "v1", "beta", -1)
serviceAlpha.BasePath = strings.Replace(config.APIEndpoint, "v1", "alpha", -1)
}
// Previously "projects/" was a part of BasePath, but recent changes in Google Cloud SDK removed it from there.
// To bring the old format back we update BasePath including "projects/" there again.
service.BasePath += "projects/"
serviceBeta.BasePath += "projects/"
serviceAlpha.BasePath += "projects/"
containerService, err := container.NewService(context.Background(), option.WithTokenSource(config.TokenSource))
if err != nil {
return nil, err
}
containerService.UserAgent = userAgent
if config.ContainerAPIEndpoint != "" {
containerService.BasePath = config.ContainerAPIEndpoint
}
client, err := newOauthClient(config.TokenSource)
if err != nil {
return nil, err
}
tpuService, err := newTPUService(client)
if err != nil {
return nil, err
}
// ProjectID and.NetworkProjectID may be project number or name.
projID, netProjID := tryConvertToProjectNames(config.ProjectID, config.NetworkProjectID, service)
onXPN := projID != netProjID
var networkURL string
var subnetURL string
var isLegacyNetwork bool
if config.NetworkURL != "" {
networkURL = config.NetworkURL
} else if config.NetworkName != "" {
networkURL = gceNetworkURL(config.APIEndpoint, netProjID, config.NetworkName)
} else {
// Other consumers may use the cloudprovider without utilizing the wrapped GCE API functions
// or functions requiring network/subnetwork URLs (e.g. Kubelet).
klog.Warningf("No network name or URL specified.")
}
if config.SubnetworkURL != "" {
subnetURL = config.SubnetworkURL
} else if config.SubnetworkName != "" {
subnetURL = gceSubnetworkURL(config.APIEndpoint, netProjID, config.Region, config.SubnetworkName)
}
// If neither SubnetworkURL nor SubnetworkName are provided, defer to
// lazy initialization. Determining subnetURL and isLegacyNetwork requires
// GCE API call. Given that it's not used in many cases and the fact that
// the provider is initialized also for Kubelets (and there can be thousands
// of them) we defer to lazy initialization here.
if len(config.ManagedZones) == 0 {
config.ManagedZones, err = getZonesForRegion(service, config.ProjectID, config.Region)
if err != nil {
return nil, err
}
}
if len(config.ManagedZones) > 1 {
klog.Infof("managing multiple zones: %v", config.ManagedZones)
}
operationPollRateLimiter := flowcontrol.NewTokenBucketRateLimiter(5, 5) // 5 qps, 5 burst.
gce := &Cloud{
service: service,
serviceAlpha: serviceAlpha,
serviceBeta: serviceBeta,
containerService: containerService,
tpuService: tpuService,
projectID: projID,
networkProjectID: netProjID,
onXPN: onXPN,
region: config.Region,
regional: config.Regional,
localZone: config.Zone,
managedZones: config.ManagedZones,
networkURL: networkURL,
unsafeIsLegacyNetwork: isLegacyNetwork,
unsafeSubnetworkURL: subnetURL,
secondaryRangeName: config.SecondaryRangeName,
nodeTags: config.NodeTags,
nodeInstancePrefix: config.NodeInstancePrefix,
useMetadataServer: config.UseMetadataServer,
operationPollRateLimiter: operationPollRateLimiter,
AlphaFeatureGate: config.AlphaFeatureGate,
nodeZones: map[string]sets.String{},
metricsCollector: newLoadBalancerMetrics(),
stackType: StackType(config.StackType),
}
gce.manager = &gceServiceManager{gce}
gce.s = &cloud.Service{
GA: service,
Alpha: serviceAlpha,
Beta: serviceBeta,
ProjectRouter: &gceProjectRouter{gce},
RateLimiter: &gceRateLimiter{gce},
}
gce.c = cloud.NewGCE(gce.s)
return gce, nil
}