libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From GitBox <...@apache.org>
Subject [GitHub] [libcloud] Kami commented on a change in pull request #1292: [LIBCLOUD-1001] Update Cloudflare DNS driver to API v4
Date Mon, 15 Jul 2019 19:50:58 GMT
Kami commented on a change in pull request #1292: [LIBCLOUD-1001] Update Cloudflare DNS driver
to API v4
URL: https://github.com/apache/libcloud/pull/1292#discussion_r303606236
 
 

 ##########
 File path: libcloud/dns/drivers/cloudflare.py
 ##########
 @@ -141,290 +159,252 @@ class CloudFlareDNSDriver(DNSDriver):
         RecordType.URL: 'LOC'
     }
 
+    PAGE_SIZE = 20
+
     def iterate_zones(self):
-        # TODO: Support pagination
-        result = self.connection.request(action='zone_load_multi').object
-        zones = self._to_zones(data=result['response']['zones']['objs'])
+        def _iterate_zones(params):
+            url = '{}/zones'.format(API_BASE)
+
+            response = self.connection.request(url, params=params)
+
+            items = response.object['result']
+            zones = [self._to_zone(item) for item in items]
 
-        return zones
+            return zones
+
+        return self._paginate(_iterate_zones)
 
     def iterate_records(self, zone):
-        # TODO: Support pagination
-        params = {'z': zone.domain}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='rec_load_all', params=params)
-        data = resp.object['response']['recs']['objs']
-        records = self._to_records(zone=zone, data=data)
-        return records
+        def _iterate_records(params):
+            url = '{}/zones/{}/dns_records'.format(API_BASE, zone.id)
+
+            self.connection.set_context({'zone_id': zone.id})
+            response = self.connection.request(url, params=params)
+
+            items = response.object['result']
+            records = [self._to_record(zone, item) for item in items]
+
+            return records
+
+        return self._paginate(_iterate_records)
 
     def get_zone(self, zone_id):
-        # TODO: This is not efficient
-        zones = self.list_zones()
+        url = '{}/zones/{}'.format(API_BASE, zone_id)
+
+        self.connection.set_context({'zone_id': zone_id})
+        response = self.connection.request(url)
 
-        try:
-            zone = [z for z in zones if z.id == zone_id][0]
-        except IndexError:
-            raise ZoneDoesNotExistError(value='', driver=self, zone_id=zone_id)
+        item = response.object['result']
+        zone = self._to_zone(item)
 
         return zone
 
-    def create_record(self, name, zone, type, data, extra=None):
+    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 {}
-        params = {'name': name, 'z': zone.domain, 'type': type,
-                  'content': data}
 
-        params['ttl'] = extra.get('ttl', 120)
+        account = extra.get('account')
+        if account is None:
+            memberships = self.ex_get_user_account_memberships()
+            memberships = list(itertools.islice(memberships, 2))
 
-        if 'priority' in extra:
-            # For MX and SRV records
-            params['prio'] = extra['priority']
+            if len(memberships) != 1:
+                raise ValueError('must specify account for zone')
 
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='rec_new', params=params)
-        item = resp.object['response']['rec']['obj']
-        record = self._to_record(zone=zone, item=item)
-        return record
+            account = memberships[0]['account']['id']
 
-    def update_record(self, record, name=None, type=None, data=None,
-                      extra=None):
-        extra = extra or {}
-        params = {'z': record.zone.domain, 'id': record.id}
+        url = '{}/zones'.format(API_BASE)
 
-        params['name'] = name or record.name
-        params['type'] = type or record.type
-        params['content'] = data or record.data
-        params['ttl'] = extra.get('ttl', None) or record.extra['ttl']
+        body = {
+            'name': domain,
+            'account': {
+                'id': account
+            },
+            'type': LIBCLOUD_TO_CLOUDFLARE_ZONE_TYPE[type]
+        }
 
-        self.connection.set_context({'zone_domain': record.zone.domain})
-        self.connection.set_context({'record_id': record.id})
-        resp = self.connection.request(action='rec_edit', params=params)
-        item = resp.object['response']['rec']['obj']
-        record = self._to_record(zone=record.zone, item=item)
-        return record
+        merge_valid_keys(body, ZONE_CREATE_ATTRIBUTES, extra)
 
