コード例 #1
0
ファイル: lambdas.py プロジェクト: ryandub/gordon
    def register_pre_resources_template(self, template):
        """Register one UploadToS3 action into the pre_resources template, as
        well as several Outputs so subsequente templates can reference these
        files.
        Before registering these actions, we create the .zip file we'll
        upload to s3 on apply time.
        """

        code_path = os.path.join(self.project.build_path, 'code')
        if not os.path.exists(code_path):
            os.makedirs(code_path)

        # We need to know to which bucket we are uploading these files.
        template.add_parameter(
            actions.Parameter(
                name="CodeBucket"
            )
        )

        filename = os.path.join(code_path, self.get_bucket_key())
        with open(filename, 'wb') as f:
            f.write(self.get_zip_file().read())

        context, context_key = {}, self.get_context_key()
        try:
            lambda_context = self.project.get_resource('contexts::{}'.format(context_key))
        except exceptions.ResourceNotFoundError:
            if context_key != 'default':
                raise
        else:
            context = lambda_context.settings

        template.add(
            actions.InjectContextAndUploadToS3(
                name="{}-upload".format(self.name),
                bucket=actions.Ref(name='CodeBucket'),
                key=self.get_bucket_key(),
                filename=os.path.relpath(filename, self.project.build_path),
                context_to_inject=context,
                context_destinaton=self.get_context_destination()
            )
        )
        template.add_output(
            actions.Output(
                name=utils.valid_cloudformation_name(self.name, "s3url"),
                value=actions.GetAttr(
                    action="{}-upload".format(self.name),
                    attr="s3url",
                )
            )
        )
        template.add_output(
            actions.Output(
                name=utils.valid_cloudformation_name(self.name, "s3version"),
                value=actions.GetAttr(
                    action="{}-upload".format(self.name),
                    attr="s3version",
                )
            )
        )
コード例 #2
0
    def register_resources_template(self, template):
        targets, target_lambdas = [], []
        for name, target in six.iteritems(self.settings.get('targets', {})):
            target_lambdas.append(target['lambda'])
            targets.append(
                events.Target(
                    Arn=self.get_destination_arn(target['lambda']),
                    Id=self.get_function_name(target['lambda']),
                    Input=target.get('input', ''),
                    InputPath=target.get('input_path', ''),
                ))

        rule = events.Rule(utils.valid_cloudformation_name(self.name, "Rule"),
                           Description=self.settings.get('description', ''),
                           EventPattern=self.settings.get(
                               'event_pattern',
                               troposphere.Ref(troposphere.AWS_NO_VALUE)),
                           ScheduleExpression=self.settings.get(
                               'schedule_expression',
                               troposphere.Ref(troposphere.AWS_NO_VALUE)),
                           State=self.get_enabled(),
                           Targets=targets)
        template.add_resource(rule)

        for lambda_ in target_lambdas:
            template.add_resource(
                troposphere.awslambda.Permission(
                    utils.valid_cloudformation_name(self.name, 'rule',
                                                    'permission'),
                    Action="lambda:InvokeFunction",
                    FunctionName=self.get_destination_arn(lambda_),
                    Principal="events.amazonaws.com",
                    SourceArn=troposphere.GetAtt(rule, 'Arn'),
                ))
コード例 #3
0
    def register_pre_resources_template(self, template):
        """Register one UploadToS3 action into the pre_resources template, as
        well as several Outputs so subsequente templates can reference these
        files.
        Before registering these actions, we create the .zip file we'll
        upload to s3 on apply time.
        """

        code_path = os.path.join(self.project.build_path, 'code')
        if not os.path.exists(code_path):
            os.makedirs(code_path)

        # We need to know to which bucket we are uploading these files.
        template.add_parameter(
            actions.Parameter(
                name="CodeBucket"
            )
        )

        filename = os.path.join(code_path, self.get_bucket_key())
        with open(filename, 'wb') as f:
            f.write(self.get_zip_file().read())

        context, context_key = {}, self.get_context_key()
        try:
            lambda_context = self.project.get_resource('contexts::{}'.format(context_key))
        except exceptions.ResourceNotFoundError:
            if context_key != 'default':
                raise
        else:
            context = lambda_context.settings

        template.add(
            actions.InjectContextAndUploadToS3(
                name="{}-upload".format(self.name),
                bucket=actions.Ref(name='CodeBucket'),
                key=self.get_bucket_key(),
                filename=os.path.relpath(filename, self.project.build_path),
                context_to_inject=context,
                context_destinaton=self.get_context_destination()
            )
        )
        template.add_output(
            actions.Output(
                name=utils.valid_cloudformation_name(self.name, "s3url"),
                value=actions.GetAttr(
                    action="{}-upload".format(self.name),
                    attr="s3url",
                )
            )
        )
        template.add_output(
            actions.Output(
                name=utils.valid_cloudformation_name(self.name, "s3version"),
                value=actions.GetAttr(
                    action="{}-upload".format(self.name),
                    attr="s3version",
                )
            )
        )
