Beispiel #1
0
    def get_api_metadata(self,
                         api_name: str,
                         stage: str,
                         attribute_filters: list = None):
        self._logger.debug(
            f"Fetching Metadata for {api_name} in Stage {stage}")
        table_name = utils.get_table_name(api_name, stage)
        meta = self._dynamo_helper.get_item(self._api_control_table, {
            'api': table_name,
            'type': params.CONTROL_TYPE_META
        })

        if meta is None:
            return meta
        else:
            if attribute_filters is None:
                return meta
            else:
                self._logger.debug(
                    f"Applying Filter for Attributes: {attribute_filters}")
                # apply the attribute filters
                out = {}
                for f in attribute_filters:
                    if f in meta:
                        out[f] = meta[f]

                return out
Beispiel #2
0
    def delete_metadata(self,
                        api_name,
                        stage,
                        metadata_type,
                        caller_identity="System"):
        table_name = utils.get_table_name(api_name, stage)

        return self._dynamo_helper.control_table_delete(
            control_hash=table_name,
            control_sort=metadata_type,
            caller_identity=caller_identity)
Beispiel #3
0
    def create_metadata(self,
                        api_name,
                        stage,
                        caller_identity="System",
                        **kwargs):
        table_name = utils.get_table_name(api_name, stage)

        return self._dynamo_helper.control_table_update(
            control_hash=table_name,
            control_sort=params.CONTROL_TYPE_META,
            caller_identity=caller_identity,
            **kwargs)
Beispiel #4
0
    def delete_all_api_metadata(self, api_name, stage):
        table_name = utils.get_table_name(api_name, stage)
        # delete schemas
        self._dynamo_helper.control_table_delete(
            control_hash=table_name,
            control_sort=params.CONTROL_TYPE_RESOURCE_SCHEMA)
        self._dynamo_helper.control_table_delete(
            control_hash=table_name,
            control_sort=params.CONTROL_TYPE_METADATA_SCHEMA)

        # delete API Metadata
        self._dynamo_helper.control_table_delete(
            control_hash=table_name, control_sort=params.CONTROL_TYPE_META)
Beispiel #5
0
    def update_metadata(self,
                        api_name,
                        stage,
                        updates,
                        caller_identity="System"):
        if updates is not None and updates != []:
            table_name = utils.get_table_name(api_name, stage)

            return self._dynamo_helper.control_table_update(
                control_hash=table_name,
                control_sort=params.CONTROL_TYPE_META,
                caller_identity=caller_identity,
                **updates)
        else:
            return None
Beispiel #6
0
    def put_schema(self, api_name, stage, schema_type, caller_identity,
                   schema):
        table_name = utils.get_table_name(api_name, stage)

        if schema_type.lower() == params.RESOURCE.lower():
            set_schema_type = params.CONTROL_TYPE_RESOURCE_SCHEMA
        elif schema_type.lower() == params.METADATA.lower():
            set_schema_type = params.CONTROL_TYPE_METADATA_SCHEMA
        else:
            raise InvalidArgumentsException(
                f"Invalid Schema Type: {schema_type}")

        # nest the schema into a named object due to possible collisions with hash/sort key
        return self._dynamo_helper.control_table_update(
            table_name, set_schema_type, caller_identity,
            **{set_schema_type: schema})
Beispiel #7
0
    def create_metadata(self,
                        api_name,
                        stage,
                        caller_identity="System",
                        **kwargs):
        table_name = utils.get_table_name(api_name, stage)

        # remove the ApiName kwarg if it's there
        if params.API_NAME_PARAM in kwargs:
            del kwargs[params.API_NAME_PARAM]

        return self._dynamo_helper.control_table_update(
            control_hash=table_name,
            control_sort=params.CONTROL_TYPE_META,
            caller_identity=caller_identity,
            **kwargs)