-    def delete_record(self, record):
-        params = {'z': record.zone.domain, 'id': record.id}
-        self.connection.set_context({'zone_domain': record.zone.domain})
-        self.connection.set_context({'record_id': record.id})
-        resp = self.connection.request(action='rec_delete', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
-
-    def ex_get_zone_stats(self, zone, interval=30):
-        params = {'z': zone.domain, 'interval': interval}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='stats', params=params)
-        result = resp.object['response']['result']['objs'][0]
-        return result
-
-    def ex_zone_check(self, zones):
-        zone_domains = [zone.domain for zone in zones]
-        zone_domains = ','.join(zone_domains)
-        params = {'zones': zone_domains}
-        resp = self.connection.request(action='zone_check', params=params)
-        result = resp.object['response']['zones']
-        return result
-
-    def ex_get_ip_threat_score(self, ip):
-        """
-        Retrieve current threat score for a given IP. Note that scores are on
-        a logarithmic scale, where a higher score indicates a higher threat.
-        """
-        params = {'ip': ip}
-        resp = self.connection.request(action='ip_lkup', params=params)
-        result = resp.object['response']
-        return result
+        response = self.connection.request(url, data=body, method='POST')
 
-    def ex_get_zone_settings(self, zone):
-        """
-        Retrieve all current settings for a given zone.
-        """
-        params = {'z': zone.domain}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='zone_settings', params=params)
-        result = resp.object['response']['result']['objs'][0]
-        return result
+        item = response.object['result']
+        zone = self._to_zone(item)
 
-    def ex_set_zone_security_level(self, zone, level):
-        """
-        Set the zone Basic Security Level to I'M UNDER ATTACK! / HIGH /
-        MEDIUM / LOW / ESSENTIALLY OFF.
+        return zone
 
-        :param level: Security level. Valid values are: help, high, med, low,
-                      eoff.
-        :type level: ``str``
+    def update_zone(self, zone, domain, type='master', ttl=None, extra=None):
         """
-        params = {'z': zone.domain, 'v': level}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='sec_lvl', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
+        @inherits: :class:`DNSDriver.update_zone`
 
-    def ex_set_zone_cache_level(self, zone, level):
+        Note that the ``zone``, ``type`` and ``ttl`` properties can't be
+        updated. The only updatable properties are the ``extra`` zone
+        properties specified in ``ZONE_UPDATE_ATTRIBUTES``. Only one property
+        may be updated at a time. Any non-updatable properties are ignored.
         """
-        Set the zone caching level.
+        body = merge_valid_keys({}, ZONE_UPDATE_ATTRIBUTES, extra)
+        if len(body) != 1:
+            return zone
 
-        :param level: Caching level. Valid values are: agg (aggresive), basic.
-        :type level: ``str``
-        """
-        params = {'z': zone.domain, 'v': level}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='cache_lvl', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
+        url = '{}/zones/{}'.format(API_BASE, zone.id)
 
-    def ex_enable_development_mode(self, zone):
-        """
-        Enable development mode. When Development Mode is on the cache is
-        bypassed. Development mode remains on for 3 hours or until when it is
-        toggled back off.
-        """
-        params = {'z': zone.domain, 'v': 1}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='devmode', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
+        self.connection.set_context({'zone_id': zone.id})
+        response = self.connection.request(url, data=body, method='PATCH')
 
-    def ex_disable_development_mode(self, zone):
-        """
-        Disable development mode.
-        """
-        params = {'z': zone.domain, 'v': 0}
-        self.connection.set_context({'zone_domain': zone.domain})
-        resp = self.connection.request(action='devmode', params=params)
-        result = resp.object
-        return result.get('result', None) == 'success'
+        item = response.object['result']
+        zone = self._to_zone(item)
 
-    def ex_purge_cached_files(self, zone):
 
 Review comment:
   It looks like some of those extension methods haven't been implemented in the v4 driver.
   
   Not a big deal for now, but eventually it would be good to implement the ones which are
still supported by v4 API.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

Mime
View raw message