We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Request Feature: Request for cloud Trail events for Lambda
Hello , 
The following policy is giving me the error :2018-12-18 14:24:39,580: custodian.commands:ERROR Policy: lambda-tag-compliance is invalid: event shortcut not defined: CreateFunction
 policy ---
```
- name: lambda-tag-compliance
    resource: lambda
    mode:
      type: cloudtrail  #### cloud trail not possible
      role: arn:aws:iam::acctnumber:role/acctname
      events: 
         - CreateFunction
    filters:
      - "tag:custodian": absent
```
i changed the policy to the following based on the cc docs and the got the following error 
```
- name: lambda-tag-compliance
    resource: lambda
    mode:
      type: cloudtrail  #### cloud trail not possible
      role: arn:aws:iam::acctnum:role/acctname
      event: CreateFunction
      ids: "requestParameters.functionName"
    filters:
      - "tag:custodian": absent
```
error ---- 2018-12-18 14:33:41,697: custodian.commands:ERROR Configuration invalid: Policy.yml
2018-12-18 14:33:41,704: custodian.commands:ERROR {'type': 'cloudtrail', 'role': 'arn:aws:iam::acctnum:role/acctname', 'event': 'CreateFunction', 'ids': 'requestParameters.functionName'} is not valid under any of the given schemas

can you add the shortcut to cloud-custodian/c7n/cwe.py ... or is there anything else that we can do resolve this ?

