Skip to content
Open
Show file tree
Hide file tree
Changes from all 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