Пример #1
0
 def disabled_xtest_get_ids(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             event_data('event-instance-state.json'),
             {'type': 'ec2-instance-state'}),
         ['i-a2d74f12'])
     self.assertEqual(
         CloudWatchEvents.get_ids(
             {'detail': event_data('event-cloud-trail-run-instances.json')},
             {'type': 'cloudtrail', 'events': ['RunInstances']}),
         ['i-d49cf94c'])
Пример #2
0
 def disabled_xtest_get_ids(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(event_data('event-instance-state.json'),
                                  {'type': 'ec2-instance-state'}),
         ['i-a2d74f12'])
     self.assertEqual(
         CloudWatchEvents.get_ids(
             {'detail': event_data('event-cloud-trail-run-instances.json')},
             {
                 'type': 'cloudtrail',
                 'events': ['RunInstances']
             }), ['i-d49cf94c'])
Пример #3
0
 def test_ec2_state(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             event_data("event-instance-state.json"), {"type": "ec2-instance-state"}
         ),
         ["i-a2d74f12"],
     )
    def test_get_ids_multiple_events(self):
        d = event_data('event-cloud-trail-run-instances.json')
        d['eventName'] = 'StartInstances'

        self.assertEqual(
            CloudWatchEvents.get_ids(
                {'detail': d},
                {'type': 'cloudtrail', 'events': [
                    # wrong event name
                    {'source': 'ec2.amazonaws.com',
                     'event': 'CreateTags',
                     'ids': 'requestParameters.resourcesSet.items[].resourceId'},
                    # wrong event source
                    {'source': 'ecs.amazonaws.com',
                     'event': 'StartInstances',
                     'ids': 'responseElements.instancesSet.items'},
                    # matches no resource ids
                    {'source': 'ec2.amazonaws.com',
                     'event': 'StartInstances',
                     'ids': 'responseElements.instancesSet2.items[].instanceId'},
                    # correct
                    {'source': 'ec2.amazonaws.com',
                     'event': 'StartInstances',
                     'ids': 'responseElements.instancesSet.items[].instanceId'},
                    # we don't fall off the end
                    {'source': 'ec2.amazonaws.com',
                     'event': 'StartInstances',
                     'ids': 'responseElements.instancesSet.items[]'},
                    ]}),
            ['i-784cdacd', u'i-7b4cdace'])
 def test_asg_state(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             event_data('event-asg-instance-failed.json'),
             {'type': 'asg-instance-state',
              'events': ['EC2 Instance Launch Unsuccessful']}),
         ['CustodianTest'])
Пример #6
0
 def test_ec2_state(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             event_data("event-instance-state.json"), {"type": "ec2-instance-state"}
         ),
         ["i-a2d74f12"],
     )
Пример #7
0
 def test_get_ids(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             {"detail": event_data("event-cloud-trail-run-instances.json")},
             {"type": "cloudtrail", "events": ["RunInstances"]},
         ),
         ["i-784cdacd", u"i-7b4cdace"],
     )
Пример #8
0
 def test_cloud_trail_resource(self):
     self.assertEqual(
         CloudWatchEvents.match(event_data("event-cloud-trail-s3.json")),
         {
             "source": "s3.amazonaws.com",
             "ids": jmespath.compile("detail.requestParameters.bucketName"),
         },
     )
Пример #9
0
 def test_get_ids(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             {'detail': event_data('event-cloud-trail-run-instances.json')},
             {
                 'type': 'cloudtrail',
                 'events': ['RunInstances']
             }), ['i-784cdacd', u'i-7b4cdace'])
Пример #10
0
 def test_get_ids(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             {"detail": event_data("event-cloud-trail-run-instances.json")},
             {"type": "cloudtrail", "events": ["RunInstances"]},
         ),
         ["i-784cdacd", "i-7b4cdace"],
     )
Пример #11
0
 def test_cloud_trail_resource(self):
     self.assertEqual(
         CloudWatchEvents.match(event_data("event-cloud-trail-s3.json")),
         {
             "source": "s3.amazonaws.com",
             "ids": jmespath.compile("detail.requestParameters.bucketName"),
         },
     )
