def __init__(self, model_controller, plugin_controller): self.active_workspace = None self._couchAvailable = False self.report_manager = ReportManager(10, plugin_controller) self.couchdbmanager = PersistenceManagerFactory().getInstance() self.fsmanager = FSManager() self._workspaces = {} self._workspaces_types = {} self._model_controller = model_controller self._excluded_directories = [".svn"] self.workspace_persister = WorkspacePersister()
class WorkspaceManager(object): """ This handles all workspaces. It checks for existing workspaces inside the persistence directory. It is in charge of starting the WorkspacesAutoSaver to persist each workspace. This class stores information in $HOME/.faraday/config/workspacemanager.xml file to keep track of created workspaces to be able to load them """ def __init__(self, model_controller, plugin_controller): self.active_workspace = None self._couchAvailable = False self.report_manager = ReportManager(10, plugin_controller) self.couchdbmanager = PersistenceManagerFactory().getInstance() self.fsmanager = FSManager() self._workspaces = {} self._workspaces_types = {} self._model_controller = model_controller self._excluded_directories = [".svn"] self.workspace_persister = WorkspacePersister() def couchAvailable(self, isit): self._couchAvailable = isit def _notifyWorkspaceNoConnection(self): notifier.showPopup( "Couchdb Connection lost. Defaulting to memory. Fix network and try again in 5 minutes." ) def reconnect(self): if not self.reconnectCouchManager(): self._notifyWorkspaceNoConnection() def getCouchManager(self): return self.couchdbmanager def setCouchManager(self, cm): self.couchdbmanager = cm @staticmethod def getAvailableWorkspaceTypes(): av = [ w.__name__ for w in Workspace.__subclasses__() if w.isAvailable() ] model.api.devlog("Available wortkspaces: %s" ", ".join(av)) return av def reconnectCouchManager(self): retval = True if not self.couchdbmanager.reconnect(): retval = False return retval WorkspacePersister.reExecutePendingActions() return retval def startAutoLoader(self): pass def stopAutoLoader(self): pass def startReportManager(self): self.report_manager.start() def stopReportManager(self): self.report_manager.stop() self.report_manager.join() def getActiveWorkspace(self): return self.active_workspace def saveWorkspaces(self): pass def addWorkspace(self, workspace): self._workspaces[workspace.name] = workspace def createVisualizations(self): stat = False url = "" if self.couchdbmanager.isAvailable(): stat = True url = self.couchdbmanager.pushReports() else: self._notifyNoVisualizationAvailable() return stat, url def _notifyNoVisualizationAvailable(self): notifier.showPopup( "No visualizations available, please install and configure CouchDB" ) def createWorkspace(self, name, description="", workspaceClass=None, shared=CONF.getAutoShareWorkspace(), customer="", sdate=None, fdate=None): model.api.devlog("Creating Workspace") if self.getWorkspaceType(name) in globals(): workspaceClass = globals()[self.getWorkspaceType(name)] elif not workspaceClass: # Defaulting =( model.api.devlog("Defaulting to WorkspaceOnFS") workspaceClass = WorkspaceOnFS w = workspaceClass(name, self, shared) # Register the created workspace type: self._workspaces_types[name] = workspaceClass.__name__ w.description = description w.customer = customer if sdate is not None: w.start_date = sdate if fdate is not None: w.finish_date = fdate self.addWorkspace(w) return w def removeWorkspace(self, name): work = self.getWorkspace(name) if not work: return dm = work.getDataManager() dm.removeWorkspace(name) datapath = CONF.getDataPath() todelete = [i for i in os.listdir(datapath) if name in i] for i in todelete: os.remove(os.path.join(datapath, i)) shutil.rmtree(self.getWorkspace(name).getReportPath()) del self._workspaces[name] if self.getWorkspace(name) == self.getActiveWorkspace( ) and self.getWorkspacesCount() > 0: self.setActiveWorkspace( self.getWorkspace(self._workspaces.keys()[0])) def getWorkspace(self, name): ''' May return None ''' if not self._workspaces.get(name): # Retrieve the workspace self.loadWorkspace(name) return self._workspaces.get(name) def loadWorkspace(self, name): workspaceClass = None workspace = None if name in self.fsmanager.getWorkspacesNames(): workspace = self.createWorkspace(name, workspaceClass=WorkspaceOnFS) elif name in self.couchdbmanager.getWorkspacesNames(): workspace = self.createWorkspace(name, workspaceClass=WorkspaceOnCouch) return workspace def openWorkspace(self, name): w = self.getWorkspace(name) self.setActiveWorkspace(w) return w def getWorkspaces(self): """ Simply returns a list of all existing workspaces (including the active one) """ self.loadWorkspaces() return [w for w in self._workspaces.itervalues()] def getWorkspacesCount(self): return len(self._workspaces) def getWorkspacesNames(self): return self._workspaces.keys() def loadWorkspaces(self): self._workspaces_types = {} fsworkspaces = { name: None for name in self.fsmanager.getWorkspacesNames() } self._workspaces.update(fsworkspaces) couchworkspaces = { name: None for name in self.couchdbmanager.getWorkspacesNames() if not name == 'reports' } self._workspaces.update(couchworkspaces) self._workspaces_types.update( {name: WorkspaceOnFS.__name__ for name in fsworkspaces}) self._workspaces_types.update( {name: WorkspaceOnCouch.__name__ for name in couchworkspaces}) def getWorkspaceType(self, name): return self._workspaces_types.get(name, 'undefined') def setActiveWorkspace(self, workspace): try: self.stopAutoLoader() except: pass if self.active_workspace is not None: self.active_workspace.setModelController(None) CONF.setLastWorkspace(workspace.name) CONF.saveConfig() self.active_workspace = workspace self.active_workspace.setModelController(self._model_controller) self._model_controller.setWorkspace(self.active_workspace) self.workspace_persister.setPersister(self.active_workspace, self.active_workspace._dmanager) self.report_manager.path = workspace.report_path if isinstance(self.active_workspace, WorkspaceOnCouch): self.startAutoLoader() def isActive(self, name): return self.active_workspace.name == name def syncWorkspaces(self): """ Synchronize persistence directory using the DataManager. We first make sure that all shared workspaces were added to the repo """ pass
def __init__(self, name, manager, shared=CONF.getAutoShareWorkspace()): Workspace.__init__(self, name, manager, shared) self._dmanager = FSManager(self._path)
class WorkspaceOnFS(Workspace): def __init__(self, name, manager, shared=CONF.getAutoShareWorkspace()): Workspace.__init__(self, name, manager, shared) self._dmanager = FSManager(self._path) @staticmethod def isAvailable(): return True def saveObj(self, obj): host = obj.getHost() try: model.api.devlog("Saving host to FileSystem") model.api.devlog("Host, %s" % host.getID()) host_as_dict = host._toDict(full=True) filepath = os.path.join(self._path, host.getID() + ".json") with open(filepath, "w") as outfile: json.dump(host_as_dict, outfile, indent=2) except Exception: model.api.devlog( "Failed while persisting workspace to filesystem, enough perms and space?" ) def delObj(self, obj): if obj.class_signature == "Host": self._dmanager.removeObject(obj.getID()) return host = obj.getHost() self.saveObj(host) def syncFiles(self): self.load() def load(self): files = os.listdir(self._path) files = filter( lambda f: f.endswith(".json") and f not in self. _persistence_excluded_filenames, files) modelobjectcontainer = self.getContainee() for filename in files: newHost = self.__loadHostFromFile(filename) modelobjectcontainer[newHost.getID()] = newHost notifier.workspaceLoad(self.getAllHosts()) def __loadHostFromFile(self, filename): if os.path.basename(filename) in self._persistence_excluded_filenames: model.api.devlog("skipping file %s" % filename) return else: model.api.devlog("loading file %s" % filename) infilepath = os.path.join(self._path, filename) host_dict = {} try: with open(infilepath) as infile: host_dict = json.load(infile) except Exception, e: model.api.log( "An error ocurred while parsing file %s\n%s" % (filename, str(e)), "ERROR") return mockito.mock() try: newHost = Host(name=None, dic=host_dict) return newHost except Exception, e: model.api.log("Could not load host from file %s" % filename, "ERROR") model.api.devlog(str(e)) return None
class WorkspaceOnFS(Workspace): def __init__(self, name, manager, shared=CONF.getAutoShareWorkspace()): Workspace.__init__(self, name, manager, shared) self._dmanager = FSManager(self._path) @staticmethod def isAvailable(): return True def saveObj(self, obj): host = obj.getHost() try: model.api.devlog("Saving host to FileSystem") model.api.devlog("Host, %s" % host.getID()) host_as_dict = host._toDict(full=True) filepath = os.path.join(self._path, host.getID() + ".json") with open(filepath, "w") as outfile: json.dump(host_as_dict, outfile, indent = 2) except Exception: model.api.devlog("Failed while persisting workspace to filesystem, enough perms and space?") def delObj(self, obj): if obj.class_signature == "Host": self._dmanager.removeObject(obj.getID()) return host = obj.getHost() self.saveObj(host) def syncFiles(self): self.load() def load(self): files = os.listdir(self._path) files = filter(lambda f: f.endswith(".json") and f not in self._persistence_excluded_filenames, files) modelobjectcontainer = self.getContainee() for filename in files: newHost = self.__loadHostFromFile(filename) modelobjectcontainer[newHost.getID()] = newHost def __loadHostFromFile(self, filename): if os.path.basename(filename) in self._persistence_excluded_filenames: model.api.devlog("skipping file %s" % filename) return else: model.api.devlog("loading file %s" % filename) infilepath = os.path.join(self._path, filename) host_dict = {} try: with open(infilepath) as infile: host_dict = json.load(infile) except Exception, e: model.api.log("An error ocurred while parsing file %s\n%s" % (filename, str(e)), "ERROR") return mockito.mock() try: newHost = Host(name=None, dic=host_dict) return newHost except Exception, e: model.api.log("Could not load host from file %s" % filename, "ERROR") model.api.devlog(str(e)) return None
class WorkspaceManager(object): """ This handles all workspaces. It checks for existing workspaces inside the persistence directory. It is in charge of starting the WorkspacesAutoSaver to persist each workspace. This class stores information in $HOME/.faraday/config/workspacemanager.xml file to keep track of created workspaces to be able to load them """ def __init__(self, model_controller, plugin_controller): self.active_workspace = None self._couchAvailable = False self.report_manager = ReportManager(10, plugin_controller) self.couchdbmanager = PersistenceManagerFactory().getInstance() self.fsmanager = FSManager() self._workspaces = {} self._workspaces_types = {} self._model_controller = model_controller self._excluded_directories = [".svn"] self.workspace_persister = WorkspacePersister() def couchAvailable(self, isit): self._couchAvailable = isit def _notifyWorkspaceNoConnection(self): notifier.showPopup("Couchdb Connection lost. Defaulting to memory. Fix network and try again in 5 minutes.") def reconnect(self): if not self.reconnectCouchManager(): self._notifyWorkspaceNoConnection() def getCouchManager(self): return self.couchdbmanager def setCouchManager(self, cm): self.couchdbmanager = cm @staticmethod def getAvailableWorkspaceTypes(): av = [w.__name__ for w in Workspace.__subclasses__() if w.isAvailable() ] model.api.devlog("Available wortkspaces: %s" ", ".join(av)) return av def reconnectCouchManager(self): retval = True if not self.couchdbmanager.reconnect(): retval = False return retval WorkspacePersister.reExecutePendingActions() return retval def startAutoLoader(self): pass def stopAutoLoader(self): pass def startReportManager(self): self.report_manager.start() def stopReportManager(self): self.report_manager.stop() self.report_manager.join() def getActiveWorkspace(self): return self.active_workspace def saveWorkspaces(self): pass def addWorkspace(self, workspace): self._workspaces[workspace.name] = workspace def createVisualizations(self): stat = False url = "" if self.couchdbmanager.isAvailable(): stat = True url = self.couchdbmanager.pushReports() else: self._notifyNoVisualizationAvailable() return stat, url def _notifyNoVisualizationAvailable(self): notifier.showPopup("No visualizations available, please install and configure CouchDB") def createWorkspace(self, name, description="", workspaceClass = None, shared=CONF.getAutoShareWorkspace(), customer="", sdate=None, fdate=None): model.api.devlog("Creating Workspace") if self.getWorkspaceType(name) in globals(): workspaceClass = globals()[self.getWorkspaceType(name)] elif not workspaceClass: # Defaulting =( model.api.devlog("Defaulting to WorkspaceOnFS") workspaceClass = WorkspaceOnFS w = workspaceClass(name, self, shared) # Register the created workspace type: self._workspaces_types[name] = workspaceClass.__name__ w.description = description w.customer = customer if sdate is not None: w.start_date = sdate if fdate is not None: w.finish_date = fdate self.addWorkspace(w) return w def removeWorkspace(self, name): work = self.getWorkspace(name) if not work: return dm = work.getDataManager() dm.removeWorkspace(name) datapath = CONF.getDataPath() todelete = [i for i in os.listdir(datapath) if name in i ] for i in todelete: os.remove(os.path.join(datapath, i)) shutil.rmtree(self.getWorkspace(name).getReportPath()) del self._workspaces[name] if self.getWorkspace(name) == self.getActiveWorkspace() and self.getWorkspacesCount() > 0: self.setActiveWorkspace(self.getWorkspace(self._workspaces.keys()[0])) def getWorkspace(self, name): ''' May return None ''' if not self._workspaces.get(name): # Retrieve the workspace self.loadWorkspace(name) return self._workspaces.get(name) def loadWorkspace(self, name): workspaceClass = None workspace = None if name in self.fsmanager.getWorkspacesNames(): workspace = self.createWorkspace(name, workspaceClass = WorkspaceOnFS) elif name in self.couchdbmanager.getWorkspacesNames(): workspace = self.createWorkspace(name, workspaceClass = WorkspaceOnCouch) return workspace def openWorkspace(self, name): w = self.getWorkspace(name) self.setActiveWorkspace(w) return w def getWorkspaces(self): """ Simply returns a list of all existing workspaces (including the active one) """ self.loadWorkspaces() return [w for w in self._workspaces.itervalues()] def getWorkspacesCount(self): return len(self._workspaces) def getWorkspacesNames(self): return self._workspaces.keys() def loadWorkspaces(self): self._workspaces_types = {} fsworkspaces = {name: None for name in self.fsmanager.getWorkspacesNames()} self._workspaces.update(fsworkspaces) couchworkspaces = {name: None for name in self.couchdbmanager .getWorkspacesNames() if not name == 'reports'} self._workspaces.update(couchworkspaces) self._workspaces_types.update({name: WorkspaceOnFS.__name__ for name in fsworkspaces}) self._workspaces_types.update({name: WorkspaceOnCouch.__name__ for name in couchworkspaces}) def getWorkspaceType(self, name): return self._workspaces_types.get(name, 'undefined') def setActiveWorkspace(self, workspace): try: self.stopAutoLoader() except : pass if self.active_workspace is not None: self.active_workspace.setModelController(None) CONF.setLastWorkspace(workspace.name) CONF.saveConfig() self.active_workspace = workspace self.active_workspace.setModelController(self._model_controller) self._model_controller.setWorkspace(self.active_workspace) self.workspace_persister.setPersister(self.active_workspace, self.active_workspace._dmanager) self.report_manager.path = workspace.report_path if isinstance(self.active_workspace, WorkspaceOnCouch): self.startAutoLoader() def isActive(self, name): return self.active_workspace.name == name def syncWorkspaces(self): """ Synchronize persistence directory using the DataManager. We first make sure that all shared workspaces were added to the repo """ pass