http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/softlayer.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/softlayer.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/softlayer.py deleted file mode 100644 index 8a3cf4c..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/softlayer.py +++ /dev/null @@ -1,214 +0,0 @@ -# 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. - -__all__ = [ - 'SoftLayerDNSDriver' -] - - -from libcloud.common.softlayer import SoftLayerConnection -from libcloud.common.softlayer import SoftLayerObjectDoesntExist -from libcloud.dns.types import Provider, RecordType -from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError -from libcloud.dns.base import DNSDriver, Zone, Record - - -VALID_RECORD_EXTRA_PARAMS = ['priority', 'ttl'] - - -class SoftLayerDNSDriver(DNSDriver): - type = Provider.SOFTLAYER - name = 'Softlayer DNS' - website = 'https://www.softlayer.com' - connectionCls = SoftLayerConnection - - RECORD_TYPE_MAP = { - RecordType.A: 'a', - RecordType.AAAA: 'aaaa', - RecordType.CNAME: 'cname', - RecordType.MX: 'mx', - RecordType.NS: 'ns', - RecordType.PTR: 'ptr', - RecordType.SOA: 'soa', - RecordType.SPF: 'spf', - RecordType.SRV: 'srv', - RecordType.TXT: 'txt', - } - - def create_zone(self, domain, ttl=None, extra=None): - self.connection.set_context({'resource': 'zone', 'id': domain}) - data = { - 'name': domain, - 'resourceRecords': [] - } - response = self.connection.request( - 'SoftLayer_Dns_Domain', 'createObject', data - ).object - zone = Zone(id=response['id'], domain=domain, - type='master', ttl=3600, driver=self) - return zone - - def get_zone(self, zone_id): - self.connection.set_context({'resource': 'zone', 'id': zone_id}) - try: - response = self.connection.request( - 'SoftLayer_Dns_Domain', 'getObject', id=zone_id - ).object - except SoftLayerObjectDoesntExist: - raise ZoneDoesNotExistError(value='', driver=self, - zone_id=zone_id) - return self._to_zone(response) - - def delete_zone(self, zone): - self.connection.set_context({'resource': 'zone', 'id': zone.id}) - try: - self.connection.request( - 'SoftLayer_Dns_Domain', 'deleteObject', id=zone.id - ).object - except SoftLayerObjectDoesntExist: - raise ZoneDoesNotExistError(value='', driver=self, - zone_id=zone.id) - else: - return True - - def iterate_zones(self): - zones_list = self.connection.request( - 'SoftLayer_Dns_Domain', 'getByDomainName', '.' - ).object - for item in zones_list: - yield self._to_zone(item) - - def iterate_records(self, zone): - self.connection.set_context({'resource': 'zone', 'id': zone.id}) - records_list = self.connection.request( - 'SoftLayer_Dns_Domain', 'getResourceRecords', id=zone.id - ).object - for item in records_list: - yield self._to_record(item, zone=zone) - - def get_record(self, zone_id, record_id): - try: - record = self.connection.request( - 'SoftLayer_Dns_Domain_ResourceRecord', - 'getObject', - id=record_id - ).object - return self._to_record(record, zone=self.get_zone(zone_id)) - except SoftLayerObjectDoesntExist: - raise RecordDoesNotExistError(value='', driver=self, - record_id=record_id) - - def delete_record(self, record): - try: - self.connection.request( - 'SoftLayer_Dns_Domain_ResourceRecord', - 'deleteObject', - id=record.id - ).object - except SoftLayerObjectDoesntExist: - raise RecordDoesNotExistError(value='', driver=self, - record_id=record.id) - else: - return True - - def create_record(self, name, zone, type, data, extra=None): - params = { - 'domainId': zone.id, - 'type': self.RECORD_TYPE_MAP[type], - 'host': name, - 'data': data - } - if extra: - if extra.get('ttl'): - params['ttl'] = extra['ttl'] - if extra.get('refresh'): - params['refresh'] = extra['refresh'] - if extra.get('retry'): - params['retry'] = extra['retry'] - if extra.get('expire'): - params['expire'] = extra['expire'] - if extra.get('priority'): - params['mxPriority'] = extra['priority'] - response = self.connection.request( - 'SoftLayer_Dns_Domain_ResourceRecord', - 'createObject', - params - ).object - - return self._to_record(response, zone=zone) - - def update_record( - self, record, name=None, type=None, data=None, extra=None): - params = {} - if type: - params['type'] = self.RECORD_TYPE_MAP[type] - if name: - params['host'] = name - if data: - params['data'] = data - - if extra: - if extra.get('ttl'): - params['ttl'] = extra['ttl'] - if extra.get('refresh'): - params['refresh'] = extra['refresh'] - if extra.get('retry'): - params['retry'] = extra['retry'] - if extra.get('expire'): - params['expire'] = extra['expire'] - if extra.get('priority'): - params['mxPriority'] = extra['priority'] - - response = self.connection.request( - 'SoftLayer_Dns_Domain_ResourceRecord', - 'editObject', - params, - id=record.id, - ).object - - if response: - changed_record = self.connection.request( - 'SoftLayer_Dns_Domain_ResourceRecord', - 'getObject', - id=record.id, - ).object - return self._to_record(changed_record, zone=record.zone) - else: - return False - - def _to_zone(self, item): - ttl = item.get('ttl', 3600) - zone = Zone(id=item['id'], domain=item['name'], - type='master', ttl=ttl, driver=self) - return zone - - def _to_record(self, item, zone=None): - extra = { - 'ttl': item['ttl'], - 'expire': item['expire'], - 'mxPriority': item['mxPriority'], - 'refresh': item['refresh'], - 'retry': item['retry'], - } - record = Record( - id=item['id'], - name=item['host'], - type=self._string_to_record_type(item['type']), - data=item['data'], - zone=zone, - driver=self, - ttl=item['ttl'], - extra=extra - ) - return record
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/vultr.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/vultr.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/vultr.py deleted file mode 100644 index f04407f..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/vultr.py +++ /dev/null @@ -1,388 +0,0 @@ -# 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. -""" -Vultr DNS Driver -""" - -from libcloud.utils.py3 import urlencode -from libcloud.common.vultr import VultrConnection, VultrResponse -from libcloud.dns.base import DNSDriver, Zone, Record -from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError -from libcloud.dns.types import ZoneAlreadyExistsError, RecordAlreadyExistsError -from libcloud.dns.types import Provider, RecordType - - -__all__ = [ - 'ZoneRequiredException', - 'VultrDNSResponse', - 'VultrDNSConnection', - 'VultrDNSDriver', -] - - -class ZoneRequiredException(Exception): - pass - - -class VultrDNSResponse(VultrResponse): - pass - - -class VultrDNSConnection(VultrConnection): - responseCls = VultrDNSResponse - - -class VultrDNSDriver(DNSDriver): - - type = Provider.VULTR - name = 'Vultr DNS' - website = 'http://www.vultr.com/' - connectionCls = VultrDNSConnection - - RECORD_TYPE_MAP = { - - RecordType.A: 'A', - RecordType.AAAA: 'AAAA', - RecordType.TXT: 'TXT', - RecordType.CNAME: 'CNAME', - RecordType.MX: 'MX', - RecordType.NS: 'NS', - RecordType.SRV: 'SRV', - } - - def list_zones(self): - """ - 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` - """ - action = '/v1/dns/list' - params = {'api_key': self.key} - response = self.connection.request(action=action, - params=params) - zones = self._to_zones(response.objects[0]) - - return zones - - def list_records(self, zone): - """ - Returns a list of records for the provided zone. - - :param zone: zone to list records for - :type zone: `Zone` - - :rtype: list of :class: `Record` - """ - if not isinstance(zone, Zone): - raise ZoneRequiredException('zone should be of type Zone') - - zones = self.list_zones() - - if not self.ex_zone_exists(zone.domain, zones): - raise ZoneDoesNotExistError(value='', driver=self, - zone_id=zone.domain) - - action = '/v1/dns/records' - params = {'domain': zone.domain} - response = self.connection.request(action=action, - params=params) - records = self._to_records(response.objects[0], zone=zone) - - return records - - def get_zone(self, zone_id): - """ - Returns a `Zone` instance. - - :param zone_id: name of the zone user wants to get. - :type zone_id: ``str`` - - :rtype: :class:`Zone` - """ - ret_zone = None - - action = '/v1/dns/list' - params = {'api_key': self.key} - response = self.connection.request(action=action, - params=params) - zones = self._to_zones(response.objects[0]) - - if not self.ex_zone_exists(zone_id, zones): - raise ZoneDoesNotExistError(value=None, zone_id=zone_id, - driver=self) - - for zone in zones: - if zone_id == zone.domain: - ret_zone = zone - - return ret_zone - - def get_record(self, zone_id, record_id): - """ - Returns a Record instance. - - :param zone_id: name of the required zone - :type zone_id: ``str`` - - :param record_id: ID of the required record - :type record_id: ``str`` - - :rtype: :class: `Record` - """ - ret_record = None - zone = self.get_zone(zone_id=zone_id) - records = self.list_records(zone=zone) - - if not self.ex_record_exists(record_id, records): - raise RecordDoesNotExistError(value='', driver=self, - record_id=record_id) - - for record in records: - if record_id == record.id: - ret_record = record - - return ret_record - - def create_zone(self, domain, type='master', ttl=None, extra=None): - """ - Returns a `Zone` object. - - :param domain: Zone domain name, (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: (optional) Extra attributes (driver specific). - (e.g. {'serverip':'127.0.0.1'}) - """ - extra = extra or {} - if extra and extra.get('serverip'): - serverip = extra['serverip'] - - params = {'api_key': self.key} - data = urlencode({'domain': domain, 'serverip': serverip}) - action = '/v1/dns/create_domain' - zones = self.list_zones() - if self.ex_zone_exists(domain, zones): - raise ZoneAlreadyExistsError(value='', driver=self, - zone_id=domain) - - self.connection.request(params=params, action=action, data=data, - method='POST') - zone = Zone(id=domain, domain=domain, type=type, ttl=ttl, - driver=self, extra=extra) - - 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 (driver specific). (optional) - :type extra: ``dict`` - - :rtype: :class:`Record` - """ - extra = extra or {} - - ret_record = None - old_records_list = self.list_records(zone=zone) - # check if record already exists - # if exists raise RecordAlreadyExistsError - for record in old_records_list: - if record.name == name and record.data == data: - raise RecordAlreadyExistsError(value='', driver=self, - record_id=record.id) - - MX = self.RECORD_TYPE_MAP.get('MX') - SRV = self.RECORD_TYPE_MAP.get('SRV') - - if extra and extra.get('priority'): - priority = int(extra['priority']) - - post_data = {'domain': zone.domain, 'name': name, - 'type': self.RECORD_TYPE_MAP.get(type), 'data': data} - - if type == MX or type == SRV: - post_data['priority'] = priority - - encoded_data = urlencode(post_data) - params = {'api_key': self.key} - action = '/v1/dns/create_record' - - self.connection.request(action=action, params=params, - data=encoded_data, method='POST') - updated_zone_records = zone.list_records() - - for record in updated_zone_records: - if record.name == name and record.data == data: - ret_record = record - - return ret_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`` - """ - action = '/v1/dns/delete_domain' - params = {'api_key': self.key} - data = urlencode({'domain': zone.domain}) - zones = self.list_zones() - if not self.ex_zone_exists(zone.domain, zones): - raise ZoneDoesNotExistError(value='', driver=self, - zone_id=zone.domain) - - response = self.connection.request(params=params, action=action, - data=data, method='POST') - - return response.status == 200 - - def delete_record(self, record): - """ - Delete a record. - - :param record: Record to delete. - :type record: :class:`Record` - - :rtype: ``bool`` - """ - action = '/v1/dns/delete_record' - params = {'api_key': self.key} - data = urlencode({'RECORDID': record.id, - 'domain': record.zone.domain}) - - zone_records = self.list_records(record.zone) - if not self.ex_record_exists(record.id, zone_records): - raise RecordDoesNotExistError(value='', driver=self, - record_id=record.id) - - response = self.connection.request(action=action, params=params, - data=data, method='POST') - - return response.status == 200 - - def ex_zone_exists(self, zone_id, zones_list): - """ - Function to check if a `Zone` object exists. - - :param zone_id: Name of the `Zone` object. - :type zone_id: ``str`` - - :param zones_list: A list containing `Zone` objects - :type zones_list: ``list`` - - :rtype: Returns `True` or `False` - """ - - zone_ids = [] - for zone in zones_list: - zone_ids.append(zone.domain) - - return zone_id in zone_ids - - def ex_record_exists(self, record_id, records_list): - """ - :param record_id: Name of the `Record` object. - :type record_id: ``str`` - - :param records_list: A list containing `Record` objects - :type records_list: ``list`` - - :rtype: ``bool`` - """ - record_ids = [] - for record in records_list: - record_ids.append(record.id) - - return record_id in record_ids - - def _to_zone(self, item): - """ - Build an object `Zone` from the item dictionary - - :param item: item to build the zone from - :type item: `dictionary` - - :rtype: :instance: `Zone` - """ - type = 'master' - extra = {'date_created': item['date_created']} - - zone = Zone(id=item['domain'], domain=item['domain'], driver=self, - type=type, ttl=None, extra=extra) - - return zone - - def _to_zones(self, items): - """ - Returns a list of `Zone` objects. - - :param: items: a list that contains dictionary objects to be passed - to the _to_zone function. - :type items: ``list`` - """ - zones = [] - for item in items: - zones.append(self._to_zone(item)) - - return zones - - def _to_record(self, item, zone): - extra = {} - - if item.get('priority'): - extra['priority'] = item['priority'] - - type = self._string_to_record_type(item['type']) - record = Record(id=item['RECORDID'], name=item['name'], type=type, - data=item['data'], zone=zone, driver=self, extra=extra) - - return record - - def _to_records(self, items, zone): - records = [] - for item in items: - records.append(self._to_record(item, zone=zone)) - - return records http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/worldwidedns.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/worldwidedns.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/worldwidedns.py deleted file mode 100644 index 8b0f90c..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/worldwidedns.py +++ /dev/null @@ -1,536 +0,0 @@ -# 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. -""" -World Wide DNS Driver -""" - -__all__ = [ - 'WorldWideDNSDriver' -] - -import re - -from libcloud.common.types import LibcloudError -from libcloud.common.worldwidedns import WorldWideDNSConnection -from libcloud.dns.types import Provider, RecordType -from libcloud.dns.types import ZoneDoesNotExistError -from libcloud.dns.types import RecordError -from libcloud.dns.types import RecordDoesNotExistError -from libcloud.dns.base import DNSDriver, Zone, Record - - -MAX_RECORD_ENTRIES = 40 # Maximum record entries for zone - - -class WorldWideDNSError(LibcloudError): - - def __repr__(self): - return ("<WorldWideDNSError in " + - repr(self.driver) + - " " + - repr(self.value) + ">") - - -class WorldWideDNSDriver(DNSDriver): - type = Provider.WORLDWIDEDNS - name = 'World Wide DNS' - website = 'https://www.worldwidedns.net/' - connectionCls = WorldWideDNSConnection - - RECORD_TYPE_MAP = { - RecordType.MX: 'MX', - RecordType.CNAME: 'CNAME', - RecordType.A: 'A', - RecordType.NS: 'NS', - RecordType.SRV: 'SRV', - RecordType.TXT: 'TXT', - } - - def __init__(self, key, secret=None, reseller_id=None, secure=True, - host=None, port=None, **kwargs): - """ - :param key: API key or username to used (required) - :type key: ``str`` - - :param secret: Secret password to be used (required) - :type secret: ``str`` - - :param reseller_id: Reseller ID for reseller accounts - :type reseller_id: ``str`` - - :param secure: Whether to use HTTPS or HTTP. Note: Some providers - only support HTTPS, and it is on by default. - :type secure: ``bool`` - - :param host: Override hostname used for connections. - :type host: ``str`` - - :param port: Override port used for connections. - :type port: ``int`` - - :return: ``None`` - """ - super(WorldWideDNSDriver, self).__init__(key=key, secret=secret, - secure=secure, host=host, - port=port, **kwargs) - self.reseller_id = reseller_id - - def list_zones(self): - """ - Return a list of zones. - - :return: ``list`` of :class:`Zone` - - For more info, please see: - https://www.worldwidedns.net/dns_api_protocol_list.asp - or - https://www.worldwidedns.net/dns_api_protocol_list_reseller.asp - """ - action = '/api_dns_list.asp' - if self.reseller_id is not None: - action = '/api_dns_list_reseller.asp' - zones = self.connection.request(action) - if len(zones.body) == 0: - return [] - else: - return self._to_zones(zones.body) - - def iterate_records(self, zone): - """ - Return a generator to iterate over records for the provided zone. - - :param zone: Zone to list records for. - :type zone: :class:`Zone` - - :rtype: ``generator`` of :class:`Record` - """ - records = self._to_records(zone) - for record in records: - yield record - - 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` - """ - zones = self.list_zones() - zone = [zone for zone in zones if zone.id == zone_id] - if len(zone) == 0: - raise ZoneDoesNotExistError(driver=self, - value="The zone doesn't exists", - zone_id=zone_id) - return zone[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 number of the required record. - :type record_id: ``str`` - - :rtype: :class:`Record` - """ - zone = self.get_zone(zone_id) - 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, - ex_raw=False): - """ - Update en existing zone. - - :param zone: Zone to update. - :type zone: :class:`Zone` - - :param domain: Zone domain name (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 (driver specific) (optional). Values not - specified such as *SECURE*, *IP*, *FOLDER*, *HOSTMASTER*, - *REFRESH*, *RETRY* and *EXPIRE* will be kept as already - is. The same will be for *S(1 to 40)*, *T(1 to 40)* and - *D(1 to 40)* if not in raw mode and for *ZONENS* and - *ZONEDATA* if it is. - :type extra: ``dict`` - - :param ex_raw: Mode we use to do the update using zone file or not. - :type ex_raw: ``bool`` - - :rtype: :class:`Zone` - - For more info, please see - https://www.worldwidedns.net/dns_api_protocol_list_domain.asp - or - https://www.worldwidedns.net/dns_api_protocol_list_domain_raw.asp - or - https://www.worldwidedns.net/dns_api_protocol_list_domain_reseller.asp - or - https://www.worldwidedns.net/dns_api_protocol_list_domain_raw_reseller.asp - """ - if extra is not None: - not_specified = [key for key in zone.extra.keys() if key not in - extra.keys()] - else: - not_specified = zone.extra.keys() - - if ttl is None: - ttl = zone.ttl - - params = {'DOMAIN': domain, - 'TTL': ttl} - - for key in not_specified: - params[key] = zone.extra[key] - if extra is not None: - params.update(extra) - if ex_raw: - action = '/api_dns_modify_raw.asp' - if self.reseller_id is not None: - action = '/api_dns_modify_raw_reseller.asp' - method = 'POST' - else: - action = '/api_dns_modify.asp' - if self.reseller_id is not None: - action = '/api_dns_modify_reseller.asp' - method = 'GET' - response = self.connection.request(action, params=params, # noqa - method=method) - 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 (MX, CNAME, A, NS, SRV, TXT). - :type type: :class:`RecordType` - - :param data: Data for the record (depends on the record type). - :type data: ``str`` - - :param extra: Contains 'entry' Entry position (1 thru 40) - :type extra: ``dict`` - - :rtype: :class:`Record` - """ - if (extra is None) or ('entry' not in extra): - raise WorldWideDNSError(value="You must enter 'entry' parameter", - driver=self) - 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' % 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, record_id) - return record - - def create_zone(self, domain, type='master', ttl=None, extra=None): - """ - Create a new zone. - - :param domain: Zone domain name (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 (driver specific). (optional). Possible - parameter in here should be *DYN* which values should be - 1 for standart and 2 for dynamic. Default is 1. - :type extra: ``dict`` - - :rtype: :class:`Zone` - - For more info, please see - https://www.worldwidedns.net/dns_api_protocol_new_domain.asp - or - https://www.worldwidedns.net/dns_api_protocol_new_domain_reseller.asp - """ - if type == 'master': - _type = 0 - elif type == 'slave': - _type = 1 - if extra: - dyn = extra.get('DYN') or 1 - else: - dyn = 1 - params = {'DOMAIN': domain, - 'TYPE': _type} - action = '/api_dns_new_domain.asp' - if self.reseller_id is not None: - params['DYN'] = dyn - action = '/api_dns_new_domain_reseller.asp' - self.connection.request(action, params=params) - zone = self.get_zone(domain) - if ttl is not None: - zone = self.update_zone(zone, zone.domain, ttl=ttl) - return zone - - 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 - argument. - :type name: ``str`` - - :param zone: Zone where the requested record is created. - :type zone: :class:`Zone` - - :param type: DNS record type (MX, CNAME, A, NS, SRV, TXT). - :type type: :class:`RecordType` - - :param data: Data for the record (depends on the record type). - :type data: ``str`` - - :param extra: Contains 'entry' Entry position (1 thru 40) - :type extra: ``dict`` - - :rtype: :class:`Record` - """ - if (extra is None) or ('entry' not in extra): - # 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=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, record_id) - 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`` - - For more information, please see - https://www.worldwidedns.net/dns_api_protocol_delete_domain.asp - or - https://www.worldwidedns.net/dns_api_protocol_delete_domain_reseller.asp - """ - params = {'DOMAIN': zone.domain} - action = '/api_dns_delete_domain.asp' - if self.reseller_id is not None: - action = '/api_dns_delete_domain_reseller.asp' - response = self.connection.request(action, params=params) - return response.success() - - def delete_record(self, record): - """ - Delete a record. - - :param record: Record to delete. - :type record: :class:`Record` - - :rtype: ``bool`` - """ - zone = record.zone - for index in range(MAX_RECORD_ENTRIES): - if record.name == zone.extra['S%s' % (index + 1)]: - entry = index + 1 - break - extra = {'S%s' % entry: '', - 'T%s' % entry: 'NONE', - 'D%s' % entry: ''} - self.update_zone(zone, zone.domain, extra=extra) - return True - - def ex_view_zone(self, domain, name_server): - """ - View zone file from a name server - - :param domain: Domain name. - :type domain: ``str`` - - :param name_server: Name server to check. (1, 2 or 3) - :type name_server: ``int`` - - :rtype: ``str`` - - For more info, please see: - https://www.worldwidedns.net/dns_api_protocol_viewzone.asp - or - https://www.worldwidedns.net/dns_api_protocol_viewzone_reseller.asp - """ - params = {'DOMAIN': domain, - 'NS': name_server} - action = '/api_dns_viewzone.asp' - if self.reseller_id is not None: - action = '/api_dns_viewzone_reseller.asp' - response = self.connection.request(action, params=params) - return response.object - - def ex_transfer_domain(self, domain, user_id): - """ - This command will allow you, if you are a reseller, to change the - userid on a domain name to another userid in your account ONLY if that - new userid is already created. - - :param domain: Domain name. - :type domain: ``str`` - - :param user_id: The new userid to connect to the domain name. - :type user_id: ``str`` - - :rtype: ``bool`` - - For more info, please see: - https://www.worldwidedns.net/dns_api_protocol_transfer.asp - """ - if self.reseller_id is None: - raise WorldWideDNSError("This is not a reseller account", - driver=self) - params = {'DOMAIN': domain, - 'NEW_ID': user_id} - response = self.connection.request('/api_dns_transfer.asp', - 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 = [] - for line in domain_list: - zone = self._to_zone(line) - zones.append(zone) - - return zones - - def _to_zone(self, line): - data = line.split('\x1f') - name = data[0] - if data[1] == "P": - type = "master" - domain_data = self._get_domain_data(name) - resp_lines = re.split('\r?\n', domain_data.body) - soa_block = resp_lines[:6] - zone_data = resp_lines[6:] - extra = {'HOSTMASTER': soa_block[0], 'REFRESH': soa_block[1], - 'RETRY': soa_block[2], 'EXPIRE': soa_block[3], - 'SECURE': soa_block[5]} - ttl = soa_block[4] - for line in range(MAX_RECORD_ENTRIES): - line_data = zone_data[line].split('\x1f') - extra['S%s' % (line + 1)] = line_data[0] - _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: - extra['D%s' % (line + 1)] = '' - elif data[1] == 'S': - type = 'slave' - extra = {} - ttl = 0 - return Zone(id=name, domain=name, type=type, - ttl=ttl, driver=self, extra=extra) - - def _get_domain_data(self, name): - params = {'DOMAIN': name} - data = self.connection.request('/api_dns_list_domain.asp', - params=params) - return data - - def _to_records(self, zone): - records = [] - 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( - record_id, subdomain, type, data, zone) - records.append(record) - return records - - def _to_record(self, _id, subdomain, type, data, zone): - return Record(id=_id, name=subdomain, type=type, data=data, zone=zone, - driver=zone.driver) http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zerigo.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zerigo.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zerigo.py deleted file mode 100644 index dacdd75..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zerigo.py +++ /dev/null @@ -1,484 +0,0 @@ -# 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. - -__all__ = [ - 'ZerigoDNSDriver' -] - - -import copy -import base64 - -from libcloud.utils.py3 import httplib -from libcloud.utils.py3 import b - -try: - from lxml import etree as ET -except ImportError: - from xml.etree import ElementTree as ET - -from libcloud.utils.misc import merge_valid_keys, get_new_obj -from libcloud.utils.xml import findtext, findall -from libcloud.common.base import XmlResponse, ConnectionUserAndKey -from libcloud.common.types import InvalidCredsError, LibcloudError -from libcloud.common.types import MalformedResponseError -from libcloud.dns.types import Provider, RecordType -from libcloud.dns.types import ZoneDoesNotExistError, RecordDoesNotExistError -from libcloud.dns.base import DNSDriver, Zone, Record - -API_HOST = 'ns.zerigo.com' -API_VERSION = '1.1' -API_ROOT = '/api/%s/' % (API_VERSION) - -VALID_ZONE_EXTRA_PARAMS = ['notes', 'tag-list', 'ns1', 'slave-nameservers'] -VALID_RECORD_EXTRA_PARAMS = ['notes', 'ttl', 'priority'] - -# Number of items per page (maximum limit is 1000) -ITEMS_PER_PAGE = 100 - - -class ZerigoError(LibcloudError): - def __init__(self, code, errors): - self.code = code - self.errors = errors or [] - - def __str__(self): - return 'Errors: %s' % (', '.join(self.errors)) - - def __repr__(self): - return ('<ZerigoError response code=%s, errors count=%s>' % ( - self.code, len(self.errors))) - - -class ZerigoDNSResponse(XmlResponse): - def success(self): - return self.status in [httplib.OK, httplib.CREATED, httplib.ACCEPTED] - - def parse_error(self): - status = int(self.status) - - if status == 401: - if not self.body: - raise InvalidCredsError(str(self.status) + ': ' + self.error) - else: - raise InvalidCredsError(self.body) - elif status == 404: - context = self.connection.context - if context['resource'] == 'zone': - raise ZoneDoesNotExistError(value='', driver=self, - zone_id=context['id']) - elif context['resource'] == 'record': - raise RecordDoesNotExistError(value='', driver=self, - record_id=context['id']) - elif status != 503: - try: - body = ET.XML(self.body) - except: - raise MalformedResponseError('Failed to parse XML', - body=self.body) - - errors = [] - for error in findall(element=body, xpath='error'): - errors.append(error.text) - - raise ZerigoError(code=status, errors=errors) - - return self.body - - -class ZerigoDNSConnection(ConnectionUserAndKey): - host = API_HOST - secure = True - responseCls = ZerigoDNSResponse - - def add_default_headers(self, headers): - auth_b64 = base64.b64encode(b('%s:%s' % (self.user_id, self.key))) - headers['Authorization'] = 'Basic %s' % (auth_b64.decode('utf-8')) - return headers - - def request(self, action, params=None, data='', headers=None, - method='GET'): - if not headers: - headers = {} - if not params: - params = {} - - if method in ("POST", "PUT"): - headers = {'Content-Type': 'application/xml; charset=UTF-8'} - return super(ZerigoDNSConnection, self).request(action=action, - params=params, - data=data, - method=method, - headers=headers) - - -class ZerigoDNSDriver(DNSDriver): - type = Provider.ZERIGO - name = 'Zerigo DNS' - website = 'http://www.zerigo.com/' - connectionCls = ZerigoDNSConnection - - RECORD_TYPE_MAP = { - RecordType.A: 'A', - RecordType.AAAA: 'AAAA', - RecordType.CNAME: 'CNAME', - RecordType.GEO: 'GEO', - RecordType.MX: 'MX', - RecordType.NAPTR: 'NAPTR', - RecordType.NS: 'NS', - RecordType.PTR: 'PTR', - RecordType.REDIRECT: 'REDIRECT', - RecordType.SPF: 'SPF', - RecordType.SRV: 'SRV', - RecordType.TXT: 'TXT', - RecordType.URL: 'URL', - } - - def iterate_zones(self): - return self._get_more('zones') - - def iterate_records(self, zone): - return self._get_more('records', zone=zone) - - def get_zone(self, zone_id): - path = API_ROOT + 'zones/%s.xml' % (zone_id) - self.connection.set_context({'resource': 'zone', 'id': zone_id}) - data = self.connection.request(path).object - zone = self._to_zone(elem=data) - return zone - - def get_record(self, zone_id, record_id): - zone = self.get_zone(zone_id=zone_id) - self.connection.set_context({'resource': 'record', 'id': record_id}) - path = API_ROOT + 'hosts/%s.xml' % (record_id) - data = self.connection.request(path).object - record = self._to_record(elem=data, zone=zone) - return record - - def create_zone(self, domain, type='master', ttl=None, extra=None): - """ - Create a new zone. - - Provider API docs: - https://www.zerigo.com/docs/apis/dns/1.1/zones/create - - @inherits: :class:`DNSDriver.create_zone` - """ - path = API_ROOT + 'zones.xml' - zone_elem = self._to_zone_elem(domain=domain, type=type, ttl=ttl, - extra=extra) - data = self.connection.request(action=path, - data=ET.tostring(zone_elem), - method='POST').object - zone = self._to_zone(elem=data) - return zone - - def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None): - """ - Update an existing zone. - - Provider API docs: - https://www.zerigo.com/docs/apis/dns/1.1/zones/update - - @inherits: :class:`DNSDriver.update_zone` - """ - if domain: - raise LibcloudError('Domain cannot be changed', driver=self) - - path = API_ROOT + 'zones/%s.xml' % (zone.id) - zone_elem = self._to_zone_elem(domain=domain, type=type, ttl=ttl, - extra=extra) - response = self.connection.request(action=path, - data=ET.tostring(zone_elem), - method='PUT') - assert response.status == httplib.OK - - merged = merge_valid_keys(params=copy.deepcopy(zone.extra), - valid_keys=VALID_ZONE_EXTRA_PARAMS, - extra=extra) - updated_zone = get_new_obj(obj=zone, klass=Zone, - attributes={'type': type, - 'ttl': ttl, - 'extra': merged}) - return updated_zone - - def create_record(self, name, zone, type, data, extra=None): - """ - Create a new record. - - Provider API docs: - https://www.zerigo.com/docs/apis/dns/1.1/hosts/create - - @inherits: :class:`DNSDriver.create_record` - """ - path = API_ROOT + 'zones/%s/hosts.xml' % (zone.id) - record_elem = self._to_record_elem(name=name, type=type, data=data, - extra=extra) - response = self.connection.request(action=path, - data=ET.tostring(record_elem), - method='POST') - assert response.status == httplib.CREATED - record = self._to_record(elem=response.object, zone=zone) - return record - - def update_record(self, record, name=None, type=None, data=None, - extra=None): - path = API_ROOT + 'hosts/%s.xml' % (record.id) - record_elem = self._to_record_elem(name=name, type=type, data=data, - extra=extra) - response = self.connection.request(action=path, - data=ET.tostring(record_elem), - method='PUT') - assert response.status == httplib.OK - - merged = merge_valid_keys(params=copy.deepcopy(record.extra), - valid_keys=VALID_RECORD_EXTRA_PARAMS, - extra=extra) - updated_record = get_new_obj(obj=record, klass=Record, - attributes={'type': type, - 'data': data, - 'extra': merged}) - return updated_record - - def delete_zone(self, zone): - path = API_ROOT + 'zones/%s.xml' % (zone.id) - self.connection.set_context({'resource': 'zone', 'id': zone.id}) - response = self.connection.request(action=path, method='DELETE') - return response.status == httplib.OK - - def delete_record(self, record): - path = API_ROOT + 'hosts/%s.xml' % (record.id) - self.connection.set_context({'resource': 'record', 'id': record.id}) - response = self.connection.request(action=path, method='DELETE') - return response.status == httplib.OK - - def ex_get_zone_by_domain(self, domain): - """ - Retrieve a zone object by the domain name. - - :param domain: The domain which should be used - :type domain: ``str`` - - :rtype: :class:`Zone` - """ - path = API_ROOT + 'zones/%s.xml' % (domain) - self.connection.set_context({'resource': 'zone', 'id': domain}) - data = self.connection.request(path).object - zone = self._to_zone(elem=data) - return zone - - def ex_force_slave_axfr(self, zone): - """ - Force a zone transfer. - - :param zone: Zone which should be used. - :type zone: :class:`Zone` - - :rtype: :class:`Zone` - """ - path = API_ROOT + 'zones/%s/force_slave_axfr.xml' % (zone.id) - self.connection.set_context({'resource': 'zone', 'id': zone.id}) - response = self.connection.request(path, method='POST') - assert response.status == httplib.ACCEPTED - return zone - - def _to_zone_elem(self, domain=None, type=None, ttl=None, extra=None): - zone_elem = ET.Element('zone', {}) - - if domain: - domain_elem = ET.SubElement(zone_elem, 'domain') - domain_elem.text = domain - - if type: - ns_type_elem = ET.SubElement(zone_elem, 'ns-type') - - if type == 'master': - ns_type_elem.text = 'pri_sec' - elif type == 'slave': - if not extra or 'ns1' not in extra: - raise LibcloudError('ns1 extra attribute is required ' + - 'when zone type is slave', driver=self) - - ns_type_elem.text = 'sec' - ns1_elem = ET.SubElement(zone_elem, 'ns1') - ns1_elem.text = extra['ns1'] - elif type == 'std_master': - # TODO: Each driver should provide supported zone types - # Slave name servers are elsewhere - if not extra or 'slave-nameservers' not in extra: - raise LibcloudError('slave-nameservers extra ' + - 'attribute is required whenzone ' + - 'type is std_master', driver=self) - - ns_type_elem.text = 'pri' - slave_nameservers_elem = ET.SubElement(zone_elem, - 'slave-nameservers') - slave_nameservers_elem.text = extra['slave-nameservers'] - - if ttl: - default_ttl_elem = ET.SubElement(zone_elem, 'default-ttl') - default_ttl_elem.text = str(ttl) - - if extra and 'tag-list' in extra: - tags = extra['tag-list'] - - tags_elem = ET.SubElement(zone_elem, 'tag-list') - tags_elem.text = ' '.join(tags) - - return zone_elem - - def _to_record_elem(self, name=None, type=None, data=None, extra=None): - record_elem = ET.Element('host', {}) - - if name: - name_elem = ET.SubElement(record_elem, 'hostname') - name_elem.text = name - - if type is not None: - type_elem = ET.SubElement(record_elem, 'host-type') - type_elem.text = self.RECORD_TYPE_MAP[type] - - if data: - data_elem = ET.SubElement(record_elem, 'data') - data_elem.text = data - - if extra: - if 'ttl' in extra: - ttl_elem = ET.SubElement(record_elem, 'ttl', - {'type': 'integer'}) - ttl_elem.text = str(extra['ttl']) - - if 'priority' in extra: - # Only MX and SRV records support priority - priority_elem = ET.SubElement(record_elem, 'priority', - {'type': 'integer'}) - - priority_elem.text = str(extra['priority']) - - if 'notes' in extra: - notes_elem = ET.SubElement(record_elem, 'notes') - notes_elem.text = extra['notes'] - - return record_elem - - def _to_zones(self, elem): - zones = [] - - for item in findall(element=elem, xpath='zone'): - zone = self._to_zone(elem=item) - zones.append(zone) - - return zones - - def _to_zone(self, elem): - id = findtext(element=elem, xpath='id') - domain = findtext(element=elem, xpath='domain') - type = findtext(element=elem, xpath='ns-type') - type = 'master' if type.find('pri') == 0 else 'slave' - ttl = findtext(element=elem, xpath='default-ttl') - - hostmaster = findtext(element=elem, xpath='hostmaster') - custom_ns = findtext(element=elem, xpath='custom-ns') - custom_nameservers = findtext(element=elem, xpath='custom-nameservers') - notes = findtext(element=elem, xpath='notes') - nx_ttl = findtext(element=elem, xpath='nx-ttl') - slave_nameservers = findtext(element=elem, xpath='slave-nameservers') - tags = findtext(element=elem, xpath='tag-list') - tags = tags.split(' ') if tags else [] - - extra = {'hostmaster': hostmaster, 'custom-ns': custom_ns, - 'custom-nameservers': custom_nameservers, 'notes': notes, - 'nx-ttl': nx_ttl, 'slave-nameservers': slave_nameservers, - 'tags': tags} - zone = Zone(id=str(id), domain=domain, type=type, ttl=int(ttl), - driver=self, extra=extra) - return zone - - def _to_records(self, elem, zone): - records = [] - - for item in findall(element=elem, xpath='host'): - record = self._to_record(elem=item, zone=zone) - records.append(record) - - return records - - def _to_record(self, elem, zone): - id = findtext(element=elem, xpath='id') - name = findtext(element=elem, xpath='hostname') - type = findtext(element=elem, xpath='host-type') - type = self._string_to_record_type(type) - data = findtext(element=elem, xpath='data') - - notes = findtext(element=elem, xpath='notes', no_text_value=None) - state = findtext(element=elem, xpath='state', no_text_value=None) - fqdn = findtext(element=elem, xpath='fqdn', no_text_value=None) - priority = findtext(element=elem, xpath='priority', no_text_value=None) - ttl = findtext(element=elem, xpath='ttl', no_text_value=None) - - if not name: - name = None - - if ttl: - ttl = int(ttl) - - extra = {'notes': notes, 'state': state, 'fqdn': fqdn, - 'priority': priority, 'ttl': ttl} - - record = Record(id=id, name=name, type=type, data=data, - zone=zone, driver=self, ttl=ttl, extra=extra) - return record - - def _get_more(self, rtype, **kwargs): - exhausted = False - last_key = None - - while not exhausted: - items, last_key, exhausted = self._get_data(rtype, last_key, - **kwargs) - - for item in items: - yield item - - def _get_data(self, rtype, last_key, **kwargs): - # Note: last_key in this case really is a "last_page". - # TODO: Update base driver and change last_key to something more - # generic - e.g. marker - params = {} - params['per_page'] = ITEMS_PER_PAGE - params['page'] = last_key + 1 if last_key else 1 - - if rtype == 'zones': - path = API_ROOT + 'zones.xml' - response = self.connection.request(path) - transform_func = self._to_zones - elif rtype == 'records': - zone = kwargs['zone'] - path = API_ROOT + 'zones/%s/hosts.xml' % (zone.id) - self.connection.set_context({'resource': 'zone', 'id': zone.id}) - response = self.connection.request(path, params=params) - transform_func = self._to_records - - exhausted = False - result_count = int(response.headers.get('x-query-count', 0)) - - if (params['page'] * ITEMS_PER_PAGE) >= result_count: - exhausted = True - - if response.status == httplib.OK: - items = transform_func(elem=response.object, **kwargs) - return items, params['page'], exhausted - else: - return [], None, True http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zonomi.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zonomi.py b/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zonomi.py deleted file mode 100644 index 003de6d..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/dns/drivers/zonomi.py +++ /dev/null @@ -1,351 +0,0 @@ -# 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. -""" -Zonomi DNS Driver -""" -import sys - -from libcloud.common.zonomi import ZonomiConnection, ZonomiResponse -from libcloud.common.zonomi import ZonomiException -from libcloud.dns.base import DNSDriver, Zone, Record -from libcloud.dns.types import ZoneDoesNotExistError, ZoneAlreadyExistsError -from libcloud.dns.types import RecordAlreadyExistsError -from libcloud.dns.types import RecordDoesNotExistError -from libcloud.dns.types import Provider, RecordType - - -__all__ = [ - 'ZonomiDNSDriver', -] - - -class ZonomiDNSResponse(ZonomiResponse): - pass - - -class ZonomiDNSConnection(ZonomiConnection): - responseCls = ZonomiDNSResponse - - -class ZonomiDNSDriver(DNSDriver): - type = Provider.ZONOMI - name = 'Zonomi DNS' - website = 'https://zonomi.com' - connectionCls = ZonomiDNSConnection - - RECORD_TYPE_MAP = { - RecordType.A: 'A', - RecordType.MX: 'MX', - RecordType.TXT: 'TXT' - } - - def list_zones(self): - """ - Return a list of zones. - - :return: ``list`` of :class:`Zone` - """ - action = '/app/dns/dyndns.jsp?' - params = {'action': 'QUERYZONES', 'api_key': self.key} - - response = self.connection.request(action=action, params=params) - zones = self._to_zones(response.objects) - - 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` - """ - action = '/app/dns/dyndns.jsp?' - params = {'action': 'QUERY', 'name': '**.' + zone.id} - try: - response = self.connection.request(action=action, params=params) - except ZonomiException: - e = sys.exc_info()[1] - if e.code == '404': - raise ZoneDoesNotExistError(zone_id=zone.id, driver=self, - value=e.message) - raise e - - records = self._to_records(response.objects, zone) - - 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` - """ - zone = None - zones = self.list_zones() - for z in zones: - if z.id == zone_id: - zone = z - - if zone is None: - raise ZoneDoesNotExistError(zone_id=zone_id, driver=self, value='') - - return zone - - 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` - """ - record = None - zone = self.get_zone(zone_id=zone_id) - records = self.list_records(zone=zone) - - for r in records: - if r.id == record_id: - record = r - - if record is None: - raise RecordDoesNotExistError(record_id=record_id, driver=self, - value='') - - return record - - def create_zone(self, domain, type='master', ttl=None, extra=None): - """ - Create a new zone. - - :param zone_id: Zone domain name (e.g. example.com) - :type zone_id: ``str`` - - :rtype: :class:`Zone` - """ - action = '/app/dns/addzone.jsp?' - params = {'name': domain} - try: - self.connection.request(action=action, params=params) - except ZonomiException: - e = sys.exc_info()[1] - if e.message == 'ERROR: This zone is already in your zone list.': - raise ZoneAlreadyExistsError(zone_id=domain, driver=self, - value=e.message) - raise e - - zone = Zone(id=domain, domain=domain, type='master', ttl=ttl, - driver=self, extra=extra) - 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, MX, TXT). - :type type: :class:`RecordType` - - :param data: Data for the record (depends on the record type). - :type data: ``str`` - - :param extra: Extra attributes (driver specific, e.g. 'prio' or 'ttl'). - (optional) - :type extra: ``dict`` - - :rtype: :class:`Record` - """ - action = '/app/dns/dyndns.jsp?' - if name: - record_name = name + '.' + zone.domain - else: - record_name = zone.domain - params = {'action': 'SET', 'name': record_name, 'value': data, - 'type': type} - - if type == 'MX' and extra is not None: - params['prio'] = extra.get('prio') - try: - response = self.connection.request(action=action, params=params) - except ZonomiException: - e = sys.exc_info()[1] - if ('ERROR: No zone found for %s' % record_name) in e.message: - raise ZoneDoesNotExistError(zone_id=zone.id, driver=self, - value=e.message) - raise e - - # we determine if an A or MX record already exists - # by looking at the response.If the key 'skipped' is present in the - # response, it means record already exists. If this is True, - # then raise RecordAlreadyExistsError - if len(response.objects) != 0 and \ - response.objects[0].get('skipped') == 'unchanged': - raise RecordAlreadyExistsError(record_id=name, driver=self, - value='') - - if 'DELETED' in response.objects: - for el in response.objects[:2]: - if el.get('content') == data: - response.objects = [el] - records = self._to_records(response.objects, zone=zone) - return records[0] - - 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`` - """ - action = '/app/dns/dyndns.jsp?' - params = {'action': 'DELETEZONE', 'name': zone.id} - try: - response = self.connection.request(action=action, params=params) - except ZonomiException: - e = sys.exc_info()[1] - if e.code == '404': - raise ZoneDoesNotExistError(zone_id=zone.id, driver=self, - value=e.message) - raise e - - return 'DELETED' in response.objects - - def delete_record(self, record): - """ - Use this method to delete a record. - - :param record: record to delete - :type record: `Record` - - :rtype: Bool - """ - action = '/app/dns/dyndns.jsp?' - params = {'action': 'DELETE', 'name': record.name, 'type': record.type} - try: - response = self.connection.request(action=action, params=params) - except ZonomiException: - e = sys.exc_info()[1] - if e.message == 'Record not deleted.': - raise RecordDoesNotExistError(record_id=record.id, driver=self, - value=e.message) - raise e - - return 'DELETED' in response.objects - - def ex_convert_to_secondary(self, zone, master): - """ - Convert existent zone to slave. - - :param zone: Zone to convert. - :type zone: :class:`Zone` - - :param master: the specified master name server IP address. - :type master: ``str`` - - :rtype: Bool - """ - action = '/app/dns/converttosecondary.jsp?' - params = {'name': zone.domain, 'master': master} - try: - self.connection.request(action=action, params=params) - except ZonomiException: - e = sys.exc_info()[1] - if 'ERROR: Could not find' in e.message: - raise ZoneDoesNotExistError(zone_id=zone.id, driver=self, - value=e.message) - return True - - def ex_convert_to_master(self, zone): - """ - Convert existent zone to master. - - :param zone: Zone to convert. - :type zone: :class:`Zone` - - :rtype: Bool - """ - action = '/app/dns/converttomaster.jsp?' - params = {'name': zone.domain} - try: - self.connection.request(action=action, params=params) - except ZonomiException: - e = sys.exc_info()[1] - if 'ERROR: Could not find' in e.message: - raise ZoneDoesNotExistError(zone_id=zone.id, driver=self, - value=e.message) - return True - - def _to_zone(self, item): - if item['type'] == 'NATIVE': - type = 'master' - elif item['type'] == 'SLAVE': - type = 'slave' - zone = Zone(id=item['name'], domain=item['name'], type=type, - driver=self, extra={}, ttl=None) - - 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): - if len(item.get('ttl')) > 0: - ttl = item.get('ttl').split(' ')[0] - else: - ttl = None - extra = {'ttl': ttl, - 'prio': item.get('prio')} - if len(item['name']) > len(zone.domain): - full_domain = item['name'] - index = full_domain.index('.' + zone.domain) - record_name = full_domain[:index] - else: - record_name = zone.domain - record = Record(id=record_name, name=record_name, - data=item['content'], type=item['type'], zone=zone, - driver=self, ttl=ttl, extra=extra) - - return record - - def _to_records(self, items, zone): - records = [] - for item in items: - records.append(self._to_record(item, zone)) - - return records http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/providers.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/providers.py b/apache-libcloud-1.0.0rc2/libcloud/dns/providers.py deleted file mode 100644 index ad55385..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/dns/providers.py +++ /dev/null @@ -1,93 +0,0 @@ -# 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. - -from libcloud.dns.types import Provider -from libcloud.dns.types import OLD_CONSTANT_TO_NEW_MAPPING -from libcloud.common.providers import get_driver as _get_provider_driver -from libcloud.common.providers import set_driver as _set_provider_driver - -__all__ = [ - 'DRIVERS', - - 'get_driver', - 'set_driver' -] - -DRIVERS = { - Provider.DUMMY: - ('libcloud.dns.drivers.dummy', 'DummyDNSDriver'), - Provider.LINODE: - ('libcloud.dns.drivers.linode', 'LinodeDNSDriver'), - Provider.ZERIGO: - ('libcloud.dns.drivers.zerigo', 'ZerigoDNSDriver'), - Provider.RACKSPACE: - ('libcloud.dns.drivers.rackspace', 'RackspaceDNSDriver'), - Provider.HOSTVIRTUAL: - ('libcloud.dns.drivers.hostvirtual', 'HostVirtualDNSDriver'), - Provider.ROUTE53: - ('libcloud.dns.drivers.route53', 'Route53DNSDriver'), - Provider.GANDI: - ('libcloud.dns.drivers.gandi', 'GandiDNSDriver'), - Provider.GOOGLE: ('libcloud.dns.drivers.google', 'GoogleDNSDriver'), - Provider.SOFTLAYER: - ('libcloud.dns.drivers.softlayer', 'SoftLayerDNSDriver'), - Provider.DIGITAL_OCEAN: - ('libcloud.dns.drivers.digitalocean', 'DigitalOceanDNSDriver'), - Provider.WORLDWIDEDNS: - ('libcloud.dns.drivers.worldwidedns', 'WorldWideDNSDriver'), - Provider.DNSIMPLE: - ('libcloud.dns.drivers.dnsimple', 'DNSimpleDNSDriver'), - Provider.POINTDNS: - ('libcloud.dns.drivers.pointdns', 'PointDNSDriver'), - Provider.VULTR: - ('libcloud.dns.drivers.vultr', 'VultrDNSDriver'), - Provider.LIQUIDWEB: - ('libcloud.dns.drivers.liquidweb', 'LiquidWebDNSDriver'), - Provider.ZONOMI: - ('libcloud.dns.drivers.zonomi', 'ZonomiDNSDriver'), - Provider.DURABLEDNS: - ('libcloud.dns.drivers.durabledns', 'DurableDNSDriver'), - Provider.AURORADNS: - ('libcloud.dns.drivers.auroradns', 'AuroraDNSDriver'), - Provider.GODADDY: - ('libcloud.dns.drivers.godaddy', 'GoDaddyDNSDriver'), - Provider.CLOUDFLARE: - ('libcloud.dns.drivers.cloudflare', 'CloudFlareDNSDriver'), - Provider.NFSN: - ('libcloud.dns.drivers.nfsn', 'NFSNDNSDriver'), - Provider.NSONE: - ('libcloud.dns.drivers.nsone', 'NsOneDNSDriver'), - Provider.LUADNS: - ('libcloud.dns.drivers.luadns', 'LuadnsDNSDriver'), - Provider.BUDDYNS: - ('libcloud.dns.drivers.buddyns', 'BuddyNSDNSDriver'), - - # Deprecated - Provider.RACKSPACE_US: - ('libcloud.dns.drivers.rackspace', 'RackspaceUSDNSDriver'), - Provider.RACKSPACE_UK: - ('libcloud.dns.drivers.rackspace', 'RackspaceUKDNSDriver') -} - - -def get_driver(provider): - deprecated_constants = OLD_CONSTANT_TO_NEW_MAPPING - return _get_provider_driver(drivers=DRIVERS, provider=provider, - deprecated_constants=deprecated_constants) - - -def set_driver(provider, module, klass): - return _set_provider_driver(drivers=DRIVERS, provider=provider, - module=module, klass=klass) http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/dns/types.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/dns/types.py b/apache-libcloud-1.0.0rc2/libcloud/dns/types.py deleted file mode 100644 index 35994e7..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/dns/types.py +++ /dev/null @@ -1,141 +0,0 @@ -# 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. - -from libcloud.common.types import LibcloudError - -__all__ = [ - 'Provider', - 'RecordType', - 'ZoneError', - 'ZoneDoesNotExistError', - 'ZoneAlreadyExistsError', - 'RecordError', - 'RecordDoesNotExistError', - 'RecordAlreadyExistsError', - - 'OLD_CONSTANT_TO_NEW_MAPPING' -] - - -class Provider(object): - DUMMY = 'dummy' - AURORADNS = 'auroradns' - BUDDYNS = 'buddyns' - CLOUDFLARE = 'cloudflare' - DIGITAL_OCEAN = 'digitalocean' - DNSIMPLE = 'dnsimple' - DURABLEDNS = 'durabledns' - GANDI = 'gandi' - GODADDY = 'godaddy' - GOOGLE = 'google' - HOSTVIRTUAL = 'hostvirtual' - LINODE = 'linode' - LIQUIDWEB = 'liquidweb' - LUADNS = 'luadns' - NFSN = 'nfsn' - NSONE = 'nsone' - POINTDNS = 'pointdns' - RACKSPACE = 'rackspace' - ROUTE53 = 'route53' - SOFTLAYER = 'softlayer' - VULTR = 'vultr' - WORLDWIDEDNS = 'worldwidedns' - ZERIGO = 'zerigo' - ZONOMI = 'zonomi' - # Deprecated - RACKSPACE_US = 'rackspace_us' - RACKSPACE_UK = 'rackspace_uk' - - -OLD_CONSTANT_TO_NEW_MAPPING = { - Provider.RACKSPACE_US: Provider.RACKSPACE, - Provider.RACKSPACE_UK: Provider.RACKSPACE, -} - - -class RecordType(object): - """ - DNS record type. - """ - A = 'A' - AAAA = 'AAAA' - ALIAS = 'ALIAS' - CNAME = 'CNAME' - DNAME = 'DNAME' - GEO = 'GEO' - HINFO = 'HINFO' - LOC = 'LOC' - MX = 'MX' - NAPTR = 'NAPTR' - NS = 'NS' - PTR = 'PTR' - REDIRECT = 'REDIRECT' - RP = 'RP' - SOA = 'SOA' - SPF = 'SPF' - SRV = 'SRV' - SSHFP = 'SSHFP' - TXT = 'TXT' - URL = 'URL' - WKS = 'WKS' - - -class ZoneError(LibcloudError): - error_type = 'ZoneError' - kwargs = ('zone_id', ) - - def __init__(self, value, driver, zone_id): - self.zone_id = zone_id - super(ZoneError, self).__init__(value=value, driver=driver) - - def __str__(self): - return self.__repr__() - - def __repr__(self): - return ('<%s in %s, zone_id=%s, value=%s>' % - (self.error_type, repr(self.driver), - self.zone_id, self.value)) - - -class ZoneDoesNotExistError(ZoneError): - error_type = 'ZoneDoesNotExistError' - - -class ZoneAlreadyExistsError(ZoneError): - error_type = 'ZoneAlreadyExistsError' - - -class RecordError(LibcloudError): - error_type = 'RecordError' - - def __init__(self, value, driver, record_id): - self.record_id = record_id - super(RecordError, self).__init__(value=value, driver=driver) - - def __str__(self): - return self.__repr__() - - def __repr__(self): - return ('<%s in %s, record_id=%s, value=%s>' % - (self.error_type, repr(self.driver), - self.record_id, self.value)) - - -class RecordDoesNotExistError(RecordError): - error_type = 'RecordDoesNotExistError' - - -class RecordAlreadyExistsError(RecordError): - error_type = 'RecordAlreadyExistsError'
