Exemple #1
0
 def _plan_managediamrole(self, resource):
     # type: (models.ManagedIAMRole) -> Sequence[InstructionMsg]
     document = resource.policy.document
     role_exists = self._remote_state.resource_exists(resource)
     varname = '%s_role_arn' % resource.role_name
     if not role_exists:
         return [(models.APICall(
             method_name='create_role',
             params={
                 'name': resource.role_name,
                 'trust_policy': resource.trust_policy,
                 'policy': document
             },
             output_var=varname,
         ), "Creating IAM role: %s\n" % resource.role_name),
                 models.RecordResourceVariable(
                     resource_type='iam_role',
                     resource_name=resource.resource_name,
                     name='role_arn',
                     variable_name=varname,
                 ),
                 models.RecordResourceValue(
                     resource_type='iam_role',
                     resource_name=resource.resource_name,
                     name='role_name',
                     value=resource.role_name,
                 )]
     role_arn = self._remote_state.resource_deployed_values(
         resource)['role_arn']
     return [
         models.StoreValue(name=varname, value=role_arn),
         (models.APICall(
             method_name='put_role_policy',
             params={
                 'role_name': resource.role_name,
                 'policy_name': resource.role_name,
                 'policy_document': document
             },
         ), "Updating policy for IAM role: %s\n" % resource.role_name),
         models.RecordResourceVariable(
             resource_type='iam_role',
             resource_name=resource.resource_name,
             name='role_arn',
             variable_name=varname,
         ),
         models.RecordResourceValue(
             resource_type='iam_role',
             resource_name=resource.resource_name,
             name='role_name',
             value=resource.role_name,
         )
     ]
Exemple #2
0
 def _plan_s3bucketnotification(self, resource):
     # type: (models.S3BucketNotification) -> Sequence[InstructionMsg]
     function_arn = Variable('%s_lambda_arn' %
                             resource.lambda_function.resource_name)
     return [
         models.APICall(
             method_name='add_permission_for_s3_event',
             params={
                 'bucket': resource.bucket,
                 'function_arn': function_arn
             },
         ),
         (models.APICall(method_name='connect_s3_bucket_to_lambda',
                         params={
                             'bucket': resource.bucket,
                             'function_arn': function_arn,
                             'prefix': resource.prefix,
                             'suffix': resource.suffix,
                             'events': resource.events
                         }),
          'Configuring S3 events in bucket %s to function %s\n' %
          (resource.bucket, resource.lambda_function.function_name)),
         models.RecordResourceValue(
             resource_type='s3_event',
             resource_name=resource.resource_name,
             name='bucket',
             value=resource.bucket,
         ),
         models.RecordResourceVariable(
             resource_type='s3_event',
             resource_name=resource.resource_name,
             name='lambda_arn',
             variable_name=function_arn.name,
         ),
     ]
Exemple #3
0
    def _create_cloudwatchevent(self, resource):
        # type: (models.CloudWatchEventBase) -> Sequence[InstructionMsg]

        function_arn = Variable('%s_lambda_arn' %
                                resource.lambda_function.resource_name)

        params = {'rule_name': resource.rule_name}
        if isinstance(resource, models.ScheduledEvent):
            resource = cast(models.ScheduledEvent, resource)
            params['schedule_expression'] = resource.schedule_expression
            if resource.rule_description is not None:
                params['rule_description'] = resource.rule_description
        else:
            resource = cast(models.CloudWatchEvent, resource)
            params['event_pattern'] = resource.event_pattern

        plan = [
            models.APICall(
                method_name='get_or_create_rule_arn',
                params=params,
                output_var='rule-arn',
            ),
            models.APICall(method_name='connect_rule_to_lambda',
                           params={
                               'rule_name': resource.rule_name,
                               'function_arn': function_arn
                           }),
            models.APICall(
                method_name='add_permission_for_cloudwatch_event',
                params={
                    'rule_arn': Variable('rule-arn'),
                    'function_arn': function_arn
                },
            ),
            # You need to remove targets (which have IDs)
            # before you can delete a rule.
            models.RecordResourceValue(
                resource_type='cloudwatch_event',
                resource_name=resource.resource_name,
                name='rule_name',
                value=resource.rule_name,
            )
        ]
        return plan
