Merge "Make column ordering consistent and predictable"
This commit is contained in:
commit
9694c6aacb
@ -51,6 +51,27 @@ def add_arg(func, *args, **kwargs):
|
||||
func.arguments.insert(0, (args, kwargs))
|
||||
|
||||
|
||||
def field_labels_from(attributes):
|
||||
"""Generate a list of slightly more human readable field names.
|
||||
|
||||
This takes the list of fields/attributes on the object and makes them
|
||||
easier to read.
|
||||
|
||||
:param list attributes:
|
||||
The attribute names to convert. For example, ``["parent_id"]``.
|
||||
:returns:
|
||||
List of field names. For example ``["Parent Id"]``
|
||||
:rtype:
|
||||
list
|
||||
|
||||
Example:
|
||||
|
||||
>>> field_labels_from(["id", "name", "cloud_id"])
|
||||
["Id", "Name", "Cloud Id"]
|
||||
"""
|
||||
return [field.replace('_', ' ').title() for field in attributes]
|
||||
|
||||
|
||||
def print_list(objs, fields, formatters=None, sortby_index=0,
|
||||
mixed_case_fields=None, field_labels=None):
|
||||
"""Print a list or objects as a table, one row per object.
|
||||
|
@ -18,6 +18,7 @@ from oslo_utils import encodeutils
|
||||
import prettytable
|
||||
import six
|
||||
|
||||
from cratonclient.common import cliutils
|
||||
from cratonclient.formatters import base
|
||||
|
||||
|
||||
@ -28,7 +29,7 @@ class Formatter(base.Formatter):
|
||||
"""Set-up after initialization."""
|
||||
self.fields = []
|
||||
self.formatters = {}
|
||||
self.sortby_index = 0
|
||||
self.sortby_index = None
|
||||
self.mixed_case_fields = set([])
|
||||
self.field_labels = []
|
||||
self.dict_property = "Property"
|
||||
@ -71,7 +72,7 @@ class Formatter(base.Formatter):
|
||||
if fields is not None:
|
||||
self.fields = fields
|
||||
if field_labels is None:
|
||||
self.field_labels = self.fields
|
||||
self.field_labels = cliutils.field_labels_from(self.fields)
|
||||
elif len(field_labels) != len(self.fields):
|
||||
raise ValueError(
|
||||
"Field labels list %(labels)s has different number "
|
||||
|
@ -16,7 +16,21 @@ from __future__ import print_function
|
||||
|
||||
from cratonclient.common import cliutils
|
||||
from cratonclient import exceptions as exc
|
||||
from cratonclient.v1 import cells
|
||||
|
||||
DEFAULT_CELL_FIELDS = [
|
||||
'id',
|
||||
'name',
|
||||
'cloud_id',
|
||||
'region_id',
|
||||
'created_at',
|
||||
]
|
||||
|
||||
CELL_FIELDS = DEFAULT_CELL_FIELDS + [
|
||||
'updated_at',
|
||||
'note',
|
||||
'variables',
|
||||
'project_id',
|
||||
]
|
||||
|
||||
|
||||
@cliutils.arg('id',
|
||||
@ -52,7 +66,7 @@ def do_cell_show(cc, args):
|
||||
@cliutils.arg('--fields',
|
||||
nargs='+',
|
||||
metavar='<fields>',
|
||||
default=[],
|
||||
default=DEFAULT_CELL_FIELDS,
|
||||
help='Space-separated list of fields to display. '
|
||||
'Only these fields will be fetched from the server. '
|
||||
'Can not be used when "--detail" is specified')
|
||||
@ -73,7 +87,6 @@ def do_cell_show(cc, args):
|
||||
def do_cell_list(cc, args):
|
||||
"""Print list of cells which are registered with the Craton service."""
|
||||
params = {}
|
||||
default_fields = ['id', 'name']
|
||||
if args.cloud is not None:
|
||||
params['cloud_id'] = args.cloud
|
||||
if args.limit is not None:
|
||||
@ -85,27 +98,29 @@ def do_cell_list(cc, args):
|
||||
if args.all is True:
|
||||
params['limit'] = 100
|
||||
|
||||
if args.fields and args.detail:
|
||||
raise exc.CommandError('Cannot specify both --fields and --detail.')
|
||||
|
||||
if args.detail:
|
||||
fields = cells.CELL_FIELDS
|
||||
if args.fields and args.fields == DEFAULT_CELL_FIELDS:
|
||||
args.fields = CELL_FIELDS
|
||||
else:
|
||||
raise exc.CommandError(
|
||||
'Cannot specify both --fields and --detail.'
|
||||
)
|
||||
params['detail'] = args.detail
|
||||
elif args.fields:
|
||||
try:
|
||||
fields = {x: cells.CELL_FIELDS[x] for x in args.fields}
|
||||
except KeyError as keyerr:
|
||||
raise exc.CommandError('Invalid field "{}"'.format(keyerr.args[0]))
|
||||
else:
|
||||
fields = {x: cells.CELL_FIELDS[x] for x in default_fields}
|
||||
|
||||
fields = args.fields
|
||||
for field in fields:
|
||||
if field not in CELL_FIELDS:
|
||||
raise exc.CommandError(
|
||||
'Invalid field "{}"'.format(field)
|
||||
)
|
||||
sort_key = args.sort_key and args.sort_key.lower()
|
||||
if sort_key is not None:
|
||||
if sort_key not in cells.CELL_FIELDS:
|
||||
if sort_key not in CELL_FIELDS:
|
||||
raise exc.CommandError(
|
||||
('"--sort-key" value was "{}" but should '
|
||||
'be one of: {}').format(
|
||||
args.sort_key,
|
||||
', '.join(cells.CELL_FIELDS.keys())
|
||||
', '.join(CELL_FIELDS)
|
||||
)
|
||||
)
|
||||
params['sort_key'] = sort_key
|
||||
@ -117,7 +132,7 @@ def do_cell_list(cc, args):
|
||||
params['autopaginate'] = args.all
|
||||
|
||||
listed_cells = cc.cells.list(**params)
|
||||
args.formatter.configure(fields=list(fields)).handle(listed_cells)
|
||||
args.formatter.configure(fields=fields).handle(listed_cells)
|
||||
|
||||
|
||||
@cliutils.arg('-n', '--name',
|
||||
@ -141,7 +156,7 @@ def do_cell_list(cc, args):
|
||||
def do_cell_create(cc, args):
|
||||
"""Register a new cell with the Craton service."""
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in cells.CELL_FIELDS and not (v is None)}
|
||||
if k in CELL_FIELDS and not (v is None)}
|
||||
cell = cc.cells.create(**fields)
|
||||
args.formatter.configure(wrap=72).handle(cell)
|
||||
|
||||
@ -168,7 +183,7 @@ def do_cell_create(cc, args):
|
||||
def do_cell_update(cc, args):
|
||||
"""Update a cell that is registered with the Craton service."""
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in cells.CELL_FIELDS and not (v is None)}
|
||||
if k in CELL_FIELDS and not (v is None)}
|
||||
cell_id = fields.pop('id')
|
||||
if not fields:
|
||||
raise exc.CommandError(
|
||||
|
@ -14,7 +14,18 @@ from __future__ import print_function
|
||||
|
||||
from cratonclient.common import cliutils
|
||||
from cratonclient import exceptions as exc
|
||||
from cratonclient.v1 import clouds
|
||||
|
||||
DEFAULT_CLOUD_FIELDS = [
|
||||
'id',
|
||||
'name',
|
||||
'created_at',
|
||||
]
|
||||
|
||||
CLOUD_FIELDS = DEFAULT_CLOUD_FIELDS + [
|
||||
'updated_at',
|
||||
'note',
|
||||
'project_id',
|
||||
]
|
||||
|
||||
|
||||
@cliutils.arg('-n', '--name',
|
||||
@ -26,7 +37,7 @@ from cratonclient.v1 import clouds
|
||||
def do_cloud_create(cc, args):
|
||||
"""Register a new cloud with the Craton service."""
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in clouds.CLOUD_FIELDS and not (v is None)}
|
||||
if k in CLOUD_FIELDS and not (v is None)}
|
||||
|
||||
cloud = cc.clouds.create(**fields)
|
||||
args.formatter.configure(wrap=72).handle(cloud)
|
||||
@ -35,7 +46,7 @@ def do_cloud_create(cc, args):
|
||||
@cliutils.arg('--fields',
|
||||
nargs='+',
|
||||
metavar='<fields>',
|
||||
default=[],
|
||||
default=DEFAULT_CLOUD_FIELDS,
|
||||
help='Comma-separated list of fields to display. '
|
||||
'Only these fields will be fetched from the server. '
|
||||
'Can not be used when "--detail" is specified')
|
||||
@ -45,6 +56,10 @@ def do_cloud_create(cc, args):
|
||||
help='Retrieve and show all clouds. This will override '
|
||||
'the provided value for --limit and automatically '
|
||||
'retrieve each page of results.')
|
||||
@cliutils.arg('--detail',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Show detailed information about all clouds.')
|
||||
@cliutils.arg('--limit',
|
||||
metavar='<limit>',
|
||||
type=int,
|
||||
@ -56,7 +71,6 @@ def do_cloud_create(cc, args):
|
||||
def do_cloud_list(cc, args):
|
||||
"""List all clouds."""
|
||||
params = {}
|
||||
default_fields = ['id', 'name']
|
||||
if args.limit is not None:
|
||||
if args.limit < 0:
|
||||
raise exc.CommandError('Invalid limit specified. Expected '
|
||||
@ -66,13 +80,22 @@ def do_cloud_list(cc, args):
|
||||
if args.all is True:
|
||||
params['limit'] = 100
|
||||
|
||||
if args.fields:
|
||||
try:
|
||||
fields = {x: clouds.CLOUD_FIELDS[x] for x in args.fields}
|
||||
except KeyError as err:
|
||||
raise exc.CommandError('Invalid field "{}"'.format(err.args[0]))
|
||||
else:
|
||||
fields = default_fields
|
||||
if args.detail:
|
||||
if args.fields and args.fields == DEFAULT_CLOUD_FIELDS:
|
||||
args.fields = CLOUD_FIELDS
|
||||
else:
|
||||
raise exc.CommandError(
|
||||
'Cannot specify both --fields and --detail.'
|
||||
)
|
||||
params['detail'] = args.detail
|
||||
|
||||
fields = args.fields
|
||||
for field in args.fields:
|
||||
if field not in CLOUD_FIELDS:
|
||||
raise exc.CommandError(
|
||||
'Invalid field "{}"'.format(field)
|
||||
)
|
||||
|
||||
params['marker'] = args.marker
|
||||
params['autopaginate'] = args.all
|
||||
|
||||
@ -102,7 +125,7 @@ def do_cloud_show(cc, args):
|
||||
def do_cloud_update(cc, args):
|
||||
"""Update a cloud that is registered with the Craton service."""
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in clouds.CLOUD_FIELDS and not (v is None)}
|
||||
if k in CLOUD_FIELDS and not (v is None)}
|
||||
item_id = fields.pop('id')
|
||||
if not fields:
|
||||
raise exc.CommandError(
|
||||
|
@ -16,7 +16,28 @@ from __future__ import print_function
|
||||
|
||||
from cratonclient.common import cliutils
|
||||
from cratonclient import exceptions as exc
|
||||
from cratonclient.v1 import hosts
|
||||
|
||||
|
||||
DEFAULT_HOST_FIELDS = [
|
||||
'id',
|
||||
'name',
|
||||
'active',
|
||||
'device_type',
|
||||
'ip_address',
|
||||
'cloud_id',
|
||||
'region_id',
|
||||
'cell_id',
|
||||
'created_at',
|
||||
]
|
||||
|
||||
HOST_FIELDS = DEFAULT_HOST_FIELDS + [
|
||||
'updated_at',
|
||||
'note',
|
||||
'variables',
|
||||
'labels',
|
||||
'parent_id',
|
||||
'project_id',
|
||||
]
|
||||
|
||||
|
||||
@cliutils.arg('id',
|
||||
@ -57,7 +78,7 @@ def do_host_show(cc, args):
|
||||
@cliutils.arg('--fields',
|
||||
nargs='+',
|
||||
metavar='<fields>',
|
||||
default=[],
|
||||
default=DEFAULT_HOST_FIELDS,
|
||||
help='Space-separated list of fields to display. '
|
||||
'Only these fields will be fetched from the server. '
|
||||
'Can not be used when "--detail" is specified')
|
||||
@ -94,7 +115,6 @@ def do_host_show(cc, args):
|
||||
def do_host_list(cc, args):
|
||||
"""Print list of hosts which are registered with the Craton service."""
|
||||
params = {}
|
||||
default_fields = ['id', 'name', 'device_type', 'active', 'cell_id']
|
||||
if args.cell is not None:
|
||||
params['cell_id'] = args.cell
|
||||
if args.cloud is not None:
|
||||
@ -116,26 +136,29 @@ def do_host_list(cc, args):
|
||||
if args.all is True:
|
||||
params['limit'] = 100
|
||||
|
||||
if args.fields and args.detail:
|
||||
raise exc.CommandError('Cannot specify both --fields and --detail.')
|
||||
|
||||
if args.detail:
|
||||
fields = hosts.HOST_FIELDS
|
||||
if args.fields and args.fields == DEFAULT_HOST_FIELDS:
|
||||
args.fields = HOST_FIELDS
|
||||
else:
|
||||
raise exc.CommandError(
|
||||
'Cannot specify both --fields and --detail.'
|
||||
)
|
||||
params['detail'] = args.detail
|
||||
elif args.fields:
|
||||
try:
|
||||
fields = {x: hosts.HOST_FIELDS[x] for x in args.fields}
|
||||
except KeyError as keyerr:
|
||||
raise exc.CommandError('Invalid field "{}"'.format(keyerr.args[0]))
|
||||
else:
|
||||
fields = {x: hosts.HOST_FIELDS[x] for x in default_fields}
|
||||
|
||||
fields = args.fields
|
||||
for field in args.fields:
|
||||
if field not in HOST_FIELDS:
|
||||
raise exc.CommandError(
|
||||
'Invalid field "{}"'.format(field)
|
||||
)
|
||||
|
||||
sort_key = args.sort_key and args.sort_key.lower()
|
||||
if sort_key is not None:
|
||||
if sort_key not in hosts.HOST_FIELDS:
|
||||
if sort_key not in HOST_FIELDS:
|
||||
raise exc.CommandError(
|
||||
'{0} is an invalid key for sorting, valid values for '
|
||||
'--sort-key are: {1}'.format(
|
||||
args.sort_key, hosts.HOST_FIELDS.keys()
|
||||
args.sort_key, HOST_FIELDS
|
||||
)
|
||||
)
|
||||
params['sort_key'] = sort_key
|
||||
@ -147,7 +170,7 @@ def do_host_list(cc, args):
|
||||
params['autopaginate'] = args.all
|
||||
|
||||
host_list = cc.hosts.list(**params)
|
||||
args.formatter.configure(fields=list(fields)).handle(host_list)
|
||||
args.formatter.configure(fields=fields).handle(host_list)
|
||||
|
||||
|
||||
@cliutils.arg('-n', '--name',
|
||||
@ -191,7 +214,7 @@ def do_host_list(cc, args):
|
||||
def do_host_create(cc, args):
|
||||
"""Register a new host with the Craton service."""
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in hosts.HOST_FIELDS and (v or v is False)}
|
||||
if k in HOST_FIELDS and (v or v is False)}
|
||||
host = cc.hosts.create(**fields)
|
||||
args.formatter.configure(wrap=72).handle(host)
|
||||
|
||||
@ -232,7 +255,7 @@ def do_host_create(cc, args):
|
||||
def do_host_update(cc, args):
|
||||
"""Update a host that is registered with the Craton service."""
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in hosts.HOST_FIELDS and (v or v is False)}
|
||||
if k in HOST_FIELDS and (v or v is False)}
|
||||
item_id = fields.pop('id')
|
||||
host = cc.hosts.update(item_id, **fields)
|
||||
print("Host {0} has been successfully updated.".format(host.id))
|
||||
|
@ -16,7 +16,17 @@ from __future__ import print_function
|
||||
|
||||
from cratonclient.common import cliutils
|
||||
from cratonclient import exceptions as exc
|
||||
from cratonclient.v1 import projects
|
||||
|
||||
|
||||
DEFAULT_PROJECT_FIELDS = [
|
||||
'id',
|
||||
'name',
|
||||
]
|
||||
|
||||
PROJECT_FIELDS = DEFAULT_PROJECT_FIELDS + [
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]
|
||||
|
||||
|
||||
@cliutils.arg('id',
|
||||
@ -38,7 +48,7 @@ def do_project_show(cc, args):
|
||||
@cliutils.arg('--fields',
|
||||
nargs='+',
|
||||
metavar='<fields>',
|
||||
default=[],
|
||||
default=DEFAULT_PROJECT_FIELDS,
|
||||
help='Space-separated list of fields to display. '
|
||||
'Only these fields will be fetched from the server. '
|
||||
'Can not be used when "--detail" is specified')
|
||||
@ -59,7 +69,6 @@ def do_project_show(cc, args):
|
||||
def do_project_list(cc, args):
|
||||
"""Print list of projects which are registered with the Craton service."""
|
||||
params = {}
|
||||
default_fields = ['id', 'name']
|
||||
if args.limit is not None:
|
||||
if args.limit < 0:
|
||||
raise exc.CommandError('Invalid limit specified. Expected '
|
||||
@ -69,20 +78,24 @@ def do_project_list(cc, args):
|
||||
if args.all is True:
|
||||
params['limit'] = 100
|
||||
|
||||
if args.fields and args.detail:
|
||||
raise exc.CommandError('Cannot specify both --fields and --detail.')
|
||||
if args.detail:
|
||||
if args.fields and args.fields == DEFAULT_PROJECT_FIELDS:
|
||||
args.fields = PROJECT_FIELDS
|
||||
else:
|
||||
raise exc.CommandError(
|
||||
'Cannot specify both --fields and --detail.'
|
||||
)
|
||||
|
||||
fields = args.fields
|
||||
for field in fields:
|
||||
if field not in PROJECT_FIELDS:
|
||||
raise exc.CommandError(
|
||||
'Invalid field "{}"'.format(field)
|
||||
)
|
||||
|
||||
if args.name:
|
||||
params['name'] = args.name
|
||||
if args.detail:
|
||||
fields = projects.PROJECT_FIELDS
|
||||
elif args.fields:
|
||||
try:
|
||||
fields = {x: projects.PROJECT_FIELDS[x] for x in args.fields}
|
||||
except KeyError as keyerr:
|
||||
raise exc.CommandError('Invalid field "{}"'.format(keyerr.args[0]))
|
||||
else:
|
||||
fields = {x: projects.PROJECT_FIELDS[x] for x in default_fields}
|
||||
|
||||
params['marker'] = args.marker
|
||||
params['autopaginate'] = args.all
|
||||
|
||||
@ -97,7 +110,7 @@ def do_project_list(cc, args):
|
||||
def do_project_create(cc, args):
|
||||
"""Register a new project with the Craton service."""
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in projects.PROJECT_FIELDS and not (v is None)}
|
||||
if k in PROJECT_FIELDS and not (v is None)}
|
||||
project = cc.projects.create(**fields)
|
||||
args.formatter.configure(wrap=72).handle(project)
|
||||
|
||||
|
@ -14,7 +14,19 @@ from __future__ import print_function
|
||||
|
||||
from cratonclient.common import cliutils
|
||||
from cratonclient import exceptions as exc
|
||||
from cratonclient.v1 import regions
|
||||
|
||||
DEFAULT_REGION_FIELDS = [
|
||||
'id',
|
||||
'name',
|
||||
'cloud_id',
|
||||
]
|
||||
|
||||
REGION_FIELDS = DEFAULT_REGION_FIELDS + [
|
||||
'project_id',
|
||||
'note',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]
|
||||
|
||||
|
||||
@cliutils.arg('-n', '--name',
|
||||
@ -32,7 +44,7 @@ from cratonclient.v1 import regions
|
||||
def do_region_create(cc, args):
|
||||
"""Register a new region with the Craton service."""
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in regions.REGION_FIELDS and not (v is None)}
|
||||
if k in REGION_FIELDS and not (v is None)}
|
||||
|
||||
region = cc.regions.create(**fields)
|
||||
args.formatter.configure(wrap=72).handle(region)
|
||||
@ -45,10 +57,14 @@ def do_region_create(cc, args):
|
||||
@cliutils.arg('--fields',
|
||||
nargs='+',
|
||||
metavar='<fields>',
|
||||
default=[],
|
||||
default=DEFAULT_REGION_FIELDS,
|
||||
help='Space-separated list of fields to display. '
|
||||
'Only these fields will be fetched from the server. '
|
||||
'Can not be used when "--detail" is specified')
|
||||
@cliutils.arg('--detail',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Show detailed information about the regions.')
|
||||
@cliutils.arg('--all',
|
||||
action='store_true',
|
||||
default=False,
|
||||
@ -66,7 +82,6 @@ def do_region_create(cc, args):
|
||||
def do_region_list(cc, args):
|
||||
"""List all regions."""
|
||||
params = {}
|
||||
default_fields = ['id', 'name']
|
||||
if args.cloud is not None:
|
||||
params['cloud_id'] = args.cloud
|
||||
if args.limit is not None:
|
||||
@ -78,13 +93,21 @@ def do_region_list(cc, args):
|
||||
if args.all is True:
|
||||
params['limit'] = 100
|
||||
|
||||
if args.fields:
|
||||
try:
|
||||
fields = {x: regions.REGION_FIELDS[x] for x in args.fields}
|
||||
except KeyError as err:
|
||||
raise exc.CommandError('Invalid field "{}"'.format(err.args[0]))
|
||||
else:
|
||||
fields = default_fields
|
||||
if args.detail:
|
||||
if args.fields and args.fields == DEFAULT_REGION_FIELDS:
|
||||
args.fields = REGION_FIELDS
|
||||
else:
|
||||
raise exc.CommandError(
|
||||
'Cannot specify both --fields and --detail.'
|
||||
)
|
||||
params['detail'] = args.detail
|
||||
|
||||
fields = args.fields
|
||||
for field in args.fields:
|
||||
if field not in REGION_FIELDS:
|
||||
raise exc.CommandError(
|
||||
'Invalid field "{}"'.format(field)
|
||||
)
|
||||
|
||||
params['marker'] = args.marker
|
||||
params['autopaginate'] = args.all
|
||||
@ -120,7 +143,7 @@ def do_region_show(cc, args):
|
||||
def do_region_update(cc, args):
|
||||
"""Update a region that is registered with the Craton service."""
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in regions.REGION_FIELDS and not (v is None)}
|
||||
if k in REGION_FIELDS and not (v is None)}
|
||||
item_id = fields.pop('id')
|
||||
if not fields:
|
||||
raise exc.CommandError(
|
||||
|
@ -31,7 +31,7 @@ class TestTableFormatter(base.FormatterTestCase):
|
||||
"""Verify we set up defaults for our PrettyTable formatter."""
|
||||
self.assertEqual([], self.formatter.fields)
|
||||
self.assertEqual({}, self.formatter.formatters)
|
||||
self.assertEqual(0, self.formatter.sortby_index)
|
||||
self.assertIsNone(self.formatter.sortby_index)
|
||||
self.assertEqual(set([]), self.formatter.mixed_case_fields)
|
||||
self.assertEqual([], self.formatter.field_labels)
|
||||
self.assertEqual("Property", self.formatter.dict_property)
|
||||
@ -63,14 +63,14 @@ class TestTableFormatter(base.FormatterTestCase):
|
||||
# Assert defaults remain unchanged
|
||||
self.assertEqual([], self.formatter.fields)
|
||||
self.assertEqual([], self.formatter.field_labels)
|
||||
self.assertEqual(0, self.formatter.sortby_index)
|
||||
self.assertIsNone(self.formatter.sortby_index)
|
||||
|
||||
# Case 1: Just fields
|
||||
def test_configure_fields_only(self):
|
||||
"""Verify the logic for configuring fields."""
|
||||
self.formatter.configure(fields=['id', 'name'])
|
||||
self.assertListEqual(['id', 'name'], self.formatter.fields)
|
||||
self.assertListEqual(['id', 'name'], self.formatter.field_labels)
|
||||
self.assertListEqual(['Id', 'Name'], self.formatter.field_labels)
|
||||
|
||||
# Case 2: fields + field_labels
|
||||
def test_configure_fields_and_field_labels(self):
|
||||
@ -167,6 +167,7 @@ class TestTableFormatter(base.FormatterTestCase):
|
||||
def test_sortby_kwargs(self):
|
||||
"""Verify sortby_kwargs relies on sortby_index."""
|
||||
self.formatter.field_labels = ['id', 'created_at']
|
||||
self.formatter.sortby_index = 0
|
||||
self.assertDictEqual({'sortby': 'id'}, self.formatter.sortby_kwargs())
|
||||
|
||||
self.formatter.sortby_index = 1
|
||||
@ -219,10 +220,10 @@ class TestTableFormatter(base.FormatterTestCase):
|
||||
self.formatter.handle_generator(crud.Resource(mock.Mock(), info)
|
||||
for info in info_list)
|
||||
|
||||
PrettyTable.assert_called_once_with(['id', 'Name'])
|
||||
PrettyTable.assert_called_once_with(['Id', 'Name'])
|
||||
self.assertListEqual(
|
||||
[mock.call([i, 'Test Resource']) for i in range(15)],
|
||||
mocktable.add_row.call_args_list,
|
||||
)
|
||||
mocktable.get_string.assert_called_once_with(sortby='id')
|
||||
mocktable.get_string.assert_called_once_with()
|
||||
self.print_.assert_called_once_with('')
|
||||
|
@ -99,3 +99,8 @@ class TestShellCommandUsingPrintList(TestShellCommand):
|
||||
kwargs = self.formatter.configure.call_args[1]
|
||||
self.assertListEqual(expected_fields,
|
||||
sorted(kwargs['fields']))
|
||||
|
||||
def assertFieldsEqualTo(self, expected_fields):
|
||||
"""Assert the sorted fields parameter is equal expected_fields."""
|
||||
kwargs = self.formatter.configure.call_args[1]
|
||||
self.assertListEqual(expected_fields, kwargs['fields'])
|
||||
|
@ -17,7 +17,6 @@ import mock
|
||||
from cratonclient import exceptions
|
||||
from cratonclient.shell.v1 import cells_shell
|
||||
from cratonclient.tests.unit.shell import base
|
||||
from cratonclient.v1 import cells
|
||||
|
||||
|
||||
class TestDoShellShow(base.TestShellCommandUsingPrintDict):
|
||||
@ -54,7 +53,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
||||
kwargs.setdefault('limit', None)
|
||||
kwargs.setdefault('sort_key', None)
|
||||
kwargs.setdefault('sort_dir', 'asc')
|
||||
kwargs.setdefault('fields', [])
|
||||
kwargs.setdefault('fields', cells_shell.DEFAULT_CELL_FIELDS)
|
||||
kwargs.setdefault('marker', None)
|
||||
kwargs.setdefault('all', False)
|
||||
return super(TestDoCellList, self).args_for(**kwargs)
|
||||
@ -71,7 +70,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(cells_shell.DEFAULT_CELL_FIELDS)
|
||||
|
||||
def test_with_cloud_id(self):
|
||||
"""Verify the behaviour of do_cell_list with mostly default values."""
|
||||
@ -86,7 +85,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(cells_shell.DEFAULT_CELL_FIELDS)
|
||||
|
||||
def test_negative_limit(self):
|
||||
"""Ensure we raise an exception for negative limits."""
|
||||
@ -108,7 +107,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(cells_shell.DEFAULT_CELL_FIELDS)
|
||||
|
||||
def test_valid_sort_key(self):
|
||||
"""Verify that we pass on our sort key."""
|
||||
@ -123,7 +122,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(cells_shell.DEFAULT_CELL_FIELDS)
|
||||
|
||||
def test_invalid_sort_key(self):
|
||||
"""Verify that do not we pass on our sort key."""
|
||||
@ -145,7 +144,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(sorted(list(cells.CELL_FIELDS)))
|
||||
self.assertFieldsEqualTo(cells_shell.CELL_FIELDS)
|
||||
|
||||
def test_raises_exception_with_detail_and_fields(self):
|
||||
"""Verify that we fail when users specify --detail and --fields."""
|
||||
@ -169,7 +168,7 @@ class TestDoCellList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name', 'note'])
|
||||
self.assertFieldsEqualTo(['id', 'name', 'note'])
|
||||
|
||||
def test_invalid_fields(self):
|
||||
"""Verify that we error out with invalid fields."""
|
||||
|
@ -196,7 +196,7 @@ class TestDoCloudList(base.TestShellCommandUsingPrintList):
|
||||
"""Generate the default argument list for cloud-list."""
|
||||
kwargs.setdefault('detail', False)
|
||||
kwargs.setdefault('limit', None)
|
||||
kwargs.setdefault('fields', [])
|
||||
kwargs.setdefault('fields', clouds_shell.DEFAULT_CLOUD_FIELDS)
|
||||
kwargs.setdefault('marker', None)
|
||||
kwargs.setdefault('all', False)
|
||||
return super(TestDoCloudList, self).args_for(**kwargs)
|
||||
@ -206,7 +206,7 @@ class TestDoCloudList(base.TestShellCommandUsingPrintList):
|
||||
args = self.args_for()
|
||||
clouds_shell.do_cloud_list(self.craton_client, args)
|
||||
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(clouds_shell.DEFAULT_CLOUD_FIELDS)
|
||||
|
||||
def test_negative_limit(self):
|
||||
"""Ensure we raise an exception for negative limits."""
|
||||
@ -222,13 +222,13 @@ class TestDoCloudList(base.TestShellCommandUsingPrintList):
|
||||
marker=None,
|
||||
autopaginate=False,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(clouds_shell.DEFAULT_CLOUD_FIELDS)
|
||||
|
||||
def test_fields(self):
|
||||
"""Verify that we print out specific fields."""
|
||||
args = self.args_for(fields=['id', 'name', 'note'])
|
||||
clouds_shell.do_cloud_list(self.craton_client, args)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name', 'note'])
|
||||
self.assertFieldsEqualTo(['id', 'name', 'note'])
|
||||
|
||||
def test_invalid_fields(self):
|
||||
"""Verify that we error out with invalid fields."""
|
||||
|
@ -46,7 +46,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
kwargs.setdefault('limit', None)
|
||||
kwargs.setdefault('sort_key', None)
|
||||
kwargs.setdefault('sort_dir', 'asc')
|
||||
kwargs.setdefault('fields', [])
|
||||
kwargs.setdefault('fields', hosts_shell.DEFAULT_HOST_FIELDS)
|
||||
kwargs.setdefault('marker', None)
|
||||
kwargs.setdefault('all', False)
|
||||
kwargs.setdefault('vars', None)
|
||||
@ -67,9 +67,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedPrintListFieldsEqualTo([
|
||||
'active', 'cell_id', 'device_type', 'id', 'name'
|
||||
])
|
||||
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
|
||||
|
||||
def test_with_cell_id(self):
|
||||
"""Verify that we include the cell_id in the params."""
|
||||
@ -84,9 +82,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedPrintListFieldsEqualTo([
|
||||
'active', 'cell_id', 'device_type', 'id', 'name',
|
||||
])
|
||||
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
|
||||
|
||||
def test_with_cloud_id(self):
|
||||
"""Verify that we include the cell_id in the params."""
|
||||
@ -101,9 +97,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedPrintListFieldsEqualTo([
|
||||
'active', 'cell_id', 'device_type', 'id', 'name',
|
||||
])
|
||||
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
|
||||
|
||||
def test_with_detail(self):
|
||||
"""Verify the behaviour of specifying --detail."""
|
||||
@ -118,22 +112,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedPrintListFieldsEqualTo([
|
||||
'active',
|
||||
'cell_id',
|
||||
'cloud_id',
|
||||
'created_at',
|
||||
'device_type',
|
||||
'id',
|
||||
'ip_address',
|
||||
'labels',
|
||||
'name',
|
||||
'note',
|
||||
'parent_id',
|
||||
'project_id',
|
||||
'region_id',
|
||||
'updated_at',
|
||||
])
|
||||
self.assertFieldsEqualTo(hosts_shell.HOST_FIELDS)
|
||||
|
||||
def test_with_limit(self):
|
||||
"""Verify the behaviour with --limit specified."""
|
||||
@ -148,9 +127,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedPrintListFieldsEqualTo([
|
||||
'active', 'cell_id', 'device_type', 'id', 'name'
|
||||
])
|
||||
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
|
||||
|
||||
def test_negative_limit_raises_command_error(self):
|
||||
"""Verify that we forbid negative limit values."""
|
||||
@ -172,9 +149,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedPrintListFieldsEqualTo([
|
||||
'active', 'cell_id', 'device_type', 'id', 'name'
|
||||
])
|
||||
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
|
||||
|
||||
def test_with_label(self):
|
||||
"""Verify the behaviour with --label specified."""
|
||||
@ -189,9 +164,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedPrintListFieldsEqualTo([
|
||||
'active', 'cell_id', 'device_type', 'id', 'name'
|
||||
])
|
||||
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
|
||||
|
||||
def test_with_device_type(self):
|
||||
"""Verify the behaviour with --device-type specified."""
|
||||
@ -206,9 +179,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedPrintListFieldsEqualTo([
|
||||
'active', 'cell_id', 'device_type', 'id', 'name'
|
||||
])
|
||||
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
|
||||
|
||||
def test_with_ip(self):
|
||||
"""Verify the behaviour with --ip specified."""
|
||||
@ -223,9 +194,7 @@ class TestDoHostList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedPrintListFieldsEqualTo([
|
||||
'active', 'cell_id', 'device_type', 'id', 'name'
|
||||
])
|
||||
self.assertFieldsEqualTo(hosts_shell.DEFAULT_HOST_FIELDS)
|
||||
|
||||
def test_fields(self):
|
||||
"""Verify that we can specify custom fields."""
|
||||
|
@ -19,7 +19,6 @@ import mock
|
||||
from cratonclient import exceptions
|
||||
from cratonclient.shell.v1 import projects_shell
|
||||
from cratonclient.tests.unit.shell import base
|
||||
from cratonclient.v1 import projects
|
||||
|
||||
|
||||
class TestDoShellShow(base.TestShellCommandUsingPrintDict):
|
||||
@ -53,7 +52,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
kwargs.setdefault('name', None)
|
||||
kwargs.setdefault('limit', None)
|
||||
kwargs.setdefault('detail', False)
|
||||
kwargs.setdefault('fields', [])
|
||||
kwargs.setdefault('fields', projects_shell.DEFAULT_PROJECT_FIELDS)
|
||||
kwargs.setdefault('marker', None)
|
||||
kwargs.setdefault('all', False)
|
||||
return super(TestDoProjectList, self).args_for(**kwargs)
|
||||
@ -68,7 +67,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
marker=None,
|
||||
autopaginate=False,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(projects_shell.DEFAULT_PROJECT_FIELDS)
|
||||
|
||||
def test_negative_limit(self):
|
||||
"""Ensure we raise an exception for negative limits."""
|
||||
@ -89,7 +88,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(projects_shell.DEFAULT_PROJECT_FIELDS)
|
||||
|
||||
def test_detail(self):
|
||||
"""Verify the behaviour of specifying --detail."""
|
||||
@ -101,7 +100,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
marker=None,
|
||||
autopaginate=False,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(sorted(list(projects.PROJECT_FIELDS)))
|
||||
self.assertFieldsEqualTo(projects_shell.PROJECT_FIELDS)
|
||||
|
||||
def test_list_name(self):
|
||||
"""Verify the behaviour of specifying --detail."""
|
||||
@ -114,13 +113,13 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(projects_shell.DEFAULT_PROJECT_FIELDS)
|
||||
|
||||
def test_raises_exception_with_detail_and_fields(self):
|
||||
"""Verify that we fail when users specify --detail and --fields."""
|
||||
args = self.args_for(
|
||||
detail=True,
|
||||
fields=['id', 'name'],
|
||||
fields=['name', 'id'],
|
||||
)
|
||||
|
||||
self.assertRaisesCommandErrorWith(projects_shell.do_project_list, args)
|
||||
@ -128,7 +127,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
|
||||
def test_fields(self):
|
||||
"""Verify that we print out specific fields."""
|
||||
args = self.args_for(fields=['id', 'name'])
|
||||
args = self.args_for(fields=['name', 'id'])
|
||||
|
||||
projects_shell.do_project_list(self.craton_client, args)
|
||||
|
||||
@ -136,7 +135,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(['name', 'id'])
|
||||
|
||||
def test_invalid_fields(self):
|
||||
"""Verify that we error out with invalid fields."""
|
||||
|
@ -204,7 +204,7 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
|
||||
kwargs.setdefault('detail', False)
|
||||
kwargs.setdefault('cloud', None)
|
||||
kwargs.setdefault('limit', None)
|
||||
kwargs.setdefault('fields', [])
|
||||
kwargs.setdefault('fields', regions_shell.DEFAULT_REGION_FIELDS)
|
||||
kwargs.setdefault('marker', None)
|
||||
kwargs.setdefault('all', False)
|
||||
return super(TestDoRegionList, self).args_for(**kwargs)
|
||||
@ -214,7 +214,7 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
|
||||
args = self.args_for()
|
||||
regions_shell.do_region_list(self.craton_client, args)
|
||||
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(regions_shell.DEFAULT_REGION_FIELDS)
|
||||
|
||||
def test_with_cloud_id(self):
|
||||
"""Test region-list with default values."""
|
||||
@ -225,7 +225,7 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
|
||||
marker=None,
|
||||
autopaginate=False,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(regions_shell.DEFAULT_REGION_FIELDS)
|
||||
|
||||
def test_negative_limit(self):
|
||||
"""Ensure we raise an exception for negative limits."""
|
||||
@ -241,13 +241,13 @@ class TestDoRegionList(base.TestShellCommandUsingPrintList):
|
||||
marker=None,
|
||||
autopaginate=False,
|
||||
)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
self.assertFieldsEqualTo(regions_shell.DEFAULT_REGION_FIELDS)
|
||||
|
||||
def test_fields(self):
|
||||
"""Verify that we print out specific fields."""
|
||||
args = self.args_for(fields=['id', 'name', 'note'])
|
||||
args = self.args_for(fields=['name', 'id', 'note'])
|
||||
regions_shell.do_region_list(self.craton_client, args)
|
||||
self.assertSortedFieldsEqualTo(['id', 'name', 'note'])
|
||||
self.assertFieldsEqualTo(['name', 'id', 'note'])
|
||||
|
||||
def test_invalid_fields(self):
|
||||
"""Verify that we error out with invalid fields."""
|
||||
|
@ -27,15 +27,3 @@ class CellManager(crud.CRUDClient):
|
||||
key = 'cell'
|
||||
base_path = '/cells'
|
||||
resource_class = Cell
|
||||
|
||||
|
||||
CELL_FIELDS = {
|
||||
'id': 'ID',
|
||||
'region_id': 'Region ID',
|
||||
'project_id': 'Project ID',
|
||||
'cloud_id': 'Cloud ID',
|
||||
'name': 'Name',
|
||||
'note': 'Note',
|
||||
'created_at': 'Created At',
|
||||
'updated_at': 'Updated At'
|
||||
}
|
||||
|
@ -27,12 +27,3 @@ class CloudManager(crud.CRUDClient):
|
||||
key = 'cloud'
|
||||
base_path = '/clouds'
|
||||
resource_class = Cloud
|
||||
|
||||
CLOUD_FIELDS = {
|
||||
'id': 'ID',
|
||||
'project_id': 'Project ID',
|
||||
'name': 'Name',
|
||||
'note': 'Note',
|
||||
'created_at': 'Created At',
|
||||
'updated_at': 'Updated At'
|
||||
}
|
||||
|
@ -27,21 +27,3 @@ class HostManager(crud.CRUDClient):
|
||||
key = 'host'
|
||||
base_path = '/hosts'
|
||||
resource_class = Host
|
||||
|
||||
|
||||
HOST_FIELDS = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'device_type': 'Device Type',
|
||||
'project_id': 'Project ID',
|
||||
'cloud_id': 'Cloud ID',
|
||||
'region_id': 'Region ID',
|
||||
'cell_id': 'Cell ID',
|
||||
'ip_address': 'IP Address',
|
||||
'active': 'Active',
|
||||
'note': 'Note',
|
||||
'created_at': 'Created At',
|
||||
'updated_at': 'Updated At',
|
||||
'labels': 'Labels',
|
||||
'parent_id': 'Parent ID',
|
||||
}
|
||||
|
@ -27,11 +27,3 @@ class ProjectManager(crud.CRUDClient):
|
||||
key = 'project'
|
||||
base_path = '/projects'
|
||||
resource_class = Project
|
||||
|
||||
|
||||
PROJECT_FIELDS = {
|
||||
'id': 'ID',
|
||||
'name': 'Name',
|
||||
'created_at': 'Created At',
|
||||
'updated_at': 'Updated At'
|
||||
}
|
||||
|
@ -28,13 +28,3 @@ class RegionManager(crud.CRUDClient):
|
||||
base_path = '/regions'
|
||||
resource_class = Region
|
||||
project_id = 0
|
||||
|
||||
REGION_FIELDS = {
|
||||
'id': 'ID',
|
||||
'project_id': 'Project ID',
|
||||
'cloud_id': 'Cloud ID',
|
||||
'name': 'Name',
|
||||
'note': 'Note',
|
||||
'created_at': 'Created At',
|
||||
'updated_at': 'Updated At'
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user