Display security group name in security-group-rule-list
It is useful to display security group name rather than its id for security_group_id and source_group_id. Also add '--no-nameconv' option to disable conversion from security group id to its name. When security-group-rule-list is executed by admin user it is likely more than one groups have same name. This option is useful for such cases. Change-Id: I7fd0f1fb26fce8ed24e0f710666866607e681bc8
This commit is contained in:
		@@ -79,6 +79,55 @@ class ListSecurityGroupRule(quantumv20.ListCommand):
 | 
			
		||||
    _formatters = {}
 | 
			
		||||
    list_columns = ['id', 'security_group_id', 'direction', 'protocol',
 | 
			
		||||
                    'source_ip_prefix', 'source_group_id']
 | 
			
		||||
    replace_rules = {'security_group_id': 'security_group',
 | 
			
		||||
                     'source_group_id': 'source_group'}
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super(ListSecurityGroupRule, self).get_parser(prog_name)
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            '--no-nameconv', action='store_true',
 | 
			
		||||
            help='Do not convert security group ID to its name')
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def replace_columns(cols, rules, reverse=False):
 | 
			
		||||
        if reverse:
 | 
			
		||||
            rules = dict((rules[k], k) for k in rules.keys())
 | 
			
		||||
        return [rules.get(col, col) for col in cols]
 | 
			
		||||
 | 
			
		||||
    def retrieve_list(self, parsed_args):
 | 
			
		||||
        parsed_args.fields = self.replace_columns(parsed_args.fields,
 | 
			
		||||
                                                  self.replace_rules,
 | 
			
		||||
                                                  reverse=True)
 | 
			
		||||
        return super(ListSecurityGroupRule, self).retrieve_list(parsed_args)
 | 
			
		||||
 | 
			
		||||
    def extend_list(self, data, parsed_args):
 | 
			
		||||
        if parsed_args.no_nameconv:
 | 
			
		||||
            return
 | 
			
		||||
        quantum_client = self.get_client()
 | 
			
		||||
        search_opts = {'fields': ['id', 'name']}
 | 
			
		||||
        secgroups = quantum_client.list_security_groups(**search_opts)
 | 
			
		||||
        secgroups = secgroups.get('security_groups', [])
 | 
			
		||||
        sg_dict = dict([(sg['id'], sg['name'])
 | 
			
		||||
                        for sg in secgroups if sg['name']])
 | 
			
		||||
        for rule in data:
 | 
			
		||||
            for key in self.replace_rules:
 | 
			
		||||
                rule[key] = sg_dict.get(rule[key], rule[key])
 | 
			
		||||
 | 
			
		||||
    def setup_columns(self, info, parsed_args):
 | 
			
		||||
        parsed_args.columns = self.replace_columns(parsed_args.columns,
 | 
			
		||||
                                                   self.replace_rules,
 | 
			
		||||
                                                   reverse=True)
 | 
			
		||||
        # NOTE(amotoki): 2nd element of the tuple returned by setup_columns()
 | 
			
		||||
        # is a generator, so if you need to create a look using the generator
 | 
			
		||||
        # object, you need to recreate a generator to show a list expectedly.
 | 
			
		||||
        info = super(ListSecurityGroupRule, self).setup_columns(info,
 | 
			
		||||
                                                                parsed_args)
 | 
			
		||||
        cols = info[0]
 | 
			
		||||
        if not parsed_args.no_nameconv:
 | 
			
		||||
            cols = self.replace_columns(info[0], self.replace_rules)
 | 
			
		||||
            parsed_args.columns = cols
 | 
			
		||||
        return (cols, info[1])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShowSecurityGroupRule(quantumv20.ShowCommand):
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,8 @@
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
import mox
 | 
			
		||||
 | 
			
		||||
from quantumclient.quantum.v2_0 import securitygroup
 | 
			
		||||
from quantumclient.tests.unit import test_cli20
 | 
			
		||||
 | 
			
		||||
