| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | import json | 
					
						
							|  |  |  | import boto3 | 
					
						
							|  |  |  | import botocore | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | import sure  # noqa # pylint: disable=unused-import | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | from moto import mock_cloudformation, mock_s3 | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  | from tests import EXAMPLE_AMI_ID | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | json_template = { | 
					
						
							|  |  |  |     "AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  |     "Description": "Stack 1", | 
					
						
							|  |  |  |     "Resources": { | 
					
						
							|  |  |  |         "EC2Instance1": { | 
					
						
							|  |  |  |             "Type": "AWS::EC2::Instance", | 
					
						
							|  |  |  |             "Properties": { | 
					
						
							| 
									
										
										
										
											2021-01-13 09:02:11 +00:00
										 |  |  |                 "ImageId": EXAMPLE_AMI_ID, | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  |                 "KeyName": "dummy", | 
					
						
							|  |  |  |                 "InstanceType": "t2.micro", | 
					
						
							|  |  |  |                 "Tags": [ | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |                     {"Key": "Description", "Value": "Test tag"}, | 
					
						
							|  |  |  |                     {"Key": "Name", "Value": "Name tag for tests"}, | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-30 22:35:47 +01:00
										 |  |  | json_valid_template_with_tabs = """
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | \t"AWSTemplateFormatVersion": "2010-09-09", | 
					
						
							|  |  |  | \t"Description": "Stack 2", | 
					
						
							|  |  |  | \t"Resources": { | 
					
						
							|  |  |  | \t\t"Queue": {"Type": "AWS::SQS::Queue", "Properties": {"VisibilityTimeout": 60}} | 
					
						
							|  |  |  | \t} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | # One resource is required | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | json_bad_template = {"AWSTemplateFormatVersion": "2010-09-09", "Description": "Stack 1"} | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | dummy_template_json = json.dumps(json_template) | 
					
						
							|  |  |  | dummy_bad_template_json = json.dumps(json_bad_template) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_boto3_json_validate_successful(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     cf_conn = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							|  |  |  |     response = cf_conn.validate_template(TemplateBody=dummy_template_json) | 
					
						
							|  |  |  |     assert response["Description"] == "Stack 1" | 
					
						
							|  |  |  |     assert response["Parameters"] == [] | 
					
						
							|  |  |  |     assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-30 22:35:47 +01:00
										 |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_boto3_json_with_tabs_validate_successful(): | 
					
						
							|  |  |  |     cf_conn = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							|  |  |  |     response = cf_conn.validate_template(TemplateBody=json_valid_template_with_tabs) | 
					
						
							|  |  |  |     assert response["Description"] == "Stack 2" | 
					
						
							|  |  |  |     assert response["Parameters"] == [] | 
					
						
							|  |  |  |     assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_boto3_json_invalid_missing_resource(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     cf_conn = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         cf_conn.validate_template(TemplateBody=dummy_bad_template_json) | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  |         assert False | 
					
						
							|  |  |  |     except botocore.exceptions.ClientError as e: | 
					
						
							| 
									
										
										
										
											2020-05-24 02:51:45 -05:00
										 |  |  |         str(e).should.contain( | 
					
						
							|  |  |  |             "An error occurred (ValidationError) when calling the ValidateTemplate operation: Stack" | 
					
						
							|  |  |  |             " with id Missing top level" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  |         assert True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | yaml_template = """
 | 
					
						
							|  |  |  |     AWSTemplateFormatVersion: '2010-09-09' | 
					
						
							|  |  |  |     Description: Simple CloudFormation Test Template | 
					
						
							|  |  |  |     Resources: | 
					
						
							|  |  |  |       S3Bucket: | 
					
						
							|  |  |  |         Type: AWS::S3::Bucket | 
					
						
							|  |  |  |         Properties: | 
					
						
							|  |  |  |           AccessControl: PublicRead | 
					
						
							|  |  |  |           BucketName: cf-test-bucket-1 | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | yaml_bad_template = """
 | 
					
						
							|  |  |  |     AWSTemplateFormatVersion: '2010-09-09' | 
					
						
							|  |  |  |     Description: Simple CloudFormation Test Template | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_boto3_yaml_validate_successful(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     cf_conn = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							|  |  |  |     response = cf_conn.validate_template(TemplateBody=yaml_template) | 
					
						
							|  |  |  |     assert response["Description"] == "Simple CloudFormation Test Template" | 
					
						
							|  |  |  |     assert response["Parameters"] == [] | 
					
						
							|  |  |  |     assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 14:01:57 +01:00
										 |  |  | @mock_cloudformation | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_boto3_yaml_validate_template_url_successful(): | 
					
						
							| 
									
										
										
										
											2020-08-27 05:11:47 -04:00
										 |  |  |     s3 = boto3.client("s3", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2020-06-26 14:01:57 +01:00
										 |  |  |     s3_conn = boto3.resource("s3", region_name="us-east-1") | 
					
						
							|  |  |  |     s3_conn.create_bucket(Bucket="foobar") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3_conn.Object("foobar", "template-key").put(Body=yaml_template) | 
					
						
							|  |  |  |     key_url = s3.generate_presigned_url( | 
					
						
							|  |  |  |         ClientMethod="get_object", Params={"Bucket": "foobar", "Key": "template-key"} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cf_conn = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							|  |  |  |     response = cf_conn.validate_template(TemplateURL=key_url) | 
					
						
							|  |  |  |     assert response["Description"] == "Simple CloudFormation Test Template" | 
					
						
							|  |  |  |     assert response["Parameters"] == [] | 
					
						
							|  |  |  |     assert response["ResponseMetadata"]["HTTPStatusCode"] == 200 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  | @mock_cloudformation | 
					
						
							|  |  |  | def test_boto3_yaml_invalid_missing_resource(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     cf_conn = boto3.client("cloudformation", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         cf_conn.validate_template(TemplateBody=yaml_bad_template) | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  |         assert False | 
					
						
							|  |  |  |     except botocore.exceptions.ClientError as e: | 
					
						
							| 
									
										
										
										
											2020-05-24 02:51:45 -05:00
										 |  |  |         str(e).should.contain( | 
					
						
							|  |  |  |             "An error occurred (ValidationError) when calling the ValidateTemplate operation: Stack" | 
					
						
							|  |  |  |             " with id Missing top level" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2018-11-02 16:04:17 -07:00
										 |  |  |         assert True |