Repository: cloud-custodian/cloud-custodian

Issue:
Deprecation warning due to invalid escape sequences 
**Describe the bug**

Deprecation warnings are raised due to invalid escape sequences. This can be fixed by using raw strings or escaping the literals. pyupgrade also helps in automatic conversion : https://github.com/asottile/pyupgrade/

**To Reproduce**

```
find . -iname '*.py' | grep -v example | xargs -P4 -I{} python3.8 -Wall -m py_compile {}
./tools/c7n_sentry/test_sentry.py:50: DeprecationWarning: invalid escape sequence \m
  msg2 = """
./tests/zpill.py:274: DeprecationWarning: invalid escape sequence \d
  response_data = re.sub("\d{12}", ACCOUNT_ID, response_data)  # noqa
```

**Background (please complete the following information):**
 - OS: [e.g. OSX 10.15]
 - Python Version: 3.8
 - Custodian Version: master branch
 - Tool Version: [if applicable]
 - Cloud Provider: [e.g. gcp, aws, azure]
 - Policy: [please exclude any account/sensitive information]

Discussion:

Patch:
diff --git a/c7n/resources/glue.py b/c7n/resources/glue.py
index e985ebc6d..d46953f56 100644
--- a/c7n/resources/glue.py
+++ b/c7n/resources/glue.py
@@ -528,6 +528,9 @@ class GlueDataCatalog(ResourceManager):
     def resources(self):
         return self.filter_resources(self._get_catalog_encryption_settings())
 
+    def get_resources(self, resource_ids):
+        return [{'CatalogId': self.config.account_id}]
+
 
 @GlueDataCatalog.action_registry.register('set-encryption')
 class GlueDataCatalogEncryption(BaseAction):


