compute: Add support for 'server boot --nic ...,tag=<tag>'
This has been around for a long time but was not exposed via OSC. Close this gap. Change-Id: I71aabf10f791f68ee7405ffb5e8317cc96cb3b38 Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
parent
c7d582379a
commit
9ed34aac0a
@ -646,6 +646,8 @@ class NICAction(argparse.Action):
|
|||||||
|
|
||||||
values = '='.join([self.key, values])
|
values = '='.join([self.key, values])
|
||||||
|
|
||||||
|
# We don't include 'tag' here by default since that requires a
|
||||||
|
# particular microversion
|
||||||
info = {
|
info = {
|
||||||
'net-id': '',
|
'net-id': '',
|
||||||
'port-id': '',
|
'port-id': '',
|
||||||
@ -656,11 +658,11 @@ class NICAction(argparse.Action):
|
|||||||
for kv_str in values.split(','):
|
for kv_str in values.split(','):
|
||||||
k, sep, v = kv_str.partition("=")
|
k, sep, v = kv_str.partition("=")
|
||||||
|
|
||||||
if k not in info or not v:
|
if k not in list(info) + ['tag'] or not v:
|
||||||
msg = _(
|
msg = _(
|
||||||
"Invalid argument %s; argument must be of form "
|
"Invalid argument %s; argument must be of form "
|
||||||
"'net-id=net-uuid,v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr,"
|
"'net-id=net-uuid,port-id=port-uuid,v4-fixed-ip=ip-addr,"
|
||||||
"port-id=port-uuid'"
|
"v6-fixed-ip=ip-addr,tag=tag'"
|
||||||
)
|
)
|
||||||
raise argparse.ArgumentTypeError(msg % values)
|
raise argparse.ArgumentTypeError(msg % values)
|
||||||
|
|
||||||
@ -801,7 +803,7 @@ class CreateServer(command.ShowOne):
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--nic',
|
'--nic',
|
||||||
metavar="<net-id=net-uuid,port-id=port-uuid,v4-fixed-ip=ip-addr,"
|
metavar="<net-id=net-uuid,port-id=port-uuid,v4-fixed-ip=ip-addr,"
|
||||||
"v6-fixed-ip=ip-addr,auto,none>",
|
"v6-fixed-ip=ip-addr,tag=tag,auto,none>",
|
||||||
action=NICAction,
|
action=NICAction,
|
||||||
dest='nics',
|
dest='nics',
|
||||||
default=[],
|
default=[],
|
||||||
@ -814,6 +816,8 @@ class CreateServer(command.ShowOne):
|
|||||||
"\n"
|
"\n"
|
||||||
"v6-fixed-ip=<ip-addr>: IPv6 fixed address for NIC (optional),"
|
"v6-fixed-ip=<ip-addr>: IPv6 fixed address for NIC (optional),"
|
||||||
"\n"
|
"\n"
|
||||||
|
"tag: interface metadata tag (optional) "
|
||||||
|
"(supported by --os-compute-api-version 2.43 or above),\n"
|
||||||
"none: (v2.37+) no network is attached,\n"
|
"none: (v2.37+) no network is attached,\n"
|
||||||
"auto: (v2.37+) the compute service will automatically "
|
"auto: (v2.37+) the compute service will automatically "
|
||||||
"allocate a network.\n"
|
"allocate a network.\n"
|
||||||
@ -1191,6 +1195,17 @@ class CreateServer(command.ShowOne):
|
|||||||
nics = nics[0]
|
nics = nics[0]
|
||||||
else:
|
else:
|
||||||
for nic in nics:
|
for nic in nics:
|
||||||
|
if 'tag' in nic:
|
||||||
|
if (
|
||||||
|
compute_client.api_version <
|
||||||
|
api_versions.APIVersion('2.43')
|
||||||
|
):
|
||||||
|
msg = _(
|
||||||
|
'--os-compute-api-version 2.43 or greater is '
|
||||||
|
'required to support the --nic tag field'
|
||||||
|
)
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
if self.app.client_manager.is_network_endpoint_enabled():
|
if self.app.client_manager.is_network_endpoint_enabled():
|
||||||
network_client = self.app.client_manager.network
|
network_client = self.app.client_manager.network
|
||||||
|
|
||||||
|
@ -1423,6 +1423,113 @@ class TestServerCreate(TestServer):
|
|||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.datalist(), data)
|
self.assertEqual(self.datalist(), data)
|
||||||
|
|
||||||
|
def test_server_create_with_network_tag(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.43')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--image', 'image1',
|
||||||
|
'--flavor', 'flavor1',
|
||||||
|
'--nic', 'net-id=net1,tag=foo',
|
||||||
|
self.new_server.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('image', 'image1'),
|
||||||
|
('flavor', 'flavor1'),
|
||||||
|
('nics', [
|
||||||
|
{
|
||||||
|
'net-id': 'net1', 'port-id': '',
|
||||||
|
'v4-fixed-ip': '', 'v6-fixed-ip': '',
|
||||||
|
'tag': 'foo',
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
('server_name', self.new_server.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
find_network = mock.Mock()
|
||||||
|
network_client = self.app.client_manager.network
|
||||||
|
network_client.find_network = find_network
|
||||||
|
network_resource = mock.Mock(id='net1_uuid')
|
||||||
|
find_network.return_value = network_resource
|
||||||
|
|
||||||
|
# Mock sdk APIs.
|
||||||
|
_network = mock.Mock(id='net1_uuid')
|
||||||
|
find_network = mock.Mock()
|
||||||
|
find_network.return_value = _network
|
||||||
|
self.app.client_manager.network.find_network = find_network
|
||||||
|
|
||||||
|
# In base command class ShowOne in cliff, abstract method take_action()
|
||||||
|
# returns a two-part tuple with a tuple of column names and a tuple of
|
||||||
|
# data to be shown.
|
||||||
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
# Set expected values
|
||||||
|
kwargs = dict(
|
||||||
|
meta=None,
|
||||||
|
files={},
|
||||||
|
reservation_id=None,
|
||||||
|
min_count=1,
|
||||||
|
max_count=1,
|
||||||
|
security_groups=[],
|
||||||
|
userdata=None,
|
||||||
|
key_name=None,
|
||||||
|
availability_zone=None,
|
||||||
|
admin_pass=None,
|
||||||
|
block_device_mapping_v2=[],
|
||||||
|
nics=[
|
||||||
|
{
|
||||||
|
'net-id': 'net1_uuid',
|
||||||
|
'v4-fixed-ip': '',
|
||||||
|
'v6-fixed-ip': '',
|
||||||
|
'port-id': '',
|
||||||
|
'tag': 'foo',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
scheduler_hints={},
|
||||||
|
config_drive=None,
|
||||||
|
)
|
||||||
|
# ServerManager.create(name, image, flavor, **kwargs)
|
||||||
|
self.servers_mock.create.assert_called_with(
|
||||||
|
self.new_server.name,
|
||||||
|
self.image,
|
||||||
|
self.flavor,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertEqual(self.datalist(), data)
|
||||||
|
|
||||||
|
network_client.find_network.assert_called_once()
|
||||||
|
self.app.client_manager.network.find_network.assert_called_once()
|
||||||
|
|
||||||
|
def test_server_create_with_network_tag_pre_v243(self):
|
||||||
|
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
||||||
|
'2.42')
|
||||||
|
|
||||||
|
arglist = [
|
||||||
|
'--image', 'image1',
|
||||||
|
'--flavor', 'flavor1',
|
||||||
|
'--nic', 'net-id=net1,tag=foo',
|
||||||
|
self.new_server.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('image', 'image1'),
|
||||||
|
('flavor', 'flavor1'),
|
||||||
|
('nics', [
|
||||||
|
{
|
||||||
|
'net-id': 'net1', 'port-id': '',
|
||||||
|
'v4-fixed-ip': '', 'v6-fixed-ip': '',
|
||||||
|
'tag': 'foo',
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
('server_name', self.new_server.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.CommandError, self.cmd.take_action, parsed_args)
|
||||||
|
|
||||||
def test_server_create_with_auto_network(self):
|
def test_server_create_with_auto_network(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'--image', 'image1',
|
'--image', 'image1',
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The ``--nic`` option of the ``server create`` command now supports an
|
||||||
|
optional ``tag=<tag>`` key-value pair. This can be used to set a tag for
|
||||||
|
the interface in server metadata, which can be useful to maintain
|
||||||
|
persistent references to interfaces during various operations.
|
Loading…
x
Reference in New Issue
Block a user