示例#1
0
    def delete_templates(self):
        """
        Deletes cross-account role and configuration templates
        :return: 
        """
        s3_client = get_client_with_retries("s3", ["delete_object"],
                                            context=self.context)
        s3_key = ""
        try:
            for action_name in actions.all_actions():
                action_properties = actions.get_action_properties(action_name)
                if not action_properties.get(actions.ACTION_INTERNAL, False):
                    self._logger.info(ERR_DELETING_ACTION_TEMPLATE,
                                      action_name)
                    s3_key = S3_CONFIGURATION_TEMPLATE.format(action_name)
                    s3_client.delete_object_with_retries(
                        Bucket=self.configuration_bucket, Key=s3_key)
                    s3_key = S3_ROLES_TEMPLATE.format(action_name)
                    s3_client.delete_object_with_retries(
                        Bucket=self.configuration_bucket, Key=s3_key)
        except Exception as ex:
            self._logger.error(ERR_DELETE_TEMPLATE_, s3_key, str(ex))

        try:
            self._logger.info(INF_DELETE_ALL_ACTIONS_TEMPLATE, s3_key)
            s3_key = S3_ROLES_TEMPLATE.format(ALL_ACTIONS_TEMPLATE_NAME)
            s3_client.delete_object_with_retries(
                Bucket=self.configuration_bucket, Key=s3_key)
        except Exception as ex:
            self._logger.error(ERR_DELETE_TEMPLATE_, s3_key, str(ex))
示例#2
0
def generate_html_actions_page(html_file, region):
    with open(html_file) as f:
        html_template = "".join(f.readlines())

    bucket = os.getenv(handlers.ENV_CONFIG_BUCKET)
    stack = os.getenv(handlers.ENV_STACK_NAME)

    action_groups = {}
    for a in actions.all_actions():
        ap = actions.get_action_properties(a)
        if ap.get(actions.ACTION_INTERNAL):
            continue
        href = CFN_CONSOLE_URL_TEMPLATE.format(
            region, region,
            urllib.parse.quote(ap.get(actions.PARAM_DESCRIPTION, "")), region,
            bucket, a)

        group_name = group_name_from_action_name(a)
        if group_name not in action_groups:
            action_groups[group_name] = {}

        action_groups[group_name][a] = (href, ap.get(actions.ACTION_TITLE))

    action_list = ""
    for g in sorted(action_groups.keys()):
        actions_list = ""
        for a in sorted(action_groups[g].keys()):
            actions_list += HTML_ACTION_LIST_ITEM.format(
                action_groups[g][a][0], action_groups[g][a][1])
        action_list += HTML_GROUP_LIST_ITEM.format(g, actions_list)
    action_list = HTML_ACTIONS_GROUPS_LISTS.format(action_list)

    return html_template.replace("%actions%",
                                 action_list).replace("%stack%", stack)
    def delete_templates(self):

        s3_client = get_client_with_retries("s3", ["delete_object"],
                                            context=self.context)
        s3_key = ""
        try:
            for action_name in actions.all_actions():
                action_properties = actions.get_action_properties(action_name)
                if not action_properties.get(actions.ACTION_INTERNAL, False):
                    self._logger.info(INF_DELETING_ACTION_TEMPLATE,
                                      action_name)
                    s3_key = S3_KEY_ACTION_CONFIGURATION_TEMPLATE.format(
                        action_name)
                    s3_client.delete_object_with_retries(
                        Bucket=self.configuration_bucket, Key=s3_key)
        except Exception as ex:
            self._logger.error(ERR_DELETE_CONFIG_ITEM, s3_key,
                               self.configuration_bucket, str(ex))

            self._logger.info(INF_DELETE_ALL_ACTIONS_TEMPLATE)
            for key in [
                    S3_KEY_ACTIONS_HTML_PAGE,
                    S3_KEY_ACCOUNT_CONFIG_WITH_PARAMS,
                    S3_KEY_ACCOUNT_CONFIG_CREATE_ALL,
                    S3_KEY_ACCOUNT_EVENTS_FORWARD_TEMPLATE
            ]:
                try:
                    s3_client.delete_object_with_retries(
                        Bucket=self.configuration_bucket, Key=key)
                except Exception as ex:
                    self._logger.error(ERR_DELETE_CONFIG_ITEM, key,
                                       self.configuration_bucket, str(ex))
