Skip to content

Commit 803d5b4

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Add --fixed-ip option to the port list command"
2 parents 8c9fff3 + e0e46bc commit 803d5b4

5 files changed

Lines changed: 136 additions & 1 deletion

File tree

doc/source/command-objects/port.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ List ports
155155
[--router <router> | --server <server>]
156156
[--network <network>]
157157
[--mac-address <mac-address>]
158+
[--fixed-ip subnet=<subnet>,ip-address=<ip-address>]
158159
[--long]
159160
[--project <project> [--project-domain <project-domain>]]
160161
@@ -179,6 +180,12 @@ List ports
179180
180181
List only ports with this MAC address
181182
183+
.. option:: --fixed-ip subnet=<subnet>,ip-address=<ip-address>
184+
185+
Desired IP and/or subnet (name or ID) for filtering ports:
186+
subnet=<subnet>,ip-address=<ip-address>
187+
(repeat option to set multiple fixed IP addresses)
188+
182189
.. option:: --long
183190
184191
List additional fields in output

openstackclient/network/v2/port.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,29 @@ def _prepare_fixed_ips(client_manager, parsed_args):
194194
parsed_args.fixed_ip = ips
195195

196196

197+
def _prepare_filter_fixed_ips(client_manager, parsed_args):
198+
"""Fix and properly format fixed_ip option for filtering.
199+
200+
Appropriately convert any subnet names to their respective ids.
201+
Convert fixed_ips in parsed args to be in valid list format for filter:
202+
['subnet_id=foo'].
203+
"""
204+
client = client_manager.network
205+
ips = []
206+
207+
for ip_spec in parsed_args.fixed_ip:
208+
if 'subnet' in ip_spec:
209+
subnet_name_id = ip_spec['subnet']
210+
if subnet_name_id:
211+
_subnet = client.find_subnet(subnet_name_id,
212+
ignore_missing=False)
213+
ips.append('subnet_id=%s' % _subnet.id)
214+
215+
if 'ip-address' in ip_spec:
216+
ips.append('ip_address=%s' % ip_spec['ip-address'])
217+
return ips
218+
219+
197220
def _add_updatable_args(parser):
198221
parser.add_argument(
199222
'--description',
@@ -466,6 +489,15 @@ def get_parser(self, prog_name):
466489
help=_("List ports according to their project (name or ID)")
467490
)
468491
identity_common.add_project_domain_option_to_parser(parser)
492+
parser.add_argument(
493+
'--fixed-ip',
494+
metavar='subnet=<subnet>,ip-address=<ip-address>',
495+
action=parseractions.MultiKeyValueAction,
496+
optional_keys=['subnet', 'ip-address'],
497+
help=_("Desired IP and/or subnet (name or ID) for filtering "
498+
"ports: subnet=<subnet>,ip-address=<ip-address> "
499+
"(repeat option to set multiple fixed IP addresses)")
500+
)
469501
return parser
470502

471503
def take_action(self, parsed_args):
@@ -516,6 +548,9 @@ def take_action(self, parsed_args):
516548
).id
517549
filters['tenant_id'] = project_id
518550
filters['project_id'] = project_id
551+
if parsed_args.fixed_ip:
552+
filters['fixed_ips'] = _prepare_filter_fixed_ips(
553+
self.app.client_manager, parsed_args)
519554

520555
data = network_client.ports(**filters)
521556

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,8 @@ def create_one_port(attrs=None):
470470
'dns_assignment': [{}],
471471
'dns_name': 'dns-name-' + uuid.uuid4().hex,
472472
'extra_dhcp_opts': [{}],
473-
'fixed_ips': [{}],
473+
'fixed_ips': [{'ip_address': '10.0.0.3',
474+
'subnet_id': 'subnet-id-' + uuid.uuid4().hex}],
474475
'id': 'port-id-' + uuid.uuid4().hex,
475476
'mac_address': 'fa:16:3e:a9:4e:72',
476477
'name': 'port-name-' + uuid.uuid4().hex,

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

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,92 @@ def test_port_list_mac_address_opt(self):
727727
self.assertEqual(self.columns, columns)
728728
self.assertEqual(self.data, list(data))
729729