コード例 #4
0
ファイル: lambdas.py プロジェクト: valgreens/gordon
    def _get_policies(self):
        """Returns a list of policies to attach to the IAM Role of this Lambda.
        Users can add more policies to this Role by defining policy documents
        in the settings of the lambda under the ``policies`` key."""

        policies = []

        if self._get_true_false('auto-run-policy', 't'):
            policies.append(
                iam.Policy(PolicyName=utils.valid_cloudformation_name(
                    self.name, 'logs', 'policy'),
                           PolicyDocument={
                               "Version":
                               "2012-10-17",
                               "Statement": [{
                                   "Effect":
                                   "Allow",
                                   "Action": ["lambda:InvokeFunction"],
                                   "Resource": ["*"]
                               }, {
                                   "Effect":
                                   "Allow",
                                   "Action": [
                                       "logs:CreateLogGroup",
                                       "logs:CreateLogStream",
                                       "logs:PutLogEvents"
                                   ],
                                   "Resource":
                                   "arn:aws:logs:*:*:*",
                               }]
                           }))

        if self.settings.get('vpc') and self._get_true_false(
                'auto-vpc-policy', 't'):
            policies.append(
                iam.Policy(PolicyName=utils.valid_cloudformation_name(
                    self.name, 'vpc'),
                           PolicyDocument={
                               "Version":
                               "2012-10-17",
                               "Statement": [{
                                   "Effect":
                                   "Allow",
                                   "Action": [
                                       "ec2:CreateNetworkInterface",
                                       "ec2:DescribeNetworkInterfaces",
                                       "ec2:DeleteNetworkInterface"
                                   ],
                                   "Resource": ["*"]
                               }]
                           }))

        for policy_nme, policy_document in six.iteritems(
                self.settings.get('policies', {})):
            policies.append(
                iam.Policy(PolicyName=utils.valid_cloudformation_name(
                    self.name, policy_nme, 'policy'),
                           PolicyDocument=policy_document))
        return policies
コード例 #5
0
ファイル: tests.py プロジェクト: Empia/gordon
    def test_0001_project(self):
        self._test_project_step('0001_project')
        self.assert_stack_succeed('p')
        self.assert_stack_succeed('r')

        lambda_ = self.get_lambda(utils.valid_cloudformation_name('cron:example'))
        rule_ = self.get_rule(utils.valid_cloudformation_name('every_night_rule'))
        targets = self.get_rule_targets(rule_['Name'])
        self.assertEqual(rule_['ScheduleExpression'], 'cron(0 20 * * ? *)')
        self.assertEqual(len(targets), 1)
        self.assertEqual(targets[0]['Arn'], '{}:current'.format(lambda_['FunctionArn']))
コード例 #6
0
    def test_0001_project(self):
        self._test_project_step('0001_project')
        self.assert_stack_succeed('p')
        self.assert_stack_succeed('r')

        lambda_ = self.get_lambda(
            utils.valid_cloudformation_name('cron:example'))
        rule_ = self.get_rule(
            utils.valid_cloudformation_name('every_night_rule'))
        targets = self.get_rule_targets(rule_['Name'])
        self.assertEqual(rule_['ScheduleExpression'], 'cron(0 20 * * ? *)')
        self.assertEqual(len(targets), 1)
        self.assertEqual(targets[0]['Arn'],
                         '{}:current'.format(lambda_['FunctionArn']))
コード例 #7
0
ファイル: base.py プロジェクト: Empia/gordon
    def register_resources_template(self, template):
        """Register one ``EventSourceMapping`` into the resources template.

        Note: We preprend a 30s Sleep before the creation of this resource
        because the IAM role of the lambda is not propagated fast enough uppon
        creation, and CloudFormation checks if the referenced lambda has
        permission to consume this stream on creation time.

        Because the ``Lambda`` and the ``EventSourceMapping`` are created in
        the same stack we need to introduce this as palliative measure, sorry!
        """
        sleep_lambda = 'lambda:contrib_helpers:sleep:current'
        sleep = Sleep.create_with(
            utils.valid_cloudformation_name(self.name, "Sleep"),
            DependsOn=[self.project.reference(sleep_lambda)],
            lambda_arn=troposphere.Ref(self.project.reference(sleep_lambda)),
            Time=30
        )
        template.add_resource(sleep)

        template.add_resource(
            awslambda.EventSourceMapping(
                self.in_project_cf_name,
                DependsOn=[sleep.name, self.get_function_name()],
                BatchSize=self.get_batch_size(),
                Enabled=self.get_enabled(),
                EventSourceArn=self.settings.get('stream'),
                FunctionName=troposphere.Ref(self.get_function_name()),
                StartingPosition=self.get_starting_position()
            )
        )
コード例 #8
0
ファイル: apigateway.py プロジェクト: timcosta/gordon-alt
    def get_or_create_resource(self, path, api, template):
        """Returns the ID of the Resource ``path`` in ``api``.
        If the resorce doesn't exits, create a new one and add it to
        ``template``."""

        # Add leading slash
        if path and path[0] != '/':
            path = '/{}'.format(path)

        # Remove trailing slash
        if path and path[-1] == '/':
            path = path[:-1]

        # Make / the root path
        if not path:
            path = '/'

        # Return API root resource if
        if path == '/':
            return troposphere.GetAtt(api, 'RootResourceId')

        if path in self._resources:
            return self._resources[path]

        parent_path, path_part = path.rsplit('/', 1)
        parent_id = self.get_or_create_resource(parent_path, api, template)
        resource = Resource(utils.valid_cloudformation_name(
            self.name, 'Resource', *path.split('/')),
                            ParentId=parent_id,
                            PathPart=path_part,
                            RestApiId=troposphere.Ref(api))

        template.add_resource(resource)
        self._resources[path] = troposphere.Ref(resource)
        return self._resources[path]
