func newKops()

in kubetest/kops.go [193:382]


func newKops(provider, gcpProject, cluster string) (*kops, error) {
	tmpdir, err := ioutil.TempDir("", "kops")
	if err != nil {
		return nil, err
	}

	if err := migrateKopsEnv(); err != nil {
		return nil, err
	}

	if *kopsCluster != "" {
		cluster = *kopsCluster
	}
	if cluster == "" {
		return nil, fmt.Errorf("--cluster or --kops-cluster must be set to a valid cluster name for kops deployment")
	}
	if *kopsState == "" && provider != "gce" {
		return nil, fmt.Errorf("--kops-state must be set to a valid S3 path for kops deployments on AWS")
	} else if provider == "gce" {
		kopsState, err = setupGCEStateStore(gcpProject)
		if err != nil {
			return nil, err
		}
	}

	if *kopsPriorityPath != "" {
		if err := util.InsertPath(*kopsPriorityPath); err != nil {
			return nil, err
		}
	}

	// TODO(fejta): consider explicitly passing these env items where needed.
	sshKey := *kopsSSHKey
	if sshKey == "" {
		usr, err := user.Current()
		if err != nil {
			return nil, err
		}
		sshKey = filepath.Join(usr.HomeDir, ".ssh/kube_aws_rsa")
	}
	if err := os.Setenv("KOPS_STATE_STORE", *kopsState); err != nil {
		return nil, err
	}
	sshPublicKey := *kopsSSHPublicKey
	if sshPublicKey == "" {
		sshPublicKey = sshKey + ".pub"
	}

	sshUser := *kopsSSHUser
	if sshUser != "" {
		if err := os.Setenv("KUBE_SSH_USER", sshUser); err != nil {
			return nil, err
		}
	}

	// Repoint KUBECONFIG to an isolated kubeconfig in our temp directory
	kubecfg := filepath.Join(tmpdir, "kubeconfig")
	f, err := os.Create(kubecfg)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	if err := f.Chmod(0600); err != nil {
		return nil, err
	}
	if err := os.Setenv("KUBECONFIG", kubecfg); err != nil {
		return nil, err
	}

	// Set KUBERNETES_CONFORMANCE_TEST so the auth info is picked up
	// from kubectl instead of bash inference.
	if err := os.Setenv("KUBERNETES_CONFORMANCE_TEST", "yes"); err != nil {
		return nil, err
	}
	// Set KUBERNETES_CONFORMANCE_PROVIDER to override the
	// cloudprovider for KUBERNETES_CONFORMANCE_TEST.
	// This value is set by the provider flag that is passed into kubetest.
	// HACK: until we merge #7408, there's a bug in the ginkgo-e2e.sh script we have to work around
	// TODO(justinsb): remove this hack once #7408 merges
	// if err := os.Setenv("KUBERNETES_CONFORMANCE_PROVIDER", provider); err != nil {
	if err := os.Setenv("KUBERNETES_CONFORMANCE_PROVIDER", "aws"); err != nil {
		return nil, err
	}
	// AWS_SSH_KEY is required by the AWS e2e tests.
	if err := os.Setenv("AWS_SSH_KEY", sshKey); err != nil {
		return nil, err
	}

	// zones are required by the kops e2e tests.
	var zones []string

	// if zones is set to zero and gcp project is not set then pick random aws zone
	if *kopsZones == "" && provider == "aws" {
		zones, err = getRandomAWSZones(*kopsMasterCount, *kopsMultipleZones)
		if err != nil {
			return nil, err
		}
	} else {
		zones = strings.Split(*kopsZones, ",")
	}

	// set ZONES for e2e.go
	if err := os.Setenv("ZONE", zones[0]); err != nil {
		return nil, err
	}

	if len(zones) == 0 {
		return nil, errors.New("no zones found")
	} else if zones[0] == "" {
		return nil, errors.New("zone cannot be a empty string")
	}

	log.Printf("executing kops with zones: %q", zones)

	// Set kops-base-url from kops-version
	if *kopsVersion != "" {
		if *kopsBaseURL != "" {
			return nil, fmt.Errorf("cannot set --kops-version and --kops-base-url")
		}

		var b bytes.Buffer
		if err := httpRead(*kopsVersion, &b); err != nil {
			return nil, err
		}
		latest := strings.TrimSpace(b.String())

		log.Printf("Got latest kops version from %v: %v", *kopsVersion, latest)
		if latest == "" {
			return nil, fmt.Errorf("version URL %v was empty", *kopsVersion)
		}
		*kopsBaseURL = latest
	}

	// kops looks at KOPS_BASE_URL env var, so export it here
	if *kopsBaseURL != "" {
		if err := os.Setenv("KOPS_BASE_URL", *kopsBaseURL); err != nil {
			return nil, err
		}
	}

	// Download kops from kopsBaseURL if kopsPath is not set
	if *kopsPath == "" {
		if *kopsBaseURL == "" {
			return nil, errors.New("--kops or --kops-base-url must be set")
		}

		kopsBinURL := *kopsBaseURL + "/linux/amd64/kops"
		log.Printf("Download kops binary from %s", kopsBinURL)
		kopsBin := filepath.Join(tmpdir, "kops")
		f, err := os.Create(kopsBin)
		if err != nil {
			return nil, fmt.Errorf("error creating file %q: %w", kopsBin, err)
		}
		defer f.Close()
		if err := httpRead(kopsBinURL, f); err != nil {
			return nil, err
		}
		if err := util.EnsureExecutable(kopsBin); err != nil {
			return nil, err
		}
		*kopsPath = kopsBin
	}

	return &kops{
		path:          *kopsPath,
		kubeVersion:   *kopsKubeVersion,
		sshPrivateKey: sshKey,
		sshPublicKey:  sshPublicKey,
		sshUser:       sshUser,
		zones:         zones,
		nodes:         *kopsNodes,
		adminAccess:   *kopsAdminAccess,
		cluster:       cluster,
		image:         *kopsImage,
		args:          *kopsArgs,
		kubecfg:       kubecfg,
		provider:      provider,
		gcpProject:    gcpProject,
		diskSize:      *kopsDiskSize,
		kopsVersion:   *kopsBaseURL,
		kopsPublish:   *kopsPublish,
		masterCount:   *kopsMasterCount,
		dnsProvider:   *kopsDNSProvider,
		etcdVersion:   *kopsEtcdVersion,
		masterSize:    *kopsMasterSize,
		networkMode:   *kopsNetworkMode,
		overrides:     *kopsOverrides,
		featureFlags:  *kopsFeatureFlags,
	}, nil
}