Skip to content

Commit c44f26e

Browse files
amotokiDean Troyer
authored andcommitted
Use cliff formattable columns in network commands
Use cliff formattable columns not to convert complex fields into a string when a machine readable format like JSON or YAML is requested. Partial-Bug: #1687955 Partially implement blueprint osc-formattable-columns Change-Id: I9878f327e39f56852cc0fb6e4eee9105b7141da9
1 parent 6385d64 commit c44f26e

25 files changed

Lines changed: 407 additions & 367 deletions

openstackclient/network/v2/ip_availability.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
"""IP Availability Info implementations"""
1515

16+
from osc_lib.cli import format_columns
1617
from osc_lib.command import command
1718
from osc_lib import utils
1819

@@ -21,7 +22,7 @@
2122
from openstackclient.network import sdk_utils
2223

2324
_formatters = {
24-
'subnet_ip_availability': utils.format_list_of_dicts,
25+
'subnet_ip_availability': format_columns.ListDictColumn,
2526
}
2627

2728

openstackclient/network/v2/network.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
"""Network action implementations"""
1515

16+
from cliff import columns as cliff_columns
17+
from osc_lib.cli import format_columns
1618
from osc_lib.command import command
1719
from osc_lib import utils
1820

@@ -23,24 +25,26 @@
2325
from openstackclient.network.v2 import _tag
2426

2527

26-
def _format_admin_state(item):
27-
return 'UP' if item else 'DOWN'
28+
class AdminStateColumn(cliff_columns.FormattableColumn):
29+
def human_readable(self):
30+
return 'UP' if self._value else 'DOWN'
2831

2932

30-
def _format_router_external(item):
31-
return 'External' if item else 'Internal'
33+
class RouterExternalColumn(cliff_columns.FormattableColumn):
34+
def human_readable(self):
35+
return 'External' if self._value else 'Internal'
3236

3337

3438
_formatters = {
35-
'subnets': utils.format_list,
36-
'subnet_ids': utils.format_list,
37-
'admin_state_up': _format_admin_state,
38-
'is_admin_state_up': _format_admin_state,
39-
'router:external': _format_router_external,
40-
'is_router_external': _format_router_external,
41-
'availability_zones': utils.format_list,
42-
'availability_zone_hints': utils.format_list,
43-
'tags': utils.format_list,
39+
'subnets': format_columns.ListColumn,
40+
'subnet_ids': format_columns.ListColumn,
41+
'admin_state_up': AdminStateColumn,
42+
'is_admin_state_up': AdminStateColumn,
43+
'router:external': RouterExternalColumn,
44+
'is_router_external': RouterExternalColumn,
45+
'availability_zones': format_columns.ListColumn,
46+
'availability_zone_hints': format_columns.ListColumn,
47+
'tags': format_columns.ListColumn,
4448
}
4549

4650

openstackclient/network/v2/network_agent.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
import logging
1717

18+
from cliff import columns as cliff_columns
19+
from osc_lib.cli import format_columns
1820
from osc_lib.command import command
1921
from osc_lib import exceptions
2022
from osc_lib import utils
@@ -26,19 +28,22 @@
2628
LOG = logging.getLogger(__name__)
2729

2830

29-
def _format_alive(alive):
30-
return ":-)" if alive else "XXX"
31+
class AliveColumn(cliff_columns.FormattableColumn):
32+
def human_readable(self):
33+
return ":-)" if self._value else "XXX"
3134

3235

33-
def _format_admin_state(state):
34-
return 'UP' if state else 'DOWN'
36+
class AdminStateColumn(cliff_columns.FormattableColumn):
37+
def human_readable(self):
38+
return 'UP' if self._value else 'DOWN'
39+
3540

3641
_formatters = {
37-
'is_alive': _format_alive,
38-
'alive': _format_alive,
39-
'admin_state_up': _format_admin_state,
40-
'is_admin_state_up': _format_admin_state,
41-
'configurations': utils.format_dict,
42+
'is_alive': AliveColumn,
43+
'alive': AliveColumn,
44+
'admin_state_up': AdminStateColumn,
45+
'is_admin_state_up': AdminStateColumn,
46+
'configurations': format_columns.DictColumn,
4247
}
4348

4449

openstackclient/network/v2/port.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import json
1919
import logging
2020

21+
from cliff import columns as cliff_columns
22+
from osc_lib.cli import format_columns
2123
from osc_lib.cli import parseractions
2224
from osc_lib.command import command
2325
from osc_lib import exceptions
@@ -33,23 +35,24 @@
3335
LOG = logging.getLogger(__name__)
3436

3537

36-
def _format_admin_state(state):
37-
return 'UP' if state else 'DOWN'
38+
class AdminStateColumn(cliff_columns.FormattableColumn):
39+
def human_readable(self):
40+
return 'UP' if self._value else 'DOWN'
3841

3942

