1616import os
1717import boto3
1818import logging
19- from time import sleep
2019from zipfile import ZipFile
21- import random
22- import string
2320
24- from acktest import resources
25- from acktest .aws .identity import get_region , get_account_id
2621from e2e import bootstrap_directory
27- from e2e .bootstrap_resources import TestBootstrapResources
22+ from e2e .bootstrap_resources import BootstrapResources
2823from botocore .exceptions import ClientError
2924
30- RAND_TEST_SUFFIX = ('' .join (random .choice (string .ascii_lowercase ) for _ in range (6 )))
31-
32- LAMBDA_BASIC_IAM_ROLE_NAME = 'ack-lambda-function-role-basic-' + RAND_TEST_SUFFIX
33- LAMBDA_ESM_IAM_ROLE_NAME = 'ack-lambda-function-role-esm-' + RAND_TEST_SUFFIX
25+ from acktest .bootstrapping import Resources , BootstrapFailureException
26+ from acktest .bootstrapping .s3 import Bucket
27+ from acktest .bootstrapping .dynamodb import Table
28+ from acktest .bootstrapping .signer import SigningProfile
29+ from acktest .bootstrapping .sqs import Queue
30+ from acktest .bootstrapping .iam import Role
3431
3532LAMBDA_IAM_ROLE_POLICY = '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": ' \
3633 '"lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]} '
3734LAMBDA_BASIC_EXECUTION_ARN = 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
3835LAMBDA_DYNAMODB_EXECUTION_ROLE = 'arn:aws:iam::aws:policy/service-role/AWSLambdaDynamoDBExecutionRole'
3936LAMBDA_SQS_QUEUE_EXECUTION_ROLE = 'arn:aws:iam::aws:policy/AmazonSQSFullAccess'
4037
41- BASIC_ROLES = [ LAMBDA_BASIC_EXECUTION_ARN ]
42- ESM_ROLES = [ LAMBDA_BASIC_EXECUTION_ARN , LAMBDA_DYNAMODB_EXECUTION_ROLE , LAMBDA_SQS_QUEUE_EXECUTION_ROLE ]
43-
44- FUNCTIONS_BUCKET_NAME = "ack-lambda-function-s3-bucket-" + RAND_TEST_SUFFIX
38+ BASIC_ROLE_POLICIES = [ LAMBDA_BASIC_EXECUTION_ARN ]
39+ ESM_ROLE_POLICIES = [ LAMBDA_BASIC_EXECUTION_ARN , LAMBDA_DYNAMODB_EXECUTION_ROLE , LAMBDA_SQS_QUEUE_EXECUTION_ROLE ]
4540
4641LAMBDA_FUNCTION_FILE = "main.py"
4742LAMBDA_FUNCTION_FILE_ZIP = "main.zip"
4843LAMBDA_FUNCTION_FILE_PATH = f"./resources/lambda_function/{ LAMBDA_FUNCTION_FILE } "
4944LAMBDA_FUNCTION_FILE_PATH_ZIP = f"./resources/lambda_function/{ LAMBDA_FUNCTION_FILE_ZIP } "
5045
51- AWS_SIGNING_PROFILE_NAME = "ack_testing_lambda_signing_profile"
5246AWS_SIGNING_PLATFORM_ID = "AWSLambda-SHA384-ECDSA"
5347
54- SQS_QUEUE_NAME = "ack-lambda-sqs-queue-" + RAND_TEST_SUFFIX
55-
56- DYNAMODB_TABLE_NAME = "ack-lambda-ddb-table-" + RAND_TEST_SUFFIX
57-
58- def service_bootstrap () -> dict :
59- logging .getLogger ().setLevel (logging .INFO )
60- lambda_esm_role_arn = create_lambda_function_esm_role (LAMBDA_ESM_IAM_ROLE_NAME )
61- lambda_basic_role_arn = create_lambda_function_basic_role (LAMBDA_BASIC_IAM_ROLE_NAME )
62- create_bucket (FUNCTIONS_BUCKET_NAME )
63- zip_function_file (LAMBDA_FUNCTION_FILE_PATH , LAMBDA_FUNCTION_FILE_PATH_ZIP )
64- upload_function_to_bucket (LAMBDA_FUNCTION_FILE_PATH_ZIP , FUNCTIONS_BUCKET_NAME )
65- signing_profile_version_arn = ensure_signing_profile (AWS_SIGNING_PROFILE_NAME , AWS_SIGNING_PLATFORM_ID )
66- sqs_queue_arn , sqs_queue_url = create_sqs_queue (SQS_QUEUE_NAME )
67- dynamodb_table_stream_arn = create_dynamodb_table (DYNAMODB_TABLE_NAME )
68-
69- return TestBootstrapResources (
70- FUNCTIONS_BUCKET_NAME ,
71- LAMBDA_FUNCTION_FILE_PATH ,
72- LAMBDA_FUNCTION_FILE_ZIP ,
73- LAMBDA_BASIC_IAM_ROLE_NAME ,
74- lambda_basic_role_arn ,
75- LAMBDA_ESM_IAM_ROLE_NAME ,
76- lambda_esm_role_arn ,
77- signing_profile_version_arn ,
78- sqs_queue_arn ,
79- sqs_queue_url ,
80- DYNAMODB_TABLE_NAME ,
81- dynamodb_table_stream_arn ,
82- BASIC_ROLES ,
83- ESM_ROLES ,
84- ).__dict__
85-
86-
87-
88- def create_role_with_policies (iam_role_name : str , policies : list ) -> str :
89- region = get_region ()
90- iam_client = boto3 .client ("iam" , region_name = region )
91-
92- logging .debug (f"Creating iam role { iam_role_name } " )
93- try :
94- iam_client .get_role (RoleName = iam_role_name )
95- raise RuntimeError (f"Expected { iam_role_name } role to not exist."
96- f" Did previous test cleanup successfully?" )
97- except iam_client .exceptions .NoSuchEntityException :
98- pass
99-
100- resp = iam_client .create_role (
101- RoleName = iam_role_name ,
102- AssumeRolePolicyDocument = LAMBDA_IAM_ROLE_POLICY
103- )
104-
105- for policyARN in policies :
106- iam_client .attach_role_policy (RoleName = iam_role_name , PolicyArn = policyARN )
107-
108- logging .info (f"Created role { iam_role_name } " )
109- return resp ['Role' ]['Arn' ]
110-
111-
112- def create_lambda_function_basic_role (iam_role_name : str ) -> str :
113- return create_role_with_policies (
114- iam_role_name ,
115- BASIC_ROLES ,
116- )
117-
118- def create_lambda_function_esm_role (iam_role_name : str ) -> str :
119- return create_role_with_policies (
120- iam_role_name ,
121- ESM_ROLES ,
122- )
123-
124- def create_bucket (bucket_name : str ):
125- region = get_region ()
126- s3_client = boto3 .resource ('s3' )
127- logging .debug (f"Creating s3 data bucket { bucket_name } " )
128- try :
129- s3_client .create_bucket (
130- Bucket = bucket_name ,
131- CreateBucketConfiguration = {"LocationConstraint" : region }
132- )
133- except s3_client .exceptions .BucketAlreadyExists :
134- raise RuntimeError (f"Expected { bucket_name } bucket to not exist."
135- f" Did previous test cleanup successfully?" )
136-
137- logging .info (f"Created bucket { bucket_name } " )
138-
13948def zip_function_file (src : str , dst : str ):
14049 with ZipFile (dst , 'w' ) as zipf :
14150 zipf .write (src , arcname = src )
@@ -155,73 +64,74 @@ def upload_function_to_bucket(file_path: str, bucket_name: str):
15564
15665 logging .info (f"Uploaded { file_path } to bucket { bucket_name } " )
15766
158- def ensure_signing_profile (signing_profile_name : str , platform_id : str ) -> str :
159- region = get_region ()
160- signer_client = boto3 .client ("signer" , region_name = region )
161-
162- # Signing profiles cannot be deleted. We just reuse the same signing profile
163- # for ACK lambda controller e2e tests.
164- try :
165- resp = signer_client .get_signing_profile (
166- profileName = signing_profile_name ,
167- )
168- return resp ['profileVersionArn' ]
169- except :
170- resp = signer_client .put_signing_profile (
171- profileName = signing_profile_name ,
172- platformId = platform_id ,
173- )
174- logging .info (f"Created signing profile { signing_profile_name } " )
175- return resp ['profileVersionArn' ]
176-
177- def create_sqs_queue (queue_name : str ) -> str :
178- region = get_region ()
179- sqs_client = boto3 .resource ('sqs' , region_name = region )
180- logging .debug (f"Creating SQS queue { queue_name } " )
181- resp = sqs_client .create_queue (
182- QueueName = queue_name ,
183- )
184- logging .info (f"Created SQS queue { queue_name } " )
185- return resp .attributes ['QueueArn' ], resp .url
186-
187- def create_dynamodb_table (table_name : str ) -> str :
188- region = get_region ()
189- dynamodb_client = boto3 .resource ('dynamodb' , region_name = region )
190- resp = dynamodb_client .create_table (
191- TableName = table_name ,
192- KeySchema = [
193- {
194- 'AttributeName' : 'id' ,
195- 'KeyType' : 'HASH'
196- },
197- {
198- 'AttributeName' : 'createdAt' ,
199- 'KeyType' : 'RANGE'
200- }
201- ],
202- AttributeDefinitions = [
203- {
204- 'AttributeName' : 'id' ,
205- 'AttributeType' : 'N'
67+ def service_bootstrap () -> Resources :
68+ logging .getLogger ().setLevel (logging .INFO )
69+ resources = BootstrapResources (
70+ FunctionsBucket = Bucket (
71+ "ack-lambda-controller-tests" ,
72+ ),
73+ SigningProfile = SigningProfile (
74+ "ack_testing_signer" ,
75+ signing_platform_id = AWS_SIGNING_PLATFORM_ID ,
76+ ),
77+ BasicRole = Role (
78+ "ack-lambda-controller-basic-role" ,
79+ principal_service = "lambda.amazonaws.com" ,
80+ managed_policies = BASIC_ROLE_POLICIES ,
81+ ),
82+ ESMRole = Role (
83+ "ack-lambda-controller-esm-role" ,
84+ principal_service = "lambda.amazonaws.com" ,
85+ managed_policies = ESM_ROLE_POLICIES ,
86+ ),
87+ ESMTable = Table (
88+ "ack-lambda-controller-table" ,
89+ attribute_definitions = [
90+ {
91+ 'AttributeName' : 'id' ,
92+ 'AttributeType' : 'N'
93+ },
94+ {
95+ 'AttributeName' : 'createdAt' ,
96+ 'AttributeType' : 'S'
97+ },
98+ ],
99+ key_schema = [
100+ {
101+ 'AttributeName' : 'id' ,
102+ 'KeyType' : 'HASH'
103+ },
104+ {
105+ 'AttributeName' : 'createdAt' ,
106+ 'KeyType' : 'RANGE'
107+ }
108+ ],
109+ stream_specification = {
110+ 'StreamEnabled' : True ,
111+ 'StreamViewType' : 'NEW_IMAGE'
206112 },
207- {
208- 'AttributeName ' : 'createdAt' ,
209- 'AttributeType ' : 'S'
113+ provisioned_throughput = {
114+ 'ReadCapacityUnits ' : 5 ,
115+ 'WriteCapacityUnits ' : 5
210116 },
211- ],
212- ProvisionedThroughput = {
213- 'ReadCapacityUnits' : 5 ,
214- 'WriteCapacityUnits' : 5
215- },
216- StreamSpecification = {
217- 'StreamEnabled' : True ,
218- 'StreamViewType' : 'NEW_IMAGE'
219- }
117+ ),
118+ ESMQueue = Queue (
119+ "ack-lambda-controller-queue"
120+ ),
220121 )
221- logging .info (f"Created Dynamodb table { table_name } " )
222- return resp .latest_stream_arn
122+
123+ try :
124+ resources .bootstrap ()
125+ zip_function_file (LAMBDA_FUNCTION_FILE_PATH , LAMBDA_FUNCTION_FILE_PATH_ZIP )
126+ upload_function_to_bucket (
127+ LAMBDA_FUNCTION_FILE_PATH_ZIP ,
128+ resources .FunctionsBucket .name ,
129+ )
130+ except BootstrapFailureException as ex :
131+ exit (254 )
132+ return resources
223133
224134if __name__ == "__main__" :
225135 config = service_bootstrap ()
226136 # Write config to current directory by default
227- resources . write_bootstrap_config ( config , bootstrap_directory )
137+ config . serialize ( bootstrap_directory )
0 commit comments