Test patch:
diff --git a/tests/data/cwe/event-cloud-trail-catalog-put-resource-policy.json b/tests/data/cwe/event-cloud-trail-catalog-put-resource-policy.json
new file mode 100644
index 000000000..69211950a
--- /dev/null
+++ b/tests/data/cwe/event-cloud-trail-catalog-put-resource-policy.json
@@ -0,0 +1,46 @@
+{
+    "version": "0",
+    "id": "4186524f-4444-4444-4444-9c149bfbbbe2",
+    "detail-type": "AWS API Call via CloudTrail",
+    "source": "aws.glue",
+    "account": "644160558196",
+    "time": "2020-06-04T15:18:28Z",
+    "region": "us-east-1",
+    "resources": [],
+    "detail": {
+      "eventVersion": "1.05",
+      "userIdentity": {
+        "type": "IAMUser",
+        "principalId": "qwefqffasdfdfsda",
+        "arn": "arn:aws:iam::644160558196:user/fake@fakeemail.com",
+        "accountId": "644160558196",
+        "accessKeyId": "1345351435",
+        "userName": "fake@fakeemail.com",
+        "sessionContext": {
+          "sessionIssuer": {},
+          "webIdFederationData": {},
+          "attributes": {
+            "mfaAuthenticated": "false",
+            "creationDate": "2020-06-04T15:06:07Z"
+          }
+        }
+      },
+      "eventTime": "2020-06-04T15:18:28Z",
+      "eventSource": "glue.amazonaws.com",
+      "eventName": "PutResourcePolicy",
+      "awsRegion": "us-east-1",
+      "sourceIPAddress": "99.99.99.99",
+      "userAgent": "console.amazonaws.com",
+      "requestParameters": {
+        "policyHashCondition": "qwerwqerewqrewqr==",
+        "policyInJson": "{\n  \"Version\" : \"2012-10-17\",\n  \"Statement\" : [ {\n    \"Effect\" : \"Allow\",\n    \"Principal\" : \"*\",\n    \"Action\" : \"glue:*\",\n    \"Resource\" : \"arn:aws:glue:us-east-1:644160558196:catalog\",\n    \"Condition\": {\n        \"StringEquals\": {\n            \"aws:PrincipalOrgID\": \"o-4amkskbcf3\"\n        }        \n    }\n  } ]\n}"
+      },
+      "responseElements": {
+        "policyHash": "eqwewrewqerwerewr=="
+      },
+      "requestID": "562ac246-0da8-4444-4444-7053b5ecf789",
+      "eventID": "1f5ed731-4444-4a5c-4444-57f55e636789",
+      "eventType": "AwsApiCall"
+    },
+    "debug": true
+  }
\ No newline at end of file
diff --git a/tests/data/cwe/event-cloud-trail-catalog-set-encryption.json b/tests/data/cwe/event-cloud-trail-catalog-set-encryption.json
new file mode 100644
index 000000000..9db76cf06
--- /dev/null
+++ b/tests/data/cwe/event-cloud-trail-catalog-set-encryption.json
@@ -0,0 +1,52 @@
+{
+    "version": "0",
+    "id": "b782ed03-9c34-41d8-4444-bc7c6a5e2cfd",
+    "detail-type": "AWS API Call via CloudTrail",
+    "source": "aws.glue",
+    "account": "644160558196",
+    "time": "2020-06-05T16:10:47Z",
+    "region": "us-east-1",
+    "resources": [],
+    "detail": {
+        "eventVersion": "1.05",
+        "userIdentity": {
+            "type": "AssumedRole",
+            "principalId": "23454235342523:custodian-net-change-encryption",
+            "arn": "arn:aws:sts::644160558196:assumed-role/CloudCustodianRole/custodian-net-change-encryption",
+            "accountId": "644160558196",
+            "accessKeyId": "1525415421513245",
+            "sessionContext": {
+                "sessionIssuer": {
+                    "type": "Role",
+                    "principalId": "23454235342523",
+                    "arn": "arn:aws:iam::644160558196:role/CloudCustodianRole",
+                    "accountId": "644160558196",
+                    "userName": "CloudCustodianRole"
+                },
+                "webIdFederationData": {},
+                "attributes": {
+                    "mfaAuthenticated": "false",
+                    "creationDate": "2020-06-05T16:09:41Z"
+                }
+            }
+        },
+        "eventTime": "2020-06-05T16:10:47Z",
+        "eventSource": "glue.amazonaws.com",
+        "eventName": "PutDataCatalogEncryptionSettings",
+        "awsRegion": "us-east-1",
+        "sourceIPAddress": "35.171.244.77",
+        "userAgent": "CloudCustodian(net-change-encryption)/0.9.2 Python/3.8.3 Linux/4.14.165-102.205.amzn2.x86_64 exec-env/AWS_Lambda_python3.8 Botocore/1.15.49",
+        "requestParameters": {
+            "dataCatalogEncryptionSettings": {
+                "encryptionAtRest": {
+                    "catalogEncryptionMode": "SSE-KMS"
+                }
+            }
+        },
+        "responseElements": null,
+        "requestID": "b86bcd00-4444-4127-a74c-6c5f04d6534c",
+        "eventID": "3cda2b5f-a6c7-4c68-4444-93b0f6e1963c",
+        "eventType": "AwsApiCall"
+    },
+    "debug": true
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_catalog_change_encryption_event/glue.GetDataCatalogEncryptionSettings_1.json b/tests/data/placebo/test_catalog_change_encryption_event/glue.GetDataCatalogEncryptionSettings_1.json
new file mode 100644
index 000000000..15a04d4de
--- /dev/null
+++ b/tests/data/placebo/test_catalog_change_encryption_event/glue.GetDataCatalogEncryptionSettings_1.json
@@ -0,0 +1,14 @@
+{
+    "status_code": 200,
+    "data": {
+        "DataCatalogEncryptionSettings": {
+            "EncryptionAtRest": {
+                "CatalogEncryptionMode": "DISABLED"
+            },
+            "ConnectionPasswordEncryption": {
+                "ReturnConnectionPasswordEncrypted": false
+            }
+        },
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_catalog_change_encryption_event/glue.GetDataCatalogEncryptionSettings_2.json b/tests/data/placebo/test_catalog_change_encryption_event/glue.GetDataCatalogEncryptionSettings_2.json
new file mode 100644
index 000000000..c80b917c2
--- /dev/null
+++ b/tests/data/placebo/test_catalog_change_encryption_event/glue.GetDataCatalogEncryptionSettings_2.json
@@ -0,0 +1,15 @@
+{
+    "status_code": 200,
+    "data": {
+        "DataCatalogEncryptionSettings": {
+            "EncryptionAtRest": {
+                "CatalogEncryptionMode": "SSE-KMS",
+                "SseAwsKmsKeyId": "alias/aws/glue"
+            },
+            "ConnectionPasswordEncryption": {
+                "ReturnConnectionPasswordEncrypted": false
+            }
+        },
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_catalog_change_encryption_event/glue.PutDataCatalogEncryptionSettings_1.json b/tests/data/placebo/test_catalog_change_encryption_event/glue.PutDataCatalogEncryptionSettings_1.json
new file mode 100644
index 000000000..5b2170a07
--- /dev/null
+++ b/tests/data/placebo/test_catalog_change_encryption_event/glue.PutDataCatalogEncryptionSettings_1.json
@@ -0,0 +1,6 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_catalog_change_rbp_event/glue.GetResourcePolicy_1.json b/tests/data/placebo/test_catalog_change_rbp_event/glue.GetResourcePolicy_1.json
new file mode 100644
index 000000000..7ff26e2ad
--- /dev/null
+++ b/tests/data/placebo/test_catalog_change_rbp_event/glue.GetResourcePolicy_1.json
@@ -0,0 +1,28 @@
+{
+    "status_code": 200,
+    "data": {
+        "PolicyInJson": "{\n  \"Version\" : \"2012-10-17\",\n  \"Statement\" : [ {\n    \"Effect\" : \"Allow\",\n    \"Principal\" : \"*\",\n    \"Action\" : \"glue:*\",\n    \"Resource\" : \"arn:aws:glue:us-east-1:644160558196:catalog\",\n    \"Condition\" : {\n      \"StringEquals\" : {\n        \"aws:PrincipalOrgID\" : \"o-4amkskbcf3\"\n      }\n    }\n  }, {\n    \"Effect\" : \"Allow\",\n    \"Principal\" : \"*\",\n    \"Action\" : \"glue:*\",\n    \"Resource\" : \"arn:aws:glue:us-east-1:644160558196:catalog\",\n    \"Condition\" : {\n      \"StringEquals\" : {\n        \"aws:PrincipalOrgID\" : \"o-4amkskbcf1\"\n      }\n    }\n  } ]\n}",
+        "PolicyHash": "vQI9F/KPAi+BKiDBvNPXSw==",
+        "CreateTime": {
+            "__class__": "datetime",
+            "year": 2020,
+            "month": 6,
+            "day": 5,
+            "hour": 12,
+            "minute": 26,
+            "second": 46,
+            "microsecond": 47000
+        },
+        "UpdateTime": {
+            "__class__": "datetime",
+            "year": 2020,
+            "month": 6,
+            "day": 5,
+            "hour": 12,
+            "minute": 26,
+            "second": 46,
+            "microsecond": 47000
+        },
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_catalog_change_rbp_event/glue.GetResourcePolicy_2.json b/tests/data/placebo/test_catalog_change_rbp_event/glue.GetResourcePolicy_2.json
new file mode 100644
index 000000000..7ff26e2ad
--- /dev/null
+++ b/tests/data/placebo/test_catalog_change_rbp_event/glue.GetResourcePolicy_2.json
@@ -0,0 +1,28 @@
+{
+    "status_code": 200,
+    "data": {
+        "PolicyInJson": "{\n  \"Version\" : \"2012-10-17\",\n  \"Statement\" : [ {\n    \"Effect\" : \"Allow\",\n    \"Principal\" : \"*\",\n    \"Action\" : \"glue:*\",\n    \"Resource\" : \"arn:aws:glue:us-east-1:644160558196:catalog\",\n    \"Condition\" : {\n      \"StringEquals\" : {\n        \"aws:PrincipalOrgID\" : \"o-4amkskbcf3\"\n      }\n    }\n  }, {\n    \"Effect\" : \"Allow\",\n    \"Principal\" : \"*\",\n    \"Action\" : \"glue:*\",\n    \"Resource\" : \"arn:aws:glue:us-east-1:644160558196:catalog\",\n    \"Condition\" : {\n      \"StringEquals\" : {\n        \"aws:PrincipalOrgID\" : \"o-4amkskbcf1\"\n      }\n    }\n  } ]\n}",
+        "PolicyHash": "vQI9F/KPAi+BKiDBvNPXSw==",
+        "CreateTime": {
+            "__class__": "datetime",
+            "year": 2020,
+            "month": 6,
+            "day": 5,
+            "hour": 12,
+            "minute": 26,
+            "second": 46,
+            "microsecond": 47000
+        },
+        "UpdateTime": {
+            "__class__": "datetime",
+            "year": 2020,
+            "month": 6,
+            "day": 5,
+            "hour": 12,
+            "minute": 26,
+            "second": 46,
+            "microsecond": 47000
+        },
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_catalog_change_rbp_event/glue.GetResourcePolicy_3.json b/tests/data/placebo/test_catalog_change_rbp_event/glue.GetResourcePolicy_3.json
new file mode 100644
index 000000000..a45197edd
--- /dev/null
+++ b/tests/data/placebo/test_catalog_change_rbp_event/glue.GetResourcePolicy_3.json
@@ -0,0 +1,28 @@
+{
+    "status_code": 200,
+    "data": {
+        "PolicyInJson": "{\n  \"Version\" : \"2012-10-17\",\n  \"Statement\" : [ {\n    \"Effect\" : \"Allow\",\n    \"Principal\" : \"*\",\n    \"Action\" : \"glue:*\",\n    \"Resource\" : \"arn:aws:glue:us-east-1:644160558196:catalog\",\n    \"Condition\" : {\n      \"StringEquals\" : {\n        \"aws:PrincipalOrgID\" : \"o-4amkskbcf1\"\n      }\n    }\n  } ]\n}",
+        "PolicyHash": "hfAqfsBoPt7ZUGlZjU5mMQ==",
+        "CreateTime": {
+            "__class__": "datetime",
+            "year": 2020,
+            "month": 6,
+            "day": 5,
+            "hour": 12,
+            "minute": 26,
+            "second": 52,
+            "microsecond": 531000
+        },
+        "UpdateTime": {
+            "__class__": "datetime",
+            "year": 2020,
+            "month": 6,
+            "day": 5,
+            "hour": 12,
+            "minute": 26,
+            "second": 52,
+            "microsecond": 531000
+        },
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_catalog_change_rbp_event/glue.PutResourcePolicy_1.json b/tests/data/placebo/test_catalog_change_rbp_event/glue.PutResourcePolicy_1.json
new file mode 100644
index 000000000..e08bc9386
--- /dev/null
+++ b/tests/data/placebo/test_catalog_change_rbp_event/glue.PutResourcePolicy_1.json
@@ -0,0 +1,7 @@
+{
+    "status_code": 200,
+    "data": {
+        "PolicyHash": "hfAqfsBoPt7ZUGlZjU5mMQ==",
+        "ResponseMetadata": {}
+    }
+}
\ No newline at end of file
diff --git a/tests/test_glue.py b/tests/test_glue.py
index 5057a3215..d4bfe5b82 100644
--- a/tests/test_glue.py
+++ b/tests/test_glue.py
@@ -15,6 +15,7 @@ from .common import BaseTest
 import time
 import json
 from c7n.exceptions import PolicyValidationError
+from .common import event_data
 
 
 class TestGlueConnections(BaseTest):
@@ -587,3 +588,102 @@ class TestGlueDataCatalog(BaseTest):
                 "actions": [{"type": "remove-statements", "statement_ids": "matched"}],
             }
         )
+
+    def test_catalog_change_encryption_event(self):
+        session_factory = self.replay_flight_data("test_catalog_change_encryption_event")
+        session = session_factory()
+        client = session.client("glue")
+        before_cat_setting = client.get_data_catalog_encryption_settings()
+        self.assertJmes(
+            'DataCatalogEncryptionSettings.EncryptionAtRest.CatalogEncryptionMode',
+            before_cat_setting,
+            'DISABLED'
+        )
+        self.assertJmes(
+            'DataCatalogEncryptionSettings.EncryptionAtRest.SseAwsKmsKeyId',
+            before_cat_setting,
+            None
+        )
+        p = self.load_policy(
+            {
+                "name": "net-change-rbp-cross-account",
+                "resource": "glue-catalog",
+                "mode": {
+                    "type": "cloudtrail",
+                    "role": "arn:aws:iam::644160558196:role/CloudCustodianRole",
+                    "events": [
+                        {
+                            "source": "glue.amazonaws.com",
+                            "event": "PutDataCatalogEncryptionSettings",
+                            "ids": "userIdentity.accountId"
+                        }
+                    ],
+                },
+                'filters': [{
+                    'type': 'value',
+                    'key': 'DataCatalogEncryptionSettings.EncryptionAtRest.SseAwsKmsKeyId',
+                    'value': 'alias/skunk/trails',
+                    'op': 'ne'},
+                ],
+                "actions": [
+                    {
+                        "type": "set-encryption",
+                        "attributes": {
+                            "EncryptionAtRest": {
+                                "CatalogEncryptionMode": "SSE-KMS"
+                            }
+                        }
+                    }
+                ],
+            },
+            session_factory=session_factory,
+        )
+        p.push(event_data("event-cloud-trail-catalog-set-encryption.json"), None)
+        after_cat_setting = client.get_data_catalog_encryption_settings()
+        self.assertJmes(
+            'DataCatalogEncryptionSettings.EncryptionAtRest.CatalogEncryptionMode',
+            after_cat_setting,
+            'SSE-KMS'
+        )
+        self.assertJmes(
+            'DataCatalogEncryptionSettings.EncryptionAtRest.SseAwsKmsKeyId',
+            after_cat_setting,
+            'alias/aws/glue'
+        )
+
+    def test_catalog_change_rbp_event(self):
+        session_factory = self.replay_flight_data("test_catalog_change_rbp_event")
+        session = session_factory()
+        client = session.client("glue")
+        before_cat_setting = client.get_resource_policy()
+        assert('o-4amkskbcf3' in before_cat_setting.get('PolicyInJson'))
+        p = self.load_policy(
+            {
+                "name": "net-change-rbp-cross-account",
+                "resource": "glue-catalog",
+                "mode": {
+                    "type": "cloudtrail",
+                    "role": "arn:aws:iam::644160558196:role/CloudCustodianRole",
+                    "events": [
+                        {
+                            "source": "glue.amazonaws.com",
+                            "event": "PutResourcePolicy",
+                            "ids": "awsRegion"
+                        }
+                    ],
+                },
+                "filters": [
+                    {
+                        "type": "cross-account",
+                        "whitelist_orgids": [
+                            "o-4amkskbcf1"
+                        ]
+                    }
+                ],
+                "actions": [{"type": "remove-statements", "statement_ids": "matched"}],
+            },
+            session_factory=session_factory,
+        )
+        p.push(event_data("event-cloud-trail-catalog-put-resource-policy.json"), None)
+        after_cat_setting = client.get_resource_policy()
+        assert('o-4amkskbcf3' not in after_cat_setting.get('PolicyInJson'))
diff --git a/tests/zpill.py b/tests/zpill.py
index 64f62430f..7835b5147 100644
--- a/tests/zpill.py
+++ b/tests/zpill.py
@@ -271,7 +271,7 @@ class RedPill(pill.Pill):
             response_data['ResponseMetadata'] = {}
 
         response_data = json.dumps(response_data, default=serialize)
-        response_data = re.sub("\d{12}", ACCOUNT_ID, response_data)  # noqa
+        response_data = re.sub(r"\d{12}", ACCOUNT_ID, response_data)  # noqa
         response_data = json.loads(response_data, object_hook=deserialize)
 
         super(RedPill, self).save_response(service, operation, response_data,
diff --git a/tools/c7n_sentry/test_sentry.py b/tools/c7n_sentry/test_sentry.py
index f3a8b3cc9..9c8f1fa78 100644
--- a/tools/c7n_sentry/test_sentry.py
+++ b/tools/c7n_sentry/test_sentry.py
@@ -48,7 +48,7 @@ msg = """2016-07-07 19:14:24,160 - ERROR - custodian.output - Error while execut
 
 
 msg2 = """
-2016-08-09 19:16:28,943 - ERROR - custodian.output - Error while executing policy Traceback (most recent call last):\n  File "/usr/local/custodian/lib/python2.7/site-packages/c7n/policy.py", line 234, in poll\n results = a.process(resources)\n File "/usr/local/custodian/lib/python2.7/site-packages/c7n/resources/rds.py", line 291, in process\n client.delete_db_instance(**params)\n  File "/usr/local/custodian/lib/python2.7/site-packages/botocore/client.py", line 278, in _api_call\n return self._make_api_call(operation_name, kwargs)\n File "/usr/local/custodian/lib/python2.7/site-packages/botocore/client.py", line 572, in _make_api_call\n raise ClientError(parsed_response, operation_name)\m ClientError: An error occurred (InvalidParameterValue) when calling the DeleteDBInstance operation: The parameter FinalDBSnapshotIdentifier is not a valid identifier. Identifiers must begin with a letter; must contain only ASCII letters, digits, and hyphens; and must not end with a hyphen or contain two consecutive hyphens.""" # NOQA
+2016-08-09 19:16:28,943 - ERROR - custodian.output - Error while executing policy Traceback (most recent call last):\n  File "/usr/local/custodian/lib/python2.7/site-packages/c7n/policy.py", line 234, in poll\n results = a.process(resources)\n File "/usr/local/custodian/lib/python2.7/site-packages/c7n/resources/rds.py", line 291, in process\n client.delete_db_instance(**params)\n  File "/usr/local/custodian/lib/python2.7/site-packages/botocore/client.py", line 278, in _api_call\n return self._make_api_call(operation_name, kwargs)\n File "/usr/local/custodian/lib/python2.7/site-packages/botocore/client.py", line 572, in _make_api_call\n raise ClientError(parsed_response, operation_name)\n ClientError: An error occurred (InvalidParameterValue) when calling the DeleteDBInstance operation: The parameter FinalDBSnapshotIdentifier is not a valid identifier. Identifiers must begin with a letter; must contain only ASCII letters, digits, and hyphens; and must not end with a hyphen or contain two consecutive hyphens.""" # NOQA
 
 if __name__ == '__main__':
     unittest.main()