Skip to content

Commit 3306768

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 7491dec commit 3306768

2 files changed

Lines changed: 53 additions & 1 deletion

File tree

libcloud/dns/base.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515

1616

1717
import datetime
18+
import re
19+
from collections import namedtuple
1820
from typing import Any, Dict, List, Type, Union, Iterator, Optional
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,18 @@ 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(value="malformed record ID",
661+
driver=cls, record_id=record_id)
662+
663+
name = match.group("name")
664+
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
@@ -180,6 +180,36 @@ def test_get_numeric_id(self):
180180
result = record._get_numeric_id()
181181
self.assertEqual(result, "")
182182

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

184214
def zero_pad(value: int) -> str:
185215
if value < 10:

0 commit comments

Comments
 (0)