GCE: Don't require SSH public key

We also pull a bit of logic out of the mega-function.

Fix #4210
This commit is contained in:
Justin Santa Barbara 2018-01-24 09:40:03 -05:00
parent 46a6d256d3
commit e2109c42f4
2 changed files with 44 additions and 18 deletions

View File

@ -22,6 +22,7 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os"
"strconv" "strconv"
"strings" "strings"
@ -74,7 +75,6 @@ type CreateClusterOptions struct {
KubernetesVersion string KubernetesVersion string
OutDir string OutDir string
Image string Image string
SSHPublicKey string
VPCID string VPCID string
SubnetIDs []string SubnetIDs []string
UtilitySubnetIDs []string UtilitySubnetIDs []string
@ -87,6 +87,9 @@ type CreateClusterOptions struct {
MasterSecurityGroups []string MasterSecurityGroups []string
AssociatePublicIP *bool AssociatePublicIP *bool
// SSHPublicKeys is a map of the SSH public keys we should configure; required on AWS, not required on GCE
SSHPublicKeys map[string][]byte
// Overrides allows settings values direct in the spec // Overrides allows settings values direct in the spec
Overrides []string Overrides []string
@ -144,7 +147,6 @@ func (o *CreateClusterOptions) InitDefaults() {
o.Yes = false o.Yes = false
o.Target = cloudup.TargetDirect o.Target = cloudup.TargetDirect
o.Models = strings.Join(cloudup.CloudupModels, ",") o.Models = strings.Join(cloudup.CloudupModels, ",")
o.SSHPublicKey = "~/.ssh/id_rsa.pub"
o.Networking = "kubenet" o.Networking = "kubenet"
o.Channel = api.DefaultChannel o.Channel = api.DefaultChannel
o.Topology = api.TopologyPublic o.Topology = api.TopologyPublic
@ -218,6 +220,7 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
options := &CreateClusterOptions{} options := &CreateClusterOptions{}
options.InitDefaults() options.InitDefaults()
sshPublicKey := "~/.ssh/id_rsa.pub"
associatePublicIP := false associatePublicIP := false
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -238,6 +241,11 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
options.ClusterName = rootCommand.clusterName options.ClusterName = rootCommand.clusterName
options.SSHPublicKeys, err = loadSSHPublicKeys(sshPublicKey, cmd.Flag("ssh-public-key").Changed)
if err != nil {
exitWithError(err)
}
err = RunCreateCluster(f, out, options) err = RunCreateCluster(f, out, options)
if err != nil { if err != nil {
exitWithError(err) exitWithError(err)
@ -262,7 +270,7 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
cmd.Flags().StringVar(&options.Project, "project", options.Project, "Project to use (must be set on GCE)") cmd.Flags().StringVar(&options.Project, "project", options.Project, "Project to use (must be set on GCE)")
cmd.Flags().StringVar(&options.KubernetesVersion, "kubernetes-version", options.KubernetesVersion, "Version of kubernetes to run (defaults to version in channel)") cmd.Flags().StringVar(&options.KubernetesVersion, "kubernetes-version", options.KubernetesVersion, "Version of kubernetes to run (defaults to version in channel)")
cmd.Flags().StringVar(&options.SSHPublicKey, "ssh-public-key", options.SSHPublicKey, "SSH public key to use") cmd.Flags().StringVar(&sshPublicKey, "ssh-public-key", sshPublicKey, "SSH public key to use")
cmd.Flags().StringVar(&options.NodeSize, "node-size", options.NodeSize, "Set instance size for nodes") cmd.Flags().StringVar(&options.NodeSize, "node-size", options.NodeSize, "Set instance size for nodes")
@ -1006,18 +1014,6 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
Legacy: false, Legacy: false,
} }
sshPublicKeys := make(map[string][]byte)
if c.SSHPublicKey != "" {
c.SSHPublicKey = utils.ExpandPath(c.SSHPublicKey)
authorized, err := ioutil.ReadFile(c.SSHPublicKey)
if err != nil {
return fmt.Errorf("error reading SSH key file %q: %v", c.SSHPublicKey, err)
}
sshPublicKeys[fi.SecretNameSSHPrimary] = authorized
glog.Infof("Using SSH public key: %v\n", c.SSHPublicKey)
}
if len(c.AdminAccess) != 0 { if len(c.AdminAccess) != 0 {
if len(c.SSHAccess) != 0 { if len(c.SSHAccess) != 0 {
cluster.Spec.SSHAccess = c.SSHAccess cluster.Spec.SSHAccess = c.SSHAccess
@ -1106,13 +1102,13 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e
return fmt.Errorf("error writing completed cluster spec: %v", err) return fmt.Errorf("error writing completed cluster spec: %v", err)
} }
if len(sshPublicKeys) != 0 { if len(c.SSHPublicKeys) != 0 {
sshCredentialStore, err := clientset.SSHCredentialStore(cluster) sshCredentialStore, err := clientset.SSHCredentialStore(cluster)
if err != nil { if err != nil {
return err return err
} }
for k, data := range sshPublicKeys { for k, data := range c.SSHPublicKeys {
err = sshCredentialStore.AddSSHPublicKey(k, data) err = sshCredentialStore.AddSSHPublicKey(k, data)
if err != nil { if err != nil {
return fmt.Errorf("error adding SSH public key: %v", err) return fmt.Errorf("error adding SSH public key: %v", err)
@ -1287,3 +1283,24 @@ func getZoneToSubnetProviderID(VPCID string, region string, subnetIDs []string)
} }
return res, nil return res, nil
} }
func loadSSHPublicKeys(sshPublicKey string, flagSpecified bool) (map[string][]byte, error) {
sshPublicKeys := make(map[string][]byte)
if sshPublicKey != "" {
sshPublicKey = utils.ExpandPath(sshPublicKey)
authorized, err := ioutil.ReadFile(sshPublicKey)
if err != nil {
// Ignore file-not-found unless the user actively specified the flag
if !flagSpecified && os.IsNotExist(err) {
glog.V(2).Infof("SSH key file %q does not exist; ignoring", sshPublicKey)
} else {
return nil, fmt.Errorf("error reading SSH key file %q: %v", sshPublicKey, err)
}
} else {
sshPublicKeys[fi.SecretNameSSHPrimary] = authorized
glog.Infof("Using SSH public key: %v\n", sshPublicKey)
}
}
return sshPublicKeys, nil
}

View File

@ -36,6 +36,7 @@ import (
"k8s.io/kops/pkg/diff" "k8s.io/kops/pkg/diff"
"k8s.io/kops/pkg/kopscodecs" "k8s.io/kops/pkg/kopscodecs"
"k8s.io/kops/pkg/testutils" "k8s.io/kops/pkg/testutils"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup" "k8s.io/kops/upup/pkg/fi/cloudup/awsup"
) )
@ -173,7 +174,15 @@ func runCreateClusterIntegrationTest(t *testing.T, srcDir string, version string
options.Target = "" options.Target = ""
// Use the public key we produced // Use the public key we produced
options.SSHPublicKey = publicKeyPath {
publicKey, err := ioutil.ReadFile(publicKeyPath)
if err != nil {
t.Fatalf("error reading public key %q: %v", publicKeyPath, err)
}
sshPublicKeys := make(map[string][]byte)
sshPublicKeys[fi.SecretNameSSHPrimary] = publicKey
options.SSHPublicKeys = sshPublicKeys
}
err = RunCreateCluster(factory, &stdout, options) err = RunCreateCluster(factory, &stdout, options)
if err != nil { if err != nil {