4043
_formatters = {
41-
'admin_state_up': _format_admin_state,
42-
'is_admin_state_up': _format_admin_state,
43-
'allowed_address_pairs': utils.format_list_of_dicts,
44-
'binding_profile': utils.format_dict,
45-
'binding_vif_details': utils.format_dict,
46-
'binding:profile': utils.format_dict,
47-
'binding:vif_details': utils.format_dict,
48-
'dns_assignment': utils.format_list_of_dicts,
49-
'extra_dhcp_opts': utils.format_list_of_dicts,
50-
'fixed_ips': utils.format_list_of_dicts,
51-
'security_group_ids': utils.format_list,
52-
'tags': utils.format_list,
44+
'admin_state_up': AdminStateColumn,
45+
'is_admin_state_up': AdminStateColumn,
46+
'allowed_address_pairs': format_columns.ListDictColumn,
47+
'binding_profile': format_columns.DictColumn,
48+
'binding_vif_details': format_columns.DictColumn,
49+
'binding:profile': format_columns.DictColumn,
50+
'binding:vif_details': format_columns.DictColumn,
51+
'dns_assignment': format_columns.ListDictColumn,
52+
'extra_dhcp_opts': format_columns.ListDictColumn,
53+
'fixed_ips': format_columns.ListDictColumn,
54+
'security_group_ids': format_columns.ListColumn,
55+
'tags': format_columns.ListColumn,
5356
}
5457

5558

openstackclient/network/v2/router.py

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import json
1919
import logging
2020

21+
from cliff import columns as cliff_columns
22+
from osc_lib.cli import format_columns
2123
from osc_lib.cli import parseractions
2224
from osc_lib.command import command
2325
from osc_lib import exceptions
@@ -32,33 +34,36 @@
3234
LOG = logging.getLogger(__name__)
3335

3436

35-
def _format_admin_state(state):
36-
return 'UP' if state else 'DOWN'
37+
class AdminStateColumn(cliff_columns.FormattableColumn):
38+
def human_readable(self):
39+
return 'UP' if self._value else 'DOWN'
3740

3841

39-
def _format_router_info(info):
40-
try:
41-
return json.dumps(info)
42-
except (TypeError, KeyError):
43-
return ''
42+
class RouterInfoColumn(cliff_columns.FormattableColumn):
43+
def human_readable(self):
44+
try:
45+
return json.dumps(self._value)
46+
except (TypeError, KeyError):
47+
return ''
4448

4549

46-
def _format_routes(routes):
47-
# Map the route keys to match --route option.
48-
for route in routes:
49-
if 'nexthop' in route:
50-
route['gateway'] = route.pop('nexthop')
51-
return utils.format_list_of_dicts(routes)
50+
class RoutesColumn(cliff_columns.FormattableColumn):
51+
def human_readable(self):
52+
# Map the route keys to match --route option.
53+
for route in self._value:
54+
if 'nexthop' in route:
55+
route['gateway'] = route.pop('nexthop')
56+
return utils.format_list_of_dicts(self._value)
5257

5358

5459
_formatters = {
55-
'admin_state_up': _format_admin_state,
56-
'is_admin_state_up': _format_admin_state,
57-
'external_gateway_info': _format_router_info,
58-
'availability_zones': utils.format_list,
59-
'availability_zone_hints': utils.format_list,
60-
'routes': _format_routes,
61-
'tags': utils.format_list,
60+
'admin_state_up': AdminStateColumn,
61+
'is_admin_state_up': AdminStateColumn,
62+
'external_gateway_info': RouterInfoColumn,
63+
'availability_zones': format_columns.ListColumn,
64+
'availability_zone_hints': format_columns.ListColumn,
65+
'routes': RoutesColumn,
66+
'tags': format_columns.ListColumn,
6267
}
6368

6469

@@ -720,7 +725,7 @@ def take_action(self, parsed_args):
720725

721726
setattr(obj, 'interfaces_info', interfaces_info)
722727
display_columns, columns = _get_columns(obj)
723-
_formatters['interfaces_info'] = _format_router_info
728+
_formatters['interfaces_info'] = RouterInfoColumn
724729
data = utils.get_item_properties(obj, columns, formatters=_formatters)
725730

726731
return (display_columns, data)

openstackclient/network/v2/security_group.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import argparse
1717

18+
from cliff import columns as cliff_columns
1819
from osc_lib.command import command
1920
from osc_lib import utils
2021
import six
@@ -65,13 +66,23 @@ def _format_compute_security_group_rules(sg_rules):
6566
return utils.format_list(rules, separator='\n')
6667

6768

69+
class NetworkSecurityGroupRulesColumn(cliff_columns.FormattableColumn):
70+
def human_readable(self):
71+
return _format_network_security_group_rules(self._value)
72+
73+
74+
class ComputeSecurityGroupRulesColumn(cliff_columns.FormattableColumn):
75+
def human_readable(self):
76+
return _format_compute_security_group_rules(self._value)
77+
78+
6879
_formatters_network = {
69-
'security_group_rules': _format_network_security_group_rules,
80+
'security_group_rules': NetworkSecurityGroupRulesColumn,
7081
}
7182

