From bb3d6da46785445f4c29ee7f8044b6ff353d2ae7 Mon Sep 17 00:00:00 2001 From: David Zhu Date: Tue, 10 Jul 2018 13:38:15 -0700 Subject: [PATCH 1/3] Add metadata with public ssh key at instance creation time --- test/remote/run_remote/run_remote.go | 52 ++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/test/remote/run_remote/run_remote.go b/test/remote/run_remote/run_remote.go index 58ce069da..5208d4633 100644 --- a/test/remote/run_remote/run_remote.go +++ b/test/remote/run_remote/run_remote.go @@ -368,6 +368,22 @@ func createInstance(serviceAccount string) (string, error) { } i.ServiceAccounts = []*compute.ServiceAccount{saObj} + if pubkey, ok := os.LookupEnv("JENKINS_GCE_SSH_PUBLIC_KEY_FILE"); ok { + glog.V(4).Infof("JENKINS_GCE_SSH_PUBLIC_KEY_FILE set to %v, adding public key to Instance", pubkey) + meta, err := generateMetadataWithPublicKey(pubkey) + if err != nil { + return "", err + } + i.Metadata = meta + /*glog.V(4).Infof("JENKINS_GCE_SSH_PUBLIC_KEY_FILE set to %v, adding public key to Instance", pubkey) + // If we're on CI add public SSH keys to the instance + i.Metadata = + err = addPubKeyToInstance(*project, *zone, i.Name, pubkey) + if err != nil { + return "", fmt.Errorf("could not add Jenkins public key %v to instance %v: %v", pubkey, i.Name, err) + }*/ + } + if _, err := computeService.Instances.Get(*project, *zone, i.Name).Do(); err != nil { op, err := computeService.Instances.Insert(*project, *zone, i).Do() glog.V(4).Infof("Inserted instance %v in project %v, zone %v", i.Name, *project, *zone) @@ -384,15 +400,6 @@ func createInstance(serviceAccount string) (string, error) { glog.V(4).Infof("Compute service GOT instance %v, skipping instance creation", i.Name) } - if pubkey, ok := os.LookupEnv("JENKINS_GCE_SSH_PUBLIC_KEY_FILE"); ok { - glog.V(4).Infof("JENKINS_GCE_SSH_PUBLIC_KEY_FILE set to %v, adding public key to Instance", pubkey) - // If we're on CI add public SSH keys to the instance - err = addPubKeyToInstance(*project, *zone, i.Name, pubkey) - if err != nil { - return "", fmt.Errorf("could not add Jenkins public key %v to instance %v: %v", pubkey, i.Name, err) - } - } - then := time.Now() err = wait.Poll(15*time.Second, 5*time.Minute, func() (bool, error) { glog.V(2).Infof("Waiting for instance %v to come up. %v elapsed", name, time.Since(then)) @@ -418,7 +425,7 @@ func createInstance(serviceAccount string) (string, error) { glog.Warningf("SSH encountered an error: %v, output: %v", err, sshOut) return false, nil } - + glog.Infof("Instance %v in state RUNNING and vailable by SSH", name) return true, nil }) @@ -431,6 +438,31 @@ func createInstance(serviceAccount string) (string, error) { return name, nil } +func generateMetadataWithPublicKey(pubKeyFile string) (*compute.Metadata, error) { + publicKeyByte, err := ioutil.ReadFile(pubKeyFile) + if err != nil { + return nil, err + } + + publicKey := string(publicKeyByte) + + // Take username and prepend it to the public key + tokens := strings.Split(publicKey, " ") + if len(tokens) != 3 { + return nil, fmt.Errorf("Public key not comprised of 3 parts, instead was: %v", publicKey) + } + publicKey = strings.TrimSpace(tokens[2]) + ":" + publicKey + newMeta := &compute.Metadata{ + Items: []*compute.MetadataItems{ + { + Key: "ssh-keys", + Value: &publicKey, + }, + }, + } + return newMeta, nil +} + func addPubKeyToInstance(project, zone, name, pubKeyFile string) error { newKeys := "" i, err := computeService.Instances.Get(project, zone, name).Do() From 3e6100734d981020c76e4454d48562c35756f818 Mon Sep 17 00:00:00 2001 From: David Zhu Date: Tue, 10 Jul 2018 14:10:21 -0700 Subject: [PATCH 2/3] Added default firewall rule check and creation logic --- test/remote/run_remote/run_remote.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/test/remote/run_remote/run_remote.go b/test/remote/run_remote/run_remote.go index 5208d4633..238147f58 100644 --- a/test/remote/run_remote/run_remote.go +++ b/test/remote/run_remote/run_remote.go @@ -78,7 +78,8 @@ func init() { } const ( - defaultMachine = "n1-standard-1" + defaultMachine = "n1-standard-1" + defaultFirewallRule = "default-allow-ssh" ) var ( @@ -333,6 +334,27 @@ func createInstance(serviceAccount string) (string, error) { name := "gce-pd-csi-e2e" myuuid := string(uuid.NewUUID()) + + // Create default filewall rule if it does not exist + if _, err = computeService.Firewalls.Get(*project, defaultFirewallRule).Do(); err != nil { + glog.Infof("Default firewall rule %v does not exist, creating", defaultFirewallRule) + f := &compute.Firewall{ + Name: defaultFirewallRule, + Allowed: []*compute.FirewallAllowed{ + &compute.FirewallAllowed{ + IPProtocol: "tcp", + Ports: []string{"22"}, + }, + }, + } + _, err = computeService.Firewalls.Insert(*project, f).Do() + if err != nil { + return "", fmt.Errorf("Failed to insert required default SSH Firewall Rule %v: %v", defaultFirewallRule, err) + } + } else { + glog.Infof("Default firewall rule %v already exists, skipping creation", defaultFirewallRule) + } + glog.V(4).Infof("Creating instance: %v", name) // TODO: Pick a better boot disk image From e4c15b8038d083d80f48e3cccb010ff5bf9c0088 Mon Sep 17 00:00:00 2001 From: David Zhu Date: Tue, 10 Jul 2018 14:16:35 -0700 Subject: [PATCH 3/3] Delete some dead code, small refactor --- test/remote/run_remote/run_remote.go | 82 ++++++---------------------- 1 file changed, 18 insertions(+), 64 deletions(-) diff --git a/test/remote/run_remote/run_remote.go b/test/remote/run_remote/run_remote.go index 238147f58..1f94810a1 100644 --- a/test/remote/run_remote/run_remote.go +++ b/test/remote/run_remote/run_remote.go @@ -328,20 +328,15 @@ func test(tests []string) *TestResult { return result } -// Provision a gce instance using image -func createInstance(serviceAccount string) (string, error) { +// Create default SSH filewall rule if it does not exist +func createDefaultFirewallRule() error { var err error - - name := "gce-pd-csi-e2e" - myuuid := string(uuid.NewUUID()) - - // Create default filewall rule if it does not exist if _, err = computeService.Firewalls.Get(*project, defaultFirewallRule).Do(); err != nil { glog.Infof("Default firewall rule %v does not exist, creating", defaultFirewallRule) f := &compute.Firewall{ Name: defaultFirewallRule, Allowed: []*compute.FirewallAllowed{ - &compute.FirewallAllowed{ + { IPProtocol: "tcp", Ports: []string{"22"}, }, @@ -349,11 +344,25 @@ func createInstance(serviceAccount string) (string, error) { } _, err = computeService.Firewalls.Insert(*project, f).Do() if err != nil { - return "", fmt.Errorf("Failed to insert required default SSH Firewall Rule %v: %v", defaultFirewallRule, err) + return fmt.Errorf("Failed to insert required default SSH firewall Rule %v: %v", defaultFirewallRule, err) } } else { glog.Infof("Default firewall rule %v already exists, skipping creation", defaultFirewallRule) } + return nil +} + +// Provision a gce instance using image +func createInstance(serviceAccount string) (string, error) { + var err error + + name := "gce-pd-csi-e2e" + myuuid := string(uuid.NewUUID()) + + err = createDefaultFirewallRule() + if err != nil { + return "", fmt.Errorf("Failed to create firewall rule: %v", err) + } glog.V(4).Infof("Creating instance: %v", name) @@ -397,13 +406,6 @@ func createInstance(serviceAccount string) (string, error) { return "", err } i.Metadata = meta - /*glog.V(4).Infof("JENKINS_GCE_SSH_PUBLIC_KEY_FILE set to %v, adding public key to Instance", pubkey) - // If we're on CI add public SSH keys to the instance - i.Metadata = - err = addPubKeyToInstance(*project, *zone, i.Name, pubkey) - if err != nil { - return "", fmt.Errorf("could not add Jenkins public key %v to instance %v: %v", pubkey, i.Name, err) - }*/ } if _, err := computeService.Instances.Get(*project, *zone, i.Name).Do(); err != nil { @@ -485,54 +487,6 @@ func generateMetadataWithPublicKey(pubKeyFile string) (*compute.Metadata, error) return newMeta, nil } -func addPubKeyToInstance(project, zone, name, pubKeyFile string) error { - newKeys := "" - i, err := computeService.Instances.Get(project, zone, name).Do() - if err != nil { - return err - } - fingerprint := i.Metadata.Fingerprint - items := i.Metadata.Items - for _, item := range items { - if item.Key == "ssh-keys" { - glog.V(2).Infof("Found existing ssh-keys, prepending to new key string") - newKeys += *item.Value - break - } - } - publicKeyByte, err := ioutil.ReadFile(pubKeyFile) - if err != nil { - return err - } - - publicKey := string(publicKeyByte) - - // Take username and prepend it to the public key - tokens := strings.Split(publicKey, " ") - if len(tokens) != 3 { - return fmt.Errorf("Public key not comprised of 3 parts, instead was: %v", publicKey) - } - publicKey = strings.TrimSpace(tokens[2]) + ":" + publicKey - - newKeys = newKeys + publicKey - glog.V(4).Infof("New ssh-keys for instance %v: %v", name, newKeys) - newMeta := &compute.Metadata{ - Fingerprint: fingerprint, - Items: []*compute.MetadataItems{ - { - Key: "ssh-keys", - Value: &newKeys, - }, - }, - } - _, err = computeService.Instances.SetMetadata(project, zone, name, newMeta).Do() - if err != nil { - return err - } - return nil - -} - func getexternalIP(instance *compute.Instance) string { for i := range instance.NetworkInterfaces { ni := instance.NetworkInterfaces[i]