Updated Branches: refs/heads/trunk 7fc910a88 -> 8d529766d
Handle Rackspace pagination of DNS records. Rackspace paginates DNS records returned from their API. In iterate_records and iterate_zones, query Rackspace multiple times, if needed, to get the full result. Signed-off-by: Tomaz Muraus <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/caa689d2 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/caa689d2 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/caa689d2 Branch: refs/heads/trunk Commit: caa689d2744af09f8ba389af1d8fd4545747e2db Parents: 7fc910a Author: Roy Wellington â £ <[email protected]> Authored: Tue Dec 10 15:57:02 2013 -0800 Committer: Tomaz Muraus <[email protected]> Committed: Fri Jan 24 22:39:45 2014 +0100 ---------------------------------------------------------------------- libcloud/dns/drivers/rackspace.py | 80 ++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/caa689d2/libcloud/dns/drivers/rackspace.py ---------------------------------------------------------------------- diff --git a/libcloud/dns/drivers/rackspace.py b/libcloud/dns/drivers/rackspace.py index 3410742..84b9ab8 100644 --- a/libcloud/dns/drivers/rackspace.py +++ b/libcloud/dns/drivers/rackspace.py @@ -150,18 +150,47 @@ class RackspaceDNSDriver(DNSDriver, OpenStackDriverMixin): RecordType.PTR: 'PTR', } - def list_zones(self): - response = self.connection.request(action='/domains') - zones = self._to_zones(data=response.object['domains']) - return zones - - def list_records(self, zone): + def iterate_zones(self): + offset = 0 + limit = 100 + while True: + params = { + 'limit': limit, + 'offset': offset, + } + response = self.connection.request( + action='/domains', params=params).object + zones_list = response['domains'] + for item in zones_list: + yield self._to_zone(item) + + if _rackspace_result_has_more(response, len(zones_list), limit): + offset += limit + else: + break + + def iterate_records(self, zone): self.connection.set_context({'resource': 'zone', 'id': zone.id}) - response = self.connection.request(action='/domains/%s' % (zone.id), - params={'showRecord': True}).object - records = self._to_records(data=response['recordsList']['records'], - zone=zone) - return records + offset = 0 + limit = 100 + while True: + params = { + 'showRecord': True, + 'limit': limit, + 'offset': offset, + } + response = self.connection.request( + action='/domains/%s' % (zone.id), params=params).object + records_list = response['recordsList'] + records = records_list['records'] + for item in records: + record = self._to_record(data=item, zone=zone) + yield record + + if _rackspace_result_has_more(records_list, len(records), limit): + offset += limit + else: + break def get_zone(self, zone_id): self.connection.set_context({'resource': 'zone', 'id': zone_id}) @@ -305,14 +334,6 @@ class RackspaceDNSDriver(DNSDriver, OpenStackDriverMixin): method='DELETE') return True - def _to_zones(self, data): - zones = [] - for item in data: - zone = self._to_zone(data=item) - zones.append(zone) - - return zones - def _to_zone(self, data): id = data['id'] domain = data['name'] @@ -330,14 +351,6 @@ class RackspaceDNSDriver(DNSDriver, OpenStackDriverMixin): driver=self, extra=extra) return zone - def _to_records(self, data, zone): - records = [] - for item in data: - record = self._to_record(data=item, zone=zone) - records.append(record) - - return records - def _to_record(self, data, zone): id = data['id'] fqdn = data['name'] @@ -396,6 +409,19 @@ class RackspaceDNSDriver(DNSDriver, OpenStackDriverMixin): return kwargs +def _rackspace_result_has_more(obj, result_length, limit): + # If rackspace returns less than the limit, then we've reached the end of + # the result set. + if result_length < limit: + return False + # Paginated results return links to the previous and next sets of data, but + # 'next' only exists when there is more to get. + for item in obj.get('links', ()): + if item['rel'] == 'next': + return True + return False + + class RackspaceUSDNSDriver(RackspaceDNSDriver): name = 'Rackspace DNS (US)' type = Provider.RACKSPACE_US
