-
Notifications
You must be signed in to change notification settings - Fork 161
/
session.go
115 lines (90 loc) · 2.35 KB
/
session.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
package ssh
import (
"fmt"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
boshsys "github.com/cloudfoundry/bosh-utils/system"
boshdir "github.com/cloudfoundry/bosh-cli/director"
)
type SessionImpl struct {
connOpts ConnectionOpts
sessOpts SessionImplOpts
result boshdir.SSHResult
privKeyFile boshsys.File
knownHostsFile boshsys.File
fs boshsys.FileSystem
}
type SessionImplOpts struct {
ForceTTY bool
}
func NewSessionImpl(
connOpts ConnectionOpts,
sessOpts SessionImplOpts,
result boshdir.SSHResult,
fs boshsys.FileSystem,
) *SessionImpl {
return &SessionImpl{connOpts: connOpts, sessOpts: sessOpts, result: result, fs: fs}
}
func (r *SessionImpl) Start() (SSHArgs, error) {
var err error
r.privKeyFile, err = r.makePrivKeyFile()
if err != nil {
return SSHArgs{}, err
}
r.knownHostsFile, err = r.makeKnownHostsFile()
if err != nil {
_ = r.fs.RemoveAll(r.privKeyFile.Name())
return SSHArgs{}, err
}
args := NewSSHArgs(
r.connOpts,
r.result,
r.sessOpts.ForceTTY,
r.privKeyFile,
r.knownHostsFile,
)
return args, nil
}
func (r *SessionImpl) Finish() error {
// Make sure to try to delete all files regardless of errors
privKeyErr := r.fs.RemoveAll(r.privKeyFile.Name())
knownHostsErr := r.fs.RemoveAll(r.knownHostsFile.Name())
if privKeyErr != nil {
return privKeyErr
}
if knownHostsErr != nil {
return knownHostsErr
}
return nil
}
func (r SessionImpl) makePrivKeyFile() (boshsys.File, error) {
file, err := r.fs.TempFile("ssh-priv-key")
if err != nil {
return nil, bosherr.WrapErrorf(err, "Creating temp file for SSH private key")
}
_, err = file.Write([]byte(r.connOpts.PrivateKey))
if err != nil {
_ = r.fs.RemoveAll(file.Name())
return nil, bosherr.WrapErrorf(err, "Writing SSH private key")
}
return file, nil
}
func (r SessionImpl) makeKnownHostsFile() (boshsys.File, error) {
file, err := r.fs.TempFile("ssh-known-hosts")
if err != nil {
return nil, bosherr.WrapErrorf(err, "Creating temp file for SSH known hosts")
}
var content string
for _, host := range r.result.Hosts {
if len(host.HostPublicKey) > 0 {
content += fmt.Sprintf("%s %s\n", host.Host, host.HostPublicKey)
}
}
if len(content) > 0 {
_, err := file.Write([]byte(content))
if err != nil {
_ = r.fs.RemoveAll(file.Name())
return nil, bosherr.WrapErrorf(err, "Writing SSH known hosts")
}
}
return file, nil
}