Add '--project' and '--project-domain' options to os cmds

This patch added '--project' and '--project-domain' options to
filter subnets resulted by 'os subnet list',
'os floating ip create' and 'os security group list' commands.

Co-Authored-By: Ha Van Tu <tuhv@vn.fujitsu.com>
Change-Id: I727663d49ffa6aa042fdeb60797f18bb753b0372
Closes-Bug: #1613231
Closes-Bug: #1610909
Closes-Bug: #1613629
Partially-Implements: blueprint network-commands-options
This commit is contained in:
Nam Nguyen Hoai 2016-08-16 16:00:32 +07:00 committed by Ha Van Tu
parent d6e058fa1f
commit ce079d2261
10 changed files with 222 additions and 2 deletions

View File

@ -18,6 +18,7 @@ Create floating IP
[--floating-ip-address <floating-ip-address>] [--floating-ip-address <floating-ip-address>]
[--fixed-ip-address <fixed-ip-address>] [--fixed-ip-address <fixed-ip-address>]
[--description <description>] [--description <description>]
[--project <project> [--project-domain <project-domain>]]
<network> <network>
.. option:: --subnet <subnet> .. option:: --subnet <subnet>
@ -45,6 +46,19 @@ Create floating IP
Set floating IP description Set floating IP description
*Network version 2 only* *Network version 2 only*
.. option:: --project <project>
Owner's project (name or ID)
*Network version 2 only*
.. option:: --project-domain <project-domain>
Domain the project belongs to (name or ID).
This can be used in case collisions between project names exist.
*Network version 2 only*
.. describe:: <network> .. describe:: <network>
Network to allocate floating IP from (name or ID) Network to allocate floating IP from (name or ID)

View File

@ -137,6 +137,7 @@ List routers
[--name <name>] [--name <name>]
[--enable | --disable] [--enable | --disable]
[--long] [--long]
[--project <project> [--project-domain <project-domain>]]
.. option:: --long .. option:: --long
@ -154,6 +155,15 @@ List routers
List disabled routers List disabled routers
.. option:: --project <project>
List routers according to their project (name or ID)
.. option:: --project-domain <project-domain>
Domain the project belongs to (name or ID).
This can be used in case collisions between project names exist.
router remove port router remove port
------------------ ------------------

View File

@ -67,6 +67,7 @@ List security groups
os security group list os security group list
[--all-projects] [--all-projects]
[--project <project> [--project-domain <project-domain>]]
.. option:: --all-projects .. option:: --all-projects
@ -75,6 +76,19 @@ List security groups
*Network version 2 ignores this option and will always display information* *Network version 2 ignores this option and will always display information*
*for all projects (admin only).* *for all projects (admin only).*
.. option:: --project <project>
List security groups according to the project (name or ID)
*Network version 2 only*
.. option:: --project-domain <project-domain>
Domain the project belongs to (name or ID).
This can be used in case collisions between project names exist.
*Network version 2 only*
security group set security group set
------------------ ------------------

View File

@ -18,6 +18,7 @@ import logging
from osc_lib import utils from osc_lib import utils
from openstackclient.i18n import _ from openstackclient.i18n import _
from openstackclient.identity import common as identity_common
from openstackclient.network import common from openstackclient.network import common
from openstackclient.network import sdk_utils from openstackclient.network import sdk_utils
@ -66,6 +67,15 @@ def _get_attrs(client_manager, parsed_args):
if parsed_args.description is not None: if parsed_args.description is not None:
attrs['description'] = parsed_args.description attrs['description'] = parsed_args.description
if parsed_args.project:
identity_client = client_manager.identity
project_id = identity_common.find_project(
identity_client,
parsed_args.project,
parsed_args.project_domain,
).id
attrs['tenant_id'] = project_id
return attrs return attrs
@ -113,6 +123,12 @@ class CreateFloatingIP(common.NetworkAndComputeShowOne):
metavar='<description>', metavar='<description>',
help=_('Set floating IP description') help=_('Set floating IP description')
) )
parser.add_argument(
'--project',
metavar='<project>',
help=_("Owner's project (name or ID)")
)
identity_common.add_project_domain_option_to_parser(parser)
return parser return parser
def take_action_network(self, client, parsed_args): def take_action_network(self, client, parsed_args):

View File

@ -282,11 +282,17 @@ class ListRouter(command.Lister):
default=False, default=False,
help=_("List additional fields in output") help=_("List additional fields in output")
) )
parser.add_argument(
'--project',
metavar='<project>',
help=_("List routers according to their project (name or ID)")
)
identity_common.add_project_domain_option_to_parser(parser)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
identity_client = self.app.client_manager.identity
client = self.app.client_manager.network client = self.app.client_manager.network
columns = ( columns = (
'id', 'id',
'name', 'name',
@ -316,6 +322,13 @@ class ListRouter(command.Lister):
elif parsed_args.disable: elif parsed_args.disable:
args['admin_state_up'] = False args['admin_state_up'] = False
if parsed_args.project:
project_id = identity_common.find_project(
identity_client,
parsed_args.project,
parsed_args.project_domain,
).id
args['tenant_id'] = project_id
if parsed_args.long: if parsed_args.long:
columns = columns + ( columns = columns + (
'routes', 'routes',

View File

@ -201,6 +201,13 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
default=False, default=False,
help=argparse.SUPPRESS, help=argparse.SUPPRESS,
) )
parser.add_argument(
'--project',
metavar='<project>',
help=_("List security groups according to the project "
"(name or ID)")
)
identity_common.add_project_domain_option_to_parser(parser)
return parser return parser
def update_parser_compute(self, parser): def update_parser_compute(self, parser):
@ -228,7 +235,16 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
) for s in data)) ) for s in data))
def take_action_network(self, client, parsed_args): def take_action_network(self, client, parsed_args):
return self._get_return_data(client.security_groups()) filters = {}
if parsed_args.project:
identity_client = self.app.client_manager.identity
project_id = identity_common.find_project(
identity_client,
parsed_args.project,
parsed_args.project_domain,
).id
filters['tenant_id'] = project_id
return self._get_return_data(client.security_groups(**filters))
def take_action_compute(self, client, parsed_args): def take_action_compute(self, client, parsed_args):
search = {'all_tenants': parsed_args.all_projects} search = {'all_tenants': parsed_args.all_projects}