示例#4
0
def main(template_file, version, bucket):
    template = get_versioned_template(template_file, version, bucket)
    all_actions = actions.all_actions()
    add_actions_permissions(template, all_actions)
    add_additional_lambda_functions(template, all_actions)
    add_action_stack_resources(template, all_actions)
    print(json.dumps(template, indent=4))
示例#5
0
def get_actions(context=None):
    """
    Returns  a dictionary with all available actions, see get_action for details on returned items
    :param context: Lambda context
    :return: all available action
    """
    with _get_logger(context=context) as logger:
        logger.info("get_actions")
        return {
            action_name: get_action(action_name, log_this_call=False)
            for action_name in actions.all_actions()
        }
 def __init__(self, context=None, logger=None):
     """
     Initializes the instance
     :param context: Lambda context
     :param logger: Optional logger for warnings, if None then warnings are printed to console
     """
     self._logger = logger
     self._this_account = None
     self._context = context
     self._all_timezones = {tz.lower(): tz for tz in pytz.all_timezones}
     self._all_actions = actions.all_actions()
     self._s3_client = None
     self._s3_configured_cross_account_roles = None
def get_action(name, context=None, log_this_call=True):
    """
    Gets the details of the specified action
    :param name: Name of the action, raises an exception if the action does not exist
    :param context: Lambda context
    :param log_this_call: switch
    :return: Details of the specified action.

    """
    with _get_logger(context=context) as logger:
        if log_this_call:
            logger.info("get_action")
        all_actions = actions.all_actions()
        if name not in all_actions:
            raise_value_error(ERR_ACTION_DOES_NOT_EXIST, name, ",".join(all_actions))
        return actions.get_action_properties(name)