コード例 #9
0
ファイル: s3.py プロジェクト: revolunet/gordon
    def register_resources_template(self, template):

        extra = defaultdict(list)
        for notification_id, notification in six.iteritems(
                self._notifications):
            notification.register_destination_publish_permission(template)

            extra[notification.api_property].append(
                NotificationConfiguration(
                    Id=troposphere.Join('-', ['gordon', notification.id]),
                    DestinationArn=notification.get_destination_arn(),
                    Events=[e for e, _, _ in notification.events],
                    KeyFilters=[
                        KeyFilter(Name=name, Value=value)
                        for name, value in notification.filters
                    ]))

        bucket_notification_configuration_lambda = 'lambda:contrib_s3:bucket_notification_configuration:current'
        template.add_resource(
            S3BucketNotificationConfiguration.create_with(
                utils.valid_cloudformation_name(self.name),
                DependsOn=[
                    self.project.reference(
                        bucket_notification_configuration_lambda)
                ],
                lambda_arn=troposphere.Ref(
                    self.project.reference(
                        bucket_notification_configuration_lambda)),
                Bucket=self.get_bucket_name(),
                **dict([[k, v] for k, v in six.iteritems(extra) if v])))
コード例 #10
0
ファイル: s3.py プロジェクト: upside-services/gordon
    def register_resources_template(self, template):

        extra = defaultdict(list)
        for notification_id, notification in six.iteritems(self._notifications):
            notification.register_destination_publish_permission(template)

            extra[notification.api_property].append(
                NotificationConfiguration(
                    Id=troposphere.Join('-', ['gordon', notification.id]),
                    DestinationArn=notification.get_destination_arn(),
                    Events=[e for e, _, _ in notification.events],
                    KeyFilters=[KeyFilter(Name=name, Value=value) for name, value in notification.filters]
                )
            )

        bucket_notification_configuration_lambda = 'lambda:contrib_s3:bucket_notification_configuration:current'
        template.add_resource(
            S3BucketNotificationConfiguration.create_with(
                utils.valid_cloudformation_name(self.name),
                DependsOn=[self.project.reference(bucket_notification_configuration_lambda)],
                lambda_arn=troposphere.Ref(self.project.reference(bucket_notification_configuration_lambda)),
                Bucket=self.get_bucket_name(),
                **dict([[k, v] for k, v in six.iteritems(extra) if v])
            )
        )
コード例 #11
0
ファイル: s3.py プロジェクト: revolunet/gordon
 def register_destination_publish_permission(self, template):
     template.add_resource(
         sns.TopicPolicy(
             utils.valid_cloudformation_name(
                 self.bucket_notification_configuration.name, self.id,
                 'permission'),
             Topics=[self.get_destination_arn()],
             PolicyDocument={
                 "Version":
                 "2008-10-17",
                 "Id":
                 "PublicationPolicy",
                 "Statement": [{
                     "Effect": "Allow",
                     "Principal": {
                         "AWS": "*"
                     },
                     "Action": ["sns:Publish"],
                     "Resource": self.get_destination_arn(),
                     "Condition": {
                         "ArnEquals": {
                             "aws:SourceArn":
                             self.bucket_notification_configuration.
                             get_bucket_arn()
                         }
                     }
                 }]
             }))
コード例 #12
0
ファイル: lambdas.py プロジェクト: ryandub/gordon
    def get_role(self):
        """Returns the role this lambda function will use. Users can customize
        which role to apply by referencing the ARN of the role. If no Role
        is defined, gordon will create and assing one with the basic
        permissions suggested by AWS.

        Users can customize the policies attached to the role using
        ``policies`` in the lambda settings."""

        role = self.settings.get('role')

        if isinstance(role, six.string_types) or isinstance(role, troposphere.Ref):
            return role
        elif role is None:
            pass
        else:
            raise exceptions.InvalidLambdaRoleError(self.name, role)

        return iam.Role(
            utils.valid_cloudformation_name(self.name, 'role'),
            AssumeRolePolicyDocument={
                "Version": "2012-10-17",
                "Statement": [{
                    "Effect": "Allow",
                    "Principal": {
                        "Service": ["lambda.amazonaws.com"]
                    },
                    "Action": ["sts:AssumeRole"]
                }]
            },
            Policies=self._get_policies()
        )
コード例 #13
0
    def get_role(self):
        """Returns the role this lambda function will use. Users can customize
        which role to apply by referencing the ARN of the role. If no Role
        is defined, gordon will create and assing one with the basic
        permissions suggested by AWS.

        Users can customize the policies attached to the role using
        ``policies`` in the lambda settings."""

        role = self.settings.get('role')

        if isinstance(role, six.string_types) or isinstance(
                role, troposphere.Ref):
            return role
        elif role is None:
            pass
        else:
            raise exceptions.InvalidLambdaRoleError(self.name, role)

        return iam.Role(utils.valid_cloudformation_name(self.name, 'role'),
                        AssumeRolePolicyDocument={
                            "Version":
                            "2012-10-17",
                            "Statement": [{
                                "Effect": "Allow",
                                "Principal": {
                                    "Service": ["lambda.amazonaws.com"]
                                },
                                "Action": ["sts:AssumeRole"]
                            }]
                        },
                        Policies=self._get_policies())
コード例 #14
0
ファイル: base.py プロジェクト: rajeev/gordon
    def register_resources_template(self, template):
        """Register one ``EventSourceMapping`` into the resources template.

        Note: We preprend a 30s Sleep before the creation of this resource
        because the IAM role of the lambda is not propagated fast enough uppon
        creation, and CloudFormation checks if the referenced lambda has
        permission to consume this stream on creation time.

        Because the ``Lambda`` and the ``EventSourceMapping`` are created in
        the same stack we need to introduce this as palliative measure, sorry!
        """
        sleep_lambda = 'lambda:contrib_helpers:sleep:current'
        sleep = Sleep.create_with(
            utils.valid_cloudformation_name(self.name, "Sleep"),
            DependsOn=[self.project.reference(sleep_lambda)],
            lambda_arn=troposphere.Ref(self.project.reference(sleep_lambda)),
            Time=30)
        template.add_resource(sleep)

        template.add_resource(
            awslambda.EventSourceMapping(
                self.in_project_cf_name,
                DependsOn=[sleep.name, self.get_function_name()],
                BatchSize=self.get_batch_size(),
                Enabled=self.get_enabled(),
                EventSourceArn=self.settings.get('stream'),
                FunctionName=troposphere.Ref(self.get_function_name()),
                StartingPosition=self.get_starting_position()))
