Repository: cloud-custodian/cloud-custodian

Issue:
APIGateway (rest-account) raise exception when there is no APIGateway in account
```
2018-02-19 07:42:08,862 - custodian.commands - ERROR - Error while executing policy rest-account, continuing
Traceback (most recent call last):
  File "/var/task/c7n/commands.py", line 217, in run
    policy()
  File "/var/task/c7n/policy.py", line 783, in __call__
    resources = PullMode(self).run()
  File "/var/task/c7n/policy.py", line 306, in run
    resources = self.policy.resource_manager.resources()
  File "/var/task/c7n/resources/apigw.py", line 50, in resources
    return self.filter_resources([self._get_account()])
  File "/var/task/c7n/resources/apigw.py", line 44, in _get_account
    account = client.get_account()
  File "/var/runtime/botocore/client.py", line 317, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 615, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.errorfactory.NotFoundException: An error occurred (NotFoundException) when calling the GetAccount operation: Invalid Customer identifier specified
```


Discussion:

Resolving patch:
diff --git a/c7n/resources/apigw.py b/c7n/resources/apigw.py
--- a/c7n/resources/apigw.py
+++ b/c7n/resources/apigw.py
@@ -13,6 +13,8 @@
 # limitations under the License.
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+from botocore.exceptions import ClientError
+
 from concurrent.futures import as_completed
 
 from c7n.actions import ActionRegistry, BaseAction
@@ -41,16 +43,20 @@ def get_model(self):
 
     def _get_account(self):
         client = utils.local_session(self.session_factory).client('apigateway')
-        account = client.get_account()
+        try:
+            account = client.get_account()
+        except ClientError as e:
+            if e.response['Error']['Code'] == 'NotFoundException':
+                return []
         account.pop('ResponseMetadata', None)
         account['account_id'] = 'apigw-settings'
-        return account
+        return [account]
 
     def resources(self):
-        return self.filter_resources([self._get_account()])
+        return self.filter_resources(self._get_account())
 
     def get_resources(self, resource_ids):
-        return [self._get_account()]
+        return self._get_account()
 
 
 OP_SCHEMA = {


Test patch:
diff --git a/tests/data/placebo/test_rest_account_missing/apigateway.GetAccount_1.json b/tests/data/placebo/test_rest_account_missing/apigateway.GetAccount_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_rest_account_missing/apigateway.GetAccount_1.json
@@ -0,0 +1,22 @@
+{
+    "status_code": 404, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 404, 
+            "RequestId": "52e76b2a-158d-11e8-b548-edb9fb9a94be", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "52e76b2a-158d-11e8-b548-edb9fb9a94be", 
+                "content-length": "52", 
+                "connection": "keep-alive", 
+                "date": "Mon, 19 Feb 2018 15:55:36 GMT", 
+                "content-type": "application/json", 
+                "x-amzn-errortype": "NotFoundException"
+            }
+        }, 
+        "Error": {
+            "Message": "Invalid Customer identifier specified", 
+            "Code": "NotFoundException"
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/test_apigw.py b/tests/test_apigw.py
--- a/tests/test_apigw.py
+++ b/tests/test_apigw.py
@@ -18,6 +18,15 @@
 
 class TestRestAccount(BaseTest):
 
+    def test_missing_rest_account(self):
+        session_factory = self.replay_flight_data('test_rest_account_missing')
+        p = self.load_policy({
+            'name': 'api-account',
+            'resource': 'rest-account'},
+            session_factory=session_factory)
+        resources = p.run()
+        self.assertEqual(resources, [])
+
     def test_rest_api_update(self):
         session_factory = self.replay_flight_data('test_rest_account_update')
         log_role = 'arn:aws:iam::644160558196:role/OtherApiGatewayLogger'
@@ -31,7 +40,7 @@ def test_rest_api_update(self):
                       'path': '/cloudwatchRoleArn',
                       'value': log_role}
                  ]}]}, session_factory=session_factory)
-        before_account = p.resource_manager._get_account()
+        before_account, = p.resource_manager._get_account()
         self.assertEqual(
             before_account['cloudwatchRoleArn'],
             'arn:aws:iam::644160558196:role/ApiGwLogger')
@@ -39,7 +48,7 @@ def test_rest_api_update(self):
         resources = p.run()
         self.assertEqual(len(resources), 1)
 
-        after_account = p.resource_manager._get_account()
+        after_account, = p.resource_manager._get_account()
         self.assertEqual(
             after_account['cloudwatchRoleArn'], log_role)