Exemplo n.º 1
0
 def __init__(self, Config=None):
     if isinstance(Config, Configuration):
         self._conf = Config
     else:
         self._conf = Configuration()
     self._notifications = Notifications(self.getConfig())
     self.ProvisionLoggers()
Exemplo n.º 2
0
 def test_set(self):
     conf = Configuration()
     self.assertFalse(conf.get('Logging', 'trace'))
     conf.set('trace', True, 'Logging')
     self.assertTrue(conf.get('Logging', 'trace'))
     conf.set('trace', False, 'Logging')
     self.assertFalse(conf.get('Logging', 'trace'))
Exemplo n.º 3
0
 def _log_line_count(self):
     conf = Configuration()
     if os.path.isfile(conf.get('Logging', 'file')):
         fil = open(conf.get('Logging', 'file'), 'r')
         filContent = fil.read().splitlines()
         fil.close()
         del fil
         ctn = 0
         for line in filContent:
             ctn += 1
         del filContent
         del conf
         return ctn
     else:
         del conf
         return 0
Exemplo n.º 4
0
    def mock_data(self, configuration):
        """Data from this source is mocked utilizing the GREASE Filesystem

        Mock data for this source can be place in `<GREASE_DIR>/etc/*.mock.es.json`. This source will pick up all these
        files and load them into the returning object. The data in these files should reflect what you expect to return
        from ElasticSearch

        Args:
            configuration (dict): Configuration Data for source

        Note:
            Argument **configuration** is not honored here

        Returns:
            list[dict]: Mocked Data

        """
        intermediate = list()
        matches = []
        conf = Configuration()
        for root, dirnames, filenames in os.walk(conf.greaseDir + 'etc'):
            for filename in fnmatch.filter(filenames, '*.mock.es.json'):
                matches.append(os.path.join(root, filename))
        for doc in matches:
            with open(doc) as current_file:
                content = current_file.read().replace('\r\n', '')
            try:
                intermediate.append(json.loads(content))
            except ValueError:
                continue
        return intermediate
Exemplo n.º 5
0
 def test_defaults(self):
     conf = Configuration()
     self.assertEqual(
         conf.get('Connectivity', 'MongoDB').get('host'), 'localhost')
     self.assertEqual(
         conf.get('Connectivity', 'MongoDB').get('port'), 27017)
     self.assertEqual(conf.get('Logging', 'mode'), 'filesystem')
     self.assertEqual(conf.get('Logging', 'verbose'), False)
     self.assertEqual(conf.get('Logging', 'file'),
                      conf.greaseDir + 'log' + conf.fs_sep + 'grease.log')
     self.assertEqual(conf.get('Configuration', 'dir'),
                      conf.greaseDir + 'etc' + conf.fs_sep)
     self.assertEqual(conf.get('Sourcing', 'dir'),
                      conf.greaseDir + 'etc' + conf.fs_sep)
Exemplo n.º 6
0
 def test_prototype_execution(self):
     ioc = GreaseContainer()
     cmd = DaemonProcess(ioc)
     # add search path
     fil = open(ioc.getConfig().greaseConfigFile, 'r')
     data = json.loads(fil.read())
     fil.close()
     fil = open(ioc.getConfig().greaseConfigFile, 'w')
     data['Import']['searchPath'].append('tgt_grease.router.Commands.tests')
     fil.write(json.dumps(data, sort_keys=True, indent=4))
     fil.close()
     Configuration.ReloadConfig()
     # Update Node to run it
     ioc.getCollection('JobServer')\
         .update_one(
         {'_id': ObjectId(ioc.getConfig().NodeIdentity)},
         {
             '$set': {
                 'prototypes': ['TestProtoType']
             }
         }
     )
     # Sleeps are because mongo in Travis is slow sometimes to persist data
     time.sleep(1.5)
     self.assertTrue(cmd.server())
     self.assertTrue(cmd.drain_jobs(ioc.getCollection('JobQueue')))
     # ensure jobs drain out
     time.sleep(1.5)
     self.assertEqual(
         ioc.getCollection('TestProtoType').find({
             'runs': {
                 '$exists': True
             }
         }).count(), 10)
     # clean up
     fil = open(ioc.getConfig().greaseConfigFile, 'r')
     data = json.loads(fil.read())
     fil.close()
     # remove collection
     ioc.getCollection('TestProtoType').drop()
     # pop search path
     trash = data['Import']['searchPath'].pop()
     # close out
     fil = open(ioc.getConfig().greaseConfigFile, 'w')
     fil.write(json.dumps(data, sort_keys=True, indent=4))
     fil.close()
     ioc.getCollection('JobServer') \
         .update_one(
         {'_id': ObjectId(ioc.getConfig().NodeIdentity)},
         {
             '$set': {
                 'prototypes': []
             }
         }
     )
