Add support for microversion 2.33
This change allows novaclient to get several hypervisors with the help of new optional parameters 'limit' and 'marker' which were added to hipervisor-list command. Change-Id: Ib723fb1dc1cd57b6f796bb93e0dd8ddf2da4b2a0
This commit is contained in:
parent
48da89e2a2
commit
6bbcedb000
@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
|
|||||||
# when client supported the max version, and bumped sequentially, otherwise
|
# when client supported the max version, and bumped sequentially, otherwise
|
||||||
# the client may break due to server side new version may include some
|
# the client may break due to server side new version may include some
|
||||||
# backward incompatible change.
|
# backward incompatible change.
|
||||||
API_MAX_VERSION = api_versions.APIVersion("2.32")
|
API_MAX_VERSION = api_versions.APIVersion("2.33")
|
||||||
|
@ -16,6 +16,7 @@ import sys
|
|||||||
import mock
|
import mock
|
||||||
from oslo_utils import encodeutils
|
from oslo_utils import encodeutils
|
||||||
import six
|
import six
|
||||||
|
from six.moves.urllib import parse
|
||||||
|
|
||||||
from novaclient import base
|
from novaclient import base
|
||||||
from novaclient import exceptions
|
from novaclient import exceptions
|
||||||
@ -437,3 +438,22 @@ class RecordTimeTestCase(test_utils.TestCase):
|
|||||||
with utils.record_time(times, False, 'x'):
|
with utils.record_time(times, False, 'x'):
|
||||||
pass
|
pass
|
||||||
self.assertEqual(0, len(times))
|
self.assertEqual(0, len(times))
|
||||||
|
|
||||||
|
|
||||||
|
class PrepareQueryStringTestCase(test_utils.TestCase):
|
||||||
|
def test_convert_dict_to_string(self):
|
||||||
|
ustr = b'?\xd0\xbf=1&\xd1\x80=2'
|
||||||
|
if six.PY3:
|
||||||
|
# in py3 real unicode symbols will be urlencoded
|
||||||
|
ustr = ustr.decode('utf8')
|
||||||
|
cases = (
|
||||||
|
({}, ''),
|
||||||
|
({'2': 2, '10': 1}, '?10=1&2=2'),
|
||||||
|
({'abc': 1, 'abc1': 2}, '?abc=1&abc1=2'),
|
||||||
|
({b'\xd0\xbf': 1, b'\xd1\x80': 2}, ustr),
|
||||||
|
({(1, 2): '1', (3, 4): '2'}, '?(1, 2)=1&(3, 4)=2')
|
||||||
|
)
|
||||||
|
for case in cases:
|
||||||
|
self.assertEqual(
|
||||||
|
case[1],
|
||||||
|
parse.unquote_plus(utils.prepare_query_string(case[0])))
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from novaclient import api_versions
|
||||||
from novaclient.tests.unit.fixture_data import client
|
from novaclient.tests.unit.fixture_data import client
|
||||||
from novaclient.tests.unit.fixture_data import hypervisors as data
|
from novaclient.tests.unit.fixture_data import hypervisors as data
|
||||||
from novaclient.tests.unit import utils
|
from novaclient.tests.unit import utils
|
||||||
@ -185,3 +186,16 @@ class HypervisorsTest(utils.FixturedTestCase):
|
|||||||
# Test for Bug #1370415, the line below used to raise AttributeError
|
# Test for Bug #1370415, the line below used to raise AttributeError
|
||||||
self.assertEqual("<HypervisorStats: 2 Hypervisors>",
|
self.assertEqual("<HypervisorStats: 2 Hypervisors>",
|
||||||
result.__repr__())
|
result.__repr__())
|
||||||
|
|
||||||
|
|
||||||
|
class HypervisorsV233Test(HypervisorsTest):
|
||||||
|
def setUp(self):
|
||||||
|
super(HypervisorsV233Test, self).setUp()
|
||||||
|
self.cs.api_version = api_versions.APIVersion("2.33")
|
||||||
|
|
||||||
|
def test_use_limit_marker_params(self):
|
||||||
|
params = {'limit': 10, 'marker': 'fake-marker'}
|
||||||
|
self.cs.hypervisors.list(**params)
|
||||||
|
for k, v in params.items():
|
||||||
|
self.assertIn('%s=%s' % (k, v),
|
||||||
|
self.requests.last_request.path_url)
|
||||||
|
@ -2154,6 +2154,11 @@ class ShellTest(utils.TestCase):
|
|||||||
self.run_command('hypervisor-list --matching hyper')
|
self.run_command('hypervisor-list --matching hyper')
|
||||||
self.assert_called('GET', '/os-hypervisors/hyper/search')
|
self.assert_called('GET', '/os-hypervisors/hyper/search')
|
||||||
|
|
||||||
|
def test_hypervisor_list_limit_marker(self):
|
||||||
|
self.run_command('hypervisor-list --limit 10 --marker hyper1',
|
||||||
|
api_version='2.33')
|
||||||
|
self.assert_called('GET', '/os-hypervisors?limit=10&marker=hyper1')
|
||||||
|
|
||||||
def test_hypervisor_servers(self):
|
def test_hypervisor_servers(self):
|
||||||
self.run_command('hypervisor-servers hyper')
|
self.run_command('hypervisor-servers hyper')
|
||||||
self.assert_called('GET', '/os-hypervisors/hyper/servers')
|
self.assert_called('GET', '/os-hypervisors/hyper/servers')
|
||||||
|
@ -24,6 +24,7 @@ from oslo_utils import encodeutils
|
|||||||
import pkg_resources
|
import pkg_resources
|
||||||
import prettytable
|
import prettytable
|
||||||
import six
|
import six
|
||||||
|
from six.moves.urllib import parse
|
||||||
|
|
||||||
from novaclient import exceptions
|
from novaclient import exceptions
|
||||||
from novaclient.i18n import _
|
from novaclient.i18n import _
|
||||||
@ -465,3 +466,9 @@ def record_time(times, enabled, *args):
|
|||||||
yield
|
yield
|
||||||
end = time.time()
|
end = time.time()
|
||||||
times.append((' '.join(args), start, end))
|
times.append((' '.join(args), start, end))
|
||||||
|
|
||||||
|
|
||||||
|
def prepare_query_string(params):
|
||||||
|
"""Convert dict params to query string"""
|
||||||
|
params = sorted(params.items(), key=lambda x: x[0])
|
||||||
|
return '?%s' % parse.urlencode(params) if params else ''
|
||||||
|
@ -19,7 +19,9 @@ Hypervisors interface (1.1 extension).
|
|||||||
|
|
||||||
from six.moves.urllib import parse
|
from six.moves.urllib import parse
|
||||||
|
|
||||||
|
from novaclient import api_versions
|
||||||
from novaclient import base
|
from novaclient import base
|
||||||
|
from novaclient import utils
|
||||||
|
|
||||||
|
|
||||||
class Hypervisor(base.Resource):
|
class Hypervisor(base.Resource):
|
||||||
@ -33,14 +35,35 @@ class HypervisorManager(base.ManagerWithFind):
|
|||||||
resource_class = Hypervisor
|
resource_class = Hypervisor
|
||||||
is_alphanum_id_allowed = True
|
is_alphanum_id_allowed = True
|
||||||
|
|
||||||
|
def _list_base(self, detailed=True, marker=None, limit=None):
|
||||||
|
path = '/os-hypervisors'
|
||||||
|
if detailed:
|
||||||
|
path += '/detail'
|
||||||
|
params = {}
|
||||||
|
if limit is not None:
|
||||||
|
params['limit'] = int(limit)
|
||||||
|
if marker is not None:
|
||||||
|
params['marker'] = str(marker)
|
||||||
|
path += utils.prepare_query_string(params)
|
||||||
|
return self._list(path, 'hypervisors')
|
||||||
|
|
||||||
|
@api_versions.wraps("2.0", "2.32")
|
||||||
def list(self, detailed=True):
|
def list(self, detailed=True):
|
||||||
"""
|
"""
|
||||||
Get a list of hypervisors.
|
Get a list of hypervisors.
|
||||||
"""
|
"""
|
||||||
detail = ""
|
return self._list_base(detailed=detailed)
|
||||||
if detailed:
|
|
||||||
detail = "/detail"
|
@api_versions.wraps("2.33")
|
||||||
return self._list('/os-hypervisors%s' % detail, 'hypervisors')
|
def list(self, detailed=True, marker=None, limit=None):
|
||||||
|
"""
|
||||||
|
Get a list of hypervisors.
|
||||||
|
:param marker: Begin returning hypervisor that appear later in the
|
||||||
|
keypair list than that represented by this keypair name
|
||||||
|
(optional).
|
||||||
|
:param limit: maximum number of keypairs to return (optional).
|
||||||
|
"""
|
||||||
|
return self._list_base(detailed=detailed, marker=marker, limit=limit)
|
||||||
|
|
||||||
def search(self, hypervisor_match, servers=False):
|
def search(self, hypervisor_match, servers=False):
|
||||||
"""
|
"""
|
||||||
|
@ -3980,6 +3980,22 @@ def _find_hypervisor(cs, hypervisor):
|
|||||||
return utils.find_resource(cs.hypervisors, hypervisor)
|
return utils.find_resource(cs.hypervisors, hypervisor)
|
||||||
|
|
||||||
|
|
||||||
|
def _do_hypervisor_list(cs, matching=None, limit=None, marker=None):
|
||||||
|
columns = ['ID', 'Hypervisor hostname', 'State', 'Status']
|
||||||
|
if matching:
|
||||||
|
utils.print_list(cs.hypervisors.search(matching), columns)
|
||||||
|
else:
|
||||||
|
params = {}
|
||||||
|
if limit is not None:
|
||||||
|
params['limit'] = limit
|
||||||
|
if marker is not None:
|
||||||
|
params['marker'] = marker
|
||||||
|
# Since we're not outputting detail data, choose
|
||||||
|
# detailed=False for server-side efficiency
|
||||||
|
utils.print_list(cs.hypervisors.list(False, **params), columns)
|
||||||
|
|
||||||
|
|
||||||
|
@api_versions.wraps("2.0", "2.32")
|
||||||
@utils.arg(
|
@utils.arg(
|
||||||
'--matching',
|
'--matching',
|
||||||
metavar='<hostname>',
|
metavar='<hostname>',
|
||||||
@ -3987,13 +4003,37 @@ def _find_hypervisor(cs, hypervisor):
|
|||||||
help=_('List hypervisors matching the given <hostname>.'))
|
help=_('List hypervisors matching the given <hostname>.'))
|
||||||
def do_hypervisor_list(cs, args):
|
def do_hypervisor_list(cs, args):
|
||||||
"""List hypervisors."""
|
"""List hypervisors."""
|
||||||
columns = ['ID', 'Hypervisor hostname', 'State', 'Status']
|
_do_hypervisor_list(cs, matching=args.matching)
|
||||||
if args.matching:
|
|
||||||
utils.print_list(cs.hypervisors.search(args.matching), columns)
|
|
||||||
else:
|
@api_versions.wraps("2.33")
|
||||||
# Since we're not outputting detail data, choose
|
@utils.arg(
|
||||||
# detailed=False for server-side efficiency
|
'--matching',
|
||||||
utils.print_list(cs.hypervisors.list(False), columns)
|
metavar='<hostname>',
|
||||||
|
default=None,
|
||||||
|
help=_('List hypervisors matching the given <hostname>. '
|
||||||
|
'If matching is used limit and marker options will be ignored.'))
|
||||||
|
@utils.arg(
|
||||||
|
'--marker',
|
||||||
|
dest='marker',
|
||||||
|
metavar='<marker>',
|
||||||
|
default=None,
|
||||||
|
help=_('The last hypervisor of the previous page; displays list of '
|
||||||
|
'hypervisors after "marker".'))
|
||||||
|
@utils.arg(
|
||||||
|
'--limit',
|
||||||
|
dest='limit',
|
||||||
|
metavar='<limit>',
|
||||||
|
type=int,
|
||||||
|
default=None,
|
||||||
|
help=_("Maximum number of hypervisors to display. If limit == -1, all "
|
||||||
|
"hypervisors will be displayed. If limit is bigger than "
|
||||||
|
"'osapi_max_limit' option of Nova API, limit 'osapi_max_limit' "
|
||||||
|
"will be used instead."))
|
||||||
|
def do_hypervisor_list(cs, args):
|
||||||
|
"""List hypervisors."""
|
||||||
|
_do_hypervisor_list(
|
||||||
|
cs, matching=args.matching, limit=args.limit, marker=args.marker)
|
||||||
|
|
||||||
|
|
||||||
@utils.arg(
|
@utils.arg(
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Added microversion v2.33 that adds pagination support for hypervisors with
|
||||||
|
the help of new optional parameters 'limit' and 'marker' which were added
|
||||||
|
to hypervisor-list command.
|
Loading…
Reference in New Issue
Block a user