예제 #1
0
    def parse_error(self):
        body = self.parse_body()

        errors = body.get('errors', [])

        for error in errors:
            error_chain = error.get('error_chain', [])

            error_chain_errors = []
            for chain_error in error_chain:
                error_chain_errors.append('%s: %s' % (chain_error.get(
                    'code', 'unknown'), chain_error.get('message', '')))

            try:
                exception_class, context = self.exceptions[error['code']]
            except KeyError:
                exception_class, context = LibcloudError, []

            kwargs = {
                'value':
                '{}: {} (error chain: {})'.format(
                    error['code'], error['message'],
                    ', '.join(error_chain_errors)),
                'driver':
                self.connection.driver,
            }

            merge_valid_keys(kwargs, context, self.connection.context)

            raise exception_class(**kwargs)
예제 #2
0
    def update_record(self, record, name=None, type=None, data=None, extra=None):
        """
        @inherits: :class:`DNSDriver.update_record`

        Note that for ``extra`` record properties, only the ones specified in
        ``RECORD_UPDATE_ATTRIBUTES`` can be updated. Any non-updatable
        properties are ignored.
        """
        url = "{}/zones/{}/dns_records/{}".format(API_BASE, record.zone.id, record.id)

        content, data = self._normalize_record_data_for_api(type=type, data=data)
        body = {
            "type": record.type if type is None else type,
            "name": record.name if name is None else name,
            "content": content,
            "extra": record.extra or {},
        }

        if data:
            body["data"] = data

        merge_valid_keys(body["extra"], RECORD_UPDATE_ATTRIBUTES, extra)

        self.connection.set_context({"record_id": record.id})
        response = self.connection.request(url, data=body, method="PUT")

        item = response.object["result"]
        record = self._to_record(record.zone, item)

        return record
예제 #3
0
    def parse_error(self):
        body = self.parse_body()

        errors = body.get('errors', [])

        for error in errors:
            error_chain = error.get('error_chain', [])

            error_chain_errors = []
            for chain_error in error_chain:
                error_chain_errors.append('%s: %s' % (chain_error.get(
                    'code', 'unknown'), chain_error.get('message', '')))

            try:
                exception_class, context = self.exceptions[error['code']]
            except KeyError:
                exception_class, context = LibcloudError, []

            kwargs = {
                'value':
                '{}: {} (error chain: {})'.format(
                    error['code'], error['message'],
                    ', '.join(error_chain_errors)),
                'driver':
                self.connection.driver,
            }

            if error['code'] == 81057:
                # Record id is not available when creating a record and not
                # updating it
                kwargs["record_id"] = "unknown"

            merge_valid_keys(kwargs, context, self.connection.context)

            raise exception_class(**kwargs)
예제 #4
0
    def update_record(self,
                      record,
                      name=None,
                      type=None,
                      data=None,
                      extra=None):
        """
        @inherits: :class:`DNSDriver.update_record`

        Note that for ``extra`` record properties, only the ones specified in
        ``RECORD_UPDATE_ATTRIBUTES`` can be updated. Any non-updatable
        properties are ignored.
        """
        url = '{}/zones/{}/dns_records/{}'.format(API_BASE, record.zone.id,
                                                  record.id)

        body = {
            'type': record.type if type is None else type,
            'name': record.name if name is None else name,
            'content': record.data if data is None else data,
            'extra': record.extra or {},
        }

        merge_valid_keys(body['extra'], RECORD_UPDATE_ATTRIBUTES, extra)

        self.connection.set_context({'record_id': record.id})
        response = self.connection.request(url, data=body, method='PUT')

        item = response.object['result']
        record = self._to_record(record.zone, item)

        return record
예제 #5
0
    def create_record(self, name, zone, type, data, extra=None):
        """
        @inherits: :class:`DNSDriver.create_record`

        Note that for ``extra`` record properties, only the ones specified in
        ``RECORD_CREATE_ATTRIBUTES`` can be set at creation time. Any
        non-settable properties are ignored.
        """
        url = '{}/zones/{}/dns_records'.format(API_BASE, zone.id)

        body = {
            'type': type,
            'name': name,
            'content': data,
        }

        merge_valid_keys(body, RECORD_CREATE_ATTRIBUTES, extra)

        self.connection.set_context({'zone_id': zone.id})
        response = self.connection.request(url, data=body, method='POST')

        item = response.object['result']
        record = self._to_record(zone, item)

        return record
