Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update worldwidedns provider with tests. #621

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
87 changes: 55 additions & 32 deletions libcloud/dns/drivers/worldwidedns.py
Expand Up @@ -144,22 +144,24 @@ def get_record(self, zone_id, record_id):
:param zone_id: ID of the required zone
:type zone_id: ``str``

:param record_id: ID of the required record
:param record_id: ID number of the required record.
:type record_id: ``str``

:rtype: :class:`Record`
"""
zone = self.get_zone(zone_id)
r_entry = [i for i in range(MAX_RECORD_ENTRIES) if
zone.extra.get('S%s' % i) == record_id]
if not r_entry:
raise RecordDoesNotExistError(value="Record doesn't exists",
driver=zone.driver,
record_id=record_id)
entry = r_entry[0]
type = zone.extra.get('T%s' % entry)
data = zone.extra.get('D%s' % entry)
record = self._to_record(record_id, type, data, zone)
try:
if int(record_id) not in range(1, MAX_RECORD_ENTRIES + 1):
raise RecordDoesNotExistError(value="Record doesn't exists",
driver=zone.driver,
record_id=record_id)
except ValueError:
raise WorldWideDNSError(
value="Record id should be a string number", driver=self)
subdomain = zone.extra.get('S%s' % record_id)
type = zone.extra.get('T%s' % record_id)
data = zone.extra.get('D%s' % record_id)
record = self._to_record(record_id, subdomain, type, data, zone)
return record

def update_zone(self, zone, domain, type='master', ttl=None, extra=None,
Expand Down Expand Up @@ -259,19 +261,19 @@ def update_record(self, record, name, type, data, extra=None):
if (extra is None) or ('entry' not in extra):
raise WorldWideDNSError(value="You must enter 'entry' parameter",
driver=self)
entry = extra.get('entry')
record_id = extra.get('entry')
if name == '':
name = '@'
if type not in self.RECORD_TYPE_MAP:
raise RecordError(value="Record type is not allowed",
driver=record.zone.driver,
record_id=name)
zone = record.zone
extra = {'S%s' % entry: name,
'T%s' % entry: type,
'D%s' % entry: data}
extra = {'S%s' % record_id: name,
'T%s' % record_id: type,
'D%s' % record_id: data}
zone = self.update_zone(zone, zone.domain, extra=extra)
record = self.get_record(zone.id, name)
record = self.get_record(zone.id, record_id)
return record

def create_zone(self, domain, type='master', ttl=None, extra=None):
Expand Down Expand Up @@ -323,6 +325,9 @@ def create_record(self, name, zone, type, data, extra=None):
"""
Create a new record.

We can create 40 record per domain. If all slots are full, we can
replace one of them by choosing a specific entry in ``extra`` argument.