Exemplo n.º 7
0
 def test_sql_parser_mock(self):
     source = sql_source()
     conf = Configuration()
     mock = {'id': 1, 'name_fs': 'sally', 'name_ls': 'sue'}
     fil = open(conf.greaseDir + 'etc' + conf.fs_sep + 'test.mock.sql.json',
                'w')
     fil.write(json.dumps(mock))
     fil.close()
     mockData = source.mock_data({})
     self.assertEqual(len(mockData), 1)
     self.assertEqual(mock.get('id'), 1)
     self.assertEqual(mock.get('name_fs'), mockData[0].get('name_fs'))
     self.assertEqual(mock.get('name_ls'), mockData[0].get('name_ls'))
     os.remove(conf.greaseDir + 'etc' + conf.fs_sep + 'test.mock.sql.json')
Exemplo n.º 8
0
 def test_url_parser_mock(self):
     source = url_source()
     conf = Configuration()
     mock = {
         'url': 'https://google.com',
         'status_code': 200,
         'headers': str({'test': 'ver', 'test1': 'val'}),
         'body': 'welcome to google'
     }
     fil = open(conf.greaseDir + 'etc' + conf.fs_sep + 'test.mock.url.json', 'w')
     fil.write(json.dumps(mock))
     fil.close()
     mockData = source.mock_data({})
     self.assertEqual(len(mockData), 1)
     self.assertEqual(mock.get('url'), mockData[0].get('url'))
     self.assertEqual(mock.get('status_code'), mockData[0].get('status_code'))
     self.assertEqual(mock.get('headers'), mockData[0].get('headers'))
     self.assertEqual(mock.get('body'), mockData[0].get('body'))
     os.remove(conf.greaseDir + 'etc' + conf.fs_sep + 'test.mock.url.json')
Exemplo n.º 9
0
    def mock_data(self, configuration):
        """Data from this source is mocked utilizing the GREASE Filesystem

        Mock data for this source can be place in `<GREASE_DIR>/etc/*.mock.url.json`. This source will pick up all these
        files and load them into the returning object. They will need to follow this schema::

            {
                'url': String, # <-- URL that would have been loaded
                'status_code': Int, # <-- HTTP Status code
                'headers': String, # <-- HTTP headers as a string
                'body': String # <-- HTTP response body
            }

        Args:
            configuration (dict): Configuration Data for source

        Note:
            Argument **configuration** is not honored here

        Returns:
            list[dict]: Mocked Data

        """
        intermediate = list()
        matches = []
        conf = Configuration()
        for root, dirnames, filenames in os.walk(conf.greaseDir + 'etc'):
            for filename in fnmatch.filter(filenames, '*.mock.url.json'):
                matches.append(os.path.join(root, filename))
        for doc in matches:
            with open(doc) as current_file:
                content = current_file.read().replace('\r\n', '')
            try:
                intermediate.append(json.loads(content))
            except ValueError:
                continue
        return intermediate
Exemplo n.º 10
0
 def __init__(self, Config=None):
     if Config and isinstance(Config, Configuration):
         self._conf = Config
     else:
         self._conf = Configuration()
Exemplo n.º 11
0
 def test_get_section(self):
     conf = Configuration()
     # test for section that should have stuff
     self.assertTrue(conf.get('Notifications'))
     # Section that is empty
     self.assertFalse(conf.get('Additional'))
Exemplo n.º 12
0
 def __init__(self, Config=None):
     if Config and isinstance(Config, Configuration):
         self._config = Config
     else:
         self._config = Configuration()
     self._client = self._generate_client()
Exemplo n.º 13
0
 def test_no_key(self):
     conf = Configuration()
     self.assertDictEqual({'MongoDB': {
         'host': 'localhost',
         'port': 27017
     }}, conf.get('Connectivity'))
Exemplo n.º 14
0
 def test_default(self):
     conf = Configuration()
     self.assertTrue(conf.get('FakeSection', default=True))
     self.assertTrue(conf.get('Connectivity', 'MongoDB'))
