| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  | from copy import deepcopy | 
					
						
							| 
									
										
										
										
											2019-12-20 10:54:38 +01:00
										 |  |  | from datetime import datetime | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import boto3 | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | import sure  # noqa # pylint: disable=unused-import | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  | from botocore.exceptions import ClientError | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  | import pytest | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | from moto import mock_codepipeline, mock_iam | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  | expected_pipeline_details = { | 
					
						
							|  |  |  |     "name": "test-pipeline", | 
					
						
							|  |  |  |     "roleArn": "arn:aws:iam::123456789012:role/test-role", | 
					
						
							|  |  |  |     "artifactStore": { | 
					
						
							|  |  |  |         "type": "S3", | 
					
						
							|  |  |  |         "location": "codepipeline-us-east-1-123456789012", | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     "stages": [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "name": "Stage-1", | 
					
						
							|  |  |  |             "actions": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "name": "Action-1", | 
					
						
							|  |  |  |                     "actionTypeId": { | 
					
						
							|  |  |  |                         "category": "Source", | 
					
						
							|  |  |  |                         "owner": "AWS", | 
					
						
							|  |  |  |                         "provider": "S3", | 
					
						
							|  |  |  |                         "version": "1", | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                     "runOrder": 1, | 
					
						
							|  |  |  |                     "configuration": { | 
					
						
							|  |  |  |                         "S3Bucket": "test-bucket", | 
					
						
							|  |  |  |                         "S3ObjectKey": "test-object", | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                     "outputArtifacts": [{"name": "artifact"}], | 
					
						
							|  |  |  |                     "inputArtifacts": [], | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "name": "Stage-2", | 
					
						
							|  |  |  |             "actions": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "name": "Action-1", | 
					
						
							|  |  |  |                     "actionTypeId": { | 
					
						
							|  |  |  |                         "category": "Approval", | 
					
						
							|  |  |  |                         "owner": "AWS", | 
					
						
							|  |  |  |                         "provider": "Manual", | 
					
						
							|  |  |  |                         "version": "1", | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                     "runOrder": 1, | 
					
						
							|  |  |  |                     "configuration": {}, | 
					
						
							|  |  |  |                     "outputArtifacts": [], | 
					
						
							|  |  |  |                     "inputArtifacts": [], | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ], | 
					
						
							|  |  |  |     "version": 1, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_create_pipeline(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     response = create_basic_codepipeline(client, "test-pipeline") | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  |     response["pipeline"].should.equal(expected_pipeline_details) | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  |     response["tags"].should.equal([{"key": "key", "value": "value"}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_codepipeline | 
					
						
							|  |  |  | @mock_iam | 
					
						
							|  |  |  | def test_create_pipeline_errors(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  |     client_iam = boto3.client("iam", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     create_basic_codepipeline(client, "test-pipeline") | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |         create_basic_codepipeline(client, "test-pipeline") | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  |     ex.operation_name.should.equal("CreatePipeline") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidStructureException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "A pipeline with the name 'test-pipeline' already exists in account '123456789012'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  |         client.create_pipeline( | 
					
						
							|  |  |  |             pipeline={ | 
					
						
							|  |  |  |                 "name": "invalid-pipeline", | 
					
						
							|  |  |  |                 "roleArn": "arn:aws:iam::123456789012:role/not-existing", | 
					
						
							|  |  |  |                 "artifactStore": { | 
					
						
							|  |  |  |                     "type": "S3", | 
					
						
							|  |  |  |                     "location": "codepipeline-us-east-1-123456789012", | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "stages": [ | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "name": "Stage-1", | 
					
						
							|  |  |  |                         "actions": [ | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                                 "name": "Action-1", | 
					
						
							|  |  |  |                                 "actionTypeId": { | 
					
						
							|  |  |  |                                     "category": "Source", | 
					
						
							|  |  |  |                                     "owner": "AWS", | 
					
						
							|  |  |  |                                     "provider": "S3", | 
					
						
							|  |  |  |                                     "version": "1", | 
					
						
							|  |  |  |                                 }, | 
					
						
							|  |  |  |                                 "runOrder": 1, | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                         ], | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  |     ex.operation_name.should.equal("CreatePipeline") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidStructureException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "CodePipeline is not authorized to perform AssumeRole on role arn:aws:iam::123456789012:role/not-existing" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     wrong_role_arn = client_iam.create_role( | 
					
						
							|  |  |  |         RoleName="wrong-role", | 
					
						
							|  |  |  |         AssumeRolePolicyDocument=json.dumps( | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Version": "2012-10-17", | 
					
						
							|  |  |  |                 "Statement": [ | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "Effect": "Allow", | 
					
						
							|  |  |  |                         "Principal": {"Service": "s3.amazonaws.com"}, | 
					
						
							|  |  |  |                         "Action": "sts:AssumeRole", | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |     )["Role"]["Arn"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  |         client.create_pipeline( | 
					
						
							|  |  |  |             pipeline={ | 
					
						
							|  |  |  |                 "name": "invalid-pipeline", | 
					
						
							|  |  |  |                 "roleArn": wrong_role_arn, | 
					
						
							|  |  |  |                 "artifactStore": { | 
					
						
							|  |  |  |                     "type": "S3", | 
					
						
							|  |  |  |                     "location": "codepipeline-us-east-1-123456789012", | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "stages": [ | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "name": "Stage-1", | 
					
						
							|  |  |  |                         "actions": [ | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                                 "name": "Action-1", | 
					
						
							|  |  |  |                                 "actionTypeId": { | 
					
						
							|  |  |  |                                     "category": "Source", | 
					
						
							|  |  |  |                                     "owner": "AWS", | 
					
						
							|  |  |  |                                     "provider": "S3", | 
					
						
							|  |  |  |                                     "version": "1", | 
					
						
							|  |  |  |                                 }, | 
					
						
							|  |  |  |                                 "runOrder": 1, | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                         ], | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  |     ex.operation_name.should.equal("CreatePipeline") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidStructureException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "CodePipeline is not authorized to perform AssumeRole on role arn:aws:iam::123456789012:role/wrong-role" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  |         client.create_pipeline( | 
					
						
							|  |  |  |             pipeline={ | 
					
						
							|  |  |  |                 "name": "invalid-pipeline", | 
					
						
							|  |  |  |                 "roleArn": get_role_arn(), | 
					
						
							|  |  |  |                 "artifactStore": { | 
					
						
							|  |  |  |                     "type": "S3", | 
					
						
							|  |  |  |                     "location": "codepipeline-us-east-1-123456789012", | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "stages": [ | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "name": "Stage-1", | 
					
						
							|  |  |  |                         "actions": [ | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                                 "name": "Action-1", | 
					
						
							|  |  |  |                                 "actionTypeId": { | 
					
						
							|  |  |  |                                     "category": "Source", | 
					
						
							|  |  |  |                                     "owner": "AWS", | 
					
						
							|  |  |  |                                     "provider": "S3", | 
					
						
							|  |  |  |                                     "version": "1", | 
					
						
							|  |  |  |                                 }, | 
					
						
							|  |  |  |                                 "runOrder": 1, | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                         ], | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-15 16:06:08 +01:00
										 |  |  |     ex.operation_name.should.equal("CreatePipeline") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidStructureException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Pipeline has only 1 stage(s). There should be a minimum of 2 stages in a pipeline" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 16:54:58 +01:00
										 |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_get_pipeline(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     create_basic_codepipeline(client, "test-pipeline") | 
					
						
							| 
									
										
										
										
											2019-12-15 16:54:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response = client.get_pipeline(name="test-pipeline") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  |     response["pipeline"].should.equal(expected_pipeline_details) | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  |     response["metadata"]["pipelineArn"].should.equal( | 
					
						
							|  |  |  |         "arn:aws:codepipeline:us-east-1:123456789012:test-pipeline" | 
					
						
							| 
									
										
										
										
											2019-12-15 16:54:58 +01:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  |     response["metadata"]["created"].should.be.a(datetime) | 
					
						
							|  |  |  |     response["metadata"]["updated"].should.be.a(datetime) | 
					
						
							| 
									
										
										
										
											2019-12-15 16:54:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_get_pipeline_errors(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-15 17:28:59 +01:00
										 |  |  |         client.get_pipeline(name="not-existing") | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-15 16:54:58 +01:00
										 |  |  |     ex.operation_name.should.equal("GetPipeline") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("PipelineNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Account '123456789012' does not have a pipeline with name 'not-existing'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 17:28:59 +01:00
										 |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_update_pipeline(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     create_basic_codepipeline(client, "test-pipeline") | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response = client.get_pipeline(name="test-pipeline") | 
					
						
							|  |  |  |     created_time = response["metadata"]["created"] | 
					
						
							|  |  |  |     updated_time = response["metadata"]["updated"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.update_pipeline( | 
					
						
							|  |  |  |         pipeline={ | 
					
						
							|  |  |  |             "name": "test-pipeline", | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |             "roleArn": get_role_arn(), | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  |             "artifactStore": { | 
					
						
							|  |  |  |                 "type": "S3", | 
					
						
							|  |  |  |                 "location": "codepipeline-us-east-1-123456789012", | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "stages": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "name": "Stage-1", | 
					
						
							|  |  |  |                     "actions": [ | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             "name": "Action-1", | 
					
						
							|  |  |  |                             "actionTypeId": { | 
					
						
							|  |  |  |                                 "category": "Source", | 
					
						
							|  |  |  |                                 "owner": "AWS", | 
					
						
							|  |  |  |                                 "provider": "S3", | 
					
						
							|  |  |  |                                 "version": "1", | 
					
						
							| 
									
										
										
										
											2019-12-15 17:28:59 +01:00
										 |  |  |                             }, | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  |                             "configuration": { | 
					
						
							|  |  |  |                                 "S3Bucket": "different-bucket", | 
					
						
							|  |  |  |                                 "S3ObjectKey": "test-object", | 
					
						
							|  |  |  |                             }, | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |                             "outputArtifacts": [{"name": "artifact"}], | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  |                         }, | 
					
						
							|  |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "name": "Stage-2", | 
					
						
							|  |  |  |                     "actions": [ | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             "name": "Action-1", | 
					
						
							|  |  |  |                             "actionTypeId": { | 
					
						
							|  |  |  |                                 "category": "Approval", | 
					
						
							|  |  |  |                                 "owner": "AWS", | 
					
						
							|  |  |  |                                 "provider": "Manual", | 
					
						
							|  |  |  |                                 "version": "1", | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-12-15 17:28:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response["pipeline"].should.equal( | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "name": "test-pipeline", | 
					
						
							|  |  |  |             "roleArn": "arn:aws:iam::123456789012:role/test-role", | 
					
						
							|  |  |  |             "artifactStore": { | 
					
						
							|  |  |  |                 "type": "S3", | 
					
						
							|  |  |  |                 "location": "codepipeline-us-east-1-123456789012", | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "stages": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "name": "Stage-1", | 
					
						
							|  |  |  |                     "actions": [ | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             "name": "Action-1", | 
					
						
							|  |  |  |                             "actionTypeId": { | 
					
						
							|  |  |  |                                 "category": "Source", | 
					
						
							|  |  |  |                                 "owner": "AWS", | 
					
						
							|  |  |  |                                 "provider": "S3", | 
					
						
							|  |  |  |                                 "version": "1", | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                             "runOrder": 1, | 
					
						
							|  |  |  |                             "configuration": { | 
					
						
							|  |  |  |                                 "S3Bucket": "different-bucket", | 
					
						
							|  |  |  |                                 "S3ObjectKey": "test-object", | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                             "outputArtifacts": [{"name": "artifact"}], | 
					
						
							|  |  |  |                             "inputArtifacts": [], | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "name": "Stage-2", | 
					
						
							|  |  |  |                     "actions": [ | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             "name": "Action-1", | 
					
						
							|  |  |  |                             "actionTypeId": { | 
					
						
							|  |  |  |                                 "category": "Approval", | 
					
						
							|  |  |  |                                 "owner": "AWS", | 
					
						
							|  |  |  |                                 "provider": "Manual", | 
					
						
							|  |  |  |                                 "version": "1", | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                             "runOrder": 1, | 
					
						
							|  |  |  |                             "configuration": {}, | 
					
						
							|  |  |  |                             "outputArtifacts": [], | 
					
						
							|  |  |  |                             "inputArtifacts": [], | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             "version": 2, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  |     metadata = client.get_pipeline(name="test-pipeline")["metadata"] | 
					
						
							|  |  |  |     metadata["created"].should.equal(created_time) | 
					
						
							|  |  |  |     metadata["updated"].should.be.greater_than(updated_time) | 
					
						
							| 
									
										
										
										
											2019-12-15 17:28:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_update_pipeline_errors(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-15 17:28:59 +01:00
										 |  |  |         client.update_pipeline( | 
					
						
							|  |  |  |             pipeline={ | 
					
						
							|  |  |  |                 "name": "not-existing", | 
					
						
							|  |  |  |                 "roleArn": get_role_arn(), | 
					
						
							|  |  |  |                 "artifactStore": { | 
					
						
							|  |  |  |                     "type": "S3", | 
					
						
							|  |  |  |                     "location": "codepipeline-us-east-1-123456789012", | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "stages": [ | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "name": "Stage-1", | 
					
						
							|  |  |  |                         "actions": [ | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                                 "name": "Action-1", | 
					
						
							|  |  |  |                                 "actionTypeId": { | 
					
						
							|  |  |  |                                     "category": "Source", | 
					
						
							|  |  |  |                                     "owner": "AWS", | 
					
						
							|  |  |  |                                     "provider": "S3", | 
					
						
							|  |  |  |                                     "version": "1", | 
					
						
							|  |  |  |                                 }, | 
					
						
							|  |  |  |                                 "configuration": { | 
					
						
							|  |  |  |                                     "S3Bucket": "test-bucket", | 
					
						
							|  |  |  |                                     "S3ObjectKey": "test-object", | 
					
						
							|  |  |  |                                 }, | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |                                 "outputArtifacts": [{"name": "artifact"}], | 
					
						
							| 
									
										
										
										
											2019-12-15 17:28:59 +01:00
										 |  |  |                             }, | 
					
						
							|  |  |  |                         ], | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "name": "Stage-2", | 
					
						
							|  |  |  |                         "actions": [ | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                                 "name": "Action-1", | 
					
						
							|  |  |  |                                 "actionTypeId": { | 
					
						
							|  |  |  |                                     "category": "Approval", | 
					
						
							|  |  |  |                                     "owner": "AWS", | 
					
						
							|  |  |  |                                     "provider": "Manual", | 
					
						
							|  |  |  |                                     "version": "1", | 
					
						
							|  |  |  |                                 }, | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                         ], | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-15 17:28:59 +01:00
										 |  |  |     ex.operation_name.should.equal("UpdatePipeline") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("ResourceNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The account with id '123456789012' does not include a pipeline with the name 'not-existing'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 17:44:54 +01:00
										 |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_list_pipelines(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     name_1 = "test-pipeline-1" | 
					
						
							|  |  |  |     create_basic_codepipeline(client, name_1) | 
					
						
							|  |  |  |     name_2 = "test-pipeline-2" | 
					
						
							|  |  |  |     create_basic_codepipeline(client, name_2) | 
					
						
							| 
									
										
										
										
											2019-12-15 17:44:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_pipelines() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  |     response["pipelines"].should.have.length_of(2) | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     response["pipelines"][0]["name"].should.equal(name_1) | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  |     response["pipelines"][0]["version"].should.equal(1) | 
					
						
							|  |  |  |     response["pipelines"][0]["created"].should.be.a(datetime) | 
					
						
							|  |  |  |     response["pipelines"][0]["updated"].should.be.a(datetime) | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     response["pipelines"][1]["name"].should.equal(name_2) | 
					
						
							| 
									
										
										
										
											2019-12-19 21:41:32 +01:00
										 |  |  |     response["pipelines"][1]["version"].should.equal(1) | 
					
						
							|  |  |  |     response["pipelines"][1]["created"].should.be.a(datetime) | 
					
						
							|  |  |  |     response["pipelines"][1]["updated"].should.be.a(datetime) | 
					
						
							| 
									
										
										
										
											2019-12-15 17:44:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-15 17:58:38 +01:00
										 |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_delete_pipeline(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     name = "test-pipeline" | 
					
						
							|  |  |  |     create_basic_codepipeline(client, name) | 
					
						
							|  |  |  |     client.list_pipelines()["pipelines"].should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.delete_pipeline(name=name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.list_pipelines()["pipelines"].should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # deleting a not existing pipeline, should raise no exception | 
					
						
							|  |  |  |     client.delete_pipeline(name=name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_list_tags_for_resource(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  |     name = "test-pipeline" | 
					
						
							|  |  |  |     create_basic_codepipeline(client, name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_tags_for_resource( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}" | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     ) | 
					
						
							|  |  |  |     response["tags"].should.equal([{"key": "key", "value": "value"}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_list_tags_for_resource_errors(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |         client.list_tags_for_resource( | 
					
						
							|  |  |  |             resourceArn="arn:aws:codepipeline:us-east-1:123456789012:not-existing" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     ex.operation_name.should.equal("ListTagsForResource") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("ResourceNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The account with id '123456789012' does not include a pipeline with the name 'not-existing'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_tag_resource(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  |     name = "test-pipeline" | 
					
						
							|  |  |  |     create_basic_codepipeline(client, name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.tag_resource( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}", | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |         tags=[{"key": "key-2", "value": "value-2"}], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_tags_for_resource( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}" | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |     ) | 
					
						
							|  |  |  |     response["tags"].should.equal( | 
					
						
							|  |  |  |         [{"key": "key", "value": "value"}, {"key": "key-2", "value": "value-2"}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_tag_resource_errors(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  |     name = "test-pipeline" | 
					
						
							|  |  |  |     create_basic_codepipeline(client, name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |         client.tag_resource( | 
					
						
							|  |  |  |             resourceArn="arn:aws:codepipeline:us-east-1:123456789012:not-existing", | 
					
						
							|  |  |  |             tags=[{"key": "key-2", "value": "value-2"}], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |     ex.operation_name.should.equal("TagResource") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("ResourceNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The account with id '123456789012' does not include a pipeline with the name 'not-existing'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |         client.tag_resource( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |             resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}", | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |             tags=[{"key": "aws:key", "value": "value"}], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |     ex.operation_name.should.equal("TagResource") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidTagsException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Not allowed to modify system tags. " | 
					
						
							|  |  |  |         "System tags start with 'aws:'. " | 
					
						
							|  |  |  |         "msg=[Caller is an end user and not allowed to mutate system tags]" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |         client.tag_resource( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |             resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}", | 
					
						
							|  |  |  |             tags=[{"key": f"key-{i}", "value": f"value-{i}"} for i in range(50)], | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |     ex.operation_name.should.equal("TagResource") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("TooManyTagsException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         f"Tag limit exceeded for resource [arn:aws:codepipeline:us-east-1:123456789012:{name}]." | 
					
						
							| 
									
										
										
										
											2019-12-23 19:33:37 +01:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-23 19:50:16 +01:00
										 |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_untag_resource(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  |     name = "test-pipeline" | 
					
						
							|  |  |  |     create_basic_codepipeline(client, name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_tags_for_resource( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}" | 
					
						
							| 
									
										
										
										
											2019-12-23 19:50:16 +01:00
										 |  |  |     ) | 
					
						
							|  |  |  |     response["tags"].should.equal([{"key": "key", "value": "value"}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.untag_resource( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}", | 
					
						
							| 
									
										
										
										
											2019-12-23 19:50:16 +01:00
										 |  |  |         tagKeys=["key"], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.list_tags_for_resource( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}" | 
					
						
							| 
									
										
										
										
											2019-12-23 19:50:16 +01:00
										 |  |  |     ) | 
					
						
							|  |  |  |     response["tags"].should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # removing a not existing tag should raise no exception | 
					
						
							|  |  |  |     client.untag_resource( | 
					
						
							| 
									
										
										
										
											2022-11-17 21:41:08 -01:00
										 |  |  |         resourceArn=f"arn:aws:codepipeline:us-east-1:123456789012:{name}", | 
					
						
							| 
									
										
										
										
											2019-12-23 19:50:16 +01:00
										 |  |  |         tagKeys=["key"], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_untag_resource_errors(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2019-12-23 19:50:16 +01:00
										 |  |  |         client.untag_resource( | 
					
						
							|  |  |  |             resourceArn="arn:aws:codepipeline:us-east-1:123456789012:not-existing", | 
					
						
							|  |  |  |             tagKeys=["key"], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-10-06 08:04:09 +02:00
										 |  |  |     ex = e.value | 
					
						
							| 
									
										
										
										
											2019-12-23 19:50:16 +01:00
										 |  |  |     ex.operation_name.should.equal("UntagResource") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("ResourceNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The account with id '123456789012' does not include a pipeline with the name 'not-existing'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  | simple_trust_policy = { | 
					
						
							|  |  |  |     "Version": "2012-10-17", | 
					
						
							|  |  |  |     "Statement": [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "Effect": "Allow", | 
					
						
							|  |  |  |             "Principal": {"Service": "codepipeline.amazonaws.com"}, | 
					
						
							|  |  |  |             "Action": "sts:AssumeRole", | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ], | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  | @mock_iam | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  | def get_role_arn(name="test-role", trust_policy=None): | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     client = boto3.client("iam", region_name="us-east-1") | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  |         return client.get_role(RoleName=name)["Role"]["Arn"] | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     except ClientError: | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  |         if trust_policy is None: | 
					
						
							|  |  |  |             trust_policy = simple_trust_policy | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |         return client.create_role( | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  |             RoleName=name, | 
					
						
							|  |  |  |             AssumeRolePolicyDocument=json.dumps(trust_policy), | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |         )["Role"]["Arn"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  | def create_basic_codepipeline(client, name, role_arn=None, tags=None): | 
					
						
							|  |  |  |     if role_arn is None: | 
					
						
							|  |  |  |         role_arn = get_role_arn() | 
					
						
							|  |  |  |     if tags is None: | 
					
						
							|  |  |  |         tags = [{"key": "key", "value": "value"}] | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |     return client.create_pipeline( | 
					
						
							| 
									
										
										
										
											2019-12-15 17:58:38 +01:00
										 |  |  |         pipeline={ | 
					
						
							| 
									
										
										
										
											2019-12-22 11:42:15 +01:00
										 |  |  |             "name": name, | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  |             "roleArn": role_arn, | 
					
						
							| 
									
										
										
										
											2019-12-15 17:58:38 +01:00
										 |  |  |             "artifactStore": { | 
					
						
							|  |  |  |                 "type": "S3", | 
					
						
							|  |  |  |                 "location": "codepipeline-us-east-1-123456789012", | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "stages": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "name": "Stage-1", | 
					
						
							|  |  |  |                     "actions": [ | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             "name": "Action-1", | 
					
						
							|  |  |  |                             "actionTypeId": { | 
					
						
							|  |  |  |                                 "category": "Source", | 
					
						
							|  |  |  |                                 "owner": "AWS", | 
					
						
							|  |  |  |                                 "provider": "S3", | 
					
						
							|  |  |  |                                 "version": "1", | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                             "configuration": { | 
					
						
							|  |  |  |                                 "S3Bucket": "test-bucket", | 
					
						
							|  |  |  |                                 "S3ObjectKey": "test-object", | 
					
						
							|  |  |  |                             }, | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |                             "outputArtifacts": [{"name": "artifact"}], | 
					
						
							| 
									
										
										
										
											2019-12-15 17:58:38 +01:00
										 |  |  |                         }, | 
					
						
							|  |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "name": "Stage-2", | 
					
						
							|  |  |  |                     "actions": [ | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             "name": "Action-1", | 
					
						
							|  |  |  |                             "actionTypeId": { | 
					
						
							|  |  |  |                                 "category": "Approval", | 
					
						
							|  |  |  |                                 "owner": "AWS", | 
					
						
							|  |  |  |                                 "provider": "Manual", | 
					
						
							|  |  |  |                                 "version": "1", | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                         }, | 
					
						
							|  |  |  |                     ], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  |         tags=tags, | 
					
						
							| 
									
										
										
										
											2019-12-15 17:58:38 +01:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2022-07-26 21:21:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extended_trust_policy = { | 
					
						
							|  |  |  |     "Version": "2012-10-17", | 
					
						
							|  |  |  |     "Statement": [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "Effect": "Allow", | 
					
						
							|  |  |  |             "Principal": {"Service": "codebuild.amazonaws.com"}, | 
					
						
							|  |  |  |             "Action": "sts:AssumeRole", | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "Effect": "Allow", | 
					
						
							|  |  |  |             "Principal": {"Service": "codepipeline.amazonaws.com"}, | 
					
						
							|  |  |  |             "Action": "sts:AssumeRole", | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     ], | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_create_pipeline_with_extended_trust_policy(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     role_arn = get_role_arn( | 
					
						
							|  |  |  |         name="test-role-extended", trust_policy=extended_trust_policy | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response = create_basic_codepipeline(client, "test-pipeline", role_arn=role_arn) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     extended_pipeline_details = deepcopy(expected_pipeline_details) | 
					
						
							|  |  |  |     extended_pipeline_details["roleArn"] = role_arn | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response["pipeline"].should.equal(extended_pipeline_details) | 
					
						
							|  |  |  |     response["tags"].should.equal([{"key": "key", "value": "value"}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_codepipeline | 
					
						
							|  |  |  | def test_create_pipeline_without_tags(): | 
					
						
							|  |  |  |     client = boto3.client("codepipeline", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = create_basic_codepipeline(client, "test-pipeline", tags=[]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response["pipeline"].should.equal(expected_pipeline_details) | 
					
						
							|  |  |  |     response["tags"].should.equal([]) |