Exemple #4
0
 def test_can_plan_s3_event(self):
     function = create_function_resource('function_name')
     bucket_event = models.S3BucketNotification(
         resource_name='function_name-s3event',
         bucket='mybucket',
         events=['s3:ObjectCreated:*'],
         prefix=None,
         suffix=None,
         lambda_function=function,
     )
     plan = self.determine_plan(bucket_event)
     self.assert_apicall_equals(
         plan[0],
         models.APICall(
             method_name='add_permission_for_s3_event',
             params={
                 'bucket': 'mybucket',
                 'function_arn': Variable('function_name_lambda_arn'),
             },
         ))
     self.assert_apicall_equals(
         plan[1],
         models.APICall(
             method_name='connect_s3_bucket_to_lambda',
             params={
                 'bucket': 'mybucket',
                 'function_arn': Variable('function_name_lambda_arn'),
                 'events': ['s3:ObjectCreated:*'],
                 'prefix': None,
                 'suffix': None,
             },
         ))
     assert plan[2] == models.RecordResourceValue(
         resource_type='s3_event',
         resource_name='function_name-s3event',
         name='bucket',
         value='mybucket',
     )
     assert plan[3] == models.RecordResourceVariable(
         resource_type='s3_event',
         resource_name='function_name-s3event',
         name='lambda_arn',
         variable_name='function_name_lambda_arn',
     )
Exemple #5
0
 def test_can_plan_scheduled_event(self):
     function = create_function_resource('function_name')
     event = models.ScheduledEvent(
         resource_name='bar',
         rule_name='myrulename',
         schedule_expression='rate(5 minutes)',
         lambda_function=function,
     )
     plan = self.determine_plan(event)
     assert len(plan) == 4
     self.assert_apicall_equals(
         plan[0],
         models.APICall(
             method_name='get_or_create_rule_arn',
             params={
                 'rule_name': 'myrulename',
                 'schedule_expression': 'rate(5 minutes)',
             },
             output_var='rule-arn',
         ))
     self.assert_apicall_equals(
         plan[1],
         models.APICall(method_name='connect_rule_to_lambda',
                        params={
                            'rule_name': 'myrulename',
                            'function_arn':
                            Variable('function_name_lambda_arn')
                        }))
     self.assert_apicall_equals(
         plan[2],
         models.APICall(
             method_name='add_permission_for_scheduled_event',
             params={
                 'rule_arn': Variable('rule-arn'),
                 'function_arn': Variable('function_name_lambda_arn'),
             },
         ))
     assert plan[3] == models.RecordResourceValue(
         resource_type='cloudwatch_event',
         resource_name='bar',
         name='rule_name',
         value='myrulename',
     )
Exemple #6
0
 def _plan_scheduledevent(self, resource):
     # type: (models.ScheduledEvent) -> Sequence[_INSTRUCTION_MSG]
     function_arn = Variable('%s_lambda_arn' %
                             resource.lambda_function.resource_name)
     # Because the underlying API calls have PUT semantics,
     # we don't have to check if the resource exists and have
     # a separate code path for updates.  We could however
     # check if the resource exists to avoid unnecessary API
     # calls, but that's a later optimization.
     plan = [
         models.APICall(
             method_name='get_or_create_rule_arn',
             params={
                 'rule_name': resource.rule_name,
                 'schedule_expression': resource.schedule_expression
             },
             output_var='rule-arn',
         ),
         models.APICall(method_name='connect_rule_to_lambda',
                        params={
                            'rule_name': resource.rule_name,
                            'function_arn': function_arn
                        }),
         models.APICall(
             method_name='add_permission_for_scheduled_event',
             params={
                 'rule_arn': Variable('rule-arn'),
                 'function_arn': function_arn
             },
         ),
         # You need to remote targets (which have IDs)
         # before you can delete a rule.
         models.RecordResourceValue(
             resource_type='cloudwatch_event',
             resource_name=resource.resource_name,
             name='rule_name',
             value=resource.rule_name,
         )
     ]
     return plan
