Repository: cloud-custodian/cloud-custodian

Issue:
AWS SES email identity resource type support
### Describe the feature

It would be useful to have support for SES EmailIdentity resource type 

### Extra information or context

I will be working on this


Discussion:

Resolving patch:
diff --git a/c7n/resources/resource_map.py b/c7n/resources/resource_map.py
--- a/c7n/resources/resource_map.py
+++ b/c7n/resources/resource_map.py
@@ -196,6 +196,7 @@
     "aws.secrets-manager": "c7n.resources.secretsmanager.SecretsManager",
     "aws.security-group": "c7n.resources.vpc.SecurityGroup",
     "aws.ses-configuration-set": "c7n.resources.ses.SESConfigurationSet",
+    "aws.ses-email-identity": "c7n.resources.ses.SESEmailIdentity",
     "aws.serverless-app": "c7n.resources.sar.ServerlessApp",
     "aws.service-quota-request": "c7n.resources.quotas.ServiceQuotaRequest",
     "aws.service-quota": "c7n.resources.quotas.ServiceQuota",
diff --git a/c7n/resources/ses.py b/c7n/resources/ses.py
--- a/c7n/resources/ses.py
+++ b/c7n/resources/ses.py
@@ -6,6 +6,7 @@
 from c7n.utils import local_session, type_schema
 from c7n.tags import universal_augment
 
+
 class DescribeConfigurationSet(DescribeSource):
 
     def augment(self, resources):
@@ -73,3 +74,17 @@ def process(self, resources):
                     'TlsPolicy': tls_policy
                 },
             )
+
+
+@resources.register('ses-email-identity')
+class SESEmailIdentity(QueryResourceManager):
+    class resource_type(TypeInfo):
+        service = 'sesv2'
+        enum_spec = ('list_email_identities', 'EmailIdentities', None)
+        detail_spec = ('get_email_identity', 'EmailIdentity', 'IdentityName', None)
+        name = id = 'IdentityName'
+        arn_type = 'identity'
+        universal_taggable = object()
+        permission_prefix = 'ses'
+        arn_service = 'ses'
+        cfn_type = 'AWS::SES::EmailIdentity'


Test patch:
diff --git a/tests/data/cfn-types.json b/tests/data/cfn-types.json
--- a/tests/data/cfn-types.json
+++ b/tests/data/cfn-types.json
@@ -803,6 +803,7 @@
   "AWS::SES::ConfigurationSet",
   "AWS::SES::ConfigurationSetEventDestination",
   "AWS::SES::ContactList",
+  "AWS::SES::EmailIdentity",
   "AWS::SES::ReceiptFilter",
   "AWS::SES::ReceiptRule",
   "AWS::SES::ReceiptRuleSet",
diff --git a/tests/data/placebo/test_ses_email_identity_query/email.GetEmailIdentity_1.json b/tests/data/placebo/test_ses_email_identity_query/email.GetEmailIdentity_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_ses_email_identity_query/email.GetEmailIdentity_1.json
@@ -0,0 +1,21 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "IdentityType": "DOMAIN",
+        "FeedbackForwardingStatus": true,
+        "VerifiedForSendingStatus": false,
+        "DkimAttributes": {
+            "SigningEnabled": false,
+            "Status": "NOT_STARTED",
+            "SigningAttributesOrigin": "AWS_SES",
+            "NextSigningKeyLength": "RSA_1024_BIT"
+        },
+        "MailFromAttributes": {
+            "BehaviorOnMxFailure": "USE_DEFAULT_VALUE"
+        },
+        "Policies": {},
+        "Tags": [],
+        "VerificationStatus": "FAILED"
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_ses_email_identity_query/email.ListEmailIdentities_1.json b/tests/data/placebo/test_ses_email_identity_query/email.ListEmailIdentities_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_ses_email_identity_query/email.ListEmailIdentities_1.json
@@ -0,0 +1,14 @@
+{
+    "status_code": 200,
+    "data": {
+        "ResponseMetadata": {},
+        "EmailIdentities": [
+            {
+                "IdentityType": "DOMAIN",
+                "IdentityName": "example.com",
+                "SendingEnabled": false,
+                "VerificationStatus": "FAILED"
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/tests/test_ses.py b/tests/test_ses.py
--- a/tests/test_ses.py
+++ b/tests/test_ses.py
@@ -2,6 +2,7 @@
 # SPDX-License-Identifier: Apache-2.0
 from .common import BaseTest
 
+
 class SESTest(BaseTest):
 
     def test_ses_configuration_set_query(self):
@@ -41,3 +42,17 @@ def test_ses_configuration_set_delivery_options(self):
                                                          ConfigurationSetAttributeNames=['deliveryOptions'])
             tls_policy = response['DeliveryOptions']['TlsPolicy']
             self.assertEqual(tls_policy, "Require")
+
+
+class SESV2Test(BaseTest):
+
+    def test_ses_email_identity_query(self):
+        session_factory = self.replay_flight_data("test_ses_email_identity_query")
+        p = self.load_policy(
+            {
+                "name": "ses-email-identity-query-test",
+                "resource": "ses-email-identity"
+            }, session_factory=session_factory
+        )
+        resources = p.run()
+        self.assertEqual(len(resources), 1)