Пример #12
0
 def test_get_ids_sans_with_details_expr(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             {'detail': event_data('event-cloud-trail-run-instances.json')},
             {'type': 'cloudtrail', 'events': [
                 {'ids': 'detail.responseElements.instancesSet.items[].instanceId',
                  'source': 'ec2.amazonaws.com',
                  'event': 'RunInstances'}]}),
         ["i-784cdacd", "i-7b4cdace"],
     )
Пример #13
0
    def push(self, event, lambda_ctx):
        """Run policy in push mode against given event.

        Lambda automatically generates cloud watch logs, and metrics
        for us, albeit with some deficienies, metrics no longer count
        against valid resources matches, but against execution.
        Fortunately we already have replacements.

        TODO: better customization around execution context outputs
        TODO: support centralized lambda exec across accounts.
        """
        mode = self.data.get('mode', {})
        mode_type = mode.get('type')

        if mode_type == 'periodic':
            return self.poll()

        resource_ids = CloudWatchEvents.get_ids(event, mode)
        if resource_ids is None:
            raise ValueError("Unknown push event mode %s" % self.data)

        self.log.info('Found resource ids: %s' % resource_ids)
        if not resource_ids:
            self.log.warning("Could not find resource ids")
            return

        resources = self.resource_manager.get_resources(resource_ids)
        if 'debug' in event:
            self.log.info("Resources %s", resources)

        resources = self.resource_manager.filter_resources(resources, event)
        if 'debug' in event:
            self.log.info("Filtered resources %d" % len(resources))

        if not resources:
            self.log.info("policy: %s resources: %s no resources matched" %
                          (self.name, self.resource_type))
            return

        self.ctx.metrics.put_metric('ResourceCount',
                                    len(resources),
                                    'Count',
                                    Scope="Policy",
                                    buffer=False)

        if 'debug' in event:
            self.log.info("Invoking actions %s", self.resource_manager.actions)
        for action in self.resource_manager.actions:
            self.log.info("policy: %s invoking action: %s resources: %d",
                          self.name, action.name, len(resources))
            if isinstance(action, EventAction):
                action.process(resources, event)
            else:
                action.process(resources)
        return resources
Пример #14
0
    def test_get_ids_multiple_events(self):
        d = event_data("event-cloud-trail-run-instances.json")
        d["eventName"] = "StartInstances"

        self.assertEqual(
            CloudWatchEvents.get_ids(
                {"detail": d},
                {
                    "type":
                    "cloudtrail",
                    "events": [
                        # wrong event name
                        {
                            "source":
                            "ec2.amazonaws.com",
                            "event":
                            "CreateTags",
                            "ids":
                            "requestParameters.resourcesSet.items[].resourceId",
                        },
                        # wrong event source
                        {
                            "source": "ecs.amazonaws.com",
                            "event": "StartInstances",
                            "ids": "responseElements.instancesSet.items",
                        },
                        # matches no resource ids
                        {
                            "source":
                            "ec2.amazonaws.com",
                            "event":
                            "StartInstances",
                            "ids":
                            "responseElements.instancesSet2.items[].instanceId",
                        },
                        # correct
                        {
                            "source":
                            "ec2.amazonaws.com",
                            "event":
                            "StartInstances",
                            "ids":
                            "responseElements.instancesSet.items[].instanceId",
                        },
                        # we don't fall off the end
                        {
                            "source": "ec2.amazonaws.com",
                            "event": "StartInstances",
                            "ids": "responseElements.instancesSet.items[]",
                        },
                    ],
                },
            ),
            ["i-784cdacd", u"i-7b4cdace"],
        )
Пример #15
0
 def test_asg_state(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             event_data("event-asg-instance-failed.json"),
             {
                 "type": "asg-instance-state",
                 "events": ["EC2 Instance Launch Unsuccessful"],
             },
         ),
         ["CustodianTest"],
     )
