We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
batch-compute resource security-group filter support
Add a security-group filter to the batch-compute resource  using the securityGroupIds attribute
  

--- 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/resources/batch.py`
Content:
```
1 # Copyright 2017-2018 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 from c7n.manager import resources
17 from c7n.query import QueryResourceManager
18 from c7n.actions import BaseAction
19 from c7n.utils import local_session, type_schema
20 
21 
22 @resources.register('batch-compute')
23 class ComputeEnvironment(QueryResourceManager):
24 
25     class resource_type(object):
26         service = 'batch'
27         filter_name = 'computeEnvironments'
28         filter_type = 'list'
29         dimension = None
30         id = name = "computeEnvironmentName"
31         enum_spec = (
32             'describe_compute_environments', 'computeEnvironments', None)
33 
34 
35 @resources.register('batch-definition')
36 class JobDefinition(QueryResourceManager):
37 
38     class resource_type(object):
39         service = 'batch'
40         filter_name = 'jobDefinitions'
41         filter_type = 'list'
42         dimension = None
43         id = name = "jobDefinitionName"
44         enum_spec = (
45             'describe_job_definitions', 'jobDefinitions', None)
46 
47 
48 class StateTransitionFilter(object):
49     """Filter resources by state.
50 
51     Try to simplify construction for policy authors by automatically
52     filtering elements (filters or actions) to the resource states
53     they are valid for.
54     """
55     valid_origin_states = ()
56 
57     def filter_resource_state(self, resources, key, states=None):
58         states = states or self.valid_origin_states
59         if not states:
60             return resources
61         orig_length = len(resources)
62         results = [r for r in resources if r[key] in states]
63         if orig_length != len(results):
64             self.log.warn(
65                 "%s implicitly filtered %d of %d resources with valid %s" % (
66                     self.__class__.__name__,
67                     len(results), orig_length, key.lower()))
68         return results
69 
70 
71 @ComputeEnvironment.action_registry.register('update-environment')
72 class UpdateComputeEnvironment(BaseAction, StateTransitionFilter):
73     """Updates an AWS batch compute environment
74 
75     :example:
76 
77     .. code-block: yaml
78 
79         policies:
80           - name: update-environments
81             resource: batch-compute
82             filters:
83               - computeResources.desiredvCpus: 0
84               - state: ENABLED
85             actions:
86               - type: update-environment
87                 state: DISABLED
88     """
89     schema = {
90         'type': 'object',
91         'additionalProperties': False,
92         'properties': {
93             'type': {'enum': ['update-environment']},
94             'computeEnvironment': {'type': 'string'},
95             'state': {'type': 'string', 'enum': ['ENABLED', 'DISABLED']},
96             'computeResources': {
97                 'type': 'object',
98                 'additionalProperties': False,
99                 'properties': {
100                     'minvCpus': {'type': 'integer'},
101                     'maxvCpus': {'type': 'integer'},
102                     'desiredvCpus': {'type': 'integer'}
103                 }
104             },
105             'serviceRole': {'type': 'string'}
106         }
107     }
108     permissions = ('batch:UpdateComputeEnvironment',)
109     valid_origin_status = ('VALID', 'INVALID')
110 
111     def process(self, resources):
112         resources = self.filter_resource_state(
113             resources, 'status', self.valid_origin_status)
114         client = local_session(self.manager.session_factory).client('batch')
115         params = dict(self.data)
116         params.pop('type')
117         for r in resources:
118             params['computeEnvironment'] = r['computeEnvironmentName']
119             client.update_compute_environment(**params)
120 
121 
122 @ComputeEnvironment.action_registry.register('delete')
123 class DeleteComputeEnvironment(BaseAction, StateTransitionFilter):
124     """Delete an AWS batch compute environment
125 
126     :example:
127 
128     .. code-block: yaml
129 
130         policies:
131           - name: delete-environments
132             resource: batch-compute
133             filters:
134               - computeResources.desiredvCpus: 0
135             action:
136               - type: delete
137     """
138     schema = type_schema('delete')
139     permissions = ('batch:DeleteComputeEnvironment',)
140     valid_origin_states = ('DISABLED',)
141     valid_origin_status = ('VALID', 'INVALID')
142 
143     def delete_environment(self, r):
144         client = local_session(self.manager.session_factory).client('batch')
145         client.delete_compute_environment(
146             computeEnvironment=r['computeEnvironmentName'])
147 
148     def process(self, resources):
149         resources = self.filter_resource_state(
150             self.filter_resource_state(
151                 resources, 'state', self.valid_origin_states),
152             'status', self.valid_origin_status)
153         with self.executor_factory(max_workers=2) as w:
154             list(w.map(self.delete_environment, resources))
155 
156 
157 @JobDefinition.action_registry.register('deregister')
158 class DefinitionDeregister(BaseAction, StateTransitionFilter):
159     """Deregisters a batch definition
160 
161     :example:
162 
163     .. code-block: yaml
164 
165         policies:
166           - name: deregister-definition
167             resource: batch-definition
168             filters:
169               - containerProperties.image: amazonlinux
170             actions:
171               - type: deregister
172     """
173     schema = type_schema('deregister')
174     permissions = ('batch:DeregisterJobDefinition',)
175     valid_origin_states = ('ACTIVE',)
176 
177     def deregister_definition(self, r):
178         self.client.deregister_job_definition(
179             jobDefinition='%s:%s' % (r['jobDefinitionName'],
180                                      r['revision']))
181 
182     def process(self, resources):
183         resources = self.filter_resource_state(
184             resources, 'status', self.valid_origin_states)
185         self.client = local_session(
186             self.manager.session_factory).client('batch')
187         with self.executor_factory(max_workers=2) as w:
188             list(w.map(self.deregister_definition, resources))
189
```
--- 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/resources/batch.py b/c7n/resources/batch.py
--- a/c7n/resources/batch.py
+++ b/c7n/resources/batch.py
@@ -13,9 +13,11 @@
 # limitations under the License.
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+from c7n.actions import BaseAction
+from c7n.filters.vpc import SecurityGroupFilter, SubnetFilter
 from c7n.manager import resources
 from c7n.query import QueryResourceManager
-from c7n.actions import BaseAction
+
 from c7n.utils import local_session, type_schema
 
 
@@ -32,6 +34,18 @@
             'describe_compute_environments', 'computeEnvironments', None)
 
 
+@ComputeEnvironment.filter_registry.register('security-group')
+class ComputeSGFilter(SecurityGroupFilter):
+
+    RelatedIdsExpression = "computeResources.securityGroupIds"
+
+
+@ComputeEnvironment.filter_registry.register('subnet')
+class ComputeSubnetFilter(SubnetFilter):
+
+    RelatedIdsExpression = "computeResources.subnets"
+
+
 @resources.register('batch-definition')
 class JobDefinition(QueryResourceManager):

{"golden_diff": "diff --git a/c7n/resources/batch.py b/c7n/resources/batch.py\n--- a/c7n/resources/batch.py\n+++ b/c7n/resources/batch.py\n@@ -13,9 +13,11 @@\n # limitations under the License.\n from __future__ import absolute_import, division, print_function, unicode_literals\n \n+from c7n.actions import BaseAction\n+from c7n.filters.vpc import SecurityGroupFilter, SubnetFilter\n from c7n.manager import resources\n from c7n.query import QueryResourceManager\n-from c7n.actions import BaseAction\n+\n from c7n.utils import local_session, type_schema\n \n \n@@ -32,6 +34,18 @@\n             'describe_compute_environments', 'computeEnvironments', None)\n \n \n+@ComputeEnvironment.filter_registry.register('security-group')\n+class ComputeSGFilter(SecurityGroupFilter):\n+\n+    RelatedIdsExpression = \"computeResources.securityGroupIds\"\n+\n+\n+@ComputeEnvironment.filter_registry.register('subnet')\n+class ComputeSubnetFilter(SubnetFilter):\n+\n+    RelatedIdsExpression = \"computeResources.subnets\"\n+\n+\n @resources.register('batch-definition')\n class JobDefinition(QueryResourceManager):\n", "issue": "batch-compute resource security-group filter support\nAdd a security-group filter to the batch-compute resource  using the securityGroupIds attribute\r\n  \n", "before_files": [{"content": "# Copyright 2017-2018 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\nfrom c7n.manager import resources\nfrom c7n.query import QueryResourceManager\nfrom c7n.actions import BaseAction\nfrom c7n.utils import local_session, type_schema\n\n\n@resources.register('batch-compute')\nclass ComputeEnvironment(QueryResourceManager):\n\n    class resource_type(object):\n        service = 'batch'\n        filter_name = 'computeEnvironments'\n        filter_type = 'list'\n        dimension = None\n        id = name = \"computeEnvironmentName\"\n        enum_spec = (\n            'describe_compute_environments', 'computeEnvironments', None)\n\n\n@resources.register('batch-definition')\nclass JobDefinition(QueryResourceManager):\n\n    class resource_type(object):\n        service = 'batch'\n        filter_name = 'jobDefinitions'\n        filter_type = 'list'\n        dimension = None\n        id = name = \"jobDefinitionName\"\n        enum_spec = (\n            'describe_job_definitions', 'jobDefinitions', None)\n\n\nclass StateTransitionFilter(object):\n    \"\"\"Filter resources by state.\n\n    Try to simplify construction for policy authors by automatically\n    filtering elements (filters or actions) to the resource states\n    they are valid for.\n    \"\"\"\n    valid_origin_states = ()\n\n    def filter_resource_state(self, resources, key, states=None):\n        states = states or self.valid_origin_states\n        if not states:\n            return resources\n        orig_length = len(resources)\n        results = [r for r in resources if r[key] in states]\n        if orig_length != len(results):\n            self.log.warn(\n                \"%s implicitly filtered %d of %d resources with valid %s\" % (\n                    self.__class__.__name__,\n                    len(results), orig_length, key.lower()))\n        return results\n\n\n@ComputeEnvironment.action_registry.register('update-environment')\nclass UpdateComputeEnvironment(BaseAction, StateTransitionFilter):\n    \"\"\"Updates an AWS batch compute environment\n\n    :example:\n\n    .. code-block: yaml\n\n        policies:\n          - name: update-environments\n            resource: batch-compute\n            filters:\n              - computeResources.desiredvCpus: 0\n              - state: ENABLED\n            actions:\n              - type: update-environment\n                state: DISABLED\n    \"\"\"\n    schema = {\n        'type': 'object',\n        'additionalProperties': False,\n        'properties': {\n            'type': {'enum': ['update-environment']},\n            'computeEnvironment': {'type': 'string'},\n            'state': {'type': 'string', 'enum': ['ENABLED', 'DISABLED']},\n            'computeResources': {\n                'type': 'object',\n                'additionalProperties': False,\n                'properties': {\n                    'minvCpus': {'type': 'integer'},\n                    'maxvCpus': {'type': 'integer'},\n                    'desiredvCpus': {'type': 'integer'}\n                }\n            },\n            'serviceRole': {'type': 'string'}\n        }\n    }\n    permissions = ('batch:UpdateComputeEnvironment',)\n    valid_origin_status = ('VALID', 'INVALID')\n\n    def process(self, resources):\n        resources = self.filter_resource_state(\n            resources, 'status', self.valid_origin_status)\n        client = local_session(self.manager.session_factory).client('batch')\n        params = dict(self.data)\n        params.pop('type')\n        for r in resources:\n            params['computeEnvironment'] = r['computeEnvironmentName']\n            client.update_compute_environment(**params)\n\n\n@ComputeEnvironment.action_registry.register('delete')\nclass DeleteComputeEnvironment(BaseAction, StateTransitionFilter):\n    \"\"\"Delete an AWS batch compute environment\n\n    :example:\n\n    .. code-block: yaml\n\n        policies:\n          - name: delete-environments\n            resource: batch-compute\n            filters:\n              - computeResources.desiredvCpus: 0\n            action:\n              - type: delete\n    \"\"\"\n    schema = type_schema('delete')\n    permissions = ('batch:DeleteComputeEnvironment',)\n    valid_origin_states = ('DISABLED',)\n    valid_origin_status = ('VALID', 'INVALID')\n\n    def delete_environment(self, r):\n        client = local_session(self.manager.session_factory).client('batch')\n        client.delete_compute_environment(\n            computeEnvironment=r['computeEnvironmentName'])\n\n    def process(self, resources):\n        resources = self.filter_resource_state(\n            self.filter_resource_state(\n                resources, 'state', self.valid_origin_states),\n            'status', self.valid_origin_status)\n        with self.executor_factory(max_workers=2) as w:\n            list(w.map(self.delete_environment, resources))\n\n\n@JobDefinition.action_registry.register('deregister')\nclass DefinitionDeregister(BaseAction, StateTransitionFilter):\n    \"\"\"Deregisters a batch definition\n\n    :example:\n\n    .. code-block: yaml\n\n        policies:\n          - name: deregister-definition\n            resource: batch-definition\n            filters:\n              - containerProperties.image: amazonlinux\n            actions:\n              - type: deregister\n    \"\"\"\n    schema = type_schema('deregister')\n    permissions = ('batch:DeregisterJobDefinition',)\n    valid_origin_states = ('ACTIVE',)\n\n    def deregister_definition(self, r):\n        self.client.deregister_job_definition(\n            jobDefinition='%s:%s' % (r['jobDefinitionName'],\n                                     r['revision']))\n\n    def process(self, resources):\n        resources = self.filter_resource_state(\n            resources, 'status', self.valid_origin_states)\n        self.client = local_session(\n            self.manager.session_factory).client('batch')\n        with self.executor_factory(max_workers=2) as w:\n            list(w.map(self.deregister_definition, resources))\n", "path": "c7n/resources/batch.py"}], "after_files": [{"content": "# Copyright 2017-2018 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\nfrom c7n.actions import BaseAction\nfrom c7n.filters.vpc import SecurityGroupFilter, SubnetFilter\nfrom c7n.manager import resources\nfrom c7n.query import QueryResourceManager\n\nfrom c7n.utils import local_session, type_schema\n\n\n@resources.register('batch-compute')\nclass ComputeEnvironment(QueryResourceManager):\n\n    class resource_type(object):\n        service = 'batch'\n        filter_name = 'computeEnvironments'\n        filter_type = 'list'\n        dimension = None\n        id = name = \"computeEnvironmentName\"\n        enum_spec = (\n            'describe_compute_environments', 'computeEnvironments', None)\n\n\n@ComputeEnvironment.filter_registry.register('security-group')\nclass ComputeSGFilter(SecurityGroupFilter):\n\n    RelatedIdsExpression = \"computeResources.securityGroupIds\"\n\n\n@ComputeEnvironment.filter_registry.register('subnet')\nclass ComputeSubnetFilter(SubnetFilter):\n\n    RelatedIdsExpression = \"computeResources.subnets\"\n\n\n@resources.register('batch-definition')\nclass JobDefinition(QueryResourceManager):\n\n    class resource_type(object):\n        service = 'batch'\n        filter_name = 'jobDefinitions'\n        filter_type = 'list'\n        dimension = None\n        id = name = \"jobDefinitionName\"\n        enum_spec = (\n            'describe_job_definitions', 'jobDefinitions', None)\n\n\nclass StateTransitionFilter(object):\n    \"\"\"Filter resources by state.\n\n    Try to simplify construction for policy authors by automatically\n    filtering elements (filters or actions) to the resource states\n    they are valid for.\n    \"\"\"\n    valid_origin_states = ()\n\n    def filter_resource_state(self, resources, key, states=None):\n        states = states or self.valid_origin_states\n        if not states:\n            return resources\n        orig_length = len(resources)\n        results = [r for r in resources if r[key] in states]\n        if orig_length != len(results):\n            self.log.warn(\n                \"%s implicitly filtered %d of %d resources with valid %s\" % (\n                    self.__class__.__name__,\n                    len(results), orig_length, key.lower()))\n        return results\n\n\n@ComputeEnvironment.action_registry.register('update-environment')\nclass UpdateComputeEnvironment(BaseAction, StateTransitionFilter):\n    \"\"\"Updates an AWS batch compute environment\n\n    :example:\n\n    .. code-block: yaml\n\n        policies:\n          - name: update-environments\n            resource: batch-compute\n            filters:\n              - computeResources.desiredvCpus: 0\n              - state: ENABLED\n            actions:\n              - type: update-environment\n                state: DISABLED\n    \"\"\"\n    schema = {\n        'type': 'object',\n        'additionalProperties': False,\n        'properties': {\n            'type': {'enum': ['update-environment']},\n            'computeEnvironment': {'type': 'string'},\n            'state': {'type': 'string', 'enum': ['ENABLED', 'DISABLED']},\n            'computeResources': {\n                'type': 'object',\n                'additionalProperties': False,\n                'properties': {\n                    'minvCpus': {'type': 'integer'},\n                    'maxvCpus': {'type': 'integer'},\n                    'desiredvCpus': {'type': 'integer'}\n                }\n            },\n            'serviceRole': {'type': 'string'}\n        }\n    }\n    permissions = ('batch:UpdateComputeEnvironment',)\n    valid_origin_status = ('VALID', 'INVALID')\n\n    def process(self, resources):\n        resources = self.filter_resource_state(\n            resources, 'status', self.valid_origin_status)\n        client = local_session(self.manager.session_factory).client('batch')\n        params = dict(self.data)\n        params.pop('type')\n        for r in resources:\n            params['computeEnvironment'] = r['computeEnvironmentName']\n            client.update_compute_environment(**params)\n\n\n@ComputeEnvironment.action_registry.register('delete')\nclass DeleteComputeEnvironment(BaseAction, StateTransitionFilter):\n    \"\"\"Delete an AWS batch compute environment\n\n    :example:\n\n    .. code-block: yaml\n\n        policies:\n          - name: delete-environments\n            resource: batch-compute\n            filters:\n              - computeResources.desiredvCpus: 0\n            action:\n              - type: delete\n    \"\"\"\n    schema = type_schema('delete')\n    permissions = ('batch:DeleteComputeEnvironment',)\n    valid_origin_states = ('DISABLED',)\n    valid_origin_status = ('VALID', 'INVALID')\n\n    def delete_environment(self, r):\n        client = local_session(self.manager.session_factory).client('batch')\n        client.delete_compute_environment(\n            computeEnvironment=r['computeEnvironmentName'])\n\n    def process(self, resources):\n        resources = self.filter_resource_state(\n            self.filter_resource_state(\n                resources, 'state', self.valid_origin_states),\n            'status', self.valid_origin_status)\n        with self.executor_factory(max_workers=2) as w:\n            list(w.map(self.delete_environment, resources))\n\n\n@JobDefinition.action_registry.register('deregister')\nclass DefinitionDeregister(BaseAction, StateTransitionFilter):\n    \"\"\"Deregisters a batch definition\n\n    :example:\n\n    .. code-block: yaml\n\n        policies:\n          - name: deregister-definition\n            resource: batch-definition\n            filters:\n              - containerProperties.image: amazonlinux\n            actions:\n              - type: deregister\n    \"\"\"\n    schema = type_schema('deregister')\n    permissions = ('batch:DeregisterJobDefinition',)\n    valid_origin_states = ('ACTIVE',)\n\n    def deregister_definition(self, r):\n        self.client.deregister_job_definition(\n            jobDefinition='%s:%s' % (r['jobDefinitionName'],\n                                     r['revision']))\n\n    def process(self, resources):\n        resources = self.filter_resource_state(\n            resources, 'status', self.valid_origin_states)\n        self.client = local_session(\n            self.manager.session_factory).client('batch')\n        with self.executor_factory(max_workers=2) as w:\n            list(w.map(self.deregister_definition, resources))\n", "path": "c7n/resources/batch.py"}]}