示例#1
0
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        """
        :param domain: Zone domain name (e.g. example.com)
        :type domain: ``str``

        :param type: Zone type (This is not really used. See API docs for extra
          parameters)
        :type type: ``str``

        :param ttl: TTL for new records (This is used through the extra param)
        :type ttl: ``int``

        :param extra: Extra attributes that are specific to the driver
        such as ttl.
        :type extra: ``dict``

        :rtype: :class:`Zone`
        """
        action = '/Domain.Create'
        data = {'domain': domain}
        if extra is not None:
            data.update(extra)
        try:
            response = self._make_request(action=action, method='POST',
                                          data=data)
        except DNSPodException as e:
            if e.message in ZONE_ALREADY_EXISTS_ERROR_MSGS:
                raise ZoneAlreadyExistsError(value=e.message, driver=self,
                                             zone_id=domain)
            else:
                raise e

        zone = self._to_zone(response.object['domain'])

        return zone
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        """
        >>> driver = DummyDNSDriver('key', 'secret')
        >>> zone = driver.create_zone(domain='apache.org', type='master',
        ...                           ttl=100)
        >>> zone
        <Zone: domain=apache.org, ttl=100, provider=Dummy DNS Provider ...>
        >>> zone = driver.create_zone(domain='apache.org', type='master',
        ...                           ttl=100)
        ... #doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ZoneAlreadyExistsError:

        @inherits: L{DNSDriver.create_zone}
        """

        id = 'id-%s' % (domain)

        if id in self._zones:
            raise ZoneAlreadyExistsError(zone_id=id, value=None, driver=self)

        zone = Zone(id=id,
                    domain=domain,
                    type=type,
                    ttl=ttl,
                    extra={},
                    driver=self)
        self._zones[id] = {'zone': zone, 'records': {}}
        return zone
示例#3
0
    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)
示例#4
0
    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
示例#5
0
    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'])
示例#6
0
    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 as e:
            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
示例#7
0
    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)
示例#8
0
    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))
示例#9
0
    def create_zone(self, domain, type=None, ttl=None, extra={}):
        """
        Create a new zone.

        There are two PowerDNS-specific quirks here. Firstly, the "type" and
        "ttl" parameters are ignored (no-ops). The "type" parameter is simply
        not implemented, and PowerDNS does not have an ability to set a
        zone-wide default TTL. (TTLs must be set per-record.)

        Secondly, PowerDNS requires that you provide a list of nameservers for
        the zone upon creation.  In other words, the "extra" parameter must be
        ``{'nameservers': ['ns1.example.org']}`` at a minimum.

        :param name: Zone domain name (e.g. example.com)
        :type  name: ``str``

        :param domain: Zone type (master / slave). (optional).  Note that the
                       PowerDNS driver does nothing with this parameter.
        :type  domain: :class:`Zone`

        :param ttl: TTL for new records. (optional). Note that the PowerDNS
                    driver does nothing with this parameter.
        :type  ttl: ``int``

        :param extra: Extra attributes (driver specific).
                      For example, specify
                      ``extra={'nameservers': ['ns1.example.org']}`` to set
                      a list of nameservers for this new zone.
        :type extra: ``dict``

        :rtype: :class:`Zone`
        """
        action = '%s/servers/%s/zones' % (self.api_root, self.ex_server)
        if extra is None or extra.get('nameservers', None) is None:
            msg = 'PowerDNS requires a list of nameservers for every new zone'
            raise ValueError(msg)
        payload = {'name': domain, 'kind': 'Native'}
        payload.update(extra)
        zone_id = domain + '.'
        try:
            self.connection.request(action=action,
                                    data=json.dumps(payload),
                                    method='POST')
        except BaseHTTPError:
            e = sys.exc_info()[1]
            if e.code == httplib.UNPROCESSABLE_ENTITY and \
               e.message.startswith("Domain '%s' already exists" % domain):
                raise ZoneAlreadyExistsError(zone_id=zone_id,
                                             driver=self,
                                             value=e.message)
            raise e
        return Zone(id=zone_id,
                    domain=domain,
                    type=None,
                    ttl=None,
                    driver=self,
                    extra=extra)
