Best Python code snippet using localstack_python
template_deployer.py
Source:template_deployer.py
...162 % (resource_id, resource, resources)163 )164 try:165 # convert resource props to resource entity166 instance = get_resource_model_instance(resource_id, resources)167 if instance:168 state = instance.fetch_and_update_state(stack_name=stack_name, resources=resources)169 return state170 # special case for stack parameters171 if resource_type == "Parameter":172 return resource_props173 # fallback: try accessing stack.moto_resource_statuses174 stack = find_stack(stack_name)175 moto_resource = stack.moto_resource_statuses.get(resource_id)176 if moto_resource:177 return moto_resource178 # if is_deployable_resource(resource):179 LOG.warning(180 "Unexpected resource type %s when resolving references of resource %s: %s"181 % (resource_type, resource_id, resource)182 )183 except DependencyNotYetSatisfied:184 return185 except Exception as e:186 check_not_found_exception(e, resource_type, resource, resource_status)187 return None188def check_not_found_exception(e, resource_type, resource, resource_status=None):189 # we expect this to be a "not found" exception190 markers = [191 "NoSuchBucket",192 "ResourceNotFound",193 "NoSuchEntity",194 "NotFoundException",195 "404",196 "not found",197 "not exist",198 ]199 if not list(filter(lambda marker, e=e: marker in str(e), markers)):200 LOG.warning(201 "Unexpected error retrieving details for resource type %s: Exception: %s - %s - status: %s"202 % (resource_type, e, resource, resource_status)203 )204 return False205 return True206def extract_resource_attribute(207 resource_type,208 resource_state,209 attribute,210 resource_id=None,211 resource=None,212 resources=None,213 stack_name=None,214):215 LOG.debug("Extract resource attribute: %s %s" % (resource_type, attribute))216 is_ref_attribute = attribute in ["PhysicalResourceId", "Ref"]217 is_ref_attr_or_arn = is_ref_attribute or attribute == "Arn"218 resource = resource or {}219 if not resource and resources:220 resource = resources[resource_id]221 if not resource_state:222 resource_state = retrieve_resource_details(resource_id, {}, resources, stack_name)223 if not resource_state:224 raise DependencyNotYetSatisfied(225 resource_ids=resource_id,226 message='Unable to fetch details for resource "%s" (attribute "%s")'227 % (resource_id, attribute),228 )229 if isinstance(resource_state, MotoCloudFormationModel):230 if is_ref_attribute:231 res_phys_id = getattr(resource_state, "physical_resource_id", None)232 get_res_phys_id = getattr(resource_state, "get_physical_resource_id", None)233 if not res_phys_id and get_res_phys_id:234 res_phys_id = get_res_phys_id(attribute)235 if res_phys_id:236 return res_phys_id237 if hasattr(resource_state, "get_cfn_attribute"):238 try:239 return resource_state.get_cfn_attribute(attribute)240 except Exception:241 pass242 raise Exception(243 'Unable to extract attribute "%s" from "%s" model class %s'244 % (attribute, resource_type, type(resource_state))245 )246 # extract resource specific attributes247 # TODO: remove the code below - move into resource model classes!248 resource_props = resource.get("Properties", {})249 if resource_type == "Parameter":250 result = None251 param_value = resource_props.get(252 "Value",253 resource.get("Value", resource_props.get("Properties", {}).get("Value")),254 )255 if is_ref_attr_or_arn:256 result = param_value257 elif isinstance(param_value, dict):258 result = param_value.get(attribute)259 if result is not None:260 return result261 return ""262 elif resource_type == "Lambda::Function":263 func_configs = resource_state.get("Configuration") or {}264 if is_ref_attr_or_arn:265 func_arn = func_configs.get("FunctionArn")266 if func_arn:267 return resolve_refs_recursively(stack_name, func_arn, resources)268 func_name = resolve_refs_recursively(269 stack_name, func_configs.get("FunctionName"), resources270 )271 return aws_stack.lambda_function_arn(func_name)272 else:273 return func_configs.get(attribute)274 elif resource_type == "Lambda::Version":275 if resource_state.get("Version"):276 return "%s:%s" % (277 resource_state.get("FunctionArn"),278 resource_state.get("Version").split(":")[-1],279 )280 elif resource_type == "DynamoDB::Table":281 actual_attribute = "LatestStreamArn" if attribute == "StreamArn" else attribute282 value = resource_state.get("Table", {}).get(actual_attribute)283 if value:284 return value285 elif resource_type == "ApiGateway::RestApi":286 if is_ref_attribute:287 result = resource_state.get("id")288 if result:289 return result290 if attribute == "RootResourceId":291 api_id = resource_state["id"]292 resources = aws_stack.connect_to_service("apigateway").get_resources(restApiId=api_id)[293 "items"294 ]295 for res in resources:296 if res["path"] == "/" and not res.get("parentId"):297 return res["id"]298 elif resource_type == "ApiGateway::Resource":299 if is_ref_attribute:300 return resource_state.get("id")301 elif resource_type == "ApiGateway::Deployment":302 if is_ref_attribute:303 return resource_state.get("id")304 elif resource_type == "S3::Bucket":305 if attribute == "WebsiteURL":306 bucket_name = resource_props.get("BucketName")307 return f"http://{bucket_name}.{S3_STATIC_WEBSITE_HOSTNAME}"308 if is_ref_attr_or_arn:309 bucket_name = resource_props.get("BucketName")310 bucket_name = resolve_refs_recursively(stack_name, bucket_name, resources)311 if attribute == "Arn":312 return aws_stack.s3_bucket_arn(bucket_name)313 return bucket_name314 elif resource_type == "Elasticsearch::Domain":315 if attribute == "DomainEndpoint":316 domain_status = resource_state.get("DomainStatus", {})317 result = domain_status.get("Endpoint")318 if result:319 return result320 if attribute in ["Arn", "DomainArn"]:321 domain_name = resource_props.get("DomainName") or resource_state.get("DomainName")322 return aws_stack.es_domain_arn(domain_name)323 elif resource_type == "StepFunctions::StateMachine":324 if is_ref_attr_or_arn:325 return resource_state["stateMachineArn"]326 elif resource_type == "SNS::Topic":327 if is_ref_attribute and resource_state.get("TopicArn"):328 topic_arn = resource_state.get("TopicArn")329 return resolve_refs_recursively(stack_name, topic_arn, resources)330 elif resource_type == "SQS::Queue":331 if is_ref_attr_or_arn:332 if attribute == "Arn" and resource_state.get("QueueArn"):333 return resolve_refs_recursively(334 stack_name, resource_state.get("QueueArn"), resources335 )336 return aws_stack.get_sqs_queue_url(resource_props.get("QueueName"))337 attribute_lower = common.first_char_to_lower(attribute)338 result = resource_state.get(attribute) or resource_state.get(attribute_lower)339 if result is None and isinstance(resource, dict):340 result = resource_props.get(attribute) or resource_props.get(attribute_lower)341 if result is None:342 result = get_attr_from_model_instance(343 resource,344 attribute,345 resource_type=resource_type,346 resource_id=resource_id,347 )348 if is_ref_attribute:349 for attr in ["Id", "PhysicalResourceId", "Ref"]:350 if result is None:351 for obj in [resource_state, resource]:352 result = result or obj.get(attr)353 return result354def canonical_resource_type(resource_type):355 if "::" in resource_type and not resource_type.startswith("AWS::"):356 resource_type = "AWS::%s" % resource_type357 return resource_type358def get_attr_from_model_instance(resource, attribute, resource_type, resource_id=None):359 resource_type = canonical_resource_type(resource_type)360 model_class = RESOURCE_MODELS.get(resource_type)361 if not model_class:362 if resource_type not in ["AWS::Parameter", "Parameter"]:363 LOG.debug('Unable to find model class for resource type "%s"' % resource_type)364 return365 try:366 inst = model_class(resource_name=resource_id, resource_json=resource)367 return inst.get_cfn_attribute(attribute)368 except Exception:369 pass370def resolve_ref(stack_name, ref, resources, attribute):371 if ref == "AWS::Region":372 return aws_stack.get_region()373 if ref == "AWS::Partition":374 return "aws"375 if ref == "AWS::StackName":376 return stack_name377 if ref == "AWS::StackId":378 # TODO return proper stack id!379 return stack_name380 if ref == "AWS::AccountId":381 return TEST_AWS_ACCOUNT_ID382 if ref == "AWS::NoValue":383 return PLACEHOLDER_AWS_NO_VALUE384 if ref == "AWS::NotificationARNs":385 # TODO!386 return {}387 if ref == "AWS::URLSuffix":388 return AWS_URL_SUFFIX389 is_ref_attribute = attribute in ["Ref", "PhysicalResourceId", "Arn"]390 if is_ref_attribute:391 # extract the Properties here, as we only want to recurse over the resource props...392 resource_props = resources.get(ref, {}).get("Properties")393 resolve_refs_recursively(stack_name, resource_props, resources)394 return determine_resource_physical_id(395 resource_id=ref,396 resources=resources,397 attribute=attribute,398 stack_name=stack_name,399 )400 if resources.get(ref):401 if isinstance(resources[ref].get(attribute), (str, int, float, bool, dict)):402 return resources[ref][attribute]403 # fetch resource details404 resource_new = retrieve_resource_details(ref, {}, resources, stack_name)405 if not resource_new:406 raise DependencyNotYetSatisfied(407 resource_ids=ref,408 message='Unable to fetch details for resource "%s" (resolving attribute "%s")'409 % (ref, attribute),410 )411 resource = resources.get(ref)412 resource_type = get_resource_type(resource)413 result = extract_resource_attribute(414 resource_type,415 resource_new,416 attribute,417 resource_id=ref,418 resource=resource,419 resources=resources,420 stack_name=stack_name,421 )422 if result is None:423 LOG.warning(424 'Unable to extract reference attribute "%s" from resource: %s %s'425 % (attribute, resource_new, resource)426 )427 return result428# Using a @prevent_stack_overflow decorator here to avoid infinite recursion429# in case we load stack exports that have circular dependencies (see issue 3438)430# TODO: Potentially think about a better approach in the future431@prevent_stack_overflow(match_parameters=True)432def resolve_refs_recursively(stack_name, value, resources):433 if isinstance(value, dict):434 keys_list = list(value.keys())435 stripped_fn_lower = keys_list[0].lower().split("::")[-1] if len(keys_list) == 1 else None436 # process special operators437 if keys_list == ["Ref"]:438 ref = resolve_ref(stack_name, value["Ref"], resources, attribute="Ref")439 if ref is None:440 msg = 'Unable to resolve Ref for resource "%s" (yet)' % value["Ref"]441 LOG.debug("%s - %s" % (msg, resources.get(value["Ref"]) or set(resources.keys())))442 raise DependencyNotYetSatisfied(resource_ids=value["Ref"], message=msg)443 ref = resolve_refs_recursively(stack_name, ref, resources)444 return ref445 if stripped_fn_lower == "getatt":446 attr_ref = value[keys_list[0]]447 attr_ref = attr_ref.split(".") if isinstance(attr_ref, str) else attr_ref448 return resolve_ref(stack_name, attr_ref[0], resources, attribute=attr_ref[1])449 if stripped_fn_lower == "join":450 join_values = value[keys_list[0]][1]451 join_values = [resolve_refs_recursively(stack_name, v, resources) for v in join_values]452 none_values = [v for v in join_values if v is None]453 if none_values:454 raise Exception(455 "Cannot resolve CF fn::Join %s due to null values: %s" % (value, join_values)456 )457 return value[keys_list[0]][0].join([str(v) for v in join_values])458 if stripped_fn_lower == "sub":459 item_to_sub = value[keys_list[0]]460 attr_refs = dict([(r, {"Ref": r}) for r in STATIC_REFS])461 if not isinstance(item_to_sub, list):462 item_to_sub = [item_to_sub, {}]463 result = item_to_sub[0]464 item_to_sub[1].update(attr_refs)465 for key, val in item_to_sub[1].items():466 val = resolve_refs_recursively(stack_name, val, resources)467 result = result.replace("${%s}" % key, val)468 # resolve placeholders469 result = resolve_placeholders_in_string(470 result, stack_name=stack_name, resources=resources471 )472 return result473 if stripped_fn_lower == "findinmap":474 attr = resolve_refs_recursively(stack_name, value[keys_list[0]][1], resources)475 result = resolve_ref(stack_name, value[keys_list[0]][0], resources, attribute=attr)476 if not result:477 raise Exception(478 "Cannot resolve fn::FindInMap: %s %s"479 % (value[keys_list[0]], list(resources.keys()))480 )481 key = value[keys_list[0]][2]482 if not isinstance(key, str):483 key = resolve_refs_recursively(stack_name, key, resources)484 return result.get(key)485 if stripped_fn_lower == "importvalue":486 import_value_key = resolve_refs_recursively(stack_name, value[keys_list[0]], resources)487 stack = find_stack(stack_name)488 stack_export = stack.exports_map.get(import_value_key) or {}489 if not stack_export.get("Value"):490 LOG.info(491 'Unable to find export "%s" in stack "%s", existing export names: %s'492 % (import_value_key, stack_name, list(stack.exports_map.keys()))493 )494 return None495 return stack_export["Value"]496 if stripped_fn_lower == "if":497 condition, option1, option2 = value[keys_list[0]]498 condition = evaluate_condition(stack_name, condition, resources)499 return resolve_refs_recursively(500 stack_name, option1 if condition else option2, resources501 )502 if stripped_fn_lower == "condition":503 result = evaluate_condition(stack_name, value[keys_list[0]], resources)504 return result505 if stripped_fn_lower == "not":506 condition = value[keys_list[0]][0]507 condition = resolve_refs_recursively(stack_name, condition, resources)508 return not condition509 if stripped_fn_lower in ["and", "or"]:510 conditions = value[keys_list[0]]511 results = [resolve_refs_recursively(stack_name, cond, resources) for cond in conditions]512 result = all(results) if stripped_fn_lower == "and" else any(results)513 return result514 if stripped_fn_lower == "equals":515 operand1, operand2 = value[keys_list[0]]516 operand1 = resolve_refs_recursively(stack_name, operand1, resources)517 operand2 = resolve_refs_recursively(stack_name, operand2, resources)518 return str(operand1) == str(operand2)519 if stripped_fn_lower == "select":520 index, values = value[keys_list[0]]521 index = resolve_refs_recursively(stack_name, index, resources)522 values = resolve_refs_recursively(stack_name, values, resources)523 return values[index]524 if stripped_fn_lower == "split":525 delimiter, string = value[keys_list[0]]526 delimiter = resolve_refs_recursively(stack_name, delimiter, resources)527 string = resolve_refs_recursively(stack_name, string, resources)528 return string.split(delimiter)529 if stripped_fn_lower == "getazs":530 region = (531 resolve_refs_recursively(stack_name, value["Fn::GetAZs"], resources)532 or aws_stack.get_region()533 )534 azs = []535 for az in ("a", "b", "c", "d"):536 azs.append("%s%s" % (region, az))537 return azs538 if stripped_fn_lower == "base64":539 value_to_encode = value[keys_list[0]]540 value_to_encode = resolve_refs_recursively(stack_name, value_to_encode, resources)541 return to_str(base64.b64encode(to_bytes(value_to_encode)))542 for key, val in dict(value).items():543 value[key] = resolve_refs_recursively(stack_name, val, resources)544 if isinstance(value, list):545 for i in range(len(value)):546 value[i] = resolve_refs_recursively(stack_name, value[i], resources)547 return value548def resolve_placeholders_in_string(result, stack_name=None, resources=None):549 def _replace(match):550 parts = match.group(1).split(".")551 if len(parts) >= 2:552 resource_name, _, attr_name = match.group(1).partition(".")553 resolved = resolve_ref(554 stack_name, resource_name.strip(), resources, attribute=attr_name.strip()555 )556 if resolved is None:557 raise DependencyNotYetSatisfied(558 resource_ids=resource_name,559 message="Unable to resolve attribute ref %s" % match.group(1),560 )561 return resolved562 if len(parts) == 1 and parts[0] in resources:563 resource_json = resources[parts[0]]564 resource_type = get_resource_type(resource_json)565 result = extract_resource_attribute(566 resource_type,567 {},568 "Ref",569 resources=resources,570 resource_id=parts[0],571 stack_name=stack_name,572 )573 if result is None:574 raise DependencyNotYetSatisfied(575 resource_ids=parts[0],576 message="Unable to resolve attribute ref %s" % match.group(1),577 )578 return result579 # TODO raise exception here?580 return match.group(0)581 regex = r"\$\{([^\}]+)\}"582 result = re.sub(regex, _replace, result)583 return result584def evaluate_condition(stack_name, condition, resources):585 condition = resolve_refs_recursively(stack_name, condition, resources)586 condition = resolve_ref(stack_name, condition, resources, attribute="Ref")587 condition = resolve_refs_recursively(stack_name, condition, resources)588 return condition589def evaluate_resource_condition(resource, stack_name, resources):590 condition = resource.get("Condition")591 if condition:592 condition = evaluate_condition(stack_name, condition, resources)593 if condition is False or condition in FALSE_STRINGS or is_none_or_empty_value(condition):594 return False595 return True596def get_stack_parameter(stack_name, parameter):597 try:598 client = aws_stack.connect_to_service("cloudformation")599 stack = client.describe_stacks(StackName=stack_name)["Stacks"]600 except Exception:601 return None602 stack = stack and stack[0]603 if not stack:604 return None605 result = [p["ParameterValue"] for p in stack["Parameters"] if p["ParameterKey"] == parameter]606 return (result or [None])[0]607def update_resource(resource_id, resources, stack_name):608 resource = resources[resource_id]609 resource_type = get_resource_type(resource)610 if resource_type not in UPDATEABLE_RESOURCES:611 LOG.warning('Unable to update resource type "%s", id "%s"' % (resource_type, resource_id))612 return613 LOG.info("Updating resource %s of type %s" % (resource_id, resource_type))614 instance = get_resource_model_instance(resource_id, resources)615 if instance:616 result = instance.update_resource(resource, stack_name=stack_name, resources=resources)617 instance.fetch_and_update_state(stack_name=stack_name, resources=resources)618 return result619def get_resource_model_instance(resource_id: str, resources) -> Optional[GenericBaseModel]:620 """Obtain a typed resource entity instance representing the given stack resource."""621 resource = resources[resource_id]622 resource_type = get_resource_type(resource)623 canonical_type = canonical_resource_type(resource_type)624 resource_class = RESOURCE_MODELS.get(canonical_type)625 if not resource_class:626 return None627 instance = resource_class(resource)628 return instance629def fix_account_id_in_arns(params):630 def fix_ids(o, **kwargs):631 if isinstance(o, dict):632 for k, v in o.items():633 if common.is_string(v, exclude_binary=True):...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!