:param name: Record name without the domain name (e.g. www).
Note: If you want to create a record for a base domain
name, you should specify empty string ('') for this
Expand All @@ -344,20 +349,25 @@ def create_record(self, name, zone, type, data, extra=None):
:rtype: :class:`Record`
"""
if (extra is None) or ('entry' not in extra):
raise WorldWideDNSError(value="You must enter 'entry' parameter",
driver=zone.driver)
entry = extra.get('entry')
# If no entry is specified, we look for an available one. If all
# are full, raise error.
record_id = self._get_available_record_entry(zone)
if not record_id:
raise WorldWideDNSError(value="All record entries are full",
driver=zone.driver)
else:
record_id = extra.get('entry')
if name == '':
name = '@'
if type not in self.RECORD_TYPE_MAP:
raise RecordError(value="Record type is not allowed",
driver=zone.driver,
record_id=name)
extra = {'S%s' % entry: name,
'T%s' % entry: type,
'D%s' % entry: data}
record_id=record_id)
extra = {'S%s' % record_id: name,
'T%s' % record_id: type,
'D%s' % record_id: data}
zone = self.update_zone(zone, zone.domain, extra=extra)
record = self.get_record(zone.id, name)
record = self.get_record(zone.id, record_id)
return record

def delete_zone(self, zone):
Expand Down Expand Up @@ -454,6 +464,17 @@ def ex_transfer_domain(self, domain, user_id):
params=params)
return response.success()

def _get_available_record_entry(self, zone):
"""Return an available entry to store a record."""
entries = zone.extra
for entry in range(1, MAX_RECORD_ENTRIES + 1):
subdomain = entries.get('S%s' % entry)
_type = entries.get('T%s' % entry)
data = entries.get('D%s' % entry)
if not any([subdomain, _type, data]):
return entry
return None

def _to_zones(self, data):
domain_list = re.split('\r?\n', data)
zones = []
Expand All @@ -479,7 +500,8 @@ def _to_zone(self, line):
for line in range(MAX_RECORD_ENTRIES):
line_data = zone_data[line].split('\x1f')
extra['S%s' % (line + 1)] = line_data[0]
extra['T%s' % (line + 1)] = line_data[1]
_type = line_data[1]
extra['T%s' % (line + 1)] = _type if _type != 'NONE' else ''
try:
extra['D%s' % (line + 1)] = line_data[2]
except IndexError:
Expand All @@ -499,14 +521,15 @@ def _get_domain_data(self, name):

def _to_records(self, zone):
records = []
for entry in range(MAX_RECORD_ENTRIES):
subdomain = zone.extra['S%s' % (entry + 1)]
type = zone.extra['T%s' % (entry + 1)]
data = zone.extra['D%s' % (entry + 1)]
for record_id in range(1, MAX_RECORD_ENTRIES + 1):
subdomain = zone.extra['S%s' % (record_id)]
type = zone.extra['T%s' % (record_id)]
data = zone.extra['D%s' % (record_id)]
if subdomain and type and data:
record = self._to_record(subdomain, type, data, zone)
record = self._to_record(
record_id, subdomain, type, data, zone)
records.append(record)
return records

def _to_record(self, subdomain, type, data, zone):
return Record(subdomain, subdomain, type, data, zone, zone.driver)
def _to_record(self, _id, subdomain, type, data, zone):
return Record(_id, subdomain, type, data, zone, zone.driver)
@@ -0,0 +1,46 @@
hostmaster.niteowebsponsoredthisone.com
21600
10800
604800
43200

wwwA0.0.0.0
domain2A0.0.0.2
@MX10 niteowebsponsoredthisone.com
domain4A0.0.0.4
domain5A0.0.0.5
domain6A0.0.0.6
domain7A0.0.0.7
domain8A0.0.0.8
domain9A0.0.0.9
domain10A0.0.0.10
domain11A0.0.0.11
domain12A0.0.0.12
domain13A0.0.0.13
domain14A0.0.0.14
domain15A0.0.0.15
domain16A0.0.0.16
domain17A0.0.0.17
domain18A0.0.0.18
domain19A0.0.0.19
domain20A0.0.0.20
domain21A0.0.0.21
domain22A0.0.0.22
domain23bA0.0.0.41
domain24A0.0.0.24
domain25A0.0.0.25
domain26A0.0.0.26
domain27A0.0.0.27
domain28A0.0.0.28
domain29A0.0.0.29
domain30A0.0.0.30
domain31A0.0.0.31
domain32A0.0.0.32
domain33A0.0.0.33
domain34A0.0.0.34
domain35A0.0.0.35
domain36A0.0.0.36
domain37A0.0.0.37
domain38A0.0.0.38
domain39A0.0.0.39
domain40A0.0.0.40
@@ -0,0 +1,46 @@
hostmaster.niteowebsponsoredthisone.com
21600
10800
604800
43200

wwwA0.0.0.0
domain2A0.0.0.2
@MX10 niteowebsponsoredthisone.com
domain4A0.0.0.4
domain5A0.0.0.5
domain6A0.0.0.6
domain7A0.0.0.7
domain8A0.0.0.8
domain9A0.0.0.9
domain10A0.0.0.10
domain11A0.0.0.11
domain12A0.0.0.12
domain13A0.0.0.13
domain14A0.0.0.14
domain15A0.0.0.15
domain16A0.0.0.16
domain17A0.0.0.17
domain18A0.0.0.18
domain19A0.0.0.19
domain20A0.0.0.20
domain21A0.0.0.21
domain22A0.0.0.22
domain23A0.0.0.23
domain24A0.0.0.24
domain25A0.0.0.25
domain26A0.0.0.26
domain27A0.0.0.27
domain28A0.0.0.28
domain29A0.0.0.29
domain30A0.0.0.30
domain31A0.0.0.31
domain32A0.0.0.32
domain33A0.0.0.33
domain34A0.0.0.34
domain35A0.0.0.35
domain36A0.0.0.36
domain37A0.0.0.37
domain38A0.0.0.38
domain39A0.0.0.39
domain40A0.0.0.40
@@ -0,0 +1,46 @@
hostmaster.niteowebsponsoredthisone.com
21600
10800
604800
43200

wwwA0.0.0.0
domain2A0.0.0.2
@MX10 niteowebsponsoredthisone.com
domain4A0.0.0.4
domain1A0.0.0.1
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE
NONE