コード例 #15
0
ファイル: s3.py プロジェクト: upside-services/gordon
 def register_destination_publish_permission(self, template):
     template.add_resource(
         sns.TopicPolicy(
             utils.valid_cloudformation_name(
                 self.bucket_notification_configuration.name,
                 self.id,
                 'permission'
             ),
             Topics=[self.get_destination_arn()],
             PolicyDocument={
                 "Version": "2008-10-17",
                 "Id": "PublicationPolicy",
                 "Statement": [{
                     "Effect": "Allow",
                     "Principal": {
                       "AWS": "*"
                     },
                     "Action": ["sns:Publish"],
                     "Resource": self.get_destination_arn(),
                     "Condition": {
                         "ArnEquals": {"aws:SourceArn": self.bucket_notification_configuration.get_bucket_arn()}
                     }
                 }]
             }
         )
     )
コード例 #16
0
    def __init__(self, *args, **kwargs):
        super(Lambda, self).__init__(*args, **kwargs)
        self.current_alias_project_name = '{}:current'.format(
            self.in_project_name)
        self.current_alias_cf_name = utils.valid_cloudformation_name(
            self.name, "CurrentAlias")

        self.project.register_resource_reference(
            self.current_alias_project_name, self.current_alias_cf_name, self)
コード例 #17
0
ファイル: lambdas.py プロジェクト: ryandub/gordon
    def __init__(self, *args, **kwargs):
        super(Lambda, self).__init__(*args, **kwargs)
        self.current_alias_project_name = '{}:current'.format(self.in_project_name)
        self.current_alias_cf_name = utils.valid_cloudformation_name(self.name, "CurrentAlias")

        self.project.register_resource_reference(
            self.current_alias_project_name,
            self.current_alias_cf_name,
            self
        )
コード例 #18
0
ファイル: tests.py プロジェクト: T2BE/gordon
    def test_0001_project(self):
        self._test_project_step('0001_project')

        self.assert_stack_succeed('p')
        self.assert_stack_succeed('r')

        lambda_ = self.get_lambda(valid_cloudformation_name('kinesisconsumer:consumer'))
        self.assertEqual(lambda_['Runtime'], 'python2.7')

        aliases = self.get_lambda_aliases(function_name=lambda_['FunctionName'])
        self.assertEqual(aliases.keys(), ['current'])
コード例 #19
0
ファイル: s3.py プロジェクト: revolunet/gordon
 def register_destination_publish_permission(self, template):
     template.add_resource(
         awslambda.Permission(
             utils.valid_cloudformation_name(
                 self.bucket_notification_configuration.name, self.id,
                 'permission'),
             Action="lambda:InvokeFunction",
             FunctionName=self.get_destination_arn(),
             Principal="s3.amazonaws.com",
             SourceAccount=troposphere.Ref(troposphere.AWS_ACCOUNT_ID),
         ))
コード例 #20
0
ファイル: events.py プロジェクト: Empia/gordon
    def register_resources_template(self, template):
        targets, target_lambdas = [], []
        for name, target in six.iteritems(self.settings.get('targets', {})):
            target_lambdas.append(target['lambda'])
            targets.append(
                events.Target(
                    Arn=self.get_destination_arn(target['lambda']),
                    Id=self.get_function_name(target['lambda']),
                    Input=target.get('input', ''),
                    InputPath=target.get('input_path', ''),
                )
            )

        rule = events.Rule(
            utils.valid_cloudformation_name(self.name, "Rule"),
            Description=self.settings.get('description', ''),
            EventPattern=self.settings.get('event_pattern', troposphere.Ref(troposphere.AWS_NO_VALUE)),
            ScheduleExpression=self.settings.get('schedule_expression', troposphere.Ref(troposphere.AWS_NO_VALUE)),
            State=self.get_enabled(),
            Targets=targets
        )
        template.add_resource(rule)

        for lambda_ in target_lambdas:
            template.add_resource(
                troposphere.awslambda.Permission(
                    utils.valid_cloudformation_name(
                        self.name,
                        'rule',
                        'permission'
                    ),
                    Action="lambda:InvokeFunction",
                    FunctionName=self.get_destination_arn(lambda_),
                    Principal="events.amazonaws.com",
                    SourceArn=troposphere.GetAtt(
                        rule, 'Arn'
                    ),
                )
            )
コード例 #21
0
    def test_0001_project(self):
        self._test_project_step('0001_project')

        self.assert_stack_succeed('p')
        self.assert_stack_succeed('r')

        lambda_ = self.get_lambda(
            valid_cloudformation_name('kinesisconsumer:consumer'))
        self.assertEqual(lambda_['Runtime'], 'python2.7')

        aliases = self.get_lambda_aliases(
            function_name=lambda_['FunctionName'])
        self.assertEqual(list(aliases.keys()), ['current'])
コード例 #22
0
ファイル: s3.py プロジェクト: upside-services/gordon
 def register_destination_publish_permission(self, template):
     template.add_resource(
         awslambda.Permission(
             utils.valid_cloudformation_name(
                 self.bucket_notification_configuration.name,
                 self.id,
                 'permission'
             ),
             Action="lambda:InvokeFunction",
             FunctionName=self.get_destination_arn(),
             Principal="s3.amazonaws.com",
             SourceAccount=troposphere.Ref(troposphere.AWS_ACCOUNT_ID),
         )
     )