730+
def test_port_list_fixed_ip_opt_ip_address(self):
731+
ip_address = self._ports[0].fixed_ips[0]['ip_address']
732+
arglist = [
733+
'--fixed-ip', "ip-address=%s" % ip_address,
734+
]
735+
verifylist = [
736+
('fixed_ip', [{'ip-address': ip_address}])
737+
]
738+
739+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
740+
741+
columns, data = self.cmd.take_action(parsed_args)
742+
743+
self.network.ports.assert_called_once_with(**{
744+
'fixed_ips': ['ip_address=%s' % ip_address]})
745+
self.assertEqual(self.columns, columns)
746+
self.assertEqual(self.data, list(data))
747+
748+
def test_port_list_fixed_ip_opt_subnet_id(self):
749+
subnet_id = self._ports[0].fixed_ips[0]['subnet_id']
750+
arglist = [
751+
'--fixed-ip', "subnet=%s" % subnet_id,
752+
]
753+
verifylist = [
754+
('fixed_ip', [{'subnet': subnet_id}])
755+
]
756+
757+
self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet(
758+
{'id': subnet_id})
759+
self.network.find_subnet = mock.Mock(return_value=self.fake_subnet)
760+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
761+
columns, data = self.cmd.take_action(parsed_args)
762+
763+
self.network.ports.assert_called_once_with(**{
764+
'fixed_ips': ['subnet_id=%s' % subnet_id]})
765+
self.assertEqual(self.columns, columns)
766+
self.assertEqual(self.data, list(data))
767+
768+
def test_port_list_fixed_ip_opts(self):
769+
subnet_id = self._ports[0].fixed_ips[0]['subnet_id']
770+
ip_address = self._ports[0].fixed_ips[0]['ip_address']
771+
arglist = [
772+
'--fixed-ip', "subnet=%s,ip-address=%s" % (subnet_id,
773+
ip_address)
774+
]
775+
verifylist = [
776+
('fixed_ip', [{'subnet': subnet_id,
777+
'ip-address': ip_address}])
778+
]
779+
780+
self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet(
781+
{'id': subnet_id})
782+
self.network.find_subnet = mock.Mock(return_value=self.fake_subnet)
783+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
784+
columns, data = self.cmd.take_action(parsed_args)
785+
786+
self.network.ports.assert_called_once_with(**{
787+
'fixed_ips': ['subnet_id=%s' % subnet_id,
788+
'ip_address=%s' % ip_address]})
789+
self.assertEqual(self.columns, columns)
790+
self.assertEqual(self.data, list(data))
791+
792+
def test_port_list_fixed_ips(self):
793+
subnet_id = self._ports[0].fixed_ips[0]['subnet_id']
794+
ip_address = self._ports[0].fixed_ips[0]['ip_address']
795+
arglist = [
796+
'--fixed-ip', "subnet=%s" % subnet_id,
797+
'--fixed-ip', "ip-address=%s" % ip_address,
798+
]
799+
verifylist = [
800+
('fixed_ip', [{'subnet': subnet_id},
801+
{'ip-address': ip_address}])
802+
]
803+
804+
self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet(
805+
{'id': subnet_id})
806+
self.network.find_subnet = mock.Mock(return_value=self.fake_subnet)
807+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
808+
columns, data = self.cmd.take_action(parsed_args)
809+
810+
self.network.ports.assert_called_once_with(**{
811+
'fixed_ips': ['subnet_id=%s' % subnet_id,
812+
'ip_address=%s' % ip_address]})
813+
self.assertEqual(self.columns, columns)
814+
self.assertEqual(self.data, list(data))
815+
730816
def test_list_port_with_long(self):
731817
arglist = [
732818
'--long',
@@ -801,6 +887,7 @@ def test_set_fixed_ip(self):
801887
arglist = [
802888
'--fixed-ip', 'ip-address=10.0.0.11',
803889
self._port.name,
890+
'--no-fixed-ip',
804891
]
805892
verifylist = [
806893
('fixed_ip', [{'ip-address': '10.0.0.11'}]),
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
features:
3+
- |
4+
Add ``--fixed-ip`` option to the ``port list`` command.
5+
[Bug `1634799 <https://bugs.launchpad.net/bugs/1634799>`_]

0 commit comments

Comments
 (0)