def read_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: LOG.info(request) if not session: raise exceptions.InternalFailure(f"boto3 session unavailable") if not request.desiredResourceState: raise exceptions.InternalFailure("Desired resource state unavailable") model = request.desiredResourceState organizations: Organizations.Client = session.client('organizations') try: scp = organizations.describe_policy(PolicyId=model.Id)["Policy"] except organizations.exceptions.PolicyNotFoundException: raise exceptions.NotFound(OrganizationsServiceControlPolicyProvisioner.TYPE, model.Id) model = ResourceModel._deserialize({ "Arn": scp["PolicySummary"]["Arn"], "Description": scp["PolicySummary"]["Description"], "Content": scp["Content"], "Id": scp["PolicySummary"]["Id"], "Name": scp["PolicySummary"]["Name"] }) return ProgressEvent( status=OperationStatus.SUCCESS, resourceModel=model, )
def update_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: LOG.info(request) if not session: raise exceptions.InternalFailure(f"boto3 session unavailable") if not request.previousResourceState: raise exceptions.InternalFailure("Previous resource state unavailable") if not request.desiredResourceState: raise exceptions.InternalFailure("Desired resource state unavailable") organizations: Organizations.Client = session.client('organizations') provisioner = OrganizationsServiceControlPolicyProvisioner(LOG, organizations) model = provisioner.update(request.previousResourceState, request.desiredResourceState) return ProgressEvent( status=OperationStatus.SUCCESS, resourceModel=model, )
def read_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: model = request.desiredResourceState config = request.typeConfiguration model.Notes = None try: req = requests.get(url='https://{}/v2/orders/{}'.format( ("api.alpaca.markets" if config.Credentials.Environment == "LIVE" else "paper-api.alpaca.markets"), model.Id), headers={ 'APCA-API-KEY-ID': config.Credentials.ApiKey, 'APCA-API-SECRET-KEY': config.Credentials.SecretKey }) if req.status_code == 404: raise exceptions.NotFound(type_name=TYPE_NAME, identifier=model.Id) order = json.loads(req.text) if 'code' in order and order['code'] in [40410000, 40010001]: raise exceptions.NotFound(type_name=TYPE_NAME, identifier=model.Id) if 'id' not in order: raise exceptions.InternalFailure(f"Internal failure") if order['canceled_at'] is not None: raise exceptions.NotFound(type_name=TYPE_NAME, identifier=model.Id) model.Symbol = order['symbol'] model.Quantity = float(order['qty']) model.FilledQuantity = str(order['filled_qty']) if order['filled_avg_price'] == None: model.FilledValue = "0" model.CurrentValue = "0" else: model.FilledValue = str( float(order['filled_qty']) * float(order['filled_avg_price'])) req = requests.get( url='https://data.alpaca.markets/v2/stocks/{}/trades/latest'. format(order['symbol']), headers={ 'APCA-API-KEY-ID': config.Credentials.ApiKey, 'APCA-API-SECRET-KEY': config.Credentials.SecretKey }) trade = json.loads(req.text) model.CurrentValue = str( float(order['filled_qty']) * float(trade['trade']['p'])) model.FilledAt = order['filled_at'] except Exception as e: if not isinstance(e, exceptions.NotFound): raise exceptions.InternalFailure(f"{e}") raise e return ProgressEvent( status=OperationStatus.SUCCESS, resourceModel=model, )
def _isAdminPolicy(policy: MutableMapping[str, Any]) -> bool: isAdminPolicy = False if policy: policyDocument = policy.get("PolicyDocument") policyName = policy.get("PolicyName") if policyDocument and policyName: for statement in policyDocument.get("Statement"): effect = statement.get("Effect") if effect != "Allow": # not an allow statement -can skip break wildcardResourceIncluded = False wildcardActionIncluded = False # resource may be single or multiple resource = statement.get("Resource") if resource == "*": wildcardResourceIncluded = True elif type(resource) is list: for res in resource: if res == "*": wildcardResourceIncluded = True break # found a wildcard resource action = statement.get("Action") if action == "*": wildcardActionIncluded = True elif type(action) is list: for act in action: if act == "*": wildcardActionIncluded = True break # found a wildcard action # we only get here if Effect was also Allow. if wildcardActionIncluded and wildcardResourceIncluded: isAdminPolicy = True if isAdminPolicy: LOG.info( f"Policy with PolicyName {policyName} includes a Statement which grants 'Allow action * on " f"resource *'") return True else: return False else: raise exceptions.InternalFailure( f"Policy model missing required parameters") else: raise exceptions.InternalFailure(f"Policy model empty")
def put_event_type_and_return_progress(frauddetector_client, model, progress: ProgressEvent): try: if hasattr(model, "Tags"): tags = model_helpers.get_tags_from_tag_models(model.Tags) put_event_type_func = partial( api_helpers.call_put_event_type, frauddetector_client=frauddetector_client, event_type_tags=tags, ) else: put_event_type_func = partial( api_helpers.call_put_event_type, frauddetector_client=frauddetector_client, ) put_event_type_for_model(put_event_type_func, model) progress.resourceModel = model_helpers.get_event_type_and_return_model( frauddetector_client, model) progress.status = OperationStatus.SUCCESS LOG.debug( f"just finished a put event_type call for event type: {progress.resourceModel.Name}" ) except RuntimeError as e: raise exceptions.InternalFailure(f"Error occurred: {e}") LOG.info(f"Returning Progress with status: {progress.status}") return progress
def create_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], # pylint: disable=unused-argument ) -> ProgressEvent: """This function is triggered by the CloudFormation CREATE event and will set the StepConcurrency level from the default of 1 to the new provided value within the up to the max of 256. It will also add a tag to the cluster in order to keep track of the resource. Attributes: session (Optional[SessionProxy]): The session proxy for connecting to the needed AWS API client cluster_id (str): The unique ID of the cluster to get details from callback_context (MutableMapping[str, Any]): Use to store any state between re-invocation via IN_PROGRESS Returns: ProgressEvent: An event with the status of the action """ LOG.info("Create Handler") model = request.desiredResourceState progress: ProgressEvent = ProgressEvent( status=OperationStatus.IN_PROGRESS, resourceModel=model, ) model.UID = "cluster:" + model.ClusterId model.StepConcurrencyLevel = int(model.StepConcurrencyLevel) uid = get_uid(session, model.ClusterId) LOG.info("UID: %s", uid) if uid == model.UID: raise exceptions.AlreadyExists(TYPE_NAME, model.ClusterId) if model.StepConcurrencyLevel < 1 or model.StepConcurrencyLevel > 256: raise exceptions.InvalidRequest( f"Step Concurency Level must be between 1 and 256, \ {model.StepConcurrencyLevel} was given.") try: client = session.client('emr') LOG.info("Setting concurrency to %s for cluster %s", model.StepConcurrencyLevel, model.ClusterId) response = client.modify_cluster(ClusterId=model.ClusterId, StepConcurrencyLevel=int( model.StepConcurrencyLevel)) LOG.info("RESPONSE TO SET CONCURRENCY:") LOG.info(response) LOG.info("Setting UID tag to %s", model.ClusterId) tag_response = client.add_tags(ResourceId=model.ClusterId, Tags=[{ "Key": "StepConcurrencyUID", "Value": model.UID }]) LOG.info("RESPONSE TO ADD TAGS:") LOG.info(tag_response) progress.status = OperationStatus.SUCCESS except Exception as unexpected_exception: LOG.error(str(unexpected_exception)) raise exceptions.InternalFailure( f"Failed Create: {str(unexpected_exception)}") return progress
def read_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], # pylint: disable=unused-argument ) -> ProgressEvent: """This function is triggered by the CloudFormation READ event and will retrieve the StepConcurrency level of the cluster. Attributes: session (Optional[SessionProxy]): The session proxy for connecting to the needed AWS API client cluster_id (str): The unique ID of the cluster to get details from callback_context (MutableMapping[str, Any]): Use to store any state between re-invocation via IN_PROGRESS Returns: ProgressEvent: An event with the status of the action """ model = request.desiredResourceState if model.UID != get_uid(session, model.ClusterId): raise exceptions.NotFound(TYPE_NAME, model.ClusterId) try: model.StepConcurrencyLevel = get_concurrency_level( session, model.ClusterId) except Exception as unexpected_exception: LOG.error(str(unexpected_exception)) raise exceptions.InternalFailure( f"Failed Read: {str(unexpected_exception)}") return ProgressEvent( status=OperationStatus.SUCCESS, resourceModel=model, )
def list_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: models = [] ensure_tracking_table_exists(session) try: ddbclient = session.client('dynamodb') items = ddbclient.scan(TableName=TRACKING_TABLE_NAME)['Items'] for item in items: model = ResourceModel(ExecutionId=item['executionId']['S'], ClusterArn=None, SecretArn=None, Databases=None, SQL=None, Users=None, SQLIdempotency=None) models.append(model) except Exception as e: raise exceptions.InternalFailure(f"{e}") return ProgressEvent( status=OperationStatus.SUCCESS, resourceModels=models, )
def put_entity_type_and_return_progress(frauddetector_client, model, progress): try: if hasattr(model, "Tags"): tags = model_helpers.get_tags_from_tag_models(model.Tags) api_helpers.call_put_entity_type( frauddetector_client, entity_type_name=model.Name, entity_type_tags=tags, entity_type_description=model.Description, ) else: api_helpers.call_put_entity_type( frauddetector_client, entity_type_name=model.Name, entity_type_description=model.Description, ) progress.resourceModel = model_helpers.get_entity_types_and_return_model_for_entity_type( frauddetector_client, model.Name) progress.status = OperationStatus.SUCCESS LOG.info( f"just finished a put entity_type call: {progress.resourceModel}") except RuntimeError as e: progress.status = OperationStatus.FAILED raise exceptions.InternalFailure(f"Error occurred: {e}") return progress
def update_tags(frauddetector_client, afd_resource_arn: str, new_tags: Sequence[models.Tag] = None): try: list_tags_response = api_helpers.call_list_tags_for_resource( frauddetector_client, afd_resource_arn) attached_tags = list_tags_response.get("tags", []) attached_tags_dict = { tag.get("key", ""): tag.get("value", None) for tag in attached_tags } tags_to_add = [model_helpers.get_tags_from_tag_models(new_tags), {}][new_tags is None] tags_to_add_dict = { tag.get("key", ""): tag.get("value", None) for tag in tags_to_add } if attached_tags_dict == tags_to_add_dict: return if attached_tags: api_helpers.call_untag_resource(frauddetector_client, afd_resource_arn, list(attached_tags_dict.keys())) if tags_to_add_dict: api_helpers.call_tag_resource(frauddetector_client, afd_resource_arn, tags_to_add) except RuntimeError as e: raise exceptions.InternalFailure( f"Error occurred while updating tags: {e}")
def execute_read_event_type_handler_work(session, model, progress): afd_client = client_helpers.get_afd_client(session) # read requests only include primary identifier (Arn). Extract Name from Arn if not model.Name: model.Name = model.Arn.split("/")[-1] # For contract_delete_read, we need to fail if the resource DNE # get_event_types will throw RNF Exception if event_type DNE ( get_event_types_works, get_event_types_response, ) = validation_helpers.check_if_get_event_types_succeeds( afd_client, model.Name) if not get_event_types_works: raise exceptions.NotFound("event_type", model.Name) try: event_types = get_event_types_response.get("eventTypes", []) if event_types: referenced_resources = model_helpers.get_referenced_resources( model) model = model_helpers.get_model_for_event_type( afd_client, event_types[0], referenced_resources) else: raise exceptions.NotFound("event_type", model.Name) progress.resourceModel = model progress.status = OperationStatus.SUCCESS except RuntimeError as e: raise exceptions.InternalFailure(f"Error occurred: {e}") LOG.info(f"Returning Progress with status: {progress.status}") return progress
def create_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: model = request.desiredResourceState progress: ProgressEvent = ProgressEvent( status=OperationStatus.IN_PROGRESS, resourceModel=model, ) if callback_context.get('pending'): return read_handler(session, request, callback_context) try: client = session.client("transcribe") if model.Phrases is not None: client.create_vocabulary( VocabularyName=model.VocabularyName, LanguageCode=model.LanguageCode, Phrases=model.Phrases ) else: client.create_vocabulary( VocabularyName=model.VocabularyName, LanguageCode=model.LanguageCode, VocabularyFileUri=model.VocabularyFileUri ) except client.exceptions.ConflictException as e: raise exceptions.AlreadyExists(type_name=TYPE_NAME, identifier=model.VocabularyName) except Exception as e: raise exceptions.InternalFailure(f"{e}") return read_handler(session, request, callback_context)
def execute_delete_event_type_handler_work(session, model, progress): afd_client = client_helpers.get_afd_client(session) # For contract_delete_delete, we need to fail if the resource DNE # get_event_types will throw RNF Exception if event_type DNE get_event_type_works, _ = validation_helpers.check_if_get_event_types_succeeds( afd_client, model.Name) if not get_event_type_works: raise exceptions.NotFound("event_type", model.Name) # Check for existing events, we'll need a DDB get call, since we do not have a plural `GetEvents` API # TODO: this, after event ingestion is released try: LOG.debug("deleting event type") api_helpers.call_delete_event_type(afd_client, model.Name) LOG.debug( "deleting inline dependencies (entity types, labels, event variables)" ) delete_worker_helpers.delete_inline_dependencies(afd_client, model) progress.resourceModel = None progress.status = OperationStatus.SUCCESS except RuntimeError as e: raise exceptions.InternalFailure(f"Error occurred: {e}") LOG.info(f"Returning Progress with status: {progress.status}") return progress
def read_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: model = request.desiredResourceState ensure_tracking_table_exists(session) if not model.ExecutionId: raise exceptions.NotFound(type_name=TYPE_NAME, identifier=model.ExecutionId) try: ddbclient = session.client('dynamodb') item = ddbclient.get_item( TableName=TRACKING_TABLE_NAME, Key={'executionId': { 'S': model.ExecutionId }}) if 'Item' not in item: raise exceptions.NotFound(type_name=TYPE_NAME, identifier=model.ExecutionId) except ddbclient.exceptions.ResourceNotFoundException: raise exceptions.NotFound(type_name=TYPE_NAME, identifier=model.ExecutionId) except Exception as e: if not isinstance(e, exceptions.NotFound): raise exceptions.InternalFailure(f"{e}") raise e return ProgressEvent( status=OperationStatus.SUCCESS, resourceModel=model, )
def update_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: model = request.desiredResourceState previous_state = request.previousResourceState LOG.debug(callback_context) LOG.debug(request.previousResourceState) LOG.debug(request.desiredResourceState) LOG.debug(request.logicalResourceIdentifier) LOG.debug(request.clientRequestToken) try: if isinstance(session, SessionProxy): client = session.client("apigateway") states_client = session.client("stepfunctions") progress = handle_update(agw_client=client, states_client=states_client, model=model, previous_state=previous_state, callback_context=callback_context) return progress else: LOG.error("No session available") raise TypeError except TypeError as e: raise exceptions.InternalFailure(f"was not expecting type {e}")
def create_variable_and_return_progress(frauddetector_client, model, progress): try: if hasattr(model, "Tags"): tags = model_helpers.get_tags_from_tag_models(model.Tags) else: tags = None api_helpers.call_create_variable( frauddetector_client, variable_name=model.Name, variable_tags=tags, variable_data_type=model.DataType, variable_data_source=model.DataSource, variable_default_value=model.DefaultValue, variable_type=model.VariableType, variable_description=model.Description, ) progress.resourceModel = model_helpers.get_variables_and_return_model_for_variable( frauddetector_client, model.Name) progress.status = OperationStatus.SUCCESS LOG.info( f"just finished a create variable call: {progress.resourceModel}") except RuntimeError as e: progress.status = OperationStatus.FAILED raise exceptions.InternalFailure(f"Error occurred: {e}") return progress
def create_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: # Typicaly model is in request.desiredResourceState # model = request.desiredResourceState # Work-a-round to create a resource with no properties (and ignore any properties set) model = ResourceModel(ID='', Content='') progress: ProgressEvent = ProgressEvent( status=OperationStatus.IN_PROGRESS, resourceModel=model, ) try: # setting up random primary identifier compliant with cfn standard model.ID = identifier_utils.generate_resource_identifier( stack_id_or_name=request.stackId, logical_resource_id=request.logicalResourceIdentifier, client_request_token=request.clientRequestToken, max_length=255) # Setting Status to success will signal to cfn that the operation is complete # progress.status = OperationStatus.SUCCESS except TypeError as e: # exceptions module lets CloudFormation know the type of failure that occurred raise exceptions.InternalFailure(f"was not expecting type {e}") # this can also be done by returning a failed progress event #return ProgressEvent.failed(HandlerErrorCode.InternalFailure, f"was not expecting type {e}") return ProgressEvent(status=OperationStatus.SUCCESS, resourceModel=model)
def execute_read_variable_handler_work(session, model, progress): afd_client = client_helpers.get_afd_client(session) # read requests only include primary identifier (Arn). Extract Name from Arn model.Name = model.Arn.split("/")[-1] # For contract_delete_read, we need to fail if the resource DNE # get variables will throw RNF Exception if variable DNE ( get_variables_works, get_variables_response, ) = validation_helpers.check_if_get_variables_succeeds( afd_client, model.Name) if not get_variables_works: raise exceptions.NotFound("variable", model.Name) try: variables = get_variables_response.get("variables", []) if variables: model = model_helpers.get_model_for_variable( afd_client, variables[0]) progress.resourceModel = model progress.status = OperationStatus.SUCCESS except RuntimeError as e: raise exceptions.InternalFailure(f"Error occurred: {e}") return progress
def delete_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: model = request.desiredResourceState progress: ProgressEvent = ProgressEvent( status=OperationStatus.IN_PROGRESS, resourceModel=None, ) try: client = session.client("transcribe") client.get_vocabulary( VocabularyName=model.VocabularyName ) client.delete_vocabulary( VocabularyName=model.VocabularyName ) progress.status = OperationStatus.SUCCESS except client.exceptions.NotFoundException as e: raise exceptions.NotFound(type_name=TYPE_NAME, identifier=model.VocabularyName) except Exception as e: if "t be found" in str(e): raise exceptions.NotFound(type_name=TYPE_NAME, identifier=model.VocabularyName) raise exceptions.InternalFailure(f"{e}") return progress
def read_handler(session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any]) -> ProgressEvent: LOG.error(request) model = request.desiredResourceState progress: ProgressEvent = ProgressEvent(status=OperationStatus.IN_PROGRESS, resourceModel=model, callbackContext=callback_context, callbackDelaySeconds=10) LOG.setLevel(model.LogLevel) LOG.info("Entering read.handle() method.") _log_parameters(model, callback_context) try: if isinstance(session, SessionProxy): read.handle(session, request, callback_context, progress) except TypeError as e: raise exceptions.InternalFailure(f"was not expecting type {e}") LOG.info("Exiting read.handle() method.") return progress
def get_afd_client(session): if isinstance(session, SessionProxy): return session.client( service_name="frauddetector", config=BOTO3_CLIENT_CONFIG_WITH_STANDARD_RETRIES, ) raise exceptions.InternalFailure( f"Error: failed to get frauddetector client.")
def create_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: model = request.desiredResourceState progress: ProgressEvent = ProgressEvent( status=OperationStatus.IN_PROGRESS, resourceModel=model, callbackContext=callback_context if callback_context is not None else {}) try: if isinstance(session, SessionProxy): if "TOKEN" in callback_context and "VERSION" in callback_context: response = session.client( "cloudformation").set_type_default_version( Arn=callback_context["VERSION"]) progress.status = OperationStatus.SUCCESS elif "TOKEN" in callback_context and "VERSION" not in callback_context: response = session.client( "cloudformation").describe_type_registration( RegistrationToken=callback_context["TOKEN"]) if response['ProgressStatus'] == 'COMPLETE': progress.callbackContext["VERSION"] = response[ "TypeVersionArn"] progress.callbackContext["Arn"] = response["TypeArn"] progress.resourceModel.Version = response["TypeVersionArn"] progress.resourceModel.Arn = response["TypeArn"] elif response['ProgressStatus'] == 'FAILED': progress.status = OperationStatus.FAILED else: progress.callbackDelaySeconds = 30 progress.status = OperationStatus.IN_PROGRESS else: response = session.client("cloudformation").register_type( Type=model.Type if model.Type is not None else 'RESOURCE', TypeName=model.TypeName, SchemaHandlerPackage=model.SchemaHandlerPackage, LoggingConfig={ 'LogRoleArn': model.LoggingConfig.LogRoleArn, 'LogGroupName': model.LoggingConfig.LogGroupName } if model.LoggingConfig is not None else None, ExecutionRoleArn=model.ExecutionRoleArn if model.ExecutionRoleArn is not None else None, ClientRequestToken=''.join( random.choice(string.ascii_lowercase) for i in range(32))) progress.callbackContext["TOKEN"] = response[ "RegistrationToken"] progress.resourceModel.Token = response["RegistrationToken"] progress.status = OperationStatus.IN_PROGRESS except TypeError as e: # exceptions module lets CloudFormation know the type of failure that occurred raise exceptions.InternalFailure(f"was not expecting type {e}") # this can also be done by returning a failed progress event # return ProgressEvent.failed(HandlerErrorCode.InternalFailure, f"was not expecting type {e}") return progress
def write_ssm_parameters(name, value, param_type, session): try: ssm = session.client('ssm') ssm.put_parameter(Name=name, Value=value, Type=param_type, Overwrite=True) except ClientError as client_error: raise exceptions.InternalFailure(str(client_error))
def get_singleton_afd_client(session): global afd_client if afd_client is not None: return afd_client if isinstance(session, SessionProxy): afd_client = session.client("frauddetector") return afd_client raise exceptions.InternalFailure( f"Error: failed to get frauddetector client.")
def pre_create_handler( session: Optional[SessionProxy], request: HookHandlerRequest, callback_context: MutableMapping[str, Any], type_configuration: TypeConfigurationModel) -> ProgressEvent: target_model = request.hookContext.targetModel progress: ProgressEvent = ProgressEvent(status=OperationStatus.IN_PROGRESS) resource_properties = target_model.get("resourceProperties") resource_name = request.hookContext.targetLogicalId target_name = request.hookContext.targetName LOG.info( f"{TYPE_NAME} CREATE_PRE_PROVISION handler triggered for resource {resource_name} of type {target_name}" ) adminPolicyFound = False if "AWS::IAM::Policy" == target_name: adminPolicyFound = _isAdminPolicy(resource_properties) elif "AWS::IAM::User" == target_name or "AWS::IAM::Role" == target_name or "AWS::IAM::Group" == target_name: if resource_properties: policies = resource_properties.get("Policies") if policies: for policy in policies: # iterate through them all - if multiple violations, logs will report them all adminPolicyFound = adminPolicyFound or _isAdminPolicy( policy) else: LOG.info("No policies defined in this resource") else: raise exceptions.InternalFailure(f"{target_name} model empty") else: raise exceptions.InvalidRequest(f"Unknown target type: {target_name}") if adminPolicyFound: progress.status = OperationStatus.FAILED progress.errorCode = HandlerErrorCode.NonCompliant progress.message = "One or more policies granting 'Allow action * on resource *' found" else: progress.status = OperationStatus.SUCCESS progress.message = "No policies granting 'Allow action * on resource *' found" if progress.status != OperationStatus.SUCCESS: LOG.info( f"{TYPE_NAME} FAIL: Resource {resource_name} - {progress.message}") else: LOG.info( f"{TYPE_NAME} SUCCESS: Resource {resource_name} - {progress.message}" ) return progress
def update_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], # pylint: disable=unused-argument ) -> ProgressEvent: """This function is triggered by the CloudFormation UPDATE event and will update the StepConcurrency level to the new provided value within the up to the max of 256. It will also add a tag to the cluster in order to keep track of the resource. Attributes: session (Optional[SessionProxy]): The session proxy for connecting to the needed AWS API client cluster_id (str): The unique ID of the cluster to get details from callback_context (MutableMapping[str, Any]): Use to store any state between re-invocation via IN_PROGRESS Returns: ProgressEvent: An event with the status of the action """ model = request.desiredResourceState previous_model = request.previousResourceState progress: ProgressEvent = ProgressEvent( status=OperationStatus.IN_PROGRESS, resourceModel=model, ) LOG.info("UPDATE HANDLER") LOG.info("MODEL") LOG.info(model) LOG.info("PREVIOUS") LOG.info(previous_model) model.StepConcurrencyLevel = int(model.StepConcurrencyLevel) if model.UID != previous_model.UID: raise exceptions.InvalidRequest("Cannot update the UID") if model.StepConcurrencyLevel < 1 or model.StepConcurrencyLevel > 256: raise exceptions.InvalidRequest( f"Step Concurency Level must be between 1 and 256, \ {model.StepConcurrencyLevel} was given.") if model.UID != get_uid(session, model.ClusterId): raise exceptions.NotFound(TYPE_NAME, model.ClusterId) try: client = session.client('emr') LOG.info("Updating concurrency to %s for cluster %s", model.StepConcurrencyLevel, model.ClusterId) response = client.modify_cluster( ClusterId=model.ClusterId, StepConcurrencyLevel=model.StepConcurrencyLevel) LOG.info("RESPONSE: %s", response) progress.status = OperationStatus.SUCCESS except Exception as unexpected_exception: LOG.error(str(unexpected_exception)) raise exceptions.InternalFailure( f"Failed Update: {str(unexpected_exception)}") return progress
def execute_list_label_handler_work(session, model, progress): afd_client = client_helpers.get_afd_client(session) try: get_labels_response = api_helpers.call_get_labels(afd_client) labels = get_labels_response.get("labels", []) progress.resourceModels = [model_helpers.get_model_for_label(afd_client, label) for label in labels] progress.status = OperationStatus.SUCCESS except RuntimeError as e: raise exceptions.InternalFailure(f"Error occurred: {e}") return progress
def read_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: if not request.desiredResourceState or not request.desiredResourceState.Id: raise exceptions.InternalFailure("Desired resource state unavailable") if not session: raise exceptions.InternalFailure(f"boto3 session unavailable") organizations = session.client("organizations") provisioner = OrganizationsOrganizationProvisioner(LOG, organizations) organization = provisioner.get(request.desiredResourceState) return ProgressEvent( status=OperationStatus.SUCCESS, resourceModel=organization, )
def list_handler( session: Optional[SessionProxy], request: ResourceHandlerRequest, callback_context: MutableMapping[str, Any], ) -> ProgressEvent: config = request.typeConfiguration models = [] try: req = requests.get(url='https://{}/v2/orders'.format( ("api.alpaca.markets" if config.Credentials.Environment == "LIVE" else "paper-api.alpaca.markets")), headers={ 'APCA-API-KEY-ID': config.Credentials.ApiKey, 'APCA-API-SECRET-KEY': config.Credentials.SecretKey }) orders = json.loads(req.text) for order in orders: model = ResourceModel( Id=order['id'], Quantity=float(order['qty']), Symbol=order['symbol'], Notes=None, FilledQuantity=str(order['filled_qty']), FilledValue="0", CurrentValue="0", FilledAt=order['filled_at'], ) if order['filled_avg_price'] != None: model.FilledValue = str( float(order['filled_qty']) * float(order['filled_avg_price'])) req = requests.get( url='https://data.alpaca.markets/v2/stocks/{}/trades/latest' .format(order['symbol']), headers={ 'APCA-API-KEY-ID': config.Credentials.ApiKey, 'APCA-API-SECRET-KEY': config.Credentials.SecretKey }) trade = json.loads(req.text) model.CurrentValue = str( float(order['filled_qty']) * float(trade['trade']['p'])) models.append(model) except Exception as e: raise exceptions.InternalFailure(f"{e}") return ProgressEvent( status=OperationStatus.SUCCESS, resourceModels=models, )
def get_labels_and_return_model_for_label(frauddetector_client, label_name): try: get_labels_response = api_helpers.call_get_labels(frauddetector_client, label_name=label_name) labels = get_labels_response.get("labels", []) if labels: return get_model_for_label(frauddetector_client, labels[0]) # if get labels worked but did not return any labels, we have major problems error_msg = f"get_labels for {label_name} worked but did not return any labels!" LOG.error(error_msg) raise RuntimeError(error_msg) except RuntimeError as e: raise exceptions.InternalFailure(f"Error occurred while getting an label: {e}")