コード例 #23
0
ファイル: base.py プロジェクト: rajeev/gordon
    def __init__(self, name, settings, project=None, app=None):
        self.name = name
        self.app = app
        self.project = project or self.app.project
        self.settings = settings
        for key in self.required_settings:
            if key not in self.settings:
                raise exceptions.ResourceSettingRequiredError(self.name, key)

        self.in_project_name = self._get_in_project_name()
        self.in_project_cf_name = utils.valid_cloudformation_name(
            self.in_project_name.split(':', 1)[1])

        self.project.register_resource_reference(self.in_project_name,
                                                 self.in_project_cf_name, self)
コード例 #24
0
    def test_0001_project(self):
        self._test_project_step('0001_project')
        self.assert_stack_succeed('p')
        self.assert_stack_succeed('r')

        lambda_ = self.get_lambda(
            utils.valid_cloudformation_name('javaexample:javaexample'))
        self.assertEqual(lambda_['Runtime'], 'java8')
        self.assertEqual(lambda_['Description'], 'My description')
        self.assertEqual(lambda_['MemorySize'], 192)
        self.assertEqual(lambda_['Timeout'], 123)

        aliases = self.get_lambda_aliases(
            function_name=lambda_['FunctionName'])
        self.assertEqual(list(aliases.keys()), ['current'])

        response = self.invoke_lambda(function_name=lambda_['FunctionName'],
                                      payload={'key1': 'hello'})
        self.assert_lambda_response(response, 'hello')
コード例 #25
0
ファイル: tests.py プロジェクト: T2BE/gordon
    def test_0001_project(self):
        self._test_project_step('0001_project')
        self.assert_stack_succeed('p')
        self.assert_stack_succeed('r')

        lambda_ = self.get_lambda(utils.valid_cloudformation_name('pyexample:pyexample'))
        self.assertEqual(lambda_['Runtime'], 'python2.7')
        self.assertEqual(lambda_['Description'], 'My description')
        self.assertEqual(lambda_['MemorySize'], 192)
        self.assertEqual(lambda_['Timeout'], 123)

        aliases = self.get_lambda_aliases(function_name=lambda_['FunctionName'])
        self.assertEqual(aliases.keys(), ['current'])

        response = self.invoke_lambda(
            function_name=lambda_['FunctionName'],
            payload={'key1': 'hello'}
        )
        self.assert_lambda_response(response, 'hello')
コード例 #26
0
ファイル: base.py プロジェクト: Empia/gordon
    def __init__(self, name, settings, project=None, app=None):
        self.name = name
        self.app = app
        self.project = project or self.app.project
        self.settings = settings
        for key in self.required_settings:
            if key not in self.settings:
                raise exceptions.ResourceSettingRequiredError(self.name, key)

        self.in_project_name = self._get_in_project_name()
        self.in_project_cf_name = utils.valid_cloudformation_name(
            self.in_project_name.split(':', 1)[1]
        )

        self.project.register_resource_reference(
            self.in_project_name,
            self.in_project_cf_name,
            self
        )
コード例 #27
0
    def test_0002_project(self):
        self._test_project_step('0002_project')
        self.assert_stack_succeed('p')
        self.assert_stack_succeed('r')

        lambda_ = self.get_lambda(utils.valid_cloudformation_name('pyexample:pyexample'))
        self.assertEqual(lambda_['Runtime'], 'python2.7')
        self.assertEqual(lambda_['Description'], 'My second description')
        self.assertEqual(lambda_['MemorySize'], 256)
        self.assertEqual(lambda_['Timeout'], 199)

        aliases = self.get_lambda_aliases(function_name=lambda_['FunctionName'])
        self.assertEqual(list(aliases.keys()), ['current'])

        response = self.invoke_lambda(
            function_name=lambda_['FunctionName'],
            payload={'key1': 'hello', 'key2': 'bye'}
        )
        self.assert_lambda_response(response, 'bye')
コード例 #28
0
ファイル: apigateway.py プロジェクト: elkelk/gordon
    def get_or_create_resource(self, path, api, template):
        """Returns the ID of the Resource ``path`` in ``api``.
        If the resorce doesn't exits, create a new one and add it to
        ``template``."""

        # Add leading slash
        if path and path[0] != '/':
            path = '/{}'.format(path)

        # Remove trailing slash
        if path and path[-1] == '/':
            path = path[:-1]

        # Make / the root path
        if not path:
            path = '/'

        # Return API root resource if
        if path == '/':
            return troposphere.GetAtt(api, 'RootResourceId')

        if path in self._resources:
            return self._resources[path]

        parent_path, path_part = path.rsplit('/', 1)
        parent_id = self.get_or_create_resource(parent_path, api, template)
        resource = Resource(
            utils.valid_cloudformation_name(self.name, 'Resource', *path.split('/')),
            ParentId=parent_id,
            PathPart=path_part,
            RestApiId=troposphere.Ref(api)
        )

        template.add_resource(resource)
        self._resources[path] = troposphere.Ref(resource)
        return self._resources[path]
