Browse Source

Make formatting consistent and improve record type support.

pull/165/head
Terrence Cole 9 years ago
parent
commit
01f8431d74
3 changed files with 281 additions and 176 deletions
  1. +172
    -127
      octodns/provider/rackspace.py
  2. +3
    -3
      tests/fixtures/rackspace-sample-recordset-existing-nameservers.json
  3. +106
    -46
      tests/test_octodns_provider_rackspace.py

+ 172
- 127
octodns/provider/rackspace.py View File

@ -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 = []
for record in rrset['records']:
order, preference, flags, service, regexp, replacement = \
record['content'].split(' ', 5)
values.append({
'order': order,
'preference': preference,
'flags': flags[1:-1],
'service': service[1:-1],
'regexp': regexp[1:-1],
'replacement': replacement,
})
return {
'type': rrset['type'],
'values': values,
'ttl': rrset['ttl']
}
raise NotImplementedError("Missing support for reading NAPTR records")
# values = []
# for record in rrset['records']:
# order, preference, flags, service, regexp, replacement = \
# record['content'].split(' ', 5)
# values.append({
# 'order': order,
# 'preference': preference,
# 'flags': flags[1:-1],
# 'service': service[1:-1],
# 'regexp': regexp[1:-1],
# 'replacement': replacement,
# })
# return {
# 'type': rrset['type'],
# 'values': values,
# 'ttl': rrset['ttl']
# }
def _data_for_SSHFP(self, rrset): def _data_for_SSHFP(self, rrset):
values = []
for record in rrset['records']:
algorithm, fingerprint_type, fingerprint = \
record['content'].split(' ', 2)
values.append({
'algorithm': algorithm,
'fingerprint_type': fingerprint_type,
'fingerprint': fingerprint,
})
return {
'type': rrset['type'],
'values': values,
'ttl': rrset['ttl']
}
raise NotImplementedError("Missing support for reading SSHFP records")
# values = []
# for record in rrset['records']:
# algorithm, fingerprint_type, fingerprint = \
# record['content'].split(' ', 2)
# values.append({
# 'algorithm': algorithm,
# 'fingerprint_type': fingerprint_type,
# 'fingerprint': fingerprint,
# })
# return {
# 'type': rrset['type'],
# 'values': values,
# 'ttl': rrset['ttl']
# }
def _data_for_SRV(self, rrset): def _data_for_SRV(self, rrset):
values = []
for record in rrset['records']:
priority, weight, port, target = \
record['content'].split(' ', 3)
values.append({
'priority': priority,
'weight': weight,
'port': port,
'target': target,
})
return {
'type': rrset['type'],
'values': values,
'ttl': rrset['ttl']
}
raise NotImplementedError("Missing support for reading SRV records")
# values = []
# for record in rrset['records']:
# priority, weight, port, target = \
# record['content'].split(' ', 3)
# values.append({
# 'priority': priority,
# 'weight': weight,
# 'port': port,
# 'target': target,
# })
# return {
# 'type': rrset['type'],
# '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,14 +251,10 @@ 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:
# 422 means powerdns doesn't know anything about the requsted
# domain. We'll just ignore it here and leave the zone
# untouched.
pass
else:
# just re-throw
raise
elif e.response.status_code == 404:
# Zone not found leaves the zone empty instead of failing.
return
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):
return [{'content': v, 'disabled': False}
for v in record.values]
_records_for_A = _records_for_multiple
_records_for_AAAA = _records_for_multiple
_records_for_NS = _records_for_multiple
def _records_for_single(self, record):
return [{'content': record.value, 'disabled': False}]
_records_for_ALIAS = _records_for_single
_records_for_CNAME = _records_for_single
_records_for_PTR = _records_for_single
def _records_for_quoted(self, record):
return [{'content': '"{}"'.format(v), 'disabled': False}
for v in record.values]
_records_for_SPF = _records_for_quoted
_records_for_TXT = _records_for_quoted
def _records_for_MX(self, record):
return [{
'content': '{} {}'.format(v.priority, v.value),
'disabled': False
} for v in record.values]
def _records_for_NAPTR(self, record):
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]
@staticmethod
def _record_for_ip(record, value):
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
@staticmethod
def _record_for_named(record, value):
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
@staticmethod
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
@staticmethod
def _record_for_MX(record, value):
return {
'name': record.fqdn,
'type': record._type,
'data': remove_trailing_dot(value),
'ttl': max(record.ttl, 300),
'priority': record.priority
}
@staticmethod
def _record_for_SRV(record, value):
raise NotImplementedError("Missing support for writing SRV records")
def _record_for_NAPTR(self, record):
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 _record_for_SSHFP(self, record):
raise NotImplementedError("Missing support for writing SSHFP records")
# return [{
# 'content': '{} {} {}'.format(v.algorithm, v.fingerprint_type,
# v.fingerprint),
# '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({
'name': change.new.fqdn,
'type': change.new._type,
'data': value,
'ttl': change.new.ttl,
})
transformer = getattr(self, "_record_for_{}".format(change.new._type))
out.append(transformer(change.new, value))
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)
rsid = self._id_map[key]
update_out.append({
'id': rsid,
'name': change.new.fqdn,
'data': value,
'ttl': change.new.ttl,
})
transformer = getattr(self, "_record_for_{}".format(change.new._type))
prior_rs_record = transformer(change.existing, value)
prior_key = self._key_for_record(prior_rs_record)
next_rs_record = transformer(change.new, value)
next_key = self._key_for_record(prior_rs_record)
next_rs_record["id"] = self._id_map[prior_key]
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)
rsid = self._id_map[key]
out.append('id=' + rsid)
transformer = getattr(self, "_record_for_{}".format(change.existing._type))
rs_record = transformer(change.existing, value)
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:


+ 3
- 3
tests/fixtures/rackspace-sample-recordset-existing-nameservers.json View File

@ -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"


+ 106
- 46
tests/test_octodns_provider_rackspace.py View File

@ -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')

Loading…
Cancel
Save