From be13167b869161b6e19dc3e94835245cdc7911e5 Mon Sep 17 00:00:00 2001 From: Sebastien Douheret Date: Tue, 31 Oct 2017 18:09:45 +0100 Subject: [PATCH] Moved all structs exposed by API into apiv1 package Signed-off-by: Sebastien Douheret --- .vscode/settings.json | 3 +- lib/agent/apiv1-config.go | 32 ++++-------------- lib/agent/apiv1-events.go | 17 ++-------- lib/agent/apiv1-exec.go | 24 +++++-------- lib/agent/apiv1-projects.go | 3 +- lib/agent/apiv1-sdks.go | 9 +++++ lib/agent/apiv1-version.go | 21 +++--------- lib/agent/apiv1.go | 5 +-- lib/agent/events.go | 40 +++++++--------------- lib/agent/project-interface.go | 45 +++++------------------- lib/agent/project-pathmap.go | 9 ++--- lib/agent/project-st.go | 21 ++++++------ lib/agent/projects.go | 29 ++++++++-------- lib/agent/{session.go => sessions.go} | 2 +- lib/agent/webserver.go | 4 +-- lib/agent/xdsserver.go | 23 +++++++------ lib/apiv1/config.go | 22 ++++++++++++ lib/apiv1/events.go | 33 ++++++++++++++++++ lib/apiv1/exec.go | 64 +++++++++++++++++++++++++++++++++++ lib/apiv1/projects.go | 32 ++++++++++++++++++ lib/apiv1/sdks.go | 11 ++++++ lib/apiv1/version.go | 15 ++++++++ 22 files changed, 282 insertions(+), 182 deletions(-) create mode 100644 lib/agent/apiv1-sdks.go rename lib/agent/{session.go => sessions.go} (99%) create mode 100644 lib/apiv1/config.go create mode 100644 lib/apiv1/events.go create mode 100644 lib/apiv1/exec.go create mode 100644 lib/apiv1/projects.go create mode 100644 lib/apiv1/sdks.go create mode 100644 lib/apiv1/version.go diff --git a/.vscode/settings.json b/.vscode/settings.json index eceb734..eafbcfa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -54,6 +54,7 @@ "prjs", "iosk", "CIFS", - "IPROJECT" + "IPROJECT", + "unregister" ] } diff --git a/lib/agent/apiv1-config.go b/lib/agent/apiv1-config.go index 31d8de6..2197720 100644 --- a/lib/agent/apiv1-config.go +++ b/lib/agent/apiv1-config.go @@ -5,33 +5,13 @@ import ( "sync" "github.com/gin-gonic/gin" + "github.com/iotbzh/xds-agent/lib/apiv1" "github.com/iotbzh/xds-agent/lib/xdsconfig" common "github.com/iotbzh/xds-common/golib" ) var confMut sync.Mutex -// APIConfig parameters (json format) of /config command -type APIConfig struct { - Servers []ServerCfg `json:"servers"` - - // Not exposed outside in JSON - Version string `json:"-"` - APIVersion string `json:"-"` - VersionGitTag string `json:"-"` -} - -// ServerCfg . -type ServerCfg struct { - ID string `json:"id"` - URL string `json:"url"` - APIURL string `json:"apiUrl"` - PartialURL string `json:"partialUrl"` - ConnRetry int `json:"connRetry"` - Connected bool `json:"connected"` - Disabled bool `json:"disabled"` -} - // GetConfig returns the configuration func (s *APIService) getConfig(c *gin.Context) { confMut.Lock() @@ -44,7 +24,7 @@ func (s *APIService) getConfig(c *gin.Context) { // SetConfig sets configuration func (s *APIService) setConfig(c *gin.Context) { - var cfgArg APIConfig + var cfgArg apiv1.APIConfig if c.BindJSON(&cfgArg) != nil { common.APIError(c, "Invalid arguments") return @@ -85,16 +65,16 @@ func (s *APIService) setConfig(c *gin.Context) { c.JSON(http.StatusOK, s._getConfig()) } -func (s *APIService) _getConfig() APIConfig { - cfg := APIConfig{ +func (s *APIService) _getConfig() apiv1.APIConfig { + cfg := apiv1.APIConfig{ Version: s.Config.Version, APIVersion: s.Config.APIVersion, VersionGitTag: s.Config.VersionGitTag, - Servers: []ServerCfg{}, + Servers: []apiv1.ServerCfg{}, } for _, svr := range s.xdsServers { - cfg.Servers = append(cfg.Servers, ServerCfg{ + cfg.Servers = append(cfg.Servers, apiv1.ServerCfg{ ID: svr.ID, URL: svr.BaseURL, APIURL: svr.APIURL, diff --git a/lib/agent/apiv1-events.go b/lib/agent/apiv1-events.go index 8aad18a..cb7cde1 100644 --- a/lib/agent/apiv1-events.go +++ b/lib/agent/apiv1-events.go @@ -4,21 +4,10 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/iotbzh/xds-agent/lib/apiv1" common "github.com/iotbzh/xds-common/golib" ) -// EventRegisterArgs is the parameters (json format) of /events/register command -type EventRegisterArgs struct { - Name string `json:"name"` - ProjectID string `json:"filterProjectID"` -} - -// EventUnRegisterArgs is the parameters (json format) of /events/unregister command -type EventUnRegisterArgs struct { - Name string `json:"name"` - ID int `json:"id"` -} - // eventsList Registering for events that will be send over a WS func (s *APIService) eventsList(c *gin.Context) { c.JSON(http.StatusOK, s.events.GetList()) @@ -26,7 +15,7 @@ func (s *APIService) eventsList(c *gin.Context) { // eventsRegister Registering for events that will be send over a WS func (s *APIService) eventsRegister(c *gin.Context) { - var args EventRegisterArgs + var args apiv1.EventRegisterArgs if c.BindJSON(&args) != nil || args.Name == "" { common.APIError(c, "Invalid arguments") @@ -50,7 +39,7 @@ func (s *APIService) eventsRegister(c *gin.Context) { // eventsRegister Registering for events that will be send over a WS func (s *APIService) eventsUnRegister(c *gin.Context) { - var args EventUnRegisterArgs + var args apiv1.EventUnRegisterArgs if c.BindJSON(&args) != nil || args.Name == "" { common.APIError(c, "Invalid arguments") diff --git a/lib/agent/apiv1-exec.go b/lib/agent/apiv1-exec.go index 37070f7..9c65bc2 100644 --- a/lib/agent/apiv1-exec.go +++ b/lib/agent/apiv1-exec.go @@ -6,16 +6,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/iotbzh/xds-agent/lib/apiv1" common "github.com/iotbzh/xds-common/golib" uuid "github.com/satori/go.uuid" ) -// ExecArgs Only define used fields -type ExecArgs struct { - ID string `json:"id" binding:"required"` - CmdID string `json:"cmdID"` // command unique ID -} - var execCmdID = 1 // ExecCmd executes remotely a command @@ -34,7 +29,7 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) { common.APIError(c, err.Error()) } - args := ExecArgs{} + args := apiv1.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 { @@ -75,10 +70,10 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) { // Forward XDSServer WS events to client WS // TODO removed static event name list and get it from XDSServer evtList := []string{ - "exec:input", - "exec:output", - "exec:inferior-input", - "exec:inferior-output", + apiv1.ExecInEvent, + apiv1.ExecOutEvent, + apiv1.ExecInferiorInEvent, + apiv1.ExecInferiorOutEvent, } so := *sock fwdFuncID := []uuid.UUID{} @@ -99,15 +94,15 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) { // Handle Exit event separately to cleanup registered listener var exitFuncID uuid.UUID exitFunc := func(evData interface{}) { - so.Emit("exec:exit", evData) + so.Emit(apiv1.ExecExitEvent, evData) // cleanup listener for i, evName := range evtList { svr.EventOff(evName, fwdFuncID[i]) } - svr.EventOff("exec:exit", exitFuncID) + svr.EventOff(apiv1.ExecExitEvent, exitFuncID) } - exitFuncID, err = svr.EventOn("exec:exit", exitFunc) + exitFuncID, err = svr.EventOn(apiv1.ExecExitEvent, exitFunc) if err != nil { common.APIError(c, err.Error()) return @@ -127,5 +122,4 @@ func (s *APIService) _execRequest(cmd string, c *gin.Context) { return } c.JSON(http.StatusOK, string(body)) - } diff --git a/lib/agent/apiv1-projects.go b/lib/agent/apiv1-projects.go index d4b5e74..89218ab 100644 --- a/lib/agent/apiv1-projects.go +++ b/lib/agent/apiv1-projects.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/iotbzh/xds-agent/lib/apiv1" common "github.com/iotbzh/xds-common/golib" ) @@ -25,7 +26,7 @@ func (s *APIService) getProject(c *gin.Context) { // addProject adds a new project to server config func (s *APIService) addProject(c *gin.Context) { - var cfgArg ProjectConfig + var cfgArg apiv1.ProjectConfig if c.BindJSON(&cfgArg) != nil { common.APIError(c, "Invalid arguments") return diff --git a/lib/agent/apiv1-sdks.go b/lib/agent/apiv1-sdks.go new file mode 100644 index 0000000..ee6409d --- /dev/null +++ b/lib/agent/apiv1-sdks.go @@ -0,0 +1,9 @@ +package agent + +// sdksPassthroughInit Declare passthrough routes for sdks +func (s *APIService) sdksPassthroughInit(svr *XdsServer) error { + svr.PassthroughGet("/sdks") + svr.PassthroughGet("/sdk/:id") + + return nil +} diff --git a/lib/agent/apiv1-version.go b/lib/agent/apiv1-version.go index 6b4923f..c75e7f5 100644 --- a/lib/agent/apiv1-version.go +++ b/lib/agent/apiv1-version.go @@ -4,25 +4,14 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/iotbzh/xds-agent/lib/apiv1" common "github.com/iotbzh/xds-common/golib" ) -type version struct { - ID string `json:"id"` - Version string `json:"version"` - APIVersion string `json:"apiVersion"` - VersionGitTag string `json:"gitTag"` -} - -type apiVersion struct { - Client version `json:"client"` - Server []version `json:"servers"` -} - // getInfo : return various information about server func (s *APIService) getVersion(c *gin.Context) { - response := apiVersion{ - Client: version{ + response := apiv1.XDSVersion{ + Client: apiv1.VersionData{ ID: "", Version: s.Config.Version, APIVersion: s.Config.APIVersion, @@ -30,9 +19,9 @@ func (s *APIService) getVersion(c *gin.Context) { }, } - svrVer := []version{} + svrVer := []apiv1.VersionData{} for _, svr := range s.xdsServers { - res := version{} + res := apiv1.VersionData{} if err := svr.GetVersion(&res); err != nil { common.APIError(c, "Cannot retrieve version of XDS server ID %s : %v", svr.ID, err.Error()) return diff --git a/lib/agent/apiv1.go b/lib/agent/apiv1.go index 77b05ba..3fd9990 100644 --- a/lib/agent/apiv1.go +++ b/lib/agent/apiv1.go @@ -95,8 +95,9 @@ func (s *APIService) AddXdsServer(cfg xdsconfig.XDSServerConf) (*XdsServer, erro // Passthrough routes (handle by XDS Server) grp := s.apiRouter.Group(svr.PartialURL) svr.SetAPIRouterGroup(grp) - svr.PassthroughGet("/sdks") - svr.PassthroughGet("/sdk/:id") + + // Declare passthrough routes + s.sdksPassthroughInit(svr) } // Established connection diff --git a/lib/agent/events.go b/lib/agent/events.go index e66f758..046c377 100644 --- a/lib/agent/events.go +++ b/lib/agent/events.go @@ -3,39 +3,23 @@ package agent import ( "fmt" "time" -) - -// Events constants -const ( - // EventTypePrefix Used as event prefix - EventTypePrefix = "event:" // following by event type - // Supported Events type - EVTAll = "all" - EVTServerConfig = "server-config" // data type ServerCfg - EVTProjectAdd = "project-add" // data type ProjectConfig - EVTProjectDelete = "project-delete" // data type ProjectConfig - EVTProjectChange = "project-state-change" // data type ProjectConfig + "github.com/iotbzh/xds-agent/lib/apiv1" ) var _EVTAllList = []string{ - EVTServerConfig, - EVTProjectAdd, - EVTProjectDelete, - EVTProjectChange, -} - -// EventMsg Message send -type EventMsg struct { - Time string `json:"time"` - Type string `json:"type"` - Data interface{} `json:"data"` + apiv1.EVTServerConfig, + apiv1.EVTProjectAdd, + apiv1.EVTProjectDelete, + apiv1.EVTProjectChange, } +// EventDef Definition on one event type EventDef struct { sids map[string]int } +// Events Hold registered events per context type Events struct { *Context eventsMap map[string]*EventDef @@ -63,7 +47,7 @@ func (e *Events) GetList() []string { // Register Used by a client/session to register to a specific (or all) event(s) func (e *Events) Register(evName, sessionID string) error { evs := _EVTAllList - if evName != EVTAll { + if evName != apiv1.EVTAll { if _, ok := e.eventsMap[evName]; !ok { return fmt.Errorf("Unsupported event type name") } @@ -78,7 +62,7 @@ func (e *Events) Register(evName, sessionID string) error { // UnRegister Used by a client/session to unregister event(s) func (e *Events) UnRegister(evName, sessionID string) error { evs := _EVTAllList - if evName != EVTAll { + if evName != apiv1.EVTAll { if _, ok := e.eventsMap[evName]; !ok { return fmt.Errorf("Unsupported event type name") } @@ -115,13 +99,13 @@ func (e *Events) Emit(evName string, data interface{}) error { } continue } - msg := EventMsg{ + msg := apiv1.EventMsg{ Time: time.Now().String(), Type: evName, Data: data, } - if err := (*so).Emit(EventTypePrefix+evName, msg); err != nil { - e.Log.Errorf("WS Emit %v error : %v", EventTypePrefix+evName, err) + if err := (*so).Emit(apiv1.EventTypePrefix+evName, msg); err != nil { + e.Log.Errorf("WS Emit %v error : %v", apiv1.EventTypePrefix+evName, err) if firstErr == nil { firstErr = err } diff --git a/lib/agent/project-interface.go b/lib/agent/project-interface.go index 0a4a17e..c9e9ec5 100644 --- a/lib/agent/project-interface.go +++ b/lib/agent/project-interface.go @@ -1,43 +1,14 @@ package agent -// ProjectType definition -type ProjectType string - -const ( - TypePathMap = "PathMap" - TypeCloudSync = "CloudSync" - TypeCifsSmb = "CIFS" -) - -// Project Status definition -const ( - StatusErrorConfig = "ErrorConfig" - StatusDisable = "Disable" - StatusEnable = "Enable" - StatusPause = "Pause" - StatusSyncing = "Syncing" -) +import "github.com/iotbzh/xds-agent/lib/apiv1" // IPROJECT Project interface type IPROJECT interface { - Add(cfg ProjectConfig) (*ProjectConfig, error) // Add a new project - Delete() error // Delete a project - GetProject() *ProjectConfig // Get project public configuration - UpdateProject(prj ProjectConfig) (*ProjectConfig, error) // Update project configuration - GetServer() *XdsServer // Get XdsServer that holds this project - Sync() error // Force project files synchronization - IsInSync() (bool, error) // Check if project files are in-sync -} - -// ProjectConfig is the config for one project -type ProjectConfig struct { - ID string `json:"id"` - ServerID string `json:"serverId"` - Label string `json:"label"` - ClientPath string `json:"clientPath"` - ServerPath string `json:"serverPath"` - Type ProjectType `json:"type"` - Status string `json:"status"` - IsInSync bool `json:"isInSync"` - DefaultSdk string `json:"defaultSdk"` + Add(cfg apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) // Add a new project + Delete() error // Delete a project + GetProject() *apiv1.ProjectConfig // Get project public configuration + UpdateProject(prj apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) // Update project configuration + GetServer() *XdsServer // Get XdsServer that holds this project + Sync() error // Force project files synchronization + IsInSync() (bool, error) // Check if project files are in-sync } diff --git a/lib/agent/project-pathmap.go b/lib/agent/project-pathmap.go index aacbd1f..7a96e6e 100644 --- a/lib/agent/project-pathmap.go +++ b/lib/agent/project-pathmap.go @@ -6,6 +6,7 @@ import ( "os" "strings" + "github.com/iotbzh/xds-agent/lib/apiv1" common "github.com/iotbzh/xds-common/golib" ) @@ -29,7 +30,7 @@ func NewProjectPathMap(ctx *Context, svr *XdsServer) *PathMap { } // Add a new project -func (p *PathMap) Add(cfg ProjectConfig) (*ProjectConfig, error) { +func (p *PathMap) Add(cfg apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) { var err error var file *os.File errMsg := "ClientPath sanity check error (%d): %v" @@ -91,17 +92,17 @@ func (p *PathMap) Delete() error { } // GetProject Get public part of project config -func (p *PathMap) GetProject() *ProjectConfig { +func (p *PathMap) GetProject() *apiv1.ProjectConfig { prj := p.server.FolderToProject(*p.folder) prj.ServerID = p.server.ID return &prj } // UpdateProject Set project config -func (p *PathMap) UpdateProject(prj ProjectConfig) (*ProjectConfig, error) { +func (p *PathMap) UpdateProject(prj apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) { p.folder = p.server.ProjectToFolder(prj) np := p.GetProject() - if err := p.events.Emit(EVTProjectChange, np); err != nil { + if err := p.events.Emit(apiv1.EVTProjectChange, np); err != nil { return np, err } return np, nil diff --git a/lib/agent/project-st.go b/lib/agent/project-st.go index c0d2550..dba5978 100644 --- a/lib/agent/project-st.go +++ b/lib/agent/project-st.go @@ -1,6 +1,7 @@ package agent import ( + "github.com/iotbzh/xds-agent/lib/apiv1" st "github.com/iotbzh/xds-agent/lib/syncthing" ) @@ -25,7 +26,7 @@ func NewProjectST(ctx *Context, svr *XdsServer) *STProject { } // Add a new project -func (p *STProject) Add(cfg ProjectConfig) (*ProjectConfig, error) { +func (p *STProject) Add(cfg apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) { var err error // Add project/folder into XDS Server @@ -48,7 +49,7 @@ func (p *STProject) Add(cfg ProjectConfig) (*ProjectConfig, error) { locPrj, err := p.SThg.FolderConfigGet(id) if err != nil { - svrPrj.Status = StatusErrorConfig + svrPrj.Status = apiv1.StatusErrorConfig return nil, err } if svrPrj.ID != locPrj.ID { @@ -70,14 +71,14 @@ func (p *STProject) Delete() error { } // GetProject Get public part of project config -func (p *STProject) GetProject() *ProjectConfig { +func (p *STProject) GetProject() *apiv1.ProjectConfig { prj := p.server.FolderToProject(*p.folder) prj.ServerID = p.server.ID return &prj } // UpdateProject Update project config -func (p *STProject) UpdateProject(prj ProjectConfig) (*ProjectConfig, error) { +func (p *STProject) UpdateProject(prj apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) { // Update folder p.folder = p.server.ProjectToFolder(prj) svrPrj := p.GetProject() @@ -141,7 +142,7 @@ func (p *STProject) _cbServerFolderChanged(data interface{}) { p.folder.DataCloudSync.STSvrIsInSync = evt.Folder.IsInSync p.folder.DataCloudSync.STSvrStatus = evt.Folder.Status - if err := p.events.Emit(EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil { + if err := p.events.Emit(apiv1.EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil { p.Log.Warningf("Cannot notify project change: %v", err) } } @@ -161,15 +162,15 @@ func (p *STProject) _cbLocalSTEvents(ev st.Event, data *st.EventsCBData) { to := ev.Data["to"] switch to { case "scanning", "syncing": - sts = StatusSyncing + sts = apiv1.StatusSyncing case "idle": - sts = StatusEnable + sts = apiv1.StatusEnable } inSync = (to == "idle") case st.EventFolderPaused: - if sts == StatusEnable { - sts = StatusPause + if sts == apiv1.StatusEnable { + sts = apiv1.StatusPause } inSync = false } @@ -179,7 +180,7 @@ func (p *STProject) _cbLocalSTEvents(ev st.Event, data *st.EventsCBData) { p.folder.DataCloudSync.STLocIsInSync = inSync p.folder.DataCloudSync.STLocStatus = sts - if err := p.events.Emit(EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil { + if err := p.events.Emit(apiv1.EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil { p.Log.Warningf("Cannot notify project change: %v", err) } } diff --git a/lib/agent/projects.go b/lib/agent/projects.go index 5e20395..6804d35 100644 --- a/lib/agent/projects.go +++ b/lib/agent/projects.go @@ -5,6 +5,7 @@ import ( "log" "time" + "github.com/iotbzh/xds-agent/lib/apiv1" "github.com/iotbzh/xds-agent/lib/syncthing" "github.com/syncthing/syncthing/lib/sync" ) @@ -78,7 +79,7 @@ func (p *Projects) Get(id string) *IPROJECT { } // GetProjectArr returns the config of all folders as an array -func (p *Projects) GetProjectArr() []ProjectConfig { +func (p *Projects) GetProjectArr() []apiv1.ProjectConfig { pjMutex.Lock() defer pjMutex.Unlock() @@ -86,8 +87,8 @@ func (p *Projects) GetProjectArr() []ProjectConfig { } // GetProjectArrUnsafe Same as GetProjectArr without mutex protection -func (p *Projects) GetProjectArrUnsafe() []ProjectConfig { - conf := []ProjectConfig{} +func (p *Projects) GetProjectArrUnsafe() []apiv1.ProjectConfig { + conf := []apiv1.ProjectConfig{} for _, v := range p.projects { prj := (*v).GetProject() conf = append(conf, *prj) @@ -96,14 +97,14 @@ func (p *Projects) GetProjectArrUnsafe() []ProjectConfig { } // Add adds a new folder -func (p *Projects) Add(newF ProjectConfig) (*ProjectConfig, error) { +func (p *Projects) Add(newF apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) { prj, err := p.createUpdate(newF, true, false) if err != nil { return prj, err } // Notify client with event - if err := p.events.Emit(EVTProjectAdd, *prj); err != nil { + if err := p.events.Emit(apiv1.EVTProjectAdd, *prj); err != nil { p.Log.Warningf("Cannot notify project deletion: %v", err) } @@ -111,7 +112,7 @@ func (p *Projects) Add(newF ProjectConfig) (*ProjectConfig, error) { } // CreateUpdate creates or update a folder -func (p *Projects) createUpdate(newF ProjectConfig, create bool, initial bool) (*ProjectConfig, error) { +func (p *Projects) createUpdate(newF apiv1.ProjectConfig, create bool, initial bool) (*apiv1.ProjectConfig, error) { var err error pjMutex.Lock() @@ -143,7 +144,7 @@ func (p *Projects) createUpdate(newF ProjectConfig, create bool, initial bool) ( var fld IPROJECT switch newF.Type { // SYNCTHING - case TypeCloudSync: + case apiv1.TypeCloudSync: if p.SThg != nil { fld = NewProjectST(p.Context, svr) } else { @@ -151,24 +152,24 @@ func (p *Projects) createUpdate(newF ProjectConfig, create bool, initial bool) ( } // PATH MAP - case TypePathMap: + case apiv1.TypePathMap: fld = NewProjectPathMap(p.Context, svr) default: return nil, fmt.Errorf("Unsupported folder type") } - var newPrj *ProjectConfig + var newPrj *apiv1.ProjectConfig if create { // Add project on server if newPrj, err = fld.Add(newF); err != nil { - newF.Status = StatusErrorConfig + newF.Status = apiv1.StatusErrorConfig log.Printf("ERROR Adding project: %v\n", err) return newPrj, err } } else { // Just update project config if newPrj, err = fld.UpdateProject(newF); err != nil { - newF.Status = StatusErrorConfig + newF.Status = apiv1.StatusErrorConfig log.Printf("ERROR Updating project: %v\n", err) return newPrj, err } @@ -194,13 +195,13 @@ func (p *Projects) createUpdate(newF ProjectConfig, create bool, initial bool) ( } // Delete deletes a specific folder -func (p *Projects) Delete(id string) (ProjectConfig, error) { +func (p *Projects) Delete(id string) (apiv1.ProjectConfig, error) { var err error pjMutex.Lock() defer pjMutex.Unlock() - fld := ProjectConfig{} + fld := apiv1.ProjectConfig{} fc, exist := p.projects[id] if !exist { return fld, fmt.Errorf("unknown id") @@ -215,7 +216,7 @@ func (p *Projects) Delete(id string) (ProjectConfig, error) { delete(p.projects, id) // Notify client with event - if err := p.events.Emit(EVTProjectDelete, *prj); err != nil { + if err := p.events.Emit(apiv1.EVTProjectDelete, *prj); err != nil { p.Log.Warningf("Cannot notify project deletion: %v", err) } diff --git a/lib/agent/session.go b/lib/agent/sessions.go similarity index 99% rename from lib/agent/session.go rename to lib/agent/sessions.go index 06789d5..7347480 100644 --- a/lib/agent/session.go +++ b/lib/agent/sessions.go @@ -154,7 +154,7 @@ func (s *Sessions) UpdateIOSocket(sid string, so *socketio.Socket) error { return nil } -// nesSession Allocate a new client session +// newSession Allocate a new client session func (s *Sessions) newSession(prefix string) *ClientSession { uuid := prefix + uuid.NewV4().String() id := base64.URLEncoding.EncodeToString([]byte(uuid)) diff --git a/lib/agent/webserver.go b/lib/agent/webserver.go index 4b2e024..d15236d 100644 --- a/lib/agent/webserver.go +++ b/lib/agent/webserver.go @@ -227,11 +227,11 @@ func (s *WebServer) socketHandler(c *gin.Context) { } s.sIOServer.On("connection", func(so socketio.Socket) { - s.Log.Debugf("WS Connected (SID=%v)", so.Id()) + s.Log.Debugf("WS Connected (WSID=%s, SID=%s)", so.Id(), sess.ID) s.sessions.UpdateIOSocket(sess.ID, &so) so.On("disconnection", func() { - s.Log.Debugf("WS disconnected (SID=%v)", so.Id()) + s.Log.Debugf("WS disconnected (WSID=%s, SID=%s)", so.Id(), sess.ID) s.sessions.UpdateIOSocket(sess.ID, nil) }) }) diff --git a/lib/agent/xdsserver.go b/lib/agent/xdsserver.go index b76908c..5851a07 100644 --- a/lib/agent/xdsserver.go +++ b/lib/agent/xdsserver.go @@ -11,6 +11,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/iotbzh/xds-agent/lib/apiv1" "github.com/iotbzh/xds-agent/lib/xdsconfig" common "github.com/iotbzh/xds-common/golib" uuid "github.com/satori/go.uuid" @@ -366,7 +367,7 @@ func (xs *XdsServer) EventOff(evName string, id uuid.UUID) error { } // ProjectToFolder Convert Project structure to Folder structure -func (xs *XdsServer) ProjectToFolder(pPrj ProjectConfig) *XdsFolderConfig { +func (xs *XdsServer) ProjectToFolder(pPrj apiv1.ProjectConfig) *XdsFolderConfig { stID := "" if pPrj.Type == XdsTypeCloudSync { stID, _ = xs.SThg.IDGet() @@ -395,7 +396,7 @@ func (xs *XdsServer) ProjectToFolder(pPrj ProjectConfig) *XdsFolderConfig { } // FolderToProject Convert Folder structure to Project structure -func (xs *XdsServer) FolderToProject(fPrj XdsFolderConfig) ProjectConfig { +func (xs *XdsServer) FolderToProject(fPrj XdsFolderConfig) apiv1.ProjectConfig { inSync := fPrj.IsInSync sts := fPrj.Status @@ -404,27 +405,27 @@ func (xs *XdsServer) FolderToProject(fPrj XdsFolderConfig) ProjectConfig { sts = fPrj.DataCloudSync.STSvrStatus switch fPrj.DataCloudSync.STLocStatus { - case StatusErrorConfig, StatusDisable, StatusPause: + case apiv1.StatusErrorConfig, apiv1.StatusDisable, apiv1.StatusPause: sts = fPrj.DataCloudSync.STLocStatus break - case StatusSyncing: - if sts != StatusErrorConfig && sts != StatusDisable && sts != StatusPause { - sts = StatusSyncing + case apiv1.StatusSyncing: + if sts != apiv1.StatusErrorConfig && sts != apiv1.StatusDisable && sts != apiv1.StatusPause { + sts = apiv1.StatusSyncing } break - case StatusEnable: + case apiv1.StatusEnable: // keep STSvrStatus break } } - pPrj := ProjectConfig{ + pPrj := apiv1.ProjectConfig{ ID: fPrj.ID, ServerID: xs.ID, Label: fPrj.Label, ClientPath: fPrj.ClientPath, ServerPath: fPrj.DataPathMap.ServerPath, - Type: ProjectType(fPrj.Type), + Type: apiv1.ProjectType(fPrj.Type), Status: sts, IsInSync: inSync, DefaultSdk: fPrj.DefaultSdk, @@ -591,7 +592,7 @@ func (xs *XdsServer) _SocketConnect() error { // Send event to notify changes func (xs *XdsServer) _NotifyState() { - evSts := ServerCfg{ + evSts := apiv1.ServerCfg{ ID: xs.ID, URL: xs.BaseURL, APIURL: xs.APIURL, @@ -599,7 +600,7 @@ func (xs *XdsServer) _NotifyState() { ConnRetry: xs.ConnRetry, Connected: xs.Connected, } - if err := xs.events.Emit(EVTServerConfig, evSts); err != nil { + if err := xs.events.Emit(apiv1.EVTServerConfig, evSts); err != nil { xs.Log.Warningf("Cannot notify XdsServer state change: %v", err) } } diff --git a/lib/apiv1/config.go b/lib/apiv1/config.go new file mode 100644 index 0000000..f5c1fb5 --- /dev/null +++ b/lib/apiv1/config.go @@ -0,0 +1,22 @@ +package apiv1 + +// APIConfig parameters (json format) of /config command +type APIConfig struct { + Servers []ServerCfg `json:"servers"` + + // Not exposed outside in JSON + Version string `json:"-"` + APIVersion string `json:"-"` + VersionGitTag string `json:"-"` +} + +// ServerCfg . +type ServerCfg struct { + ID string `json:"id"` + URL string `json:"url"` + APIURL string `json:"apiUrl"` + PartialURL string `json:"partialUrl"` + ConnRetry int `json:"connRetry"` + Connected bool `json:"connected"` + Disabled bool `json:"disabled"` +} diff --git a/lib/apiv1/events.go b/lib/apiv1/events.go new file mode 100644 index 0000000..8bad394 --- /dev/null +++ b/lib/apiv1/events.go @@ -0,0 +1,33 @@ +package apiv1 + +// EventRegisterArgs is the parameters (json format) of /events/register command +type EventRegisterArgs struct { + Name string `json:"name"` + ProjectID string `json:"filterProjectID"` +} + +// EventUnRegisterArgs is the parameters (json format) of /events/unregister command +type EventUnRegisterArgs struct { + Name string `json:"name"` + ID int `json:"id"` +} + +// Events definitions +const ( + // EventTypePrefix Used as event prefix + EventTypePrefix = "event:" // following by event type + + // Supported Events type + EVTAll = "all" + EVTServerConfig = "server-config" // data type apiv1.ServerCfg + EVTProjectAdd = "project-add" // data type apiv1.ProjectConfig + EVTProjectDelete = "project-delete" // data type apiv1.ProjectConfig + EVTProjectChange = "project-state-change" // data type apiv1.ProjectConfig +) + +// EventMsg Message send +type EventMsg struct { + Time string `json:"time"` + Type string `json:"type"` + Data interface{} `json:"data"` +} diff --git a/lib/apiv1/exec.go b/lib/apiv1/exec.go new file mode 100644 index 0000000..914ed79 --- /dev/null +++ b/lib/apiv1/exec.go @@ -0,0 +1,64 @@ +package apiv1 + +type ( + // ExecArgs JSON parameters of /exec command + ExecArgs struct { + ID string `json:"id" binding:"required"` + SdkID string `json:"sdkID"` // sdk ID to use for setting env + CmdID string `json:"cmdID"` // command unique ID + Cmd string `json:"cmd" binding:"required"` + Args []string `json:"args"` + Env []string `json:"env"` + RPath string `json:"rpath"` // relative path into project + TTY bool `json:"tty"` // Use a tty, specific to gdb --tty option + TTYGdbserverFix bool `json:"ttyGdbserverFix"` // Set to true to activate gdbserver workaround about inferior output + ExitImmediate bool `json:"exitImmediate"` // when true, exit event sent immediately when command exited (IOW, don't wait file synchronization) + CmdTimeout int `json:"timeout"` // command completion timeout in Second + } + + // ExecInMsg Message used to received input characters (stdin) + ExecInMsg struct { + CmdID string `json:"cmdID"` + Timestamp string `json:"timestamp"` + Stdin string `json:"stdin"` + } + + // ExecOutMsg Message used to send output characters (stdout+stderr) + ExecOutMsg struct { + CmdID string `json:"cmdID"` + Timestamp string `json:"timestamp"` + Stdout string `json:"stdout"` + Stderr string `json:"stderr"` + } + + // ExecExitMsg Message sent when executed command exited + ExecExitMsg struct { + CmdID string `json:"cmdID"` + Timestamp string `json:"timestamp"` + Code int `json:"code"` + Error error `json:"error"` + } + + // ExecSignalArgs JSON parameters of /exec/signal command + ExecSignalArgs struct { + CmdID string `json:"cmdID" binding:"required"` // command id + Signal string `json:"signal" binding:"required"` // signal number + } +) + +const ( + // ExecInEvent Event send in WS when characters are sent (stdin) + ExecInEvent = "exec:input" + + // ExecOutEvent Event send in WS when characters are received (stdout or stderr) + ExecOutEvent = "exec:output" + + // ExecExitEvent Event send in WS when program exited + ExecExitEvent = "exec:exit" + + // ExecInferiorInEvent Event send in WS when characters are sent to an inferior (used by gdb inferior/tty) + ExecInferiorInEvent = "exec:inferior-input" + + // ExecInferiorOutEvent Event send in WS when characters are received by an inferior + ExecInferiorOutEvent = "exec:inferior-output" +) diff --git a/lib/apiv1/projects.go b/lib/apiv1/projects.go new file mode 100644 index 0000000..d76fa09 --- /dev/null +++ b/lib/apiv1/projects.go @@ -0,0 +1,32 @@ +package apiv1 + +// ProjectType definition +type ProjectType string + +const ( + TypePathMap = "PathMap" + TypeCloudSync = "CloudSync" + TypeCifsSmb = "CIFS" +) + +// Project Status definition +const ( + StatusErrorConfig = "ErrorConfig" + StatusDisable = "Disable" + StatusEnable = "Enable" + StatusPause = "Pause" + StatusSyncing = "Syncing" +) + +// ProjectConfig is the config for one project +type ProjectConfig struct { + ID string `json:"id"` + ServerID string `json:"serverId"` + Label string `json:"label"` + ClientPath string `json:"clientPath"` + ServerPath string `json:"serverPath"` + Type ProjectType `json:"type"` + Status string `json:"status"` + IsInSync bool `json:"isInSync"` + DefaultSdk string `json:"defaultSdk"` +} diff --git a/lib/apiv1/sdks.go b/lib/apiv1/sdks.go new file mode 100644 index 0000000..dfa44e2 --- /dev/null +++ b/lib/apiv1/sdks.go @@ -0,0 +1,11 @@ +package apiv1 + +// SDK Define a cross tool chain used to build application +type SDK struct { + ID string `json:"id" binding:"required"` + Name string `json:"name"` + Profile string `json:"profile"` + Version string `json:"version"` + Arch string `json:"arch"` + Path string `json:"path"` +} diff --git a/lib/apiv1/version.go b/lib/apiv1/version.go new file mode 100644 index 0000000..956f890 --- /dev/null +++ b/lib/apiv1/version.go @@ -0,0 +1,15 @@ +package apiv1 + +// VersionData +type VersionData struct { + ID string `json:"id"` + Version string `json:"version"` + APIVersion string `json:"apiVersion"` + VersionGitTag string `json:"gitTag"` +} + +// XDSVersion +type XDSVersion struct { + Client VersionData `json:"client"` + Server []VersionData `json:"servers"` +} -- 2.16.6