You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2011/09/22 13:37:49 UTC
svn commit: r1174075 - /libcloud/trunk/libcloud/dns/drivers/linode.py
Author: tomaz
Date: Thu Sep 22 11:37:48 2011
New Revision: 1174075
URL: http://svn.apache.org/viewvc?rev=1174075&view=rev
Log:
Finish Linode DNS driver and implement all the missing methods. Still need to
add tests.
Modified:
libcloud/trunk/libcloud/dns/drivers/linode.py
Modified: libcloud/trunk/libcloud/dns/drivers/linode.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/dns/drivers/linode.py?rev=1174075&r1=1174074&r2=1174075&view=diff
==============================================================================
--- libcloud/trunk/libcloud/dns/drivers/linode.py (original)
+++ libcloud/trunk/libcloud/dns/drivers/linode.py Thu Sep 22 11:37:48 2011
@@ -21,11 +21,27 @@ __all__ = [
from libcloud.common.linode import (API_ROOT, LinodeException,
LinodeConnection,
LINODE_PLAN_IDS)
-from libcloud.common.linode import API_HOST, API_ROOT
-from libcloud.dns.types import Provider
+from libcloud.common.linode import API_HOST, API_ROOT, LinodeException
+from libcloud.dns.types import Provider, RecordType
+from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError
from libcloud.dns.base import DNSDriver, Zone, Record
+VALID_ZONE_EXTRA_PARAMS = ['SOA_Email', 'Refresh_sec', 'Retry_sec',
+ 'Expire_sec', 'status', 'master_ips']
+
+VALID_RECORD_EXTRA_PARAMS = ['Priority', 'Weight', 'Port', 'Protocol',
+ 'TTL_sec']
+
+RECORD_TYPE_MAP = {
+ RecordType.A: 'A',
+ RecordType.AAAA: 'AAAAA',
+ RecordType.CNAME: 'CNAME',
+ RecordType.TXT: 'TXT',
+ RecordType.SRV: 'SRV',
+}
+
+
class LinodeDNSDriver(DNSDriver):
type = Provider.LINODE
name = 'Linode DNS'
@@ -45,28 +61,131 @@ class LinodeDNSDriver(DNSDriver):
def get_zone(self, zone_id):
params = {'api_action': 'domain.list', 'DomainID': zone_id}
+ data = self.connection.request(API_ROOT, params=params).objects[0]
+ zones = self._to_zones(data)
+
+ if len(zones) != 1:
+ raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone_id)
+
+ return zones[0]
def get_record(self, zone_id, record_id):
+ zone = self.get_zone(zone_id=zone_id)
params = {'api_action': 'domain.resource.list', 'DomainID': zone_id,
'ResourceID': record_id}
+ data = self.connection.request(API_ROOT, params=params).objects[0]
+ records = self._to_records(items=data, zone=zone)
+
+ if len(records) != 1:
+ raise RecordDoesNotExistError(value='', driver=self,
+ record_id=record_id)
+
+ return records[0]
def create_zone(self, domain, type='master', ttl=None, extra=None):
- params = {'api_action': 'domain.create'}
+ """
+ Create a new zone.
+
+ API docs: http://www.linode.com/api/dns/domain.create
+ """
+ params = {'api_action': 'domain.create', 'Type': type,
+ 'Domain': domain}
+
+ if ttl:
+ params['TTL_sec'] = ttl
+
+ merged = self._merge_valid_keys(params=params,
+ valid_keys=VALID_ZONE_EXTRA_PARAMS,
+ extra=extra)
+ data = self.connection.request(API_ROOT, params=params).objects[0]
+ zone = Zone(id=data['DomainID'], domain=domain, type=type, ttl=ttl,
+ extra=merged, driver=self)
+ return zone
def create_record(self, name, zone, type, data, extra=None):
- params = {'api_action': 'domain.resource.create'}
+ """
+ Create a new record.
+
+ API docs: http://www.linode.com/api/dns/domain.resource.create
+ """
+ params = {'api_action': 'domain.resource.create', 'DomainID': zone.id,
+ 'Name': name, 'Target': data, 'Type': RECORD_TYPE_MAP[type]}
+ merged = self._merge_valid_keys(params=params,
+ valid_keys=VALID_RECORD_EXTRA_PARAMS,
+ extra=extra)
+
+ data = self.connection.request(API_ROOT, params=params).objects[0]
+ record = Record(id=data['ResourceID'], name=name, type=type,
+ data=data, extra=merged, zone=zone, driver=self)
+ return record
def update_record(self, record, name, type, data, extra):
- params = {'api_action': 'domain.resource.update'}
+ """
+ Update an existing record.
+
+ API docs: http://www.linode.com/api/dns/domain.resource.update
+ """
+ params = {'api_action': 'domain.resource.update',
+ 'ResourceID': record.id, 'DomainID': record.zone.id,
+ 'Name': name, 'Target': data, 'Type': RECORD_TYPE_MAP[type]}
+ merged = self._merge_valid_keys(params=params,
+ valid_keys=VALID_RECORD_EXTRA_PARAMS,
+ extra=extra)
+
+ data = self.connection.request(API_ROOT, params=params).objects[0]
+ record = Record(id=data['ResourceID'], name=name, type=type,
+ data=data, extra=merged, zone=record.zone, driver=self)
+ return record
def delete_zone(self, zone):
params = {'api_action': 'domain.delete', 'DomainID': zone.id}
+ try:
+ data = self.connection.request(API_ROOT, params=params).objects[0]
+ except LinodeException, e:
+ # TODO: Refactor LinodeException, args[0] should be error_id
+ if e.args[0] == 5:
+ raise ZoneDoesNotExistError(value='', driver=self,
+ zone_id=zone.id)
+
+ return 'DomainID' in data
+
def delete_record(self, record):
params = {'api_action': 'domain.resource.delete',
- 'DomainID': record.zone.id, 'ResourceID': record.id}
+ 'DomainID': record.zone.id, 'ResourceID': record.id}
+
+ try:
+ data = self.connection.request(API_ROOT, params=params).objects[0]
+ except LinodeException, e:
+ # TODO: Refactor LinodeException, args[0] should be error_id
+ if e.args[0] == 5:
+ raise RecordDoesNotExistError(value='', driver=self,
+ record_id=record.id)
+
+ return 'ResourceID' in data
+
+ def _merge_valid_keys(self, params, valid_keys, extra):
+ """
+ Merge valid keys from extra into params dictionary and return
+ dictionary with keys which have been merged.
+
+ Note: params is modified in place.
+ """
+ merged = {}
+ if not extra:
+ return merged
+
+ for key in valid_keys:
+ if key in extra:
+ params[key] = extra[key]
+ merged[key] = extra[key]
+
+ return merged
def _to_zones(self, items):
+ """
+ Convert a list of items to the Zone objects.
+ """
zones = []
for item in items:
@@ -75,6 +194,9 @@ class LinodeDNSDriver(DNSDriver):
return zones
def _to_zone(self, item):
+ """
+ Build an Zone object from the item dictionary.
+ """
extra = {'soa_email': item['SOA_EMAIL'], 'status': item['STATUS'],
'description': item['DESCRIPTION']}
zone = Zone(id=item['DOMAINID'], domain=item['DOMAIN'],
@@ -83,6 +205,9 @@ class LinodeDNSDriver(DNSDriver):
return zone
def _to_records(self, items, zone=None):
+ """
+ Convert a list of items to the Record objects.
+ """
records = []
for item in items:
@@ -91,6 +216,9 @@ class LinodeDNSDriver(DNSDriver):
return records
def _to_record(self, item, zone=None):
+ """
+ Build a Record object from the item dictionary.
+ """
extra = {'protocol': item['PROTOCOL'], 'ttl_sec': item['TTL_SEC'],
'port': item['PORT'], 'weight': item['WEIGHT']}
type = self._string_to_record_type(item['TYPE'])