Skip to content

Commit 340f25f

Browse files
zhubx007Dean Troyer
authored andcommitted
Add host and hypervisor_hostname to create servers
Adds the --host and --hypervisor-hostname options to ``openstack server create`` CLI. Depends-On: https://review.opendev.org/670558 Change-Id: If188c3d96fa506dbe62ef256418f2f9bca1520c2 Blueprint: add-host-and-hypervisor-hostname-flag-to-create-server
1 parent d270174 commit 340f25f

5 files changed

Lines changed: 268 additions & 2 deletions

File tree

lower-constraints.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ python-mimeparse==1.6.0
100100
python-mistralclient==3.1.0
101101
python-muranoclient==0.8.2
102102
python-neutronclient==6.7.0
103-
python-novaclient==14.1.0
103+
python-novaclient==14.2.0
104104
python-octaviaclient==1.3.0
105105
python-rsdclient==0.1.0
106106
python-saharaclient==1.4.0

openstackclient/compute/v2/server.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,20 @@ def get_parser(self, prog_name):
553553
metavar='<zone-name>',
554554
help=_('Select an availability zone for the server'),
555555
)
556+
parser.add_argument(
557+
'--host',
558+
metavar='<host>',
559+
help=_('Requested host to create servers. Admin only '
560+
'by default. (supported by --os-compute-api-version 2.74 '
561+
'or above)'),
562+
)
563+
parser.add_argument(
564+
'--hypervisor-hostname',
565+
metavar='<hypervisor-hostname>',
566+
help=_('Requested hypervisor hostname to create servers. Admin '
567+
'only by default. (supported by --os-compute-api-version '
568+
'2.74 or above)'),
569+
)
556570
parser.add_argument(
557571
'--block-device-mapping',
558572
metavar='<dev-name=mapping>',
@@ -927,6 +941,21 @@ def _match_image(image_api, wanted_properties):
927941
if parsed_args.description:
928942
boot_kwargs['description'] = parsed_args.description
929943

944+
if parsed_args.host:
945+
if compute_client.api_version < api_versions.APIVersion("2.74"):
946+
msg = _("Specifying --host is not supported for "
947+
"--os-compute-api-version less than 2.74")
948+
raise exceptions.CommandError(msg)
949+
boot_kwargs['host'] = parsed_args.host
950+
951+
if parsed_args.hypervisor_hostname:
952+
if compute_client.api_version < api_versions.APIVersion("2.74"):
953+
msg = _("Specifying --hypervisor-hostname is not supported "
954+
"for --os-compute-api-version less than 2.74")
955+
raise exceptions.CommandError(msg)
956+
boot_kwargs['hypervisor_hostname'] = (
957+
parsed_args.hypervisor_hostname)
958+
930959
LOG.debug('boot_args: %s', boot_args)
931960
LOG.debug('boot_kwargs: %s', boot_kwargs)
932961

openstackclient/tests/unit/compute/v2/test_server.py

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,6 +1926,237 @@ def test_server_create_with_description_api_older(self):
19261926
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
19271927
parsed_args)
19281928