コード例 #29
0
    def register_resources_template(self, template):
        """Register the lambda Function into the troposphere template. If
        this function requires a custom Role, register it too."""

        role = self.get_role()
        depends_on = []
        if isinstance(role, iam.Role):
            template.add_resource(role)
            depends_on.append(role.name)
            role = troposphere.GetAtt(role, 'Arn')

        template.add_parameter(
            troposphere.Parameter(
                utils.valid_cloudformation_name(self.name, "s3version"),
                Type="String",
            ))

        extra = {}
        if self.settings.get('vpc'):
            vpc = self.project.get_resource('vpc::{}'.format(
                self.settings.get('vpc')))

            if isinstance(vpc.settings['security-groups'], troposphere.Ref):
                vpc.settings[
                    'security-groups']._type = 'List<AWS::EC2::SecurityGroup::Id>'

            if isinstance(vpc.settings['subnet-ids'], troposphere.Ref):
                vpc.settings['subnet-ids']._type = 'List<AWS::EC2::Subnet::Id>'

            extra['VpcConfig'] = awslambda.VPCConfig(
                SecurityGroupIds=vpc.settings['security-groups'],
                SubnetIds=vpc.settings['subnet-ids'])

        function = template.add_resource(
            awslambda.Function(self.in_project_cf_name,
                               DependsOn=depends_on,
                               Code=awslambda.Code(
                                   S3Bucket=troposphere.Ref("CodeBucket"),
                                   S3Key=self.get_bucket_key(),
                                   S3ObjectVersion=troposphere.Ref(
                                       utils.valid_cloudformation_name(
                                           self.name, "s3version")),
                               ),
                               Description=self.settings.get(
                                   'description', ''),
                               Handler=self.get_handler(),
                               MemorySize=self.get_memory(),
                               Role=role,
                               Runtime=self.get_runtime(),
                               Timeout=self.get_timeout(),
                               **extra))

        lambda_version = 'lambda:contrib_lambdas:version'
        lambda_ref = troposphere.GetAtt(self.project.reference(lambda_version),
                                        'Arn')
        if not self.in_project_name.startswith('lambda:contrib_lambdas:'):
            lambda_version = '{}:current'.format(lambda_version)
            lambda_ref = troposphere.Ref(
                self.project.reference(lambda_version))

        version = template.add_resource(
            LambdaVersion.create_with(
                utils.valid_cloudformation_name(self.name, "Version"),
                DependsOn=[
                    self.project.reference(lambda_version), function.name
                ],
                lambda_arn=lambda_ref,
                FunctionName=troposphere.Ref(function),
                S3ObjectVersion=troposphere.Ref(
                    utils.valid_cloudformation_name(self.name, "s3version")),
            ))

        alias = template.add_resource(
            awslambda.Alias(
                self.current_alias_cf_name,
                DependsOn=[version.name],
                FunctionName=troposphere.Ref(function),
                FunctionVersion=troposphere.GetAtt(version, "Version"),
                Name="current",
            ))
        if self._get_true_false('cli-output', 't'):
            template.add_output([
                troposphere.Output(
                    utils.valid_cloudformation_name("Clioutput",
                                                    self.in_project_name),
                    Value=troposphere.Ref(alias),
                )
            ])
コード例 #30
0
ファイル: lambdas.py プロジェクト: ryandub/gordon
    def register_resources_template(self, template):
        """Register the lambda Function into the troposphere template. If
        this function requires a custom Role, register it too."""

        role = self.get_role()
        depends_on = []
        if isinstance(role, iam.Role):
            template.add_resource(role)
            depends_on.append(role.name)
            role = troposphere.GetAtt(role, 'Arn')

        template.add_parameter(
            troposphere.Parameter(
                utils.valid_cloudformation_name(self.name, "s3version"),
                Type="String",
            )
        )

        extra = {}
        if self.settings.get('vpc'):
            vpc = self.project.get_resource('vpc::{}'.format(self.settings.get('vpc')))
            extra['VpcConfig'] = awslambda.VPCConfig(
                SecurityGroupIds=vpc.settings['security-groups'],
                SubnetIds=vpc.settings['subnet-ids']
            )

        function = template.add_resource(
            awslambda.Function(
                self.in_project_cf_name,
                DependsOn=depends_on,
                Code=awslambda.Code(
                    S3Bucket=troposphere.Ref("CodeBucket"),
                    S3Key=self.get_bucket_key(),
                    S3ObjectVersion=troposphere.Ref(
                        utils.valid_cloudformation_name(self.name, "s3version")
                    ),
                ),
                Description=self.settings.get('description', ''),
                Handler=self.get_handler(),
                MemorySize=self.get_memory(),
                Role=role,
                Runtime=self.get_runtime(),
                Timeout=self.get_timeout(),
                **extra
            )
        )

        lambda_version = 'lambda:contrib_lambdas:version'
        lambda_ref = troposphere.GetAtt(self.project.reference(lambda_version), 'Arn')
        if not self.in_project_name.startswith('lambda:contrib_lambdas:'):
            lambda_version = '{}:current'.format(lambda_version)
            lambda_ref = troposphere.Ref(self.project.reference(lambda_version))

        version = template.add_resource(
            LambdaVersion.create_with(
                utils.valid_cloudformation_name(self.name, "Version"),
                DependsOn=[
                    self.project.reference(lambda_version),
                    function.name
                ],
                lambda_arn=lambda_ref,
                FunctionName=troposphere.Ref(
                    function
                ),
                S3ObjectVersion=troposphere.Ref(
                   utils.valid_cloudformation_name(self.name, "s3version")
                ),
            )
        )

        alias = template.add_resource(
            awslambda.Alias(
                self.current_alias_cf_name,
                DependsOn=[
                    version.name
                ],
                FunctionName=troposphere.Ref(
                    function
                ),
                FunctionVersion=troposphere.GetAtt(
                    version, "Version"
                ),
                Name="current",
            )
        )
        if self._get_true_false('cli-output', 't'):
            template.add_output([
                troposphere.Output(
                    utils.valid_cloudformation_name("Clioutput", self.in_project_name),
                    Value=troposphere.Ref(alias),
                )
            ])