예제 #6
0
    def create_record(self, name, zone, type, data, extra=None):
        """
        @inherits: :class:`DNSDriver.create_record`

        Note that for ``extra`` record properties, only the ones specified in
        ``RECORD_CREATE_ATTRIBUTES`` can be set at creation time. Any
        non-settable properties are ignored.

        NOTE: For CAA RecordType, data needs to be in the following format:
        <flags> <tag> <ca domain name> where the tag can be issue, issuewild
        or iodef.

        For example: 0 issue test.caa.com

        NOTE: For SSHFP RecordType, data need to be in the format:
        <algorithm> <type> <fingerprint>
        """
        url = '{}/zones/{}/dns_records'.format(API_BASE, zone.id)

        content, data = self._normalize_record_data_for_api(type=type,
                                                            data=data)
        body = {'type': type, 'name': name, 'content': content}

        if data:
            body['data'] = data

        merge_valid_keys(body, RECORD_CREATE_ATTRIBUTES, extra)

        self.connection.set_context({'zone_id': zone.id})
        response = self.connection.request(url, data=body, method='POST')

        item = response.object['result']
        record = self._to_record(zone, item)

        return record
예제 #7
0
파일: linode.py 프로젝트: wandera/libcloud
    def update_record(self,
                      record,
                      name=None,
                      type=None,
                      data=None,
                      extra=None):
        """
        Update an existing record.

        :param record: Record to update.
        :type  record: :class:`Record`

        :param name: Record name.This field's actual usage\
         depends on the type of record this represents.
        :type  name: ``str``

        :param type: DNS record type
        :type  type: :class:`RecordType`

        :param data: Data for the record (depends on the record type).
        :type  data: ``str``

        :param extra: Extra attributes.('port', 'priority', \
        'protocol', 'service', 'tag', 'ttl_sec', 'target', 'weight')
        :type  extra: ``dict``

        :rtype: :class:`Record`
        """
        if not isinstance(record, Record):
            raise LinodeExceptionV4("Invalid zone instance")

        zone = record.zone
        attr = {}

        if name is not None:
            attr["name"] = name

        if type is not None:
            attr["type"] = self.RECORD_TYPE_MAP[type]

        if data is not None:
            attr["target"] = data

        merge_valid_keys(params=attr,
                         valid_keys=VALID_RECORD_EXTRA_PARAMS_V4,
                         extra=extra)

        data = self.connection.request(
            "/v4/domains/%s/records/%s" % (zone.id, record.id),
            data=json.dumps(attr),
            method="PUT",
        ).object

        return self._to_record(data, zone=zone)
예제 #8
0
파일: linode.py 프로젝트: wandera/libcloud
    def create_record(self, name, zone, type, data, extra=None):
        """
        Create a new record.

        API docs: http://www.linode.com/api/dns/domain.resource.create
        """
        params = {
            "api_action": "domain.resource.create",
            "DomainID": zone.id,
            "Name": name,
            "Target": data,
            "Type": self.RECORD_TYPE_MAP[type],
        }
        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)

        result = self.connection.request(API_ROOT, params=params).objects[0]
        record = Record(
            id=result["ResourceID"],
            name=name,
            type=type,
            data=data,
            extra=merged,
            zone=zone,
            driver=self,
            ttl=merged.get("TTL_sec", None),
        )
        return record
예제 #9
0
파일: linode.py 프로젝트: wandera/libcloud
    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
        """
        Update an existing zone.

        API docs: http://www.linode.com/api/dns/domain.update
        """
        params = {"api_action": "domain.update", "DomainID": zone.id}

        if type:
            params["Type"] = type

        if domain:
            params["Domain"] = domain

        if ttl:
            params["TTL_sec"] = ttl

        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        self.connection.request(API_ROOT, params=params).objects[0]
        updated_zone = get_new_obj(
            obj=zone,
            klass=Zone,
            attributes={
                "domain": domain,
                "type": type,
                "ttl": ttl,
                "extra": merged
            },
        )
        return updated_zone
