[Compute]Make column content readable for both human and machine
Currently, we use utils.format_dict(), utils.format_list(), utils.format_list_of_dicts to make column value can be easy to read by human, but osc support to format the CLI output into several format, like: json, shell, csv, yaml, most of these should be understand by program and code, so keeping the column content as the original value make sense, like {u'name': u'RuiChen'} than name='RuiChen' The patch include all compute commands. Change-Id: I313a52f94895625e6045df870320840fee157759 Implements: blueprint osc-formattable-columns Partial-Bug: #1538015 Partial-Bug: #1538006
This commit is contained in:
parent
5309bf5f87
commit
ff9bd34b3c
openstackclient
compute/v2
tests
functional/compute/v2
unit/compute/v2
releasenotes/notes
@ -18,6 +18,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib.cli import parseractions
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
@ -324,7 +325,9 @@ class ShowAggregate(command.ShowOne):
|
||||
# 'metadata' --> 'properties'
|
||||
data._info.update(
|
||||
{
|
||||
'properties': utils.format_dict(data._info.pop('metadata')),
|
||||
'properties': format_columns.DictColumn(
|
||||
data._info.pop('metadata')
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib.cli import parseractions
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
@ -180,7 +181,14 @@ class CreateFlavor(command.ShowOne):
|
||||
|
||||
flavor_info = flavor._info.copy()
|
||||
flavor_info.pop("links")
|
||||
flavor_info['properties'] = utils.format_dict(flavor.get_keys())
|
||||
flavor_info['properties'] = format_columns.DictColumn(
|
||||
# NOTE(RuiChen): novaclient flavor.get_keys() return a mixin class
|
||||
# DictWithMeta, that can't be represented properly
|
||||
# in yaml format(-f yaml), wrapping it in base type
|
||||
# dict is a workaround, please do not remove the
|
||||
# conversion.
|
||||
dict(flavor.get_keys())
|
||||
)
|
||||
|
||||
return zip(*sorted(six.iteritems(flavor_info)))
|
||||
|
||||
@ -291,13 +299,19 @@ class ListFlavor(command.Lister):
|
||||
"Properties",
|
||||
)
|
||||
for f in data:
|
||||
f.properties = f.get_keys()
|
||||
# NOTE(RuiChen): novaclient flavor.get_keys() return a mixin
|
||||
# class DictWithMeta, that can't be represented
|
||||
# properly in yaml format(-f yaml), wrapping it
|
||||
# in base type dict is a workaround, please do
|
||||
# not remove the conversion.
|
||||
f.properties = dict(f.get_keys())
|
||||
|
||||
column_headers = columns
|
||||
|
||||
return (column_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns, formatters={'Properties': utils.format_dict},
|
||||
s, columns,
|
||||
formatters={'Properties': format_columns.DictColumn},
|
||||
) for s in data))
|
||||
|
||||
|
||||
@ -405,9 +419,7 @@ class ShowFlavor(command.ShowOne):
|
||||
flavor=resource_flavor.id)
|
||||
projects = [utils.get_field(access, 'tenant_id')
|
||||
for access in flavor_access]
|
||||
# TODO(Huanxuan Ao): This format case can be removed after
|
||||
# patch https://review.openstack.org/#/c/330223/ merged.
|
||||
access_projects = utils.format_list(projects)
|
||||
access_projects = format_columns.ListColumn(projects)
|
||||
except Exception as e:
|
||||
msg = _("Failed to get access projects list "
|
||||
"for flavor '%(flavor)s': %(e)s")
|
||||
@ -419,7 +431,14 @@ class ShowFlavor(command.ShowOne):
|
||||
})
|
||||
flavor.pop("links", None)
|
||||
|
||||
flavor['properties'] = utils.format_dict(resource_flavor.get_keys())
|
||||
flavor['properties'] = format_columns.DictColumn(
|
||||
# NOTE(RuiChen): novaclient flavor.get_keys() return a mixin class
|
||||
# DictWithMeta, that can't be represented properly
|
||||
# in yaml format(-f yaml), wrapping it in base type
|
||||
# dict is a workaround, please do not remove the
|
||||
# conversion.
|
||||
dict(resource_flavor.get_keys())
|
||||
)
|
||||
|
||||
return zip(*sorted(six.iteritems(flavor)))
|
||||
|
||||
|
@ -23,6 +23,7 @@ import os
|
||||
import sys
|
||||
|
||||
from novaclient.v2 import servers
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib.cli import parseractions
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
@ -37,22 +38,6 @@ from openstackclient.identity import common as identity_common
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _format_servers_list_networks(networks):
|
||||
"""Return a formatted string of a server's networks
|
||||
|
||||
:param networks: a Server.networks field
|
||||
:rtype: a string of formatted network addresses
|
||||
"""
|
||||
output = []
|
||||
for (network, addresses) in networks.items():
|
||||
if not addresses:
|
||||
continue
|
||||
addresses_csv = ', '.join(addresses)
|
||||
group = "%s=%s" % (network, addresses_csv)
|
||||
output.append(group)
|
||||
return '; '.join(output)
|
||||
|
||||
|
||||
def _format_servers_list_power_state(state):
|
||||
"""Return a formatted string of a server's power state
|
||||
|
||||
@ -154,24 +139,26 @@ def _prep_server_detail(compute_client, image_client, server):
|
||||
if 'os-extended-volumes:volumes_attached' in info:
|
||||
info.update(
|
||||
{
|
||||
'volumes_attached': utils.format_list_of_dicts(
|
||||
info.pop('os-extended-volumes:volumes_attached'))
|
||||
'volumes_attached': format_columns.ListDictColumn(
|
||||
info.pop('os-extended-volumes:volumes_attached')
|
||||
)
|
||||
}
|
||||
)
|
||||
if 'security_groups' in info:
|
||||
info.update(
|
||||
{
|
||||
'security_groups': utils.format_list_of_dicts(
|
||||
info.pop('security_groups'))
|
||||
'security_groups': format_columns.ListDictColumn(
|
||||
info.pop('security_groups')
|
||||
)
|
||||
}
|
||||
)
|
||||
# NOTE(dtroyer): novaclient splits these into separate entries...
|
||||
# Format addresses in a useful way
|
||||
info['addresses'] = _format_servers_list_networks(server.networks)
|
||||
info['addresses'] = format_columns.DictListColumn(server.networks)
|
||||
|
||||
# Map 'metadata' field to 'properties'
|
||||
info.update(
|
||||
{'properties': utils.format_dict(info.pop('metadata'))}
|
||||
{'properties': format_columns.DictColumn(info.pop('metadata'))}
|
||||
)
|
||||
|
||||
# Migrate tenant_id to project_id naming
|
||||
@ -1161,8 +1148,8 @@ class ListServer(command.Lister):
|
||||
formatters={
|
||||
'OS-EXT-STS:power_state':
|
||||
_format_servers_list_power_state,
|
||||
'Networks': _format_servers_list_networks,
|
||||
'Metadata': utils.format_dict,
|
||||
'Networks': format_columns.DictListColumn,
|
||||
'Metadata': format_columns.DictColumn,
|
||||
},
|
||||
) for s in data))
|
||||
return table
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
import sys
|
||||
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
@ -122,7 +123,9 @@ class CreateServerBackup(command.ShowOne):
|
||||
if self.app.client_manager._api_version['image'] == '1':
|
||||
info = {}
|
||||
info.update(image._info)
|
||||
info['properties'] = utils.format_dict(info.get('properties', {}))
|
||||
info['properties'] = format_columns.DictColumn(
|
||||
info.get('properties', {})
|
||||
)
|
||||
else:
|
||||
# Get the right image module to format the output
|
||||
image_module = importutils.import_module(
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
@ -28,8 +29,8 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
_formatters = {
|
||||
'policies': utils.format_list,
|
||||
'members': utils.format_list,
|
||||
'policies': format_columns.ListColumn,
|
||||
'members': format_columns.ListColumn,
|
||||
}
|
||||
|
||||
|
||||
@ -155,8 +156,8 @@ class ListServerGroup(command.Lister):
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
formatters={
|
||||
'Policies': utils.format_list,
|
||||
'Members': utils.format_list,
|
||||
'Policies': format_columns.ListColumn,
|
||||
'Members': format_columns.ListColumn,
|
||||
}
|
||||
) for s in data))
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
@ -101,7 +102,9 @@ class CreateServerImage(command.ShowOne):
|
||||
if self.app.client_manager._api_version['image'] == '1':
|
||||
info = {}
|
||||
info.update(image._info)
|
||||
info['properties'] = utils.format_dict(info.get('properties', {}))
|
||||
info['properties'] = format_columns.DictColumn(
|
||||
info.get('properties', {})
|
||||
)
|
||||
else:
|
||||
# Get the right image module to format the output
|
||||
image_module = importutils.import_module(
|
||||
|
@ -136,14 +136,7 @@ class AggregateTests(base.TestCase):
|
||||
'internal',
|
||||
cmd_output['availability_zone']
|
||||
)
|
||||
self.assertIn(
|
||||
"c='d'",
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertNotIn(
|
||||
"a='b'",
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual({'c': 'd'}, cmd_output['properties'])
|
||||
|
||||
# Test unset
|
||||
raw_output = self.openstack(
|
||||
@ -157,10 +150,7 @@ class AggregateTests(base.TestCase):
|
||||
'aggregate show -f json ' +
|
||||
name2
|
||||
))
|
||||
self.assertNotIn(
|
||||
"c='d'",
|
||||
cmd_output['properties']
|
||||
)
|
||||
self.assertEqual({}, cmd_output['properties'])
|
||||
|
||||
def test_aggregate_add_and_remove_host(self):
|
||||
"""Test aggregate add and remove host"""
|
||||
|
@ -91,7 +91,7 @@ class FlavorTests(base.TestCase):
|
||||
"--ram 123 " +
|
||||
"--private " +
|
||||
"--property a=b2 " +
|
||||
"--property b=d2 " +
|
||||
"--property c=d2 " +
|
||||
name2
|
||||
))
|
||||
self.addCleanup(self.openstack, "flavor delete " + name2)
|
||||
@ -116,10 +116,7 @@ class FlavorTests(base.TestCase):
|
||||
False,
|
||||
cmd_output["os-flavor-access:is_public"],
|
||||
)
|
||||
self.assertEqual(
|
||||
"a='b2', b='d2'",
|
||||
cmd_output["properties"],
|
||||
)
|
||||
self.assertEqual({'a': 'b2', 'c': 'd2'}, cmd_output["properties"])
|
||||
|
||||
# Test list
|
||||
cmd_output = json.loads(self.openstack(
|
||||
@ -135,11 +132,11 @@ class FlavorTests(base.TestCase):
|
||||
"--long"
|
||||
))
|
||||
col_name = [x["Name"] for x in cmd_output]
|
||||
col_properties = [x['Properties'] for x in cmd_output]
|
||||
self.assertIn(name1, col_name)
|
||||
self.assertIn("a='b', c='d'", col_properties)
|
||||
self.assertNotIn(name2, col_name)
|
||||
self.assertNotIn("b2', b='d2'", col_properties)
|
||||
|
||||
props = [x['Properties'] for x in cmd_output]
|
||||
self.assertIn({'a': 'b', 'c': 'd'}, props)
|
||||
|
||||
# Test list --public
|
||||
cmd_output = json.loads(self.openstack(
|
||||
@ -203,10 +200,8 @@ class FlavorTests(base.TestCase):
|
||||
False,
|
||||
cmd_output["os-flavor-access:is_public"],
|
||||
)
|
||||
self.assertEqual(
|
||||
"a='first', b='second'",
|
||||
cmd_output["properties"],
|
||||
)
|
||||
self.assertEqual({'a': 'first', 'b': 'second'},
|
||||
cmd_output['properties'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
"flavor set " +
|
||||
@ -224,10 +219,8 @@ class FlavorTests(base.TestCase):
|
||||
"qaz",
|
||||
cmd_output["id"],
|
||||
)
|
||||
self.assertEqual(
|
||||
"a='third and 10', b='second', g='fourth'",
|
||||
cmd_output['properties'],
|
||||
)
|
||||
self.assertEqual({'a': 'third and 10', 'b': 'second', 'g': 'fourth'},
|
||||
cmd_output['properties'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
"flavor unset " +
|
||||
@ -240,7 +233,5 @@ class FlavorTests(base.TestCase):
|
||||
"flavor show -f json " +
|
||||
name1
|
||||
))
|
||||
self.assertEqual(
|
||||
"a='third and 10', g='fourth'",
|
||||
cmd_output["properties"],
|
||||
)
|
||||
self.assertEqual({'a': 'third and 10', 'g': 'fourth'},
|
||||
cmd_output['properties'])
|
||||
|
@ -107,25 +107,19 @@ class ServerTests(common.ComputeTestCase):
|
||||
'server show -f json ' +
|
||||
name
|
||||
))
|
||||
# Really, shouldn't this be a list?
|
||||
self.assertEqual(
|
||||
"a='b', c='d'",
|
||||
cmd_output['properties'],
|
||||
)
|
||||
self.assertEqual({'a': 'b', 'c': 'd'}, cmd_output['properties'])
|
||||
|
||||
raw_output = self.openstack(
|
||||
'server unset ' +
|
||||
'--property a ' +
|
||||
name
|
||||
)
|
||||
self.assertOutput('', raw_output)
|
||||
cmd_output = json.loads(self.openstack(
|
||||
'server show -f json ' +
|
||||
name
|
||||
))
|
||||
self.assertEqual(
|
||||
"c='d'",
|
||||
cmd_output['properties'],
|
||||
)
|
||||
self.assertEqual({'c': 'd'}, cmd_output['properties'])
|
||||
|
||||
# Test set --name
|
||||
new_name = uuid.uuid4().hex
|
||||
@ -248,10 +242,8 @@ class ServerTests(common.ComputeTestCase):
|
||||
'server show -f json ' +
|
||||
name
|
||||
))
|
||||
self.assertIn(
|
||||
floating_ip,
|
||||
cmd_output['addresses'],
|
||||
)
|
||||
self.assertIsInstance(cmd_output['addresses'], dict)
|
||||
self.assertIn(floating_ip, cmd_output['addresses']['private'])
|
||||
|
||||
# detach ip
|
||||
raw_output = self.openstack(
|
||||
@ -265,10 +257,8 @@ class ServerTests(common.ComputeTestCase):
|
||||
'server show -f json ' +
|
||||
name
|
||||
))
|
||||
self.assertNotIn(
|
||||
floating_ip,
|
||||
cmd_output['addresses'],
|
||||
)
|
||||
self.assertIsInstance(cmd_output['addresses'], dict)
|
||||
self.assertNotIn(floating_ip, cmd_output['addresses']['private'])
|
||||
|
||||
def test_server_reboot(self):
|
||||
"""Test server reboot"""
|
||||
@ -456,8 +446,10 @@ class ServerTests(common.ComputeTestCase):
|
||||
server_name
|
||||
))
|
||||
volumes_attached = cmd_output['volumes_attached']
|
||||
self.assertTrue(volumes_attached.startswith('id='))
|
||||
attached_volume_id = volumes_attached.replace('id=', '')
|
||||
self.assertIsInstance(volumes_attached, list)
|
||||
self.assertEqual(1, len(volumes_attached))
|
||||
self.assertIn('id', volumes_attached[0])
|
||||
attached_volume_id = volumes_attached[0]['id']
|
||||
|
||||
# check the volume that attached on server
|
||||
cmd_output = json.loads(self.openstack(
|
||||
@ -514,7 +506,7 @@ class ServerTests(common.ComputeTestCase):
|
||||
'server show -f json ' + server_name
|
||||
))
|
||||
self.assertIsNotNone(server['addresses'])
|
||||
self.assertEqual('', server['addresses'])
|
||||
self.assertEqual({}, server['addresses'])
|
||||
|
||||
def test_server_create_with_security_group(self):
|
||||
"""Test server create with security group ID and name"""
|
||||
@ -553,14 +545,27 @@ class ServerTests(common.ComputeTestCase):
|
||||
|
||||
self.assertIsNotNone(server['id'])
|
||||
self.assertEqual(server_name, server['name'])
|
||||
self.assertIn(str(security_group1['id']), server['security_groups'])
|
||||
self.assertIn(str(security_group2['id']), server['security_groups'])
|
||||
self.assertIsInstance(server['security_groups'], list)
|
||||
self.assertEqual(2, len(server['security_groups']))
|
||||
# NOTE(RuiChen): Nova return security group id in response of server
|
||||
# create API, but return security group name in server
|
||||
# show API for the same server, so we assert id and name
|
||||
# for different create and show commands in the
|
||||
# following code.
|
||||
sg_ids = [each_sg['name'] for each_sg in server['security_groups']]
|
||||
# Security group id is integer in nova-network, convert to string
|
||||
self.assertIn(str(security_group1['id']), sg_ids)
|
||||
self.assertIn(str(security_group2['id']), sg_ids)
|
||||
|
||||
self.wait_for_status(server_name, 'ACTIVE')
|
||||
server = json.loads(self.openstack(
|
||||
'server show -f json ' + server_name
|
||||
))
|
||||
self.assertIn(sg_name1, server['security_groups'])
|
||||
self.assertIn(sg_name2, server['security_groups'])
|
||||
self.assertIsInstance(server['security_groups'], list)
|
||||
self.assertEqual(2, len(server['security_groups']))
|
||||
sg_names = [each_sg['name'] for each_sg in server['security_groups']]
|
||||
self.assertIn(sg_name1, sg_names)
|
||||
self.assertIn(sg_name2, sg_names)
|
||||
|
||||
def test_server_create_with_empty_network_option_latest(self):
|
||||
"""Test server create with empty network option in nova 2.latest."""
|
||||
|
@ -32,10 +32,7 @@ class ServerGroupTests(base.TestCase):
|
||||
name1,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
'affinity',
|
||||
cmd_output['policies']
|
||||
)
|
||||
self.assertEqual(['affinity'], cmd_output['policies'])
|
||||
|
||||
cmd_output = json.loads(self.openstack(
|
||||
'server group create -f json ' +
|
||||
@ -46,10 +43,7 @@ class ServerGroupTests(base.TestCase):
|
||||
name2,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
'anti-affinity',
|
||||
cmd_output['policies']
|
||||
)
|
||||
self.assertEqual(['anti-affinity'], cmd_output['policies'])
|
||||
|
||||
del_output = self.openstack(
|
||||
'server group delete ' + name1 + ' ' + name2)
|
||||
@ -73,10 +67,7 @@ class ServerGroupTests(base.TestCase):
|
||||
name1,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
'affinity',
|
||||
cmd_output['policies']
|
||||
)
|
||||
self.assertEqual(['affinity'], cmd_output['policies'])
|
||||
|
||||
cmd_output = json.loads(self.openstack(
|
||||
'server group create -f json ' +
|
||||
@ -90,10 +81,7 @@ class ServerGroupTests(base.TestCase):
|
||||
name2,
|
||||
cmd_output['name']
|
||||
)
|
||||
self.assertEqual(
|
||||
'anti-affinity',
|
||||
cmd_output['policies']
|
||||
)
|
||||
self.assertEqual(['anti-affinity'], cmd_output['policies'])
|
||||
|
||||
# test server group list
|
||||
cmd_output = json.loads(self.openstack(
|
||||
@ -102,5 +90,5 @@ class ServerGroupTests(base.TestCase):
|
||||
self.assertIn(name1, names)
|
||||
self.assertIn(name2, names)
|
||||
policies = [x["Policies"] for x in cmd_output]
|
||||
self.assertIn('affinity', policies)
|
||||
self.assertIn('anti-affinity', policies)
|
||||
self.assertIn(['affinity'], policies)
|
||||
self.assertIn(['anti-affinity'], policies)
|
||||
|
@ -16,6 +16,7 @@
|
||||
import mock
|
||||
from mock import call
|
||||
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
@ -443,7 +444,7 @@ class TestAggregateShow(TestAggregate):
|
||||
TestAggregate.fake_ag.hosts,
|
||||
TestAggregate.fake_ag.id,
|
||||
TestAggregate.fake_ag.name,
|
||||
utils.format_dict(
|
||||
format_columns.DictColumn(
|
||||
{key: value
|
||||
for key, value in TestAggregate.fake_ag.metadata.items()
|
||||
if key != 'availability_zone'}),
|
||||
@ -467,7 +468,7 @@ class TestAggregateShow(TestAggregate):
|
||||
self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
self.assertItemEqual(self.data, data)
|
||||
|
||||
|
||||
class TestAggregateUnset(TestAggregate):
|
||||
|
@ -16,8 +16,8 @@
|
||||
import mock
|
||||
from mock import call
|
||||
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
from openstackclient.compute.v2 import flavor
|
||||
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
|
||||
@ -67,7 +67,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
flavor.id,
|
||||
flavor.name,
|
||||
flavor.is_public,
|
||||
utils.format_dict(flavor.properties),
|
||||
format_columns.DictColumn(flavor.properties),
|
||||
flavor.ram,
|
||||
flavor.rxtx_factor,
|
||||
flavor.swap,
|
||||
@ -107,7 +107,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
self.flavors_mock.create.assert_called_once_with(*default_args)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
self.assertItemEqual(self.data, data)
|
||||
|
||||
def test_flavor_create_all_options(self):
|
||||
|
||||
@ -154,7 +154,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
self.flavor.get_keys.assert_called_once_with()
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
self.assertItemEqual(self.data, data)
|
||||
|
||||
def test_flavor_create_other_options(self):
|
||||
|
||||
@ -208,7 +208,7 @@ class TestFlavorCreate(TestFlavor):
|
||||
{'key1': 'value1', 'key2': 'value2'})
|
||||
self.flavor.get_keys.assert_called_with()
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
self.assertItemEqual(self.data, data)
|
||||
|
||||
def test_public_flavor_create_with_project(self):
|
||||
arglist = [
|
||||
@ -338,7 +338,7 @@ class TestFlavorList(TestFlavor):
|
||||
data_long = (data[0] + (
|
||||
flavors[0].swap,
|
||||
flavors[0].rxtx_factor,
|
||||
u'property=\'value\''
|
||||
format_columns.DictColumn(flavors[0].properties),
|
||||
), )
|
||||
|
||||
def setUp(self):
|
||||
@ -376,7 +376,7 @@ class TestFlavorList(TestFlavor):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data), tuple(data))
|
||||
self.assertListItemEqual(self.data, list(data))
|
||||
|
||||
def test_flavor_list_all_flavors(self):
|
||||
arglist = [
|
||||
@ -405,7 +405,7 @@ class TestFlavorList(TestFlavor):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data), tuple(data))
|
||||
self.assertListItemEqual(self.data, list(data))
|
||||
|
||||
def test_flavor_list_private_flavors(self):
|
||||
arglist = [
|
||||
@ -434,7 +434,7 @@ class TestFlavorList(TestFlavor):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data), tuple(data))
|
||||
self.assertListItemEqual(self.data, list(data))
|
||||
|
||||
def test_flavor_list_public_flavors(self):
|
||||
arglist = [
|
||||
@ -463,7 +463,7 @@ class TestFlavorList(TestFlavor):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data), tuple(data))
|
||||
self.assertListItemEqual(self.data, list(data))
|
||||
|
||||
def test_flavor_list_long(self):
|
||||
arglist = [
|
||||
@ -492,7 +492,7 @@ class TestFlavorList(TestFlavor):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns_long, columns)
|
||||
self.assertEqual(tuple(self.data_long), tuple(data))
|
||||
self.assertListItemEqual(self.data_long, list(data))
|
||||
|
||||
|
||||
class TestFlavorSet(TestFlavor):
|
||||
@ -652,7 +652,7 @@ class TestFlavorShow(TestFlavor):
|
||||
flavor.id,
|
||||
flavor.name,
|
||||
flavor.is_public,
|
||||
utils.format_dict(flavor.get_keys()),
|
||||
format_columns.DictColumn(flavor.get_keys()),
|
||||
flavor.ram,
|
||||
flavor.rxtx_factor,
|
||||
flavor.swap,
|
||||
@ -689,7 +689,7 @@ class TestFlavorShow(TestFlavor):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
self.assertItemEqual(self.data, data)
|
||||
|
||||
def test_private_flavor_show(self):
|
||||
private_flavor = compute_fakes.FakeFlavor.create_one_flavor(
|
||||
@ -709,12 +709,12 @@ class TestFlavorShow(TestFlavor):
|
||||
data_with_project = (
|
||||
private_flavor.disabled,
|
||||
private_flavor.ephemeral,
|
||||
self.flavor_access.tenant_id,
|
||||
format_columns.ListColumn([self.flavor_access.tenant_id]),
|
||||
private_flavor.disk,
|
||||
private_flavor.id,
|
||||
private_flavor.name,
|
||||
private_flavor.is_public,
|
||||
utils.format_dict(private_flavor.get_keys()),
|
||||
format_columns.DictColumn(private_flavor.get_keys()),
|
||||
private_flavor.ram,
|
||||
private_flavor.rxtx_factor,
|
||||
private_flavor.swap,
|
||||
@ -728,7 +728,7 @@ class TestFlavorShow(TestFlavor):
|
||||
self.flavor_access_mock.list.assert_called_with(
|
||||
flavor=private_flavor.id)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(data_with_project, data)
|
||||
self.assertItemEqual(data_with_project, data)
|
||||
|
||||
|
||||
class TestFlavorUnset(TestFlavor):
|
||||
|
@ -18,6 +18,7 @@ import getpass
|
||||
|
||||
import mock
|
||||
from mock import call
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils as common_utils
|
||||
from oslo_utils import timeutils
|
||||
@ -298,14 +299,15 @@ class TestServerCreate(TestServer):
|
||||
def datalist(self):
|
||||
datalist = (
|
||||
server._format_servers_list_power_state(
|
||||
getattr(self.new_server, 'OS-EXT-STS:power_state')),
|
||||
'',
|
||||
getattr(self.new_server, 'OS-EXT-STS:power_state')
|
||||
),
|
||||
format_columns.DictListColumn(self.new_server.networks),
|
||||
self.flavor.name + ' (' + self.new_server.flavor.get('id') + ')',
|
||||
self.new_server.id,
|
||||
self.image.name + ' (' + self.new_server.image.get('id') + ')',
|
||||
self.new_server.name,
|
||||
self.new_server.networks,
|
||||
'',
|
||||
format_columns.DictColumn(''),
|
||||
)
|
||||
return datalist
|
||||
|
||||
@ -313,7 +315,10 @@ class TestServerCreate(TestServer):
|
||||
super(TestServerCreate, self).setUp()
|
||||
|
||||
attrs = {
|
||||
'networks': {},
|
||||
'networks': {
|
||||
'private': ['fdb4:4f0f:960b:0:f816:3eff:fed9:af5e',
|
||||
'10.0.0.8']
|
||||
},
|
||||
}
|
||||
self.new_server = compute_fakes.FakeServer.create_one_server(
|
||||
attrs=attrs)
|
||||
@ -394,7 +399,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
self.assertFalse(self.images_mock.called)
|
||||
self.assertFalse(self.flavors_mock.called)
|
||||
|
||||
@ -459,7 +464,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_not_exist_security_group(self):
|
||||
arglist = [
|
||||
@ -545,7 +550,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_network(self):
|
||||
arglist = [
|
||||
@ -650,7 +655,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_auto_network(self):
|
||||
arglist = [
|
||||
@ -695,7 +700,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_none_network(self):
|
||||
arglist = [
|
||||
@ -740,7 +745,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_conflict_network_options(self):
|
||||
arglist = [
|
||||
@ -903,7 +908,7 @@ class TestServerCreate(TestServer):
|
||||
**kwargs
|
||||
)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
@mock.patch.object(common_utils, 'wait_for_status', return_value=False)
|
||||
def test_server_create_with_wait_fails(self, mock_wait_for_status):
|
||||
@ -1010,7 +1015,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_block_device_mapping(self):
|
||||
arglist = [
|
||||
@ -1062,7 +1067,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_block_device_mapping_min_input(self):
|
||||
arglist = [
|
||||
@ -1113,7 +1118,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_block_device_mapping_default_input(self):
|
||||
arglist = [
|
||||
@ -1164,7 +1169,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_block_device_mapping_full_input(self):
|
||||
arglist = [
|
||||
@ -1219,7 +1224,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_block_device_mapping_snapshot(self):
|
||||
arglist = [
|
||||
@ -1274,7 +1279,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_block_device_mapping_multiple(self):
|
||||
arglist = [
|
||||
@ -1337,7 +1342,7 @@ class TestServerCreate(TestServer):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.datalist(), data)
|
||||
self.assertItemEqual(self.datalist(), data)
|
||||
|
||||
def test_server_create_with_block_device_mapping_invalid_format(self):
|
||||
# 1. block device mapping don't contain equal sign "="
|
||||
@ -1597,7 +1602,7 @@ class TestServerList(TestServer):
|
||||
s.id,
|
||||
s.name,
|
||||
s.status,
|
||||
server._format_servers_list_networks(s.networks),
|
||||
format_columns.DictListColumn(s.networks),
|
||||
self.image.name,
|
||||
self.flavor.name,
|
||||
))
|
||||
@ -1609,20 +1614,20 @@ class TestServerList(TestServer):
|
||||
server._format_servers_list_power_state(
|
||||
getattr(s, 'OS-EXT-STS:power_state')
|
||||
),
|
||||
server._format_servers_list_networks(s.networks),
|
||||
format_columns.DictListColumn(s.networks),
|
||||
self.image.name,
|
||||
s.image['id'],
|
||||
self.flavor.name,
|
||||
s.flavor['id'],
|
||||
getattr(s, 'OS-EXT-AZ:availability_zone'),
|
||||
getattr(s, 'OS-EXT-SRV-ATTR:host'),
|
||||
s.Metadata,
|
||||
format_columns.DictColumn(s.Metadata),
|
||||
))
|
||||
self.data_no_name_lookup.append((
|
||||
s.id,
|
||||
s.name,
|
||||
s.status,
|
||||
server._format_servers_list_networks(s.networks),
|
||||
format_columns.DictListColumn(s.networks),
|
||||
s.image['id'],
|
||||
s.flavor['id']
|
||||
))
|
||||
@ -1640,7 +1645,7 @@ class TestServerList(TestServer):
|
||||
|
||||
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data), tuple(data))
|
||||
self.assertListItemEqual(self.data, list(data))
|
||||
|
||||
def test_server_list_long_option(self):
|
||||
arglist = [
|
||||
@ -1656,7 +1661,7 @@ class TestServerList(TestServer):
|
||||
|
||||
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||
self.assertEqual(self.columns_long, columns)
|
||||
self.assertEqual(tuple(self.data_long), tuple(data))
|
||||
self.assertListItemEqual(self.data_long, list(data))
|
||||
|
||||
def test_server_list_no_name_lookup_option(self):
|
||||
arglist = [
|
||||
@ -1672,7 +1677,7 @@ class TestServerList(TestServer):
|
||||
|
||||
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data_no_name_lookup), tuple(data))
|
||||
self.assertListItemEqual(self.data_no_name_lookup, list(data))
|
||||
|
||||
def test_server_list_n_option(self):
|
||||
arglist = [
|
||||
@ -1688,7 +1693,7 @@ class TestServerList(TestServer):
|
||||
|
||||
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data_no_name_lookup), tuple(data))
|
||||
self.assertListItemEqual(self.data_no_name_lookup, list(data))
|
||||
|
||||
def test_server_list_with_image(self):
|
||||
|
||||
@ -1708,7 +1713,7 @@ class TestServerList(TestServer):
|
||||
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data), tuple(data))
|
||||
self.assertListItemEqual(self.data, list(data))
|
||||
|
||||
def test_server_list_with_flavor(self):
|
||||
|
||||
@ -1728,7 +1733,7 @@ class TestServerList(TestServer):
|
||||
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data), tuple(data))
|
||||
self.assertListItemEqual(self.data, list(data))
|
||||
|
||||
def test_server_list_with_changes_since(self):
|
||||
|
||||
@ -1749,7 +1754,7 @@ class TestServerList(TestServer):
|
||||
self.servers_mock.list.assert_called_with(**self.kwargs)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(tuple(self.data), tuple(data))
|
||||
self.assertListItemEqual(self.data, list(data))
|
||||
|
||||
@mock.patch.object(timeutils, 'parse_isotime', side_effect=ValueError)
|
||||
def test_server_list_with_invalid_changes_since(self, mock_parse_isotime):
|
||||
@ -2700,14 +2705,16 @@ class TestServerShow(TestServer):
|
||||
|
||||
self.data = (
|
||||
'Running',
|
||||
'public=10.20.30.40, 2001:db8::f',
|
||||
format_columns.DictListColumn(
|
||||
{'public': ['10.20.30.40', '2001:db8::f']}
|
||||
),
|
||||
self.flavor.name + " (" + self.flavor.id + ")",
|
||||
self.server.id,
|
||||
self.image.name + " (" + self.image.id + ")",
|
||||
self.server.name,
|
||||
{'public': ['10.20.30.40', '2001:db8::f']},
|
||||
'tenant-id-xxx',
|
||||
'',
|
||||
format_columns.DictColumn(''),
|
||||
)
|
||||
|
||||
def test_show_no_options(self):
|
||||
@ -2730,7 +2737,7 @@ class TestServerShow(TestServer):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
self.assertItemEqual(self.data, data)
|
||||
|
||||
def test_show_diagnostics(self):
|
||||
arglist = [
|
||||
@ -2989,13 +2996,13 @@ class TestServerGeneral(TestServer):
|
||||
# Prepare expected data.
|
||||
# Since networks is a dict, whose items are in random order, there
|
||||
# could be two results after formatted.
|
||||
data_1 = (u'private=2001:db8::f, 10.20.30.40; '
|
||||
data_1 = (u'private=10.20.30.40, 2001:db8::f; '
|
||||
u'public=10.20.30.40, 2001:db8::f')
|
||||
data_2 = (u'public=10.20.30.40, 2001:db8::f; '
|
||||
u'private=2001:db8::f, 10.20.30.40')
|
||||
u'private=10.20.30.40, 2001:db8::f')
|
||||
|
||||
# Call _format_servers_list_networks().
|
||||
networks_format = server._format_servers_list_networks(networks)
|
||||
format_col = format_columns.DictListColumn(networks)
|
||||
networks_format = format_col.human_readable()
|
||||
|
||||
msg = ('Network string is not formatted correctly.\n'
|
||||
'reference = %s or %s\n'
|
||||
@ -3044,5 +3051,17 @@ class TestServerGeneral(TestServer):
|
||||
# 'networks' is used to create _server. Remove it.
|
||||
server_detail.pop('networks')
|
||||
|
||||
# Special handle for 'properties', it's DictColumn type
|
||||
prop = server_detail.pop('properties')
|
||||
expected_prop = info.pop('properties')
|
||||
self.assertIsInstance(prop, format_columns.DictColumn)
|
||||
self.assertEqual(expected_prop, prop.human_readable())
|
||||
|
||||
# Special handle for 'addresses', it's DictListColumn type
|
||||
prop = server_detail.pop('addresses')
|
||||
expected_prop = info.pop('addresses')
|
||||
self.assertIsInstance(prop, format_columns.DictListColumn)
|
||||
self.assertEqual(expected_prop, prop.human_readable())
|
||||
|
||||
# Check the results.
|
||||
self.assertEqual(info, server_detail)
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
import mock
|
||||
|
||||
from osc_lib.cli import format_columns
|
||||
from osc_lib import exceptions
|
||||
from osc_lib import utils
|
||||
|
||||
@ -38,9 +39,9 @@ class TestServerGroup(compute_fakes.TestComputev2):
|
||||
|
||||
data = (
|
||||
fake_server_group.id,
|
||||
utils.format_list(fake_server_group.members),
|
||||
format_columns.ListColumn(fake_server_group.members),
|
||||
fake_server_group.name,
|
||||
utils.format_list(fake_server_group.policies),
|
||||
format_columns.ListColumn(fake_server_group.policies),
|
||||
fake_server_group.project_id,
|
||||
fake_server_group.user_id,
|
||||
)
|
||||
@ -78,7 +79,7 @@ class TestServerGroupCreate(TestServerGroup):
|
||||
)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
self.assertItemEqual(self.data, data)
|
||||
|
||||
|
||||
class TestServerGroupDelete(TestServerGroup):
|
||||
@ -182,14 +183,14 @@ class TestServerGroupList(TestServerGroup):
|
||||
list_data = ((
|
||||
TestServerGroup.fake_server_group.id,
|
||||
TestServerGroup.fake_server_group.name,
|
||||
utils.format_list(TestServerGroup.fake_server_group.policies),
|
||||
format_columns.ListColumn(TestServerGroup.fake_server_group.policies),
|
||||
),)
|
||||
|
||||
list_data_long = ((
|
||||
TestServerGroup.fake_server_group.id,
|
||||
TestServerGroup.fake_server_group.name,
|
||||
utils.format_list(TestServerGroup.fake_server_group.policies),
|
||||
utils.format_list(TestServerGroup.fake_server_group.members),
|
||||
format_columns.ListColumn(TestServerGroup.fake_server_group.policies),
|
||||
format_columns.ListColumn(TestServerGroup.fake_server_group.members),
|
||||
TestServerGroup.fake_server_group.project_id,
|
||||
TestServerGroup.fake_server_group.user_id,
|
||||
),)
|
||||
@ -211,7 +212,7 @@ class TestServerGroupList(TestServerGroup):
|
||||
self.server_groups_mock.list.assert_called_once_with(False)
|
||||
|
||||
self.assertEqual(self.list_columns, columns)
|
||||
self.assertEqual(self.list_data, tuple(data))
|
||||
self.assertListItemEqual(self.list_data, list(data))
|
||||
|
||||
def test_server_group_list_with_all_projects_and_long(self):
|
||||
arglist = [
|
||||
@ -227,7 +228,7 @@ class TestServerGroupList(TestServerGroup):
|
||||
self.server_groups_mock.list.assert_called_once_with(True)
|
||||
|
||||
self.assertEqual(self.list_columns_long, columns)
|
||||
self.assertEqual(self.list_data_long, tuple(data))
|
||||
self.assertListItemEqual(self.list_data_long, list(data))
|
||||
|
||||
|
||||
class TestServerGroupShow(TestServerGroup):
|
||||
@ -250,4 +251,4 @@ class TestServerGroupShow(TestServerGroup):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(self.columns, columns)
|
||||
self.assertEqual(self.data, data)
|
||||
self.assertItemEqual(self.data, data)
|
||||
|
@ -0,0 +1,149 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Make console output machine readable. Openstackclient support to format the
|
||||
console output into several formats, like: json, shell, csv, yaml, table.
|
||||
Most of these should be understood by program and code, so we should keep
|
||||
column content as actually complex data structures rather than string, if
|
||||
users specify the output format as machine readable type, for example:
|
||||
``json``, ``yaml``, ``cvs`` and so on, that make sense, like:
|
||||
{'key': 'value'} vs "key='value'"
|
||||
[Blueprint :oscbp:`osc-formattable-columns`]
|
||||
|
||||
The following output format are changed when machine readable format is
|
||||
specified:
|
||||
|
||||
- Compute v2:
|
||||
|
||||
- ``properties`` in **aggregate show**
|
||||
- ``properties`` in **flavor create**
|
||||
- ``Properties`` in **flavor list**
|
||||
- ``properties``, ``access_project_ids`` in **flavor show**
|
||||
- ``volumes_attached``, ``security_groups``, ``addresses``,
|
||||
``properties`` in **server create**
|
||||
- ``volumes_attached``, ``security_groups``, ``addresses``,
|
||||
``properties`` in **server rebuild**
|
||||
- ``volumes_attached``, ``security_groups``, ``addresses``,
|
||||
``properties`` in **server show**
|
||||
- ``Networks``, ``Metadata`` in **server list**
|
||||
- ``properties`` in **server backup create**
|
||||
- ``policies``, ``members`` in **server group create**
|
||||
- ``policies``, ``members`` in **server group show**
|
||||
- ``Policies``, ``Members`` in **server group list**
|
||||
- ``properties`` in **server image create**
|
||||
|
||||
- Object store v1:
|
||||
|
||||
- ``properties`` in **account show**
|
||||
- ``properties`` in **container show**
|
||||
- ``properties`` in **object show**
|
||||
|
||||
- Volume v1:
|
||||
|
||||
- ``Volume ID`` in **volume backup list**
|
||||
- ``properties`` in **volume qos create**
|
||||
- ``Specs``, ``Associations`` in **volume qos list**
|
||||
- ``associations``, ``properties`` in **volume qos show**
|
||||
- ``properties`` in **snapshot create**
|
||||
- ``Metadata``, ``Volume ID`` in **snapshot list**
|
||||
- ``properties`` in **snapshot show**
|
||||
- ``properties`` in **volume create**
|
||||
- ``Metadata``, ``Attachments`` in **volume list**
|
||||
- ``properties`` in **volume show**
|
||||
- ``properties`` in **volume snapshot create**
|
||||
- ``Metadata``, ``Volume ID`` in **volume snapshot list**
|
||||
- ``properties`` in **volume snapshot show**
|
||||
- ``properties``, ``encryption`` in **volume type create**
|
||||
- ``Extra Specs``, ``id`` in **volume type list**
|
||||
- ``properties``, ``encryption`` in **volume type show**
|
||||
|
||||
- Volume v2:
|
||||
|
||||
- ``Volume ID`` in **volume backup list**
|
||||
- ``Volume Types`` in **consistency group list**
|
||||
- ``properties`` in **volume qos create**
|
||||
- ``Specs``, ``Associations`` in **volume qos list**
|
||||
- ``associations``, ``properties`` in **volume qos show**
|
||||
- ``properties`` in **snapshot create**
|
||||
- ``Metadata``, ``Volume ID`` in **snapshot list**
|
||||
- ``properties`` in **snapshot show**
|
||||
- ``properties`` in **volume create**
|
||||
- ``Metadata``, ``Attachments`` in **volume list**
|
||||
- ``properties`` in **volume show**
|
||||
- ``properties`` in **volume snapshot create**
|
||||
- ``Metadata``, ``Volume ID`` in **volume snapshot list**
|
||||
- ``properties`` in **volume snapshot show**
|
||||
- ``properties``, ``encryption`` in **volume type create**
|
||||
- ``Extra Specs``, ``id`` in **volume type list**
|
||||
- ``properties``, ``access_project_ids``, ``encryption``
|
||||
in **volume type show**
|
||||
|
||||
- Identity v2.0:
|
||||
|
||||
- ``Endpoints`` in **catalog list**
|
||||
- ``endpoints`` in **catalog show**
|
||||
- ``properties`` in **project show**
|
||||
- ``tenantId`` in **user list**
|
||||
|
||||
- Identity v3:
|
||||
|
||||
- ``Endpoints`` in **catalog list**
|
||||
- ``endpoints`` in **catalog show**
|
||||
- ``remote_ids`` in **identity provider create**
|
||||
- ``remote_ids`` in **identity provider show**
|
||||
|
||||
- Image v1:
|
||||
|
||||
- ``properties`` in **image create**
|
||||
- ``Visibility``, ``Properties`` in **image list**
|
||||
- ``properties`` in **image show**
|
||||
|
||||
- Image v2:
|
||||
|
||||
- ``tags``, ``properties`` in **image create**
|
||||
- ``Tags`` in **image list**
|
||||
- ``tags``, ``properties`` in **image show**
|
||||
|
||||
- Network v2:
|
||||
|
||||
- ``subnet_ip_availability`` in **ip availability show**
|
||||
- ``subnets``, ``subnet_ids``, ``admin_state_up``,
|
||||
``is_admin_state_up``, ``router:external``, ``is_router_external``,
|
||||
``availability_zones``, ``availability_zone_hints``, ``tags`` in
|
||||
**network create**
|
||||
- ``Subnets``, ``State``, ``Router Type``, ``Availability Zones``,
|
||||
``Tags`` in **network list**
|
||||
- ``subnets``, ``subnet_ids``, ``admin_state_up``,
|
||||
``is_admin_state_up``, ``router:external``, ``is_router_external``,
|
||||
``availability_zones``, ``availability_zone_hints``, ``tags`` in
|
||||
**network show**
|
||||
- ``Alive``, ``State`` in **network agent list**
|
||||
- ``alive``, ``admin_state_up``, ``configurations`` in
|
||||
**network agent show**
|
||||
- ``admin_state_up``, ``allowed_address_pairs``, ``binding_profile``,
|
||||
``binding_vif_details``, ``dns_assignment``, ``extra_dhcp_opts``,
|
||||
``fixed_ips``, ``security_group_ids``, ``tags`` in **port create**
|
||||
- ``Fixed IP Addresses``, ``Status``, ``Security Groups``, ``Tags``
|
||||
in **port list**
|
||||
- ``admin_state_up``, ``allowed_address_pairs``, ``binding_profile``,
|
||||
``binding_vif_details``, ``dns_assignment``, ``extra_dhcp_opts``,
|
||||
``fixed_ips``, ``security_group_ids``, ``tags`` in **port show**
|
||||
- ``admin_state_up``, ``external_gateway_info``,
|
||||
``availability_zones``, ``availability_zone_hints``, ``routes``,
|
||||
``tags`` in **router create**
|
||||
- ``State``, ``Routes``, ``External gateway info``, ``Tags``,
|
||||
``Availability zones`` in **router list**
|
||||
- ``admin_state_up``, ``external_gateway_info``,
|
||||
``availability_zones``, ``availability_zone_hints``, ``routes``,
|
||||
``tags`` in **router show**
|
||||
- ``security_group_rules`` in **security group create**
|
||||
- ``security_group_rules`` in **security group show**
|
||||
- ``allocation_pools``, ``dns_nameservers``, ``host_routes``, ``tags``,
|
||||
``service_types`` in **subnet create**
|
||||
- ``Name Servers``, ``Allocation Pools``, ``Host Routes``, ``Tags``,
|
||||
``Service Types`` in **subnet list**
|
||||
- ``allocation_pools``, ``dns_nameservers``, ``host_routes``, ``tags``,
|
||||
``service_types`` in **subnet show**
|
||||
- ``prefixes``, ``tags`` in **subnet pool create**
|
||||
- ``Prefixes``, ``Tags`` in **subnet pool list**
|
||||
- ``prefixes``, ``tags`` in **subnet pool show**
|
Loading…
x
Reference in New Issue
Block a user