1929+
def test_server_create_with_host_v274(self):
1930+
1931+
# Explicit host is supported for nova api version 2.74 or above
1932+
self.app.client_manager.compute.api_version = 2.74
1933+
1934+
arglist = [
1935+
'--image', 'image1',
1936+
'--flavor', 'flavor1',
1937+
'--host', 'host1',
1938+
self.new_server.name,
1939+
]
1940+
verifylist = [
1941+
('image', 'image1'),
1942+
('flavor', 'flavor1'),
1943+
('host', 'host1'),
1944+
('config_drive', False),
1945+
('server_name', self.new_server.name),
1946+
]
1947+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1948+
1949+
with mock.patch.object(api_versions,
1950+
'APIVersion',
1951+
return_value=2.74):
1952+
# In base command class ShowOne in cliff, abstract method
1953+
# take_action() returns a two-part tuple with a tuple of
1954+
# column names and a tuple of data to be shown.
1955+
columns, data = self.cmd.take_action(parsed_args)
1956+
1957+
# Set expected values
1958+
kwargs = dict(
1959+
meta=None,
1960+
files={},
1961+
reservation_id=None,
1962+
min_count=1,
1963+
max_count=1,
1964+
security_groups=[],
1965+
userdata=None,
1966+
key_name=None,
1967+
availability_zone=None,
1968+
block_device_mapping_v2=[],
1969+
nics='auto',
1970+
scheduler_hints={},
1971+
config_drive=None,
1972+
host='host1',
1973+
)
1974+
# ServerManager.create(name, image, flavor, **kwargs)
1975+
self.servers_mock.create.assert_called_with(
1976+
self.new_server.name,
1977+
self.image,
1978+
self.flavor,
1979+
**kwargs
1980+
)
1981+
1982+
self.assertEqual(self.columns, columns)
1983+
self.assertEqual(self.datalist(), data)
1984+
self.assertFalse(self.images_mock.called)
1985+
self.assertFalse(self.flavors_mock.called)
1986+
1987+
def test_server_create_with_host_pre_v274(self):
1988+
1989+
# Host is not supported for nova api version below 2.74
1990+
self.app.client_manager.compute.api_version = 2.73
1991+
1992+
arglist = [
1993+
'--image', 'image1',
1994+
'--flavor', 'flavor1',
1995+
'--host', 'host1',
1996+
self.new_server.name,
1997+
]
1998+
verifylist = [
1999+
('image', 'image1'),
2000+
('flavor', 'flavor1'),
2001+
('host', 'host1'),
2002+
('config_drive', False),
2003+
('server_name', self.new_server.name),
2004+
]
2005+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2006+
2007+
with mock.patch.object(api_versions,
2008+
'APIVersion',
2009+
return_value=2.74):
2010+
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
2011+
parsed_args)
2012+
2013+
def test_server_create_with_hypervisor_hostname_v274(self):
2014+
2015+
# Explicit hypervisor_hostname is supported for nova api version
2016+
# 2.74 or above
2017+
self.app.client_manager.compute.api_version = 2.74
2018+
2019+
arglist = [
2020+
'--image', 'image1',
2021+
'--flavor', 'flavor1',
2022+
'--hypervisor-hostname', 'node1',
2023+
self.new_server.name,
2024+
]
2025+
verifylist = [
2026+
('image', 'image1'),
2027+
('flavor', 'flavor1'),
2028+
('hypervisor_hostname', 'node1'),
2029+
('config_drive', False),
2030+
('server_name', self.new_server.name),
2031+
]
2032+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2033+
2034+
with mock.patch.object(api_versions,
2035+
'APIVersion',
2036+
return_value=2.74):
2037+
# In base command class ShowOne in cliff, abstract method
2038+
# take_action() returns a two-part tuple with a tuple of
2039+
# column names and a tuple of data to be shown.
2040+
columns, data = self.cmd.take_action(parsed_args)
2041+
2042+
# Set expected values
2043+
kwargs = dict(
2044+
meta=None,
2045+
files={},
2046+
reservation_id=None,
2047+
min_count=1,
2048+
max_count=1,
2049+
security_groups=[],
2050+
userdata=None,
2051+
key_name=None,
2052+
availability_zone=None,
2053+
block_device_mapping_v2=[],
2054+
nics='auto',
2055+
scheduler_hints={},
2056+
config_drive=None,
2057+
hypervisor_hostname='node1',
2058+
)
2059+
# ServerManager.create(name, image, flavor, **kwargs)
2060+
self.servers_mock.create.assert_called_with(
2061+
self.new_server.name,
2062+
self.image,
2063+
self.flavor,
2064+
**kwargs
2065+
)
2066+
2067+
self.assertEqual(self.columns, columns)
2068+
self.assertEqual(self.datalist(), data)
2069+
self.assertFalse(self.images_mock.called)
2070+
self.assertFalse(self.flavors_mock.called)
2071+
2072+
def test_server_create_with_hypervisor_hostname_pre_v274(self):
2073+
2074+
# Hypervisor_hostname is not supported for nova api version below 2.74
2075+
self.app.client_manager.compute.api_version = 2.73
2076+
2077+
arglist = [
2078+
'--image', 'image1',
2079+
'--flavor', 'flavor1',
2080+
'--hypervisor-hostname', 'node1',
2081+
self.new_server.name,
2082+
]
2083+
verifylist = [
2084+
('image', 'image1'),
2085+
('flavor', 'flavor1'),
2086+
('hypervisor_hostname', 'node1'),
2087+
('config_drive', False),
2088+
('server_name', self.new_server.name),
2089+
]
2090+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2091+
2092+
with mock.patch.object(api_versions,
2093+
'APIVersion',
2094+
return_value=2.74):
2095+
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
2096+
parsed_args)
2097+
2098+
def test_server_create_with_host_and_hypervisor_hostname_v274(self):
2099+
2100+
# Explicit host and hypervisor_hostname is supported for nova api
2101+
# version 2.74 or above
2102+
self.app.client_manager.compute.api_version = 2.74
2103+
2104+
arglist = [
2105+
'--image', 'image1',
2106+
'--flavor', 'flavor1',
2107+
'--host', 'host1',
2108+
'--hypervisor-hostname', 'node1',
2109+
self.new_server.name,
2110+
]
2111+
verifylist = [
2112+
('image', 'image1'),
2113+
('flavor', 'flavor1'),
2114+
('host', 'host1'),
2115+
('hypervisor_hostname', 'node1'),
2116+
('config_drive', False),
2117+
('server_name', self.new_server.name),
2118+
]
2119+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2120+
2121+
with mock.patch.object(api_versions,
2122+
'APIVersion',
2123+
return_value=2.74):
2124+
# In base command class ShowOne in cliff, abstract method
2125+
# take_action() returns a two-part tuple with a tuple of
2126+
# column names and a tuple of data to be shown.
2127+
columns, data = self.cmd.take_action(parsed_args)
2128+
2129+
# Set expected values
2130+
kwargs = dict(
2131+
meta=None,
2132+
files={},
2133+
reservation_id=None,
2134+
min_count=1,
2135+
max_count=1,
2136+
security_groups=[],
2137+
userdata=None,
2138+
key_name=None,
2139+
availability_zone=None,
2140+
block_device_mapping_v2=[],
2141+
nics='auto',
2142+
scheduler_hints={},
2143+
config_drive=None,
2144+
host='host1',
2145+
hypervisor_hostname='node1',
2146+
)
2147+
# ServerManager.create(name, image, flavor, **kwargs)
2148+
self.servers_mock.create.assert_called_with(
2149+
self.new_server.name,
2150+
self.image,
2151+
self.flavor,
2152+
**kwargs
2153+
)
2154+
2155+
self.assertEqual(self.columns, columns)
2156+
self.assertEqual(self.datalist(), data)
2157+
self.assertFalse(self.images_mock.called)
2158+
self.assertFalse(self.flavors_mock.called)
2159+
19292160

19302161
class TestServerDelete(TestServer):
19312162

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
Add ``--host`` and ``--hypervisor-hostname`` options to
5+
``server create`` command.
6+
[Blueprint `add-host-and-hypervisor-hostname-flag-to-create-server <https://blueprints.launchpad.net/nova/+spec/add-host-and-hypervisor-hostname-flag-to-create-server>`_]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ oslo.i18n>=3.15.3 # Apache-2.0
1313
oslo.utils>=3.33.0 # Apache-2.0
1414
python-glanceclient>=2.8.0 # Apache-2.0
1515
python-keystoneclient>=3.17.0 # Apache-2.0
16-
python-novaclient>=14.1.0 # Apache-2.0
16+
python-novaclient>=14.2.0 # Apache-2.0
1717
python-cinderclient>=3.3.0 # Apache-2.0

0 commit comments

Comments
 (0)