def test_invalid_url(self): url = "someweirdurl/wheretheresnoprotocol/justcoz" adapter = Boto3Client("123456789", "eu-west-1", "stack-id") with pytest.raises(InvalidURLException): adapter.download_template_to_dictionary(url)
def get_template(event): try: account_id = event.get("account", {}).get("id") region = event.get("region") stack_name = event.get("stack", {}).get("name") boto3_client = Boto3Client(account_id, region, stack_name) except Exception: boto3_client = None logger.exception("Could not create Boto3 Cloudformation Client...") template = None if boto3_client: try: if event.get("stack_template_url"): template = boto3_client.download_template_to_dictionary( event["stack_template_url"]) else: logger.info(f"stack_template_url not available") except Exception: logger.exception( f"Error calling download_template_to_dictionary for: {stack_name} on {account_id} - {region}" ) if not template: try: template = boto3_client.get_template() except Exception: logger.exception( f"Error calling get_template for: {stack_name} on {account_id} - {region}" ) return template
def test_get_template(self, aws_responses, expected_template): adapter = Boto3Client("123456789", "eu-west-1", "stack-id") with patch.object(adapter, "session") as session_mock: session_mock.client().get_template( ).get.side_effect = aws_responses template = adapter.get_template() assert template == expected_template
def test_export_values(boto3_client: Boto3Client): cf_client = boto3_client.session.client("cloudformation", "eu-west-1") cf_client.create_stack( StackName="Test-Stack", TemplateBody=json.dumps({ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "MyQueue": { "Type": "AWS::SQS::Queue", "Properties": {} } }, "Outputs": { "QueueARN": { "Description": "ARN of newly created SQS Queue", "Value": { "Fn::GetAtt": ["MyQueue", "Arn"] }, "Export": { "Name": "MainQueue" }, }, }, }), ) # actual suffix changes between tests export_values = boto3_client.get_exports() assert len(export_values) == 1 assert "arn:aws:sqs:eu-west-1:123456789012:Test-Stack-MyQueue-" in export_values[ "MainQueue"]
def test_valid_yaml(self): yaml_content = """ hello: this is valid\n\r """ bucket = "cf-templates-1234" filename = "myexamplestack.yml" self.set_s3_file(bucket, filename, yaml_content) url = f"https://s3-eu-west-1.amazonaws.com/{bucket}/{filename}" adapter = Boto3Client("123456789", "eu-west-1", "stack-id") result = adapter.download_template_to_dictionary(url) assert result["hello"] == "this is valid"
def test_valid_yaml_with_cf_getatt_dotsyntax(self): yaml_content = """ myprop: !GetAtt hello.world\n\r """ bucket = "cf-templates-1234" filename = "myexamplestack.yml" self.set_s3_file(bucket, filename, yaml_content) url = f"https://s3-eu-west-1.amazonaws.com/{bucket}/{filename}" adapter = Boto3Client("123456789", "eu-west-1", "stack-id") result = adapter.download_template_to_dictionary(url) assert result["myprop"] == {"Fn::GetAtt": ["hello", "world"]}
def test_valid_yaml_with_cf_shorthand_join(self): yaml_content = """ myprop: !Join ['-', ['hello', 'world']]\n\r """ bucket = "cf-templates-1234" filename = "myexamplestack.yml" self.set_s3_file(bucket, filename, yaml_content) url = f"https://s3-eu-west-1.amazonaws.com/{bucket}/{filename}" adapter = Boto3Client("123456789", "eu-west-1", "stack-id") result = adapter.download_template_to_dictionary(url) assert result["myprop"] == {"Fn::Join": ["-", ["hello", "world"]]}
def test_valid_yaml_with_cf_shorthand_ref(self): yaml_content = """ myprop: !Ref hello\n\r """ bucket = "cf-templates-1234" filename = "myexamplestack.yml" self.set_s3_file(bucket, filename, yaml_content) url = f"https://s3-eu-west-1.amazonaws.com/{bucket}/{filename}" adapter = Boto3Client("123456789", "eu-west-1", "stack-id") result = adapter.download_template_to_dictionary(url) assert result["myprop"] == {"Ref": "hello"}
def test_urlencoded_url(self): json_content = """ { "hello": "this is valid json" } """ bucket = "cf-templates-1234" filename = "2017284ltK-adfs%20iam%20role.json" self.set_s3_file(bucket, "2017284ltK-adfs iam role.json", json_content) url = f"https://s3-eu-west-1.amazonaws.com/{bucket}/{filename}" adapter = Boto3Client("123456789", "eu-west-1", "stack-id") result = adapter.download_template_to_dictionary(url) assert result["hello"] == "this is valid json"
def test_url_with_path_prefix(self): json_content = """ { "hello": "this is valid json" } """ bucket = "cf-templates-1234" filename = "myprefixes/aaaaaa/myexamplestack.json" self.set_s3_file(bucket, filename, json_content) url = f"https://s3-eu-west-1.amazonaws.com/{bucket}/{filename}" adapter = Boto3Client("123456789", "eu-west-1", "stack-id") result = adapter.download_template_to_dictionary(url) assert result["hello"] == "this is valid json"
def test_invalid_format(self): invalid_content = """ { 'asdf': 'asdf' 'asd': 'asd' """ bucket = "cf-templates-1234" filename = "myexamplestack.yml" self.set_s3_file(bucket, filename, invalid_content) url = f"https://s3-eu-west-1.amazonaws.com/{bucket}/{filename}" adapter = Boto3Client("123456789", "eu-west-1", "stack-id") assert adapter.download_template_to_dictionary(url) is None
def boto3_client(default_aws_region): with mock_sts(): yield Boto3Client("123456789", default_aws_region, "stack-id")
def boto3_client(): with mock_sts(): yield Boto3Client("123456789", "eu-west-1", "stack-id")