示例#10
0
 def parse_error(self):
     context = self.connection.context
     status_description = self.parse_body()['statusDescription']
     if status_description == u'{} has been already added.'.format(
             context['id']):
         if context['resource'] == 'zone':
             raise ZoneAlreadyExistsError(value='',
                                          driver=self,
                                          zone_id=context['id'])
     super(ClouDNSDNSResponse, self).parse_error()
     return self.body
示例#11
0
    def update_zone(self, zone, domain, type=None, ttl=None, extra=None):
        """
        Update an 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: not supported. RcodeZero uses RRSet-specific TTLs
        :type  ttl: ``int``

        :param extra: Extra attributes: 'masters' (for type=slave)
                     ``extra={'masters': ['193.0.2.2','2001:db8::2']}``
                     sets the Master nameserver addresses for a type=slave zone
        :type extra: ``dict``

        :rtype: :class:`Zone`
        """
        action = '%s/zones/%s' % (self.api_root, domain)
        if type is None:
            type = zone.type

        if type.lower() == 'slave' and (extra is None
                                        or extra.get('masters', None) is None):
            msg = 'Master IPs required for slave zones'
            raise ValueError(msg)
        payload = {'domain': domain.lower(), 'type': type.lower()}
        if extra is not None:
            payload.update(extra)
        try:
            self.connection.request(action=action,
                                    data=json.dumps(payload),
                                    method='PUT')
        except BaseHTTPError:
            e = sys.exc_info()[1]
            if e.code == httplib.UNPROCESSABLE_ENTITY and \
               e.message.startswith("Domain '%s' update failed" % domain):
                raise ZoneAlreadyExistsError(zone_id=zone.id,
                                             driver=self,
                                             value=e.message)
            raise e
        return Zone(id=zone.id,
                    domain=domain,
                    type=type,
                    ttl=None,
                    driver=self,
                    extra=extra)
示例#12
0
    def create_zone(self, domain, type='master', ttl=None, extra={}):
        """
        Create a new zone.

        :param name: Zone domain name (e.g. example.com)
        :type  name: ``str``

        :param domain: Zone type ('master' / 'slave'). (required).
        :type  domain: :class:`Zone`

        :param ttl: TTL for new records. (optional). Ignored by RcodeZero.
                    RcodeZero uses record specific TTLs.
        :type  ttl: ``int``

        :param extra: Extra attributes: 'masters' (for type=slave):
                    ``extra={'masters': ['193.0.2.2','2001:db8::2']}``
                    sets the Master nameservers for a type=slave zone.
        :type extra: ``dict``

        :rtype: :class:`Zone`
        """
        action = '%s/zones' % (self.api_root)
        if type.lower() == 'slave' and (extra is None
                                        or extra.get('masters', None) is None):
            msg = 'Master IPs required for slave zones'
            raise ValueError(msg)
        payload = {'domain': domain.lower(), 'type': type.lower()}
        payload.update(extra)
        zone_id = domain + '.'
        try:
            self.connection.request(action=action,
                                    data=json.dumps(payload),
                                    method='POST')
        except BaseHTTPError:
            e = sys.exc_info()[1]
            if e.code == httplib.UNPROCESSABLE_ENTITY and \
               e.message.find("Zone '%s' already configured for your account"
                              % domain):
                raise ZoneAlreadyExistsError(zone_id=zone_id,
                                             driver=self,
                                             value=e.message)
            raise e
        return Zone(id=zone_id,
                    domain=domain,
                    type=type.lower(),
                    ttl=None,
                    driver=self,
                    extra=extra)
示例#13
0
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        """Using older API that supports creating zones"""

        data = urllib.urlencode({'aid': self.connection.key, 'domain': domain})
        req = urllib2.Request(
            'https://secure.leaseweb.com/api/domain/register/dnsOnly', data)
        res = urllib2.urlopen(req).read()

        if (('The following domain is already'
                ' registered in our system: {}').format(domain) in res):
            raise ZoneAlreadyExistsError(value=domain, driver=self,
                                         zone_id=domain)
        zone = self.get_zone(domain)

        # Delete all default records that point to leaseweb.com
        for record in self.list_records(zone=zone):
            self.delete_record(record)