예제 #10
0
파일: linode.py 프로젝트: wandera/libcloud
    def create_zone(self, domain, type="master", ttl=None, extra=None):
        """
        Create a new zone.

        API docs: http://www.linode.com/api/dns/domain.create
        """
        params = {
            "api_action": "domain.create",
            "Type": type,
            "Domain": domain
        }

        if ttl:
            params["TTL_sec"] = ttl

        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        data = self.connection.request(API_ROOT, params=params).objects[0]
        zone = Zone(
            id=data["DomainID"],
            domain=domain,
            type=type,
            ttl=ttl,
            extra=merged,
            driver=self,
        )
        return zone
예제 #11
0
 def update_record(self,
                   record,
                   name=None,
                   type=None,
                   data=None,
                   extra=None):
     params = {"domain_id": record.zone.id, "record_id": record.id}
     if name:
         params["name"] = name
     if data:
         params["content"] = data
     if type is not None:
         params["type"] = self.RECORD_TYPE_MAP[type]
         merged = merge_valid_keys(params=params,
                                   valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                   extra=extra)
     self.connection.set_context({"resource": "record", "id": record.id})
     self.connection.request(API_ROOT + "/dns/record/",
                             data=json.dumps(params),
                             method="PUT").object
     updated_record = get_new_obj(
         obj=record,
         klass=Record,
         attributes={
             "name": name,
             "data": data,
             "type": type,
             "extra": merged
         },
     )
     return updated_record
예제 #12
0
 def create_record(self, name, zone, type, data, extra=None):
     params = {
         "name": name,
         "type": self.RECORD_TYPE_MAP[type],
         "domain_id": zone.id,
         "content": data,
     }
     merged = merge_valid_keys(params=params,
                               valid_keys=VALID_RECORD_EXTRA_PARAMS,
                               extra=extra)
     self.connection.set_context({"resource": "zone", "id": zone.id})
     result = self.connection.request(API_ROOT + "/dns/record/",
                                      data=json.dumps(params),
                                      method="POST").object
     record = Record(
         id=result["id"],
         name=name,
         type=type,
         data=data,
         extra=merged,
         zone=zone,
         ttl=merged.get("ttl", None),
         driver=self,
     )
     return record
예제 #13
0
    def update_record(self, record, name=None, type=None, data=None,
                      extra=None):
        """
        Update an existing record.

        API docs: http://www.linode.com/api/dns/domain.resource.update
        """
        params = {'api_action': 'domain.resource.update',
                  'ResourceID': record.id, 'DomainID': record.zone.id}

        if name:
            params['Name'] = name

        if data:
            params['Target'] = data

        if type is not None:
            params['Type'] = self.RECORD_TYPE_MAP[type]

        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)

        self.connection.request(API_ROOT, params=params).objects[0]
        updated_record = get_new_obj(obj=record, klass=Record,
                                     attributes={'name': name, 'data': data,
                                                 'type': type,
                                                 'extra': merged})
        return updated_record
예제 #14
0
    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
        # Only ttl, comment and email address can be changed
        extra = extra if extra else {}

        if domain:
            raise LibcloudError('Domain cannot be changed', driver=self)

        data = {}

        if ttl:
            data['ttl'] = int(ttl)

        if 'email' in extra:
            data['emailAddress'] = extra['email']

        if 'comment' in extra:
            data['comment'] = extra['comment']

        type = type if type else zone.type
        ttl = ttl if ttl else zone.ttl

        self.connection.set_context({'resource': 'zone', 'id': zone.id})
        self.connection.async_request(action='/domains/%s' % (zone.id),
                                      method='PUT', data=data)
        merged = merge_valid_keys(params=copy.deepcopy(zone.extra),
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        updated_zone = get_new_obj(obj=zone, klass=Zone,
                                   attributes={'type': type,
                                               'ttl': ttl,
                                               'extra': merged})
        return updated_zone
예제 #15
0
    def create_record(self, name, zone, type, data, extra=None):
        """
        Create a new record.

        API docs: http://www.linode.com/api/dns/domain.resource.create
        """
        params = {
            'api_action': 'domain.resource.create',
            'DomainID': zone.id,
            'Name': name,
            'Target': data,
            'Type': self.RECORD_TYPE_MAP[type]
        }
        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)

        result = self.connection.request(API_ROOT, params=params).objects[0]
        record = Record(id=result['ResourceID'],
                        name=name,
                        type=type,
                        data=data,
                        extra=merged,
                        zone=zone,
                        driver=self)
        return record