Exemplo n.º 15
0
class Mongo(object):
    """MongoDB Connection Class

    Attributes:
        _client (pymongo.MongoClient): The actual PyMongo Connection
        _config (Configuration): Configuration Object

    """

    _client = None
    _config = None

    def __init__(self, Config=None):
        if Config and isinstance(Config, Configuration):
            self._config = Config
        else:
            self._config = Configuration()
        self._client = self._generate_client()

    def Client(self):
        """get the connection client

        Returns:
            pymongo.MongoClient: Returns the mongoDB connection client

        """
        return self._client

    def Close(self):
        """Close PyMongo Connection

        Returns:
            None: Void Method to close connection

        """
        self._client.close()

    def _generate_client(self):
        """Creates a PyMongo Client

        Returns:
            pymongo.MongoClient: Mongo Connection

        """
        mongoConf = self._config.get('Connectivity', 'MongoDB')  # type: dict
        if mongoConf.get('username') and mongoConf.get('password'):
            return pymongo.MongoClient(
                "mongodb://{0}:{1}@{2}:{3}/{4}".format(
                    mongoConf.get('username', ''),
                    mongoConf.get('password', ''),
                    mongoConf.get('host', 'localhost'),
                    mongoConf.get('port', 27017),
                    mongoConf.get('db', 'grease')
                ),
                w=1
            )
        else:
            return pymongo.MongoClient(
                host=mongoConf.get('host', 'localhost'),
                port=mongoConf.get('port', 27017),
                w=1
            )
Exemplo n.º 16
0
 def test_filesystem(self):
     conf = Configuration()
     for elem in conf.FileSystem:
         self.assertTrue(os.path.isdir(conf.greaseDir + conf.fs_sep + elem))