示例#14
0
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        r = self._api.dns.managed.POST(
            data=json.dumps({'names': [domain]}),
            headers={'Content-Type': 'application/json'})

        try:
            self._raise_for_response(r)
            return self._to_zone(r.json())

        except self.ParsedError as e:
            code, message = e.args
            if code == 1 or code == 2:
                raise ZoneAlreadyExistsError(value=domain,
                                             driver=self,
                                             zone_id=-1)
            else:
                raise
示例#15
0
    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 (This is not really used. See API docs for extra
                     parameters).
        :type  type: ``str``

        :param ttl: TTL for new records. (This is not really used)
        :type  ttl: ``int``

        :param extra: Extra attributes (driver specific). ('region_support',
                      'zone_data')
        :type extra: ``dict``

        :rtype: :class:`Zone`

        For more info, please see:
        https://www.liquidweb.com/storm/api/docs/v1/Network/DNS/Zone.html
        """
        action = '/v1/Network/DNS/Zone/create'
        data = {'params': {'name': domain}}

        if extra is not None:
            data['params'].update(extra)
        try:
            data = json.dumps(data)
            response = self.connection.request(action=action,
                                               method='POST',
                                               data=data)
        except APIException:
            e = sys.exc_info()[1]
            if e.error_class == 'LW::Exception::DuplicateRecord':
                raise ZoneAlreadyExistsError(zone_id=domain,
                                             value=e.value,
                                             driver=self)
            else:
                raise e

        zone = self._to_zone(response.objects[0])

        return zone
示例#16
0
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        """
        :param domain: Zone domain name (e.g. example.com)
        :type domain: ``str``

        :param type: Zone type (This is not really used. See API docs for extra
          parameters)
        :type type: ``str``

        :param ttl: TTL for new records (This is used through the extra param)
        :type ttl: ``int``

        :param extra: Extra attributes that are specific to the driver
        such as ttl.
        :type extra: ``dict``

        :rtype: :class:`Zone`
        Do not forget to pass the master in extra,
        extra = {'master':'65.55.37.62'} for example.
        """
        action = '/api/v2/zone/'
        data = {'name': domain}
        if extra is not None:
            data.update(extra)
        post_data = json.dumps(data)
        try:
            response = self.connection.request(action=action,
                                               method='POST',
                                               data=post_data)
        except BuddyNSException:
            e = sys.exc_info()[1]
            if e.message == 'Invalid zone submitted for addition.':
                raise ZoneAlreadyExistsError(value=e.message,
                                             driver=self,
                                             zone_id=domain)
            else:
                raise e

        zone = self._to_zone(response.parse_body())

        return zone
示例#17
0
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        """
        :param domain: Zone domain name (e.g. example.com)
        :type domain: ``str``

        :param type: Zone type (This is not really used. See API docs for extra
          parameters)
        :type type: ``str``

        :param ttl: TTL for new records (This is used through the extra param)
        :type ttl: ``int``

        :param extra: Extra attributes that are specific to the driver
        such as ttl.
        :type extra: ``dict``

        :rtype: :class:`Zone`
        """
        action = '/v1/zones/%s' % domain
        raw_data = {'zone': domain}
        if extra is not None:
            raw_data.update(extra)
        post_data = json.dumps(raw_data)
        try:
            response = self.connection.request(action=action,
                                               method='PUT',
                                               data=post_data)
        except NsOneException:
            e = sys.exc_info()[1]
            if e.message == 'zone already exists':
                raise ZoneAlreadyExistsError(value=e.message,
                                             driver=self,
                                             zone_id=domain)
            else:
                raise e

        zone = self._to_zone(response.object)

        return zone
示例#18
0
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        if extra and 'name' in extra:
            zone_name = extra['name']
        else:
            zone_name = '%s zone' % domain
        zone_data = {
            'name': zone_name,
        }

        try:
            new_zone = self.connection.request(action='%s/zones' % API_BASE,
                                               method='POST',
                                               data=zone_data)
        except ResourceConflictError:
            raise ZoneAlreadyExistsError(value='',
                                         driver=self.connection.driver,
                                         zone_id=zone_name)
        new_zone_uuid = new_zone.headers['location'].split('/')[-1]

        self.ex_switch_domain_gandi_zone(domain, new_zone_uuid)

        return self._to_zone({'fqdn': domain, 'zone_uuid': new_zone_uuid})
示例#19
0
    def create_zone(self, domain, type="master", ttl=None, extra=None):
        if extra and "name" in extra:
            zone_name = extra["name"]
        else:
            zone_name = "%s zone" % domain
        zone_data = {
            "name": zone_name,
        }

        try:
            new_zone = self.connection.request(action="%s/zones" % API_BASE,
                                               method="POST",
                                               data=zone_data)
        except ResourceConflictError:
            raise ZoneAlreadyExistsError(value="",
                                         driver=self.connection.driver,
                                         zone_id=zone_name)
        new_zone_uuid = new_zone.headers["location"].split("/")[-1]

        self.ex_switch_domain_gandi_zone(domain, new_zone_uuid)

        return self._to_zone({"fqdn": domain, "zone_uuid": new_zone_uuid})
示例#20
0
    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 (This is not really used. See API docs for extra
                     parameters).
        :type  type: ``str``

        :param ttl: TTL for new records. (This is not really used)
        :type  ttl: ``int``

        :param extra: Extra attributes (driver specific). ('region_support',
                      'zone_data')
        :type extra: ``dict``

        :rtype: :class:`Zone`
        """
        action = '/v1/zones'
        data = json.dumps({'name': domain})
        try:
            response = self.connection.request(action=action,
                                               method='POST',
                                               data=data)
        except LuadnsException:
            e = sys.exc_info()[1]
            if e.message == "Zone '%s' is taken already." % domain:
                raise ZoneAlreadyExistsError(zone_id=domain,
                                             value='',
                                             driver=self)
            else:
                raise e
        zone = self._to_zone(response.parse_body())

        return zone
