Added target and terminal support.
[src/xds/xds-server.git] / lib / xdsserver / apiv1-targets.go
1 /*
2  * Copyright (C) 2018 "IoT.bzh"
3  * Author Sebastien Douheret <sebastien@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package xdsserver
19
20 import (
21         "net/http"
22
23         common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git/golib"
24         "gerrit.automotivelinux.org/gerrit/src/xds/xds-server/lib/xsapiv1"
25         "github.com/gin-gonic/gin"
26 )
27
28 /***
29  * Targets
30  ***/
31
32 // getTargets returns all targets configuration
33 func (s *APIService) getTargets(c *gin.Context) {
34         c.JSON(http.StatusOK, s.targets.GetConfigArr())
35 }
36
37 // getTarget returns a specific target configuration
38 func (s *APIService) getTarget(c *gin.Context) {
39         id, err := s.targets.ResolveID(c.Param("id"))
40         if err != nil {
41                 common.APIError(c, err.Error())
42                 return
43         }
44         f := s.targets.Get(id)
45         if f == nil {
46                 common.APIError(c, "Invalid id")
47                 return
48         }
49
50         c.JSON(http.StatusOK, (*f).GetConfig())
51 }
52
53 // addTarget adds a new target to server config
54 func (s *APIService) addTarget(c *gin.Context) {
55         var cfgArg xsapiv1.TargetConfig
56         if c.BindJSON(&cfgArg) != nil {
57                 common.APIError(c, "Invalid arguments")
58                 return
59         }
60
61         s.Log.Debugln("Add target config: ", cfgArg)
62
63         newTgt, err := s.targets.Add(cfgArg)
64         if err != nil {
65                 common.APIError(c, err.Error())
66                 return
67         }
68
69         c.JSON(http.StatusOK, newTgt)
70 }
71
72 // delTarget deletes target from server config
73 func (s *APIService) delTarget(c *gin.Context) {
74         id, err := s.targets.ResolveID(c.Param("id"))
75         if err != nil {
76                 common.APIError(c, err.Error())
77                 return
78         }
79
80         s.Log.Debugln("Delete target id ", id)
81
82         delEntry, err := s.targets.Delete(id)
83         if err != nil {
84                 common.APIError(c, err.Error())
85                 return
86         }
87         c.JSON(http.StatusOK, delEntry)
88 }
89
90 /***
91  * Terminals
92  ***/
93 // getTgtTerms Get list of all terminals
94 func (s *APIService) getTgtTerms(c *gin.Context) {
95         id, err := s.targets.ResolveID(c.Param("id"))
96         if err != nil {
97                 common.APIError(c, err.Error())
98                 return
99         }
100
101         res, err := s.targets.GetTerminalsArr(id)
102         if err != nil {
103                 common.APIError(c, err.Error())
104                 return
105         }
106
107         c.JSON(http.StatusOK, res)
108 }
109
110 // getTgtTerm Get info a terminal
111 func (s *APIService) getTgtTerm(c *gin.Context) {
112         id, tid, err := s._decodeTermArgs(c)
113         if err != nil {
114                 common.APIError(c, err.Error())
115                 return
116         }
117
118         iTerm, err := s.targets.GetTerminal(id, tid)
119         if err != nil {
120                 common.APIError(c, err.Error())
121                 return
122         }
123
124         c.JSON(http.StatusOK, (*iTerm).GetConfig())
125 }
126
127 // createTgtTerm Create a new terminal
128 func (s *APIService) createTgtTerm(c *gin.Context) {
129         s.updateTgtTerm(c)
130 }
131
132 // updateTgtTerm Update terminal config
133 func (s *APIService) updateTgtTerm(c *gin.Context) {
134         var cfgArg xsapiv1.TerminalConfig
135
136         tgtID, termID, err := s._decodeTermArgs(c)
137         if tgtID == "" && err != nil {
138                 common.APIError(c, err.Error())
139                 return
140         }
141         if err := c.BindJSON(&cfgArg); err != nil {
142                 common.APIError(c, "Invalid arguments")
143                 return
144         }
145         if cfgArg.ID == "" {
146                 cfgArg.ID = termID
147         }
148         if termID != "" && cfgArg.ID != termID {
149                 common.APIError(c, "Invalid arguments, inconsistent terminal id ")
150                 return
151         }
152         s.Log.Debugln("Add or Update terminal config: ", cfgArg)
153         term, err := s.targets.CreateUpdateTerminal(tgtID, cfgArg, false)
154         if err != nil {
155                 common.APIError(c, err.Error())
156                 return
157         }
158         c.JSON(http.StatusOK, term)
159 }
160
161 // delTgtTerm Delete a terminal
162 func (s *APIService) delTgtTerm(c *gin.Context) {
163
164         tgtID, termID, err := s._decodeTermArgs(c)
165         if err != nil {
166                 common.APIError(c, err.Error())
167                 return
168         }
169         term, err := s.targets.DeleteTerminal(tgtID, termID)
170         if err != nil {
171                 common.APIError(c, err.Error())
172                 return
173         }
174
175         c.JSON(http.StatusOK, term)
176 }
177
178 // openTgtTerm Open a target terminal/console
179 func (s *APIService) openTgtTerm(c *gin.Context) {
180
181         id, tid, err := s._decodeTermArgs(c)
182         if err != nil {
183                 common.APIError(c, err.Error())
184                 return
185         }
186
187         // Retrieve session info
188         sess := s.sessions.Get(c)
189         if sess == nil {
190                 common.APIError(c, "Unknown sessions")
191                 return
192         }
193         sock := sess.IOSocket
194         if sock == nil {
195                 common.APIError(c, "Websocket not established")
196                 return
197         }
198
199         term, err := s.targets.OpenTerminal(id, tid, sock, sess.ID)
200         if err != nil {
201                 common.APIError(c, err.Error())
202                 return
203         }
204         c.JSON(http.StatusOK, term)
205 }
206
207 // closeTgtTerm Close a terminal
208 func (s *APIService) closeTgtTerm(c *gin.Context) {
209         id, tid, err := s._decodeTermArgs(c)
210         if err != nil {
211                 common.APIError(c, err.Error())
212                 return
213         }
214         term, err := s.targets.CloseTerminal(id, tid)
215         if err != nil {
216                 common.APIError(c, err.Error())
217                 return
218         }
219         c.JSON(http.StatusOK, term)
220 }
221
222 // resizeTgtTerm Resize a terminal
223 func (s *APIService) resizeTgtTerm(c *gin.Context) {
224         var sizeArg xsapiv1.TerminalResizeArgs
225
226         id, tid, err := s._decodeTermArgs(c)
227         if err != nil {
228                 common.APIError(c, err.Error())
229                 return
230         }
231         if err := c.BindJSON(&sizeArg); err != nil {
232                 common.APIError(c, "Invalid arguments")
233                 return
234         }
235
236         term, err := s.targets.ResizeTerminal(id, tid, sizeArg.Cols, sizeArg.Rows)
237         if err != nil {
238                 common.APIError(c, err.Error())
239                 return
240         }
241         c.JSON(http.StatusOK, term)
242 }
243
244 // signalTgtTerm Send a signal to a terminal
245 func (s *APIService) signalTgtTerm(c *gin.Context) {
246         var sigArg xsapiv1.TerminalSignalArgs
247
248         id, tid, err := s._decodeTermArgs(c)
249         if err != nil {
250                 common.APIError(c, err.Error())
251                 return
252         }
253
254         sigName := c.Param("sig")
255         if sigName == "" {
256                 if err := c.BindJSON(&sigArg); err != nil {
257                         common.APIError(c, "Invalid arguments")
258                         return
259                 }
260                 sigName = sigArg.Signal
261         }
262         if sigName == "" {
263                 common.APIError(c, "Invalid arguments")
264                 return
265         }
266
267         if err := s.targets.SignalTerminal(id, tid, sigName); err != nil {
268                 common.APIError(c, err.Error())
269                 return
270         }
271
272         c.JSON(http.StatusOK, "")
273 }
274
275 // _decodeTermArgs Helper to decode arguments of Terminal routes
276 func (s *APIService) _decodeTermArgs(c *gin.Context) (string, string, error) {
277         id, err := s.targets.ResolveID(c.Param("id"))
278         if err != nil {
279                 return "", "", err
280         }
281
282         termID, err := s.targets.ResolveTerminalID(c.Param("tid"))
283         if err != nil {
284                 return id, "", err
285         }
286
287         return id, termID, nil
288 }