// NewManager constructs NodeManager instances func NewManager(port int, rMgr region.Manager, pers persist.MGMDB, notify notifier, log logger.Log) Manager { mgr := Manager{} mgr.listenPort = port mgr.mgm = pers mgr.log = logger.Wrap("HOST", log) mgr.internalMsgs = make(chan internalMsg, 32) mgr.requestChan = make(chan Message, 32) mgr.rMgr = rMgr mgr.notify = notify //ch := make(chan hostSession, 32) //go mgr.listen(ch) regions := rMgr.GetRegions() mgr.hosts = make(map[int64]mgm.Host) mgr.hostStats = make(map[int64]mgm.HostStat) mgr.hostConnections = make(map[int64]hostConn) mgr.hMutex = &sync.Mutex{} mgr.hsMutex = &sync.Mutex{} mgr.hcMutex = &sync.Mutex{} for _, h := range pers.QueryHosts() { mgr.hosts[h.ID] = h mgr.hostStats[h.ID] = mgm.HostStat{ID: h.ID} } for _, r := range regions { h, ok := mgr.hosts[r.Host] if ok { h.Regions = append(h.Regions, r.UUID) mgr.hosts[h.ID] = h } } return mgr }
// NewRegionManager constructs a region manager for use func NewRegionManager(binDir string, regionDir string, hostname string, rStat chan<- mgm.RegionStat, log logger.Log) RegionManager { return regMgr{ copyFrom: binDir, regionDir: regionDir, hostName: hostname, rStat: rStat, logger: logger.Wrap("Region", log), } }
// NewMGMDB constructs an MGMDB instance for use func NewMGMDB(db Database, osdb Database, sim simian.Connector, log logger.Log) MGMDB { mgm := MGMDB{ db: db, osdb: osdb, sim: sim, log: logger.Wrap("MGMDB", log), reqs: make(chan mgmReq, 64), } go mgm.process() return mgm }
// NewRegion constructs a Region for use func NewRegion(rID uuid.UUID, path string, hostname string, rStat chan<- mgm.RegionStat, log logger.Log) Region { reg := region{} reg.UUID = rID reg.cmds = make(chan regionCmd, 8) reg.log = logger.Wrap(rID.String(), log) reg.dir = path reg.rStat = rStat reg.hostName = hostname go reg.communicate() return reg }
// NewManager constructs a session manager for use func NewManager(uMgr user.Manager, hMgr host.Manager, rMgr region.Manager, jMgr job.Manager, notify Notifier, log logger.Log) Manager { m := Manager{} m.log = logger.Wrap("CLIENT", log) m.uMgr = uMgr m.hMgr = hMgr m.rMgr = rMgr m.jMgr = jMgr m.clients = make(map[uuid.UUID]userConn) m.clientMutex = &sync.Mutex{} go listen(&m, notify) return m }
// NewManager constructs a user.Manager for use func NewManager(rMgr region.Manager, hMgr host.Manager, jMgr job.Manager, userConnector core.UserConnector, pers persist.MGMDB, notify notifier, log logger.Log) Manager { um := Manager{} um.log = logger.Wrap("USER", log) um.conn = userConnector um.hMgr = hMgr um.rMgr = rMgr um.jMgr = jMgr um.mgm = pers um.users = make(map[uuid.UUID]mgm.User) um.uMutex = &sync.Mutex{} um.pendingUsers = make(map[string]mgm.PendingUser) um.puMutex = &sync.Mutex{} um.estates = make(map[int64]mgm.Estate) um.estateMutex = &sync.Mutex{} um.groups = make(map[uuid.UUID]mgm.Group) um.groupMutex = &sync.Mutex{} um.notify = notify // Get users from simian users, err := userConnector.GetUsers() if err != nil { um.log.Fatal("Cannot get users from simian: ", err.Error()) } for _, u := range users { um.users[u.UserID] = u } // get pending users from mysql for _, u := range pers.QueryPendingUsers() { um.pendingUsers[u.Email] = u } //get estates from mysql for _, e := range pers.QueryEstates() { um.estates[e.ID] = e } // Get groups from simian groups, err := userConnector.GetGroups() if err != nil { um.log.Fatal("Cannot get groups from simian: ", err.Error()) } for _, g := range groups { um.groups[g.ID] = g } return um }
// NewManager constructs a RegionManager for use func NewManager(mgmURL string, simianURL string, pers persist.MGMDB, osdb persist.Database, notify notifier, log logger.Log) Manager { rMgr := Manager{} rMgr.simianURL = simianURL rMgr.mgmURL = mgmURL rMgr.mgm = pers rMgr.osdb = osdb rMgr.log = logger.Wrap("REGION", log) rMgr.regions = make(map[uuid.UUID]mgm.Region) rMgr.regionStats = make(map[uuid.UUID]mgm.RegionStat) rMgr.rMutex = &sync.Mutex{} rMgr.rsMutex = &sync.Mutex{} rMgr.notify = notify for _, r := range pers.QueryRegions() { rMgr.regions[r.UUID] = r rMgr.regionStats[r.UUID] = mgm.RegionStat{} } return rMgr }
// NewManager constructs a jobManager for use func NewManager(filePath string, mgmURL string, hubRegion uuid.UUID, pers persist.MGMDB, notify notifier, log logger.Log) Manager { j := Manager{} j.fileUp = make(chan fileUpload, 32) j.localPath = filePath j.mgmURL = mgmURL j.log = logger.Wrap("JOB", log) j.mgm = pers j.hub = hubRegion j.rUp = make(chan uuid.UUID, 32) j.rDn = make(chan uuid.UUID, 32) j.notify = notify j.jobs = make(map[int64]mgm.Job) for _, t := range pers.QueryJobs() { j.jobs[t.ID] = t } j.jMutex = &sync.Mutex{} go j.process() return j }
// NewClient register a new html5 websocket connection to the client manager func (m Manager) NewClient(so socketio.Socket, guid uuid.UUID) { m.log.Info("New client: %v", guid.String()) c := userConn{guid, so, logger.Wrap(guid.String(), m.log)} c.log.Info("Connected") m.clientMutex.Lock() if conn, ok := m.clients[guid]; ok { conn.Close() } m.clients[guid] = c m.clientMutex.Unlock() permissionDenied, _ := json.Marshal(userResponse{false, "Permission Denied"}) success, _ := json.Marshal(userResponse{true, ""}) so.On("AddHost", func(hostString string) string { c.log.Info("Requesting add host %v", hostString) // only admins may operate on hosts if !m.uMgr.UserIsAdmin(c.uid) { return string(permissionDenied) } err := m.hMgr.AddHost(hostString) if err != nil { resp, _ := json.Marshal(userResponse{false, err.Error()}) return string(resp) } return string(success) }) so.On("RemoveHost", func(idString string) string { c.log.Info("Requesting Remove host %v", idString) // only admins may operate on hosts if !m.uMgr.UserIsAdmin(c.uid) { return string(permissionDenied) } //parse host id from string id, err := strconv.ParseInt(idString, 10, 64) if err != nil { resp, _ := json.Marshal(userResponse{false, err.Error()}) return string(resp) } //remove the host err = m.hMgr.RemoveHost(id) if err != nil { resp, _ := json.Marshal(userResponse{false, err.Error()}) return string(resp) } return string(success) }) so.On("StartRegion", func(msg string) string { return string(permissionDenied) }) so.On("StopRegion", func(msg string) string { return string(permissionDenied) }) so.On("KillRegion", func(msg string) string { return string(permissionDenied) }) so.On("OpenConsole", func(msg string) string { return string(permissionDenied) }) so.On("ConsoleCommand", func(msg string) string { return string(permissionDenied) }) so.On("CloseConsole", func(msg string) string { return string(permissionDenied) }) so.On("SetLocation", func(msg string) string { return string(permissionDenied) }) so.On("SetHost", func(msg string) string { return string(permissionDenied) }) so.On("SetEstate", func(msg string) string { return string(permissionDenied) }) so.On("DeleteJob", func(msg string) string { return string(permissionDenied) }) so.On("OarUpload", func(msg string) string { return string(permissionDenied) }) so.On("IarUpload", func(msg string) string { return string(permissionDenied) }) so.On("SetPassword", func(msg string) string { type credentials struct { UserID uuid.UUID Password string } creds := credentials{} err := json.Unmarshal([]byte(msg), &creds) if err != nil { resp, _ := json.Marshal(userResponse{false, "Invalid data packet"}) return string(resp) } c.log.Info("Requesting change password for %v", creds.UserID.String()) //only admins may change other users passwords if !m.uMgr.UserIsAdmin(c.uid) && creds.UserID != c.uid { return string(permissionDenied) } err = m.uMgr.SetPassword(creds.UserID, creds.Password) if err != nil { resp, _ := json.Marshal(userResponse{false, err.Error()}) return string(resp) } return string(success) }) so.On("GetConfig", func(guid string) string { c.log.Info("Requesting config %v", guid) if !m.uMgr.UserIsAdmin(c.uid) { return string(permissionDenied) } type response struct { Success bool Message string Configs []mgm.ConfigOption } state := response{} state.Configs = []mgm.ConfigOption{} if guid == "" { state.Configs = m.rMgr.GetDefaultConfigs() state.Success = true } else { id, err := uuid.FromString(guid) if err != nil { m.log.Error("Error serving region configs, invalid uuid") state.Message = fmt.Sprintf("Invalid Region ID %v", guid) } else { state.Configs = m.rMgr.GetConfigs(id) state.Success = true } } c.log.Info("Config complete with result %v", state.Success) result, _ := json.Marshal(state) return string(result) }) so.On("GetState", func(msg string) string { c.log.Info("Requesting MGM State") type mgmState struct { Success bool Users []mgm.User PendingUsers []mgm.PendingUser Jobs []mgm.Job Estates []mgm.Estate Groups []mgm.Group Regions []mgm.Region RegionStats []mgm.RegionStat Hosts []mgm.Host HostStats []mgm.HostStat } state := mgmState{} state.Success = true //populate data fields state.Users = m.uMgr.GetUsers() state.Jobs = m.jMgr.GetJobsForUser(c.uid) state.Estates = m.uMgr.GetEstates() state.Groups = m.uMgr.GetGroups() state.Regions = m.rMgr.GetRegions() state.RegionStats = m.rMgr.GetRegionStats() if m.uMgr.UserIsAdmin(c.uid) { state.PendingUsers = m.uMgr.GetPendingUsers() state.Hosts = m.hMgr.GetHosts() state.HostStats = m.hMgr.GetHostStats() } c.log.Info("Sending MGM state") result, _ := json.Marshal(state) return string(result) }) }
// NewHTTPConnector constructs an http connector for use func NewHTTPConnector(jobMgr job.Manager, mgm persist.MGMDB, authenticator simian.Connector, userMgr user.Manager, mailer email.ClientEmailer, log logger.Log) HTTPConnector { gob.Register(uuid.UUID{}) return HTTPConnector{authenticator, logger.Wrap("HTTP", log), userMgr, mailer, jobMgr, mgm} }
// NewWebsocketConnector constructs a websocket handler for use func NewWebsocketConnector(hc HTTPConnector, s chan<- core.UserSession, log logger.Log) WebSocketConnector { return wsConn{hc, s, logger.Wrap("WEBSOCK", log)} }