diff options
author | Sebastien Douheret <sebastien.douheret@iot.bzh> | 2017-09-25 14:15:16 +0200 |
---|---|---|
committer | Sebastien Douheret <sebastien.douheret@iot.bzh> | 2017-10-06 18:25:04 +0200 |
commit | 97ca1f277dc8b6973d6fa67add5593a9c395ce60 (patch) | |
tree | 761649d7771e8699a67567476c17fb2fa0e28e57 /lib/agent/apiv1-exec.go | |
parent | 12a20d0905b0d3e7e0f4c9ec8ee619f683256d71 (diff) |
Added webapp Dashboard + logic to interact with server.
Signed-off-by: Sebastien Douheret <sebastien.douheret@iot.bzh>
Diffstat (limited to 'lib/agent/apiv1-exec.go')
-rw-r--r-- | lib/agent/apiv1-exec.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/agent/apiv1-exec.go b/lib/agent/apiv1-exec.go new file mode 100644 index 0000000..83ec7aa --- /dev/null +++ b/lib/agent/apiv1-exec.go @@ -0,0 +1,99 @@ +package agent + +import ( + "encoding/json" + "io/ioutil" + "net/http" + + "github.com/gin-gonic/gin" + common "github.com/iotbzh/xds-common/golib" +) + +// Only define useful fields +type ExecArgs struct { + ID string `json:"id" binding:"required"` +} + +// ExecCmd executes remotely a command +func (s *APIService) execCmd(c *gin.Context) { + s._execRequest("/exec", c) +} + +// execSignalCmd executes remotely a command +func (s *APIService) execSignalCmd(c *gin.Context) { + s._execRequest("/signal", c) +} + +func (s *APIService) _execRequest(url string, c *gin.Context) { + data, err := c.GetRawData() + if err != nil { + common.APIError(c, err.Error()) + } + + // First get Project ID to retrieve Server ID and send command to right server + id := c.Param("id") + if id == "" { + args := ExecArgs{} + // XXX - we cannot use c.BindJSON, so directly unmarshall it + // (see https://github.com/gin-gonic/gin/issues/1078) + if err := json.Unmarshal(data, &args); err != nil { + common.APIError(c, "Invalid arguments") + return + } + id = args.ID + } + prj := s.projects.Get(id) + if prj == nil { + common.APIError(c, "Unknown id") + return + } + + svr := (*prj).GetServer() + if svr == nil { + common.APIError(c, "Cannot identify XDS Server") + return + } + + // Retrieve session info + sess := s.sessions.Get(c) + if sess == nil { + common.APIError(c, "Unknown sessions") + return + } + sock := sess.IOSocket + if sock == nil { + common.APIError(c, "Websocket not established") + return + } + + // Forward XDSServer WS events to client WS + // TODO removed static event name list and get it from XDSServer + for _, evName := range []string{ + "exec:input", + "exec:output", + "exec:exit", + "exec:inferior-input", + "exec:inferior-output", + } { + evN := evName + svr.EventOn(evN, func(evData interface{}) { + (*sock).Emit(evN, evData) + }) + } + + // Forward back command to right server + response, err := svr.HTTPPostBody(url, string(data)) + if err != nil { + common.APIError(c, err.Error()) + return + } + + // Decode response + body, err := ioutil.ReadAll(response.Body) + if err != nil { + common.APIError(c, "Cannot read response body") + return + } + c.JSON(http.StatusOK, string(body)) + +} |