Skip to content

Commit

Permalink
Fix namecheap MX record support. (#514)
Browse files Browse the repository at this point in the history
namecheap MX records are handled a bit specially compared to
other records; it seems all records has the MXPref field, but only the
MX record uses it.
maybe a new feature or something.

It used to not be able to create MX records, but now it can.
  • Loading branch information
doddo committed Jun 1, 2020
1 parent 014bc62 commit 99d2388
Show file tree
Hide file tree
Showing 52 changed files with 17,188 additions and 14,287 deletions.
43 changes: 35 additions & 8 deletions lexicon/providers/namecheap.py
Expand Up @@ -190,8 +190,18 @@ def _create_record(self, rtype, name, content):
# required
'Type': rtype,
'Name': self._relative_name(name),
'Address': content,
}

# MX records needd special treatment
if rtype == 'MX':
mxpref, address = content.split()
record.update({
'MxPref': int(mxpref),
'Address': address
})
else:
record.update({'Address': content})

# inject the ttl if specified
option_ttl = self.option_ttl()
if option_ttl:
Expand Down Expand Up @@ -249,18 +259,31 @@ def _convert_to_namecheap(self, record):
""" converts from lexicon format record to namecheap format record,
suitable to sending through the api to namecheap"""

processed_record = {}

name = record['name']
if name.endswith('.'):
name = name[:-1]

short_name = name[:name.find(self.domain) - 1]
processed_record = {

if record['type'] == 'MX':
# MX records needs to have separate treatment.
mxpref, address = record['content'].split()
processed_record.update({
'MxPref': mxpref,
'Address': address
})
else:
processed_record.update({
'Address': record['content']})

processed_record.update({
'Type': record['type'],
'Name': short_name,
'TTL': record['ttl'],
'Address': record['content'],
'HostId': record['id']
}
})

return processed_record

Expand All @@ -269,14 +292,18 @@ def _convert_to_lexicon(self, record):
"""

name = record['Name']
if self.domain not in name:
name = "{}.{}".format(name, self.domain)

if not name.endswith(self.domain):
name += ".{}".format(self.domain)

content = '{} {}'.format(record['MXPref'], record['Address']) \
if record['Type'] == 'MX' else record['Address']

processed_record = {
'type': record['Type'],
'name': '{0}.{1}'.format(record['Name'], self.domain),
'name': name,
'ttl': record['TTL'],
'content': record['Address'],
'content': content,
'id': record['HostId']
}

Expand Down
4 changes: 2 additions & 2 deletions lexicon/tests/providers/test_namecheap.py
Expand Up @@ -62,7 +62,7 @@ def domain(self):
LEXICON_NAMECHEAP_DOMAIN
"""
env_domain = os.environ.get('LEXICON_NAMECHEAP_DOMAIN', None)
return env_domain or 'example-aptise.com'
return env_domain or 'unittest2.dev'

