Skip to content

Commit 6d2412b

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Add filtering options to os subnet list command"
2 parents e1cdba4 + d44782b commit 6d2412b

4 files changed

Lines changed: 198 additions & 2 deletions

File tree

doc/source/command-objects/subnet.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ List subnets
161161
[--long]
162162
[--ip-version {4,6}]
163163
[--dhcp | --no-dhcp]
164+
[--project <project> [--project-domain <project-domain>]]
165+
[--network <network>]
166+
[--gateway <gateway>]
167+
[--name <name>]
168+
[--subnet-range <subnet-range>]
164169
165170
.. option:: --long
166171
@@ -186,6 +191,32 @@ List subnets
186191
Must be a valid device owner value for a network port
187192
(repeat option to list multiple service types)
188193
194+
.. option:: --project <project>
195+
196+
List only subnets which belong to a given project (name or ID) in output
197+
198+
.. option:: --project-domain <project-domain>
199+
200+
Domain the project belongs to (name or ID).
201+
This can be used in case collisions between project names exist.
202+
203+
.. option:: --network <network>
204+
205+
List only subnets which belong to a given network (name or ID) in output
206+
207+
.. option:: --gateway <gateway>
208+
209+
List only subnets of given gateway IP in output
210+
211+
.. option:: --name <name>
212+
213+
List only subnets of given name in output
214+
215+
.. option:: --subnet-range <subnet-range>
216+
217+
List only subnets of given subnet range (in CIDR notation) in output
218+
e.g.: ``--subnet-range 10.10.0.0/16``
219+
189220
subnet set
190221
----------
191222

openstackclient/network/v2/subnet.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,41 @@ def get_parser(self, prog_name):
381381
"Must be a valid device owner value for a network port "
382382
"(repeat option to list multiple service types)")
383383
)
384+
parser.add_argument(
385+
'--project',
386+
metavar='<project>',
387+
help=_("List only subnets which belong to a given project "
388+
"(name or ID) in output")
389+
)
390+
identity_common.add_project_domain_option_to_parser(parser)
391+
parser.add_argument(
392+
'--network',
393+
metavar='<network>',
394+
help=_("List only subnets which belong to a given network "
395+
"(name or ID) in output")
396+
)
397+
parser.add_argument(
398+
'--gateway',
399+
metavar='<gateway>',
400+
help=_("List only subnets of given gateway IP in output")
401+
)
402+
parser.add_argument(
403+
'--name',
404+
metavar='<name>',
405+
help=_("List only subnets of given name in output")
406+
)
407+
parser.add_argument(
408+
'--subnet-range',
409+
metavar='<subnet-range>',
410+
help=_("List only subnets of given subnet range "
411+
"(in CIDR notation) in output "
412+
"e.g.: --subnet-range 10.10.0.0/16")
413+
)
384414
return parser
385415

386416
def take_action(self, parsed_args):
417+
identity_client = self.app.client_manager.identity
418+
network_client = self.app.client_manager.network
387419
filters = {}
388420
if parsed_args.ip_version:
389421
filters['ip_version'] = parsed_args.ip_version
@@ -393,7 +425,24 @@ def take_action(self, parsed_args):
393425
filters['enable_dhcp'] = False
394426
if parsed_args.service_types:
395427
filters['service_types'] = parsed_args.service_types
396-
data = self.app.client_manager.network.subnets(**filters)
428+
if parsed_args.project:
429+
project_id = identity_common.find_project(
430+
identity_client,
431+
parsed_args.project,
432+
parsed_args.project_domain,
433+
).id
434+
filters['tenant_id'] = project_id
435+
if parsed_args.network:
436+
network_id = network_client.find_network(parsed_args.network,
437+
ignore_missing=False).id
438+
filters['network_id'] = network_id
439+
if parsed_args.gateway:
440+
filters['gateway_ip'] = parsed_args.gateway
441+
if parsed_args.name:
442+
filters['name'] = parsed_args.name
443+
if parsed_args.subnet_range:
444+
filters['cidr'] = parsed_args.subnet_range
445+
data = network_client.subnets(**filters)
397446

398447
headers = ('ID', 'Name', 'Network', 'Subnet')
399448
columns = ('id', 'name', 'network_id', 'cidr')

openstackclient/tests/unit/network/v2/test_subnet.py

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,14 +646,31 @@ def test_subnet_list_service_type(self):
646646
('service_types', ['network:router_gateway']),
647647
]
648648
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
649-
650649
columns, data = self.cmd.take_action(parsed_args)
651650
filters = {'service_types': ['network:router_gateway']}
652651

653652
self.network.subnets.assert_called_once_with(**filters)
654653
self.assertEqual(self.columns, columns)
655654
self.assertEqual(self.data, list(data))
656655