Пример #16
0
    def push(self, event, lambda_ctx):
        """Run policy in push mode against given event.

        Lambda automatically generates cloud watch logs, and metrics
        for us, albeit with some deficienies, metrics no longer count
        against valid resources matches, but against execution.
        Fortunately we already have replacements.

        TODO: better customization around execution context outputs
        TODO: support centralized lambda exec across accounts.
        """
        mode = self.data.get('mode', {})
        mode_type = mode.get('type')

        if mode_type == 'periodic':
            return self.poll()

        resource_ids = CloudWatchEvents.get_ids(event, mode)
        if resource_ids is None:
            raise ValueError("Unknown push event mode %s" % self.data)

        self.log.info('Found resource ids: %s' % resource_ids)
        if not resource_ids:
            self.log.warning("Could not find resource ids")
            return

        resources = self.resource_manager.get_resources(resource_ids)
        if 'debug' in event:
            self.log.info("Resources %s", resources)

        resources = self.resource_manager.filter_resources(resources, event)
        if 'debug' in event:
            self.log.info("Filtered resources %d" % len(resources))

        if not resources:
            self.log.info("policy: %s resources: %s no resources matched" % (
                self.name, self.resource_type))
            return

        self.ctx.metrics.put_metric(
            'ResourceCount', len(resources), 'Count', Scope="Policy",
            buffer=False)

        if 'debug' in event:
            self.log.info("Invoking actions %s", self.resource_manager.actions)
        for action in self.resource_manager.actions:
            self.log.info(
                "policy: %s invoking action: %s resources: %d",
                self.name, action.name, len(resources))
            if isinstance(action, EventAction):
                action.process(resources, event)
            else:
                action.process(resources)
        return resources
Пример #17
0
 def test_asg_state(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             event_data("event-asg-instance-failed.json"),
             {
                 "type": "asg-instance-state",
                 "events": ["EC2 Instance Launch Unsuccessful"],
             },
         ),
         ["CustodianTest"],
     )
 def test_custom_event(self):
     d = {'detail': event_data('event-cloud-trail-run-instances.json')}
     d['detail']['eventName'] = 'StartInstances'
     self.assertEqual(
         CloudWatchEvents.get_ids(
             d,
             {'type': 'cloudtrail', 'events': [{
                  'event': 'StartInstances',
                  'ids': 'responseElements.instancesSet.items[].instanceId',
                  'source': 'ec2.amazonaws.com'}]}),
         ['i-784cdacd', u'i-7b4cdace'])
Пример #19
0
    def resolve_cloudtrail_payload(self, payload):
        ids = []
        sources = self.data.get('sources', [])

        for e in self.data.get('events'):
            event_info = CloudWatchEvents.get(e)
            if event_info is None:
                continue
            sources.append(event_info['source'])

        payload['detail'] = {
            'eventSource': list(set(sources)),
            'eventName': self.data.get('events', [])}
Пример #20
0
    def resolve_cloudtrail_payload(self, payload):
        ids = []
        sources = self.data.get('sources', [])

        for e in self.data.get('events'):
            event_info = CloudWatchEvents.get(e)
            if event_info is None:
                continue
            sources.append(event_info['source'])

        payload['detail'] = {
            'eventSource': list(set(sources)),
            'eventName': self.data.get('events', [])}
Пример #21
0
    def resolve_resources(self, event):
        mode = self.policy.data.get('mode', {})
        resource_ids = CloudWatchEvents.get_ids(event, mode)
        if resource_ids is None:
            raise ValueError("Unknown push event mode %s" % self.data)

        self.policy.log.info('Found resource ids: %s' % resource_ids)
        if not resource_ids:
            self.policy.log.warning("Could not find resource ids")
            return []

        resources = self.policy.resource_manager.get_resources(resource_ids)
        if 'debug' in event:
            self.policy.log.info("Resources %s", resources)
        return resources
Пример #22
0
    def resolve_resources(self, event):
        mode = self.policy.data.get('mode', {})
        resource_ids = CloudWatchEvents.get_ids(event, mode)
        if resource_ids is None:
            raise ValueError("Unknown push event mode %s" % self.data)

        self.policy.log.info('Found resource ids: %s' % resource_ids)
        if not resource_ids:
            self.policy.log.warning("Could not find resource ids")
            return []

        resources = self.policy.resource_manager.get_resources(resource_ids)
        if 'debug' in event:
            self.policy.log.info("Resources %s", resources)
        return resources