Exemplo n.º 17
0
class Logging(object):
    """Application Logging for GREASE

    This is the primary configuration source for GREASE logging. All log information will be passed here to
    enable centralized log aggregation

    Attributes:
        _conf (Configuration): This is an instance of the Config to enable configuring loggers
        _logger (logging.Logger): This is the actual logger for GREASE
        _formatter (logging.Formatter): This is the log formatter
        _notifications (Notifications): Notifications instance
        foreground (bool): If set will override config and print all log messages

    """

    _conf = None
    _logger = None
    _formatter = None
    _notifications = None
    foreground = False

    def __init__(self, Config=None):
        if isinstance(Config, Configuration):
            self._conf = Config
        else:
            self._conf = Configuration()
        self._notifications = Notifications(self.getConfig())
        self.ProvisionLoggers()

    def getConfig(self):
        """Getter for Configuration

        Returns:
            Configuration: The loaded configuration object

        """
        return self._conf

    def getNotification(self):
        """Get Notification Class

        Returns:
            Notifications: The current Notifications instance

        """
        return self._notifications

    def TriageMessage(self, message, additional=None, verbose=False, trace=False, notify=False, level=logging.DEBUG):
        """Central message handler

        Args:
            message (str): Message to Log
            additional (object): Additional information to log
            verbose (bool): To be printed if verbose is enabled
            trace (bool): To be printed if trace is enabled
            notify (bool): If true will pass through notification system
            level (int): Log Level

        Returns:
            bool: Log Success

        """
        # first prevent verbose processing
        if verbose and not self._conf.get('Logging', 'verbose'):
            return True
        # prevent trace processing
        if trace and not self._conf.get('Logging', 'trace'):
            return True
        # create a pre-message
        if level is 0:
            preMsg = "TRACE"
        elif level is logging.DEBUG:
            preMsg = "DEBUG"
        elif level is logging.INFO:
            preMsg = "INFO"
        elif level is logging.WARNING:
            preMsg = "WARNING"
        elif level is logging.ERROR:
            preMsg = "ERROR"
        elif level is logging.CRITICAL:
            preMsg = "CRITICAL"
        else:
            preMsg = "UNSET"
        if verbose:
            preMsg = "VERBOSE::{0}".format(preMsg)
        if trace:
            preMsg = "TRACE::{0}".format(preMsg)
        if additional:
            message = "{0}::{1}::{2}::{3}".format(preMsg, self._conf.NodeIdentity, message, additional)
        else:
            message = "{0}::{1}::{2}".format(preMsg, self._conf.NodeIdentity, message)
        # Foreground mode print log messages
        if self._conf.get('Logging', 'foreground') or self.foreground:
            print("{0}::{1}".format(datetime.utcnow(), message))
        # actually log the message
        if level is 0:
            self._logger.log(logging.DEBUG, message)
        else:
            self._logger.log(level, message)
        # notify if needed
        if notify:
            return bool(self._notifications.SendMessage(message, level))
        return True

    def trace(self, message, additional=None, verbose=False, trace=True, notify=False):
        """Trace Messages

        Use this method for logging tracing (enhanced debug) statements

        Args:
            message (str): Message to log
            additional (object): Additional information to log. Note: object must be able to transform to string
            verbose (bool): Print only if verbose mode
            trace (bool): Print only if trace mode
            notify (bool): Run through the notification management system

        Returns:
            bool: Message is logged

        """
        return bool(self.TriageMessage(
            message,
            additional=additional,
            verbose=verbose,
            trace=trace,
            notify=notify,
            level=0
        ))

    def debug(self, message, additional=None, verbose=False, trace=False, notify=False):
        """Debug Messages

        Use this method for logging debug statements

        Args:
            message (str): Message to log
            additional (object): Additional information to log. Note: object must be able to transform to string
            verbose (bool): Print only if verbose mode
            trace (bool): Print only if trace mode
            notify (bool): Run through the notification management system

        Returns:
            bool: Message is logged

        """
        return bool(self.TriageMessage(
            message,
            additional=additional,
            verbose=verbose,
            trace=trace,
            notify=notify,
            level=logging.DEBUG
        ))

    def info(self, message, additional=None, verbose=False, trace=False, notify=False):
        """Info Messages

        Use this method for logging info statements

        Args:
            message (str): Message to log
            additional (object): Additional information to log. Note: object must be able to transform to string
            verbose (bool): Print only if verbose mode
            trace (bool): Print only if trace mode
            notify (bool): Run through the notification management system

        Returns:
            bool: Message is logged

        """
        return bool(self.TriageMessage(
            message,
            additional=additional,
            verbose=verbose,
            trace=trace,
            notify=notify,
            level=logging.INFO
        ))

    def warning(self, message, additional=None, verbose=False, trace=False, notify=False):
        """Warning Messages

        Use this method for logging warning statements

        Args:
            message (str): Message to log
            additional (object): Additional information to log. Note: object must be able to transform to string
            verbose (bool): Print only if verbose mode
            trace (bool): Print only if trace mode
            notify (bool): Run through the notification management system

        Returns:
            bool: Message is logged

        """
        return bool(self.TriageMessage(
            message,
            additional=additional,
            verbose=verbose,
            trace=trace,
            notify=notify,
            level=logging.WARNING
        ))

    def error(self, message, additional=None, verbose=False, trace=False, notify=True):
        """Error Messages

        Use this method for logging error statements

        Args:
            message (str): Message to log
            additional (object): Additional information to log. Note: object must be able to transform to string
            verbose (bool): Print only if verbose mode
            trace (bool): Print only if trace mode
            notify (bool): Run through the notification management system

        Returns:
            bool: Message is logged

        """
        return bool(self.TriageMessage(
            message,
            additional=additional,
            verbose=verbose,
            trace=trace,
            notify=notify,
            level=logging.ERROR
        ))

    def critical(self, message, additional=None, verbose=False, trace=False, notify=True):
        """Critical Messages

        Use this method for logging critical statements

        Args:
            message (str): Message to log
            additional (object): Additional information to log. Note: object must be able to transform to string
            verbose (bool): Print only if verbose mode
            trace (bool): Print only if trace mode
            notify (bool): Run through the notification management system

        Returns:
            bool: Message is logged

        """
        return bool(self.TriageMessage(
            message,
            additional=additional,
            verbose=verbose,
            trace=trace,
            notify=notify,
            level=logging.CRITICAL
        ))

    def ProvisionLoggers(self):
        """Loads Log Handler & Config

        Returns:
            None: Simple loader, Nothing needed

        """
        if self._conf.get('Logging', 'ConfigurationFile'):
            if os.path.isfile(self._conf.get('Logging', 'ConfigurationFile')):
                config.fileConfig(self._conf.get('Logging', 'ConfigurationFile'))
                self._logger = logging.getLogger('GREASE')
            else:
                self.DefaultLogger()
        else:
            self.DefaultLogger()

    def DefaultLogger(self):
        """Default Logging Provisioning

        Returns:
            None: void method to provision class internals

        """
        global GREASE_LOG_HANDLER
        self._logger = logging.getLogger('GREASE')
        self._logger.setLevel(logging.DEBUG)
        self._formatter = logging.Formatter(
            "{"
            "\"timestamp\": \"%(asctime)s.%(msecs)03d\", "
            "\"thread\": \"%(threadName)s\", "
            "\"level\" : \"%(levelname)s\", "
            "\"message\" : \"%(message)s\"}",
            "%Y-%m-%d %H:%M:%S"
        )
        self._formatter.converter = time.gmtime
        if not GREASE_LOG_HANDLER:
            if os.path.isdir(self._conf.greaseDir):
                GREASE_LOG_HANDLER = logging.FileHandler(self._conf.get('Logging', 'file'))
                GREASE_LOG_HANDLER.setLevel(logging.DEBUG)
                GREASE_LOG_HANDLER.setFormatter(self._formatter)
                self._logger.addHandler(GREASE_LOG_HANDLER)
            else:
                GREASE_LOG_HANDLER = logging.StreamHandler()
                GREASE_LOG_HANDLER.setLevel(logging.DEBUG)
                GREASE_LOG_HANDLER.setFormatter(self._formatter)
                self._logger.addHandler(GREASE_LOG_HANDLER)
