def __init__(self, metadata=None, template=None): if template is None: template = {} self.metadata = metadata or {} self.template = template or {} self._template_raw = clone_safe(self.template) self.template_original = clone_safe(self.template) # initialize resources for resource_id, resource in self.template_resources.items(): resource["LogicalResourceId"] = self.template_original["Resources"][resource_id][ "LogicalResourceId" ] = (resource.get("LogicalResourceId") or resource_id) # initialize stack template attributes stack_id = self.metadata.get("StackId") or aws_stack.cloudformation_stack_arn( self.stack_name, short_uid() ) self.template["StackId"] = self.metadata["StackId"] = stack_id self.template["Parameters"] = self.template.get("Parameters") or {} self.template["Outputs"] = self.template.get("Outputs") or {} self.template["Conditions"] = self.template.get("Conditions") or {} # initialize metadata self.metadata["Parameters"] = self.metadata.get("Parameters") or [] self.metadata["StackStatus"] = "CREATE_IN_PROGRESS" self.metadata["CreationTime"] = self.metadata.get("CreationTime") or timestamp_millis() # maps resource id to resource state self._resource_states = {} # list of stack events self.events = [] # list of stack change sets self.change_sets = []
def get_function_event_invoke_config(self): response = {} if self.max_retry_attempts is not None: response["MaximumRetryAttempts"] = self.max_retry_attempts if self.max_event_age is not None: response["MaximumEventAgeInSeconds"] = self.max_event_age if self.on_successful_invocation or self.on_failed_invocation: response["DestinationConfig"] = {} if self.on_successful_invocation: response["DestinationConfig"].update( {"OnSuccess": { "Destination": self.on_successful_invocation }}) if self.on_failed_invocation: response["DestinationConfig"].update( {"OnFailure": { "Destination": self.on_failed_invocation }}) if not response: return None response.update({ "LastModified": timestamp_millis(self.last_modified), "FunctionArn": str(self.id), }) return response
def set_resource_status(self, resource_id: str, status: str, physical_res_id: str = None): """Update the deployment status of the given resource ID and publish a corresponding stack event.""" self._set_resource_status_details(resource_id, physical_res_id=physical_res_id) state = self.resource_states.setdefault(resource_id, {}) state["PreviousResourceStatus"] = state.get("ResourceStatus") state["ResourceStatus"] = status state["LastUpdatedTimestamp"] = timestamp_millis() self.add_stack_event(resource_id, physical_res_id, status)
def list_templates(self, context: RequestContext, next_token: NextToken = None, max_items: MaxItems = None) -> ListTemplatesResponse: for template in ses_backend.list_templates(): if isinstance(template["Timestamp"], (date, datetime)): template["Timestamp"] = timestamp_millis(template["Timestamp"]) return call_moto(context)
def add_stack_event(self, resource_id: str, physical_res_id: str, status: str): event = { "EventId": long_uid(), "Timestamp": timestamp_millis(), "StackId": self.stack_id, "StackName": self.stack_name, "LogicalResourceId": resource_id, "PhysicalResourceId": physical_res_id, "ResourceStatus": status, "ResourceType": "AWS::CloudFormation::Stack", } self.events.insert(0, event)
def lambda_result_to_destination( func_details: LambdaFunction, event: Dict, result: InvocationResult, is_async: bool, error: InvocationException, ): if not func_details.destination_enabled(): return payload = { "version": "1.0", "timestamp": timestamp_millis(), "requestContext": { "requestId": long_uid(), "functionArn": func_details.arn(), "condition": "RetriesExhausted", "approximateInvokeCount": 1, }, "requestPayload": event, "responseContext": { "statusCode": 200, "executedVersion": "$LATEST" }, "responsePayload": {}, } if result and result.result: try: payload["requestContext"]["condition"] = "Success" payload["responsePayload"] = json.loads(result.result) except Exception: payload["responsePayload"] = result.result if error: payload["responseContext"]["functionError"] = "Unhandled" # add the result in the response payload if error.result is not None: payload["responsePayload"] = json.loads(error.result) send_event_to_target(func_details.on_failed_invocation, payload) return if func_details.on_successful_invocation is not None: send_event_to_target(func_details.on_successful_invocation, payload)
def set_time_attribute(self, attribute, new_time=None): self.metadata[attribute] = new_time or timestamp_millis()