7283

7384
_formatters_compute = {
74-
'rules': _format_compute_security_group_rules,
85+
'rules': ComputeSecurityGroupRulesColumn,
7586
}
7687

7788

openstackclient/network/v2/subnet.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import copy
1717
import logging
1818

19+
from cliff import columns as cliff_columns
20+
from osc_lib.cli import format_columns
1921
from osc_lib.cli import parseractions
2022
from osc_lib.command import command
2123
from osc_lib import exceptions
@@ -40,23 +42,27 @@ def _update_arguments(obj_list, parsed_args_list, option):
4042
raise exceptions.CommandError(msg)
4143

4244

43-
def _format_allocation_pools(data):
44-
pool_formatted = ['%s-%s' % (pool.get('start', ''), pool.get('end', ''))
45-
for pool in data]
46-
return ','.join(pool_formatted)
45+
class AllocationPoolsColumn(cliff_columns.FormattableColumn):
46+
def human_readable(self):
47+
pool_formatted = ['%s-%s' % (pool.get('start', ''),
48+
pool.get('end', ''))
49+
for pool in self._value]
50+
return ','.join(pool_formatted)
4751

4852

49-
def _format_host_routes(data):
50-
# Map the host route keys to match --host-route option.
51-
return utils.format_list_of_dicts(convert_entries_to_gateway(data))
53+
class HostRoutesColumn(cliff_columns.FormattableColumn):
54+
def human_readable(self):
55+
# Map the host route keys to match --host-route option.
56+
return utils.format_list_of_dicts(
57+
convert_entries_to_gateway(self._value))
5258

5359

5460
_formatters = {
55-
'allocation_pools': _format_allocation_pools,
56-
'dns_nameservers': utils.format_list,
57-
'host_routes': _format_host_routes,
58-
'service_types': utils.format_list,
59-
'tags': utils.format_list,
61+
'allocation_pools': AllocationPoolsColumn,
62+
'dns_nameservers': format_columns.ListColumn,
63+
'host_routes': HostRoutesColumn,
64+
'service_types': format_columns.ListColumn,
65+
'tags': format_columns.ListColumn,
6066
}
6167

6268

openstackclient/network/v2/subnet_pool.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import logging
1717

18+
from osc_lib.cli import format_columns
1819
from osc_lib.cli import parseractions
1920
from osc_lib.command import command
2021
from osc_lib import exceptions
@@ -41,8 +42,8 @@ def _get_columns(item):
4142

4243

4344
_formatters = {
44-
'prefixes': utils.format_list,
45-
'tags': utils.format_list,
45+
'prefixes': format_columns.ListColumn,
46+
'tags': format_columns.ListColumn,
4647
}
4748

4849

openstackclient/tests/functional/network/v2/common.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,13 @@ def test_tag_operation(self):
6262
self._set_resource_and_tag_check('unset', name1, '--all-tag', [])
6363
self._set_resource_and_tag_check('set', name2, '--no-tag', [])
6464

65-
def _assertTagsEqual(self, expected, actual):
66-
# TODO(amotoki): Should migrate to cliff format columns.
67-
# At now, unit test assert method needs to be replaced
68-
# to handle format columns, so format_list() is used.
69-
# NOTE: The order of tag is undeterminestic.
70-
actual_tags = filter(bool, actual.split(', '))
71-
self.assertEqual(set(expected), set(actual_tags))
72-
7365
def _list_tag_check(self, project_id, expected):
7466
cmd_output = json.loads(self.openstack(
7567
'{} list --long --project {} -f json'.format(self.base_command,
7668
project_id)))
7769
for name, tags in expected:
7870
net = [n for n in cmd_output if n['Name'] == name][0]
79-
self._assertTagsEqual(tags, net['Tags'])
71+
self.assertEqual(set(tags), set(net['Tags']))
8072

8173
def _create_resource_for_tag_test(self, name, args):
8274
return json.loads(self.openstack(
@@ -89,7 +81,7 @@ def _create_resource_and_tag_check(self, args, expected):
8981
self.addCleanup(
9082
self.openstack, '{} delete {}'.format(self.base_command, name))
9183
self.assertIsNotNone(cmd_output["id"])
92-
self._assertTagsEqual(expected, cmd_output['tags'])
84+
self.assertEqual(set(expected), set(cmd_output['tags']))
9385
return name
9486

9587
def _set_resource_and_tag_check(self, command, name, args, expected):
@@ -100,4 +92,4 @@ def _set_resource_and_tag_check(self, command, name, args, expected):
10092
cmd_output = json.loads(self.openstack(
10193
'{} show -f json {}'.format(self.base_command, name)
10294
))
103-
self._assertTagsEqual(expected, cmd_output['tags'])
95+
self.assertEqual(set(expected), set(cmd_output['tags']))

0 commit comments

Comments
 (0)