github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/cloudstack/step_keypair.go (about) 1 package cloudstack 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "runtime" 8 9 "github.com/hashicorp/packer/packer" 10 "github.com/mitchellh/multistep" 11 "github.com/xanzy/go-cloudstack/cloudstack" 12 ) 13 14 type stepKeypair struct { 15 Debug bool 16 DebugKeyPath string 17 KeyPair string 18 PrivateKeyFile string 19 SSHAgentAuth bool 20 TemporaryKeyPairName string 21 } 22 23 func (s *stepKeypair) Run(state multistep.StateBag) multistep.StepAction { 24 ui := state.Get("ui").(packer.Ui) 25 26 if s.PrivateKeyFile != "" { 27 privateKeyBytes, err := ioutil.ReadFile(s.PrivateKeyFile) 28 if err != nil { 29 state.Put("error", fmt.Errorf( 30 "Error loading configured private key file: %s", err)) 31 return multistep.ActionHalt 32 } 33 34 state.Put("keypair", s.KeyPair) 35 state.Put("privateKey", string(privateKeyBytes)) 36 37 return multistep.ActionContinue 38 } 39 40 if s.SSHAgentAuth && s.KeyPair == "" { 41 ui.Say("Using SSH Agent with keypair in Source image") 42 return multistep.ActionContinue 43 } 44 45 if s.SSHAgentAuth && s.KeyPair != "" { 46 ui.Say(fmt.Sprintf("Using SSH Agent for existing keypair %s", s.KeyPair)) 47 state.Put("keypair", s.KeyPair) 48 return multistep.ActionContinue 49 } 50 51 if s.TemporaryKeyPairName == "" { 52 ui.Say("Not using a keypair") 53 state.Put("keypair", "") 54 return multistep.ActionContinue 55 } 56 57 client := state.Get("client").(*cloudstack.CloudStackClient) 58 59 ui.Say(fmt.Sprintf("Creating temporary keypair: %s ...", s.TemporaryKeyPairName)) 60 61 p := client.SSH.NewCreateSSHKeyPairParams(s.TemporaryKeyPairName) 62 keypair, err := client.SSH.CreateSSHKeyPair(p) 63 if err != nil { 64 err := fmt.Errorf("Error creating temporary keypair: %s", err) 65 state.Put("error", err) 66 ui.Error(err.Error()) 67 return multistep.ActionHalt 68 } 69 70 if keypair.Privatekey == "" { 71 err := fmt.Errorf("The temporary keypair returned was blank") 72 state.Put("error", err) 73 ui.Error(err.Error()) 74 return multistep.ActionHalt 75 } 76 77 ui.Say(fmt.Sprintf("Created temporary keypair: %s", s.TemporaryKeyPairName)) 78 79 // If we're in debug mode, output the private key to the working directory. 80 if s.Debug { 81 ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath)) 82 f, err := os.Create(s.DebugKeyPath) 83 if err != nil { 84 state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) 85 return multistep.ActionHalt 86 } 87 defer f.Close() 88 89 // Write the key out 90 if _, err := f.Write([]byte(keypair.Privatekey)); err != nil { 91 err := fmt.Errorf("Error saving debug key: %s", err) 92 state.Put("error", err) 93 ui.Error(err.Error()) 94 return multistep.ActionHalt 95 } 96 97 // Chmod it so that it is SSH ready 98 if runtime.GOOS != "windows" { 99 if err := f.Chmod(0600); err != nil { 100 err := fmt.Errorf("Error setting permissions of debug key: %s", err) 101 state.Put("error", err) 102 ui.Error(err.Error()) 103 return multistep.ActionHalt 104 } 105 } 106 } 107 108 // Set some state data for use in future steps 109 state.Put("keypair", s.TemporaryKeyPairName) 110 state.Put("privateKey", keypair.Privatekey) 111 112 return multistep.ActionContinue 113 } 114 115 func (s *stepKeypair) Cleanup(state multistep.StateBag) { 116 if s.TemporaryKeyPairName == "" { 117 return 118 } 119 120 ui := state.Get("ui").(packer.Ui) 121 client := state.Get("client").(*cloudstack.CloudStackClient) 122 123 ui.Say(fmt.Sprintf("Deleting temporary keypair: %s ...", s.TemporaryKeyPairName)) 124 125 _, err := client.SSH.DeleteSSHKeyPair(client.SSH.NewDeleteSSHKeyPairParams( 126 s.TemporaryKeyPairName, 127 )) 128 if err != nil { 129 ui.Error(err.Error()) 130 ui.Error(fmt.Sprintf( 131 "Error cleaning up keypair. Please delete the key manually: %s", s.TemporaryKeyPairName)) 132 } 133 }