예제 #16
0
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        """
        Create a new zone.

        API docs: http://www.linode.com/api/dns/domain.create
        """
        params = {
            'api_action': 'domain.create',
            'Type': type,
            'Domain': domain
        }

        if ttl:
            params['TTL_sec'] = ttl

        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        data = self.connection.request(API_ROOT, params=params).objects[0]
        zone = Zone(id=data['DomainID'],
                    domain=domain,
                    type=type,
                    ttl=ttl,
                    extra=merged,
                    driver=self)
        return zone
예제 #17
0
 def update_record(self,
                   record,
                   name=None,
                   type=None,
                   data=None,
                   extra=None):
     params = {'domain_id': record.zone.id, 'record_id': record.id}
     if name:
         params['name'] = name
     if data:
         params['content'] = data
     if type is not None:
         params['type'] = self.RECORD_TYPE_MAP[type]
         merged = merge_valid_keys(params=params,
                                   valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                   extra=extra)
     self.connection.set_context({'resource': 'record', 'id': record.id})
     self.connection.request(API_ROOT + '/dns/record/',
                             data=json.dumps(params),
                             method='PUT').object
     updated_record = get_new_obj(obj=record,
                                  klass=Record,
                                  attributes={
                                      'name': name,
                                      'data': data,
                                      'type': type,
                                      'extra': merged
                                  })
     return updated_record
예제 #18
0
 def update_record(self, record, name=None, type=None,
                   data=None, extra=None):
     params = {
         'domain_id': record.zone.id,
         'record_id': record.id
     }
     if name:
         params['name'] = name
     if data:
         params['content'] = data
     if type is not None:
         params['type'] = self.RECORD_TYPE_MAP[type]
         merged = merge_valid_keys(
             params=params,
             valid_keys=VALID_RECORD_EXTRA_PARAMS,
             extra=extra
         )
     self.connection.set_context({'resource': 'record', 'id': record.id})
     self.connection.request(API_ROOT + '/dns/record/',
                             data=json.dumps(params), method='PUT').object
     updated_record = get_new_obj(
         obj=record, klass=Record, attributes={
             'name': name, 'data': data,
             'type': type,
             'extra': merged
         })
     return updated_record
예제 #19
0
    def update_record(self, record, name=None, type=None, data=None,
                      extra=None):
        # Only data, ttl, and comment attributes can be modified, but name
        # attribute must always be present.
        extra = extra if extra else {}

        name = self._to_full_record_name(domain=record.zone.domain,
                                         name=record.name)
        payload = {'name': name}

        if data:
            payload['data'] = data

        if 'ttl' in extra:
            payload['ttl'] = extra['ttl']

        if 'comment' in extra:
            payload['comment'] = extra['comment']

        type = type if type is not None else record.type
        data = data if data else record.data

        self.connection.set_context({'resource': 'record', 'id': record.id})
        self.connection.async_request(action='/domains/%s/records/%s' %
                                      (record.zone.id, record.id),
                                      method='PUT', data=payload)

        merged = merge_valid_keys(params=copy.deepcopy(record.extra),
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)
        updated_record = get_new_obj(obj=record, klass=Record,
                                     attributes={'type': type,
                                                 'data': data,
                                                 'extra': merged})
        return updated_record
예제 #20
0
    def update_record(self, record, name=None, type=None, data=None,
                      extra=None):
        # Only data, ttl, and comment attributes can be modified, but name
        # attribute must always be present.
        extra = extra if extra else {}

        name = self._to_full_record_name(domain=record.zone.domain,
                                         name=record.name)
        payload = {'name': name}

        if data:
            payload['data'] = data

        if 'ttl' in extra:
            payload['ttl'] = extra['ttl']

        if 'comment' in extra:
            payload['comment'] = extra['comment']

        type = type if type else record.type
        data = data if data else record.data

        self.connection.set_context({'resource': 'record', 'id': record.id})
        self.connection.async_request(action='/domains/%s/records/%s' %
                                      (record.zone.id, record.id),
                                      method='PUT', data=payload)

        merged = merge_valid_keys(params=copy.deepcopy(record.extra),
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)
        updated_record = get_new_obj(obj=record, klass=Record,
                                     attributes={'type': type,
                                                 'data': data,
                                                 'extra': merged})
        return updated_record