Пример #23
0
    def resolve_cloudtrail_payload(self, payload):
        sources = self.data.get('sources', [])
        events = []
        for e in self.data.get('events'):
            if not isinstance(e, dict):
                events.append(e)
                event_info = CloudWatchEvents.get(e)
                if event_info is None:
                    continue
            else:
                event_info = e
                events.append(e['event'])
            sources.append(event_info['source'])

        payload['detail'] = {
            'eventSource': list(set(sources)),
            'eventName': events}
Пример #24
0
    def resolve_resources(self, event):
        self.assume_member(event)
        mode = self.policy.data.get('mode', {})
        resource_ids = CloudWatchEvents.get_ids(event, mode)
        if resource_ids is None:
            raise ValueError("Unknown push event mode %s", self.data)
        self.policy.log.info('Found resource ids: %s', resource_ids)
        # Handle multi-resource type events, like ec2 CreateTags
        resource_ids = self.policy.resource_manager.match_ids(resource_ids)
        if not resource_ids:
            self.policy.log.warning("Could not find resource ids")
            return []

        resources = self.policy.resource_manager.get_resources(resource_ids)
        if 'debug' in event:
            self.policy.log.info("Resources %s", resources)
        return resources
Пример #25
0
    def resolve_resources(self, event):
        self.assume_member(event)
        mode = self.policy.data.get('mode', {})
        resource_ids = CloudWatchEvents.get_ids(event, mode)
        if resource_ids is None:
            raise ValueError("Unknown push event mode %s", self.data)
        self.policy.log.info('Found resource ids: %s', resource_ids)
        # Handle multi-resource type events, like ec2 CreateTags
        resource_ids = self.policy.resource_manager.match_ids(resource_ids)
        if not resource_ids:
            self.policy.log.warning("Could not find resource ids")
            return []

        resources = self.policy.resource_manager.get_resources(resource_ids)
        if 'debug' in event:
            self.policy.log.info("Resources %s", resources)
        return resources
Пример #26
0
    def resolve_cloudtrail_payload(self, payload):
        sources = self.data.get('sources', [])
        events = []
        for e in self.data.get('events'):
            if not isinstance(e, dict):
                events.append(e)
                event_info = CloudWatchEvents.get(e)
                if event_info is None:
                    continue
            else:
                event_info = e
                events.append(e['event'])
            sources.append(event_info['source'])

        payload['detail'] = {
            'eventSource': list(set(sources)),
            'eventName': events}
Пример #27
0
    def test_get_ids_multiple_events(self):
        d = event_data("event-cloud-trail-run-instances.json")
        d["eventName"] = "StartInstances"

        self.assertEqual(
            CloudWatchEvents.get_ids(
                {"detail": d},
                {
                    "type": "cloudtrail",
                    "events": [
                        # wrong event name
                        {
                            "source": "ec2.amazonaws.com",
                            "event": "CreateTags",
                            "ids": "requestParameters.resourcesSet.items[].resourceId",
                        },
                        # wrong event source
                        {
                            "source": "ecs.amazonaws.com",
                            "event": "StartInstances",
                            "ids": "responseElements.instancesSet.items",
                        },
                        # matches no resource ids
                        {
                            "source": "ec2.amazonaws.com",
                            "event": "StartInstances",
                            "ids": "responseElements.instancesSet2.items[].instanceId",
                        },
                        # correct
                        {
                            "source": "ec2.amazonaws.com",
                            "event": "StartInstances",
                            "ids": "responseElements.instancesSet.items[].instanceId",
                        },
                        # we don't fall off the end
                        {
                            "source": "ec2.amazonaws.com",
                            "event": "StartInstances",
                            "ids": "responseElements.instancesSet.items[]",
                        },
                    ],
                },
            ),
            ["i-784cdacd", u"i-7b4cdace"],
        )
