Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions libcloud/dns/drivers/rcodezero.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def __init__(
secure=True,
host=None,
port=None,
api_version="v1",
api_version="v2",
**kwargs,
):
"""
Expand Down Expand Up @@ -141,6 +141,8 @@ def __init__(

if api_version == "v1":
self.api_root = "/api/v1"
elif api_version == "v2":
self.api_root = "/api/v2"
else:
raise NotImplementedError("Unsupported API version: %s" % api_version)

Expand Down Expand Up @@ -565,8 +567,8 @@ def _to_patchrequest(self, zone, record, name, type, data, extra, action):

continue

if name == r.name and r.id != id:
# we have other records with the same name so make an update
if name == r.name and type == r.type and r.id != id:
# we have other records with the same name and type so make an update
# request
rrset["changetype"] = "update"
content = {}
Expand Down
11 changes: 11 additions & 0 deletions libcloud/test/dns/fixtures/rcodezero/list_records.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@
"disabled": false
}
]
},
{
"name": "aaaaexisting.example.at.",
"type": "AAAA",
"ttl": 3600,
"records": [
{
"content": "2001:db8::42",
"disabled": false
}
]
}
],
"from": 1,
Expand Down
36 changes: 27 additions & 9 deletions libcloud/test/dns/test_rcodezero.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def test_list_record_types(self):

def test_list_records(self):
records = self.driver.list_records(self.test_zone)
self.assertEqual(len(records), 3)
self.assertEqual(len(records), 4)

def test_list_zones(self):
zones = self.driver.list_zones()
Expand Down Expand Up @@ -118,6 +118,24 @@ def test_update_record(self):
self.assertEqual(record.type, RecordType.A)
self.assertEqual(record.ttl, 300)

# test issue #2042
def test_add_other_type_to_existing_record(self):
payload = self.driver._to_patchrequest(
self.test_record.zone.id,
self.test_record,
"aaaaexisting",
RecordType.A,
"127.0.0.1",
{"ttl": 300},
"update",
)
self.assertEqual(payload[0]["name"], "aaaaexisting.example.at.")
self.assertEqual(payload[0]["type"], RecordType.A)
self.assertEqual(payload[0]["ttl"], 300)
self.assertEqual(payload[0]["changetype"], "update")
expected_record = [{"content": "127.0.0.1"}]
self.assertEqual(payload[0]["records"], expected_record)

def test_update_zone(self):
with self.assertRaises(NotImplementedError):
self.driver.update_zone(self.test_zone, "example.at")
Expand All @@ -144,7 +162,7 @@ class RcodeZeroDNSMockHttp(MockHttp):
fixtures = DNSFileFixtures("rcodezero")
base_headers = {"content-type": "application/json"}

def _api_v1_zones(self, method, url, body, headers):
def _api_v2_zones(self, method, url, body, headers):
if method == "GET":
# list_zones()
body = self.fixtures.load("list_zones.json")
Expand All @@ -157,7 +175,7 @@ def _api_v1_zones(self, method, url, body, headers):
raise NotImplementedError("Unexpected method: %s" % method)
return (httplib.OK, body, self.base_headers, httplib.responses[httplib.OK])

def _api_v1_zones_example_at(self, method, *args, **kwargs):
def _api_v2_zones_example_at(self, method, *args, **kwargs):
if method == "GET":
# list_records()
body = self.fixtures.load("get_zone_details.json")
Expand All @@ -173,10 +191,10 @@ def _api_v1_zones_example_at(self, method, *args, **kwargs):
raise NotImplementedError("Unexpected method: %s" % method)
return (httplib.OK, body, self.base_headers, httplib.responses[httplib.OK])

def _api_v1_zones_example_at__rrsets(self, method, *args, **kwargs):
return self._api_v1_zones_example_at_rrsets(method, *args, **kwargs)
def _api_v2_zones_example_at__rrsets(self, method, *args, **kwargs):
return self._api_v2_zones_example_at_rrsets(method, *args, **kwargs)

def _api_v1_zones_example_at_rrsets(self, method, *args, **kwargs):
def _api_v2_zones_example_at_rrsets(self, method, *args, **kwargs):
if method == "GET":
# list_records()
body = self.fixtures.load("list_records.json")
Expand All @@ -189,7 +207,7 @@ def _api_v1_zones_example_at_rrsets(self, method, *args, **kwargs):
raise NotImplementedError("Unexpected method: %s" % method)
return (httplib.OK, body, self.base_headers, httplib.responses[httplib.OK])

def _api_v1_zones_EXISTS(self, method, url, body, headers):
def _api_v2_zones_EXISTS(self, method, url, body, headers):
# create_zone() is a POST. Raise on all other operations to be safe.
if method != "POST":
raise NotImplementedError("Unexpected method: %s" % method)
Expand All @@ -203,15 +221,15 @@ def _api_v1_zones_EXISTS(self, method, url, body, headers):
"Unprocessable Entity",
)

def _api_v1_zones_example_com_MISSING(self, *args, **kwargs):
def _api_v2_zones_example_com_MISSING(self, *args, **kwargs):
return (
httplib.NOT_FOUND,
'{"status": "failed","message": "Zone not found"}',
self.base_headers,
"Unprocessable Entity",
)

def _api_v1_zones_example_at_MISSING(self, *args, **kwargs):
def _api_v2_zones_example_at_MISSING(self, *args, **kwargs):
return (
httplib.NOT_FOUND,
'{"status": "failed","message": "Zone not found"}',
Expand Down