Exemplo n.º 18
0
 def test_logging_creation_with_conf(self):
     conf = Configuration()
     log = Logging(conf)
     self.assertTrue(isinstance(log, Logging))
Exemplo n.º 19
0
class GreaseRouter(object):
    """Main GREASE CLI Router

    This class handles routing CLI requests as well as starting the Daemon on Windows/POSIX systems

    Attributes:
        _config (Configuration): Main Configuration Object
        _logger (Logging): Main Logging Instance
        _importTool (ImportTool): Importer Tool Instance
        _exit_message (str): Exit Message

    """

    _config = Configuration(os.environ.get('GREASE_CONF', None))
    _logger = Logging(_config)
    _importTool = ImportTool(_logger)
    _exit_message = None

    def __init__(self):
        self._logger.trace("Router Startup", trace=True)

    def StartGREASE(self):
        """EntryPoint for CLI scripts for GREASE

        Returns:
            None: Void Method for GREASE

        """
        status = self.run()
        self.exit(status, self._exit_message)

    def run(self):
        """Route commands through GREASE

        Returns:
            int: Exit Code

        """
        # ensure at least a sub-command has been provided
        if len(sys.argv) > 1:
            cmd, context = self.get_arguments()
            if cmd:
                # Parse long args to command context
                if cmd.execute(context):
                    cmd.__del__()
                    del cmd
                    return 0
                else:
                    return 3
            else:
                self._exit_message = "Command not found"
                return 2
        else:
            self._logger.error("Sub-command not provided")
            self._exit_message = "Sub-command not provided to GREASE CLI"
            return 1

    def exit(self, code, message=None):
        """Exit program with exit code

        Args:
            code (int): Exit Code
            message (str): Exit message if any

        Returns:
            None: Will exit program

        """
        if message:
            self._logger.info("Message: [{0}]".format(message))
            if code != 0:
                print("ERROR: {0}".format(message))
            else:
                print(message)
        self._logger.debug("GREASE exit code: [{0}]".format(code),
                           verbose=True)
        sys.exit(code)

    def get_arguments(self):
        """Parse CLI long arguments into dictionaries

        This expects arguments separated by space `--opt val`, colon `--opt:val`, or equal `--opt=val` signs

        Returns:
            object, dict: key->value pairs of arguments

        """
        i = 1
        context = {}
        other = []
        cmd = None
        while i < len(sys.argv):
            arg = str(sys.argv[i])
            if arg.startswith("--"):
                # Found long opt
                if len(arg.split("=")) > 1:
                    # was equal separated
                    context[arg.split("=")[0].strip("--")] = arg.split("=")[1]
                elif len(arg.split(":")) > 1:
                    # was colon separated
                    context[arg.split(":")[0].strip("--")] = arg.split(":")[1]
                else:
                    if len(sys.argv) < i + 1:
                        # we have a flag rather than an arg
                        context[arg.strip("--")] = True
                        i += 1
                    elif len(sys.argv) - 1 == i or sys.argv[i + 1].startswith(
                            "--"):
                        # we have a flag rather than an arg
                        context[arg.strip("--")] = True
                    elif sys.argv[i + 1].startswith("--"):
                        # we have a flag rather than an arg
                        context[arg.strip("--")] = True
                    else:
                        # space separated
                        possible_imp = self._importTool.load(sys.argv[i + 1])
                        if not isinstance(possible_imp, Command):
                            context[arg.strip("--")] = sys.argv[i + 1]
                        else:
                            cmd = possible_imp
                        i += 1
            else:
                possible_imp = self._importTool.load(sys.argv[i])
                if isinstance(possible_imp, Command):
                    cmd = possible_imp
                else:
                    other.append(arg)
            i += 1
        context['grease_other_args'] = other
        return cmd, context
