Repository: cloud-custodian/cloud-custodian

Issue:
Allow `events` to be optional for PHD type
```
policies:
  - name: phd-alerts
    resource: account
    comment: Olay PHD alerts
    mode:
      type: phd
      role: arn:aws:iam::1234567890:role/cloud_custodian_role
```

Should be valid for account level policies (PHD). 
The events[] list can be updated at any point and keeping this list up to date would be impossible.

Output for attempting:

```
Traceback (most recent call last):
  File "/usr/bin/custodian", line 10, in <module>
    sys.exit(main())
  File "/usr/lib/python2.7/site-packages/c7n/cli.py", line 374, in main
    command(config)
  File "/usr/lib/python2.7/site-packages/c7n/commands.py", line 65, in _load_policies
    collection = policy_load(options, fp, validate=validate, vars=vars)
  File "/usr/lib/python2.7/site-packages/c7n/policy.py", line 63, in load
    errors[1], errors[0]))
c7n.exceptions.PolicyValidationError: Failed to validate policy phd-alerts
 Error on policy:phd-alerts resource:account
u'events' is a required property

Failed validating u'required' in schema[5]:
    {u'additionalProperties': False,
     u'properties': {'categories': {u'items': {u'enum': [u'issue',
                                                         u'accountNotification',
                                                         u'scheduledChange']},
                                    u'type': u'array'},
                     u'concurrency': {u'type': u'integer'},
                     u'dead_letter_config': {u'type': u'object'},
                     u'environment': {u'type': u'object'},
                     'events': {u'items': {u'type': u'string'},
                                u'type': u'array'},
                     u'execution-options': {u'type': u'object'},
                     u'function-prefix': {u'type': u'string'},
                     u'kms_key_arn': {u'type': u'string'},
                     u'layers': {u'items': {u'type': u'string'},
                                 u'type': u'array'},
                     u'member-role': {u'type': u'string'},
                     u'memory': {u'type': u'number'},
                     u'packages': {u'items': {u'type': u'string'},
                                   u'type': u'array'},
                     u'role': {u'type': u'string'},
                     u'runtime': {u'enum': [u'python2.7',
                                            u'python3.6',
                                            u'python3.7']},
                     u'security_groups': {u'type': u'array'},
                     'statuses': {u'items': {u'enum': [u'open',
                                                       u'upcoming',
                                                       u'closed']},
                                  u'type': u'array'},
                     u'subnets': {u'type': u'array'},
                     u'tags': {u'type': u'object'},
                     u'timeout': {u'type': u'number'},
                     u'tracing_config': {u'type': u'object'},
                     u'type': {u'enum': [u'phd']}},
     u'required': [u'events', u'type'],
     u'type': u'object'}

On instance:
    {'role': 'arn:aws:iam::1234567890:role/cloud_custodian_role',
     'type': 'phd'}
```


Discussion:
Hey @kapilt this ended up causing a KeyError from `mu.py` line 1090:

```
        elif event_type == 'phd':
            payload['source'] = ['aws.health']
            payload['detail'] = {
                'eventTypeCode': list(self.data['events'])}
```

error:

```
2019-12-02 12:35:17,387: custodian.policy:INFO Provisioning policy lambda phd
2019-12-02 12:35:17,708: custodian.output:ERROR Error while executing policy
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/c7n/policy.py", line 568, in provision
    role=self.policy.options.assume_role)
  File "/usr/lib/python2.7/site-packages/c7n/mu.py", line 375, in publish
    if e.add(func):
  File "/usr/lib/python2.7/site-packages/c7n/mu.py", line 1114, in add
    pattern = self.render_event_pattern()
  File "/usr/lib/python2.7/site-packages/c7n/mu.py", line 1090, in render_event_pattern
    'eventTypeCode': list(self.data['events'])}
KeyError: u'events'
2019-12-02 12:35:17,711: custodian.commands:ERROR Error while executing policy phd, continuing
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/c7n/commands.py", line 283, in run
    policy()
  File "/usr/lib/python2.7/site-packages/c7n/policy.py", line 1030, in __call__
    resources = mode.provision()
  File "/usr/lib/python2.7/site-packages/c7n/policy.py", line 568, in provision
    role=self.policy.options.assume_role)
  File "/usr/lib/python2.7/site-packages/c7n/mu.py", line 375, in publish
    if e.add(func):
  File "/usr/lib/python2.7/site-packages/c7n/mu.py", line 1114, in add
    pattern = self.render_event_pattern()
  File "/usr/lib/python2.7/site-packages/c7n/mu.py", line 1090, in render_event_pattern
    'eventTypeCode': list(self.data['events'])}
KeyError: u'events'
```

Resolving patch:
diff --git a/c7n/mu.py b/c7n/mu.py
--- a/c7n/mu.py
+++ b/c7n/mu.py
@@ -1086,8 +1086,10 @@ def render_event_pattern(self):
             payload['detail-type'] = events
         elif event_type == 'phd':
             payload['source'] = ['aws.health']
-            payload['detail'] = {
-                'eventTypeCode': list(self.data['events'])}
+            if self.data.get('events'):
+                payload['detail'] = {
+                    'eventTypeCode': list(self.data['events'])
+                }
             if self.data.get('categories', []):
                 payload['detail']['eventTypeCategory'] = self.data['categories']
         elif event_type == 'hub-finding':


Test patch: