def integration_add_permission_to_lambda(self,api_id, lambda_name): # create permission to allow lambda function to be invoked by API Gateway iam = IAM() aws_acct_id = iam.account_id() aws_region = iam.region() aws_lambda = Lambda(lambda_name) function_arn = aws_lambda.function_Arn()#'gw_bot.lambdas.dev.hello_world' statement_id = 'allow-api-gateway-invoke' action = 'lambda:InvokeFunction' principal = 'apigateway.amazonaws.com' source_arn = f'arn:aws:execute-api:{aws_region}:{aws_acct_id}:{api_id}/*/GET/' aws_lambda.permission_delete(function_arn, statement_id) # remove in case there was already a permission with this name return aws_lambda.permission_add(function_arn, statement_id, action, principal, source_arn)
class Temp_Lambda: def __init__(self): self.lambda_name = "temp_lambda_{0}".format( Misc.random_string_and_numbers()) self.aws_lambda = Lambda(self.lambda_name) self.tmp_folder = Temp_Folder_Code(self.lambda_name) self.role_arn = Temp_Aws_Roles().for_lambda_invocation() self.create_log = None self.delete_on_exit = True self.s3_bucket = Globals.lambda_s3_bucket self.s3_key = 'unit_tests/lambdas/{0}.zip'.format(self.lambda_name) self.s3 = self.aws_lambda.s3() def __enter__(self): (self.aws_lambda.set_role(self.role_arn).set_s3_bucket( self.s3_bucket).set_s3_key(self.s3_key).set_folder_code( self.tmp_folder.folder)) self.aws_lambda.upload() self.create_log = self.aws_lambda.create() assert self.aws_lambda.exists() == True return self def __exit__(self, type, value, traceback): if self.delete_on_exit: assert self.aws_lambda.delete() is True self.delete_s3_file() def arn(self): return self.aws_lambda.function_Arn() def info(self): return self.aws_lambda.info() def invoke(self, params=None): return self.aws_lambda.invoke(params) def invoke_raw(self, params=None): return self.aws_lambda.invoke_raw(params) def set_s3_bucket(self, value): self.s3_bucket = value def s3_file_exists(self): return self.s3.file_exists(self.s3_bucket, self.s3_key) def delete_s3_file(self): self.s3.file_delete(self.s3_bucket, self.s3_key) assert self.s3_file_exists() is False return self
class Temp_Lambda: def __init__(self, lambda_name=None, delete_on_exit=True): self.lambda_name = lambda_name or "temp_lambda_{0}".format(random_string_and_numbers()) self.aws_lambda = Lambda(self.lambda_name) self.tmp_folder = Temp_Folder_With_Lambda_File(self.lambda_name).create_temp_file() self.role_arn = Temp_Aws_Roles().for_lambda_invocation__role_arn() # todo: refactor to have option to create the role programatically (needs feature to wait for role to be available) self.create_log = None self.delete_on_exit = delete_on_exit self.s3_bucket = AWS_Config().lambda_s3_bucket() self.s3_key = 'unit_tests/lambdas/{0}.zip'.format(self.lambda_name) self.s3 = self.aws_lambda.s3() def __enter__(self): self.create() return self def __exit__(self, type, value, traceback): if self.delete_on_exit: self.delete() def arn(self): return self.aws_lambda.function_Arn() def create(self): (self.aws_lambda.set_role (self.role_arn) .set_s3_bucket (self.s3_bucket ) .set_s3_key (self.s3_key ) .set_folder_code(self.tmp_folder.folder ) .upload()) self.create_log = self.aws_lambda.create() assert self.exists() is True return self.create_log def delete(self): assert self.aws_lambda.delete() self.delete_s3_file() def exists(self): return self.aws_lambda.exists() def info(self): return self.aws_lambda.info() def invoke(self, params=None): return self.aws_lambda.invoke(params) def invoke_return_logs(self, params=None): return self.aws_lambda.invoke_return_logs(params) def invoke_raw(self, params=None): return self.aws_lambda.invoke_raw(params) def set_s3_bucket(self, value): self.s3_bucket = value def s3_file_exists(self): return self.s3.file_exists(self.s3_bucket, self.s3_key) def delete_s3_file(self): self.s3.file_delete(self.s3_bucket, self.s3_key) assert self.s3_file_exists() is False
class Lambda_Package: def __init__(self,lambda_name): self.lambda_name = lambda_name self.aws_lambda = Lambda(self.lambda_name) self.s3_bucket = AWS_Config().lambda_s3_bucket() self.s3_key = f'{AWS_Config().lambda_s3_folder_lambdas()}/{self.lambda_name}.zip' self.role_arn = Temp_Aws_Roles().for_lambda_invocation__role_arn() self.tmp_folder = Files.temp_folder('tmp_lambda_') (self.aws_lambda.set_s3_bucket (self.s3_bucket ) .set_s3_key (self.s3_key ) .set_role (self.role_arn ) .set_folder_code (self.tmp_folder )) # helper methods @staticmethod def get_root_folder(): return Files.path_combine(__file__, '../..') # Lambda class wrappers def create(self ): return self.aws_lambda.create() def delete(self ): return self.aws_lambda.delete() def invoke(self, params=None): return self.aws_lambda.invoke(params) def update(self ): return self.aws_lambda.update() def reset (self ): return self.aws_lambda.update_lambda_code() # this will trigger a reset and force cold start on next execution # main methods def add_file(self, source): Files.copy(source, self.tmp_folder) def add_folder(self, source, ignore=None): destination = Files.path_combine(self.tmp_folder,Files.file_name(source)) if folder_not_exists(destination): folder_copy(source=source, destination=destination,ignore_pattern=ignore) self.remove_files('__pycache__') return self def add_module(self,module_name): module_path = importlib.import_module(module_name).__path__[0] # get folder of module self.add_folder(module_path) # add module's folder return self def add_modules(self, modules_names): for module_name in modules_names: self.add_module(module_name) return self def add_root_folder(self): self.add_folder(self.get_root_folder()) return self def add_osbot_aws(self): self.add_osbot_utils() self.add_module('osbot_aws') def add_osbot_browser(self): self.add_module('osbot_browser') def add_osbot_elastic(self): self.add_module('osbot_elastic') def add_osbot_utils(self): self.add_module('dotenv') self.add_module('osbot_utils') return self def arn(self): return self.aws_lambda.function_Arn() def get_files(self): all_files = [] for root, dirs, files in os.walk(self.tmp_folder): for file in files: file_path = Files.path_combine(root,file).replace(self.tmp_folder,'') all_files.append(file_path) return all_files def remove_files(self,pattern): for file in self.get_files(): if pattern in file: file_to_delete = Files.path_combine(self.tmp_folder,file[1:]) Files.delete(file_to_delete) def set_image_uri(self, image_uri): self.aws_lambda.image_uri = image_uri def use_lambda_file(self,lambda_file): file_path = Files.path_combine(self.get_root_folder(), lambda_file) if Files.exists(file_path) is False: return { 'status': 'error', 'data': 'could not find lambda file `{0}` in root folder `{1}`'.format(lambda_file, self.get_root_folder())} target_file = Files.path_combine(self.tmp_folder, '{0}.py'.format(self.lambda_name)) Files.copy(file_path,target_file) return { 'status': 'ok', 'file_path': file_path, 'target_file': target_file } def update_with_root_folder(self,delete_before=False): if delete_before: self.delete() self.add_root_folder() self.add_osbot_utils() self.update() return self def update_code(self): base_folder = self.lambda_name.split('.').pop(0) # will point to the top level module self.add_module(base_folder) # add module's folder self.add_root_folder() # add osbot-aws folder self.add_osbot_utils() # add osbot-utils folder self.update() # zip files up and update lambda return self
class Lambda_Package: def __init__(self, lambda_name): self.lambda_name = lambda_name self.aws_lambda = Lambda(self.lambda_name) self.s3_bucket = Globals.lambda_s3_bucket self.s3_key = f'{Globals.lambda_s3_key_prefix}/{self.lambda_name}.zip' self.role_arn = Temp_Aws_Roles().for_lambda_invocation() self.tmp_folder = Files.temp_folder('tmp_lambda_') (self.aws_lambda.set_s3_bucket(self.s3_bucket).set_s3_key( self.s3_key).set_role(self.role_arn).set_folder_code( self.tmp_folder)) # helper methods @staticmethod def get_root_folder(): return Files.path_combine(__file__, '../..') # Lambda class wrappers def create(self): return self.aws_lambda.create() def delete(self): return self.aws_lambda.delete() def invoke(self, params=None): return self.aws_lambda.invoke(params) def update(self): return self.aws_lambda.update() def reset(self): return self.aws_lambda.update_lambda_code() # main methods def add_file(self, source): Files.copy(source, self.tmp_folder) def add_folder(self, source): destination = Files.path_combine(self.tmp_folder, Files.file_name(source)) Temp_Files.folder_copy(source, destination) self.remove_files('__pycache__') return self def add_module(self, module_name): module_path = importlib.import_module(module_name).__path__[ 0] # get folder of module self.add_folder(module_path) # add module's folder return self def add_modules(self, modules_names): for module_name in modules_names: self.add_module(module_name) return self def add_root_folder(self): self.add_folder(self.get_root_folder()) return self def add_pbx_gs_python_utils(self): self.add_module( 'osbot_utils' ) # todo: when all dependencies on pbx_gs_python_utils have been removed lib_path = Files.folder_name( pbx_gs_python_utils.__file__ ) # refactor this to add_osbot_utils and remove pbx_gs_python_utils from codebase self.add_folder(lib_path) return self def arn(self): return self.aws_lambda.function_Arn() def get_files(self): all_files = [] for root, dirs, files in os.walk(self.tmp_folder): for file in files: file_path = Files.path_combine(root, file).replace( self.tmp_folder, '') all_files.append(file_path) return all_files def remove_files(self, pattern): for file in self.get_files(): if pattern in file: file_to_delete = Files.path_combine(self.tmp_folder, file[1:]) Files.delete(file_to_delete) def use_lambda_file(self, lambda_file): file_path = Files.path_combine(self.get_root_folder(), lambda_file) if Files.exists(file_path) is False: return { 'status': 'error', 'data': 'could not find lambda file `{0}` in root folder `{1}`'.format( lambda_file, self.get_root_folder()) } target_file = Files.path_combine(self.tmp_folder, '{0}.py'.format(self.lambda_name)) Files.copy(file_path, target_file) return { 'status': 'ok', 'file_path': file_path, 'target_file': target_file } def update_with_root_folder(self, delete_before=False): if delete_before: self.delete() self.add_root_folder() self.add_pbx_gs_python_utils() self.update() return self def update_code(self): base_folder = self.lambda_name.split('.').pop( 0) # will point to the top level module self.add_module(base_folder) # add module's folder self.add_root_folder() # add osbot-aws folder self.add_pbx_gs_python_utils() # add pbx-gs-python-utils folder self.update() # zip files up and update lambda return self