示例#8
0
    def generate_templates(self):
        """
        Generates configuration and cross-account role templates
        :return: 
        """

        def generate_configuration_template(s3, builder, action):
            configuration_template = S3_KEY_ACTION_CONFIGURATION_TEMPLATE.format(action)
            self._logger.info(INF_CREATE_ACTION_TEMPLATE, action, configuration_template)
            template = json.dumps(builder.build_template(action), indent=3)
            s3.put_object_with_retries(Body=template, Bucket=self.configuration_bucket, Key=configuration_template)

        def generate_all_actions_cross_account_role_template_parameterized(s3, builder, all_act, template_description):
            self._logger.info(INF_CREATE_ALL_ACTIONS_CROSS_ROLES_TEMPLATE, S3_KEY_ACCOUNT_CONFIG_WITH_PARAMS)

            template = builder.build_template(action_list=all_act, description=template_description, with_conditional_params=True)
            if self.optimize_cross_account_template:
                template = CrossAccountRoleBuilder.compress_template(template)
            template_json = json.dumps(template, indent=3)
            s3.put_object_with_retries(Body=template_json, Bucket=self.configuration_bucket, Key=S3_KEY_ACCOUNT_CONFIG_WITH_PARAMS)

        # noinspection PyUnusedLocal
        def generate_all_actions_cross_account_role_template(s3, builder, all_act, template_description):
            self._logger.info(INF_CREATE_ALL_ACTIONS_CROSS_ROLES_TEMPLATE, S3_KEY_ACCOUNT_CONFIG_CREATE_ALL)
            template = json.dumps(
                builder.build_template(action_list=all_act, description=template_description, with_conditional_params=False),
                indent=3)
            s3.put_object_with_retries(Body=template, Bucket=self.configuration_bucket, Key=S3_KEY_ACCOUNT_CONFIG_CREATE_ALL)

        def generate_forward_events_template(s3):
            self._logger.info(INF_CREATE_EVENT_FORWARD_TEMPLATE, S3_KEY_ACCOUNT_EVENTS_FORWARD_TEMPLATE)
            template = build_events_forward_template(template_filename="./cloudformation/{}".format(FORWARD_EVENTS_TEMPLATE),
                                                     script_filename="./forward-events.py",
                                                     stack=self.stack_name,
                                                     event_role_arn=self.events_forward_role,
                                                     ops_automator_topic_arn=self.ops_automator_topic_arn,
                                                     version=self.stack_version)

            s3.put_object_with_retries(Body=template, Bucket=self.configuration_bucket, Key=S3_KEY_ACCOUNT_EVENTS_FORWARD_TEMPLATE)

        def generate_scenario_templates(s3):
            self._logger.info("Creating task scenarios templates")

            for template_name, template in list(builders.build_scenario_templates(templates_dir="./cloudformation/scenarios",
                                                                                  stack=self.stack_name)):
                self._logger.info(INF_SCENARIO_TEMPLATE, template_name, S3_KEY_SCENARIO_TEMPLATE_BUCKET)
                s3.put_object_with_retries(Body=template,
                                           Bucket=self.configuration_bucket,
                                           Key=S3_KEY_SCENARIO_TEMPLATE_KEY.format(template_name))

        def generate_custom_resource_builder(s3):
            self._logger.info("Create custom resource builder script {}", S3_KEY_CUSTOM_RESOURCE_BUILDER)

            with open("./build_task_custom_resource.py", "rt") as f:
                script_text = "".join(f.readlines())
                script_text = script_text.replace("%stack%", self.stack_name)
                script_text = script_text.replace("%account%", self.account)
                script_text = script_text.replace("%region%", self.region)
                script_text = script_text.replace("%config_table%", os.getenv("CONFIG_TABLE"))

            s3.put_object_with_retries(Body=script_text, Bucket=self.configuration_bucket, Key=S3_KEY_CUSTOM_RESOURCE_BUILDER)

        def generate_actions_html_page(s3):
            self._logger.info("Generating Actions HTML page {}", S3_KEY_ACTIONS_HTML_PAGE)
            html = builders.generate_html_actions_page(html_file="./builders/actions.html", region=self.region)
            s3.put_object_with_retries(Body=html, Bucket=self.configuration_bucket, Key=S3_KEY_ACTIONS_HTML_PAGE,
                                       ContentType="text/html")

        self._logger.info(INF_GENERATING_TEMPLATES, self.configuration_bucket)
        try:
            stack = os.getenv(handlers.ENV_STACK_NAME, "")
            s3_client = get_client_with_retries("s3", ["put_object"], context=self.context)
            config_template_builder = ActionTemplateBuilder(self.context,
                                                            service_token_arn="arn:aws:region:account:function:used-for-debug-only",
                                                            ops_automator_role=self.automator_role_arn,
                                                            use_ecs=self.use_ecs)
            role_template_builder = CrossAccountRoleBuilder(self.automator_role_arn, stack)

            all_actions = []
            for action_name in actions.all_actions():
                action_properties = actions.get_action_properties(action_name)
                if not action_properties.get(actions.ACTION_INTERNAL, False):
                    generate_configuration_template(s3_client, config_template_builder, action_name)
                    # Enable to generate a template for every individual action
                    # description = TEMPLATE_DESC_CROSS_ACCOUNT_ACTION.format(action_name, stack, account)
                    # generate_action_cross_account_role_template(s3_client, role_template_builder, action_name, description)
                    all_actions.append(action_name)

            if len(all_actions) > 0:
                description = TEMPLATE_DESC_ALL_ACTIONS_PARAMETERS.format(stack, self.account)
                generate_all_actions_cross_account_role_template_parameterized(s3_client, role_template_builder, all_actions,
                                                                               description)
            # enable to generate a template with all actions enabled
            #     description = TEMPLATE_DESC_ALL_ACTIONS.format(stack, account)
            #     generate_all_actions_cross_account_role_template(s3_client, role_template_builder, all_actions, description)

            for action_name in actions.all_actions():
                action_properties = actions.get_action_properties(action_name)
                if action_properties.get(actions.ACTION_EVENTS, None) is not None:
                    generate_forward_events_template(s3_client)
                    break

            generate_actions_html_page(s3_client)

            generate_scenario_templates(s3_client)

            generate_custom_resource_builder(s3_client)

        except Exception as ex:
            self._logger.error(ERR_BUILDING_TEMPLATES, str(ex), full_stack())
