示例#1
0
    def add_app(self, func_name, app_info):
        """Add a configuration for a new streamalert app integration function

        Args:
            app_info (dict): The necessary values needed to begin configuring
                a new app integration

        Returns:
            bool: False if errors occurred, True otherwise
        """
        exists, prompt_for_auth, overwrite = False, True, False
        app = StreamAlertApp.get_app(app_info['type'])

        cluster_name = app_info['cluster']
        app_name = app_info['app_name']

        # Check to see if there is an existing configuration for this app integration
        cluster_config = self.config['clusters'][cluster_name]

        if func_name in cluster_config['modules'].get('streamalert_apps', {}):
            prompt = (
                'An app with the name \'{}\' is already configured for cluster '
                '\'{}\'. Would you like to update the existing app\'s configuration'
                '?'.format(app_name, cluster_name))

            exists = True

            # Return if the user is not deliberately updating an existing config
            if not continue_prompt(message=prompt):
                return

            prompt = (
                'Would you also like to update the authentication information for '
                'app integration with name \'{}\'?'.format(app_name))

            # If this is true, we shouldn't prompt again to warn about overwriting
            prompt_for_auth = overwrite = continue_prompt(message=prompt)

        if prompt_for_auth and not save_app_auth_info(app, app_info, func_name,
                                                      overwrite):
            return False

        apps_config = cluster_config['modules'].get('streamalert_apps', {})
        if not exists:
            # Save a default app settings to the config for new apps
            new_app_config = {
                'app_name': app_info['app_name'],
                'concurrency_limit': 2,
                'log_level': 'info',
                'log_retention_days': 14,
                'memory': app_info['memory'],
                'metric_alarms': {
                    'errors': {
                        'enabled': True,
                        'evaluation_periods': 1,
                        'period_secs': 120
                    }
                },
                'schedule_expression': app_info['schedule_expression'],
                'timeout': app_info['timeout'],
                'type': app_info['type']
            }
            apps_config[func_name] = new_app_config
        else:

            # Allow for updating certain attributes for the app without overwriting
            # current parts of the configuration
            updated_app_config = {
                'memory': app_info['memory'],
                'schedule_expression': app_info['schedule_expression'],
                'timeout': app_info['timeout']
            }
            apps_config[func_name].update(updated_app_config)

        cluster_config['modules']['streamalert_apps'] = apps_config

        # Add this service to the sources for this app integration
        # The `streamalert_app` is purposely singular here
        app_sources = self.config['clusters'][cluster_name][
            'data_sources'].get('streamalert_app', {})
        app_sources[func_name] = [app.service()]
        self.config['clusters'][cluster_name]['data_sources'][
            'streamalert_app'] = app_sources

        LOGGER.info(
            'Successfully added \'%s\' app integration to \'conf/clusters/%s.json\' '
            'for service \'%s\'.', app_info['app_name'], app_info['cluster'],
            app_info['type'])

        self.write()

        return True
示例#2
0
    def handler(cls, options, config):
        """Perform app related functions

        Args:
            options (argparse.Namespace): Parsed arguments with info to configure a new app
                or update an existing one
            config (CLIConfig): Loaded StreamAlert config

        Returns:
            bool: False if errors occurred, True otherwise
        """
        if not options:
            return False

        # List all of the available app integrations, broken down by cluster
        if options.subcommand == 'list':
            all_info = {
                cluster: cluster_config['modules'].get('streamalert_apps')
                for cluster, cluster_config in config['clusters'].items()
            }

            for cluster, info in all_info.items():
                print('\nCluster: {}\n'.format(cluster))
                if not info:
                    print('\tNo Apps configured\n')
                    continue

                for name, details in info.items():
                    print('\tName: {}'.format(name))
                    print('\n'.join([
                        '\t\t{key}:{padding_char:<{padding_count}}{value}'.
                        format(key=key_name,
                               padding_char=' ',
                               padding_count=30 - (len(key_name)),
                               value=value)
                        for key_name, value in details.items()
                    ] + ['\n']))
            return True

        # Convert the options to a dict
        app_info = vars(options)

        # Add the region and prefix for this StreamAlert instance to the app info
        app_info['region'] = str(config['global']['account']['region'])
        app_info['prefix'] = str(config['global']['account']['prefix'])

        # Create a new app integration function
        if options.subcommand == 'new':
            function_name = '_'.join([
                app_info['prefix'], app_info['cluster'], app_info['type'],
                app_info['app_name'], 'app'
            ])

            return config.add_app(function_name, app_info)

        # Update the auth information for an existing app integration function
        if options.subcommand == 'update-auth':
            cluster_config = config['clusters'][app_info['cluster']]
            apps = cluster_config['modules'].get('streamalert_apps', {})
            if not apps:
                LOGGER.error('No apps configured for cluster \'%s\'',
                             app_info['cluster'])
                return False

            # Find the appropriate function config for this app
            func_name = None
            for function_name, app_config in apps.items():
                if app_config.get('app_name') == app_info['app_name']:
                    func_name = function_name
                    break

            if not func_name:
                LOGGER.error(
                    'App with name \'%s\' does not exist for cluster \'%s\'',
                    app_info['app_name'], app_info['cluster'])
                return False

            # Get the type for this app integration from the current
            # config so we can update it properly
            app_info['type'] = cluster_config['modules']['streamalert_apps'][
                func_name]['type']

            app = StreamAlertApp.get_app(app_info['type'])

            if not save_app_auth_info(app, app_info, func_name, True):
                return False

            return True