Allow the OSC CLI Plugin to walk pages

Change-Id: I5587ad816c99dc159f2c1a5660450a631ddecd6e
Closes-Bug: #1538611
This commit is contained in:
Graham Hayes 2016-01-27 20:11:44 +00:00
parent 24dd22d431
commit 8f3e935f77
10 changed files with 102 additions and 10 deletions

1
.gitignore vendored
View File

@ -23,3 +23,4 @@ dist
designateclient/versioninfo
.testrepository
*.log
.idea/

View File

@ -0,0 +1,43 @@
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
#
# Author: Graham Hayes <endre.karlson@hp.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from designateclient import client
from designateclient.v2.utils import parse_query_from_url
class DesignateList(list):
next_link_criterion = {}
next_page = False
class V2Controller(client.Controller):
def _get(self, url, response_key=None):
resp, body = self.client.session.get(url)
if response_key is not None:
data = DesignateList()
data.extend(body[response_key])
if 'next' in body.get('links', {}):
data.next_page = True
data.next_link_criterion = parse_query_from_url(
body['links']['next'])
return data
return body

View File

@ -22,6 +22,7 @@ from cliff import show
import six
from designateclient import utils
from designateclient.v2.utils import get_all
LOG = logging.getLogger(__name__)
@ -40,7 +41,7 @@ class ListBlacklistsCommand(lister.Lister):
client = self.app.client_manager.dns
cols = self.columns
data = client.blacklists.list()
data = get_all(client.blacklists.list)
return cols, (utils.get_item_properties(s, cols) for s in data)

View File

@ -22,6 +22,7 @@ from cliff import show
import six
from designateclient import utils
from designateclient.v2.utils import get_all
LOG = logging.getLogger(__name__)
@ -48,7 +49,8 @@ class ListRecordSetsCommand(lister.Lister):
client = self.app.client_manager.dns
cols = self.columns
data = client.recordsets.list(parsed_args.zone_id)
data = get_all(client.recordsets.list, args=[parsed_args.zone_id])
six.moves.map(_format_recordset, data)
return cols, (utils.get_item_properties(s, cols) for s in data)

View File

@ -22,6 +22,7 @@ from cliff import show
import six
from designateclient import utils
from designateclient.v2.utils import get_all
LOG = logging.getLogger(__name__)
@ -40,7 +41,7 @@ class ListFloatingIPCommand(lister.Lister):
client = self.app.client_manager.dns
cols = self.columns
data = client.floatingips.list()
data = get_all(client.floatingips.list)
return cols, (utils.get_item_properties(s, cols) for s in data)

View File

@ -22,6 +22,7 @@ from cliff import show
import six
from designateclient import utils
from designateclient.v2.utils import get_all
LOG = logging.getLogger(__name__)
@ -39,7 +40,7 @@ class ListTLDsCommand(lister.Lister):
def take_action(self, parsed_args):
client = self.app.client_manager.dns
data = client.tlds.list()
data = get_all(client.tlds.list)
cols = self.columns
return cols, (utils.get_item_properties(s, cols) for s in data)

View File

@ -23,6 +23,7 @@ from openstackclient.common import exceptions as osc_exc
import six
from designateclient import utils
from designateclient.v2.utils import get_all
LOG = logging.getLogger(__name__)
@ -73,7 +74,7 @@ class ListZonesCommand(lister.Lister):
if parsed_args.status is not None:
criterion["status"] = parsed_args.status
data = client.zones.list(criterion=criterion)
data = get_all(client.zones.list, criterion)
cols = self.columns
return cols, (utils.get_item_properties(s, cols) for s in data)

View File

@ -16,11 +16,11 @@
from oslo_utils import uuidutils
import six
from designateclient import client
from designateclient.v2.base import V2Controller
from designateclient.v2 import utils as v2_utils
class RecordSetController(client.Controller):
class RecordSetController(V2Controller):
def _canonicalize_record_name(self, zone, name):
zone_info = None

View File

@ -13,7 +13,12 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_utils import uuidutils
from six import iteritems
from six import iterkeys
from six.moves.urllib.parse import parse_qs
from six.moves.urllib.parse import urlparse
from designateclient import exceptions
@ -36,3 +41,40 @@ def resolve_by_name(func, name, *args):
else:
msg = "Multiple matches found for %s, please use ID instead." % name
raise exceptions.NoUniqueMatch(msg)
def parse_query_from_url(url):
"""
Helper to get key bits of data from the "next" url returned
from the API on collections
:param url:
:return: dict
"""
values = parse_qs(urlparse(url)[4])
return {k: values[k][0] for k in iterkeys(values)}
def get_all(function, criterion=None, args=None):
"""
:param function: Function to be called to get data
:param criterion: dict of filters to be applied
:param args: arguments to be given to the function
:return: DesignateList()
"""
criterion = criterion or {}
args = args or []
data = function(*args, criterion=criterion)
returned_data = data
while True:
if data.next_page:
for k, v in iteritems(data.next_link_criterion):
criterion[k] = v
data = function(*args, criterion=criterion)
returned_data.extend(data)
else:
break
return returned_data

View File

@ -13,11 +13,11 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from designateclient import client
from designateclient.v2.base import V2Controller
from designateclient.v2 import utils as v2_utils
class ZoneController(client.Controller):
class ZoneController(V2Controller):
def create(self, name, type_=None, email=None, description=None, ttl=None,
masters=None):
type_ = type_ or "PRIMARY"
@ -81,7 +81,7 @@ class ZoneController(client.Controller):
self.client.session.post(url)
class ZoneTransfersController(client.Controller):
class ZoneTransfersController(V2Controller):
def create_request(self, zone, target_project_id, description=None):
zone = v2_utils.resolve_by_name(self.client.zones.list, zone)