예제 #21
0
파일: linode.py 프로젝트: xiama/automations
    def update_record(self, record, name=None, type=None, data=None,
                      extra=None):
        """
        Update an existing record.

        API docs: http://www.linode.com/api/dns/domain.resource.update
        """
        params = {'api_action': 'domain.resource.update',
                  'ResourceID': record.id, 'DomainID': record.zone.id}

        if name:
            params['Name'] = name

        if data:
            params['Target'] = data

        if type:
            params['Type'] = RECORD_TYPE_MAP[type]

        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)

        result = self.connection.request(API_ROOT, params=params).objects[0]
        updated_record = get_new_obj(obj=record, klass=Record,
                                     attributes={'name': name, 'data': data,
                                                 'type': type,
                                                 'extra': merged})
        return updated_record
예제 #22
0
    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
        # Only ttl, comment and email address can be changed
        extra = extra if extra else {}

        if domain:
            raise LibcloudError('Domain cannot be changed', driver=self)

        data = {}

        if ttl:
            data['ttl'] = int(ttl)

        if 'email' in extra:
            data['emailAddress'] = extra['email']

        if 'comment' in extra:
            data['comment'] = extra['comment']

        type = type if type else zone.type
        ttl = ttl if ttl else zone.ttl

        self.connection.set_context({'resource': 'zone', 'id': zone.id})
        self.connection.async_request(action='/domains/%s' % (zone.id),
                                      method='PUT', data=data)
        merged = merge_valid_keys(params=copy.deepcopy(zone.extra),
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        updated_zone = get_new_obj(obj=zone, klass=Zone,
                                   attributes={'type': type,
                                               'ttl': ttl,
                                               'extra': merged})
        return updated_zone
예제 #23
0
파일: linode.py 프로젝트: xiama/automations
    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
        """
        Update an existing zone.

        API docs: http://www.linode.com/api/dns/domain.update
        """
        params = {'api_action': 'domain.update', 'DomainID': zone.id}

        if type:
            params['Type'] = type

        if domain:
            params['Domain'] = domain

        if ttl:
            params['TTL_sec'] = ttl

        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        data = self.connection.request(API_ROOT, params=params).objects[0]
        updated_zone = get_new_obj(obj=zone, klass=Zone,
                                  attributes={'domain': domain,
                                              'type': type, 'ttl': ttl,
                                              'extra': merged})
        return updated_zone
예제 #24
0
    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
        """
        Update an existing zone.

        API docs: http://www.linode.com/api/dns/domain.update
        """
        params = {'api_action': 'domain.update', 'DomainID': zone.id}

        if type:
            params['Type'] = type

        if domain:
            params['Domain'] = domain

        if ttl:
            params['TTL_sec'] = ttl

        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        self.connection.request(API_ROOT, params=params).objects[0]
        updated_zone = get_new_obj(obj=zone,
                                   klass=Zone,
                                   attributes={
                                       'domain': domain,
                                       'type': type,
                                       'ttl': ttl,
                                       'extra': merged
                                   })
        return updated_zone
예제 #25
0
    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
        """
        Update an existing zone.

        Provider API docs:
        https://www.zerigo.com/docs/apis/dns/1.1/zones/update

        @inherits: :class:`DNSDriver.update_zone`
        """
        if domain:
            raise LibcloudError('Domain cannot be changed', driver=self)

        path = API_ROOT + 'zones/%s.xml' % (zone.id)
        zone_elem = self._to_zone_elem(domain=domain,
                                       type=type,
                                       ttl=ttl,
                                       extra=extra)
        response = self.connection.request(action=path,
                                           data=ET.tostring(zone_elem),
                                           method='PUT')
        assert response.status == httplib.OK

        merged = merge_valid_keys(params=copy.deepcopy(zone.extra),
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        updated_zone = get_new_obj(obj=zone,
                                   klass=Zone,
                                   attributes={
                                       'type': type,
                                       'ttl': ttl,
                                       'extra': merged
                                   })
        return updated_zone
예제 #26
0
    def update_record(self,
                      record,
                      name=None,
                      type=None,
                      data=None,
                      extra=None):
        path = API_ROOT + 'hosts/%s.xml' % (record.id)
        record_elem = self._to_record_elem(name=name,
                                           type=type,
                                           data=data,
                                           extra=extra)
        response = self.connection.request(action=path,
                                           data=ET.tostring(record_elem),
                                           method='PUT')
        assert response.status == httplib.OK

        merged = merge_valid_keys(params=copy.deepcopy(record.extra),
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)
        updated_record = get_new_obj(obj=record,
                                     klass=Record,
                                     attributes={
                                         'type': type,
                                         'data': data,
                                         'extra': merged
                                     })
        return updated_record
예제 #27
0
    def update_zone(self, zone, domain=None, type=None, ttl=None, extra=None):
        """
        Update an existing zone.

        Provider API docs:
        https://www.zerigo.com/docs/apis/dns/1.1/zones/update

        @inherits: :class:`DNSDriver.update_zone`
        """
        if domain:
            raise LibcloudError('Domain cannot be changed', driver=self)

        path = API_ROOT + 'zones/%s.xml' % (zone.id)
        zone_elem = self._to_zone_elem(domain=domain, type=type, ttl=ttl,
                                       extra=extra)
        response = self.connection.request(action=path,
                                           data=ET.tostring(zone_elem),
                                           method='PUT')
        assert response.status == httplib.OK

        merged = merge_valid_keys(params=copy.deepcopy(zone.extra),
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        updated_zone = get_new_obj(obj=zone, klass=Zone,
                                   attributes={'type': type,
                                               'ttl': ttl,
                                               'extra': merged})
        return updated_zone
예제 #28
0
파일: linode.py 프로젝트: wandera/libcloud
    def update_zone(self, zone, domain, type="master", ttl=None, extra=None):
        """
        Update an existing zone.

        :param zone: Zone to update.
        :type  zone: :class:`Zone`

        :param domain: Name of zone
        :type  domain: ``str``

        :param type: Zone type (master / slave).
        :type  type: ``str``

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

        :param extra: Extra attributes ('description', 'expire_sec', \
        'master_ips','refresh_sec', 'retry_sec', 'soa_email','status', 'tags')

        :type  extra: ``dict``

        :rtype: :class:`Zone`
        """
        if not isinstance(zone, Zone):
            raise LinodeExceptionV4("Invalid zone instance")

        attr = {
            "domain": domain,
            "type": type,
        }

        if ttl is not None:
            attr["ttl_sec"] = ttl

        merge_valid_keys(params=attr,
                         valid_keys=VALID_ZONE_EXTRA_PARAMS_V4,
                         extra=extra)

        data = self.connection.request("/v4/domains/%s" % zone.id,
                                       data=json.dumps(attr),
                                       method="PUT").object

        return self._to_zone(data)
예제 #29
0
    def parse_error(self):
        body = self.parse_body()

        errors = body.get('errors', [])

        for error in errors:
            try:
                exception_class, context = self.exceptions[error['code']]
            except KeyError:
                exception_class, context = LibcloudError, []

            kwargs = {
                'value': '{}: {}'.format(error['code'], error['message']),
                'driver': self.connection.driver,
            }

            merge_valid_keys(kwargs, context, self.connection.context)

            raise exception_class(**kwargs)
예제 #30
0
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        """
        @inherits: :class:`DNSDriver.create_zone`

        Note that for users who have more than one account membership,
        the id of the account in which to create the zone must be
        specified via the ``extra`` key ``account``.

        Note that for ``extra`` zone properties, only the ones specified in
        ``ZONE_CREATE_ATTRIBUTES`` can be set at creation time. Additionally,
        setting the ``ttl` property is not supported.
        """
        extra = extra or {}

        account = extra.get('account')
        if account is None:
            memberships = self.ex_get_user_account_memberships()
            memberships = list(itertools.islice(memberships, 2))

            if len(memberships) != 1:
                raise ValueError('must specify account for zone')

            account = memberships[0]['account']['id']

        url = '{}/zones'.format(API_BASE)

        body = {
            'name': domain,
            'account': {
                'id': account
            },
            'type': LIBCLOUD_TO_CLOUDFLARE_ZONE_TYPE[type]
        }

        merge_valid_keys(body, ZONE_CREATE_ATTRIBUTES, extra)

        response = self.connection.request(url, data=body, method='POST')

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

        return zone
예제 #31
0
파일: linode.py 프로젝트: wandera/libcloud
    def create_record(self, name, zone, type, data, extra=None):
        """
        Create a record.

        :param name: The name of this Record.For A records\
        this is the subdomain being associated with an IP address.
        :type  name: ``str``

        :param zone: Zone which the records will be created for.
        :type zone: :class:`Zone`

        :param type: DNS record type.
        :type  type: :class:`RecordType`

        :param data: Data for the record (depends on the record type).\
         For A records, this is the address the domain should resolve to.
        :type  data: ``str``

        :param extra: Extra attributes.('port', 'priority', \
        'protocol', 'service', 'tag', 'ttl_sec', 'target', 'weight')
        :type  extra: ``dict``

        :rtype: :class:`Record`
        """
        if not isinstance(zone, Zone):
            raise LinodeExceptionV4("Invalid zone instance")

        attr = {
            "type": self.RECORD_TYPE_MAP[type],
            "name": name,
            "target": data,
        }

        merge_valid_keys(params=attr,
                         valid_keys=VALID_RECORD_EXTRA_PARAMS_V4,
                         extra=extra)
        data = self.connection.request("/v4/domains/%s/records" % zone.id,
                                       data=json.dumps(attr),
                                       method="POST").object

        return self._to_record(data, zone=zone)
예제 #32
0
    def parse_error(self):
        body = self.parse_body()

        errors = body.get("errors", [])

        for error in errors:
            error_chain = error.get("error_chain", [])

            error_chain_errors = []
            for chain_error in error_chain:
                error_chain_errors.append(
                    "%s: %s"
                    % (
                        chain_error.get("code", "unknown"),
                        chain_error.get("message", ""),
                    )
                )

            try:
                exception_class, context = self.exceptions[error["code"]]
            except KeyError:
                exception_class, context = LibcloudError, []

            kwargs = {
                "value": "{}: {} (error chain: {})".format(
                    error["code"], error["message"], ", ".join(error_chain_errors)
                ),
                "driver": self.connection.driver,
            }

            if error["code"] == 81057:
                # Record id is not available when creating a record and not
                # updating it
                kwargs["record_id"] = "unknown"

            merge_valid_keys(kwargs, context, self.connection.context)

            raise exception_class(**kwargs)
예제 #33
0
    def update_record(self,
                      record,
                      name=None,
                      type=None,
                      data=None,
                      extra=None):
        # Only data, ttl, and comment attributes can be modified, but name
        # attribute must always be present.
        extra = extra if extra else {}

        name = self._to_full_record_name(domain=record.zone.domain,
                                         name=record.name)
        payload = {"name": name}

        if data:
            payload["data"] = data

        if "ttl" in extra:
            payload["ttl"] = extra["ttl"]

        if "comment" in extra:
            payload["comment"] = extra["comment"]

        type = type if type is not None else record.type
        data = data if data else record.data

        self.connection.set_context({"resource": "record", "id": record.id})
        self.connection.async_request(
            action="/domains/%s/records/%s" % (record.zone.id, record.id),
            method="PUT",
            data=payload,
        )

        merged = merge_valid_keys(
            params=copy.deepcopy(record.extra),
            valid_keys=VALID_RECORD_EXTRA_PARAMS,
            extra=extra,
        )
        updated_record = get_new_obj(
            obj=record,
            klass=Record,
            attributes={
                "type": type,
                "data": data,
                "driver": self,
                "extra": merged
            },
        )
        return updated_record
예제 #34
0
파일: linode.py 프로젝트: wandera/libcloud
    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``

        :keyword type: Zone type (master / slave).
        :type  type: ``str``

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

        :keyword extra: Extra attributes.('description', 'expire_sec', \
        'master_ips','refresh_sec', 'retry_sec', 'soa_email',\
        'status', 'tags'). 'soa_email' required for master zones
        :type extra: ``dict``

        :rtype: :class:`Zone`
        """

        attr = {
            "domain": domain,
            "type": type,
        }
        if ttl is not None:
            attr["ttl_sec"] = ttl

        merge_valid_keys(params=attr,
                         valid_keys=VALID_ZONE_EXTRA_PARAMS_V4,
                         extra=extra)
        data = self.connection.request("/v4/domains",
                                       data=json.dumps(attr),
                                       method="POST").object

        return self._to_zone(data)
예제 #35
0
파일: linode.py 프로젝트: xiama/automations
    def create_record(self, name, zone, type, data, extra=None):
        """
        Create a new record.

        API docs: http://www.linode.com/api/dns/domain.resource.create
        """
        params = {'api_action': 'domain.resource.create', 'DomainID': zone.id,
                  'Name': name, 'Target': data, 'Type': RECORD_TYPE_MAP[type]}
        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)

        result = self.connection.request(API_ROOT, params=params).objects[0]
        record = Record(id=result['ResourceID'], name=name, type=type,
                        data=data, extra=merged, zone=zone, driver=self)
        return record
예제 #36
0
    def update_record(self, record, name=None, type=None, data=None,
                      extra=None):
        path = API_ROOT + 'hosts/%s.xml' % (record.id)
        record_elem = self._to_record_elem(name=name, type=type, data=data,
                                           extra=extra)
        response = self.connection.request(action=path,
                                           data=ET.tostring(record_elem),
                                           method='PUT')
        assert response.status == httplib.OK

        merged = merge_valid_keys(params=copy.deepcopy(record.extra),
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)
        updated_record = get_new_obj(obj=record, klass=Record,
                                     attributes={'type': type,
                                                 'data': data,
                                                 'extra': merged})
        return updated_record
예제 #37
0
파일: linode.py 프로젝트: xiama/automations
    def create_zone(self, domain, type='master', ttl=None, extra=None):
        """
        Create a new zone.

        API docs: http://www.linode.com/api/dns/domain.create
        """
        params = {'api_action': 'domain.create', 'Type': type,
                  'Domain': domain}

        if ttl:
            params['TTL_sec'] = ttl

        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_ZONE_EXTRA_PARAMS,
                                  extra=extra)
        data = self.connection.request(API_ROOT, params=params).objects[0]
        zone = Zone(id=data['DomainID'], domain=domain, type=type, ttl=ttl,
                    extra=merged, driver=self)
        return zone
예제 #38
0
파일: linode.py 프로젝트: wandera/libcloud
    def update_record(self,
                      record,
                      name=None,
                      type=None,
                      data=None,
                      extra=None):
        """
        Update an existing record.

        API docs: http://www.linode.com/api/dns/domain.resource.update
        """
        params = {
            "api_action": "domain.resource.update",
            "ResourceID": record.id,
            "DomainID": record.zone.id,
        }

        if name:
            params["Name"] = name

        if data:
            params["Target"] = data

        if type is not None:
            params["Type"] = self.RECORD_TYPE_MAP[type]

        merged = merge_valid_keys(params=params,
                                  valid_keys=VALID_RECORD_EXTRA_PARAMS,
                                  extra=extra)

        self.connection.request(API_ROOT, params=params).objects[0]
        updated_record = get_new_obj(
            obj=record,
            klass=Record,
            attributes={
                "name": name,
                "data": data,
                "type": type,
                "extra": merged
            },
        )
        return updated_record
예제 #39
0
 def create_record(self, name, zone, type, data, extra=None):
     params = {
         'name': name,
         'type': self.RECORD_TYPE_MAP[type],
         'domain_id': zone.id,
         'content': data
     }
     merged = merge_valid_keys(
         params=params,
         valid_keys=VALID_RECORD_EXTRA_PARAMS,
         extra=extra
     )
     self.connection.set_context({'resource': 'zone', 'id': zone.id})
     result = self.connection.request(
         API_ROOT + '/dns/record/',
         data=json.dumps(params), method='POST').object
     record = Record(id=result['id'], name=name,
                     type=type, data=data,
                     extra=merged, zone=zone, driver=self)
     return record