Exemplo n.º 20
0
 def test_config_is_false_before_startup(self):
     self.assertFalse(Configuration.get('MongoDB', 'host'))
Exemplo n.º 21
0
    def test_scan(self):
        # setup
        configList = [
            {
                "name": "test1",
                "job": "fakeJob",
                "exe_env": "windows",
                "source": "TestSource",
                "logic": {
                    "regex": [
                        {
                            "field": "character",
                            "pattern": ".*skywalker.*"
                        }
                    ]
                }
            }
        ]
        ioc = GreaseContainer()
        ioc.ensureRegistration()
        ioc.getConfig().set('trace', True, 'Logging')
        ioc.getConfig().set('verbose', True, 'Logging')
        fil = open(ioc.getConfig().greaseConfigFile, 'r')
        data = json.loads(fil.read())
        fil.close()
        fil = open(ioc.getConfig().greaseConfigFile, 'w')
        data['Import']['searchPath'].append('tgt_grease.enterprise.Model.tests')
        fil.write(json.dumps(data, sort_keys=True, indent=4))
        fil.close()
        Configuration.ReloadConfig()
        jServer = ioc.getCollection('JobServer')
        jID1 = jServer.insert_one({
                'jobs': 0,
                'os': platform.system().lower(),
                'roles': ["general"],
                'prototypes': ["detect"],
                'active': True,
                'activationTime': datetime.utcnow()
        }).inserted_id
        time.sleep(1)
        jID2 = jServer.insert_one({
                'jobs': 0,
                'os': platform.system().lower(),
                'roles': ["general"],
                'prototypes': ["detect"],
                'active': True,
                'activationTime': datetime.utcnow()
        }).inserted_id

        # Begin Test
        conf = PrototypeConfig(ioc)
        conf.load(reloadConf=True, ConfigurationList=configList)
        scanner = Scan(ioc)
        # Scan Environment
        self.assertTrue(scanner.Parse())
        # Begin ensuring environment is how we expect
        # we assert less or equal because sometimes uuid's are close :p
        self.assertLessEqual(ioc.getCollection('SourceData').find({
            'detectionServer': ObjectId(jID1)
        }).count(), 3)
        self.assertLessEqual(ioc.getCollection('SourceData').find({
            'detectionServer': ObjectId(jID2)
        }).count(), 3)
        self.assertLessEqual(ioc.getCollection('JobServer').find_one({
            '_id': ObjectId(jID1)
        })['jobs'], 3)
        self.assertLessEqual(ioc.getCollection('JobServer').find_one({
            '_id': ObjectId(jID2)
        })['jobs'], 3)

        # clean up
        fil = open(ioc.getConfig().greaseConfigFile, 'r')
        data = json.loads(fil.read())
        fil.close()
        # remove collection
        ioc.getCollection('TestProtoType').drop()
        # remove prototypes
        data['NodeInformation']['ProtoTypes'] = []
        # pop search path
        trash = data['Import']['searchPath'].pop()
        # close out
        fil = open(ioc.getConfig().greaseConfigFile, 'w')
        fil.write(json.dumps(data, sort_keys=True, indent=4))
        fil.close()
        jServer.delete_one({'_id': ObjectId(jID1)})
        jServer.delete_one({'_id': ObjectId(jID2)})
        ioc.getCollection('SourceData').drop()
        ioc.getCollection('Dedup_Sourcing').drop()
        ioc.getConfig().set('trace', False, 'Logging')
        ioc.getConfig().set('verbose', False, 'Logging')
        Configuration.ReloadConfig()
Exemplo n.º 22
0
 def test_initialization(self):
     conf = Configuration()
     self.assertTrue(conf.get('Connectivity', 'MongoDB'))
