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
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)
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)
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)
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
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})
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)
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
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}")