From 94c9cd5c66512d52b31dfaa42bc3d1cc7fd81702 Mon Sep 17 00:00:00 2001 From: Richard Theis Date: Mon, 11 Apr 2016 13:45:12 -0500 Subject: Add options to security group rule list Add the following options to the 'os security group rule list' command: --long: Display direction and ethertype for Network v2 --all-projects: Display information from all projects for Compute v2 Change-Id: If8a1cbd7669cdfa6577d6d2f6fffd9e999a39a82 Partial-Bug: #1519512 Implements: blueprint neutron-client --- openstackclient/network/v2/security_group_rule.py | 46 +++++++++- .../tests/network/v2/test_security_group_rule.py | 99 ++++++++++++++++++---- 2 files changed, 126 insertions(+), 19 deletions(-) (limited to 'openstackclient') diff --git a/openstackclient/network/v2/security_group_rule.py b/openstackclient/network/v2/security_group_rule.py index 67472de0..5b22a0dd 100644 --- a/openstackclient/network/v2/security_group_rule.py +++ b/openstackclient/network/v2/security_group_rule.py @@ -13,6 +13,7 @@ """Security Group Rule action implementations""" +import argparse import six try: @@ -242,14 +243,50 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister): ) return parser + def update_parser_network(self, parser): + # Accept but hide the argument for consistency with compute. + # Network will always return all projects for an admin. + parser.add_argument( + '--all-projects', + action='store_true', + default=False, + help=argparse.SUPPRESS + ) + parser.add_argument( + '--long', + action='store_true', + default=False, + help=_("List additional fields in output") + ) + return parser + + def update_parser_compute(self, parser): + parser.add_argument( + '--all-projects', + action='store_true', + default=False, + help=_("Display information from all projects (admin only)") + ) + # Accept but hide the argument for consistency with network. + # There are no additional fields to display at this time. + parser.add_argument( + '--long', + action='store_false', + default=False, + help=argparse.SUPPRESS + ) + return parser + def _get_column_headers(self, parsed_args): column_headers = ( 'ID', 'IP Protocol', 'IP Range', 'Port Range', - 'Remote Security Group', ) + if parsed_args.long: + column_headers = column_headers + ('Direction', 'Ethertype',) + column_headers = column_headers + ('Remote Security Group',) if parsed_args.group is None: column_headers = column_headers + ('Security Group',) return column_headers @@ -261,8 +298,10 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister): 'protocol', 'remote_ip_prefix', 'port_range_min', - 'remote_group_id', ) + if parsed_args.long: + columns = columns + ('direction', 'ethertype',) + columns = columns + ('remote_group_id',) # Get the security group rules using the requested query. query = {} @@ -309,7 +348,8 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister): rules_to_list = group.rules else: columns = columns + ('parent_group_id',) - for group in client.security_groups.list(): + search = {'all_tenants': parsed_args.all_projects} + for group in client.security_groups.list(search_opts=search): rules_to_list.extend(group.rules) # NOTE(rtheis): Turn the raw rules into resources. diff --git a/openstackclient/tests/network/v2/test_security_group_rule.py b/openstackclient/tests/network/v2/test_security_group_rule.py index c2fa1256..df7414aa 100644 --- a/openstackclient/tests/network/v2/test_security_group_rule.py +++ b/openstackclient/tests/network/v2/test_security_group_rule.py @@ -532,31 +532,46 @@ class TestListSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): _security_group_rules = [_security_group_rule_tcp, _security_group_rule_icmp] - expected_columns_with_group = ( + expected_columns_with_group_and_long = ( 'ID', 'IP Protocol', 'IP Range', 'Port Range', + 'Direction', + 'Ethertype', 'Remote Security Group', ) - expected_columns_no_group = \ - expected_columns_with_group + ('Security Group',) + expected_columns_no_group = ( + 'ID', + 'IP Protocol', + 'IP Range', + 'Port Range', + 'Remote Security Group', + 'Security Group', + ) - expected_data_with_group = [] + expected_data_with_group_and_long = [] expected_data_no_group = [] for _security_group_rule in _security_group_rules: - expected_rule_with_group = ( + expected_data_with_group_and_long.append(( _security_group_rule.id, _security_group_rule.protocol, _security_group_rule.remote_ip_prefix, security_group_rule._format_network_port_range( _security_group_rule), + _security_group_rule.direction, + _security_group_rule.ethertype, _security_group_rule.remote_group_id, - ) - expected_rule_no_group = expected_rule_with_group + \ - (_security_group_rule.security_group_id,) - expected_data_with_group.append(expected_rule_with_group) - expected_data_no_group.append(expected_rule_no_group) + )) + expected_data_no_group.append(( + _security_group_rule.id, + _security_group_rule.protocol, + _security_group_rule.remote_ip_prefix, + security_group_rule._format_network_port_range( + _security_group_rule), + _security_group_rule.remote_group_id, + _security_group_rule.security_group_id, + )) def setUp(self): super(TestListSecurityGroupRuleNetwork, self).setUp() @@ -570,7 +585,7 @@ class TestListSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): self.cmd = security_group_rule.ListSecurityGroupRule( self.app, self.namespace) - def test_list_no_group(self): + def test_list_default(self): self._security_group_rule_tcp.port_range_min = 80 parsed_args = self.check_parser(self.cmd, [], []) @@ -580,12 +595,14 @@ class TestListSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): self.assertEqual(self.expected_columns_no_group, columns) self.assertEqual(self.expected_data_no_group, list(data)) - def test_list_with_group(self): + def test_list_with_group_and_long(self): self._security_group_rule_tcp.port_range_min = 80 arglist = [ + '--long', self._security_group.id, ] verifylist = [ + ('long', True), ('group', self._security_group.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -595,8 +612,24 @@ class TestListSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): self.network.security_group_rules.assert_called_once_with(**{ 'security_group_id': self._security_group.id, }) - self.assertEqual(self.expected_columns_with_group, columns) - self.assertEqual(self.expected_data_with_group, list(data)) + self.assertEqual(self.expected_columns_with_group_and_long, columns) + self.assertEqual(self.expected_data_with_group_and_long, list(data)) + + def test_list_with_ignored_options(self): + self._security_group_rule_tcp.port_range_min = 80 + arglist = [ + '--all-projects', + ] + verifylist = [ + ('all_projects', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.security_group_rules.assert_called_once_with(**{}) + self.assertEqual(self.expected_columns_no_group, columns) + self.assertEqual(self.expected_data_no_group, list(data)) class TestListSecurityGroupRuleCompute(TestSecurityGroupRuleCompute): @@ -665,11 +698,13 @@ class TestListSecurityGroupRuleCompute(TestSecurityGroupRuleCompute): # Get the command object to test self.cmd = security_group_rule.ListSecurityGroupRule(self.app, None) - def test_list_no_group(self): + def test_list_default(self): parsed_args = self.check_parser(self.cmd, [], []) columns, data = self.cmd.take_action(parsed_args) - self.compute.security_groups.list.assert_called_once_with() + self.compute.security_groups.list.assert_called_once_with( + search_opts={'all_tenants': False} + ) self.assertEqual(self.expected_columns_no_group, columns) self.assertEqual(self.expected_data_no_group, list(data)) @@ -689,6 +724,38 @@ class TestListSecurityGroupRuleCompute(TestSecurityGroupRuleCompute): self.assertEqual(self.expected_columns_with_group, columns) self.assertEqual(self.expected_data_with_group, list(data)) + def test_list_all_projects(self): + arglist = [ + '--all-projects', + ] + verifylist = [ + ('all_projects', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.compute.security_groups.list.assert_called_once_with( + search_opts={'all_tenants': True} + ) + self.assertEqual(self.expected_columns_no_group, columns) + self.assertEqual(self.expected_data_no_group, list(data)) + + def test_list_with_ignored_options(self): + arglist = [ + '--long', + ] + verifylist = [ + ('long', False), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.compute.security_groups.list.assert_called_once_with( + search_opts={'all_tenants': False} + ) + self.assertEqual(self.expected_columns_no_group, columns) + self.assertEqual(self.expected_data_no_group, list(data)) + class TestShowSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): -- cgit v1.2.1