aboutsummaryrefslogtreecommitdiffstats
path: root/lib/agent/apiv1-exec.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/agent/apiv1-exec.go')
-rw-r--r--lib/agent/apiv1-exec.go99
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))
+
+}