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