def delete_record(self, record): """ Delete a record. :param record: Record to delete. :type record: :class:`Record` :rtype: ``bool`` """ action = '/Record.Remove' data = {'domain_id': record.zone.id, 'record_id': record.id} try: self._make_request(action=action, method='POST', data=data) except DNSPodException: e = sys.exc_info()[1] if e.message in RECORD_DOES_NOT_EXIST_ERRORS_MSGS: raise RecordDoesNotExistError(record_id=record.id, driver=self, value='') elif e.message in ZONE_DOES_NOT_EXIST_ERROR_MSGS: raise ZoneDoesNotExistError(zone_id=record.zone.id, driver=self, value='') else: raise e return True
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
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 Exception: 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
def delete_record(self, record): """ Delete a record in a given zone. :param record: record to delete (record object) :type record: `Record` :rtype: ``bool`` """ action = '%s/zones/%s/rrsets' % (self.api_root, record.zone.id) payload = self._to_patchrequest(record.zone.id, None, record.name, record.type, record.data, record.extra, 'delete') try: self.connection.request(action=action, data=json.dumps(payload), method='PATCH') except BaseHTTPError as e: if e.code == httplib.UNPROCESSABLE_ENTITY and \ e.message.startswith('Could not find domain'): raise ZoneDoesNotExistError(zone_id=record.zone.id, driver=self, value=e.message) raise e return True
def get_zone(self, zone_id): """ Return a Zone instance. :param zone_id: name of the required zone, for example "example.com". :type zone_id: ``str`` :rtype: :class:`Zone` :raises: ZoneDoesNotExistError: If no zone could be found. """ # We will check if there is a serial property for this zone. If so, # then the zone exists. try: self.connection.request(action='/dns/%s/serial' % zone_id) except BaseHTTPError: e = sys.exc_info()[1] if e.code == httplib.NOT_FOUND: raise ZoneDoesNotExistError(zone_id=None, driver=self, value=e.message) raise e return Zone(id=None, domain=zone_id, type='master', ttl=3600, driver=self)
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` """ action = "/v1/Network/DNS/Zone/details" data = json.dumps({"params": {"id": zone_id}}) try: response = self.connection.request(action=action, method="POST", data=data) except APIException as e: if e.error_class == "LW::Exception::RecordNotFound": raise ZoneDoesNotExistError(zone_id=zone_id, value=e.value, driver=self) else: raise e zone = self._to_zone(response.objects[0]) return zone
def parse_error(self): status = int(self.status) if status == httplib.UNAUTHORIZED: raise InvalidCredsError(value='Authentication failed', driver=self) elif status == httplib.FORBIDDEN: raise ProviderError(value='Authorization failed', http_code=status, driver=self) elif status == httplib.NOT_FOUND: 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 == httplib.CONFLICT: context = self.connection.context if context['resource'] == 'zone': raise ZoneAlreadyExistsError(value='', driver=self, zone_id=context['id'])
def parse_error(self): status = int(self.status) error = {"driver": self, "value": ""} if status == httplib.UNAUTHORIZED: error["value"] = "Authentication failed" raise InvalidCredsError(**error) elif status == httplib.FORBIDDEN: error["value"] = "Authorization failed" error["http_code"] = status raise ProviderError(**error) elif status == httplib.NOT_FOUND: context = self.connection.context if context["resource"] == "zone": error["zone_id"] = context["id"] raise ZoneDoesNotExistError(**error) elif context["resource"] == "record": error["record_id"] = context["id"] raise RecordDoesNotExistError(**error) elif context["resource"] == "healthcheck": error["health_check_id"] = context["id"] raise HealthCheckDoesNotExistError(**error) elif status == httplib.CONFLICT: context = self.connection.context if context["resource"] == "zone": error["zone_id"] = context["id"] raise ZoneAlreadyExistsError(**error) elif status == httplib.BAD_REQUEST: context = self.connection.context body = self.parse_body() raise ProviderError(value=body["errormsg"], http_code=status, driver=self)
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` """ zone = self.get_zone(zone_id=zone_id) action = '/Record.Info' data = {'domain_id': zone_id, 'record_id': record_id} try: response = self._make_request(action=action, method='POST', data=data) except DNSPodException: e = sys.exc_info()[1] if e.message in RECORD_DOES_NOT_EXIST_ERRORS_MSGS: raise RecordDoesNotExistError(record_id=record_id, driver=self, value='') elif e.message in ZONE_DOES_NOT_EXIST_ERROR_MSGS: raise ZoneDoesNotExistError(zone_id=zone_id, driver=self, value='') else: raise e record = self._to_record(response.object['record'], zone=zone) return record
def parse_error(self): status = int(self.status) context = self.connection.context body = self.parse_body() if status == httplib.NOT_FOUND: 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']) if status == httplib.CONFLICT: if context['resource'] == 'zone': raise ZoneAlreadyExistsError(value=context['value'], driver=self, zone_id=None) elif context['resource'] == 'record': raise RecordAlreadyExistsError(value=context['value'], driver=self, record_id=None) if body: if 'code' and 'message' in body: err = '%s - %s (%s)' % (body['code'], body['message'], body['errors'][0]['message']) return err raise LibcloudError('Unexpected status code: %s' % (status))
def parse_error(self): status = int(self.status) error = {'driver': self, 'value': ''} if status == httplib.UNAUTHORIZED: error['value'] = 'Authentication failed' raise InvalidCredsError(**error) elif status == httplib.FORBIDDEN: error['value'] = 'Authorization failed' error['http_status'] = status raise ProviderError(**error) elif status == httplib.NOT_FOUND: context = self.connection.context if context['resource'] == 'zone': error['zone_id'] = context['id'] raise ZoneDoesNotExistError(**error) elif context['resource'] == 'record': error['record_id'] = context['id'] raise RecordDoesNotExistError(**error) elif context['resource'] == 'healthcheck': error['health_check_id'] = context['id'] raise HealthCheckDoesNotExistError(**error) elif status == httplib.CONFLICT: context = self.connection.context if context['resource'] == 'zone': error['zone_id'] = context['id'] raise ZoneAlreadyExistsError(**error) elif status == httplib.BAD_REQUEST: context = self.connection.context body = self.parse_body() raise ProviderError(value=body['errormsg'], http_code=status, driver=self)
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 = '/Record.List' data = {'domain_id': zone.id} try: response = self._make_request(action=action, data=data, method='POST') except DNSPodException: e = sys.exc_info()[1] if e.message in ZONE_DOES_NOT_EXIST_ERROR_MSGS: raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone.id) else: raise e records = self._to_records(response.object['records'], zone=zone) return records
def delete_record(self, record): """ Delete a record. :param record: Record to delete. :type record: :class:`Record` :rtype: ``bool`` """ action = "/Record.Remove" data = {"domain_id": record.zone.id, "record_id": record.id} try: self._make_request(action=action, method="POST", data=data) except DNSPodException as e: if e.message in RECORD_DOES_NOT_EXIST_ERRORS_MSGS: raise RecordDoesNotExistError(record_id=record.id, driver=self, value="") elif e.message in ZONE_DOES_NOT_EXIST_ERROR_MSGS: raise ZoneDoesNotExistError(zone_id=record.zone.id, driver=self, value="") else: raise e return True
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 = "/Record.List" data = {"domain_id": zone.id} try: response = self._make_request(action=action, data=data, method="POST") except DNSPodException as e: if e.message in ZONE_DOES_NOT_EXIST_ERROR_MSGS: raise ZoneDoesNotExistError(value="", driver=self, zone_id=zone.id) else: raise e records = self._to_records(response.object["records"], zone=zone) return records
def parse_error(self): status = int(self.status) context = self.connection.context body = self.parse_body() if status == httplib.NOT_FOUND: 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"]) if body: if "code" and "message" in body: err = "%s - %s (%s)" % (body["code"], body["message"], body["details"]) return err elif "validationErrors" in body: errors = [m for m in body["validationErrors"]["messages"]] err = "Validation errors: %s" % ", ".join(errors) return err raise LibcloudError("Unexpected status code: %s" % (status))
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 get_zone(self, zone_id): """ Return a Zone instance. (Note that PowerDNS does not support per-zone TTL defaults, so all Zone objects will have ``ttl=None``.) :param zone_id: name of the required zone with the trailing period, for example "example.com.". :type zone_id: ``str`` :rtype: :class:`Zone` :raises: ZoneDoesNotExistError: If no zone could be found. """ action = '%s/servers/%s/zones/%s' % (self.api_root, self.ex_server, zone_id) try: response = self.connection.request(action=action, method='GET') except BaseHTTPError: e = sys.exc_info()[1] if e.code == httplib.UNPROCESSABLE_ENTITY: raise ZoneDoesNotExistError(zone_id=zone_id, driver=self, value=e.message) raise e return self._to_zone(response.object)
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/Network/DNS/Zone/delete' data = json.dumps({'params': {'id': zone.id}}) try: response = self.connection.request(action=action, method='POST', data=data) except APIException: e = sys.exc_info()[1] if e.error_class == 'LW::Exception::RecordNotFound': raise ZoneDoesNotExistError(zone_id=zone.id, value=e.value, driver=self) else: raise e return zone.domain in response.objects
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): """ Return a Zone instance. :param zone_id: ID of the required zone :type zone_id: ``str`` :rtype: :class:`Zone` """ action = '/v1/Network/DNS/Zone/details' data = json.dumps({'params': {'id': zone_id}}) try: response = self.connection.request(action=action, method='POST', data=data) except APIException: e = sys.exc_info()[1] if e.error_class == 'LW::Exception::RecordNotFound': raise ZoneDoesNotExistError(zone_id=zone_id, value=e.value, driver=self) else: raise e zone = self._to_zone(response.objects[0]) 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_type, record_name) = record_id.split(':', 1) params = { 'name': record_name, 'type': record_type, } request = '/managedZones/%s/rrsets' % (zone_id) try: response = self.connection.request(request, method='GET', params=params).object except ResourceNotFoundError: raise ZoneDoesNotExistError(value='', driver=self.connection.driver, zone_id=zone_id) if len(response['rrsets']) > 0: zone = self.get_zone(zone_id) return self._to_record(response['rrsets'][0], zone) raise RecordDoesNotExistError(value='', driver=self.connection.driver, record_id=record_id)
def parse_body(self): body = super(CloudFlareDNSResponse, self).parse_body() body = body or {} result = body.get('result', None) error_code = body.get('err_code', None) msg = body.get('msg', None) is_error_result = result == 'error' context = self.connection.context or {} context_record_id = context.get('record_id', None) context_zone_domain = context.get('zone_domain', None) if (is_error_result and 'invalid record id' in msg.lower() and context_record_id): raise RecordDoesNotExistError(value=msg, driver=self.connection.driver, record_id=context_record_id) elif (is_error_result and 'invalid zone' in msg.lower() and context_zone_domain): raise ZoneDoesNotExistError(value=msg, driver=self.connection.driver, zone_id=context_zone_domain) if error_code == 'E_UNAUTH': raise InvalidCredsError(msg) elif result == 'error' or error_code is not None: msg = 'Request failed: %s' % (self.body) raise LibcloudError(value=msg, driver=self.connection.driver) return body
def parse_error(self): status = int(self.status) context = self.connection.context body = self.parse_body() if status == httplib.NOT_FOUND: 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']) if body: if 'code' and 'message' in body: err = '%s - %s (%s)' % (body['code'], body['message'], body['details']) return err elif 'validationErrors' in body: errors = [m for m in body['validationErrors']['messages']] err = 'Validation errors: %s' % ', '.join(errors) return err raise LibcloudError('Unexpected status code: %s' % (status))
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 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 get_zone(self, zone_id): self.connection.set_context({'resource': 'zone', 'id': zone_id}) params = {'page': 1, 'rows-per-page': 10, 'search': zone_id} zone_result = self.connection.request('/dns/list-zones.json', params=params).object if not zone_result: raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone_id) return self._to_zone(zone_result[0])
def get_zone(self, zone_id): params = {'api_action': 'domain.list', 'DomainID': zone_id} data = self.connection.request(API_ROOT, params=params).objects[0] zones = self._to_zones(data) if len(zones) != 1: raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone_id) return zones[0]
def get_zone(self, zone_id): params = {'id': zone_id} self.connection.set_context({'resource': 'zone', 'id': zone_id}) result = self.connection.request(API_ROOT + '/dns/zone/', params=params).object if 'id' not in result: raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone_id) zone = self._to_zone(result) return zone
def get_zone(self, zone_id): action = '%s/domains/%s' % (API_BASE, zone_id) try: zone = self.connection.request(action=action, method='GET') except ResourceNotFoundError: raise ZoneDoesNotExistError(value='', driver=self.connection.driver, zone_id=zone_id) return self._to_zone(zone.object)
def get_zone(self, zone_id): params = {"id": zone_id} self.connection.set_context({"resource": "zone", "id": zone_id}) result = self.connection.request(API_ROOT + "/dns/zone/", params=params).object if "id" not in result: raise ZoneDoesNotExistError(value="", driver=self, zone_id=zone_id) zone = self._to_zone(result) return zone