def _filter_query_parameters(self):
return ['ApiKey', 'UserName', 'ApiUser']
Expand Down Expand Up @@ -98,4 +98,4 @@ def domain(self):
LEXICON_NAMECHEAP_DOMAINMANAGED
"""
env_domain = os.environ.get('LEXICON_NAMECHEAP_DOMAINMANAGED', None)
return env_domain or 'example-aptise-2.com'
return env_domain or 'unittest-seconddomain.dev'
Expand Up @@ -2,41 +2,59 @@ interactions:
- request:
body: null
headers:
Accept: ['*/*']
Accept-Encoding: ['gzip, deflate']
Connection: [keep-alive]
Content-Length: ['0']
User-Agent: [python-requests/2.18.4]
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '0'
User-Agent:
- python-requests/2.23.0
method: POST
uri: https://api.sandbox.namecheap.com/xml.response?ClientIP=127.0.0.1&Command=namecheap.domains.getInfo&DomainName=example-aptise.com
uri: https://api.sandbox.namecheap.com/xml.response?ClientIP=127.0.0.1&Command=namecheap.domains.getInfo&DomainName=unittest2.dev
response:
body: {string: !!python/unicode "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n\
<ApiResponse Status=\"OK\" xmlns=\"http://api.namecheap.com/xml.response\"\
>\r\n <Errors />\r\n <Warnings />\r\n <RequestedCommand>namecheap.domains.getinfo</RequestedCommand>\r\
\n <CommandResponse Type=\"namecheap.domains.getInfo\">\r\n <DomainGetInfoResult\
\ Status=\"Ok\" ID=\"277432\" DomainName=\"example-aptise.com\" OwnerName=\"\
jvsandbox\" IsOwner=\"true\" IsPremium=\"false\">\r\n <DomainDetails>\r\
\n <CreatedDate>03/25/2018</CreatedDate>\r\n <ExpiredDate>03/25/2019</ExpiredDate>\r\
\n <NumYears>0</NumYears>\r\n </DomainDetails>\r\n <LockDetails\
\ />\r\n <Whoisguard Enabled=\"NotAlloted\">\r\n <ID>0</ID>\r\n\
\ </Whoisguard>\r\n <PremiumDnsSubscription>\r\n <UseAutoRenew>false</UseAutoRenew>\r\
\n <SubscriptionId>-1</SubscriptionId>\r\n <CreatedDate>0001-01-01T00:00:00</CreatedDate>\r\
\n <ExpirationDate>0001-01-01T00:00:00</ExpirationDate>\r\n \
\ <IsActive>false</IsActive>\r\n </PremiumDnsSubscription>\r\n <DnsDetails\
\ ProviderType=\"FREE\" IsUsingOurDNS=\"true\" HostCount=\"18\" EmailType=\"\
FWD\" DynamicDNSStatus=\"false\" IsFailover=\"false\">\r\n <Nameserver>dns1.registrar-servers.com</Nameserver>\r\
\n <Nameserver>dns2.registrar-servers.com</Nameserver>\r\n </DnsDetails>\r\
\n <Modificationrights All=\"true\" />\r\n </DomainGetInfoResult>\r\
\n </CommandResponse>\r\n <Server>PHX01SBAPI02</Server>\r\n <GMTTimeDifference>--7:00</GMTTimeDifference>\r\
\n <ExecutionTime>0.849</ExecutionTime>\r\n</ApiResponse>"}
body:
string: "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ApiResponse Status=\"OK\"
xmlns=\"http://api.namecheap.com/xml.response\">\r\n <Errors />\r\n <Warnings
/>\r\n <RequestedCommand>namecheap.domains.getinfo</RequestedCommand>\r\n
\ <CommandResponse Type=\"namecheap.domains.getInfo\">\r\n <DomainGetInfoResult
Status=\"Ok\" ID=\"589667\" DomainName=\"unittest2.dev\" OwnerName=\"phassberg\"
IsOwner=\"true\" IsPremium=\"false\">\r\n <DomainDetails>\r\n <CreatedDate>05/20/2020</CreatedDate>\r\n
\ <ExpiredDate>05/20/2021</ExpiredDate>\r\n <NumYears>0</NumYears>\r\n
\ </DomainDetails>\r\n <LockDetails />\r\n <Whoisguard Enabled=\"True\">\r\n
\ <ID>481121</ID>\r\n <ExpiredDate>05/20/2021</ExpiredDate>\r\n
\ <EmailDetails WhoisGuardEmail=\"824017ccbed343119b3459c7d3304ba5.protect@whoisguard.com\"
ForwardedTo=\"dr.doddo@gmail.com\" LastAutoEmailChangeDate=\"05/20/2020\"
AutoEmailChangeFrequencyDays=\"3\" />\r\n </Whoisguard>\r\n <PremiumDnsSubscription>\r\n
\ <UseAutoRenew>false</UseAutoRenew>\r\n <SubscriptionId>-1</SubscriptionId>\r\n
\ <CreatedDate>0001-01-01T00:00:00</CreatedDate>\r\n <ExpirationDate>0001-01-01T00:00:00</ExpirationDate>\r\n
\ <IsActive>false</IsActive>\r\n </PremiumDnsSubscription>\r\n
\ <DnsDetails ProviderType=\"FREE\" IsUsingOurDNS=\"true\" HostCount=\"31\"
EmailType=\"FWD\" DynamicDNSStatus=\"false\" IsFailover=\"false\">\r\n <Nameserver>dns1.registrar-servers.com</Nameserver>\r\n
\ <Nameserver>dns2.registrar-servers.com</Nameserver>\r\n </DnsDetails>\r\n
\ <Modificationrights All=\"true\" />\r\n </DomainGetInfoResult>\r\n
\ </CommandResponse>\r\n <Server>PHX01SBAPIEXT01</Server>\r\n <GMTTimeDifference>--4:00</GMTTimeDifference>\r\n
\ <ExecutionTime>0.241</ExecutionTime>\r\n</ApiResponse>"
headers:
cache-control: [private]
content-length: ['1493']
content-type: [text/xml; charset=utf-8]
date: ['Mon, 26 Mar 2018 17:40:58 GMT']
server: [Microsoft-IIS/8.5]
vary: [Accept-Encoding]
x-aspnet-version: [4.0.30319]
x-powered-by: [ASP.NET]
status: {code: 200, message: OK}
Cache-Control:
- private
Content-Type:
- text/xml; charset=utf-8
Date:
- Wed, 20 May 2020 18:59:13 GMT
Server:
- Microsoft-IIS/8.5
Vary:
- Accept-Encoding
X-AspNet-Version:
- 4.0.30319
X-Powered-By:
- ASP.NET
content-length:
- '1740'
status:
code: 200
message: OK
version: 1
Expand Up @@ -2,38 +2,53 @@ interactions:
- request:
body: null
headers:
Accept: ['*/*']
Accept-Encoding: ['gzip, deflate']
Connection: [keep-alive]
Content-Length: ['0']
User-Agent: [python-requests/2.18.4]
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '0'
User-Agent:
- python-requests/2.23.0
method: POST
uri: https://api.sandbox.namecheap.com/xml.response?ClientIP=127.0.0.1&Command=namecheap.domains.getInfo&DomainName=thisisadomainidonotown.com
response:
body: {string: !!python/unicode "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n\
<ApiResponse Status=\"ERROR\" xmlns=\"http://api.namecheap.com/xml.response\"\
>\r\n <Errors>\r\n <Error Number=\"2030166\">Domain is invalid</Error>\r\
\n </Errors>\r\n <Warnings />\r\n <RequestedCommand>namecheap.domains.getinfo</RequestedCommand>\r\
\n <CommandResponse Type=\"namecheap.domains.getInfo\">\r\n <DomainGetInfoResult\
\ ID=\"0\" IsOwner=\"false\" IsPremium=\"false\">\r\n <DomainDetails>\r\
\n <NumYears>0</NumYears>\r\n </DomainDetails>\r\n <LockDetails\
\ />\r\n <Whoisguard>\r\n <ID>0</ID>\r\n </Whoisguard>\r\n\
\ <PremiumDnsSubscription>\r\n <UseAutoRenew>false</UseAutoRenew>\r\
\n <SubscriptionId>-1</SubscriptionId>\r\n <CreatedDate>0001-01-01T00:00:00</CreatedDate>\r\
\n <ExpirationDate>0001-01-01T00:00:00</ExpirationDate>\r\n \
\ <IsActive>false</IsActive>\r\n </PremiumDnsSubscription>\r\n <DnsDetails\
\ IsUsingOurDNS=\"false\" HostCount=\"0\" DynamicDNSStatus=\"false\" IsFailover=\"\
false\" />\r\n <Modificationrights />\r\n </DomainGetInfoResult>\r\
\n </CommandResponse>\r\n <Server>PHX01SBAPI02</Server>\r\n <GMTTimeDifference>--7:00</GMTTimeDifference>\r\
\n <ExecutionTime>0.191</ExecutionTime>\r\n</ApiResponse>"}
body:
string: "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ApiResponse Status=\"ERROR\"
xmlns=\"http://api.namecheap.com/xml.response\">\r\n <Errors>\r\n <Error
Number=\"2030166\">Domain is invalid</Error>\r\n </Errors>\r\n <Warnings
/>\r\n <RequestedCommand>namecheap.domains.getinfo</RequestedCommand>\r\n
\ <CommandResponse Type=\"namecheap.domains.getInfo\">\r\n <DomainGetInfoResult
ID=\"0\" IsOwner=\"false\" IsPremium=\"false\">\r\n <DomainDetails>\r\n
\ <NumYears>0</NumYears>\r\n </DomainDetails>\r\n <LockDetails
/>\r\n <Whoisguard>\r\n <ID>0</ID>\r\n </Whoisguard>\r\n
\ <PremiumDnsSubscription>\r\n <UseAutoRenew>false</UseAutoRenew>\r\n
\ <SubscriptionId>-1</SubscriptionId>\r\n <CreatedDate>0001-01-01T00:00:00</CreatedDate>\r\n
\ <ExpirationDate>0001-01-01T00:00:00</ExpirationDate>\r\n <IsActive>false</IsActive>\r\n
\ </PremiumDnsSubscription>\r\n <DnsDetails IsUsingOurDNS=\"false\"
HostCount=\"0\" DynamicDNSStatus=\"false\" IsFailover=\"false\" />\r\n <Modificationrights
/>\r\n </DomainGetInfoResult>\r\n </CommandResponse>\r\n <Server>PHX01SBAPIEXT02</Server>\r\n
\ <GMTTimeDifference>--4:00</GMTTimeDifference>\r\n <ExecutionTime>0.246</ExecutionTime>\r\n</ApiResponse>"
headers:
cache-control: [private]
content-length: ['1189']
content-type: [text/xml; charset=utf-8]
date: ['Mon, 26 Mar 2018 17:40:58 GMT']
server: [Microsoft-IIS/8.5]
vary: [Accept-Encoding]
x-aspnet-version: [4.0.30319]
x-powered-by: [ASP.NET]
status: {code: 200, message: OK}
Cache-Control:
- private
Content-Type:
- text/xml; charset=utf-8
Date:
- Wed, 20 May 2020 18:59:13 GMT
Server:
- Microsoft-IIS/8.5
Vary:
- Accept-Encoding
X-AspNet-Version:
- 4.0.30319
X-Powered-By:
- ASP.NET
content-length:
- '1192'
status:
code: 200
message: OK
version: 1

0 comments on commit 99d2388

Please sign in to comment.