656+
def test_subnet_list_project(self):
657+
project = identity_fakes_v3.FakeProject.create_one_project()
658+
self.projects_mock.get.return_value = project
659+
arglist = [
660+
'--project', project.id,
661+
]
662+
verifylist = [
663+
('project', project.id),
664+
]
665+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
666+
667+
columns, data = self.cmd.take_action(parsed_args)
668+
filters = {'tenant_id': project.id}
669+
670+
self.network.subnets.assert_called_once_with(**filters)
671+
self.assertEqual(self.columns, columns)
672+
self.assertEqual(self.data, list(data))
673+
657674
def test_subnet_list_service_type_multiple(self):
658675
arglist = [
659676
'--service-type', 'network:router_gateway',
@@ -668,6 +685,97 @@ def test_subnet_list_service_type_multiple(self):
668685
columns, data = self.cmd.take_action(parsed_args)
669686
filters = {'service_types': ['network:router_gateway',
670687
'network:floatingip_agent_gateway']}
688+
self.network.subnets.assert_called_once_with(**filters)
689+
self.assertEqual(self.columns, columns)
690+
self.assertEqual(self.data, list(data))
691+
692+
def test_subnet_list_project_domain(self):
693+
project = identity_fakes_v3.FakeProject.create_one_project()
694+
self.projects_mock.get.return_value = project
695+
arglist = [
696+
'--project', project.id,
697+
'--project-domain', project.domain_id,
698+
]
699+
verifylist = [
700+
('project', project.id),
701+
('project_domain', project.domain_id),
702+
]
703+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
704+
705+
columns, data = self.cmd.take_action(parsed_args)
706+
filters = {'tenant_id': project.id}
707+
708+
self.network.subnets.assert_called_once_with(**filters)
709+
self.assertEqual(self.columns, columns)
710+
self.assertEqual(self.data, list(data))
711+
712+
def test_subnet_list_network(self):
713+
network = network_fakes.FakeNetwork.create_one_network()
714+
self.network.find_network = mock.Mock(return_value=network)
715+
arglist = [
716+
'--network', network.id,
717+
]
718+
verifylist = [
719+
('network', network.id),
720+
]
721+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
722+
723+
columns, data = self.cmd.take_action(parsed_args)
724+
filters = {'network_id': network.id}
725+
726+
self.network.subnets.assert_called_once_with(**filters)
727+
self.assertEqual(self.columns, columns)
728+
self.assertEqual(self.data, list(data))
729+
730+
def test_subnet_list_gateway(self):
731+
subnet = network_fakes.FakeSubnet.create_one_subnet()
732+
self.network.find_network = mock.Mock(return_value=subnet)
733+
arglist = [
734+
'--gateway', subnet.gateway_ip,
735+
]
736+
verifylist = [
737+
('gateway', subnet.gateway_ip),
738+
]
739+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
740+
741+
columns, data = self.cmd.take_action(parsed_args)
742+
filters = {'gateway_ip': subnet.gateway_ip}
743+
744+
self.network.subnets.assert_called_once_with(**filters)
745+
self.assertEqual(self.columns, columns)
746+
self.assertEqual(self.data, list(data))
747+
748+
def test_subnet_list_name(self):
749+
subnet = network_fakes.FakeSubnet.create_one_subnet()
750+
self.network.find_network = mock.Mock(return_value=subnet)
751+
arglist = [
752+
'--name', subnet.name,
753+
]
754+
verifylist = [
755+
('name', subnet.name),
756+
]
757+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
758+
759+
columns, data = self.cmd.take_action(parsed_args)
760+
filters = {'name': subnet.name}
761+
762+
self.network.subnets.assert_called_once_with(**filters)
763+
self.assertEqual(self.columns, columns)
764+
self.assertEqual(self.data, list(data))
765+
766+
def test_subnet_list_subnet_range(self):
767+
subnet = network_fakes.FakeSubnet.create_one_subnet()
768+
self.network.find_network = mock.Mock(return_value=subnet)
769+
arglist = [
770+
'--subnet-range', subnet.cidr,
771+
]
772+
verifylist = [
773+
('subnet_range', subnet.cidr),
774+
]
775+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
776+
777+
columns, data = self.cmd.take_action(parsed_args)
778+
filters = {'cidr': subnet.cidr}
671779

672780
self.network.subnets.assert_called_once_with(**filters)
673781
self.assertEqual(self.columns, columns)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
features:
3+
- |
4+
Make ``subnet list`` command supports listing up subnets with
5+
some filtering options by adding ``--project`` and ``--project-domain``,
6+
``--network``, ``--gateway``,``--name``, ``--subnet-range``
7+
options to the command.
8+
[Bug `1610883 <https://bugs.launchpad.net/bugs/1610883>`_]

0 commit comments

Comments
 (0)