コード例 #31
0
ファイル: tests.py プロジェクト: timcosta/gordon-alt
    def test_0001_project(self):
        self._test_project_step('0001_project')
        self.assert_stack_succeed('p')
        self.assert_stack_succeed('r')

        lambda_ = self.get_lambda(utils.valid_cloudformation_name('pyexample:hellopy'))
        self.assertEqual(lambda_['Runtime'], 'python2.7')
        self.assertEqual(lambda_['Description'], 'My hello description')
        self.assertEqual(lambda_['MemorySize'], 192)
        self.assertEqual(lambda_['Timeout'], 123)

        aliases = self.get_lambda_aliases(function_name=lambda_['FunctionName'])
        self.assertEqual(list(aliases.keys()), ['current'])

        response = self.invoke_lambda(
            function_name=lambda_['FunctionName'],
            payload={}
        )
        self.assert_lambda_response(response, 'hello')

        lambda_ = self.get_lambda(utils.valid_cloudformation_name('pyexample:byepy'))
        self.assertEqual(lambda_['Runtime'], 'python2.7')
        self.assertEqual(lambda_['Description'], 'My bye description')
        self.assertEqual(lambda_['MemorySize'], 192)
        self.assertEqual(lambda_['Timeout'], 123)

        aliases = self.get_lambda_aliases(function_name=lambda_['FunctionName'])
        self.assertEqual(list(aliases.keys()), ['current'])

        response = self.invoke_lambda(
            function_name=lambda_['FunctionName'],
            payload={}
        )
        self.assert_lambda_response(response, 'bye')

        client = boto3.client('apigateway')
        api = [a for a in client.get_rest_apis()['items'] if a['name'] == 'helloapi-{}'.format(self.uid)][0]
        endpoint = 'https://{}.execute-api.{}.amazonaws.com/{}'.format(api['id'], os.environ['AWS_DEFAULT_REGION'], self.uid)

        response = requests.get(endpoint)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content.decode('utf-8'), '"hello"')

        response = requests.get('{}/404'.format(endpoint))
        self.assertEqual(response.status_code, 404)
        self.assertEqual(response.content.decode('utf-8'), '"hello"')

        response = requests.get('{}/shop/2'.format(endpoint))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content.decode('utf-8'), '"hello"')

        response = requests.get('{}/http'.format(endpoint))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(json.loads(response.content.decode('utf-8'))['args'], {'hello': 'world'})

        response = requests.get('{}/complex'.format(endpoint))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content.decode('utf-8'), '"hello"')

        response = requests.post('{}/complex'.format(endpoint))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content.decode('utf-8'), '"bye"')
コード例 #32
0
ファイル: lambdas.py プロジェクト: ryandub/gordon
    def _get_policies(self):
        """Returns a list of policies to attach to the IAM Role of this Lambda.
        Users can add more policies to this Role by defining policy documents
        in the settings of the lambda under the ``policies`` key."""

        policies = []

        if self._get_true_false('auto-run-policy', 't'):
            policies.append(
                iam.Policy(
                    PolicyName=utils.valid_cloudformation_name(self.name, 'logs', 'policy'),
                    PolicyDocument={
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": [
                                    "lambda:InvokeFunction"
                                ],
                                "Resource": [
                                    "*"
                                ]
                            },
                            {
                                "Effect": "Allow",
                                "Action": [
                                    "logs:CreateLogGroup",
                                    "logs:CreateLogStream",
                                    "logs:PutLogEvents"
                                ],
                                "Resource": "arn:aws:logs:*:*:*",
                            }
                        ]
                    }
                )
            )

        if self.settings.get('vpc') and self._get_true_false('auto-vpc-policy', 't'):
            policies.append(
                iam.Policy(
                    PolicyName=utils.valid_cloudformation_name(self.name, 'vpc'),
                    PolicyDocument={
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": [
                                    "ec2:CreateNetworkInterface"
                                ],
                                "Resource": [
                                    "*"
                                ]
                            }
                        ]
                    }
                )
            )

        for policy_nme, policy_document in six.iteritems(self.settings.get('policies', {})):
            policies.append(
                iam.Policy(
                    PolicyName=utils.valid_cloudformation_name(self.name, policy_nme, 'policy'),
                    PolicyDocument=policy_document
                )
            )
        return policies
