-
Notifications
You must be signed in to change notification settings - Fork 36
/
setupConnection.go
122 lines (95 loc) · 3 KB
/
setupConnection.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
package ilo
import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httputil"
"net/url"
"strings"
"github.com/bmc-toolbox/bmclib/errors"
"github.com/bmc-toolbox/bmclib/internal/httpclient"
"github.com/bmc-toolbox/bmclib/providers/hp"
multierror "github.com/hashicorp/go-multierror"
)
// Login initiates the connection to a bmc device
func (i *Ilo) httpLogin() (err error) {
if i.httpClient != nil {
return
}
httpClient, err := httpclient.Build(i.httpClientSetupFuncs...)
if err != nil {
return err
}
i.log.V(1).Info("connecting to bmc", "step", "bmc connection", "vendor", hp.VendorID, "ip", i.ip)
data := fmt.Sprintf("{\"method\":\"login\", \"user_login\":\"%s\", \"password\":\"%s\" }", i.username, i.password)
req, err := http.NewRequest("POST", i.loginURL.String(), bytes.NewBufferString(data))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
reqDump, _ := httputil.DumpRequestOut(req, true)
i.log.V(2).Info("requestTrace", "requestDump", string(reqDump), "url", i.loginURL.String())
resp, err := httpClient.Do(req)
if err != nil {
return err
}
u, err := url.Parse(i.loginURL.String())
if err != nil {
return err
}
for _, cookie := range httpClient.Jar.Cookies(u) {
if cookie.Name == "sessionKey" {
i.sessionKey = cookie.Value
}
}
if i.sessionKey == "" {
i.log.V(1).Info("Expected sessionKey cookie value not found.", "step", "Login()", "IP", i.ip, "HardwareType", i.HardwareType())
}
if resp.StatusCode == 404 {
return errors.ErrPageNotFound
}
payload, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
defer resp.Body.Close()
respDump, _ := httputil.DumpResponse(resp, true)
i.log.V(2).Info("responseTrace", "responseDump", string(respDump))
if strings.Contains(string(payload), "Invalid login attempt") {
return errors.ErrLoginFailed
}
i.httpClient = httpClient
return err
}
// Close closes the connection properly
func (i *Ilo) Close(ctx context.Context) error {
var multiErr error
if i.httpClient != nil {
i.log.V(1).Info("logout from bmc http", "step", "bmc connection", "vendor", hp.VendorID, "ip", i.ip)
data := []byte(fmt.Sprintf(`{"method":"logout", "session_key": "%s"}`, i.sessionKey))
req, err := http.NewRequest("POST", i.loginURL.String(), bytes.NewBuffer(data))
if err != nil {
multiErr = multierror.Append(multiErr, err)
} else {
req.Header.Set("Content-Type", "application/json")
reqDump, _ := httputil.DumpRequestOut(req, true)
i.log.V(2).Info("requestTrace", "requestDump", string(reqDump), "url", i.loginURL.String())
resp, err := i.httpClient.Do(req)
if err != nil {
multiErr = multierror.Append(multiErr, err)
} else {
defer resp.Body.Close()
defer io.Copy(ioutil.Discard, resp.Body) // nolint
respDump, _ := httputil.DumpResponse(resp, true)
i.log.V(2).Info("responseTrace", "responseDump", string(respDump))
}
}
}
if err := i.sshClient.Close(); err != nil {
multiErr = multierror.Append(multiErr, err)
}
return multiErr
}