Exemple #7
0
 def _plan_sqseventsource(self, resource):
     # type: (models.SQSEventSource) -> Sequence[InstructionMsg]
     queue_arn_varname = '%s_queue_arn' % resource.resource_name
     uuid_varname = '%s_uuid' % resource.resource_name
     function_arn = Variable('%s_lambda_arn' %
                             resource.lambda_function.resource_name)
     instruction_for_queue_arn = [
         models.BuiltinFunction(
             'parse_arn',
             [function_arn],
             output_var='parsed_lambda_arn',
         ),
         models.JPSearch('account_id',
                         input_var='parsed_lambda_arn',
                         output_var='account_id'),
         models.JPSearch('region',
                         input_var='parsed_lambda_arn',
                         output_var='region_name'),
         models.StoreValue(
             name=queue_arn_varname,
             value=StringFormat(
                 'arn:aws:sqs:{region_name}:{account_id}:%s' %
                 (resource.queue),
                 ['region_name', 'account_id'],
             ),
         ),
     ]  # type: List[InstructionMsg]
     if self._remote_state.resource_exists(resource):
         deployed = self._remote_state.resource_deployed_values(resource)
         uuid = deployed['event_uuid']
         return instruction_for_queue_arn + [
             models.APICall(method_name='update_sqs_event_source',
                            params={
                                'event_uuid': uuid,
                                'batch_size': resource.batch_size
                            }),
             models.RecordResourceValue(
                 resource_type='sqs_event',
                 resource_name=resource.resource_name,
                 name='queue_arn',
                 value=deployed['queue_arn'],
             ),
             models.RecordResourceValue(
                 resource_type='sqs_event',
                 resource_name=resource.resource_name,
                 name='event_uuid',
                 value=uuid,
             ),
             models.RecordResourceValue(
                 resource_type='sqs_event',
                 resource_name=resource.resource_name,
                 name='queue',
                 value=resource.queue,
             ),
             models.RecordResourceValue(
                 resource_type='sqs_event',
                 resource_name=resource.resource_name,
                 name='lambda_arn',
                 value=deployed['lambda_arn'],
             ),
         ]
     return instruction_for_queue_arn + [
         (models.APICall(
             method_name='create_sqs_event_source',
             params={
                 'queue_arn': Variable(queue_arn_varname),
                 'batch_size': resource.batch_size,
                 'function_name': function_arn
             },
             output_var=uuid_varname,
         ), 'Subscribing %s to SQS queue %s\n' %
          (resource.lambda_function.function_name, resource.queue)),
         models.RecordResourceVariable(
             resource_type='sqs_event',
             resource_name=resource.resource_name,
             name='queue_arn',
             variable_name=queue_arn_varname,
         ),
         # We record this because this is what's used to unsubscribe
         # lambda to the SQS queue.
         models.RecordResourceVariable(
             resource_type='sqs_event',
             resource_name=resource.resource_name,
             name='event_uuid',
             variable_name=uuid_varname,
         ),
         models.RecordResourceValue(
             resource_type='sqs_event',
             resource_name=resource.resource_name,
             name='queue',
             value=resource.queue,
         ),
         models.RecordResourceVariable(
             resource_type='sqs_event',
             resource_name=resource.resource_name,
             name='lambda_arn',
             variable_name=function_arn.name,
         ),
     ]