示例#21
0
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        """
        Create a new zone.

        :param domain: Name of zone, followed by a dot (.) (e.g. example.com.)
        :type  domain: ``str``

        :param type: Zone type (Only master available). (optional)
        :type  type: ``str``

        :param ttl: TTL for new records. (optional)
        :type  ttl: ``int``

        :param extra: Extra attributes ('mbox', 'ns', 'minimum', 'refresh',
                                        'expire', 'update_acl', 'xfer').
                      (optional)
        :type extra: ``dict``

        :rtype: :class:`Zone`
        """
        if extra is None:
            extra = ZONE_EXTRA_PARAMS_DEFAULT_VALUES
        else:
            extra_fields = ZONE_EXTRA_PARAMS_DEFAULT_VALUES.keys()
            missing = set(extra_fields).difference(set(extra.keys()))
            for field in missing:
                extra[field] = ZONE_EXTRA_PARAMS_DEFAULT_VALUES.get(field)
        schema_params = SCHEMA_BUILDER_MAP.get('create_zone')
        attributes = schema_params.get('attributes')
        schema = api_schema_builder(schema_params.get('urn_nid'),
                                    schema_params.get('method'),
                                    attributes)
        params = {'apiuser': self.key, 'apikey': self.secret,
                  'zonename': domain, 'ttl': ttl or DEFAULT_TTL}
        params.update(extra)
        urn = schema.getchildren()[0]
        for child in urn:
            key = child.tag.split(':')[2]
            if key in attributes:
                if isinstance(params.get(key), int):
                    child.text = "%d"
                else:
                    child.text = "%s"
        # We can't insert values directly in child.text because API raises
        # and exception for values that need to be integers. And tostring
        # method from ElementTree can't handle int values.
        skel = ensure_string(tostring(schema))  # Deal with PY3
        req_data = skel % (self.key, self.secret, domain, extra.get('ns'),
                           extra.get('mbox'), extra.get('refresh'),
                           extra.get('retry'), extra.get('expire'),
                           extra.get('minimum'), ttl or DEFAULT_TTL,
                           extra.get('xfer'), extra.get('update_acl'))
        action = '/services/dns/createZone.php?'
        params = {}
        headers = {"SOAPAction": "urn:createZonewsdl#createZone"}
        try:
            self.connection.request(action=action, params=params,
                                    data=req_data, method="POST",
                                    headers=headers)
        except DurableDNSException:
            e = sys.exc_info()[1]
            if 'Zone Already Exist' in e.message:
                raise ZoneAlreadyExistsError(zone_id=domain, driver=self,
                                             value=e.message)
            raise e

        zone = self.get_zone(domain)
        return zone