Пример #28
0
 def test_custom_event(self):
     d = {"detail": event_data("event-cloud-trail-run-instances.json")}
     d["detail"]["eventName"] = "StartInstances"
     self.assertEqual(
         CloudWatchEvents.get_ids(
             d,
             {
                 "type": "cloudtrail",
                 "events": [
                     {
                         "event": "StartInstances",
                         "ids": "responseElements.instancesSet.items[].instanceId",
                         "source": "ec2.amazonaws.com",
                     }
                 ],
             },
         ),
         ["i-784cdacd", u"i-7b4cdace"],
     )
Пример #29
0
 def test_custom_event(self):
     d = {"detail": event_data("event-cloud-trail-run-instances.json")}
     d["detail"]["eventName"] = "StartInstances"
     self.assertEqual(
         CloudWatchEvents.get_ids(
             d,
             {
                 "type": "cloudtrail",
                 "events": [
                     {
                         "event": "StartInstances",
                         "ids": "responseElements.instancesSet.items[].instanceId",
                         "source": "ec2.amazonaws.com",
                     }
                 ],
             },
         ),
         ["i-784cdacd", u"i-7b4cdace"],
     )
 def test_cloud_trail_resource(self):
     self.assertEqual(
         CloudWatchEvents.match(
             event_data('event-cloud-trail-s3.json')),
         {'source': 's3.amazonaws.com',
          'ids': jmespath.compile('detail.requestParameters.bucketName')})
 def test_non_cloud_trail_event(self):
     for event in ['event-instance-state.json', 'event-scheduled.json']:
         self.assertFalse(CloudWatchEvents.match(event_data(event)))
Пример #32
0
    def run(self, event, lambda_context):
        """Run policy in push mode against given event.

        Lambda automatically generates cloud watch logs, and metrics
        for us, albeit with some deficienies, metrics no longer count
        against valid resources matches, but against execution.

        If metrics execution option is enabled, custodian will generate
        metrics per normal.
        """
        from c7n.actions import EventAction

        mode = self.policy.data.get('mode', {})
        if not bool(mode.get("log", True)):
            root = logging.getLogger()
            map(root.removeHandler, root.handlers[:])
            root.handlers = [logging.NullHandler()]

        member_id = self.get_member_account_id(event)
        region = self.get_member_region(event)
        resource_ids = CloudWatchEvents.get_ids(event, mode)

        resources = self.resolve_resources(event)
        if not resources:
            return resources
        resources = self.policy.resource_manager.filter_resources(
            resources, event)

        if 'debug' in event:
            self.policy.log.info("Filtered resources %d" % len(resources))

        if not resources:
            self.policy.log.info(
                "policy: %s resources: %s no resources matched" %
                (self.policy.name, self.policy.resource_type))
            self.policy.log.info(
                "Compliant resource matched: Rule: %s: Account: %s region: %s type: %s resource: %s"
                % (self.policy.name, member_id, region,
                   self.policy.resource_type, resource_ids[0]))
            return

        with self.policy.ctx:
            self.policy.ctx.metrics.put_metric('ResourceCount',
                                               len(resources),
                                               'Count',
                                               Scope="Policy",
                                               buffer=False)

            if 'debug' in event:
                self.policy.log.info("Invoking actions %s",
                                     self.policy.resource_manager.actions)

            self.policy._write_file('resources.json',
                                    utils.dumps(resources, indent=2))

            for action in self.policy.resource_manager.actions:
                self.policy.log.info(
                    "policy: %s invoking action: %s resources: %d",
                    self.policy.name, action.name, len(resources))
                if isinstance(action, EventAction):
                    results = action.process(resources, event)
                else:
                    results = action.process(resources)
                self.policy._write_file("action-%s" % action.name,
                                        utils.dumps(results))
        return resources
 def test_ec2_state(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             event_data('event-instance-state.json'),
             {'type': 'ec2-instance-state'}),
         ['i-a2d74f12'])
Пример #34
0
 def test_get_ids(self):
     self.assertEqual(
         CloudWatchEvents.get_ids(
             {'detail': event_data('event-cloud-trail-run-instances.json')},
             {'type': 'cloudtrail', 'events': ['RunInstances']}),
         ['i-784cdacd', u'i-7b4cdace'])