Added target and terminal support.
[src/xds/xds-server.git] / lib / xdsserver / apiv1-targets.go
diff --git a/lib/xdsserver/apiv1-targets.go b/lib/xdsserver/apiv1-targets.go
new file mode 100644 (file)
index 0000000..978dc75
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2018 "IoT.bzh"
+ * Author Sebastien Douheret <sebastien@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package xdsserver
+
+import (
+       "net/http"
+
+       common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git/golib"
+       "gerrit.automotivelinux.org/gerrit/src/xds/xds-server/lib/xsapiv1"
+       "github.com/gin-gonic/gin"
+)
+
+/***
+ * Targets
+ ***/
+
+// getTargets returns all targets configuration
+func (s *APIService) getTargets(c *gin.Context) {
+       c.JSON(http.StatusOK, s.targets.GetConfigArr())
+}
+
+// getTarget returns a specific target configuration
+func (s *APIService) getTarget(c *gin.Context) {
+       id, err := s.targets.ResolveID(c.Param("id"))
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       f := s.targets.Get(id)
+       if f == nil {
+               common.APIError(c, "Invalid id")
+               return
+       }
+
+       c.JSON(http.StatusOK, (*f).GetConfig())
+}
+
+// addTarget adds a new target to server config
+func (s *APIService) addTarget(c *gin.Context) {
+       var cfgArg xsapiv1.TargetConfig
+       if c.BindJSON(&cfgArg) != nil {
+               common.APIError(c, "Invalid arguments")
+               return
+       }
+
+       s.Log.Debugln("Add target config: ", cfgArg)
+
+       newTgt, err := s.targets.Add(cfgArg)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+
+       c.JSON(http.StatusOK, newTgt)
+}
+
+// delTarget deletes target from server config
+func (s *APIService) delTarget(c *gin.Context) {
+       id, err := s.targets.ResolveID(c.Param("id"))
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+
+       s.Log.Debugln("Delete target id ", id)
+
+       delEntry, err := s.targets.Delete(id)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       c.JSON(http.StatusOK, delEntry)
+}
+
+/***
+ * Terminals
+ ***/
+// getTgtTerms Get list of all terminals
+func (s *APIService) getTgtTerms(c *gin.Context) {
+       id, err := s.targets.ResolveID(c.Param("id"))
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+
+       res, err := s.targets.GetTerminalsArr(id)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+
+       c.JSON(http.StatusOK, res)
+}
+
+// getTgtTerm Get info a terminal
+func (s *APIService) getTgtTerm(c *gin.Context) {
+       id, tid, err := s._decodeTermArgs(c)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+
+       iTerm, err := s.targets.GetTerminal(id, tid)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+
+       c.JSON(http.StatusOK, (*iTerm).GetConfig())
+}
+
+// createTgtTerm Create a new terminal
+func (s *APIService) createTgtTerm(c *gin.Context) {
+       s.updateTgtTerm(c)
+}
+
+// updateTgtTerm Update terminal config
+func (s *APIService) updateTgtTerm(c *gin.Context) {
+       var cfgArg xsapiv1.TerminalConfig
+
+       tgtID, termID, err := s._decodeTermArgs(c)
+       if tgtID == "" && err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       if err := c.BindJSON(&cfgArg); err != nil {
+               common.APIError(c, "Invalid arguments")
+               return
+       }
+       if cfgArg.ID == "" {
+               cfgArg.ID = termID
+       }
+       if termID != "" && cfgArg.ID != termID {
+               common.APIError(c, "Invalid arguments, inconsistent terminal id ")
+               return
+       }
+       s.Log.Debugln("Add or Update terminal config: ", cfgArg)
+       term, err := s.targets.CreateUpdateTerminal(tgtID, cfgArg, false)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       c.JSON(http.StatusOK, term)
+}
+
+// delTgtTerm Delete a terminal
+func (s *APIService) delTgtTerm(c *gin.Context) {
+
+       tgtID, termID, err := s._decodeTermArgs(c)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       term, err := s.targets.DeleteTerminal(tgtID, termID)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+
+       c.JSON(http.StatusOK, term)
+}
+
+// openTgtTerm Open a target terminal/console
+func (s *APIService) openTgtTerm(c *gin.Context) {
+
+       id, tid, err := s._decodeTermArgs(c)
+       if err != nil {
+               common.APIError(c, err.Error())
+               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
+       }
+
+       term, err := s.targets.OpenTerminal(id, tid, sock, sess.ID)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       c.JSON(http.StatusOK, term)
+}
+
+// closeTgtTerm Close a terminal
+func (s *APIService) closeTgtTerm(c *gin.Context) {
+       id, tid, err := s._decodeTermArgs(c)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       term, err := s.targets.CloseTerminal(id, tid)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       c.JSON(http.StatusOK, term)
+}
+
+// resizeTgtTerm Resize a terminal
+func (s *APIService) resizeTgtTerm(c *gin.Context) {
+       var sizeArg xsapiv1.TerminalResizeArgs
+
+       id, tid, err := s._decodeTermArgs(c)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       if err := c.BindJSON(&sizeArg); err != nil {
+               common.APIError(c, "Invalid arguments")
+               return
+       }
+
+       term, err := s.targets.ResizeTerminal(id, tid, sizeArg.Cols, sizeArg.Rows)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+       c.JSON(http.StatusOK, term)
+}
+
+// signalTgtTerm Send a signal to a terminal
+func (s *APIService) signalTgtTerm(c *gin.Context) {
+       var sigArg xsapiv1.TerminalSignalArgs
+
+       id, tid, err := s._decodeTermArgs(c)
+       if err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+
+       sigName := c.Param("sig")
+       if sigName == "" {
+               if err := c.BindJSON(&sigArg); err != nil {
+                       common.APIError(c, "Invalid arguments")
+                       return
+               }
+               sigName = sigArg.Signal
+       }
+       if sigName == "" {
+               common.APIError(c, "Invalid arguments")
+               return
+       }
+
+       if err := s.targets.SignalTerminal(id, tid, sigName); err != nil {
+               common.APIError(c, err.Error())
+               return
+       }
+
+       c.JSON(http.StatusOK, "")
+}
+
+// _decodeTermArgs Helper to decode arguments of Terminal routes
+func (s *APIService) _decodeTermArgs(c *gin.Context) (string, string, error) {
+       id, err := s.targets.ResolveID(c.Param("id"))
+       if err != nil {
+               return "", "", err
+       }
+
+       termID, err := s.targets.ResolveTerminalID(c.Param("tid"))
+       if err != nil {
+               return id, "", err
+       }
+
+       return id, termID, nil
+}