Exemplo n.º 23
0
class Notifications(object):
    """Notification Router for third party resources

    This is the class to handle all notifications to third party resources

    Attributes:
        _conf (Configuration): Configuration Object
        hipchat_url (str): This is the hipchat API url
        hipchat_token (str): set this to override the config for the auth token
        hipchat_room (str): set this to override the config for the room

    """

    _conf = None
    # HipChat Configuration
    hipchat_url = "https://api.hipchat.com/v2/room/"
    hipchat_token = None
    hipchat_room = None

    def __init__(self, Config=None):
        if Config and isinstance(Config, Configuration):
            self._conf = Config
        else:
            self._conf = Configuration()

    def SendMessage(self, message, level=DEBUG, channel=None):
        """Send Message to configured channels

        This method is the main point of contact with Notifications in GREASE. This will handle routing to all
        configured channels. Use `level` to define what level the message is. This can impact whether a message is
        sent as well as if the message sent will have special attributes (EX: red text). Use `channel` to route
        around sending to multiple channels if the message traditionally would go to multiple, instead going only
        to the selected one.

        Note:
            if you use the channel argument and the channel is not found you will receive False back

        Args:
            message (str): Message to send
            level (int): Level of message to be sent
            channel (str): Specific channel to notify

        Returns:
            bool: Success of sending

        """
        if channel \
                and 'enabled' in self._conf.get('Notifications', channel, {}) \
                and self._conf.get('Notifications', channel, {}).get('enabled'):
            return bool(self._route_notification(channel, message, level))
        else:
            # Capture object for notification channel statuses
            NotificationStatus = []
            NotificationChannels = self._conf.get('Notifications', default={})  # type: dict
            # Loop through those channels
            for Notifier, Config in NotificationChannels.items():
                # ensure channel is enabled
                if 'enabled' in Config and Config.get('enabled'):
                    # loop through the channels
                    NotificationStatus.append(bool(self._route_notification(Notifier, message, level)))
            # make the list unique
            NotificationStatus = list(set(NotificationStatus))
            if len(NotificationStatus) > 1:
                # we got at least one true and at least one false
                return False
            elif len(NotificationStatus) is 1:
                # return what the categorical state was
                return bool(NotificationStatus[0])
            else:
                # nothing was configured to run return true
                return True

    def _route_notification(self, channel, message, level):
        """Handle actual calling of notification channels

        Args:
            channel (str): Channel to notify
            message (str): Message to send
            level (int): Level to send at

        Returns:
            bool: Method success status

        """
        if channel == "HipChat":
            return self.send_hipchat_message(message, level)
        elif channel == "Slack":
            return self.send_slack_message(message)
        else:
            return False

    def send_hipchat_message(self, message, level, color=None):
        """Send a hipchat message

        Args:
            message (str): Message to send to hipchat
            level (int): message level
            color (str): color of message

        Returns:
            bool: API response status

        """
        if not color:
            if level is DEBUG:
                color = 'grey'
            elif level is INFO:
                color = 'purple'
            elif level is WARNING:
                color = 'yellow'
            elif level is ERROR:
                color = 'red'
            elif level is CRITICAL:
                color = 'red'
            else:
                color = 'grey'
        if self.hipchat_room and self.hipchat_token:
            url = "{0}{1}/notification?auth_token={2}".format(
                self.hipchat_url,
                self.hipchat_room,
                self.hipchat_token
            )
        else:
            url = "{0}{1}/notification?auth_token={2}".format(
                self.hipchat_url,
                self._conf.get('Notifications', 'HipChat').get('room'),
                self._conf.get('Notifications', 'HipChat').get('token')
            )
        try:
            response = requests.post(
                url=url,
                data={
                    'message': message,
                    'color': color
                },
                verify=False
                )
            if response.status_code == 204:
                return True
            else:
                return False
        except HTTPError:
            return False

    def send_slack_message(self, message):
        """Send a slack message to slack channel using webhook url in the configuration

        Args:
            message (str): Message to send to Slack

        Returns:
            bool: API response status

        """

        webhook_url = self._conf.get('Notifications', 'Slack').get('webhookURL')
        slack_data = {'text': message}

        try:
            response = requests.post(
                webhook_url, data=json.dumps(slack_data),
                headers={'Content-Type': 'application/json'}
            )
            return True
        except HTTPError:
            return False