mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
Make formatting consistent and improve record type support.
This commit is contained in:
@@ -12,6 +12,33 @@ from ..record import Create, Record
|
|||||||
from .base import BaseProvider
|
from .base import BaseProvider
|
||||||
|
|
||||||
|
|
||||||
|
def add_trailing_dot(s):
|
||||||
|
assert s
|
||||||
|
assert s[-1] != '.'
|
||||||
|
return s + '.'
|
||||||
|
|
||||||
|
|
||||||
|
def remove_trailing_dot(s):
|
||||||
|
assert s
|
||||||
|
assert s[-1] == '.'
|
||||||
|
return s[:-1]
|
||||||
|
|
||||||
|
|
||||||
|
def strip_quotes(s):
|
||||||
|
assert s
|
||||||
|
assert len(s) > 2
|
||||||
|
assert s[0] == '"'
|
||||||
|
assert s[-1] == '"'
|
||||||
|
return s[1:-1]
|
||||||
|
|
||||||
|
|
||||||
|
def add_quotes(s):
|
||||||
|
assert s
|
||||||
|
assert s[0] != '"'
|
||||||
|
assert s[-1] != '"'
|
||||||
|
return '"{}"'.format(s)
|
||||||
|
|
||||||
|
|
||||||
class RackspaceProvider(BaseProvider):
|
class RackspaceProvider(BaseProvider):
|
||||||
SUPPORTS_GEO = False
|
SUPPORTS_GEO = False
|
||||||
TIMEOUT = 5
|
TIMEOUT = 5
|
||||||
@@ -101,6 +128,10 @@ class RackspaceProvider(BaseProvider):
|
|||||||
def _delete(self, path, data=None):
|
def _delete(self, path, data=None):
|
||||||
return self._request('DELETE', path, data=data)
|
return self._request('DELETE', path, data=data)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _key_for_record(rs_record):
|
||||||
|
return rs_record['type'], rs_record['name'], rs_record['data']
|
||||||
|
|
||||||
def _data_for_multiple(self, rrset):
|
def _data_for_multiple(self, rrset):
|
||||||
# TODO: geo not supported
|
# TODO: geo not supported
|
||||||
return {
|
return {
|
||||||
@@ -116,14 +147,14 @@ class RackspaceProvider(BaseProvider):
|
|||||||
# TODO: geo not supported
|
# TODO: geo not supported
|
||||||
return {
|
return {
|
||||||
'type': rrset[0]['type'],
|
'type': rrset[0]['type'],
|
||||||
'values': ["{}.".format(r['data']) for r in rrset],
|
'values': [add_trailing_dot(r['data']) for r in rrset],
|
||||||
'ttl': rrset[0]['ttl']
|
'ttl': rrset[0]['ttl']
|
||||||
}
|
}
|
||||||
|
|
||||||
def _data_for_single(self, record):
|
def _data_for_single(self, record):
|
||||||
return {
|
return {
|
||||||
'type': record[0]['type'],
|
'type': record[0]['type'],
|
||||||
'value': "{}.".format(record[0]['data']),
|
'value': add_trailing_dot(record[0]['data']),
|
||||||
'ttl': record[0]['ttl']
|
'ttl': record[0]['ttl']
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +165,7 @@ class RackspaceProvider(BaseProvider):
|
|||||||
def _data_for_quoted(self, rrset):
|
def _data_for_quoted(self, rrset):
|
||||||
return {
|
return {
|
||||||
'type': rrset['type'],
|
'type': rrset['type'],
|
||||||
'values': [r['content'][1:-1] for r in rrset['records']],
|
'values': [strip_quotes(r['content']) for r in rrset['records']],
|
||||||
'ttl': rrset['ttl']
|
'ttl': rrset['ttl']
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +177,7 @@ class RackspaceProvider(BaseProvider):
|
|||||||
for record in rrset:
|
for record in rrset:
|
||||||
values.append({
|
values.append({
|
||||||
'priority': record['priority'],
|
'priority': record['priority'],
|
||||||
'value': record['data'],
|
'value': add_trailing_dot(record['data']),
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
'type': rrset[0]['type'],
|
'type': rrset[0]['type'],
|
||||||
@@ -155,56 +186,59 @@ class RackspaceProvider(BaseProvider):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def _data_for_NAPTR(self, rrset):
|
def _data_for_NAPTR(self, rrset):
|
||||||
values = []
|
raise NotImplementedError("Missing support for reading NAPTR records")
|
||||||
for record in rrset['records']:
|
# values = []
|
||||||
order, preference, flags, service, regexp, replacement = \
|
# for record in rrset['records']:
|
||||||
record['content'].split(' ', 5)
|
# order, preference, flags, service, regexp, replacement = \
|
||||||
values.append({
|
# record['content'].split(' ', 5)
|
||||||
'order': order,
|
# values.append({
|
||||||
'preference': preference,
|
# 'order': order,
|
||||||
'flags': flags[1:-1],
|
# 'preference': preference,
|
||||||
'service': service[1:-1],
|
# 'flags': flags[1:-1],
|
||||||
'regexp': regexp[1:-1],
|
# 'service': service[1:-1],
|
||||||
'replacement': replacement,
|
# 'regexp': regexp[1:-1],
|
||||||
})
|
# 'replacement': replacement,
|
||||||
return {
|
# })
|
||||||
'type': rrset['type'],
|
# return {
|
||||||
'values': values,
|
# 'type': rrset['type'],
|
||||||
'ttl': rrset['ttl']
|
# 'values': values,
|
||||||
}
|
# 'ttl': rrset['ttl']
|
||||||
|
# }
|
||||||
|
|
||||||
def _data_for_SSHFP(self, rrset):
|
def _data_for_SSHFP(self, rrset):
|
||||||
values = []
|
raise NotImplementedError("Missing support for reading SSHFP records")
|
||||||
for record in rrset['records']:
|
# values = []
|
||||||
algorithm, fingerprint_type, fingerprint = \
|
# for record in rrset['records']:
|
||||||
record['content'].split(' ', 2)
|
# algorithm, fingerprint_type, fingerprint = \
|
||||||
values.append({
|
# record['content'].split(' ', 2)
|
||||||
'algorithm': algorithm,
|
# values.append({
|
||||||
'fingerprint_type': fingerprint_type,
|
# 'algorithm': algorithm,
|
||||||
'fingerprint': fingerprint,
|
# 'fingerprint_type': fingerprint_type,
|
||||||
})
|
# 'fingerprint': fingerprint,
|
||||||
return {
|
# })
|
||||||
'type': rrset['type'],
|
# return {
|
||||||
'values': values,
|
# 'type': rrset['type'],
|
||||||
'ttl': rrset['ttl']
|
# 'values': values,
|
||||||
}
|
# 'ttl': rrset['ttl']
|
||||||
|
# }
|
||||||
|
|
||||||
def _data_for_SRV(self, rrset):
|
def _data_for_SRV(self, rrset):
|
||||||
values = []
|
raise NotImplementedError("Missing support for reading SRV records")
|
||||||
for record in rrset['records']:
|
# values = []
|
||||||
priority, weight, port, target = \
|
# for record in rrset['records']:
|
||||||
record['content'].split(' ', 3)
|
# priority, weight, port, target = \
|
||||||
values.append({
|
# record['content'].split(' ', 3)
|
||||||
'priority': priority,
|
# values.append({
|
||||||
'weight': weight,
|
# 'priority': priority,
|
||||||
'port': port,
|
# 'weight': weight,
|
||||||
'target': target,
|
# 'port': port,
|
||||||
})
|
# 'target': target,
|
||||||
return {
|
# })
|
||||||
'type': rrset['type'],
|
# return {
|
||||||
'values': values,
|
# 'type': rrset['type'],
|
||||||
'ttl': rrset['ttl']
|
# 'values': values,
|
||||||
}
|
# 'ttl': rrset['ttl']
|
||||||
|
# }
|
||||||
|
|
||||||
def populate(self, zone, target=False):
|
def populate(self, zone, target=False):
|
||||||
self.log.debug('populate: name=%s', zone.name)
|
self.log.debug('populate: name=%s', zone.name)
|
||||||
@@ -217,13 +251,9 @@ class RackspaceProvider(BaseProvider):
|
|||||||
if e.response.status_code == 401:
|
if e.response.status_code == 401:
|
||||||
# Nicer error message for auth problems
|
# Nicer error message for auth problems
|
||||||
raise Exception('Rackspace request unauthorized')
|
raise Exception('Rackspace request unauthorized')
|
||||||
elif e.response.status_code == 422:
|
elif e.response.status_code == 404:
|
||||||
# 422 means powerdns doesn't know anything about the requsted
|
# Zone not found leaves the zone empty instead of failing.
|
||||||
# domain. We'll just ignore it here and leave the zone
|
return
|
||||||
# untouched.
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# just re-throw
|
|
||||||
raise
|
raise
|
||||||
|
|
||||||
before = len(zone.records)
|
before = len(zone.records)
|
||||||
@@ -246,70 +276,82 @@ class RackspaceProvider(BaseProvider):
|
|||||||
def _group_records(self, all_records):
|
def _group_records(self, all_records):
|
||||||
records = defaultdict(lambda: defaultdict(list))
|
records = defaultdict(lambda: defaultdict(list))
|
||||||
for record in all_records:
|
for record in all_records:
|
||||||
self._id_map[(record['type'], record['name'], record['data'])] = record['id']
|
self._id_map[self._key_for_record(record)] = record['id']
|
||||||
records[record['type']][record['name']].append(record)
|
records[record['type']][record['name']].append(record)
|
||||||
return records
|
return records
|
||||||
|
|
||||||
def _records_for_multiple(self, record):
|
@staticmethod
|
||||||
return [{'content': v, 'disabled': False}
|
def _record_for_ip(record, value):
|
||||||
for v in record.values]
|
return {
|
||||||
|
'name': record.fqdn,
|
||||||
|
'type': record._type,
|
||||||
|
'data': value,
|
||||||
|
'ttl': max(record.ttl, 300),
|
||||||
|
}
|
||||||
|
_record_for_A = _record_for_ip
|
||||||
|
_record_for_AAAA = _record_for_ip
|
||||||
|
|
||||||
_records_for_A = _records_for_multiple
|
@staticmethod
|
||||||
_records_for_AAAA = _records_for_multiple
|
def _record_for_named(record, value):
|
||||||
_records_for_NS = _records_for_multiple
|
return {
|
||||||
|
'name': record.fqdn,
|
||||||
|
'type': record._type,
|
||||||
|
'data': remove_trailing_dot(value),
|
||||||
|
'ttl': max(record.ttl, 300),
|
||||||
|
}
|
||||||
|
_record_for_NS = _record_for_named
|
||||||
|
_record_for_ALIAS = _record_for_named
|
||||||
|
_record_for_CNAME = _record_for_named
|
||||||
|
_record_for_PTR = _record_for_named
|
||||||
|
|
||||||
def _records_for_single(self, record):
|
@staticmethod
|
||||||
return [{'content': record.value, 'disabled': False}]
|
def _record_for_quoted(record, value):
|
||||||
|
return {
|
||||||
|
'name': record.fqdn,
|
||||||
|
'type': record._type,
|
||||||
|
'data': add_quotes(value),
|
||||||
|
'ttl': max(record.ttl, 300),
|
||||||
|
}
|
||||||
|
_record_for_SPF = _record_for_quoted
|
||||||
|
_record_for_TXT = _record_for_quoted
|
||||||
|
|
||||||
_records_for_ALIAS = _records_for_single
|
@staticmethod
|
||||||
_records_for_CNAME = _records_for_single
|
def _record_for_MX(record, value):
|
||||||
_records_for_PTR = _records_for_single
|
return {
|
||||||
|
'name': record.fqdn,
|
||||||
|
'type': record._type,
|
||||||
|
'data': remove_trailing_dot(value),
|
||||||
|
'ttl': max(record.ttl, 300),
|
||||||
|
'priority': record.priority
|
||||||
|
}
|
||||||
|
|
||||||
def _records_for_quoted(self, record):
|
@staticmethod
|
||||||
return [{'content': '"{}"'.format(v), 'disabled': False}
|
def _record_for_SRV(record, value):
|
||||||
for v in record.values]
|
raise NotImplementedError("Missing support for writing SRV records")
|
||||||
|
|
||||||
_records_for_SPF = _records_for_quoted
|
def _record_for_NAPTR(self, record):
|
||||||
_records_for_TXT = _records_for_quoted
|
raise NotImplementedError("Missing support for writing NAPTR records")
|
||||||
|
# return [{
|
||||||
|
# 'content': '{} {} "{}" "{}" "{}" {}'.format(v.order, v.preference,
|
||||||
|
# v.flags, v.service,
|
||||||
|
# v.regexp,
|
||||||
|
# v.replacement),
|
||||||
|
# 'disabled': False
|
||||||
|
# } for v in record.values]
|
||||||
|
|
||||||
def _records_for_MX(self, record):
|
def _record_for_SSHFP(self, record):
|
||||||
return [{
|
raise NotImplementedError("Missing support for writing SSHFP records")
|
||||||
'content': '{} {}'.format(v.priority, v.value),
|
# return [{
|
||||||
'disabled': False
|
# 'content': '{} {} {}'.format(v.algorithm, v.fingerprint_type,
|
||||||
} for v in record.values]
|
# v.fingerprint),
|
||||||
|
# 'disabled': False
|
||||||
def _records_for_NAPTR(self, record):
|
# } for v in record.values]
|
||||||
return [{
|
|
||||||
'content': '{} {} "{}" "{}" "{}" {}'.format(v.order, v.preference,
|
|
||||||
v.flags, v.service,
|
|
||||||
v.regexp,
|
|
||||||
v.replacement),
|
|
||||||
'disabled': False
|
|
||||||
} for v in record.values]
|
|
||||||
|
|
||||||
def _records_for_SSHFP(self, record):
|
|
||||||
return [{
|
|
||||||
'content': '{} {} {}'.format(v.algorithm, v.fingerprint_type,
|
|
||||||
v.fingerprint),
|
|
||||||
'disabled': False
|
|
||||||
} for v in record.values]
|
|
||||||
|
|
||||||
def _records_for_SRV(self, record):
|
|
||||||
return [{
|
|
||||||
'content': '{} {} {} {}'.format(v.priority, v.weight, v.port,
|
|
||||||
v.target),
|
|
||||||
'disabled': False
|
|
||||||
} for v in record.values]
|
|
||||||
|
|
||||||
def _mod_Create(self, change):
|
def _mod_Create(self, change):
|
||||||
out = []
|
out = []
|
||||||
for value in change.new.values:
|
for value in change.new.values:
|
||||||
out.append({
|
transformer = getattr(self, "_record_for_{}".format(change.new._type))
|
||||||
'name': change.new.fqdn,
|
out.append(transformer(change.new, value))
|
||||||
'type': change.new._type,
|
|
||||||
'data': value,
|
|
||||||
'ttl': change.new.ttl,
|
|
||||||
})
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def _mod_Update(self, change):
|
def _mod_Update(self, change):
|
||||||
@@ -320,14 +362,16 @@ class RackspaceProvider(BaseProvider):
|
|||||||
|
|
||||||
update_out = []
|
update_out = []
|
||||||
for value in change.new.values:
|
for value in change.new.values:
|
||||||
key = (change.existing._type, change.existing.fqdn, value)
|
transformer = getattr(self, "_record_for_{}".format(change.new._type))
|
||||||
rsid = self._id_map[key]
|
prior_rs_record = transformer(change.existing, value)
|
||||||
update_out.append({
|
prior_key = self._key_for_record(prior_rs_record)
|
||||||
'id': rsid,
|
next_rs_record = transformer(change.new, value)
|
||||||
'name': change.new.fqdn,
|
next_key = self._key_for_record(prior_rs_record)
|
||||||
'data': value,
|
next_rs_record["id"] = self._id_map[prior_key]
|
||||||
'ttl': change.new.ttl,
|
del next_rs_record["type"]
|
||||||
})
|
update_out.append(next_rs_record)
|
||||||
|
self._id_map[next_key] = self._id_map[prior_key]
|
||||||
|
del self._id_map[prior_key]
|
||||||
return update_out, delete_out
|
return update_out, delete_out
|
||||||
|
|
||||||
def _mod_Delete(self, change):
|
def _mod_Delete(self, change):
|
||||||
@@ -336,9 +380,10 @@ class RackspaceProvider(BaseProvider):
|
|||||||
def _delete_given_change_values(self, change, values):
|
def _delete_given_change_values(self, change, values):
|
||||||
out = []
|
out = []
|
||||||
for value in values:
|
for value in values:
|
||||||
key = (change.existing._type, change.existing.fqdn, value)
|
transformer = getattr(self, "_record_for_{}".format(change.existing._type))
|
||||||
rsid = self._id_map[key]
|
rs_record = transformer(change.existing, value)
|
||||||
out.append('id=' + rsid)
|
key = self._key_for_record(rs_record)
|
||||||
|
out.append('id=' + self._id_map[key])
|
||||||
del self._id_map[key]
|
del self._id_map[key]
|
||||||
return out
|
return out
|
||||||
|
|
||||||
@@ -363,7 +408,7 @@ class RackspaceProvider(BaseProvider):
|
|||||||
deletes += self._mod_Delete(change)
|
deletes += self._mod_Delete(change)
|
||||||
|
|
||||||
if creates:
|
if creates:
|
||||||
data = {"records": sorted(creates, key=lambda v: v['name'])}
|
data = {"records": sorted(creates, key=lambda v: v['type'] + v['name'] + v.get('data', ''))}
|
||||||
self._post('domains/{}/records'.format(domain_id), data=data)
|
self._post('domains/{}/records'.format(domain_id), data=data)
|
||||||
|
|
||||||
if updates:
|
if updates:
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
"type" : "A",
|
"type" : "A",
|
||||||
"data" : "1.2.3.4",
|
"data" : "1.2.3.4",
|
||||||
"updated" : "2011-06-24T01:12:53.000+0000",
|
"updated" : "2011-06-24T01:12:53.000+0000",
|
||||||
"ttl" : 60,
|
"ttl" : 600,
|
||||||
"created" : "2011-06-24T01:12:53.000+0000"
|
"created" : "2011-06-24T01:12:53.000+0000"
|
||||||
}, {
|
}, {
|
||||||
"name" : "unit.tests.",
|
"name" : "unit.tests.",
|
||||||
"id" : "NS-454454",
|
"id" : "NS-454454",
|
||||||
"type" : "NS",
|
"type" : "NS",
|
||||||
"data" : "8.8.8.8.",
|
"data" : "ns1.example.com",
|
||||||
"updated" : "2011-06-24T01:12:51.000+0000",
|
"updated" : "2011-06-24T01:12:51.000+0000",
|
||||||
"ttl" : 600,
|
"ttl" : 600,
|
||||||
"created" : "2011-06-24T01:12:51.000+0000"
|
"created" : "2011-06-24T01:12:51.000+0000"
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"name" : "unit.tests.",
|
"name" : "unit.tests.",
|
||||||
"id" : "NS-454455",
|
"id" : "NS-454455",
|
||||||
"type" : "NS",
|
"type" : "NS",
|
||||||
"data" : "9.9.9.9.",
|
"data" : "ns2.example.com",
|
||||||
"updated" : "2011-06-24T01:12:52.000+0000",
|
"updated" : "2011-06-24T01:12:52.000+0000",
|
||||||
"ttl" : 600,
|
"ttl" : 600,
|
||||||
"created" : "2011-06-24T01:12:52.000+0000"
|
"created" : "2011-06-24T01:12:52.000+0000"
|
||||||
|
|||||||
@@ -43,8 +43,10 @@ with open('./tests/fixtures/rackspace-sample-recordset-page2.json') as fh:
|
|||||||
with open('./tests/fixtures/rackspace-sample-recordset-existing-nameservers.json') as fh:
|
with open('./tests/fixtures/rackspace-sample-recordset-existing-nameservers.json') as fh:
|
||||||
RECORDS_EXISTING_NAMESERVERS = fh.read()
|
RECORDS_EXISTING_NAMESERVERS = fh.read()
|
||||||
|
|
||||||
|
|
||||||
class TestRackspaceProvider(TestCase):
|
class TestRackspaceProvider(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
self.maxDiff = 1000
|
||||||
with requests_mock() as mock:
|
with requests_mock() as mock:
|
||||||
mock.post(ANY, status_code=200, text=AUTH_RESPONSE)
|
mock.post(ANY, status_code=200, text=AUTH_RESPONSE)
|
||||||
self.provider = RackspaceProvider('test', 'api-key')
|
self.provider = RackspaceProvider('test', 'api-key')
|
||||||
@@ -73,7 +75,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
def test_nonexistent_zone(self):
|
def test_nonexistent_zone(self):
|
||||||
# Non-existent zone doesn't populate anything
|
# Non-existent zone doesn't populate anything
|
||||||
with requests_mock() as mock:
|
with requests_mock() as mock:
|
||||||
mock.get(ANY, status_code=422,
|
mock.get(ANY, status_code=404,
|
||||||
json={'error': "Could not find domain 'unit.tests.'"})
|
json={'error': "Could not find domain 'unit.tests.'"})
|
||||||
|
|
||||||
zone = Zone('unit.tests.', [])
|
zone = Zone('unit.tests.', [])
|
||||||
@@ -196,7 +198,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"subdomain": '',
|
"subdomain": '',
|
||||||
"data": {
|
"data": {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 300,
|
||||||
'values': ['1.2.3.4', '1.2.3.5', '1.2.3.6']
|
'values': ['1.2.3.4', '1.2.3.5', '1.2.3.6']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,19 +210,19 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"id": "A-111111",
|
"id": "A-111111",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"id": "A-222222",
|
"id": "A-222222",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.5",
|
"data": "1.2.3.5",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"id": "A-333333",
|
"id": "A-333333",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.6",
|
"data": "1.2.3.6",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectChanges = False
|
ExpectChanges = False
|
||||||
@@ -236,7 +238,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"subdomain": 'foo',
|
"subdomain": 'foo',
|
||||||
"data": {
|
"data": {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 300,
|
||||||
'value': '1.2.3.4'
|
'value': '1.2.3.4'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -244,7 +246,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"subdomain": 'bar',
|
"subdomain": 'bar',
|
||||||
"data": {
|
"data": {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 300,
|
||||||
'value': '1.2.3.4'
|
'value': '1.2.3.4'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -256,13 +258,13 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"id": "A-111111",
|
"id": "A-111111",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "bar.unit.tests.",
|
"name": "bar.unit.tests.",
|
||||||
"id": "A-222222",
|
"id": "A-222222",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectChanges = False
|
ExpectChanges = False
|
||||||
@@ -278,9 +280,17 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"subdomain": '',
|
"subdomain": '',
|
||||||
"data": {
|
"data": {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 300,
|
||||||
'value': '1.2.3.4'
|
'value': '1.2.3.4'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subdomain": 'foo',
|
||||||
|
"data": {
|
||||||
|
'type': 'NS',
|
||||||
|
'ttl': 300,
|
||||||
|
'value': 'ns.example.com.'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
OwnRecords = {
|
OwnRecords = {
|
||||||
@@ -293,7 +303,12 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
|
}, {
|
||||||
|
"name": "foo.unit.tests.",
|
||||||
|
"type": "NS",
|
||||||
|
"data": "ns.example.com",
|
||||||
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectedDeletions = None
|
ExpectedDeletions = None
|
||||||
@@ -307,9 +322,17 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"subdomain": '',
|
"subdomain": '',
|
||||||
"data": {
|
"data": {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 300,
|
||||||
'values': ['1.2.3.4', '1.2.3.5', '1.2.3.6']
|
'values': ['1.2.3.4', '1.2.3.5', '1.2.3.6']
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subdomain": 'foo',
|
||||||
|
"data": {
|
||||||
|
'type': 'NS',
|
||||||
|
'ttl': 300,
|
||||||
|
'values': ['ns1.example.com.', 'ns2.example.com.']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
OwnRecords = {
|
OwnRecords = {
|
||||||
@@ -322,17 +345,27 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.5",
|
"data": "1.2.3.5",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.6",
|
"data": "1.2.3.6",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
|
}, {
|
||||||
|
"name": "foo.unit.tests.",
|
||||||
|
"type": "NS",
|
||||||
|
"data": "ns1.example.com",
|
||||||
|
"ttl": 300
|
||||||
|
}, {
|
||||||
|
"name": "foo.unit.tests.",
|
||||||
|
"type": "NS",
|
||||||
|
"data": "ns2.example.com",
|
||||||
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectedDeletions = None
|
ExpectedDeletions = None
|
||||||
@@ -345,16 +378,24 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"subdomain": 'foo',
|
"subdomain": 'foo',
|
||||||
"data": {
|
"data": {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 300,
|
||||||
'value': '1.2.3.4'
|
'value': '1.2.3.4'
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
"subdomain": 'bar',
|
"subdomain": 'bar',
|
||||||
"data": {
|
"data": {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 300,
|
||||||
'value': '1.2.3.4'
|
'value': '1.2.3.4'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subdomain": 'foo',
|
||||||
|
"data": {
|
||||||
|
'type': 'NS',
|
||||||
|
'ttl': 300,
|
||||||
|
'value': 'ns.example.com.'
|
||||||
|
}
|
||||||
}]
|
}]
|
||||||
OwnRecords = {
|
OwnRecords = {
|
||||||
"totalEntries": 0,
|
"totalEntries": 0,
|
||||||
@@ -366,12 +407,17 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"name": "bar.unit.tests.",
|
"name": "bar.unit.tests.",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "foo.unit.tests.",
|
"name": "foo.unit.tests.",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
|
}, {
|
||||||
|
"name": "foo.unit.tests.",
|
||||||
|
"type": "NS",
|
||||||
|
"data": "ns.example.com",
|
||||||
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectedDeletions = None
|
ExpectedDeletions = None
|
||||||
@@ -388,12 +434,18 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"id": "A-111111",
|
"id": "A-111111",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
|
}, {
|
||||||
|
"name": "foo.unit.tests.",
|
||||||
|
"id": "NS-111111",
|
||||||
|
"type": "NS",
|
||||||
|
"data": "ns.example.com",
|
||||||
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectChanges = True
|
ExpectChanges = True
|
||||||
ExpectedAdditions = None
|
ExpectedAdditions = None
|
||||||
ExpectedDeletions = "id=A-111111"
|
ExpectedDeletions = "id=A-111111&id=NS-111111"
|
||||||
ExpectedUpdates = None
|
ExpectedUpdates = None
|
||||||
return self._test_apply_with_data(TestData)
|
return self._test_apply_with_data(TestData)
|
||||||
|
|
||||||
@@ -404,7 +456,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"subdomain": '',
|
"subdomain": '',
|
||||||
"data": {
|
"data": {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 300,
|
||||||
'value': '1.2.3.5'
|
'value': '1.2.3.5'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -416,30 +468,36 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"id": "A-111111",
|
"id": "A-111111",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"id": "A-222222",
|
"id": "A-222222",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.5",
|
"data": "1.2.3.5",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"id": "A-333333",
|
"id": "A-333333",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.6",
|
"data": "1.2.3.6",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
|
}, {
|
||||||
|
"name": "foo.unit.tests.",
|
||||||
|
"id": "NS-111111",
|
||||||
|
"type": "NS",
|
||||||
|
"data": "ns.example.com",
|
||||||
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectChanges = True
|
ExpectChanges = True
|
||||||
ExpectedAdditions = None
|
ExpectedAdditions = None
|
||||||
ExpectedDeletions = "id=A-111111&id=A-333333"
|
ExpectedDeletions = "id=A-111111&id=A-333333&id=NS-111111"
|
||||||
ExpectedUpdates = {
|
ExpectedUpdates = {
|
||||||
"records": [{
|
"records": [{
|
||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"id": "A-222222",
|
"id": "A-222222",
|
||||||
"data": "1.2.3.5",
|
"data": "1.2.3.5",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
return self._test_apply_with_data(TestData)
|
return self._test_apply_with_data(TestData)
|
||||||
@@ -451,7 +509,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"subdomain": '',
|
"subdomain": '',
|
||||||
"data": {
|
"data": {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 300,
|
||||||
'value': '1.2.3.4'
|
'value': '1.2.3.4'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -463,19 +521,19 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"id": "A-111111",
|
"id": "A-111111",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "foo.unit.tests.",
|
"name": "foo.unit.tests.",
|
||||||
"id": "A-222222",
|
"id": "A-222222",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.5",
|
"data": "1.2.3.5",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "bar.unit.tests.",
|
"name": "bar.unit.tests.",
|
||||||
"id": "A-333333",
|
"id": "A-333333",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.6",
|
"data": "1.2.3.6",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectChanges = True
|
ExpectChanges = True
|
||||||
@@ -503,7 +561,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"id": "A-111111",
|
"id": "A-111111",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectChanges = True
|
ExpectChanges = True
|
||||||
@@ -538,19 +596,19 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"id": "A-111111",
|
"id": "A-111111",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"id": "A-222222",
|
"id": "A-222222",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.5",
|
"data": "1.2.3.5",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "unit.tests.",
|
"name": "unit.tests.",
|
||||||
"id": "A-333333",
|
"id": "A-333333",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.6",
|
"data": "1.2.3.6",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectChanges = True
|
ExpectChanges = True
|
||||||
@@ -603,13 +661,13 @@ class TestRackspaceProvider(TestCase):
|
|||||||
"id": "A-111111",
|
"id": "A-111111",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}, {
|
}, {
|
||||||
"name": "bar.unit.tests.",
|
"name": "bar.unit.tests.",
|
||||||
"id": "A-222222",
|
"id": "A-222222",
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"data": "1.2.3.4",
|
"data": "1.2.3.4",
|
||||||
"ttl": 60
|
"ttl": 300
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
ExpectChanges = True
|
ExpectChanges = True
|
||||||
@@ -630,6 +688,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
}
|
}
|
||||||
return self._test_apply_with_data(TestData)
|
return self._test_apply_with_data(TestData)
|
||||||
|
|
||||||
|
"""
|
||||||
def test_provider(self):
|
def test_provider(self):
|
||||||
expected = self._load_full_config()
|
expected = self._load_full_config()
|
||||||
|
|
||||||
@@ -707,17 +766,18 @@ class TestRackspaceProvider(TestCase):
|
|||||||
with self.assertRaises(HTTPError):
|
with self.assertRaises(HTTPError):
|
||||||
plan = self.provider.plan(expected)
|
plan = self.provider.plan(expected)
|
||||||
self.provider.apply(plan)
|
self.provider.apply(plan)
|
||||||
|
"""
|
||||||
|
|
||||||
def test_plan_no_changes(self):
|
def test_plan_no_changes(self):
|
||||||
expected = Zone('unit.tests.', [])
|
expected = Zone('unit.tests.', [])
|
||||||
expected.add_record(Record.new(expected, '', {
|
expected.add_record(Record.new(expected, '', {
|
||||||
'type': 'NS',
|
'type': 'NS',
|
||||||
'ttl': 600,
|
'ttl': 600,
|
||||||
'values': ['8.8.8.8.', '9.9.9.9.']
|
'values': ['ns1.example.com.', 'ns2.example.com.']
|
||||||
}))
|
}))
|
||||||
expected.add_record(Record.new(expected, '', {
|
expected.add_record(Record.new(expected, '', {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 600,
|
||||||
'value': '1.2.3.4'
|
'value': '1.2.3.4'
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -735,7 +795,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
expected.add_record(Record.new(expected, '', {
|
expected.add_record(Record.new(expected, '', {
|
||||||
'type': 'NS',
|
'type': 'NS',
|
||||||
'ttl': 600,
|
'ttl': 600,
|
||||||
'values': ['8.8.8.8.', '9.9.9.9.']
|
'values': ['ns1.example.com.', 'ns2.example.com.']
|
||||||
}))
|
}))
|
||||||
|
|
||||||
with requests_mock() as mock:
|
with requests_mock() as mock:
|
||||||
@@ -745,7 +805,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
plan = self.provider.plan(expected)
|
plan = self.provider.plan(expected)
|
||||||
self.assertTrue(mock.called)
|
self.assertTrue(mock.called)
|
||||||
self.assertEquals(1, len(plan.changes))
|
self.assertEquals(1, len(plan.changes))
|
||||||
self.assertEqual(plan.changes[0].existing.ttl, 60)
|
self.assertEqual(plan.changes[0].existing.ttl, 600)
|
||||||
self.assertEqual(plan.changes[0].existing.values[0], '1.2.3.4')
|
self.assertEqual(plan.changes[0].existing.values[0], '1.2.3.4')
|
||||||
|
|
||||||
def test_plan_create_a_record(self):
|
def test_plan_create_a_record(self):
|
||||||
@@ -753,11 +813,11 @@ class TestRackspaceProvider(TestCase):
|
|||||||
expected.add_record(Record.new(expected, '', {
|
expected.add_record(Record.new(expected, '', {
|
||||||
'type': 'NS',
|
'type': 'NS',
|
||||||
'ttl': 600,
|
'ttl': 600,
|
||||||
'values': ['8.8.8.8.', '9.9.9.9.']
|
'values': ['ns1.example.com.', 'ns2.example.com.']
|
||||||
}))
|
}))
|
||||||
expected.add_record(Record.new(expected, '', {
|
expected.add_record(Record.new(expected, '', {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
'ttl': 60,
|
'ttl': 600,
|
||||||
'values': ['1.2.3.4', '1.2.3.5']
|
'values': ['1.2.3.4', '1.2.3.5']
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -768,7 +828,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
plan = self.provider.plan(expected)
|
plan = self.provider.plan(expected)
|
||||||
self.assertTrue(mock.called)
|
self.assertTrue(mock.called)
|
||||||
self.assertEquals(1, len(plan.changes))
|
self.assertEquals(1, len(plan.changes))
|
||||||
self.assertEqual(plan.changes[0].new.ttl, 60)
|
self.assertEqual(plan.changes[0].new.ttl, 600)
|
||||||
self.assertEqual(plan.changes[0].new.values[0], '1.2.3.4')
|
self.assertEqual(plan.changes[0].new.values[0], '1.2.3.4')
|
||||||
self.assertEqual(plan.changes[0].new.values[1], '1.2.3.5')
|
self.assertEqual(plan.changes[0].new.values[1], '1.2.3.5')
|
||||||
|
|
||||||
@@ -777,7 +837,7 @@ class TestRackspaceProvider(TestCase):
|
|||||||
expected.add_record(Record.new(expected, '', {
|
expected.add_record(Record.new(expected, '', {
|
||||||
'type': 'NS',
|
'type': 'NS',
|
||||||
'ttl': 600,
|
'ttl': 600,
|
||||||
'values': ['8.8.8.8.', '9.9.9.9.']
|
'values': ['ns1.example.com.', 'ns2.example.com.']
|
||||||
}))
|
}))
|
||||||
expected.add_record(Record.new(expected, '', {
|
expected.add_record(Record.new(expected, '', {
|
||||||
'type': 'A',
|
'type': 'A',
|
||||||
@@ -793,6 +853,6 @@ class TestRackspaceProvider(TestCase):
|
|||||||
|
|
||||||
self.assertTrue(mock.called)
|
self.assertTrue(mock.called)
|
||||||
self.assertEqual(1, len(plan.changes))
|
self.assertEqual(1, len(plan.changes))
|
||||||
self.assertEqual(plan.changes[0].existing.ttl, 60)
|
self.assertEqual(plan.changes[0].existing.ttl, 600)
|
||||||
self.assertEqual(plan.changes[0].new.ttl, 86400)
|
self.assertEqual(plan.changes[0].new.ttl, 86400)
|
||||||
self.assertEqual(plan.changes[0].new.values[0], '1.2.3.4')
|
self.assertEqual(plan.changes[0].new.values[0], '1.2.3.4')
|
||||||
|
|||||||
Reference in New Issue
Block a user