def get_action(name, context=None, log_this_call=True):
    """
    Gets the details of the specified action
    :param name: Name of the action, raises an exception if the action does not exist
    :param context: Lambda context
    :param log_this_call: switch
    :return: Details of the specified action. This dictionary can contain the following actions:

    Constants used below can be found in actions/__init__.py

    -ACTION_SERVICE: Name of the service of the resources of this action

    -ACTION_RESOURCES: Name of the resources for this action

    -ACTION_AGGREGATION: Possible values are:
        ACTION_AGGREGATION_RESOURCE: resources are not aggregated, execution of the action for each individual resource.
        ACTION_AGGREGATION_ACCOUNT: resources are aggregated per account, execution of the action for the list of resources 
        in that account
        ACTION_AGGREGATION_TASK: resources are aggregated per task, single execution of the action for list of all resources 
        in all accounts

    -ACTION_SELECT_EXPRESSION: Optional JMES path to map/select attributes of and filtering of resources

    -ACTION_BATCH_SIZE: Optional batch size for aggregated resources.

    -ACTION_PERMISSIONS: Optional, permissions required for the action

    -ACTION_MEMORY: Optional memory requirement for lambda function to run action, default is size of the scheduler lambda function

    -ACTION_CROSS_ACCOUNT: Optional, cross account operations supported by action, default is True

    -ACTION_EVENT_FILTER: Optional, regex filter which type of source events are supported by the 
    action, default is None (all events)

    -ACTION_TITLE: Optional, title to be used in UI

    -ACTION_DESCRIPTION: Optional, description or url to be used in UI

    -ACTION_AUTHOR: Optional, author of the action

    -ACTION_VERSION: Optional, implementation version of the action

    -ACTION_MULTI_REGION: Optional, True if the action can execute in multiple regions (default)

    -ACTION_INTERNAL: Optional, True if the service can only be used in internal tasks

    -ACTION_PARAM_STACK_RESOURCES: Optional, cloudformation snippet of resources owen and used by action implementation

    -ACTION_STACK_RESOURCES_PERMISSIONS: Optional, list of permissions for action stack resources

    -ACTION_PARAMETERS: Parameters for the action:

        -PARAM_ALLOWED_VALUES: allowed valued for a parameter (optional)

        -PARAM_DEFAULT: default value for a parameter (optional)

        -PARAM_MAX_LEN: max length for a string parameter (optional)

        -PARAM_MAX_VALUE: max value for a numeric parameter (optional)

        -PARAM_MIN_LEN: min length for a string parameter (optional)

        -PARAM_MIN_VALUE: # min value for a numeric parameter (optional)

        -PARAM_PATTERN: allowed pattern for a string parameter (optional)

        -PARAM_REQUIRED: true if parameter is required (default=False)

        -PARAM_TYPE:  (Python) type name of a parameter

        -PARAM_DESCRIBE_PARAMETER: name of a parameter if it must be used as a parameter in the describe method for a resource

        -PARAM_DESCRIPTION: user readable description for parameter

        -PARAM_LABEL: label for parameter

    """
    with _get_logger(context=context) as logger:
        if log_this_call:
            logger.info("get_action")
        all_actions = actions.all_actions()
        if name not in all_actions:
            raise ValueError(ERR_ACTION_DOES_NOT_EXIST.format(name, ",".join(all_actions)))
        return safe_json(actions.get_action_properties(name))