Beispiel #8
0
    def get_schema(self, api_name, stage, schema_type):
        table_name = utils.get_table_name(api_name, stage)

        if schema_type.lower() == params.RESOURCE.lower():
            schema_type = params.CONTROL_TYPE_RESOURCE_SCHEMA
        elif schema_type.lower() == params.METADATA.lower():
            schema_type = params.CONTROL_TYPE_METADATA_SCHEMA
        else:
            raise InvalidArgumentsException(
                f"Invalid Schema Type {schema_type}")

        schema = self._dynamo_helper.get_control_item(
            table_ref=self._api_control_table,
            api_name=table_name,
            control_type=schema_type)

        if schema is not None:
            return schema[schema_type]
        else:
            return None
Beispiel #9
0
def provisioning_lambda(event, context):
    # TODO Add support for creation of Read/Only and Read/Write IAM Roles during provisioning
    log.debug(event)
    api_name = event.get("ApiName")
    event.pop("ApiName")

    # create an API Metadata Handler
    api_metadata_handler = ApiMetadata(REGION, log)

    # check if this API is already deployed
    table_name = utils.get_table_name(table_name=api_name, deployment_stage=STAGE)
    api_metadata = api_metadata_handler.get_api_metadata(api_name, STAGE)

    if api_metadata is None:
        log.debug(f"API {api_name} not found. Creating new Data API")
        api_metadata = {}
        # add the default parameters from the application container
        _add_api_defaults(api_metadata)
        api_metadata[params.DATA_TYPE] = api_name
        api_metadata[params.DEPLOYED_ACCOUNT] = context.invoked_function_arn.split(":")[4]
        api_metadata[params.STORAGE_TABLE] = table_name
        api_metadata[params.STORAGE_HANDLER] = params.DEFAULT_STORAGE_HANDLER
        api_metadata[params.CATALOG_DATABASE] = params.DEFAULT_CATALOG_DATABASE
    else:
        log.debug(f"API {api_name} already exists. Performing property update and instance rebuild")

        # remove last update date/by information to prevent update collision
        utils.remove_internal_attrs(api_metadata)

    # overlay the supplied parameters onto the api metadata
    api_metadata.update(event)

    # add a pending status
    api_metadata['Status'] = params.STATUS_CREATING

    # add a control table entry for this stage with the current configuration
    api_metadata_handler.create_metadata(api_name=api_name, stage=STAGE, caller_identity='System', **api_metadata)

    api_metadata[params.APP] = app

    # load the api class
    api = dapi.load_api(**api_metadata)

    # setup the search flow
    search_config = None
    if params.ES_DOMAIN in event:
        try:
            search_config = es_indexer.configure_search_flow(endpoints=api.get_endpoints(),
                                                             es_domain_name=event.get(params.ES_DOMAIN),
                                                             firehose_delivery_role_arn=event.get(
                                                                 params.FIREHOSE_DELIVERY_ROLE_ARN),
                                                             failure_record_bucket=event.get(
                                                                 params.DELIVERY_STREAM_FAILURE_BUCKET),
                                                             kms_key_arn=event.get(params.KMS_KEY_ARN)
                                                             )
        except KeyError:
            raise BadRequestError(
                f"Unable to provision search configuration without {params.ES_DOMAIN}, {params.FIREHOSE_DELIVERY_ROLE_ARN}, and {params.DELIVERY_STREAM_FAILURE_BUCKET}")

    # add the search config to metadata
    if search_config is not None:
        api_metadata_handler.update_metadata(api_name=api_name, stage=STAGE,
                                             updates=search_config, caller_identity='System')

    # destroy the cache reference to cause a reload on next invoke
    if api_cache.contains(api_name):
        log.debug(f"Invalidating API Cache")
        api_cache.remove(api_name)

    # update the metadata to show that the API is online
    api_metadata_handler.update_metadata(api_name=api_name, stage=STAGE,
                                         updates={"Status": params.STATUS_ACTIVE}, caller_identity='System')
    log.info(f"Provisioning complete. API {api_name} online in Stage {STAGE}")