summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhu.boxiang <zhu.boxiang@99cloud.net>2019-03-26 15:48:46 +0800
committerMatt Riedemann <mriedem.os@gmail.com>2019-07-08 19:26:01 +0000
commit41c25881e669b1ebe6211615dd8d2b24a1db23dc (patch)
tree473ae2d29f9d92ad79d7e474664e20e9cb910e14
parent4bfcc1a9faae1c505266abd0e2a61b8b3cf621f4 (diff)
downloadpython-novaclient-41c25881e669b1ebe6211615dd8d2b24a1db23dc.tar.gz
Add host and hypervisor_hostname to create servers
Adds the --host and --hypervisor-hostname options to the nova boot command and related python API bindings. Depends-On: https://review.opendev.org/#/c/645520/ Change-Id: If16d00b75f4d5f2b96aa6e3f32a973108049d928 Blueprint: add-host-and-hypervisor-hostname-flag-to-create-server
-rw-r--r--doc/source/cli/nova.rst10
-rw-r--r--novaclient/__init__.py2
-rw-r--r--novaclient/tests/unit/v2/test_servers.py96
-rw-r--r--novaclient/tests/unit/v2/test_shell.py78
-rw-r--r--novaclient/v2/servers.py30
-rw-r--r--novaclient/v2/shell.py21
-rw-r--r--releasenotes/notes/microversion-v2_74-43b128fe6b84b630.yaml9
7 files changed, 242 insertions, 4 deletions
diff --git a/doc/source/cli/nova.rst b/doc/source/cli/nova.rst
index 1fb28798..f93c3124 100644
--- a/doc/source/cli/nova.rst
+++ b/doc/source/cli/nova.rst
@@ -952,6 +952,8 @@ nova boot
[--description <description>] [--tags <tags>]
[--return-reservation-id]
[--trusted-image-certificate-id <trusted-image-certificate-id>]
+ [--host <host>]
+ [--hypervisor-hostname <hypervisor-hostname>]
<name>
Boot a new server.
@@ -1117,6 +1119,14 @@ quality of service support, microversion ``2.72`` is required.
May be specified multiple times to pass multiple trusted image
certificate IDs. (Supported by API versions '2.63' - '2.latest')
+``--host <host>``
+ Requested host to create servers. Admin only by default.
+ (Supported by API versions '2.74' - '2.latest')
+
+``--hypervisor-hostname <hypervisor-hostname>``
+ Requested hypervisor hostname to create servers. Admin only by default.
+ (Supported by API versions '2.74' - '2.latest')
+
.. _nova_cell-capacities:
nova cell-capacities
diff --git a/novaclient/__init__.py b/novaclient/__init__.py
index 304660c9..fb9a485e 100644
--- a/novaclient/__init__.py
+++ b/novaclient/__init__.py
@@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
# when client supported the max version, and bumped sequentially, otherwise
# the client may break due to server side new version may include some
# backward incompatible change.
-API_MAX_VERSION = api_versions.APIVersion("2.73")
+API_MAX_VERSION = api_versions.APIVersion("2.74")
diff --git a/novaclient/tests/unit/v2/test_servers.py b/novaclient/tests/unit/v2/test_servers.py
index 5410f1b3..62c8d8d4 100644
--- a/novaclient/tests/unit/v2/test_servers.py
+++ b/novaclient/tests/unit/v2/test_servers.py
@@ -1743,3 +1743,99 @@ class ServersV273Test(ServersV268Test):
self.assert_called('GET', '/servers/detail?locked=False')
for s in sl:
self.assertIsInstance(s, servers.Server)
+
+
+class ServersV274Test(ServersV273Test):
+
+ api_version = "2.74"
+
+ def test_create_server_with_host(self):
+ self.cs.servers.create(
+ name="My server",
+ image=1,
+ flavor=1,
+ nics="auto",
+ host="new-host"
+ )
+ self.assert_called('POST', '/servers',
+ {'server': {
+ 'flavorRef': '1',
+ 'imageRef': '1',
+ 'max_count': 1,
+ 'min_count': 1,
+ 'name': 'My server',
+ 'networks': 'auto',
+ 'host': 'new-host'
+ }}
+ )
+
+ def test_create_server_with_hypervisor_hostname(self):
+ self.cs.servers.create(
+ name="My server",
+ image=1,
+ flavor=1,
+ nics="auto",
+ hypervisor_hostname="new-host"
+ )
+ self.assert_called('POST', '/servers',
+ {'server': {
+ 'flavorRef': '1',
+ 'imageRef': '1',
+ 'max_count': 1,
+ 'min_count': 1,
+ 'name': 'My server',
+ 'networks': 'auto',
+ 'hypervisor_hostname': 'new-host'
+ }}
+ )
+
+ def test_create_server_with_host_and_hypervisor_hostname(self):
+ self.cs.servers.create(
+ name="My server",
+ image=1,
+ flavor=1,
+ nics="auto",
+ host="new-host",
+ hypervisor_hostname="new-host"
+ )
+ self.assert_called('POST', '/servers',
+ {'server': {
+ 'flavorRef': '1',
+ 'imageRef': '1',
+ 'max_count': 1,
+ 'min_count': 1,
+ 'name': 'My server',
+ 'networks': 'auto',
+ 'host': 'new-host',
+ 'hypervisor_hostname': 'new-host'
+ }}
+ )
+
+ def test_create_server_with_host_pre_274_fails(self):
+ self.cs.api_version = api_versions.APIVersion('2.73')
+ ex = self.assertRaises(exceptions.UnsupportedAttribute,
+ self.cs.servers.create,
+ name="My server", image=1, flavor=1,
+ nics='auto', host="new-host")
+ self.assertIn("'host' argument is only allowed since microversion "
+ "2.74", six.text_type(ex))
+
+ def test_create_server_with_hypervisor_hostname_pre_274_fails(self):
+ self.cs.api_version = api_versions.APIVersion('2.73')
+ ex = self.assertRaises(exceptions.UnsupportedAttribute,
+ self.cs.servers.create,
+ name="My server", image=1, flavor=1,
+ nics='auto', hypervisor_hostname="new-host")
+ self.assertIn("'hypervisor_hostname' argument is only allowed since "
+ "microversion 2.74", six.text_type(ex))
+
+ def test_create_server_with_host_and_hypervisor_hostname_pre_274_fails(
+ self):
+ self.cs.api_version = api_versions.APIVersion('2.73')
+ ex = self.assertRaises(exceptions.UnsupportedAttribute,
+ self.cs.servers.create,
+ name="My server", image=1, flavor=1,
+ nics='auto', host="new-host",
+ hypervisor_hostname="new-host")
+ self.assertIn("'host' argument is only allowed since microversion "
+ "2.74", six.text_type(ex))
diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py
index 354475dc..30ee8bc7 100644
--- a/novaclient/tests/unit/v2/test_shell.py
+++ b/novaclient/tests/unit/v2/test_shell.py
@@ -1374,6 +1374,83 @@ class ShellTest(utils.TestCase):
self.assertIn('Instance %s could not be found.' % FAKE_UUID_1,
six.text_type(ex))
+ def test_boot_with_host_v274(self):
+ self.run_command('boot --flavor 1 --image %s '
+ '--host new-host --nic auto '
+ 'some-server' % FAKE_UUID_1,
+ api_version='2.74')
+ self.assert_called_anytime(
+ 'POST', '/servers',
+ {'server': {
+ 'flavorRef': '1',
+ 'name': 'some-server',
+ 'imageRef': FAKE_UUID_1,
+ 'min_count': 1,
+ 'max_count': 1,
+ 'networks': 'auto',
+ 'host': 'new-host',
+ }},
+ )
+
+ def test_boot_with_hypervisor_hostname_v274(self):
+ self.run_command('boot --flavor 1 --image %s --nic auto '
+ '--hypervisor-hostname new-host '
+ 'some-server' % FAKE_UUID_1,
+ api_version='2.74')
+ self.assert_called_anytime(
+ 'POST', '/servers',
+ {'server': {
+ 'flavorRef': '1',
+ 'name': 'some-server',
+ 'imageRef': FAKE_UUID_1,
+ 'min_count': 1,
+ 'max_count': 1,
+ 'networks': 'auto',
+ 'hypervisor_hostname': 'new-host',
+ }},
+ )
+
+ def test_boot_with_host_and_hypervisor_hostname_v274(self):
+ self.run_command('boot --flavor 1 --image %s '
+ '--host new-host --nic auto '
+ '--hypervisor-hostname new-host '
+ 'some-server' % FAKE_UUID_1,
+ api_version='2.74')
+ self.assert_called_anytime(
+ 'POST', '/servers',
+ {'server': {
+ 'flavorRef': '1',
+ 'name': 'some-server',
+ 'imageRef': FAKE_UUID_1,
+ 'min_count': 1,
+ 'max_count': 1,
+ 'networks': 'auto',
+ 'host': 'new-host',
+ 'hypervisor_hostname': 'new-host',
+ }},
+ )
+
+ def test_boot_with_host_pre_v274(self):
+ cmd = ('boot --flavor 1 --image %s --nic auto '
+ '--host new-host some-server'
+ % FAKE_UUID_1)
+ self.assertRaises(SystemExit, self.run_command,
+ cmd, api_version='2.73')
+
+ def test_boot_with_hypervisor_hostname_pre_v274(self):
+ cmd = ('boot --flavor 1 --image %s --nic auto '
+ '--hypervisor-hostname new-host some-server'
+ % FAKE_UUID_1)
+ self.assertRaises(SystemExit, self.run_command,
+ cmd, api_version='2.73')
+
+ def test_boot_with_host_and_hypervisor_hostname_pre_v274(self):
+ cmd = ('boot --flavor 1 --image %s --nic auto '
+ '--host new-host --hypervisor-hostname new-host some-server'
+ % FAKE_UUID_1)
+ self.assertRaises(SystemExit, self.run_command,
+ cmd, api_version='2.73')
+
def test_flavor_list(self):
out, _ = self.run_command('flavor-list')
self.assert_called_anytime('GET', '/flavors/detail')
@@ -4185,6 +4262,7 @@ class ShellTest(utils.TestCase):
70, # There are no version-wrapped shell method changes for this.
71, # There are no version-wrapped shell method changes for this.
72, # There are no version-wrapped shell method changes for this.
+ 74, # There are no version-wrapped shell method changes for this.
])
versions_supported = set(range(0,
novaclient.API_MAX_VERSION.ver_minor + 1))
diff --git a/novaclient/v2/servers.py b/novaclient/v2/servers.py
index 3f003c93..f9f176d2 100644
--- a/novaclient/v2/servers.py
+++ b/novaclient/v2/servers.py
@@ -694,7 +694,8 @@ class ServerManager(base.BootingManagerWithFind):
block_device_mapping_v2=None, nics=None, scheduler_hints=None,
config_drive=None, admin_pass=None, disk_config=None,
access_ip_v4=None, access_ip_v6=None, description=None,
- tags=None, trusted_image_certificates=None, **kwargs):
+ tags=None, trusted_image_certificates=None,
+ host=None, hypervisor_hostname=None, **kwargs):
"""
Create (boot) a new server.
"""
@@ -817,6 +818,12 @@ class ServerManager(base.BootingManagerWithFind):
body['server']['trusted_image_certificates'] = (
trusted_image_certificates)
+ if host:
+ body['server']['host'] = host
+
+ if hypervisor_hostname:
+ body['server']['hypervisor_hostname'] = hypervisor_hostname
+
return self._create('/servers', body, response_key,
return_raw=return_raw, **kwargs)
@@ -1267,7 +1274,9 @@ class ServerManager(base.BootingManagerWithFind):
nics=None, scheduler_hints=None,
config_drive=None, disk_config=None, admin_pass=None,
access_ip_v4=None, access_ip_v6=None,
- trusted_image_certificates=None, **kwargs):
+ trusted_image_certificates=None,
+ host=None, hypervisor_hostname=None,
+ **kwargs):
# TODO(anthony): indicate in doc string if param is an extension
# and/or optional
"""
@@ -1334,6 +1343,10 @@ class ServerManager(base.BootingManagerWithFind):
server as tags (allowed since microversion 2.52)
:param trusted_image_certificates: A list of trusted certificate IDs
(allowed since microversion 2.63)
+ :param host: requested host to create servers
+ (allowed since microversion 2.74)
+ :param hypervisor_hostname: requested hypervisor hostname to create
+ servers (allowed since microversion 2.74)
"""
if not min_count:
min_count = 1
@@ -1388,6 +1401,15 @@ class ServerManager(base.BootingManagerWithFind):
"Block device volume_type is not supported before "
"microversion 2.67")
+ host_microversion = api_versions.APIVersion("2.74")
+ if host and self.api_version < host_microversion:
+ raise exceptions.UnsupportedAttribute("host", "2.74")
+ hypervisor_hostname_microversion = api_versions.APIVersion("2.74")
+ if (hypervisor_hostname and
+ self.api_version < hypervisor_hostname_microversion):
+ raise exceptions.UnsupportedAttribute(
+ "hypervisor_hostname", "2.74")
+
boot_kwargs = dict(
meta=meta, files=files, userdata=userdata,
reservation_id=reservation_id, min_count=min_count,
@@ -1396,7 +1418,9 @@ class ServerManager(base.BootingManagerWithFind):
scheduler_hints=scheduler_hints, config_drive=config_drive,
disk_config=disk_config, admin_pass=admin_pass,
access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6,
- trusted_image_certificates=trusted_image_certificates, **kwargs)
+ trusted_image_certificates=trusted_image_certificates,
+ host=host, hypervisor_hostname=hypervisor_hostname,
+ **kwargs)
if block_device_mapping:
boot_kwargs['block_device_mapping'] = block_device_mapping
diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py
index 6653aa2f..3ab22032 100644
--- a/novaclient/v2/shell.py
+++ b/novaclient/v2/shell.py
@@ -517,6 +517,12 @@ def _boot(cs, args):
if 'tags' in args and args.tags:
boot_kwargs["tags"] = args.tags.split(',')
+ if 'host' in args and args.host:
+ boot_kwargs["host"] = args.host
+
+ if 'hypervisor_hostname' in args and args.hypervisor_hostname:
+ boot_kwargs["hypervisor_hostname"] = args.hypervisor_hostname
+
if include_files:
boot_kwargs['files'] = files
@@ -942,6 +948,21 @@ def _boot(cs, args):
'May be specified multiple times to pass multiple trusted image '
'certificate IDs.'),
start_version="2.63")
+@utils.arg(
+ '--host',
+ metavar='<host>',
+ dest='host',
+ default=None,
+ help=_('Requested host to create servers. Admin only by default.'),
+ start_version="2.74")
+@utils.arg(
+ '--hypervisor-hostname',
+ metavar='<hypervisor-hostname>',
+ dest='hypervisor_hostname',
+ default=None,
+ help=_('Requested hypervisor hostname to create servers. Admin only by '
+ 'default.'),
+ start_version="2.74")
def do_boot(cs, args):
"""Boot a new server."""
boot_args, boot_kwargs = _boot(cs, args)
diff --git a/releasenotes/notes/microversion-v2_74-43b128fe6b84b630.yaml b/releasenotes/notes/microversion-v2_74-43b128fe6b84b630.yaml
new file mode 100644
index 00000000..de98f866
--- /dev/null
+++ b/releasenotes/notes/microversion-v2_74-43b128fe6b84b630.yaml
@@ -0,0 +1,9 @@
+---
+features:
+ - |
+ Support is added for the `2.74 microversion`_ which allows specifying the
+ ``--host`` and ``--hypervisor-hostname`` options on the ``nova boot``
+ command. The ``novaclient.v2.servers.ServerManager.create()`` method now
+ also supports ``host`` and ``hypervisor_hostname`` parameters.
+
+ .. _2.74 microversion: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id66