@@ -137,6 +139,10 @@ class CLITestV20SecurityGroups(test_cli20.CLITestV20Base):
 | 
			
		||||
        resources = "security_group_rules"
 | 
			
		||||
        cmd = securitygroup.ListSecurityGroupRule(
 | 
			
		||||
            test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self.mox.StubOutWithMock(securitygroup.ListSecurityGroupRule,
 | 
			
		||||
                                 "extend_list")
 | 
			
		||||
        securitygroup.ListSecurityGroupRule.extend_list(mox.IsA(list),
 | 
			
		||||
                                                        mox.IgnoreArg())
 | 
			
		||||
        self._test_list_resources(resources, cmd, True)
 | 
			
		||||
 | 
			
		||||
    def test_show_security_group_rule(self):
 | 
			
		||||
@@ -146,3 +152,97 @@ class CLITestV20SecurityGroups(test_cli20.CLITestV20Base):
 | 
			
		||||
        args = ['--fields', 'id', self.test_id]
 | 
			
		||||
        self._test_show_resource(resource, cmd, self.test_id,
 | 
			
		||||
                                 args, ['id'])
 | 
			
		||||
 | 
			
		||||
    def _test_list_security_group_rules_extend(self, data=None, expected=None,
 | 
			
		||||
                                               args=[], conv=True,
 | 
			
		||||
                                               query_field=False):
 | 
			
		||||
        def setup_list_stub(resources, data, query):
 | 
			
		||||
            reses = {resources: data}
 | 
			
		||||
            resstr = self.client.serialize(reses)
 | 
			
		||||
            resp = (test_cli20.MyResp(200), resstr)
 | 
			
		||||
            path = getattr(self.client, resources + '_path')
 | 
			
		||||
            self.client.httpclient.request(
 | 
			
		||||
                test_cli20.end_url(path, query), 'GET',
 | 
			
		||||
                body=None,
 | 
			
		||||
                headers=mox.ContainsKeyValue(
 | 
			
		||||
                    'X-Auth-Token', test_cli20.TOKEN)).AndReturn(resp)
 | 
			
		||||
 | 
			
		||||
        # Setup the default data
 | 
			
		||||
        _data = {'cols': ['id', 'security_group_id', 'source_group_id'],
 | 
			
		||||
                 'data': [('ruleid1', 'myid1', 'myid1'),
 | 
			
		||||
                          ('ruleid2', 'myid2', 'myid3'),
 | 
			
		||||
                          ('ruleid3', 'myid2', 'myid2')]}
 | 
			
		||||
        _expected = {'cols': ['id', 'security_group', 'source_group'],
 | 
			
		||||
                     'data': [('ruleid1', 'group1', 'group1'),
 | 
			
		||||
                              ('ruleid2', 'group2', 'group3'),
 | 
			
		||||
                              ('ruleid3', 'group2', 'group2')]}
 | 
			
		||||
        if data is None:
 | 
			
		||||
            data = _data
 | 
			
		||||
        list_data = [dict(zip(data['cols'], d)) for d in data['data']]
 | 
			
		||||
        if expected is None:
 | 
			
		||||
            expected = {}
 | 
			
		||||
        expected['cols'] = expected.get('cols', _expected['cols'])
 | 
			
		||||
        expected['data'] = expected.get('data', _expected['data'])
 | 
			
		||||
 | 
			
		||||
        resources = "security_group_rules"
 | 
			
		||||
        cmd = securitygroup.ListSecurityGroupRule(
 | 
			
		||||
            test_cli20.MyApp(sys.stdout), None)
 | 
			
		||||
        self.mox.StubOutWithMock(cmd, 'get_client')
 | 
			
		||||
        self.mox.StubOutWithMock(self.client.httpclient, 'request')
 | 
			
		||||
        cmd.get_client().AndReturn(self.client)
 | 
			
		||||
        query = ''
 | 
			
		||||
        if query_field:
 | 
			
		||||
            query = '&'.join(['fields=' + f for f in data['cols']])
 | 
			
		||||
        setup_list_stub('security_group_rules', list_data, query)
 | 
			
		||||
        if conv:
 | 
			
		||||
            cmd.get_client().AndReturn(self.client)
 | 
			
		||||
            setup_list_stub('security_groups',
 | 
			
		||||
                            [{'id': 'myid1', 'name': 'group1'},
 | 
			
		||||
                             {'id': 'myid2', 'name': 'group2'},
 | 
			
		||||
                             {'id': 'myid3', 'name': 'group3'}],
 | 
			
		||||
                            query='fields=id&fields=name')
 | 
			
		||||
        self.mox.ReplayAll()
 | 
			
		||||
 | 
			
		||||
        cmd_parser = cmd.get_parser('list_security_group_rules')
 | 
			
		||||
        parsed_args = cmd_parser.parse_args(args)
 | 
			
		||||
        result = cmd.get_data(parsed_args)
 | 
			
		||||
        self.mox.VerifyAll()
 | 
			
		||||
        self.mox.UnsetStubs()
 | 
			
		||||
        # Check columns
 | 
			
		||||
        self.assertEqual(result[0], expected['cols'])
 | 
			
		||||
        # Check data
 | 
			
		||||
        _result = [x for x in result[1]]
 | 
			
		||||
        self.assertEqual(len(_result), len(expected['data']))
 | 
			
		||||
        for res, exp in zip(_result, expected['data']):
 | 
			
		||||
            self.assertEqual(len(res), len(exp))
 | 
			
		||||
            self.assertEqual(res, exp)
 | 
			
		||||
 | 
			
		||||
    def test_list_security_group_rules_extend_source_id(self):
 | 
			
		||||
        self._test_list_security_group_rules_extend()
 | 
			
		||||
 | 
			
		||||
    def test_list_security_group_rules_extend_no_nameconv(self):
 | 
			
		||||
        expected = {'cols': ['id', 'security_group_id', 'source_group_id'],
 | 
			
		||||
                    'data': [('ruleid1', 'myid1', 'myid1'),
 | 
			
		||||
                             ('ruleid2', 'myid2', 'myid3'),
 | 
			
		||||
                             ('ruleid3', 'myid2', 'myid2')]}
 | 
			
		||||
        args = ['--no-nameconv']
 | 
			
		||||
        self._test_list_security_group_rules_extend(expected=expected,
 | 
			
		||||
                                                    args=args, conv=False)
 | 
			
		||||
 | 
			
		||||
    def test_list_security_group_rules_extend_with_columns(self):
 | 
			
		||||
        args = '-c id -c security_group_id -c source_group_id'.split()
 | 
			
		||||
        self._test_list_security_group_rules_extend(args=args)
 | 
			
		||||
 | 
			
		||||
    def test_list_security_group_rules_extend_with_columns_no_id(self):
 | 
			
		||||
        args = '-c id -c security_group -c source_group'.split()
 | 
			
		||||
        self._test_list_security_group_rules_extend(args=args)
 | 
			
		||||
 | 
			
		||||
    def test_list_security_group_rules_extend_with_fields(self):
 | 
			
		||||
        args = '-F id -F security_group_id -F source_group_id'.split()
 | 
			
		||||
        self._test_list_security_group_rules_extend(args=args,
 | 
			
		||||
                                                    query_field=True)
 | 
			
		||||
 | 
			
		||||
    def test_list_security_group_rules_extend_with_fields_no_id(self):
 | 
			
		||||
        args = '-F id -F security_group -F source_group'.split()
 | 
			
		||||
        self._test_list_security_group_rules_extend(args=args,
 | 
			
		||||
                                                    query_field=True)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user