Added support for the GoDaddy driver to purchase domains, list records, add and update records, cancel domains, check availability, validate purchase requests
Signed-off-by: Anthony Shaw <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/a3d1103c Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/a3d1103c Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/a3d1103c Branch: refs/heads/trunk Commit: a3d1103cdee285ba53827d2db0dbf9496b584f9a Parents: 7b38ce3 Author: Anthony Shaw <[email protected]> Authored: Fri Nov 27 14:28:23 2015 +1100 Committer: Anthony Shaw <[email protected]> Committed: Fri Nov 27 17:30:11 2015 +1100 ---------------------------------------------------------------------- libcloud/dns/drivers/godaddy.py | 369 ++++- .../test/dns/fixtures/godaddy/v1_domains.json | 77 + .../v1_domains_aperture_platform_com.json | 86 ++ ...1_domains_aperture_platform_com_records.json | 88 ++ ...ins_aperture_platform_com_records_A_www.json | 8 + .../fixtures/godaddy/v1_domains_available.json | 7 + .../godaddy/v1_domains_purchase_schema_com.json | 432 ++++++ .../dns/fixtures/godaddy/v1_domains_tlds.json | 1326 ++++++++++++++++++ libcloud/test/dns/test_godaddy.py | 139 ++ libcloud/test/secrets.py-dist | 1 + 10 files changed, 2495 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/dns/drivers/godaddy.py ---------------------------------------------------------------------- diff --git a/libcloud/dns/drivers/godaddy.py b/libcloud/dns/drivers/godaddy.py index ce1ae7d..55587ab 100644 --- a/libcloud/dns/drivers/godaddy.py +++ b/libcloud/dns/drivers/godaddy.py @@ -51,23 +51,16 @@ class GoDaddyDNSResponse(JsonResponse): def parse_body(self): if not self.body: return None + # json.loads doesn't like the regex expressions used in godaddy schema + self.body = self.body.replace('\\.', '\\\\.') data = json.loads(self.body) return data def parse_error(self): data = self.parse_body() - - if self.status == httplib.UNAUTHORIZED: - raise GoDaddyDNSException('%(code)s:%(message)s' % (data['error'])) - elif self.status == httplib.PRECONDITION_FAILED: - raise GoDaddyDNSException( - data['error']['code'], data['error']['message']) - elif self.status == httplib.NOT_FOUND: - raise GoDaddyDNSException( - data['error']['code'], data['error']['message']) - - return self.body + raise GoDaddyDNSException( + data['code'], data['message']) def success(self): return self.status in self.valid_response_codes @@ -82,11 +75,8 @@ class GoDaddyDNSConnection(ConnectionKey): def __init__(self, key, secret, shopper_id, secure=True, host=None, port=None, url=None, timeout=None, proxy_url=None, backoff=None, retry_delay=None): - """ - Initialize `user_id` and `key`; set `secure` to an ``int`` based on - passed value. - """ super(GoDaddyDNSConnection, self).__init__( + key, secure=secure, host=host, port=port, url=url, timeout=timeout, @@ -105,6 +95,13 @@ class GoDaddyDNSConnection(ConnectionKey): class GoDaddyDNSDriver(DNSDriver): + """ + A driver for GoDaddy DNS. + + This is for customers of GoDaddy + who wish to purchase, update existing domains + and manage records for DNS zones owned by GoDaddy NS servers. + """ type = Provider.GODADDY name = 'GoDaddy DNS' website = 'https://www.godaddy.com/' @@ -122,10 +119,22 @@ class GoDaddyDNSDriver(DNSDriver): def __init__(self, shopper_id, key, secret, secure=True, host=None, port=None): + """ + Instantiate a new `GoDaddyDNSDriver` + + :param shopper_id: Your customer ID or shopped ID with GoDaddy + :type shopper_id: `str` + + :param key: Your access key from developer.godaddy.com + :type key: `str` + + :param secret: Your access key secret + :type secret: `str` + """ super(GoDaddyDNSDriver, self).__init__(key=key, secret=secret, secure=secure, host=host, port=port, - shopper_id=shopper_id) + shopper_id=str(shopper_id)) def _to_zones(self, items): zones = [] @@ -134,13 +143,9 @@ class GoDaddyDNSDriver(DNSDriver): return zones def _to_zone(self, item): - extra = {} - if 'records' in item: - extra['records'] = item['records'] - if item['type'] == 'NATIVE': - item['type'] = 'master' - zone = Zone(id=item['id'], domain=item['name'], - type=item['type'], ttl=item['ttl'], + extra = {"expires": item['expires']} + zone = Zone(id=item['domainId'], domain=item['domain'], + type='master', ttl=None, driver=self, extra=extra) return zone @@ -152,41 +157,329 @@ class GoDaddyDNSDriver(DNSDriver): return records def _to_record(self, item, zone=None): - extra = {'ttl': item['ttl']} + ttl = item['ttl'] type = self._string_to_record_type(item['type']) - name = item['name'][:-len(zone.domain) - 1] - record = Record(id=item['id'], name=name, - type=type, data=item['content'], - zone=zone, driver=self, extra=extra) + name = item['name'] + id = '{0}:{1}'.format(name, type) + record = Record(id=id, name=name, + type=type, data=item['data'], + zone=zone, driver=self, + extra={'ttl': ttl}) return record + def _to_tlds(self, items): + tlds = [] + for item in items: + tlds.append(self._to_tld(item)) + return tlds + + def _to_tld(self, item): + return GoDaddyTLD( + name=item['name'], + tld_type=item['type'] + ) + def list_zones(self): + """ + Return a list of zones (purchased domains) + + :return: ``list`` of :class:`Zone` + """ result = self.connection.request( '/v1/domains/').object zones = self._to_zones(result) 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` + """ result = self.connection.request( - '/v1/domains/%s/records' % zone.id).object + '/v1/domains/%s/records' % zone.domain).object records = self._to_records(items=result, zone=zone) return records + 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` + """ + if extra is None: + extra = {} + new_record = {} + if type is RecordType.SRV: + new_record = { + 'type': type, + 'name': name, + 'data': data, + 'priority': 1, + 'ttl': extra['ttl'] if hasattr(extra, 'ttl') else 5, + 'service': extra['service'] + if hasattr(extra, 'service') else '', + 'protocol': extra['protocol'] + if hasattr(extra, 'protocol') else '', + 'port': extra['port'] + if hasattr(extra, 'port') else '', + 'weight': extra['weight'] + if hasattr(extra, 'weight') else '' + } + else: + new_record = { + 'type': type, + 'name': name, + 'data': data, + 'priority': 1, + 'ttl': extra['ttl'] if hasattr(extra, 'ttl') else 5 + } + self.connection.request( + '/v1/domains/{0}/records'.format( + zone.domain), method='PATCH', + data=[new_record]) + id = '{0}:{1}'.format(name, type) + return Record( + id=id, name=name, + type=type, data=data, + zone=zone, driver=self, + extra=extra) + + 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` + """ + if extra is None: + extra = {} + new_record = {} + if type is RecordType.SRV: + new_record = { + 'type': type, + 'name': name, + 'data': data, + 'priority': 1, + 'ttl': extra['ttl'] if hasattr(extra, 'ttl') else 5, + 'service': extra['service'] + if hasattr(extra, 'service') else '', + 'protocol': extra['protocol'] + if hasattr(extra, 'protocol') else '', + 'port': extra['port'] + if hasattr(extra, 'port') else '', + 'weight': extra['weight'] + if hasattr(extra, 'weight') else '' + } + else: + new_record = { + 'type': type, + 'name': name, + 'data': data, + 'priority': 1, + 'ttl': extra['ttl'] if hasattr(extra, 'ttl') else 5 + } + self.connection.request( + '/v1/domains/{0}/records'.format( + record.zone.domain), method='PUT', + data=[new_record]) + id = '{0}:{1}'.format(name, type) + return Record( + id=id, name=name, + type=type, data=data, + zone=record.zone, driver=self, + extra=extra) + + 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` + """ + parts = record_id.split(':') + result = self.connection.request( + '/v1/domains/{0}/records/{1}/{2}'.format( + zone_id, + parts[1], + parts[0])).object + if len(result) is 0: + raise GoDaddyDNSException("Could not locate record") + return self._to_record(result[0], + self.get_zone(zone_id)) + def get_zone(self, zone_id): + """ + Get a zone (by domain) + + :param zone_id: The domain, not the ID + :type zone_id: `str` + + :rtype: :class:`Zone` + """ result = self.connection.request( '/v1/domains/%s/' % zone_id).object zone = self._to_zone(result) return zone - def get_record(self, zone_id, record_type, record_name): + def delete_zone(self, zone): + """ + Delete a zone. + + Note: This will CANCEL a purchased domain + + :param zone: Zone to delete. + :type zone: :class:`Zone` + + :rtype: ``bool`` + """ + self.connection.request( + '/v1/domains/%s' % zone.domain, + method='DELETE') + # no error means ok + return True + + def ex_check_availability(self, domain, for_transfer=False): + """ + Check the availability of the domain + + :param domain: the domain name e.g. wazzlewobbleflooble.com + :type domain: `str` + + :param for_transfer: Check if domain is available for transfer + :type for_transfer: `bool` + + :rtype: `list` of :class:`GoDaddyAvailability` + """ result = self.connection.request( - '/v1/domains/%s/record/%s/%s' % (zone_id, record_type, record_name)) - record = self._to_record(item=result.object, - zone=self.get_zone(zone_id)) - return record + '/v1/domains/available', + method='GET', + params={ + 'domain': domain, + 'forTransfer': str(for_transfer) + } + ).object + return GoDaddyAvailability( + domain=result['domain'], + available=result['available'], + price=result['price'], + currency=result['currency'], + period=result['period'] + ) + + def ex_list_tlds(self): + """ + List available TLDs for sale - def delete_zone(self, zone): + :rtype: `list` of `GoDaddyTLD` + """ + result = self.connection.request( + '/v1/domains/tlds', + method='GET' + ).object + return self._to_tlds(result) + + def ex_get_purchase_schema(self, tld): + """ + Get the schema that needs completing to purchase a new domain + Use this in conjunction with ex_purchase_domain + + :param tld: The top level domain e.g com, eu, uk + :type tld: `str` + + :rtype: `dict` the JSON Schema + """ + result = self.connection.request( + '/v1/domains/purchase/schema/{0}'.format(tld), + method='GET' + ).object + return result + + def ex_purchase_domain(self, purchase_request): + """ + Purchase a domain with GoDaddy + + :param purchase_request: The completed document + from ex_get_purchase_schema + :type purchase_request: `dict` + + :rtype: :class:`GoDaddyDomainPurchaseResponse` Your order + """ result = self.connection.request( - '/v1/domains/%s' % zone.id, - method='DELETE').object - return bool(result) + '/v1/domains/purchase', + data=purchase_request, + method='POST' + ).object + return GoDaddyDomainPurchaseResponse( + order_id=result['orderId'], + item_count=result['itemCount'], + total=result['total'], + currency=result['currency'] + ) + + +class GoDaddyAvailability(object): + def __init__(self, domain, available, price, currency, period): + self.domain = domain + self.available = bool(available) + # currency comes in micro-units, convert to dollars. + self.price = float(price) / 1000000 + self.currency = currency + self.period = int(period) + + +class GoDaddyTLD(object): + def __init__(self, name, tld_type): + self.name = name + self.type = tld_type + + +class GoDaddyDomainPurchaseResponse(object): + def __init__(self, order_id, item_count, total, currency): + self.order_id = order_id + self.item_count = item_count + self.total = total + self.current = currency http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/test/dns/fixtures/godaddy/v1_domains.json ---------------------------------------------------------------------- diff --git a/libcloud/test/dns/fixtures/godaddy/v1_domains.json b/libcloud/test/dns/fixtures/godaddy/v1_domains.json new file mode 100644 index 0000000..64fa1ca --- /dev/null +++ b/libcloud/test/dns/fixtures/godaddy/v1_domains.json @@ -0,0 +1,77 @@ +[ + { + "domainId": 177184419, + "domain": "aperture-platform.com", + "status": "ACTIVE", + "expires": "2016-09-25T19:29:32Z", + "expirationProtected": false, + "holdRegistrar": false, + "limited": false, + "locked": true, + "privacy": false, + "renewAuto": true, + "renewable": true, + "smart": false, + "transferProtected": false + }, + { + "domainId": 203342445, + "domain": "dd-innovation-days.com", + "status": "ACTIVE", + "expires": "2016-11-15T20:10:17Z", + "expirationProtected": false, + "holdRegistrar": false, + "limited": false, + "locked": true, + "privacy": false, + "renewAuto": true, + "renewable": true, + "smart": false, + "transferProtected": false + }, + { + "domainId": 183117834, + "domain": "givesourcing.com", + "status": "ACTIVE", + "expires": "2017-01-01T19:00:40Z", + "expirationProtected": false, + "holdRegistrar": false, + "limited": false, + "locked": true, + "privacy": false, + "renewAuto": true, + "renewable": true, + "smart": false, + "transferProtected": false + }, + { + "domainId": 200411864, + "domain": "service-layer.com", + "status": "ACTIVE", + "expires": "2018-09-30T18:22:00Z", + "expirationProtected": false, + "holdRegistrar": false, + "limited": false, + "locked": true, + "privacy": false, + "renewAuto": true, + "renewable": true, + "smart": false, + "transferProtected": false + }, + { + "domainId": 183221633, + "domain": "sourcewise.org", + "status": "ACTIVE", + "expires": "2017-01-04T04:02:07Z", + "expirationProtected": false, + "holdRegistrar": false, + "limited": false, + "locked": true, + "privacy": false, + "renewAuto": true, + "renewable": true, + "smart": false, + "transferProtected": false + } +] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com.json ---------------------------------------------------------------------- diff --git a/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com.json b/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com.json new file mode 100644 index 0000000..4e47db6 --- /dev/null +++ b/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com.json @@ -0,0 +1,86 @@ +{ + "domainId": 177184419, + "domain": "aperture-platform.com", + "status": "ACTIVE", + "expires": "2016-09-25T19:29:32Z", + "expirationProtected": false, + "holdRegistrar": false, + "limited": false, + "locked": true, + "privacy": false, + "renewAuto": true, + "renewable": true, + "renewDeadline": "2016-11-09T19:29:32Z", + "smart": false, + "transferProtected": false, + "createdAt": "2014-09-25T19:29:32Z", + "authCode": "nowayamiputtingthishere", + "nameServers": [ + "ns25.domaincontrol.com", + "ns26.domaincontrol.com" + ], + "contactRegistrant": { + "nameFirst": "Anthony", + "nameLast": "Shaw", + "organization": "DIMENSION DATA Cloud Solutions Australia", + "email": "[email protected]", + "phone": 61.414529701, + "fax": "", + "addressMailing": { + "address1": "3 Richardson Place", + "address2": "", + "city": "North Ryde", + "state": "New South Wales", + "postalCode": 2113, + "country": "AU" + } + }, + "contactBilling": { + "nameFirst": "Anthony", + "nameLast": "Shaw", + "organization": "DIMENSION DATA Cloud Solutions Australia", + "email": "[email protected]", + "phone": 61.414529701, + "fax": "", + "addressMailing": { + "address1": "3 Richardson Place", + "address2": "", + "city": "North Ryde", + "state": "New South Wales", + "postalCode": 2113, + "country": "AU" + } + }, + "contactAdmin": { + "nameFirst": "Anthony", + "nameLast": "Shaw", + "organization": "DIMENSION DATA Cloud Solutions Australia", + "email": "[email protected]", + "phone": 61.414529701, + "fax": "", + "addressMailing": { + "address1": "3 Richardson Place", + "address2": "", + "city": "North Ryde", + "state": "New South Wales", + "postalCode": 2113, + "country": "AU" + } + }, + "contactTech": { + "nameFirst": "Anthony", + "nameLast": "Shaw", + "organization": "DIMENSION DATA Cloud Solutions Australia", + "email": "[email protected]", + "phone": 61.414529701, + "fax": "", + "addressMailing": { + "address1": "3 Richardson Place", + "address2": "", + "city": "North Ryde", + "state": "New South Wales", + "postalCode": 2113, + "country": "AU" + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com_records.json ---------------------------------------------------------------------- diff --git a/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com_records.json b/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com_records.json new file mode 100644 index 0000000..65bf86f --- /dev/null +++ b/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com_records.json @@ -0,0 +1,88 @@ +[ + { + "type": "A", + "name": "@", + "data": "50.63.202.42", + "ttl": 600 + }, + { + "type": "A", + "name": "mercury", + "data": "197.96.19.72", + "ttl": 3600 + }, + { + "type": "A", + "name": "secure", + "data": "175.184.215.248", + "ttl": 3600 + }, + { + "type": "A", + "name": "manga", + "data": "175.184.205.28", + "ttl": 3600 + }, + { + "type": "CNAME", + "name": "email", + "data": "email.secureserver.net", + "ttl": 3600 + }, + { + "type": "CNAME", + "name": "ftp", + "data": "@", + "ttl": 3600 + }, + { + "type": "CNAME", + "name": "www", + "data": "@", + "ttl": 3600 + }, + { + "type": "MX", + "name": "@", + "data": "mailstore1.secureserver.net", + "priority": 10, + "ttl": 3600 + }, + { + "type": "MX", + "name": "@", + "data": "smtp.secureserver.net", + "priority": 0, + "ttl": 3600 + }, + { + "type": "TXT", + "name": "@", + "data": "MS=ms30628878", + "ttl": 3600 + }, + { + "type": "AAAA", + "name": "wazzle", + "data": "2607:f480:111:1336:6503:544c:74a6:3a28", + "ttl": 3600 + }, + { + "type": "AAAA", + "name": "flerg", + "data": "2607:f480:111:1336:6503:544c:74a6:3a28", + "ttl": 3600 + }, + { + "type": "NS", + "name": "@", + "data": "ns25.domaincontrol.com", + "ttl": 3600 + }, + { + "type": "NS", + "name": "@", + "data": "ns26.domaincontrol.com", + "ttl": 3600 + } +] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com_records_A_www.json ---------------------------------------------------------------------- diff --git a/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com_records_A_www.json b/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com_records_A_www.json new file mode 100644 index 0000000..14d1251 --- /dev/null +++ b/libcloud/test/dns/fixtures/godaddy/v1_domains_aperture_platform_com_records_A_www.json @@ -0,0 +1,8 @@ +[ + { + "type": "A", + "name": "www", + "data": "50.63.202.42", + "ttl": 600 + } +] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/test/dns/fixtures/godaddy/v1_domains_available.json ---------------------------------------------------------------------- diff --git a/libcloud/test/dns/fixtures/godaddy/v1_domains_available.json b/libcloud/test/dns/fixtures/godaddy/v1_domains_available.json new file mode 100644 index 0000000..3210b86 --- /dev/null +++ b/libcloud/test/dns/fixtures/godaddy/v1_domains_available.json @@ -0,0 +1,7 @@ +{ + "price": 14990000, + "currency": "USD", + "period": 1, + "available": true, + "domain": "wazzlewobbleflooble.com" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/test/dns/fixtures/godaddy/v1_domains_purchase_schema_com.json ---------------------------------------------------------------------- diff --git a/libcloud/test/dns/fixtures/godaddy/v1_domains_purchase_schema_com.json b/libcloud/test/dns/fixtures/godaddy/v1_domains_purchase_schema_com.json new file mode 100644 index 0000000..91025a6 --- /dev/null +++ b/libcloud/test/dns/fixtures/godaddy/v1_domains_purchase_schema_com.json @@ -0,0 +1,432 @@ +{ + "id": "https://api.godaddy.com/DomainPurchase#", + "additionalProperties": false, + "properties": { + "domain": { + "type": "string", + "format": "domain", + "pattern": "^[^.]{1,63}(\.[^.]{2,}){1,2}$" + }, + "consent": { + "$ref": "https://api.godaddy.com/DomainPurchase#/definitions/Consent" + }, + "period": { + "type": "integer", + "format": "integer-positive", + "defaultValue": 1, + "minimum": 1, + "maximum": 10, + "pattern": "[1]?[0-9]" + }, + "renewAuto": { + "type": "boolean", + "defaultValue": true + }, + "privacy": { + "type": "boolean", + "defaultValue": false + }, + "nameServers": { + "type": "array", + "items": { + "format": "host-name", + "pattern": "([^.]+\.)*[^.]+\.[^.]+", + "type": "string" + }, + "minItems": 0, + "maxItems": 13 + }, + "contactAdmin": { + "$ref": "https://api.godaddy.com/DomainPurchase#/definitions/Contact" + }, + "contactBilling": { + "$ref": "https://api.godaddy.com/DomainPurchase#/definitions/Contact" + }, + "contactRegistrant": { + "$ref": "https://api.godaddy.com/DomainPurchase#/definitions/Contact" + }, + "contactTech": { + "$ref": "https://api.godaddy.com/DomainPurchase#/definitions/Contact" + } + }, + "required": [ + "domain", + "consent", + "contactAdmin", + "contactBilling", + "contactRegistrant", + "contactTech" + ], + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "Consent": { + "id": "Consent", + "additionalProperties": false, + "properties": { + "agreementKeys": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Unique identifiers of the legal agreements to which the end-user has agreed, as returned from the/domains/agreements endpoint" + }, + "agreedBy": { + "type": "string", + "description": "Originating client IP address of the end-user's computer when they consented to these legal agreements" + }, + "agreedAt": { + "type": "string", + "format": "iso-datetime", + "description": "Timestamp indicating when the end-user consented to these legal agreements" + } + }, + "required": [ + "agreementKeys", + "agreedBy", + "agreedAt" + ] + }, + "Contact": { + "id": "Contact", + "additionalProperties": false, + "properties": { + "nameFirst": { + "type": "string", + "format": "person-name", + "maxLength": 30 + }, + "nameMiddle": { + "type": "string" + }, + "nameLast": { + "type": "string", + "format": "person-name", + "maxLength": 30 + }, + "organization": { + "type": "string", + "format": "organization-name", + "maxLength": 100 + }, + "jobTitle": { + "type": "string" + }, + "email": { + "type": "string", + "format": "email", + "maxLength": 80 + }, + "phone": { + "type": "string", + "format": "phone", + "maxLength": 17 + }, + "fax": { + "type": "string", + "format": "phone", + "maxLength": 17 + }, + "addressMailing": { + "$ref": "https://api.godaddy.com/DomainPurchase#/definitions/Address" + } + }, + "required": [ + "nameFirst", + "nameLast", + "email", + "phone", + "addressMailing" + ] + }, + "Address": { + "id": "Address", + "additionalProperties": false, + "properties": { + "address1": { + "type": "string", + "format": "street-address", + "maxLength": 41 + }, + "address2": { + "type": "string", + "format": "street-address2", + "maxLength": 41 + }, + "city": { + "type": "string", + "format": "city-name", + "maxLength": 30 + }, + "state": { + "type": "string", + "format": "state-province-territory", + "minLength": 2, + "maxLength": 30, + "description": "State or province or territory" + }, + "postalCode": { + "type": "string", + "format": "postal-code", + "minLength": 2, + "maxLength": 10, + "description": "Postal or zip code" + }, + "country": { + "type": "string", + "format": "iso-country-code", + "defaultValue": "US", + "enum": [ + "AD", + "AE", + "AF", + "AG", + "AI", + "AL", + "AM", + "AO", + "AQ", + "AR", + "AS", + "AT", + "AU", + "AW", + "AZ", + "BA", + "BB", + "BD", + "BE", + "BF", + "BG", + "BH", + "BI", + "BJ", + "BM", + "BN", + "BO", + "BQ", + "BR", + "BS", + "BT", + "BV", + "BW", + "BY", + "BZ", + "CA", + "CC", + "CD", + "CF", + "CG", + "CH", + "CI", + "CK", + "CL", + "CM", + "CN", + "CO", + "CR", + "CV", + "CW", + "CX", + "CY", + "CZ", + "DE", + "DJ", + "DK", + "DM", + "DO", + "DZ", + "EC", + "EE", + "EG", + "EH", + "ER", + "ES", + "ET", + "FI", + "FJ", + "FK", + "FM", + "FO", + "FR", + "GA", + "GB", + "GD", + "GE", + "GF", + "GG", + "GH", + "GI", + "GL", + "GM", + "GN", + "GP", + "GQ", + "GR", + "GS", + "GT", + "GU", + "GW", + "GY", + "HK", + "HM", + "HN", + "HR", + "HT", + "HU", + "ID", + "IE", + "IL", + "IM", + "IN", + "IO", + "IQ", + "IS", + "IT", + "JE", + "JM", + "JO", + "JP", + "KE", + "KG", + "KH", + "KI", + "KM", + "KN", + "KR", + "KW", + "KY", + "KZ", + "LA", + "LB", + "LC", + "LI", + "LK", + "LR", + "LS", + "LT", + "LU", + "LV", + "LY", + "MA", + "MC", + "MD", + "ME", + "MG", + "MH", + "MK", + "ML", + "MM", + "MN", + "MO", + "MP", + "MQ", + "MR", + "MS", + "MT", + "MU", + "MV", + "MW", + "MX", + "MY", + "MZ", + "NA", + "NC", + "NE", + "NF", + "NG", + "NI", + "NL", + "NO", + "NP", + "NR", + "NU", + "NZ", + "OM", + "PA", + "PE", + "PF", + "PG", + "PH", + "PK", + "PL", + "PM", + "PN", + "PR", + "PS", + "PT", + "PW", + "PY", + "QA", + "RE", + "RO", + "RS", + "RU", + "RW", + "SA", + "SB", + "SC", + "SE", + "SG", + "SH", + "SI", + "SJ", + "SK", + "SL", + "SM", + "SN", + "SO", + "SR", + "ST", + "SV", + "SX", + "SZ", + "TC", + "TD", + "TF", + "TG", + "TH", + "TJ", + "TK", + "TL", + "TM", + "TN", + "TO", + "TR", + "TT", + "TV", + "TW", + "TZ", + "UA", + "UG", + "UM", + "US", + "UY", + "UZ", + "VA", + "VC", + "VE", + "VG", + "VI", + "VN", + "VU", + "WF", + "WS", + "YE", + "YT", + "ZA", + "ZM", + "ZW" + ], + "description": "Two-letter ISO country code to be used as a hint for target region<br/><br/>\nNOTE: These are sample values, there are many\n<a href='http://www.iso.org/iso/country_codes.htm'>more</a>" + } + }, + "required": [ + "address1", + "city", + "state", + "postalCode", + "country" + ] + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/test/dns/fixtures/godaddy/v1_domains_tlds.json ---------------------------------------------------------------------- diff --git a/libcloud/test/dns/fixtures/godaddy/v1_domains_tlds.json b/libcloud/test/dns/fixtures/godaddy/v1_domains_tlds.json new file mode 100644 index 0000000..ae1d554 --- /dev/null +++ b/libcloud/test/dns/fixtures/godaddy/v1_domains_tlds.json @@ -0,0 +1,1326 @@ +[ + { + "name": "academy", + "type": "GENERIC" + }, + { + "name": "accountants", + "type": "GENERIC" + }, + { + "name": "actor", + "type": "GENERIC" + }, + { + "name": "ag", + "type": "COUNTRY_CODE" + }, + { + "name": "agency", + "type": "GENERIC" + }, + { + "name": "airforce", + "type": "GENERIC" + }, + { + "name": "am", + "type": "COUNTRY_CODE" + }, + { + "name": "apartments", + "type": "GENERIC" + }, + { + "name": "archi", + "type": "GENERIC" + }, + { + "name": "army", + "type": "GENERIC" + }, + { + "name": "associates", + "type": "GENERIC" + }, + { + "name": "at", + "type": "COUNTRY_CODE" + }, + { + "name": "auction", + "type": "GENERIC" + }, + { + "name": "audio", + "type": "GENERIC" + }, + { + "name": "band", + "type": "GENERIC" + }, + { + "name": "bar", + "type": "GENERIC" + }, + { + "name": "bargains", + "type": "GENERIC" + }, + { + "name": "be", + "type": "COUNTRY_CODE" + }, + { + "name": "beer", + "type": "GENERIC" + }, + { + "name": "best", + "type": "GENERIC" + }, + { + "name": "bid", + "type": "GENERIC" + }, + { + "name": "bike", + "type": "GENERIC" + }, + { + "name": "bingo", + "type": "GENERIC" + }, + { + "name": "bio", + "type": "GENERIC" + }, + { + "name": "biz", + "type": "GENERIC" + }, + { + "name": "black", + "type": "GENERIC" + }, + { + "name": "blackfriday", + "type": "GENERIC" + }, + { + "name": "blue", + "type": "GENERIC" + }, + { + "name": "boutique", + "type": "GENERIC" + }, + { + "name": "build", + "type": "GENERIC" + }, + { + "name": "builders", + "type": "GENERIC" + }, + { + "name": "business", + "type": "GENERIC" + }, + { + "name": "buzz", + "type": "GENERIC" + }, + { + "name": "bz", + "type": "COUNTRY_CODE" + }, + { + "name": "ca", + "type": "COUNTRY_CODE" + }, + { + "name": "cab", + "type": "GENERIC" + }, + { + "name": "camera", + "type": "GENERIC" + }, + { + "name": "camp", + "type": "GENERIC" + }, + { + "name": "capital", + "type": "GENERIC" + }, + { + "name": "cards", + "type": "GENERIC" + }, + { + "name": "care", + "type": "GENERIC" + }, + { + "name": "careers", + "type": "GENERIC" + }, + { + "name": "cash", + "type": "GENERIC" + }, + { + "name": "catering", + "type": "GENERIC" + }, + { + "name": "cc", + "type": "COUNTRY_CODE" + }, + { + "name": "center", + "type": "GENERIC" + }, + { + "name": "ch", + "type": "COUNTRY_CODE" + }, + { + "name": "chat", + "type": "GENERIC" + }, + { + "name": "cheap", + "type": "GENERIC" + }, + { + "name": "christmas", + "type": "GENERIC" + }, + { + "name": "church", + "type": "GENERIC" + }, + { + "name": "city", + "type": "GENERIC" + }, + { + "name": "claims", + "type": "GENERIC" + }, + { + "name": "cleaning", + "type": "GENERIC" + }, + { + "name": "click", + "type": "GENERIC" + }, + { + "name": "clinic", + "type": "GENERIC" + }, + { + "name": "clothing", + "type": "GENERIC" + }, + { + "name": "club", + "type": "GENERIC" + }, + { + "name": "co", + "type": "COUNTRY_CODE" + }, + { + "name": "co.in", + "type": "COUNTRY_CODE" + }, + { + "name": "co.nz", + "type": "COUNTRY_CODE" + }, + { + "name": "co.uk", + "type": "COUNTRY_CODE" + }, + { + "name": "coach", + "type": "GENERIC" + }, + { + "name": "codes", + "type": "GENERIC" + }, + { + "name": "coffee", + "type": "GENERIC" + }, + { + "name": "com", + "type": "GENERIC" + }, + { + "name": "com.ag", + "type": "COUNTRY_CODE" + }, + { + "name": "com.bz", + "type": "COUNTRY_CODE" + }, + { + "name": "com.co", + "type": "COUNTRY_CODE" + }, + { + "name": "com.es", + "type": "COUNTRY_CODE" + }, + { + "name": "com.mx", + "type": "COUNTRY_CODE" + }, + { + "name": "com.ph", + "type": "COUNTRY_CODE" + }, + { + "name": "com.tw", + "type": "COUNTRY_CODE" + }, + { + "name": "community", + "type": "GENERIC" + }, + { + "name": "company", + "type": "GENERIC" + }, + { + "name": "computer", + "type": "GENERIC" + }, + { + "name": "condos", + "type": "GENERIC" + }, + { + "name": "construction", + "type": "GENERIC" + }, + { + "name": "consulting", + "type": "GENERIC" + }, + { + "name": "contractors", + "type": "GENERIC" + }, + { + "name": "cooking", + "type": "GENERIC" + }, + { + "name": "cool", + "type": "GENERIC" + }, + { + "name": "country", + "type": "GENERIC" + }, + { + "name": "credit", + "type": "GENERIC" + }, + { + "name": "creditcard", + "type": "GENERIC" + }, + { + "name": "cruises", + "type": "GENERIC" + }, + { + "name": "cz", + "type": "COUNTRY_CODE" + }, + { + "name": "dance", + "type": "GENERIC" + }, + { + "name": "dating", + "type": "GENERIC" + }, + { + "name": "de", + "type": "COUNTRY_CODE" + }, + { + "name": "deals", + "type": "GENERIC" + }, + { + "name": "degree", + "type": "GENERIC" + }, + { + "name": "delivery", + "type": "GENERIC" + }, + { + "name": "democrat", + "type": "GENERIC" + }, + { + "name": "dental", + "type": "GENERIC" + }, + { + "name": "desi", + "type": "GENERIC" + }, + { + "name": "design", + "type": "GENERIC" + }, + { + "name": "diamonds", + "type": "GENERIC" + }, + { + "name": "diet", + "type": "GENERIC" + }, + { + "name": "digital", + "type": "GENERIC" + }, + { + "name": "direct", + "type": "GENERIC" + }, + { + "name": "directory", + "type": "GENERIC" + }, + { + "name": "discount", + "type": "GENERIC" + }, + { + "name": "domains", + "type": "GENERIC" + }, + { + "name": "education", + "type": "GENERIC" + }, + { + "name": "email", + "type": "GENERIC" + }, + { + "name": "energy", + "type": "GENERIC" + }, + { + "name": "engineer", + "type": "GENERIC" + }, + { + "name": "engineering", + "type": "GENERIC" + }, + { + "name": "enterprises", + "type": "GENERIC" + }, + { + "name": "equipment", + "type": "GENERIC" + }, + { + "name": "es", + "type": "COUNTRY_CODE" + }, + { + "name": "estate", + "type": "GENERIC" + }, + { + "name": "eu", + "type": "COUNTRY_CODE" + }, + { + "name": "events", + "type": "GENERIC" + }, + { + "name": "exchange", + "type": "GENERIC" + }, + { + "name": "expert", + "type": "GENERIC" + }, + { + "name": "exposed", + "type": "GENERIC" + }, + { + "name": "fail", + "type": "GENERIC" + }, + { + "name": "farm", + "type": "GENERIC" + }, + { + "name": "finance", + "type": "GENERIC" + }, + { + "name": "financial", + "type": "GENERIC" + }, + { + "name": "firm.in", + "type": "COUNTRY_CODE" + }, + { + "name": "fish", + "type": "GENERIC" + }, + { + "name": "fishing", + "type": "GENERIC" + }, + { + "name": "fitness", + "type": "GENERIC" + }, + { + "name": "flights", + "type": "GENERIC" + }, + { + "name": "florist", + "type": "GENERIC" + }, + { + "name": "flowers", + "type": "GENERIC" + }, + { + "name": "fm", + "type": "COUNTRY_CODE" + }, + { + "name": "forsale", + "type": "GENERIC" + }, + { + "name": "foundation", + "type": "GENERIC" + }, + { + "name": "fund", + "type": "GENERIC" + }, + { + "name": "furniture", + "type": "GENERIC" + }, + { + "name": "futbol", + "type": "GENERIC" + }, + { + "name": "gallery", + "type": "GENERIC" + }, + { + "name": "gen.in", + "type": "COUNTRY_CODE" + }, + { + "name": "gift", + "type": "GENERIC" + }, + { + "name": "gifts", + "type": "GENERIC" + }, + { + "name": "gives", + "type": "GENERIC" + }, + { + "name": "glass", + "type": "GENERIC" + }, + { + "name": "global", + "type": "GENERIC" + }, + { + "name": "graphics", + "type": "GENERIC" + }, + { + "name": "gratis", + "type": "GENERIC" + }, + { + "name": "green", + "type": "GENERIC" + }, + { + "name": "gripe", + "type": "GENERIC" + }, + { + "name": "gs", + "type": "COUNTRY_CODE" + }, + { + "name": "guide", + "type": "GENERIC" + }, + { + "name": "guitars", + "type": "GENERIC" + }, + { + "name": "guru", + "type": "GENERIC" + }, + { + "name": "haus", + "type": "GENERIC" + }, + { + "name": "healthcare", + "type": "GENERIC" + }, + { + "name": "help", + "type": "GENERIC" + }, + { + "name": "hiphop", + "type": "GENERIC" + }, + { + "name": "hiv", + "type": "GENERIC" + }, + { + "name": "holdings", + "type": "GENERIC" + }, + { + "name": "holiday", + "type": "GENERIC" + }, + { + "name": "horse", + "type": "GENERIC" + }, + { + "name": "host", + "type": "GENERIC" + }, + { + "name": "hosting", + "type": "GENERIC" + }, + { + "name": "house", + "type": "GENERIC" + }, + { + "name": "idv.tw", + "type": "COUNTRY_CODE" + }, + { + "name": "immo", + "type": "GENERIC" + }, + { + "name": "immobilien", + "type": "GENERIC" + }, + { + "name": "in", + "type": "COUNTRY_CODE" + }, + { + "name": "ind.in", + "type": "COUNTRY_CODE" + }, + { + "name": "industries", + "type": "GENERIC" + }, + { + "name": "info", + "type": "GENERIC" + }, + { + "name": "ink", + "type": "GENERIC" + }, + { + "name": "institute", + "type": "GENERIC" + }, + { + "name": "insure", + "type": "GENERIC" + }, + { + "name": "international", + "type": "GENERIC" + }, + { + "name": "investments", + "type": "GENERIC" + }, + { + "name": "juegos", + "type": "GENERIC" + }, + { + "name": "kaufen", + "type": "GENERIC" + }, + { + "name": "kim", + "type": "GENERIC" + }, + { + "name": "kitchen", + "type": "GENERIC" + }, + { + "name": "kiwi", + "type": "GENERIC" + }, + { + "name": "la", + "type": "COUNTRY_CODE" + }, + { + "name": "land", + "type": "GENERIC" + }, + { + "name": "lease", + "type": "GENERIC" + }, + { + "name": "legal", + "type": "GENERIC" + }, + { + "name": "lgbt", + "type": "GENERIC" + }, + { + "name": "life", + "type": "GENERIC" + }, + { + "name": "lighting", + "type": "GENERIC" + }, + { + "name": "limited", + "type": "GENERIC" + }, + { + "name": "limo", + "type": "GENERIC" + }, + { + "name": "link", + "type": "GENERIC" + }, + { + "name": "loans", + "type": "GENERIC" + }, + { + "name": "london", + "type": "GENERIC" + }, + { + "name": "ltda", + "type": "GENERIC" + }, + { + "name": "maison", + "type": "GENERIC" + }, + { + "name": "management", + "type": "GENERIC" + }, + { + "name": "market", + "type": "GENERIC" + }, + { + "name": "marketing", + "type": "GENERIC" + }, + { + "name": "me", + "type": "COUNTRY_CODE" + }, + { + "name": "me.uk", + "type": "COUNTRY_CODE" + }, + { + "name": "media", + "type": "GENERIC" + }, + { + "name": "memorial", + "type": "GENERIC" + }, + { + "name": "menu", + "type": "GENERIC" + }, + { + "name": "mobi", + "type": "GENERIC" + }, + { + "name": "moda", + "type": "GENERIC" + }, + { + "name": "moe", + "type": "GENERIC" + }, + { + "name": "money", + "type": "GENERIC" + }, + { + "name": "mortgage", + "type": "GENERIC" + }, + { + "name": "ms", + "type": "COUNTRY_CODE" + }, + { + "name": "mx", + "type": "COUNTRY_CODE" + }, + { + "name": "nagoya", + "type": "GENERIC" + }, + { + "name": "navy", + "type": "GENERIC" + }, + { + "name": "net", + "type": "GENERIC" + }, + { + "name": "net.ag", + "type": "COUNTRY_CODE" + }, + { + "name": "net.bz", + "type": "COUNTRY_CODE" + }, + { + "name": "net.co", + "type": "COUNTRY_CODE" + }, + { + "name": "net.in", + "type": "COUNTRY_CODE" + }, + { + "name": "net.nz", + "type": "COUNTRY_CODE" + }, + { + "name": "net.ph", + "type": "COUNTRY_CODE" + }, + { + "name": "network", + "type": "GENERIC" + }, + { + "name": "ninja", + "type": "GENERIC" + }, + { + "name": "nl", + "type": "COUNTRY_CODE" + }, + { + "name": "nom.co", + "type": "COUNTRY_CODE" + }, + { + "name": "nom.es", + "type": "COUNTRY_CODE" + }, + { + "name": "nyc", + "type": "GENERIC" + }, + { + "name": "okinawa", + "type": "GENERIC" + }, + { + "name": "onl", + "type": "GENERIC" + }, + { + "name": "org", + "type": "GENERIC" + }, + { + "name": "org.ag", + "type": "COUNTRY_CODE" + }, + { + "name": "org.es", + "type": "COUNTRY_CODE" + }, + { + "name": "org.in", + "type": "COUNTRY_CODE" + }, + { + "name": "org.nz", + "type": "COUNTRY_CODE" + }, + { + "name": "org.ph", + "type": "COUNTRY_CODE" + }, + { + "name": "org.tw", + "type": "COUNTRY_CODE" + }, + { + "name": "org.uk", + "type": "COUNTRY_CODE" + }, + { + "name": "partners", + "type": "GENERIC" + }, + { + "name": "parts", + "type": "GENERIC" + }, + { + "name": "ph", + "type": "COUNTRY_CODE" + }, + { + "name": "photo", + "type": "GENERIC" + }, + { + "name": "photography", + "type": "GENERIC" + }, + { + "name": "photos", + "type": "GENERIC" + }, + { + "name": "pics", + "type": "GENERIC" + }, + { + "name": "pictures", + "type": "GENERIC" + }, + { + "name": "pink", + "type": "GENERIC" + }, + { + "name": "pizza", + "type": "GENERIC" + }, + { + "name": "place", + "type": "GENERIC" + }, + { + "name": "plumbing", + "type": "GENERIC" + }, + { + "name": "poker", + "type": "GENERIC" + }, + { + "name": "press", + "type": "GENERIC" + }, + { + "name": "productions", + "type": "GENERIC" + }, + { + "name": "properties", + "type": "GENERIC" + }, + { + "name": "property", + "type": "GENERIC" + }, + { + "name": "pub", + "type": "GENERIC" + }, + { + "name": "qpon", + "type": "GENERIC" + }, + { + "name": "recipes", + "type": "GENERIC" + }, + { + "name": "red", + "type": "GENERIC" + }, + { + "name": "rehab", + "type": "GENERIC" + }, + { + "name": "reisen", + "type": "GENERIC" + }, + { + "name": "rentals", + "type": "GENERIC" + }, + { + "name": "repair", + "type": "GENERIC" + }, + { + "name": "report", + "type": "GENERIC" + }, + { + "name": "republican", + "type": "GENERIC" + }, + { + "name": "rest", + "type": "GENERIC" + }, + { + "name": "restaurant", + "type": "GENERIC" + }, + { + "name": "reviews", + "type": "GENERIC" + }, + { + "name": "rich", + "type": "GENERIC" + }, + { + "name": "rip", + "type": "GENERIC" + }, + { + "name": "rocks", + "type": "GENERIC" + }, + { + "name": "rodeo", + "type": "GENERIC" + }, + { + "name": "ryukyu", + "type": "GENERIC" + }, + { + "name": "sale", + "type": "GENERIC" + }, + { + "name": "sarl", + "type": "GENERIC" + }, + { + "name": "schule", + "type": "GENERIC" + }, + { + "name": "services", + "type": "GENERIC" + }, + { + "name": "sexy", + "type": "GENERIC" + }, + { + "name": "shiksha", + "type": "GENERIC" + }, + { + "name": "shoes", + "type": "GENERIC" + }, + { + "name": "singles", + "type": "GENERIC" + }, + { + "name": "site", + "type": "GENERIC" + }, + { + "name": "social", + "type": "GENERIC" + }, + { + "name": "software", + "type": "GENERIC" + }, + { + "name": "solar", + "type": "GENERIC" + }, + { + "name": "solutions", + "type": "GENERIC" + }, + { + "name": "space", + "type": "GENERIC" + }, + { + "name": "style", + "type": "GENERIC" + }, + { + "name": "supplies", + "type": "GENERIC" + }, + { + "name": "supply", + "type": "GENERIC" + }, + { + "name": "support", + "type": "GENERIC" + }, + { + "name": "surf", + "type": "GENERIC" + }, + { + "name": "surgery", + "type": "GENERIC" + }, + { + "name": "systems", + "type": "GENERIC" + }, + { + "name": "tattoo", + "type": "GENERIC" + }, + { + "name": "tax", + "type": "GENERIC" + }, + { + "name": "technology", + "type": "GENERIC" + }, + { + "name": "tennis", + "type": "GENERIC" + }, + { + "name": "tienda", + "type": "GENERIC" + }, + { + "name": "tips", + "type": "GENERIC" + }, + { + "name": "tires", + "type": "GENERIC" + }, + { + "name": "today", + "type": "GENERIC" + }, + { + "name": "tokyo", + "type": "GENERIC" + }, + { + "name": "tools", + "type": "GENERIC" + }, + { + "name": "town", + "type": "GENERIC" + }, + { + "name": "toys", + "type": "GENERIC" + }, + { + "name": "trade", + "type": "GENERIC" + }, + { + "name": "training", + "type": "GENERIC" + }, + { + "name": "tv", + "type": "COUNTRY_CODE" + }, + { + "name": "tw", + "type": "COUNTRY_CODE" + }, + { + "name": "university", + "type": "GENERIC" + }, + { + "name": "uno", + "type": "GENERIC" + }, + { + "name": "us", + "type": "COUNTRY_CODE" + }, + { + "name": "vacations", + "type": "GENERIC" + }, + { + "name": "vegas", + "type": "GENERIC" + }, + { + "name": "ventures", + "type": "GENERIC" + }, + { + "name": "vet", + "type": "GENERIC" + }, + { + "name": "viajes", + "type": "GENERIC" + }, + { + "name": "video", + "type": "GENERIC" + }, + { + "name": "villas", + "type": "GENERIC" + }, + { + "name": "vision", + "type": "GENERIC" + }, + { + "name": "vodka", + "type": "GENERIC" + }, + { + "name": "vote", + "type": "GENERIC" + }, + { + "name": "voto", + "type": "GENERIC" + }, + { + "name": "voyage", + "type": "GENERIC" + }, + { + "name": "watch", + "type": "GENERIC" + }, + { + "name": "webcam", + "type": "GENERIC" + }, + { + "name": "website", + "type": "GENERIC" + }, + { + "name": "wiki", + "type": "GENERIC" + }, + { + "name": "works", + "type": "GENERIC" + }, + { + "name": "world", + "type": "GENERIC" + }, + { + "name": "ws", + "type": "COUNTRY_CODE" + }, + { + "name": "wtf", + "type": "GENERIC" + }, + { + "name": "xxx", + "type": "GENERIC" + }, + { + "name": "xyz", + "type": "GENERIC" + }, + { + "name": "yokohama", + "type": "GENERIC" + }, + { + "name": "zone", + "type": "GENERIC" + } +] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/test/dns/test_godaddy.py ---------------------------------------------------------------------- diff --git a/libcloud/test/dns/test_godaddy.py b/libcloud/test/dns/test_godaddy.py new file mode 100644 index 0000000..5aaa648 --- /dev/null +++ b/libcloud/test/dns/test_godaddy.py @@ -0,0 +1,139 @@ +# 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. + +import sys +import unittest + +from libcloud.utils.py3 import httplib +from libcloud.dns.drivers.godaddy import GoDaddyDNSDriver +from libcloud.test import MockHttp +from libcloud.test.file_fixtures import DNSFileFixtures +from libcloud.test.secrets import DNS_PARAMS_GODADDY +from libcloud.dns.base import Zone, RecordType + + +class GoDaddyTests(unittest.TestCase): + + def setUp(self): + GoDaddyMockHttp.type = None + GoDaddyDNSDriver.connectionCls.conn_classes = ( + None, GoDaddyMockHttp) + self.driver = GoDaddyDNSDriver(*DNS_PARAMS_GODADDY) + + def assertHasKeys(self, dictionary, keys): + for key in keys: + self.assertTrue(key in dictionary, 'key "%s" not in dictionary' % + (key)) + + def test_list_zones(self): + zones = self.driver.list_zones() + self.assertEqual(len(zones), 5) + self.assertEqual(zones[0].id, '177184419') + self.assertEqual(zones[0].domain, 'aperture-platform.com') + + def test_ex_check_availability(self): + check = self.driver.ex_check_availability("wazzlewobbleflooble.com") + self.assertEqual(check.available, True) + self.assertEqual(check.price, 14.99) + + def test_ex_list_tlds(self): + tlds = self.driver.ex_list_tlds() + self.assertEqual(len(tlds), 331) + self.assertEqual(tlds[0].name, 'academy') + self.assertEqual(tlds[0].type, 'GENERIC') + + def test_ex_get_purchase_schema(self): + schema = self.driver.ex_get_purchase_schema('com') + self.assertEqual(schema['id'], + 'https://api.godaddy.com/DomainPurchase#') + + def test_list_records(self): + zone = Zone(id='177184419', + domain='aperture-platform.com', + type='master', + ttl=None, + driver=self.driver) + records = self.driver.list_records(zone) + self.assertEqual(len(records), 14) + self.assertEqual(records[0].type, RecordType.A) + self.assertEqual(records[0].name, '@') + self.assertEqual(records[0].data, '50.63.202.42') + self.assertEqual(records[0].id, '@:A') + + def test_get_record(self): + record = self.driver.get_record( + 'aperture-platform.com', + 'www:A') + self.assertEqual(record.id, 'www:A') + self.assertEqual(record.name, 'www') + self.assertEqual(record.type, RecordType.A) + self.assertEqual(record.data, '50.63.202.42') + + def test_create_record(self): + zone = Zone(id='177184419', + domain='aperture-platform.com', + type='master', + ttl=None, + driver=self.driver) + record = self.driver.create_record( + zone=zone, + name='www', + type=RecordType.A, + data='50.63.202.42' + ) + self.assertEqual(record.id, 'www:A') + self.assertEqual(record.name, 'www') + self.assertEqual(record.type, RecordType.A) + self.assertEqual(record.data, '50.63.202.42') + + def test_get_zone(self): + zone = self.driver.get_zone('aperture-platform.com') + self.assertEqual(zone.id, '177184419') + self.assertEqual(zone.domain, 'aperture-platform.com') + + +class GoDaddyMockHttp(MockHttp): + fixtures = DNSFileFixtures('godaddy') + + def _v1_domains(self, method, url, body, headers): + body = self.fixtures.load('v1_domains.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _v1_domains_aperture_platform_com(self, method, url, body, headers): + body = self.fixtures.load('v1_domains_aperture_platform_com.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _v1_domains_aperture_platform_com_records(self, method, url, body, headers): + body = self.fixtures.load('v1_domains_aperture_platform_com_records.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _v1_domains_available(self, method, url, body, headers): + body = self.fixtures.load('v1_domains_available.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _v1_domains_tlds(self, method, url, body, headers): + body = self.fixtures.load('v1_domains_tlds.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _v1_domains_aperture_platform_com_records_A_www(self, method, url, body, headers): + body = self.fixtures.load('v1_domains_aperture_platform_com_records_A_www.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _v1_domains_purchase_schema_com(self, method, url, body, headers): + body = self.fixtures.load('v1_domains_purchase_schema_com.json') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + +if __name__ == '__main__': + sys.exit(unittest.main()) http://git-wip-us.apache.org/repos/asf/libcloud/blob/a3d1103c/libcloud/test/secrets.py-dist ---------------------------------------------------------------------- diff --git a/libcloud/test/secrets.py-dist b/libcloud/test/secrets.py-dist index 9048837..98b5512 100644 --- a/libcloud/test/secrets.py-dist +++ b/libcloud/test/secrets.py-dist @@ -79,3 +79,4 @@ DNS_PARAMS_POINTDNS = ('user', 'key') DNS_PARAMS_LIQUIDWEB = ('user', 'key') DNS_PARAMS_ZONOMI = ('key') DNS_PARAMS_DURABLEDNS = ('api_user', 'api_key') +DNS_PARAMS_GODADDY = ('customer-id', 'api_user', 'api_key')