コード例 #33
0
ファイル: apigateway.py プロジェクト: elkelk/gordon
    def register_resources_template(self, template):

        deployment_resources = []
        api = RestApi(
            self.in_project_cf_name,
            Name=troposphere.Join("-", [self.name, troposphere.Ref('Stage')]),
            Description=self.settings.get('description', '')
        )
        template.add_resource(api)
        deployment_resources.append(api)

        invoke_lambda_role = troposphere.iam.Role(
            utils.valid_cloudformation_name(self.name, 'Role'),
            AssumeRolePolicyDocument={
                "Version": "2012-10-17",
                "Statement": [{
                    "Effect": "Allow",
                    "Principal": {
                        "Service": ["apigateway.amazonaws.com"]
                    },
                    "Action": ["sts:AssumeRole"]
                }]
            },
            Policies=[
                troposphere.iam.Policy(
                    PolicyName=utils.valid_cloudformation_name(self.name, 'Role', 'Policy'),
                    PolicyDocument={
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": [
                                    "lambda:InvokeFunction"
                                ],
                                "Resource": [
                                    "*"
                                ]
                            }
                        ]
                    }
                )
            ]
        )

        template.add_resource(invoke_lambda_role)
        deployment_resources.append(invoke_lambda_role)

        deployment_dependencies = []
        for path, resource in six.iteritems(self.settings.get('resources', {})):
            resource_reference = self.get_or_create_resource(path, api, template)
            methods = resource['methods']

            if isinstance(methods, six.string_types):
                methods = [methods]

            if not isinstance(methods, dict):
                method_properties = copy.deepcopy(resource)
                method_properties.pop('methods', None)
                methods = dict([[method, method_properties] for method in methods])

            for method, configuration in six.iteritems(methods):
                method_name = [self.name]
                method_name.extend(path.split('/'))
                method_name.append(method)

                extra = {}
                if 'parameters' in configuration:
                    extra['RequestParameters'] = configuration['parameters']
                m = Method(
                    utils.valid_cloudformation_name(*method_name),
                    HttpMethod=method,
                    AuthorizationType=self.get_authorization_type(configuration),
                    ApiKeyRequired=self.get_api_key_required(configuration),
                    Integration=self.get_integration(configuration, invoke_lambda_role),
                    MethodResponses=self.get_method_responses(configuration),
                    ResourceId=resource_reference,
                    RestApiId=troposphere.Ref(api),
                    **extra
                )
                template.add_resource(m)
                deployment_dependencies.append(m.name)
                deployment_resources.append(m)

        deploy_hash = hashlib.sha1(six.text_type(uuid.uuid4()).encode('utf-8')).hexdigest()
        deploy = Deployment(
            utils.valid_cloudformation_name(self.name, "Deployment", deploy_hash[:8]),
            DependsOn=sorted(deployment_dependencies),
            StageName=troposphere.Ref('Stage'),
            RestApiId=troposphere.Ref(api)
        )

        template.add_resource(deploy)

        if self._get_true_false('cli-output', 't'):
            template.add_output([
                troposphere.Output(
                    utils.valid_cloudformation_name("Clioutput", self.in_project_name),
                    Value=troposphere.Join(
                        "",
                        [
                            "https://",
                            troposphere.Ref(api),
                            ".execute-api.",
                            troposphere.Ref(troposphere.AWS_REGION),
                            ".amazonaws.com/",
                            troposphere.Ref('Stage')
                        ]
                    ),
                )
            ])
コード例 #34
0
    def register_resources_template(self, template):

        deployment_resources = []
        api = RestApi(
            self.in_project_cf_name,
            Name=troposphere.Join("-", [self.name, troposphere.Ref('Stage')]),
            Description=self.settings.get('description', '')
        )
        template.add_resource(api)
        deployment_resources.append(api)

        invoke_lambda_role = troposphere.iam.Role(
            utils.valid_cloudformation_name(self.name, 'Role'),
            AssumeRolePolicyDocument={
                "Version": "2012-10-17",
                "Statement": [{
                    "Effect": "Allow",
                    "Principal": {
                        "Service": ["apigateway.amazonaws.com"]
                    },
                    "Action": ["sts:AssumeRole"]
                }]
            },
            Policies=[
                troposphere.iam.Policy(
                    PolicyName=utils.valid_cloudformation_name(self.name, 'Role', 'Policy'),
                    PolicyDocument={
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": [
                                    "lambda:InvokeFunction"
                                ],
                                "Resource": [
                                    "*"
                                ]
                            }
                        ]
                    }
                )
            ]
        )

        template.add_resource(invoke_lambda_role)
        deployment_resources.append(invoke_lambda_role)

        deployment_dependencies = []
        for path, resource in six.iteritems(self.settings.get('resources', {})):
            resource_reference = self.get_or_create_resource(path, api, template)
            methods = resource['methods']

            if isinstance(methods, six.string_types):
                methods = [methods]

            if not isinstance(methods, dict):
                method_properties = copy.deepcopy(resource)
                method_properties.pop('methods', None)
                methods = dict([[method, method_properties] for method in methods])

            for method, configuration in six.iteritems(methods):
                method_name = [self.name]
                method_name.extend(path.split('/'))
                method_name.append(method)

                extra = {}
                if 'parameters' in configuration:
                    extra['RequestParameters'] = configuration['parameters']
                m = Method(
                    utils.valid_cloudformation_name(*method_name),
                    HttpMethod=method,
                    AuthorizationType=self.get_authorization_type(configuration),
                    ApiKeyRequired=self.get_api_key_required(configuration),
                    Integration=self.get_integration(configuration, invoke_lambda_role),
                    MethodResponses=self.get_method_responses(configuration),
                    ResourceId=resource_reference,
                    RestApiId=troposphere.Ref(api),
                    **extra
                )
                template.add_resource(m)
                deployment_dependencies.append(m.name)
                deployment_resources.append(m)

        deploy_hash = hashlib.sha1(six.text_type(uuid.uuid4()).encode('utf-8')).hexdigest()
        deploy = Deployment(
            utils.valid_cloudformation_name(self.name, "Deployment", deploy_hash[:8]),
            DependsOn=sorted(deployment_dependencies),
            StageName=troposphere.Ref('Stage'),
            RestApiId=troposphere.Ref(api)
        )

        template.add_resource(deploy)

        if self._get_true_false('cli-output', 't'):
            template.add_output([
                troposphere.Output(
                    utils.valid_cloudformation_name("Clioutput", self.in_project_name),
                    Value=troposphere.Join(
                        "",
                        [
                            "https://",
                            troposphere.Ref(api),
                            ".execute-api.",
                            troposphere.Ref(troposphere.AWS_REGION),
                            ".amazonaws.com/",
                            troposphere.Ref('Stage')
                        ]
                    ),
                )
            ])