Exemple #8
0
    def _plan_snslambdasubscription(self, resource):
        # type: (models.SNSLambdaSubscription) -> Sequence[InstructionMsg]
        function_arn = Variable('%s_lambda_arn' %
                                resource.lambda_function.resource_name)
        topic_arn_varname = '%s_topic_arn' % resource.resource_name
        subscribe_varname = '%s_subscription_arn' % resource.resource_name

        instruction_for_topic_arn = []  # type: List[InstructionMsg]
        if resource.topic.startswith('arn:aws:sns:'):
            instruction_for_topic_arn += [
                models.StoreValue(
                    name=topic_arn_varname,
                    value=resource.topic,
                )
            ]
        else:
            # To keep the user API simple, we only require the topic
            # name and not the ARN.  However, the APIs require the topic
            # ARN so we need to reconstruct it here in the planner.
            instruction_for_topic_arn += [
                models.BuiltinFunction(
                    'parse_arn',
                    [function_arn],
                    output_var='parsed_lambda_arn',
                ),
                models.JPSearch('account_id',
                                input_var='parsed_lambda_arn',
                                output_var='account_id'),
                models.JPSearch('region',
                                input_var='parsed_lambda_arn',
                                output_var='region_name'),
                models.StoreValue(
                    name=topic_arn_varname,
                    value=StringFormat(
                        'arn:aws:sns:{region_name}:{account_id}:%s' %
                        (resource.topic),
                        ['region_name', 'account_id'],
                    ),
                ),
            ]
        if self._remote_state.resource_exists(resource):
            # Given there's nothing about an SNS subscription you can
            # configure for now, if the resource exists, we don't do
            # anything.  The resource sweeper will verify that if the
            # subscription doesn't actually apply that we should unsubscribe
            # from the topic.
            deployed = self._remote_state.resource_deployed_values(resource)
            subscription_arn = deployed['subscription_arn']
            return instruction_for_topic_arn + [
                models.RecordResourceValue(
                    resource_type='sns_event',
                    resource_name=resource.resource_name,
                    name='topic',
                    value=resource.topic,
                ),
                models.RecordResourceVariable(
                    resource_type='sns_event',
                    resource_name=resource.resource_name,
                    name='lambda_arn',
                    variable_name=function_arn.name,
                ),
                models.RecordResourceValue(
                    resource_type='sns_event',
                    resource_name=resource.resource_name,
                    name='subscription_arn',
                    value=subscription_arn,
                ),
                models.RecordResourceVariable(
                    resource_type='sns_event',
                    resource_name=resource.resource_name,
                    name='topic_arn',
                    variable_name=topic_arn_varname,
                ),
            ]
        return instruction_for_topic_arn + [
            models.APICall(
                method_name='add_permission_for_sns_topic',
                params={
                    'topic_arn': Variable(topic_arn_varname),
                    'function_arn': function_arn
                },
            ),
            (models.APICall(
                method_name='subscribe_function_to_topic',
                params={
                    'topic_arn': Variable(topic_arn_varname),
                    'function_arn': function_arn
                },
                output_var=subscribe_varname,
            ), 'Subscribing %s to SNS topic %s\n' %
             (resource.lambda_function.function_name, resource.topic)),
            models.RecordResourceValue(
                resource_type='sns_event',
                resource_name=resource.resource_name,
                name='topic',
                value=resource.topic,
            ),
            models.RecordResourceVariable(
                resource_type='sns_event',
                resource_name=resource.resource_name,
                name='lambda_arn',
                variable_name=function_arn.name,
            ),
            models.RecordResourceVariable(
                resource_type='sns_event',
                resource_name=resource.resource_name,
                name='subscription_arn',
                variable_name=subscribe_varname,
            ),
            models.RecordResourceVariable(
                resource_type='sns_event',
                resource_name=resource.resource_name,
                name='topic_arn',
                variable_name=topic_arn_varname,
            ),
        ]