View File

@ -18,6 +18,7 @@ from osc_lib import exceptions
from openstackclient.network.v2 import floating_ip from openstackclient.network.v2 import floating_ip
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
from openstackclient.tests.unit.network.v2 import fakes as network_fakes from openstackclient.tests.unit.network.v2 import fakes as network_fakes
from openstackclient.tests.unit import utils as tests_utils from openstackclient.tests.unit import utils as tests_utils
@ -31,6 +32,7 @@ class TestFloatingIPNetwork(network_fakes.TestNetworkV2):
# Get a shortcut to the network client # Get a shortcut to the network client
self.network = self.app.client_manager.network self.network = self.app.client_manager.network
self.projects_mock = self.app.client_manager.identity.projects
class TestCreateFloatingIPNetwork(TestFloatingIPNetwork): class TestCreateFloatingIPNetwork(TestFloatingIPNetwork):
@ -145,6 +147,54 @@ class TestCreateFloatingIPNetwork(TestFloatingIPNetwork):
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)
def test_floating_ip_create_project(self):
project = identity_fakes_v3.FakeProject.create_one_project()
self.projects_mock.get.return_value = project
arglist = [
'--project', project.id,
self.floating_ip.floating_network_id,
]
verifylist = [
('network', self.floating_ip.floating_network_id),
('project', project.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_ip.assert_called_once_with(**{
'floating_network_id': self.floating_ip.floating_network_id,
'tenant_id': project.id,
})
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
def test_floating_ip_create_project_domain(self):
project = identity_fakes_v3.FakeProject.create_one_project()
domain = identity_fakes_v3.FakeDomain.create_one_domain()
self.projects_mock.get.return_value = project
arglist = [
"--project", project.name,
"--project-domain", domain.name,
self.floating_ip.floating_network_id,
]
verifylist = [
('network', self.floating_ip.floating_network_id),
('project', project.name),
('project_domain', domain.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_ip.assert_called_once_with(**{
'floating_network_id': self.floating_ip.floating_network_id,
'tenant_id': project.id,
})
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
class TestDeleteFloatingIPNetwork(TestFloatingIPNetwork): class TestDeleteFloatingIPNetwork(TestFloatingIPNetwork):

View File

@ -18,6 +18,7 @@ from osc_lib import exceptions
from osc_lib import utils as osc_utils from osc_lib import utils as osc_utils
from openstackclient.network.v2 import router from openstackclient.network.v2 import router
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
from openstackclient.tests.unit.network.v2 import fakes as network_fakes from openstackclient.tests.unit.network.v2 import fakes as network_fakes
from openstackclient.tests.unit import utils as tests_utils from openstackclient.tests.unit import utils as tests_utils
@ -29,6 +30,7 @@ class TestRouter(network_fakes.TestNetworkV2):
# Get a shortcut to the network client # Get a shortcut to the network client
self.network = self.app.client_manager.network self.network = self.app.client_manager.network
self.projects_mock = self.app.client_manager.identity.projects
class TestAddPortToRouter(TestRouter): class TestAddPortToRouter(TestRouter):
@ -476,6 +478,45 @@ class TestListRouter(TestRouter):
self.network.routers.assert_called_once_with( self.network.routers.assert_called_once_with(
**{'admin_state_up': False} **{'admin_state_up': False}
) )
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_router_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)
filters = {'tenant_id': project.id}
self.network.routers.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_router_list_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),
('project_domain', project.domain_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
filters = {'tenant_id': project.id}
self.network.routers.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))

View File

@ -444,6 +444,44 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data)) self.assertEqual(self.data, list(data))
def test_security_group_list_project(self):
project = identity_fakes.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)
filters = {'tenant_id': project.id}
self.network.security_groups.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_security_group_list_project_domain(self):
project = identity_fakes.FakeProject.create_one_project()
self.projects_mock.get.return_value = project
arglist = [
'--project', project.id,
'--project-domain', project.domain_id,
]
verifylist = [
('project', project.id),
('project_domain', project.domain_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
filters = {'tenant_id': project.id}
self.network.security_groups.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
class TestListSecurityGroupCompute(TestSecurityGroupCompute): class TestListSecurityGroupCompute(TestSecurityGroupCompute):

View File

@ -0,0 +1,8 @@
---
features:
- |
Add ``--project`` and ``--project-domain`` options to the ``router list``,
``floating ip create`` and ``security group list`` commands.
[Bug `1613231 <https://bugs.launchpad.net/bugs/1613231>`_]
[Bug `1613629 <https://bugs.launchpad.net/bugs/1613629>`_]
[Bug `1610909 <https://bugs.launchpad.net/bugs/1610909>`_]