[英]How do I verify a domain registered in AWS Route 53 with AWS Simple Email Service (SES) purely through the Python client, boto3?
I have read every ounce of documentation I could find related to this topic.我已经阅读了所有我能找到的与该主题相关的文档。 I've been using the boto3 Python client to work with AWS to register a new domain and verify it to be used with the AWS Simple Email Service (SES).我一直在使用 boto3 Python 客户端与 AWS 一起注册一个新域并验证它是否与 AWS 简单 Email 服务 (SES) 一起使用。
This is an entirely painless task in just a few clicks with the GUI:这是一项完全轻松的任务,只需在 GUI 中单击几下:
And I thought, reading the SES boto3 documentation , I could achieve the same thing via API with the Python client.我想,阅读SES boto3 文档,我可以通过 API 和 Python 客户端实现同样的事情。
But nothing happens.但是没有任何反应。 I get no error.我没有错误。 No indication appears in the GUI that the verification is pending (the way it does when done through the GUI). GUI 中没有指示验证正在等待(通过 GUI 完成时的方式)。 Even after 72 hours, nothing changes.即使在 72 小时后,也没有任何变化。 But when I do it in the GUI, it works pretty quickly, so presumably I just missed some important API step.但是当我在 GUI 中执行它时,它运行得非常快,所以大概我只是错过了一些重要的 API 步骤。
%pip install boto3 # a Jupyter-ism
import boto3
import time
class Domain:
# AWS Route 53 Domains Documentation:
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/route53domains.html#Route53Domains.Client.get_operation_detail
def __init__(self, static_domain=False): # identity: Identity
self.client = boto3.client('route53domains')
if static_domain:
domain_list_response = self.client.list_domains()
print(domain_list_response)
domain_owned = False
for domain in domain_list_response['Domains']:
if domain['DomainName'] == static_domain:
domain_owned = True
if domain_owned:
print('Domain already owned...')
self.name = static_domain
else:
availability_response = self.client.check_domain_availability(
DomainName=static_domain
)
first_name = 'First' # identity.fname
last_name = 'Last' # identity.lname
org_name = 'Testing123' # identity.org
address = '123 Testing Drive' # idenity.addr
city = 'TestingCity' # identity.city
state = 'TestingState' # identity.state_code
country = 'US' # identity.country_code
zip_code = '12345' # identity.zip_code
phone = '+1.1234567890' # identity.phone
email = f'admin@{static_domain}'
if availability_response['Availability'] == 'AVAILABLE':
print('Domain available...')
registration_response = self.client.register_domain(
DomainName=static_domain,
DurationInYears=1,
AutoRenew=False,
AdminContact={
'FirstName': first_name,
'LastName': last_name,
'ContactType': 'PERSON',
'OrganizationName': org_name,
'AddressLine1': address,
'City': city,
'State': state,
'CountryCode': country,
'ZipCode': zip_code,
'PhoneNumber': phone,
'Email': email
},
RegistrantContact={
'FirstName': first_name,
'LastName': last_name,
'ContactType': 'PERSON',
'OrganizationName': org_name,
'AddressLine1': address,
'City': city,
'State': state,
'CountryCode': country,
'ZipCode': zip_code,
'PhoneNumber': phone,
'Email': email
},
TechContact={
'FirstName': first_name,
'LastName': last_name,
'ContactType': 'PERSON',
'OrganizationName': org_name,
'AddressLine1': address,
'City': city,
'State': state,
'CountryCode': country,
'ZipCode': zip_code,
'PhoneNumber': phone,
'Email': email
},
PrivacyProtectAdminContact=False,
PrivacyProtectRegistrantContact=False,
PrivacyProtectTechContact=False
)
print(registration_response)
operation_id = registration_response['OperationId']
print(operation_id)
operation_detail_response = self.client.get_operation_detail(
OperationId=operation_id
)
print(operation_detail_response)
while operation_detail_response['Status'] == 'IN_PROGRESS':
time.sleep(10)
operation_detail_response = self.client.get_operation_detail(
OperationId=operation_id
)
print(operation_detail_response)
if operation_detail_response['Status'] == 'IN_PROGRESS':
print('Domain registration in progress...')
else:
print('Domain registration successful...')
else:
print('dynamic domain generation not yet supported')
class Inbox:
def __init__(self, domain, username: str):
self.client = boto3.client('ses')
self.domain = domain
self.username = username
self.address = f'{self.username}@{self.domain.name}'
print(f'Inbox ({self.domain.name}) ready...')
verify_domain_id_response = self.client.verify_domain_identity(
Domain=self.domain.name
)
print('verify_domain_id_response[\'VerificationToken\']', verify_domain_id_response['VerificationToken'])
print('')
domain_verified = False
while domain_verified == False:
get_identity_verification_attributes_response = self.client.get_identity_verification_attributes(
Identities=[
self.domain.name,
]
)
print('get_identity_verification_attributes_response', get_identity_verification_attributes_response)
print('')
for identity in get_identity_verification_attributes_response['VerificationAttributes']:
status = get_identity_verification_attributes_response['VerificationAttributes'][identity]['VerificationStatus']
if status == 'Success':
domain_verified = True
else:
print('Domain verification status:', status)
print('This could take up to 72 hours. Feel free to close this notebook and re-execute the code from this cell later. The process is happening on AWS\'s end and will not be interrupted. Once verified, re-executing the code won\'t reset the status, don\'t worry.')
time.sleep(100)
verify_domain_dkim_response = self.client.verify_domain_dkim(
Domain=self.domain.name
)
print('verify_domain_dkim_response[\'DkimTokens\']', verify_domain_dkim_response['DkimTokens'])
print('')
enable_id_dkim_response = self.client.set_identity_dkim_enabled(
Identity=self.domain.name,
DkimEnabled=True
)
print('enable_id_dkim_response', enable_id_dkim_response)
print('')
# ... snip ... code to create actual inboxes + send & receive emails
# from domain
print('Inbox verified...')
domain = Domain(static_domain='testing.com')
inbox = Inbox(domain=domain, username='admin')
Output: Output:
{'Domains': [{'DomainName': '... snip ...', 'AutoRenew': False, 'TransferLock': False, 'Expiry': datetime.datetime(2024, 1, 21, 16, 51, 56, tzinfo=tzlocal())}], 'ResponseMetadata': {'RequestId': '... snip ...', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '... snip ...', 'content-type': 'application/x-amz-json-1.1', 'content-length': '104', 'date': 'Mon, 23 Jan 2023 02:31:27 GMT'}, 'RetryAttempts': 0}}
Domain already owned...
Inbox (... snip ...) ready...
verify_domain_id_response['VerificationToken'] ... snip ...
get_identity_verification_attributes_response {'VerificationAttributes': {'... snip ...': {'VerificationStatus': 'Pending', 'VerificationToken': '... snip ...'}}, 'ResponseMetadata': {'RequestId': '... snip ...', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Mon, 23 Jan 2023 02:31:27 GMT', 'content-type': 'text/xml', 'content-length': '639', 'connection': 'keep-alive', 'x-amzn-requestid': '... snip ...'}, 'RetryAttempts': 0}}
Domain verification status: Pending
This could take up to 72 hours. Yes, really. Feel free to close this notebook and re-execute the code from this cell later. The process is happening on AWS's end and will not be interrupted. Once verified, re-executing the code won't reset the status, don't worry.
What am I missing here?我在这里错过了什么? Is what I'm trying to do a simple matter of something I missed in the documentation?我想做的是我在文档中遗漏的简单问题吗? Or is this not even viable purely via API in AWS?还是仅通过 AWS 中的 API 甚至不可行? I suspect the former.我怀疑是前者。
Maybe I need to handle the record assignment process manually with the Route53 API?也许我需要使用 Route53 API 手动处理记录分配过程? I'd really appreciate an example of what that would like if so.如果是这样的话,我真的很感激一个例子。 Otherwise just a hint that this is a requirement, and that SES will not do it automatically like with the GUI functionality, would be helpful to know.否则,只要提示这是一项要求,并且 SES 不会像使用 GUI 功能那样自动执行此操作,就会很有帮助。
You are already done with the configuration, but the same time you have to add the same key-value pair against the domain and add the key accordingly.您已经完成了配置,但同时您必须针对域添加相同的键值对并相应地添加键。
it depends if your NS is with Route53 and making that configuration with IDE than, your data with automatically pushed to that service, or if you using SDK or adding entries via API than parallel you have to add that key(DKIM entries to the given zone via Route53 APIs) against the given zone-id这取决于你的 NS 是否使用 Route53 并使用 IDE 进行配置,你的数据是否自动推送到该服务,或者如果你使用 SDK 或通过 API 添加条目比并行你必须添加该密钥(DKIM 条目到给定区域通过 Route53 API)针对给定的区域 ID
but if you're not working with Route53 than you must add the given key-value of DKIM entries with the NS Handler.但如果您不使用 Route53,则必须使用 NS 处理程序添加 DKIM 条目的给定键值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.