package sshAPI import ( "bytes" "encoding/json" "errors" "fmt" "io/ioutil" "net/http" "github.com/sirupsen/logrus" ) // BareClient : Used to talk directly to the sshapi. Does not gather any information from CORE or any other location type BareClient struct { IP string Platform string Prompt string RePrompt string Username string Password string CallingUser string Log *logrus.Logger } func (b *BareClient) encodePayload(payload string) ([]byte, error) { type UserInfo struct { Username string `json:"Username"` } type PayloadStruct struct { Host string `json:"host"` Platform string `json:"platform"` Command string `json:"command"` Prompt string `json:"prompt"` UserInfo UserInfo `json:"user_info"` } p := PayloadStruct{ Host: b.IP, Platform: b.Platform, Command: payload, Prompt: b.Prompt, UserInfo: UserInfo{ Username: "FirepowerAPI", }, } jsonStr, err := json.MarshalIndent(p, "", " ") if err != nil { return nil, err } return jsonStr, nil } func (b *BareClient) decodeResponse(body []byte, code int) (string, error) { type AutoGenerated struct { Data struct { Timeout int `json:"timeout"` Response string `json:"response"` } `json:"data"` Error string `json:"error"` Success bool `json:"success"` } var returned AutoGenerated if err := json.Unmarshal(body, &returned); err != nil { b.Log.WithError(err).Error("error unmarshalling response") return "", fmt.Errorf("error from sshapi: %v - %s", code, string(body)) } if code != http.StatusOK || returned.Error != "" || !returned.Success { b.Log.Errorf("error from sshapi: %s", returned.Error) return "", fmt.Errorf("error from sshapi: %v - %s", code, returned.Error) } return returned.Data.Response, nil } func (b *BareClient) Post(uri string, payload string) (string, error) { b.Log.Trace("Begin") defer b.Log.Trace("End") jsonStr, err := b.encodePayload(payload) if err != nil { return "", err } req, err := http.NewRequest(http.MethodPost, "http://sshapi.nsi.rackspace.com:26000/cmd", bytes.NewBuffer(jsonStr)) if err != nil { b.Log.WithError(err).Error("error creating new http request") return "", fmt.Errorf("error creating http request: %s", err.Error()) } req.Header.Set("Content-Type", "application/json") if b.Username == "" || b.Password == "" { b.Log.Error("username and password not supplied") return "", errors.New("username and password most be initialized before calling this function") } req.SetBasicAuth(b.Username, b.Password) client := &http.Client{} res, err := client.Do(req) if err != nil { b.Log.WithError(err).Error("error performing http client request") return "", fmt.Errorf("error performing request: %s", err.Error()) } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { b.Log.WithError(err).Error("error reading body of response") return "", fmt.Errorf("error reading body of response: %s", err.Error()) } return b.decodeResponse(body, res.StatusCode) }