def test_can_build_single_lambda_function_app_with_managed_layer( self, sample_app_lambda_only): # This is the simplest configuration we can get. builder = ApplicationGraphBuilder() config = self.create_config(sample_app_lambda_only, iam_role_arn='role:arn', automatic_layer=True) application = builder.build(config, stage_name='dev') # The top level resource is always an Application. assert isinstance(application, models.Application) assert len(application.resources) == 1 assert application.resources[0] == models.LambdaFunction( resource_name='myfunction', function_name='lambda-only-dev-myfunction', environment_variables={}, runtime=config.lambda_python_version, handler='app.myfunction', tags=config.tags, timeout=None, memory_size=None, deployment_package=models.DeploymentPackage( models.Placeholder.BUILD_STAGE), role=models.PreCreatedIAMRole('role:arn'), security_group_ids=[], subnet_ids=[], layers=[], managed_layer=models.LambdaLayer( resource_name='managed-layer', layer_name='lambda-only-dev-managed-layer', runtime=config.lambda_python_version, deployment_package=models.DeploymentPackage( models.Placeholder.BUILD_STAGE, )), reserved_concurrency=None, xray=None, )
def create_function_resource(name, function_name=None, environment_variables=None, runtime='python2.7', handler='app.app', tags=None, timeout=60, memory_size=128, deployment_package=None, role=None): if function_name is None: function_name = 'appname-dev-%s' % name if environment_variables is None: environment_variables = {} if tags is None: tags = {} if deployment_package is None: deployment_package = models.DeploymentPackage(filename='foo') if role is None: role = models.PreCreatedIAMRole(role_arn='role:arn') return models.LambdaFunction( resource_name=name, function_name=function_name, environment_variables=environment_variables, runtime=runtime, handler=handler, tags=tags, timeout=timeout, memory_size=memory_size, deployment_package=deployment_package, role=role, security_group_ids=[], subnet_ids=[], reserved_concurrency=None, )
def build(self, config, stage_name): # type: (Config, str) -> models.Application resources = [] # type: List[models.Model] deployment = models.DeploymentPackage(models.Placeholder.BUILD_STAGE) for function in config.chalice_app.pure_lambda_functions: resource = self._create_lambda_model( config=config, deployment=deployment, name=function.name, handler_name=function.handler_string, stage_name=stage_name) resources.append(resource) for event_source in config.chalice_app.event_sources: scheduled_event = self._create_event_model(config, deployment, event_source, stage_name) resources.append(scheduled_event) if config.chalice_app.routes: rest_api = self._create_rest_api_model(config, deployment, config.chalice_app, stage_name) resources.append(rest_api) for s3_event in config.chalice_app.s3_events: bucket_notification = self._create_bucket_notification( config, deployment, s3_event, stage_name) resources.append(bucket_notification) return models.Application(stage_name, resources)
def test_managed_layer_removed_if_no_deps(self): function = create_function_resource('myfunction') function.managed_layer = models.LambdaLayer( resource_name='managed-layer', layer_name='appname-dev-managed-layer', runtime='python2.7', deployment_package=models.DeploymentPackage( models.Placeholder.BUILD_STAGE ) ) lambda_packager = mock.Mock(spec=packager.BaseLambdaDeploymentPackager) layer_packager = mock.Mock(spec=packager.BaseLambdaDeploymentPackager) lambda_packager.create_deployment_package.return_value = 'package.zip' layer_packager.create_deployment_package.side_effect = \ packager.EmptyPackageError() config = Config.create(project_dir='.') p = ManagedLayerDeploymentPackager(lambda_packager, layer_packager) p.handle(config, function.managed_layer) p.handle(config, function) # If the deployment package for layers would result in an empty # deployment package, we expect that resource to be removed, it can't # be created on the service. assert function.managed_layer is None
def test_sam_injects_policy(self, sample_app): function = models.LambdaFunction( resource_name='foo', function_name='app-dev-foo', environment_variables={}, runtime='python27', handler='app.app', tags={'foo': 'bar'}, timeout=120, memory_size=128, deployment_package=models.DeploymentPackage(filename='foo.zip'), role=models.ManagedIAMRole( resource_name='role', role_name='app-role', trust_policy={}, policy=models.AutoGenIAMPolicy(document={'iam': 'policy'}), )) template = self.template_gen.generate_sam_template([function]) cfn_resource = list(template['Resources'].values())[0] assert cfn_resource == { 'Type': 'AWS::Serverless::Function', 'Properties': { 'CodeUri': 'foo.zip', 'Handler': 'app.app', 'MemorySize': 128, 'Role': { 'Fn::GetAtt': ['Role', 'Arn'] }, 'Runtime': 'python27', 'Tags': { 'foo': 'bar' }, 'Timeout': 120 }, }
def test_role_arn_inserted_when_necessary(self): function = models.LambdaFunction( resource_name='foo', function_name='app-dev-foo', environment_variables={}, runtime='python27', handler='app.app', tags={'foo': 'bar'}, timeout=120, memory_size=128, deployment_package=models.DeploymentPackage(filename='foo.zip'), role=models.PreCreatedIAMRole(role_arn='role:arn'), ) template = self.template_gen.generate_sam_template([function]) cfn_resource = list(template['Resources'].values())[0] assert cfn_resource == { 'Type': 'AWS::Serverless::Function', 'Properties': { 'CodeUri': 'foo.zip', 'Handler': 'app.app', 'MemorySize': 128, 'Role': 'role:arn', 'Runtime': 'python27', 'Tags': { 'foo': 'bar' }, 'Timeout': 120 }, }
def test_can_generate_layer_package(self): function = create_function_resource('myfunction') function.managed_layer = models.LambdaLayer( resource_name='managed-layer', layer_name='appname-dev-managed-layer', runtime='python2.7', deployment_package=models.DeploymentPackage( models.Placeholder.BUILD_STAGE)) lambda_packager = mock.Mock(spec=packager.BaseLambdaDeploymentPackager) layer_packager = mock.Mock(spec=packager.BaseLambdaDeploymentPackager) lambda_packager.create_deployment_package.return_value = 'package.zip' layer_packager.create_deployment_package.return_value = ( 'package-layer.zip') config = Config.create(project_dir='.') p = ManagedLayerDeploymentPackager(lambda_packager, layer_packager) p.handle(config, function.managed_layer) p.handle(config, function) assert function.deployment_package.filename == 'package.zip' lambda_packager.create_deployment_package.assert_called_with( '.', config.lambda_python_version) assert function.managed_layer.deployment_package.filename == ( 'package-layer.zip') layer_packager.create_deployment_package.assert_called_with( '.', config.lambda_python_version)
def test_can_build_lambda_function_app_with_vpc_config( self, sample_app_lambda_only): @sample_app_lambda_only.lambda_function() def foo(event, context): pass builder = ApplicationGraphBuilder() config = self.create_config(sample_app_lambda_only, iam_role_arn='role:arn', security_group_ids=['sg1', 'sg2'], subnet_ids=['sn1', 'sn2']) application = builder.build(config, stage_name='dev') assert application.resources[0] == models.LambdaFunction( resource_name='myfunction', function_name='lambda-only-dev-myfunction', environment_variables={}, runtime=config.lambda_python_version, handler='app.myfunction', tags=config.tags, timeout=None, memory_size=None, deployment_package=models.DeploymentPackage( models.Placeholder.BUILD_STAGE), role=models.PreCreatedIAMRole('role:arn'), security_group_ids=['sg1', 'sg2'], subnet_ids=['sn1', 'sn2'], layers=[], reserved_concurrency=None, xray=None, )
def test_can_generate_package(self): generator = mock.Mock(spec=packager.LambdaDeploymentPackager) generator.create_deployment_package.return_value = 'package.zip' package = models.DeploymentPackage(models.Placeholder.BUILD_STAGE) config = Config.create() p = DeploymentPackager(generator) p.handle(config, package) assert package.filename == 'package.zip'
def test_package_not_generated_if_filename_populated(self): generator = mock.Mock(spec=packager.LambdaDeploymentPackager) generator.create_deployment_package.return_value = 'NEWPACKAGE.zip' package = models.DeploymentPackage(filename='original-name.zip') config = Config.create() p = DeploymentPackager(generator) p.handle(config, package) assert package.filename == 'original-name.zip' assert not generator.create_deployment_package.called
def lambda_function(self): return models.LambdaFunction( resource_name='foo', function_name='app-dev-foo', environment_variables={}, runtime='python27', handler='app.app', tags={'foo': 'bar'}, timeout=120, memory_size=128, deployment_package=models.DeploymentPackage(filename='foo.zip'), role=models.PreCreatedIAMRole(role_arn='role:arn'), )
def _get_managed_lambda_layer(self, config): # type: (Config) -> Optional[models.LambdaLayer] if not config.automatic_layer: return None if self._managed_layer is None: self._managed_layer = models.LambdaLayer( resource_name='managed-layer', layer_name='%s-%s-%s' % (config.app_name, config.chalice_stage, 'managed-layer'), runtime=config.lambda_python_version, deployment_package=models.DeploymentPackage( models.Placeholder.BUILD_STAGE)) return self._managed_layer
def create_function_resource(name): return models.LambdaFunction( resource_name=name, function_name='appname-dev-%s' % name, environment_variables={}, runtime='python2.7', handler='app.app', tags={}, timeout=60, memory_size=128, deployment_package=models.DeploymentPackage(filename='foo'), role=models.PreCreatedIAMRole(role_arn='role:arn'), security_group_ids=[], subnet_ids=[], layers=[])
def test_layer_package_not_generated_if_filename_populated(self): generator = mock.Mock(spec=packager.BaseLambdaDeploymentPackager) function = create_function_resource('myfunction') layer = models.LambdaLayer(resource_name='layer', layer_name='name', runtime='python2.7', deployment_package=models.DeploymentPackage( filename='original.zip')) function.managed_layer = layer config = Config.create(project_dir='.') p = ManagedLayerDeploymentPackager(None, generator) p.handle(config, layer) assert layer.deployment_package.filename == 'original.zip' assert not generator.create_deployment_package.called
def lambda_function(self): return models.LambdaFunction( resource_name='foo', function_name='app-dev-foo', environment_variables={}, runtime='python27', handler='app.app', tags={'foo': 'bar'}, timeout=120, memory_size=128, deployment_package=models.DeploymentPackage(filename='foo.zip'), role=models.PreCreatedIAMRole(role_arn='role:arn'), security_group_ids=[], subnet_ids=[], reserved_concurrency=None, layers=None, )
def build(self, config, stage_name): # type: (Config, str) -> models.Application resources = [] # type: List[models.Model] deployment = models.DeploymentPackage(models.Placeholder.BUILD_STAGE) for function in config.chalice_app.pure_lambda_functions: resource = self._create_lambda_model( config=config, deployment=deployment, name=function.name, handler_name=function.handler_string, stage_name=stage_name) resources.append(resource) event_resources = self._create_lambda_event_resources( config, deployment, stage_name) resources.extend(event_resources) if config.chalice_app.routes: rest_api = self._create_rest_api_model( config, deployment, stage_name) resources.append(rest_api) return models.Application(stage_name, resources)
def create_function_resource(name): return models.LambdaFunction( resource_name=name, function_name='appname-dev-%s' % name, environment_variables={}, runtime='python2.7', handler='app.app', tags={}, timeout=60, memory_size=128, deployment_package=models.DeploymentPackage( models.Placeholder.BUILD_STAGE), xray=False, role=models.PreCreatedIAMRole(role_arn='role:arn'), security_group_ids=[], subnet_ids=[], layers=[], reserved_concurrency=None, )