示例#10
0
    def generate_templates(self):
        """
        Generates configuration and cross-account role templates
        :return: 
        """
        def generate_configuration_template(s3, builder, action):
            configuration_template = S3_CONFIGURATION_TEMPLATE.format(action)
            self._logger.info(INF_CREATE_ACTION_TEMPLATE, action,
                              configuration_template)
            template = json.dumps(builder.build_template(action), indent=3)
            s3.put_object_with_retries(Body=template,
                                       Bucket=self.configuration_bucket,
                                       Key=configuration_template)

        def generate_action_cross_account_role_template(
                s3, builder, action, template_description):
            role_template = S3_ROLES_TEMPLATE.format(action)
            self._logger.info(INF_CREATECROSS_ROLE_TEMPLATE, action,
                              role_template)
            template = json.dumps(builder.build_template(
                role_actions=[action], description=template_description),
                                  indent=3)
            s3.put_object_with_retries(Body=template,
                                       Bucket=self.configuration_bucket,
                                       Key=role_template)

        def generate_all_actions_cross_cross_account_role_template(
                s3, builder, allactions, template_description):
            role_template = S3_ROLES_TEMPLATE.format(ALL_ACTIONS_TEMPLATE_NAME)
            self._logger.info(INF_CREATE_ALL_ACTIONS_CROSS_ROLES_TEMPLAE,
                              role_template)
            template = json.dumps(builder.build_template(
                role_actions=allactions, description=template_description),
                                  indent=3)
            s3.put_object_with_retries(Body=template,
                                       Bucket=self.configuration_bucket,
                                       Key=role_template)

        self._logger.info(INF_GENERATING_TEMPLATES, self.configuration_bucket)
        try:
            account = AwsService.get_aws_account()
            stack = os.getenv(handlers.ENV_STACK_NAME, "")
            s3_client = get_client_with_retries("s3", ["put_object"],
                                                context=self.context)
            config_template_builder = ActionTemplateBuilder(
                self.context, "arn:aws:region:account:function:debug-only")
            role_template_builder = CrossAccountRoleBuilder(
                self.scheduler_role_arn)

            all_actions = []
            for action_name in actions.all_actions():
                action_properties = actions.get_action_properties(action_name)
                if not action_properties.get(actions.ACTION_INTERNAL, False):
                    generate_configuration_template(s3_client,
                                                    config_template_builder,
                                                    action_name)
                    description = TEMPLATE_DESC_CROSS_ACCOUNT_ACTION.format(
                        action_name, stack, account)
                    generate_action_cross_account_role_template(
                        s3_client, role_template_builder, action_name,
                        description)
                    all_actions.append(action_name)
            if len(all_actions) > 0:
                description = TEMPLATE_DESC_ALL_ACTIONS.format(stack, account)
                generate_all_actions_cross_cross_account_role_template(
                    s3_client, role_template_builder, all_actions, description)

        except Exception as ex:
            self._logger.error(ERR_BUILDING_TEMPLATES, str(ex),
                               traceback.format_exc())
示例#11
0
#!/usr/bin/env python

from server import Server
from actions import all_actions
import asyncio
from domain import Counter, Users
import logging
import websockets

logging.basicConfig()

counter = Counter()
domain_objects = [counter]

users = Users(domian_objects=domain_objects)
conn = Server(users=users, actions=all_actions(counter))

for d in domain_objects:
    d.attach(conn.send_message)

start_server = websockets.serve(conn.manage_user_connection, "localhost", 6789)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()