diff --git a/doc/source/command-objects/address-scope.rst b/doc/source/command-objects/address-scope.rst index 7481ed53de..f7572d97da 100644 --- a/doc/source/command-objects/address-scope.rst +++ b/doc/source/command-objects/address-scope.rst @@ -72,6 +72,35 @@ List address scopes .. code:: bash os address scope list + [--name ] + [--ip-version ] + [--project [--project-domain ]] + [--share | --no-share] + +.. option:: --name + + List only address scopes of given name in output + +.. option:: --ip-version + + List address scopes of given IP version networks (4 or 6) + +.. option:: --project + + List address scopes according to their project (name or ID) + +.. option:: --project-domain + + Domain the project belongs to (name or ID). + This can be used in case collisions between project names exist. + +.. option:: --share + + List address scopes shared between projects + +.. option:: --no-share + + List address scopes not shared between projects address scope set ----------------- diff --git a/openstackclient/network/v2/address_scope.py b/openstackclient/network/v2/address_scope.py index 0d8f80d025..9f77aed685 100644 --- a/openstackclient/network/v2/address_scope.py +++ b/openstackclient/network/v2/address_scope.py @@ -140,9 +140,48 @@ class DeleteAddressScope(command.Command): raise exceptions.CommandError(msg) +# TODO(yanxing'an): Use the SDK resource mapped attribute names once the +# OSC minimum requirements include SDK 1.0. class ListAddressScope(command.Lister): _description = _("List address scopes") + def get_parser(self, prog_name): + parser = super(ListAddressScope, self).get_parser(prog_name) + + parser.add_argument( + '--name', + metavar='', + help=_("List only address scopes of given name in output") + ) + parser.add_argument( + '--ip-version', + type=int, + choices=[4, 6], + metavar='', + dest='ip_version', + help=_("List address scopes of given IP version networks (4 or 6)") + ) + parser.add_argument( + '--project', + metavar="", + help=_("List address scopes according to their project " + "(name or ID)") + ) + identity_common.add_project_domain_option_to_parser(parser) + + shared_group = parser.add_mutually_exclusive_group() + shared_group.add_argument( + '--share', + action='store_true', + help=_("List address scopes shared between projects") + ) + shared_group.add_argument( + '--no-share', + action='store_true', + help=_("List address scopes not shared between projects") + ) + return parser + def take_action(self, parsed_args): client = self.app.client_manager.network columns = ( @@ -159,7 +198,27 @@ class ListAddressScope(command.Lister): 'Shared', 'Project', ) - data = client.address_scopes() + attrs = {} + if parsed_args.name: + attrs['name'] = parsed_args.name + if parsed_args.ip_version: + attrs['ip_version'] = parsed_args.ip_version + if parsed_args.share: + attrs['shared'] = True + attrs['is_shared'] = True + if parsed_args.no_share: + attrs['shared'] = False + attrs['is_shared'] = False + if 'project' in parsed_args and parsed_args.project is not None: + identity_client = self.app.client_manager.identity + project_id = identity_common.find_project( + identity_client, + parsed_args.project, + parsed_args.project_domain, + ).id + attrs['tenant_id'] = project_id + attrs['project_id'] = project_id + data = client.address_scopes(**attrs) return (column_headers, (utils.get_item_properties( diff --git a/openstackclient/tests/unit/network/v2/test_address_scope.py b/openstackclient/tests/unit/network/v2/test_address_scope.py index 12c3f1d638..516b879589 100644 --- a/openstackclient/tests/unit/network/v2/test_address_scope.py +++ b/openstackclient/tests/unit/network/v2/test_address_scope.py @@ -275,6 +275,104 @@ class TestListAddressScope(TestAddressScope): self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) + def test_address_scope_list_name(self): + arglist = [ + '--name', self.address_scopes[0].name, + ] + verifylist = [ + ('name', self.address_scopes[0].name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.address_scopes.assert_called_once_with( + **{'name': self.address_scopes[0].name}) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_address_scope_list_ip_version(self): + arglist = [ + '--ip-version', str(4), + ] + verifylist = [ + ('ip_version', 4), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.address_scopes.assert_called_once_with( + **{'ip_version': 4}) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_address_scope_list_project(self): + project = identity_fakes_v3.FakeProject.create_one_project() + self.projects_mock.get.return_value = project + arglist = [ + '--project', project.id, + ] + verifylist = [ + ('project', project.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.address_scopes.assert_called_once_with( + **{'tenant_id': project.id, 'project_id': project.id}) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_address_scope_project_domain(self): + project = identity_fakes_v3.FakeProject.create_one_project() + self.projects_mock.get.return_value = project + arglist = [ + '--project', project.id, + '--project-domain', project.domain_id, + ] + verifylist = [ + ('project', project.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + filters = {'tenant_id': project.id, 'project_id': project.id} + + self.network.address_scopes.assert_called_once_with(**filters) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_address_scope_list_share(self): + arglist = [ + '--share', + ] + verifylist = [ + ('share', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.address_scopes.assert_called_once_with( + **{'shared': True, 'is_shared': True} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_address_scope_list_no_share(self): + arglist = [ + '--no-share', + ] + verifylist = [ + ('no_share', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.address_scopes.assert_called_once_with( + **{'shared': False, 'is_shared': False} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + class TestSetAddressScope(TestAddressScope): diff --git a/releasenotes/notes/bug-1636046-98dc0e69a4e44850.yaml b/releasenotes/notes/bug-1636046-98dc0e69a4e44850.yaml new file mode 100644 index 0000000000..7b6c7d833c --- /dev/null +++ b/releasenotes/notes/bug-1636046-98dc0e69a4e44850.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Add ``--name``, ``--ip-version``, ``--project``, ``--project-domain``, + ``--share``, ``--no-share`` options to the ``address scope list`` command. + [Bug `1636046 `_]