Skip to content

Commit 772d792

Browse files
author
Aaron Sierra
committed
dns: Add {to,from}_default_id() to DNSDriver class
Add .to_default_id() and .from_default_id() functions to the DNSDriver class. These functions support the <type>[:<name>] (e.g. "A:www") record ID format used by many of the drivers.
1 parent 9d43a7c commit 772d792

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

libcloud/dns/base.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
# limitations under the License.
1515

1616

17+
import re
1718
import datetime
1819
from typing import Any, Dict, List, Type, Union, Iterator, Optional
20+
from collections import namedtuple
1921

2022
from libcloud import __version__
21-
from libcloud.dns.types import RecordType
23+
from libcloud.dns.types import RecordType, RecordDoesNotExistError
2224
from libcloud.common.base import BaseDriver, Connection, ConnectionUserAndKey
2325

2426
__all__ = ["Zone", "Record", "DNSDriver"]
@@ -277,6 +279,11 @@ class DNSDriver(BaseDriver):
277279
# Map libcloud record type enum to provider record type name
278280
RECORD_TYPE_MAP = {} # type: Dict[RecordType, str]
279281

282+
# "A" -> type: "A", prefix: None
283+
# "A:www" -> type: "A", prefix: "www"
284+
DEFAULT_ID_RE = re.compile(r"(?P<type>[A-Z]+)(\:(?P<name>.+))?")
285+
DefaultID = namedtuple("DefaultID", "type,name")
286+
280287
def __init__(
281288
self,
282289
key, # type: str
@@ -640,3 +647,19 @@ def _string_to_record_type(self, string):
640647
string = string.upper()
641648
record_type = getattr(RecordType, string)
642649
return record_type
650+
651+
@staticmethod
652+
def to_default_id(zone, name, type):
653+
prefix = zone.prefix(name)
654+
return f"{type}:{prefix}" if prefix else str(type)
655+
656+
@classmethod
657+
def from_default_id(cls, zone, record_id):
658+
match = cls.DEFAULT_ID_RE.match(record_id)
659+
if match is None:
660+
raise RecordDoesNotExistError(
661+
value="malformed record ID", driver=cls, record_id=record_id
662+
)
663+
664+
name = match.group("name")
665+
return cls.DefaultID(match.group("type"), "" if name is None else zone.prefix(name))

libcloud/test/dns/test_base.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,36 @@ def test_get_numeric_id(self):
182182
result = record._get_numeric_id()
183183
self.assertEqual(result, "")
184184

185+
def test_driver_to_default_id(self):
186+
data = [
187+
# name, type, id (expected)
188+
("", "A", "A"),
189+
("example.com", "A", "A"),
190+
("example.com.", "A", "A"),
191+
("mail", "MX", "MX:mail"),
192+
("mail.example.com", "MX", "MX:mail"),
193+
("mail.example.com.", "MX", "MX:mail"),
194+
]
195+
for rname, rtype, rexpect in data:
196+
rid = self.driver.to_default_id(self.master_zone, rname, rtype)
197+
self.assertEqual(rid, rexpect)
198+
199+
def test_driver_from_default_id(self):
200+
data = [
201+
# id, name (expected), type (expected)
202+
("A", "", "A"), # without trailing colon
203+
("A:", "", "A"), # with trailing colon
204+
("A:example.com", "", "A"),
205+
("A:example.com.", "", "A"),
206+
("MX:mail", "mail", "MX"),
207+
("MX:mail.example.com", "mail", "MX"),
208+
("MX:mail.example.com.", "mail", "MX"),
209+
]
210+
for rid, rname, rtype in data:
211+
rparts = self.driver.from_default_id(self.master_zone, rid)
212+
self.assertEqual(rparts.name, rname)
213+
self.assertEqual(rparts.type, rtype)
214+
185215

186216
def zero_pad(value: int) -> str:
187217
if value < 10:

0 commit comments

Comments
 (0)