Thank you 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `c7n/cwe.py`
Content:
```
1 # Copyright 2016-2017 Capital One Services, LLC
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 from __future__ import absolute_import, division, print_function, unicode_literals
15 
16 import jmespath
17 import six
18 
19 
20 class CloudWatchEvents(object):
21     """A mapping of events to resource types."""
22 
23     # **These are just shortcuts**, you can use the policy definition to
24     # subscribe to any arbitrary cloud trail event that corresponds to
25     # a custodian resource.
26 
27     # For common events that we want to match, just keep a short mapping.
28     # Users can specify arbitrary cloud watch events by specifying these
29     # values in their config, but keep the common case simple.
30 
31     trail_events = {
32         # event source, resource type as keys, mapping to api call and
33         # jmespath expression
34         'ConsoleLogin': {
35             'ids': 'userIdentity.arn',
36             'source': 'signin.amazonaws.com'},
37 
38         'CreateAutoScalingGroup': {
39             'ids': 'requestParameters.autoScalingGroupName',
40             'source': 'autoscaling.amazonaws.com'},
41 
42         'UpdateAutoScalingGroup': {
43             'ids': 'requestParameters.autoScalingGroupName',
44             'source': 'autoscaling.amazonaws.com'},
45 
46         'CreateBucket': {
47             'ids': 'requestParameters.bucketName',
48             'source': 's3.amazonaws.com'},
49 
50         'CreateCluster': {
51             'ids': 'requestParameters.clusterIdentifier',
52             'source': 'redshift.amazonaws.com'},
53 
54         'CreateLoadBalancer': {
55             'ids': 'requestParameters.loadBalancerName',
56             'source': 'elasticloadbalancing.amazonaws.com'},
57 
58         'CreateLoadBalancerPolicy': {
59             'ids': 'requestParameters.loadBalancerName',
60             'source': 'elasticloadbalancing.amazonaws.com'},
61 
62         'CreateDBInstance': {
63             'ids': 'requestParameters.dBInstanceIdentifier',
64             'source': 'rds.amazonaws.com'},
65 
66         'CreateVolume': {
67             'ids': 'responseElements.volumeId',
68             'source': 'ec2.amazonaws.com'},
69 
70         'SetLoadBalancerPoliciesOfListener': {
71             'ids': 'requestParameters.loadBalancerName',
72             'source': 'elasticloadbalancing.amazonaws.com'},
73 
74         'CreateElasticsearchDomain': {
75             'ids': 'requestParameters.domainName',
76             'source': 'es.amazonaws.com'},
77 
78         'CreateTable': {
79             'ids': 'requestParameters.tableName',
80             'source': 'dynamodb.amazonaws.com'},
81 
82         'RunInstances': {
83             'ids': 'responseElements.instancesSet.items[].instanceId',
84             'source': 'ec2.amazonaws.com'}}
85 
86     @classmethod
87     def get(cls, event_name):
88         return cls.trail_events.get(event_name)
89 
90     @classmethod
91     def match(cls, event):
92         """Match a given cwe event as cloudtrail with an api call
93 
94         That has its information filled out.
95         """
96         if 'detail' not in event:
97             return False
98         if 'eventName' not in event['detail']:
99             return False
100         k = event['detail']['eventName']
101 
102         # We want callers to use a compiled expression, but want to avoid
103         # initialization cost of doing it without cause. Not thread safe,
104         # but usage context is lambda entry.
105         if k in cls.trail_events:
106             v = dict(cls.trail_events[k])
107             if isinstance(v['ids'], six.string_types):
108                 v['ids'] = e = jmespath.compile('detail.%s' % v['ids'])
109                 cls.trail_events[k]['ids'] = e
110             return v
111 
112         return False
113 
114     @classmethod
115     def get_trail_ids(cls, event, mode):
116         """extract resources ids from a cloud trail event."""
117         resource_ids = ()
118         event_name = event['detail']['eventName']
119         event_source = event['detail']['eventSource']
120         for e in mode.get('events', []):
121             if not isinstance(e, dict):
122                 # Check if we have a short cut / alias
123                 info = CloudWatchEvents.match(event)
124                 if info:
125                     return info['ids'].search(event)
126                 continue
127             if event_name != e.get('event'):
128                 continue
129             if event_source != e.get('source'):
130                 continue
131 
132             id_query = e.get('ids')
133             if not id_query:
134                 raise ValueError("No id query configured")
135             evt = event
136             # be forgiving for users specifying with details or without
137             if not id_query.startswith('detail.'):
138                 evt = event.get('detail', {})
139             resource_ids = jmespath.search(id_query, evt)
140             if resource_ids:
141                 break
142         return resource_ids
143 
144     @classmethod
145     def get_ids(cls, event, mode):
146         mode_type = mode.get('type')
147         if mode_type == 'ec2-instance-state':
148             resource_ids = [event.get('detail', {}).get('instance-id')]
149         elif mode_type == 'asg-instance-state':
150             resource_ids = [event.get('detail', {}).get('AutoScalingGroupName')]
151         elif mode_type != 'cloudtrail':
152             return None
153         else:
154             resource_ids = cls.get_trail_ids(event, mode)
155 
156         if not isinstance(resource_ids, (tuple, list)):
157             resource_ids = [resource_ids]
158 
159         return list(filter(None, resource_ids))
160
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/c7n/cwe.py b/c7n/cwe.py
--- a/c7n/cwe.py
+++ b/c7n/cwe.py
@@ -79,6 +79,11 @@
             'ids': 'requestParameters.tableName',
             'source': 'dynamodb.amazonaws.com'},
 
+        'CreateFunction': {
+            'event': 'CreateFunction20150331',
+            'source': 'lambda.amazonaws.com',
+            'ids': 'requestParameters.functionName'},
+
         'RunInstances': {
             'ids': 'responseElements.instancesSet.items[].instanceId',
             'source': 'ec2.amazonaws.com'}}

{"golden_diff": "diff --git a/c7n/cwe.py b/c7n/cwe.py\n--- a/c7n/cwe.py\n+++ b/c7n/cwe.py\n@@ -79,6 +79,11 @@\n             'ids': 'requestParameters.tableName',\n             'source': 'dynamodb.amazonaws.com'},\n \n+        'CreateFunction': {\n+            'event': 'CreateFunction20150331',\n+            'source': 'lambda.amazonaws.com',\n+            'ids': 'requestParameters.functionName'},\n+\n         'RunInstances': {\n             'ids': 'responseElements.instancesSet.items[].instanceId',\n             'source': 'ec2.amazonaws.com'}}\n", "issue": "Request Feature: Request for cloud Trail events for Lambda\nHello , \r\nThe following policy is giving me the error :2018-12-18 14:24:39,580: custodian.commands:ERROR Policy: lambda-tag-compliance is invalid: event shortcut not defined: CreateFunction\r\n policy ---\r\n```\r\n- name: lambda-tag-compliance\r\n    resource: lambda\r\n    mode:\r\n      type: cloudtrail  #### cloud trail not possible\r\n      role: arn:aws:iam::acctnumber:role/acctname\r\n      events: \r\n         - CreateFunction\r\n    filters:\r\n      - \"tag:custodian\": absent\r\n```\r\ni changed the policy to the following based on the cc docs and the got the following error \r\n```\r\n- name: lambda-tag-compliance\r\n    resource: lambda\r\n    mode:\r\n      type: cloudtrail  #### cloud trail not possible\r\n      role: arn:aws:iam::acctnum:role/acctname\r\n      event: CreateFunction\r\n      ids: \"requestParameters.functionName\"\r\n    filters:\r\n      - \"tag:custodian\": absent\r\n```\r\nerror ---- 2018-12-18 14:33:41,697: custodian.commands:ERROR Configuration invalid: Policy.yml\r\n2018-12-18 14:33:41,704: custodian.commands:ERROR {'type': 'cloudtrail', 'role': 'arn:aws:iam::acctnum:role/acctname', 'event': 'CreateFunction', 'ids': 'requestParameters.functionName'} is not valid under any of the given schemas\r\n\r\ncan you add the shortcut to cloud-custodian/c7n/cwe.py ... or is there anything else that we can do resolve this ?\r\n\r\nThank you \n", "before_files": [{"content": "# Copyright 2016-2017 Capital One Services, LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport jmespath\nimport six\n\n\nclass CloudWatchEvents(object):\n    \"\"\"A mapping of events to resource types.\"\"\"\n\n    # **These are just shortcuts**, you can use the policy definition to\n    # subscribe to any arbitrary cloud trail event that corresponds to\n    # a custodian resource.\n\n    # For common events that we want to match, just keep a short mapping.\n    # Users can specify arbitrary cloud watch events by specifying these\n    # values in their config, but keep the common case simple.\n\n    trail_events = {\n        # event source, resource type as keys, mapping to api call and\n        # jmespath expression\n        'ConsoleLogin': {\n            'ids': 'userIdentity.arn',\n            'source': 'signin.amazonaws.com'},\n\n        'CreateAutoScalingGroup': {\n            'ids': 'requestParameters.autoScalingGroupName',\n            'source': 'autoscaling.amazonaws.com'},\n\n        'UpdateAutoScalingGroup': {\n            'ids': 'requestParameters.autoScalingGroupName',\n            'source': 'autoscaling.amazonaws.com'},\n\n        'CreateBucket': {\n            'ids': 'requestParameters.bucketName',\n            'source': 's3.amazonaws.com'},\n\n        'CreateCluster': {\n            'ids': 'requestParameters.clusterIdentifier',\n            'source': 'redshift.amazonaws.com'},\n\n        'CreateLoadBalancer': {\n            'ids': 'requestParameters.loadBalancerName',\n            'source': 'elasticloadbalancing.amazonaws.com'},\n\n        'CreateLoadBalancerPolicy': {\n            'ids': 'requestParameters.loadBalancerName',\n            'source': 'elasticloadbalancing.amazonaws.com'},\n\n        'CreateDBInstance': {\n            'ids': 'requestParameters.dBInstanceIdentifier',\n            'source': 'rds.amazonaws.com'},\n\n        'CreateVolume': {\n            'ids': 'responseElements.volumeId',\n            'source': 'ec2.amazonaws.com'},\n\n        'SetLoadBalancerPoliciesOfListener': {\n            'ids': 'requestParameters.loadBalancerName',\n            'source': 'elasticloadbalancing.amazonaws.com'},\n\n        'CreateElasticsearchDomain': {\n            'ids': 'requestParameters.domainName',\n            'source': 'es.amazonaws.com'},\n\n        'CreateTable': {\n            'ids': 'requestParameters.tableName',\n            'source': 'dynamodb.amazonaws.com'},\n\n        'RunInstances': {\n            'ids': 'responseElements.instancesSet.items[].instanceId',\n            'source': 'ec2.amazonaws.com'}}\n\n    @classmethod\n    def get(cls, event_name):\n        return cls.trail_events.get(event_name)\n\n    @classmethod\n    def match(cls, event):\n        \"\"\"Match a given cwe event as cloudtrail with an api call\n\n        That has its information filled out.\n        \"\"\"\n        if 'detail' not in event:\n            return False\n        if 'eventName' not in event['detail']:\n            return False\n        k = event['detail']['eventName']\n\n        # We want callers to use a compiled expression, but want to avoid\n        # initialization cost of doing it without cause. Not thread safe,\n        # but usage context is lambda entry.\n        if k in cls.trail_events:\n            v = dict(cls.trail_events[k])\n            if isinstance(v['ids'], six.string_types):\n                v['ids'] = e = jmespath.compile('detail.%s' % v['ids'])\n                cls.trail_events[k]['ids'] = e\n            return v\n\n        return False\n\n    @classmethod\n    def get_trail_ids(cls, event, mode):\n        \"\"\"extract resources ids from a cloud trail event.\"\"\"\n        resource_ids = ()\n        event_name = event['detail']['eventName']\n        event_source = event['detail']['eventSource']\n        for e in mode.get('events', []):\n            if not isinstance(e, dict):\n                # Check if we have a short cut / alias\n                info = CloudWatchEvents.match(event)\n                if info:\n                    return info['ids'].search(event)\n                continue\n            if event_name != e.get('event'):\n                continue\n            if event_source != e.get('source'):\n                continue\n\n            id_query = e.get('ids')\n            if not id_query:\n                raise ValueError(\"No id query configured\")\n            evt = event\n            # be forgiving for users specifying with details or without\n            if not id_query.startswith('detail.'):\n                evt = event.get('detail', {})\n            resource_ids = jmespath.search(id_query, evt)\n            if resource_ids:\n                break\n        return resource_ids\n\n    @classmethod\n    def get_ids(cls, event, mode):\n        mode_type = mode.get('type')\n        if mode_type == 'ec2-instance-state':\n            resource_ids = [event.get('detail', {}).get('instance-id')]\n        elif mode_type == 'asg-instance-state':\n            resource_ids = [event.get('detail', {}).get('AutoScalingGroupName')]\n        elif mode_type != 'cloudtrail':\n            return None\n        else:\n            resource_ids = cls.get_trail_ids(event, mode)\n\n        if not isinstance(resource_ids, (tuple, list)):\n            resource_ids = [resource_ids]\n\n        return list(filter(None, resource_ids))\n", "path": "c7n/cwe.py"}], "after_files": [{"content": "# Copyright 2016-2017 Capital One Services, LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport jmespath\nimport six\n\n\nclass CloudWatchEvents(object):\n    \"\"\"A mapping of events to resource types.\"\"\"\n\n    # **These are just shortcuts**, you can use the policy definition to\n    # subscribe to any arbitrary cloud trail event that corresponds to\n    # a custodian resource.\n\n    # For common events that we want to match, just keep a short mapping.\n    # Users can specify arbitrary cloud watch events by specifying these\n    # values in their config, but keep the common case simple.\n\n    trail_events = {\n        # event source, resource type as keys, mapping to api call and\n        # jmespath expression\n        'ConsoleLogin': {\n            'ids': 'userIdentity.arn',\n            'source': 'signin.amazonaws.com'},\n\n        'CreateAutoScalingGroup': {\n            'ids': 'requestParameters.autoScalingGroupName',\n            'source': 'autoscaling.amazonaws.com'},\n\n        'UpdateAutoScalingGroup': {\n            'ids': 'requestParameters.autoScalingGroupName',\n            'source': 'autoscaling.amazonaws.com'},\n\n        'CreateBucket': {\n            'ids': 'requestParameters.bucketName',\n            'source': 's3.amazonaws.com'},\n\n        'CreateCluster': {\n            'ids': 'requestParameters.clusterIdentifier',\n            'source': 'redshift.amazonaws.com'},\n\n        'CreateLoadBalancer': {\n            'ids': 'requestParameters.loadBalancerName',\n            'source': 'elasticloadbalancing.amazonaws.com'},\n\n        'CreateLoadBalancerPolicy': {\n            'ids': 'requestParameters.loadBalancerName',\n            'source': 'elasticloadbalancing.amazonaws.com'},\n\n        'CreateDBInstance': {\n            'ids': 'requestParameters.dBInstanceIdentifier',\n            'source': 'rds.amazonaws.com'},\n\n        'CreateVolume': {\n            'ids': 'responseElements.volumeId',\n            'source': 'ec2.amazonaws.com'},\n\n        'SetLoadBalancerPoliciesOfListener': {\n            'ids': 'requestParameters.loadBalancerName',\n            'source': 'elasticloadbalancing.amazonaws.com'},\n\n        'CreateElasticsearchDomain': {\n            'ids': 'requestParameters.domainName',\n            'source': 'es.amazonaws.com'},\n\n        'CreateTable': {\n            'ids': 'requestParameters.tableName',\n            'source': 'dynamodb.amazonaws.com'},\n\n        'CreateFunction': {\n            'event': 'CreateFunction20150331',\n            'source': 'lambda.amazonaws.com',\n            'ids': 'requestParameters.functionName'},\n\n        'RunInstances': {\n            'ids': 'responseElements.instancesSet.items[].instanceId',\n            'source': 'ec2.amazonaws.com'}}\n\n    @classmethod\n    def get(cls, event_name):\n        return cls.trail_events.get(event_name)\n\n    @classmethod\n    def match(cls, event):\n        \"\"\"Match a given cwe event as cloudtrail with an api call\n\n        That has its information filled out.\n        \"\"\"\n        if 'detail' not in event:\n            return False\n        if 'eventName' not in event['detail']:\n            return False\n        k = event['detail']['eventName']\n\n        # We want callers to use a compiled expression, but want to avoid\n        # initialization cost of doing it without cause. Not thread safe,\n        # but usage context is lambda entry.\n        if k in cls.trail_events:\n            v = dict(cls.trail_events[k])\n            if isinstance(v['ids'], six.string_types):\n                v['ids'] = e = jmespath.compile('detail.%s' % v['ids'])\n                cls.trail_events[k]['ids'] = e\n            return v\n\n        return False\n\n    @classmethod\n    def get_trail_ids(cls, event, mode):\n        \"\"\"extract resources ids from a cloud trail event.\"\"\"\n        resource_ids = ()\n        event_name = event['detail']['eventName']\n        event_source = event['detail']['eventSource']\n        for e in mode.get('events', []):\n            if not isinstance(e, dict):\n                # Check if we have a short cut / alias\n                info = CloudWatchEvents.match(event)\n                if info:\n                    return info['ids'].search(event)\n                continue\n            if event_name != e.get('event'):\n                continue\n            if event_source != e.get('source'):\n                continue\n\n            id_query = e.get('ids')\n            if not id_query:\n                raise ValueError(\"No id query configured\")\n            evt = event\n            # be forgiving for users specifying with details or without\n            if not id_query.startswith('detail.'):\n                evt = event.get('detail', {})\n            resource_ids = jmespath.search(id_query, evt)\n            if resource_ids:\n                break\n        return resource_ids\n\n    @classmethod\n    def get_ids(cls, event, mode):\n        mode_type = mode.get('type')\n        if mode_type == 'ec2-instance-state':\n            resource_ids = [event.get('detail', {}).get('instance-id')]\n        elif mode_type == 'asg-instance-state':\n            resource_ids = [event.get('detail', {}).get('AutoScalingGroupName')]\n        elif mode_type != 'cloudtrail':\n            return None\n        else:\n            resource_ids = cls.get_trail_ids(event, mode)\n\n        if not isinstance(resource_ids, (tuple, list)):\n            resource_ids = [resource_ids]\n\n        return list(filter(None, resource_ids))\n", "path": "c7n/cwe.py"}]}