650 lines
26 KiB
Python
650 lines
26 KiB
Python
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
# (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""
|
|
DurableDNS Driver
|
|
"""
|
|
from libcloud.utils.py3 import httplib
|
|
from libcloud.utils.py3 import ensure_string
|
|
from libcloud.dns.types import Provider, RecordType
|
|
from libcloud.dns.base import Record, Zone
|
|
from libcloud.dns.base import DNSDriver
|
|
from libcloud.dns.types import ZoneDoesNotExistError, ZoneAlreadyExistsError
|
|
from libcloud.dns.types import RecordDoesNotExistError
|
|
from xml.etree.ElementTree import tostring
|
|
from libcloud.common.durabledns import DurableConnection, DurableResponse
|
|
from libcloud.common.durabledns import DurableDNSException
|
|
from libcloud.common.durabledns import _schema_builder as api_schema_builder
|
|
from libcloud.common.durabledns import SCHEMA_BUILDER_MAP
|
|
|
|
|
|
__all__ = [
|
|
'ZONE_EXTRA_PARAMS_DEFAULT_VALUES',
|
|
'RECORD_EXTRA_PARAMS_DEFAULT_VALUES',
|
|
'DEFAULT_TTL',
|
|
'DurableDNSResponse',
|
|
'DurableDNSConnection',
|
|
'DurableDNSDriver'
|
|
]
|
|
|
|
# This will be the default values for each extra attributes when are not
|
|
# specified in the 'extra' parameter
|
|
ZONE_EXTRA_PARAMS_DEFAULT_VALUES = {
|
|
'ns': 'ns1.durabledns.com.', 'mbox': 'support.durabledns.com',
|
|
'refresh': '28800', 'retry': 7200, 'expire': 604800, 'minimum': 82000,
|
|
'xfer': '', 'update_acl': ''
|
|
}
|
|
|
|
RECORD_EXTRA_PARAMS_DEFAULT_VALUES = {'aux': 0, 'ttl': 3600}
|
|
|
|
DEFAULT_TTL = 3600
|
|
|
|
|
|
class DurableDNSResponse(DurableResponse):
|
|
pass
|
|
|
|
|
|
class DurableDNSConnection(DurableConnection):
|
|
responseCls = DurableDNSResponse
|
|
|
|
|
|
class DurableDNSDriver(DNSDriver):
|
|
type = Provider.DURABLEDNS
|
|
name = 'DurableDNS'
|
|
website = 'https://durabledns.com'
|
|
connectionCls = DurableDNSConnection
|
|
|
|
RECORD_TYPE_MAP = {
|
|
RecordType.A: 'A',
|
|
RecordType.AAAA: 'AAAA',
|
|
RecordType.CNAME: 'CNAME',
|
|
RecordType.HINFO: 'HINFO',
|
|
RecordType.MX: 'MX',
|
|
RecordType.NS: 'NS',
|
|
RecordType.PTR: 'PTR',
|
|
RecordType.RP: 'RP',
|
|
RecordType.SRV: 'SRV',
|
|
RecordType.TXT: 'TXT'
|
|
}
|
|
|
|
def list_zones(self):
|
|
"""
|
|
Return a list of zones.
|
|
|
|
:return: ``list`` of :class:`Zone`
|
|
"""
|
|
schema_params = SCHEMA_BUILDER_MAP.get('list_zones')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret}
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
child.text = str(params.get(key))
|
|
req_data = tostring(schema)
|
|
action = '/services/dns/listZones.php'
|
|
params = {}
|
|
headers = {"SOAPAction": "urn:listZoneswsdl#listZones"}
|
|
response = self.connection.request(action=action, params=params,
|
|
data=req_data, method="POST",
|
|
headers=headers)
|
|
# listZones method doens't return full data in zones as getZone
|
|
# method does.
|
|
zones = []
|
|
for data in response.objects:
|
|
zone = self.get_zone(data.get('id'))
|
|
zones.append(zone)
|
|
return zones
|
|
|
|
def list_records(self, zone):
|
|
"""
|
|
Return a list of records for the provided zone.
|
|
|
|
:param zone: Zone to list records for.
|
|
:type zone: :class:`Zone`
|
|
|
|
:return: ``list`` of :class:`Record`
|
|
"""
|
|
schema_params = SCHEMA_BUILDER_MAP.get('list_records')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret,
|
|
'zonename': zone.id}
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
child.text = str(params.get(key))
|
|
req_data = tostring(schema)
|
|
action = '/services/dns/listRecords.php?'
|
|
params = {}
|
|
headers = {"SOAPAction": "urn:listRecordswsdl#listRecords"}
|
|
try:
|
|
response = self.connection.request(action=action, params=params,
|
|
data=req_data, method="POST",
|
|
headers=headers)
|
|
except DurableDNSException as e:
|
|
if 'Zone does not exist' in e.message:
|
|
raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
|
|
value=e.message)
|
|
raise e
|
|
|
|
# listRecords method doens't return full data in records as getRecord
|
|
# method does.
|
|
records = []
|
|
for data in response.objects:
|
|
record = self.get_record(zone.id, data.get('id'))
|
|
records.append(record)
|
|
|
|
return records
|
|
|
|
def get_zone(self, zone_id):
|
|
"""
|
|
Return a Zone instance.
|
|
|
|
:param zone_id: ID of the required zone
|
|
:type zone_id: ``str``
|
|
|
|
:rtype: :class:`Zone`
|
|
"""
|
|
schema_params = SCHEMA_BUILDER_MAP.get('get_zone')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret,
|
|
'zonename': zone_id}
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
child.text = str(params.get(key))
|
|
req_data = tostring(schema)
|
|
action = '/services/dns/getZone.php?'
|
|
params = {}
|
|
headers = {"SOAPAction": "urn:getZonewsdl#getZone"}
|
|
try:
|
|
response = self.connection.request(action=action, params=params,
|
|
data=req_data, method="POST",
|
|
headers=headers)
|
|
except DurableDNSException as e:
|
|
if 'Zone does not exist' in e.message:
|
|
raise ZoneDoesNotExistError(zone_id=zone_id, driver=self,
|
|
value=e.message)
|
|
raise e
|
|
|
|
zones = self._to_zones(response.objects)
|
|
|
|
return zones[0]
|
|
|
|
def get_record(self, zone_id, record_id):
|
|
"""
|
|
Return a Record instance.
|
|
|
|
:param zone_id: ID of the required zone
|
|
:type zone_id: ``str``
|
|
|
|
:param record_id: ID of the required record
|
|
:type record_id: ``str``
|
|
|
|
:rtype: :class:`Record`
|
|
"""
|
|
schema_params = SCHEMA_BUILDER_MAP.get('get_record')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret,
|
|
'zonename': zone_id, 'recordid': record_id}
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
child.text = str(params.get(key))
|
|
req_data = tostring(schema)
|
|
action = '/services/dns/getRecord.php?'
|
|
params = {}
|
|
headers = {"SOAPAction": "urn:getRecordwsdl#getRecord"}
|
|
try:
|
|
response = self.connection.request(action=action, params=params,
|
|
data=req_data, method="POST",
|
|
headers=headers)
|
|
except DurableDNSException as e:
|
|
if 'Zone does not exist' in e.message:
|
|
raise ZoneDoesNotExistError(zone_id=zone_id, driver=self,
|
|
value=e.message)
|
|
if 'Record does not exist' in e.message:
|
|
raise RecordDoesNotExistError(record_id=record_id, driver=self,
|
|
value=e.message)
|
|
raise e
|
|
|
|
zone = self.get_zone(zone_id)
|
|
record = self._to_record(response.objects[0], zone)
|
|
return record
|
|
|
|
def create_zone(self, domain, type='master', ttl=None, extra=None):
|
|
"""
|
|
Create a new zone.
|
|
|
|
:param domain: Name of zone, followed by a dot (.) (e.g. example.com.)
|
|
:type domain: ``str``
|
|
|
|
:param type: Zone type (Only master available). (optional)
|
|
:type type: ``str``
|
|
|
|
:param ttl: TTL for new records. (optional)
|
|
:type ttl: ``int``
|
|
|
|
:param extra: Extra attributes ('mbox', 'ns', 'minimum', 'refresh',
|
|
'expire', 'update_acl', 'xfer').
|
|
(optional)
|
|
:type extra: ``dict``
|
|
|
|
:rtype: :class:`Zone`
|
|
"""
|
|
if extra is None:
|
|
extra = ZONE_EXTRA_PARAMS_DEFAULT_VALUES
|
|
else:
|
|
extra_fields = ZONE_EXTRA_PARAMS_DEFAULT_VALUES.keys()
|
|
missing = set(extra_fields).difference(set(extra.keys()))
|
|
for field in missing:
|
|
extra[field] = ZONE_EXTRA_PARAMS_DEFAULT_VALUES.get(field)
|
|
schema_params = SCHEMA_BUILDER_MAP.get('create_zone')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret,
|
|
'zonename': domain, 'ttl': ttl or DEFAULT_TTL}
|
|
params.update(extra)
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
if isinstance(params.get(key), int):
|
|
child.text = "%d"
|
|
else:
|
|
child.text = "%s"
|
|
# We can't insert values directly in child.text because API raises
|
|
# and exception for values that need to be integers. And tostring
|
|
# method from ElementTree can't handle int values.
|
|
skel = ensure_string(tostring(schema)) # Deal with PY3
|
|
req_data = skel % (self.key, self.secret, domain, extra.get('ns'),
|
|
extra.get('mbox'), extra.get('refresh'),
|
|
extra.get('retry'), extra.get('expire'),
|
|
extra.get('minimum'), ttl or DEFAULT_TTL,
|
|
extra.get('xfer'), extra.get('update_acl'))
|
|
action = '/services/dns/createZone.php?'
|
|
params = {}
|
|
headers = {"SOAPAction": "urn:createZonewsdl#createZone"}
|
|
try:
|
|
self.connection.request(action=action, params=params,
|
|
data=req_data, method="POST",
|
|
headers=headers)
|
|
except DurableDNSException as e:
|
|
if 'Zone Already Exist' in e.message:
|
|
raise ZoneAlreadyExistsError(zone_id=domain, driver=self,
|
|
value=e.message)
|
|
raise e
|
|
|
|
zone = self.get_zone(domain)
|
|
return zone
|
|
|
|
def create_record(self, name, zone, type, data, extra=None):
|
|
"""
|
|
Create a new record.
|
|
|
|
: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
|
|
argument.
|
|
:type name: ``str``
|
|
|
|
:param zone: Zone where the requested record is created.
|
|
:type zone: :class:`Zone`
|
|
|
|
:param type: DNS record type (A, AAAA, ...).
|
|
:type type: :class:`RecordType`
|
|
|
|
:param data: Data for the record (depends on the record type).
|
|
:type data: ``str``
|
|
|
|
:param extra: Extra attributes (e.g. 'aux', 'ttl'). (optional)
|
|
:type extra: ``dict``
|
|
|
|
:rtype: :class:`Record`
|
|
"""
|
|
if extra is None:
|
|
extra = RECORD_EXTRA_PARAMS_DEFAULT_VALUES
|
|
else:
|
|
if 'aux' not in extra:
|
|
extra['aux'] = RECORD_EXTRA_PARAMS_DEFAULT_VALUES.get('aux')
|
|
if 'ttl' not in extra:
|
|
extra['ttl'] = RECORD_EXTRA_PARAMS_DEFAULT_VALUES.get('ttl')
|
|
extra['ddns_enabled'] = 'N'
|
|
schema_params = SCHEMA_BUILDER_MAP.get('create_record')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret,
|
|
'zonename': zone.id, 'name': name, 'type': type,
|
|
'data': data}
|
|
params.update(extra)
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
if isinstance(params.get(key), int):
|
|
child.text = "%d"
|
|
else:
|
|
child.text = "%s"
|
|
# We can't insert values directly in child.text because API raises
|
|
# and exception for values that need to be integers. And tostring
|
|
# method from ElementTree can't handle int values.
|
|
skel = ensure_string(tostring(schema)) # Deal with PY3
|
|
req_data = skel % (self.key, self.secret, zone.id, name, type, data,
|
|
extra.get('aux'), extra.get('ttl'),
|
|
extra.get('ddns_enabled'))
|
|
action = '/services/dns/createRecord.php?'
|
|
headers = {"SOAPAction": "urn:createRecordwsdl#createRecord"}
|
|
try:
|
|
response = self.connection.request(action=action, data=req_data,
|
|
method="POST", headers=headers)
|
|
objects = response.objects
|
|
except DurableDNSException as e:
|
|
# In DurableDNS is possible to create records with same data.
|
|
# Their ID's will be different but the API does not implement
|
|
# the RecordAlreadyExist exception. Only ZoneDoesNotExist will
|
|
# be handled.
|
|
if 'Zone does not exist' in e.message:
|
|
raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
|
|
value=e.message)
|
|
raise e
|
|
|
|
record_item = objects[0]
|
|
record_item['name'] = name
|
|
record_item['type'] = type
|
|
record_item['data'] = data
|
|
record_item['ttl'] = extra.get('ttl')
|
|
record_item['aux'] = extra.get('aux')
|
|
|
|
record = self._to_record(record_item, zone)
|
|
return record
|
|
|
|
def update_zone(self, zone, domain, type='master', ttl=None, extra=None):
|
|
"""
|
|
Update an existing zone.
|
|
|
|
:param zone: Zone to update.
|
|
:type zone: :class:`Zone`
|
|
|
|
:param domain: Name of zone, followed by a dot (.) (e.g. example.com.)
|
|
:type domain: ``str``
|
|
|
|
:param type: Zone type (master / slave).
|
|
:type type: ``str``
|
|
|
|
:param ttl: TTL for new records. (optional)
|
|
:type ttl: ``int``
|
|
|
|
:param extra: Extra attributes ('ns', 'mbox', 'refresh', 'retry',
|
|
'expire', 'minimum', 'xfer', 'update_acl'). (optional)
|
|
:type extra: ``dict``
|
|
|
|
:rtype: :class:`Zone`
|
|
"""
|
|
if ttl is None:
|
|
ttl = zone.ttl
|
|
if extra is None:
|
|
extra = zone.extra
|
|
else:
|
|
extra_fields = ZONE_EXTRA_PARAMS_DEFAULT_VALUES.keys()
|
|
missing = set(extra_fields).difference(set(extra.keys()))
|
|
for field in missing:
|
|
extra[field] = zone.extra.get(field)
|
|
schema_params = SCHEMA_BUILDER_MAP.get('update_zone')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret,
|
|
'zonename': domain, 'ttl': ttl}
|
|
params.update(extra)
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
if isinstance(params.get(key), int):
|
|
child.text = "%d"
|
|
else:
|
|
child.text = "%s"
|
|
# We can't insert values directly in child.text because API raises
|
|
# and exception for values that need to be integers. And tostring
|
|
# method from ElementTree can't handle int values.
|
|
skel = ensure_string(tostring(schema)) # Deal with PY3
|
|
req_data = skel % (self.key, self.secret, domain, extra['ns'],
|
|
extra['mbox'], extra['refresh'], extra['retry'],
|
|
extra['expire'], extra['minimum'], ttl,
|
|
extra['xfer'], extra['update_acl'])
|
|
action = '/services/dns/updateZone.php?'
|
|
headers = {"SOAPAction": "urn:updateZonewsdl#updateZone"}
|
|
try:
|
|
self.connection.request(action=action,
|
|
data=req_data,
|
|
method="POST",
|
|
headers=headers)
|
|
except DurableDNSException as e:
|
|
if 'Zone does not exist' in e.message:
|
|
raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
|
|
value=e.message)
|
|
raise e
|
|
|
|
# After update the zone, serial number change. In order to have it
|
|
# updated, we need to get again the zone data.
|
|
zone = self.get_zone(zone.id)
|
|
return zone
|
|
|
|
def update_record(self, record, name, type, data, extra=None):
|
|
"""
|
|
Update an existing record.
|
|
|
|
:param record: Record to update.
|
|
:type record: :class:`Record`
|
|
|
|
: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
|
|
argument.
|
|
:type name: ``str``
|
|
|
|
:param type: DNS record type (A, AAAA, ...).
|
|
:type type: :class:`RecordType`
|
|
|
|
:param data: Data for the record (depends on the record type).
|
|
:type data: ``str``
|
|
|
|
:param extra: (optional) Extra attributes (driver specific).
|
|
:type extra: ``dict``
|
|
|
|
:rtype: :class:`Record`
|
|
"""
|
|
zone = record.zone
|
|
if extra is None:
|
|
extra = record.extra
|
|
else:
|
|
extra_fields = ['aux', 'ttl']
|
|
missing = set(extra_fields).difference(set(extra.keys()))
|
|
for field in missing:
|
|
extra[field] = record.extra.get(field)
|
|
extra['ddns_enabled'] = 'N'
|
|
schema_params = SCHEMA_BUILDER_MAP.get('update_record')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret,
|
|
'zonename': zone.id, 'id': record.id, 'name': name,
|
|
'data': data}
|
|
params.update(extra)
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
if isinstance(params.get(key), int):
|
|
child.text = "%d"
|
|
else:
|
|
child.text = "%s"
|
|
# We can't insert values directly in child.text because API raises
|
|
# and exception for values that need to be integers. And tostring
|
|
# method from ElementTree can't handle int values.
|
|
skel = ensure_string(tostring(schema)) # Deal with PY3
|
|
req_data = skel % (self.key, self.secret, zone.id, record.id, name,
|
|
extra.get('aux'), data, extra.get('ttl'),
|
|
extra.get('ddns_enabled'))
|
|
action = '/services/dns/updateRecord.php?'
|
|
headers = {"SOAPAction": "urn:updateRecordwsdl#updateRecord"}
|
|
try:
|
|
self.connection.request(action=action,
|
|
data=req_data,
|
|
method="POST",
|
|
headers=headers)
|
|
except DurableDNSException as e:
|
|
if 'Zone does not exist' in e.message:
|
|
raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
|
|
value=e.message)
|
|
raise e
|
|
|
|
record_item = {}
|
|
record_item['id'] = record.id
|
|
record_item['name'] = name
|
|
record_item['type'] = type
|
|
record_item['data'] = data
|
|
record_item['ttl'] = extra.get('ttl')
|
|
record_item['aux'] = extra.get('aux')
|
|
record = self._to_record(record_item, zone)
|
|
return record
|
|
|
|
def delete_zone(self, zone):
|
|
"""
|
|
Delete a zone.
|
|
|
|
Note: This will delete all the records belonging to this zone.
|
|
|
|
:param zone: Zone to delete.
|
|
:type zone: :class:`Zone`
|
|
|
|
:rtype: ``bool``
|
|
"""
|
|
schema_params = SCHEMA_BUILDER_MAP.get('delete_zone')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret,
|
|
'zonename': zone.id}
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
child.text = str(params.get(key))
|
|
req_data = tostring(schema)
|
|
action = '/services/dns/deleteZone.php?'
|
|
headers = {"SOAPAction": "urn:deleteZonewsdl#deleteZone"}
|
|
try:
|
|
response = self.connection.request(action=action,
|
|
data=req_data, method="POST",
|
|
headers=headers)
|
|
except DurableDNSException as e:
|
|
if 'Zone does not exist' in e.message:
|
|
raise ZoneDoesNotExistError(zone_id=zone.id, driver=self,
|
|
value=e.message)
|
|
raise e
|
|
|
|
return response.status in [httplib.OK]
|
|
|
|
def delete_record(self, record):
|
|
"""
|
|
Delete a record.
|
|
|
|
:param record: Record to delete.
|
|
:type record: :class:`Record`
|
|
|
|
:rtype: ``bool``
|
|
"""
|
|
schema_params = SCHEMA_BUILDER_MAP.get('delete_record')
|
|
attributes = schema_params.get('attributes')
|
|
schema = api_schema_builder(schema_params.get('urn_nid'),
|
|
schema_params.get('method'),
|
|
attributes)
|
|
params = {'apiuser': self.key, 'apikey': self.secret,
|
|
'zonename': record.zone.id, 'id': record.id}
|
|
urn = list(schema)[0]
|
|
for child in urn:
|
|
key = child.tag.split(':')[2]
|
|
if key in attributes:
|
|
child.text = str(params.get(key))
|
|
req_data = tostring(schema)
|
|
action = '/services/dns/deleteRecord.php?'
|
|
headers = {"SOAPAction": "urn:deleteRecordwsdl#deleteRecord"}
|
|
try:
|
|
response = self.connection.request(action=action, data=req_data,
|
|
headers=headers, method="POST")
|
|
except DurableDNSException as e:
|
|
if 'Record does not exists' in e.message:
|
|
raise RecordDoesNotExistError(record_id=record.id, driver=self,
|
|
value=e.message)
|
|
if 'Zone does not exist' in e.message:
|
|
raise ZoneDoesNotExistError(zone_id=record.zone.id,
|
|
driver=self, value=e.message)
|
|
raise e
|
|
|
|
return response.status in [httplib.OK]
|
|
|
|
def _to_zone(self, item):
|
|
extra = item.get('extra')
|
|
# DurableDNS does not return information about zone type. This will be
|
|
# set as master by default.
|
|
zone = Zone(id=item.get('id'), type='master', domain=item.get('id'),
|
|
ttl=item.get('ttl'), driver=self, extra=extra)
|
|
|
|
return zone
|
|
|
|
def _to_zones(self, items):
|
|
zones = []
|
|
for item in items:
|
|
zones.append(self._to_zone(item))
|
|
|
|
return zones
|
|
|
|
def _to_record(self, item, zone=None):
|
|
extra = {'aux': int(item.get('aux')), 'ttl': int(item.get('ttl'))}
|
|
record = Record(id=item.get('id'), type=item.get('type'), zone=zone,
|
|
name=item.get('name'), data=item.get('data'),
|
|
driver=self, ttl=item.get('ttl', None), extra=extra)
|
|
|
|
return record
|
|
|
|
def _to_records(self, items, zone=None):
|
|
records = []
|
|
for item in items:
|
|
records.append(self._to_record(item, zone))
|
|
|
|
return records
|