in kubetest/gke.go [130:313]
func newGKE(provider, project, zone, region, network, image, imageFamily, imageProject, cluster, sshProxyInstanceName string, testArgs *string, upgradeArgs *string) (*gkeDeployer, error) {
if provider != "gke" {
return nil, fmt.Errorf("--provider must be 'gke' for GKE deployment, found %q", provider)
}
g := &gkeDeployer{}
if cluster == "" {
return nil, fmt.Errorf("--cluster must be set for GKE deployment")
}
g.cluster = cluster
if project == "" {
return nil, fmt.Errorf("--gcp-project must be set for GKE deployment")
}
g.project = project
if zone == "" && region == "" {
return nil, fmt.Errorf("--gcp-zone or --gcp-region must be set for GKE deployment")
} else if zone != "" && region != "" {
return nil, fmt.Errorf("--gcp-zone and --gcp-region cannot both be set")
}
if zone != "" {
g.zone = zone
g.location = "--zone=" + zone
} else if region != "" {
g.region = region
g.location = "--region=" + region
}
if network == "" {
return nil, fmt.Errorf("--gcp-network must be set for GKE deployment")
}
g.network = network
if strings.ToUpper(image) == "CUSTOM" {
if imageFamily == "" || imageProject == "" {
return nil, fmt.Errorf("--image-family and --image-project must be set for GKE deployment if --gcp-node-image=CUSTOM")
}
}
poolRe, err := regexp.Compile(fmt.Sprintf(poolReTemplate, *gkeInstanceGroupPrefix))
if err != nil {
return nil, fmt.Errorf("Couldn't compile regex %v. prefix: %s", err, *gkeInstanceGroupPrefix)
}
g.poolRe = poolRe
g.imageFamily = imageFamily
g.imageProject = imageProject
g.image = image
g.additionalZones = *gkeAdditionalZones
g.nodeLocations = *gkeNodeLocations
g.nodePorts = *gkeNodePorts
g.createNat = *gkeCreateNat
g.natMinPortsPerVm = *gkeNatMinPortsPerVm
err = json.Unmarshal([]byte(*gkeShape), &g.shape)
if err != nil {
return nil, fmt.Errorf("--gke-shape must be valid JSON, unmarshal error: %v, JSON: %q", err, *gkeShape)
}
if _, ok := g.shape[defaultPool]; !ok {
return nil, fmt.Errorf("--gke-shape must include a node pool named 'default', found %q", *gkeShape)
}
switch subnetMode := *gkeSubnetMode; subnetMode {
case "auto", "custom":
g.subnetMode = subnetMode
default:
return nil, fmt.Errorf("--gke-subnet-mode must be set either to 'auto' or 'custom', got: %s", subnetMode)
}
g.commandGroup = strings.Fields(*gkeCommandGroup)
g.createCommand = append([]string{}, g.commandGroup...)
g.createCommand = append(g.createCommand, strings.Fields(*gkeCreateCommand)...)
createArgs := strings.Fields(*gkeCreateArgs)
if len(createArgs) > 0 {
log.Printf("--gke-create-args is deprecated, please use '--gke-create-command=%s %s'", defaultCreate, *gkeCreateArgs)
}
g.createCommand = append(g.createCommand, createArgs...)
if err := util.MigrateOptions([]util.MigratedOption{{
Env: "CLOUDSDK_API_ENDPOINT_OVERRIDES_CONTAINER",
Option: gkeEnvironment,
Name: "--gke-environment",
}}); err != nil {
return nil, err
}
var endpoint string
switch env := *gkeEnvironment; {
case env == "test":
endpoint = "https://test-container.sandbox.googleapis.com/"
case env == "staging":
endpoint = "https://staging-container.sandbox.googleapis.com/"
case env == "staging2":
endpoint = "https://staging2-container.sandbox.googleapis.com/"
case env == "prod":
endpoint = "https://container.googleapis.com/"
case urlRe.MatchString(env):
endpoint = env
default:
return nil, fmt.Errorf("--gke-environment must be one of {test,staging,prod} or match %v, found %q", urlRe, env)
}
if err := os.Setenv("CLOUDSDK_API_ENDPOINT_OVERRIDES_CONTAINER", endpoint); err != nil {
return nil, err
}
// Override kubecfg to a temporary file rather than trashing the user's.
f, err := ioutil.TempFile("", "gke-kubecfg")
if err != nil {
return nil, err
}
defer f.Close()
kubecfg := f.Name()
if err := f.Chmod(0600); err != nil {
return nil, err
}
g.kubecfg = kubecfg
// We want no KUBERNETES_PROVIDER, but to set
// KUBERNETES_CONFORMANCE_PROVIDER and
// KUBERNETES_CONFORMANCE_TEST. This prevents ginkgo-e2e.sh from
// using the cluster/gke functions.
//
// We do this in the deployer constructor so that
// cluster/gce/list-resources.sh outputs the same provider for the
// extent of the binary. (It seems like it belongs in TestSetup,
// but that way leads to madness.)
//
// TODO(zmerlynn): This is gross.
if err := os.Unsetenv("KUBERNETES_PROVIDER"); err != nil {
return nil, err
}
if err := os.Setenv("KUBERNETES_CONFORMANCE_TEST", "yes"); err != nil {
return nil, err
}
if err := os.Setenv("KUBERNETES_CONFORMANCE_PROVIDER", "gke"); err != nil {
return nil, err
}
// TODO(zmerlynn): Another snafu of cluster/gke/list-resources.sh:
// Set KUBE_GCE_INSTANCE_PREFIX so that we don't accidentally pick
// up CLUSTER_NAME later.
if err := os.Setenv("KUBE_GCE_INSTANCE_PREFIX", "gke-"+g.cluster); err != nil {
return nil, err
}
// set --num-nodes flag for ginkgo, since NUM_NODES is not set for gke deployer.
numNodes := strconv.Itoa(g.shape[defaultPool].Nodes)
// testArgs can be empty, and we need to support this case
*testArgs = strings.Join(util.SetFieldDefault(strings.Fields(*testArgs), "--num-nodes", numNodes), " ")
if *upgradeArgs != "" {
// --upgrade-target will be passed to e2e upgrade framework to get a valid update version.
// See usage from https://github.com/kubernetes/kubernetes/blob/master/hack/get-build.sh for supported targets.
// Here we special case for gke-latest and will extract an actual valid gke version.
// - gke-latest will be resolved to the latest gke version, and
// - gke-latest-1.7 will be resolved to the latest 1.7 patch version supported on gke.
fields, val, exist := util.ExtractField(strings.Fields(*upgradeArgs), "--upgrade-target")
if exist {
if strings.HasPrefix(val, "gke-latest") {
releasePrefix := ""
if strings.HasPrefix(val, "gke-latest-") {
releasePrefix = strings.TrimPrefix(val, "gke-latest-")
}
if val, err = getLatestGKEVersion(project, zone, region, releasePrefix); err != nil {
return nil, fmt.Errorf("fail to get latest gke version : %w", err)
}
}
fields = util.SetFieldDefault(fields, "--upgrade-target", val)
}
*upgradeArgs = strings.Join(util.SetFieldDefault(fields, "--num-nodes", numNodes), " ")
}
g.singleZoneNodeInstanceGroup = *gkeSingleZoneNodeInstanceGroup
g.sshProxyInstanceName = sshProxyInstanceName
err = json.Unmarshal([]byte(*gkeDumpConfigMaps), &g.dumpedConfigMaps)
if err != nil {
return nil, fmt.Errorf("--gke-dump-configmaps must be valid JSON, unmarshal error: %v, JSON: %q", err, *gkeDumpConfigMaps)
}
return g, nil
}