def __init__(self): """ This is the constructor for the class. Here we instantiate a logger and override the super class. :return: """ # Set the logger object self._logger = logging.getLogger( "PluginManager" ) # Override the super class PluginManager.__init__(self) self.setPluginInfoExtension(PLUGIN_EXTENSION) # Set the internal configurations manager - Singleton self._manager = Reader() return
class Manager(PluginManager): """ This class defines the interface to the plugins that are loaded dynamically based on the configuration file given to this engine. From the config file, we can determine which plugins are needed and which ones to download from the centralized plugin server. """ # The logger engine _logger = None # The configurations manager # *** Note: this reader is the global reader for the application _manager = None # The plugins configuration _configs = None # The plugin objects _plugins = None # The workspace _workspace = CONFIG_WORKSPACE # The running plugins _running = {} def __init__(self): """ This is the constructor for the class. Here we instantiate a logger and override the super class. :return: """ # Set the logger object self._logger = logging.getLogger( "PluginManager" ) # Override the super class PluginManager.__init__(self) self.setPluginInfoExtension(PLUGIN_EXTENSION) # Set the internal configurations manager - Singleton self._manager = Reader() return def setup(self): """ This is the method that will read the plugins configuration and load the ones that are addressed. :return: """ # Load configs self._load_plugins_configs() # Load plugins self._load_plugins() return def run(self, plugin=None): """ Default run method. :param plugin: The runall method is called if None :return: """ if plugin is None: self.run_all() else: self.run_plugin(plugin) return def run_plugin(self, name): """ This only runs one plugin that is passed to the method. :param name: The plugin name :return: """ # Sanity check for plugin in self._plugins: if name == plugin.name: # We setup and run the plugin self._logger.info("[+] Running plugin: %s" %name) self._run_plugin(plugin) return # Couldn't find the plugin with that name self._logger.info("[-] Plugin: %s not found." %name) return def run_all(self): """ This runs all the plugins in the enabled plugins. :return: """ # Run all the plugin for plugin in self._plugins: self.run_plugin(plugin.name) return def kill_plugin(self, name): """ This only kills one plugin that is passed to the method. :param name: The plugin name :return: """ # Sanity check for plugin in self._plugins: if name == plugin.name: # We setup and run the plugin self._logger.info("[-] Killing plugin: %s" %name) self._kill_plugin(plugin) return # Couldn't find the plugin with that name self._logger.info("[-] Plugin: %s not found." %name) return def kill_all(self): """ This kills all the plugins in the enabled plugins. :return: """ # Run all the plugin for plugin in self._plugins: self.kill_plugin(plugin.name) return def _run_plugin(self, plugin): """ This is the internal method that calls the runnable plugin and sets it up, and starts it. :param plugin: The plugin object that is needed to run :return: """ # Activate the plugin plugin.plugin_object.activate() self._logger.info( "[+] Activating plugin: %s" %plugin.name ) # Setup the plugin self._logger.info( "[+] Setting up plugin: %s" %plugin.name ) plugin.plugin_object.setup( self._find_configs( plugin.name ) ) # Run the plugin self._logger.info( "[+] Running plugin: %s" %plugin.name ) # Store the handle for the future self._running[plugin.name] = plugin.plugin_object.run() return def _kill_plugin(self, plugin): """ This is the internal method that calls the runnable plugin and kills it as well as run the finally context. :param plugin: The plugin object that is needed to be killed :return: """ # Deactivate the plugin plugin.plugin_object.deactivate() self._logger.info( "[-] Deactivating plugin: %s" %plugin.name ) # Kill the process self._running[plugin.name].kill() self._running[plugin.name].join() self._logger.info( "[-] Killed plugin: %s" %plugin.name ) del self._running[plugin.name] return def _load_plugins_configs(self, workspace=None): """ This is the configs loading method for the plugin manager. :param workspace: The workspace where the plugins would be located. Typically [./NetworkDeviceMonitor/Configs/App] :return: """ # Here we do a sanity check or address the default location if workspace is not None: # Set the passed directory self._workspace = workspace # We load the configs self._logger.info( "[+] Loading the plugin workspace [%s]" %self._workspace ) self._manager.load( self._workspace ) # We check to see which ones are plugin configs. self._logger.info( "[+] Filtering plugins configurations." ) self._configs = self._filter_plugin_configs() return def _load_plugins(self): """ This is the method that will load the plugins based on the the Yapsy framework. :return: """ self.setPluginPlaces( self._get_locations() ) self.collectPlugins() def adjust(str1, value): return str1.ljust(20, " ") + value + '\n' """ Adjusts a string to the logging format """ # Set the appropriate plugins self._plugins = self._filter_plugins() # List the plugins available for plugin in self._plugins: # Print relevant information about the plugin. self._logger.info( "\n===========================\n" + adjust( "Name: ", plugin.name ) + adjust( "Author: ", plugin.author ) + adjust( "Version: ", str( plugin.version ) ) + adjust( "Copyright: ", plugin.copyright ) + adjust( "Website: ", plugin.website ) + adjust( "Category: ", plugin.category ) + adjust( "Path: ", plugin.path ) + adjust( "Description: ", plugin.description ) ) return def _filter_plugin_configs(self): """ This method returns only the plugin configurations. :return: """ # Container plugins = [] # Get all plugins files = self._manager.get_configs() # Filter for file in files.values(): for config in file: for plugin in config.values(): if plugin['type'] == PLUGIN_TYPE: # Check where the location is if plugin['location'] == PLUGIN_DEFAULT: plugin['location'] = PLUGIN_DEFAULT_LOC self._logger.info( "[+] Found configurations for plugin: %s " %plugin['name'] + "Location: %s" %plugin['location'] ) plugins.append( plugin ) return plugins def _filter_plugins(self): """ Filters the plugins that are needed and deletes the other ones. :return: """ # Container filered_plugins = [] # We need to only get the plugins needed plugins = self.getAllPlugins() for plugin in plugins: for config in self._configs: if (plugin.name in config['name']) \ and (plugin not in filered_plugins): filered_plugins.append(plugin) elif plugin.name not in config['name']: del plugin return filered_plugins def _find_configs(self, name): """ Finds and returns the configs for a specific plugin. :param name: The plugin name :return: """ for plugin in self._configs: if name == plugin['name']: return plugin self._logger.info( "[-] Could not find configs for plugin: %s" %name ) return def _get_locations(self): """ This method returns the locations of the plugins. :return: """ # Container locations = [] # We look at the locations of the plugins and set them in the # plugin engine for plugin in self._configs: if plugin['location'] not in locations: locations.append( plugin['location'] ) return locations