Skip to content

Commit 230d38f

Browse files
author
reedip
committed
Add command to unset information from ports
This patch introduces the ``port unset`` command to clear the fixed-ip and binding:profile information from the ports. Implements: blueprint network-property-unset Change-Id: I9dba309234105af477e7618a8a437b7fa3b13cd7
1 parent 46b14af commit 230d38f

5 files changed

Lines changed: 173 additions & 0 deletions

File tree

doc/source/command-objects/port.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,32 @@ Display port details
215215
.. describe:: <port>
216216
217217
Port to display (name or ID)
218+
219+
port unset
220+
----------
221+
222+
Unset port properties
223+
224+
.. program:: port unset
225+
.. code:: bash
226+
227+
os port unset
228+
[--fixed-ip subnet=<subnet>,ip-address=<ip-address> [...]]
229+
[--binding-profile <binding-profile-key> [...]]
230+
<port>
231+
232+
.. option:: --fixed-ip subnet=<subnet>,ip-address=<ip-address>
233+
234+
Desired IP and/or subnet (name or ID) which should be removed
235+
from this port: subnet=<subnet>,ip-address=<ip-address>
236+
(repeat option to unset multiple fixed IP addresses)
237+
238+
.. option:: --binding-profile <binding-profile-key>
239+
240+
Desired key which should be removed from binding-profile
241+
(repeat option to unset multiple binding:profile data)
242+
243+
.. _port_unset-port:
244+
.. describe:: <port>
245+
246+
Port to modify (name or ID)

openstackclient/network/v2/port.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"""Port action implementations"""
1515

1616
import argparse
17+
import copy
1718
import json
1819
import logging
1920

@@ -485,3 +486,61 @@ def take_action(self, parsed_args):
485486
columns = _get_columns(obj)
486487
data = utils.get_item_properties(obj, columns, formatters=_formatters)
487488
return (columns, data)
489+
490+
491+
class UnsetPort(command.Command):
492+
"""Unset port properties"""
493+
494+
def get_parser(self, prog_name):
495+
parser = super(UnsetPort, self).get_parser(prog_name)
496+
parser.add_argument(
497+
'--fixed-ip',
498+
metavar='subnet=<subnet>,ip-address=<ip-address>',
499+
action=parseractions.MultiKeyValueAction,
500+
optional_keys=['subnet', 'ip-address'],
501+
help=_("Desired IP and/or subnet (name or ID) which should be "
502+
"removed from this port: subnet=<subnet>,"
503+
"ip-address=<ip-address> (repeat option to unset multiple "
504+
"fixed IP addresses)"))
505+
506+
parser.add_argument(
507+
'--binding-profile',
508+
metavar='<binding-profile-key>',
509+
action='append',
510+
help=_("Desired key which should be removed from binding:profile"
511+
"(repeat option to unset multiple binding:profile data)"))
512+
parser.add_argument(
513+
'port',
514+
metavar="<port>",
515+
help=_("Port to modify (name or ID)")
516+
)
517+
return parser
518+
519+
def take_action(self, parsed_args):
520+
client = self.app.client_manager.network
521+
obj = client.find_port(parsed_args.port, ignore_missing=False)
522+
# SDK ignores update() if it recieves a modified obj and attrs
523+
# To handle the same tmp_obj is created in all take_action of
524+
# Unset* classes
525+
tmp_fixed_ips = copy.deepcopy(obj.fixed_ips)
526+
tmp_binding_profile = copy.deepcopy(obj.binding_profile)
527+
_prepare_fixed_ips(self.app.client_manager, parsed_args)
528+
attrs = {}
529+
if parsed_args.fixed_ip:
530+
try:
531+
for ip in parsed_args.fixed_ip:
532+
tmp_fixed_ips.remove(ip)
533+
except ValueError:
534+
msg = _("Port does not contain fixed-ip %s") % ip
535+
raise exceptions.CommandError(msg)
536+
attrs['fixed_ips'] = tmp_fixed_ips
537+
if parsed_args.binding_profile:
538+
try:
539+
for key in parsed_args.binding_profile:
540+
del tmp_binding_profile[key]
541+
except KeyError:
542+
msg = _("Port does not contain binding-profile %s") % key
543+
raise exceptions.CommandError(msg)
544+
attrs['binding:profile'] = tmp_binding_profile
545+
if attrs:
546+
client.update_port(obj, **attrs)

openstackclient/tests/network/v2/test_port.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,3 +616,81 @@ def test_show_all_options(self):
616616
ref_columns, ref_data = self._get_common_cols_data(self._port)
617617
self.assertEqual(ref_columns, columns)
618618
self.assertEqual(ref_data, data)
619+
620+
621+
class TestUnsetPort(TestPort):
622+
623+
def setUp(self):
624+
super(TestUnsetPort, self).setUp()
625+
self._testport = network_fakes.FakePort.create_one_port(
626+
{'fixed_ips': [{'subnet_id': '042eb10a-3a18-4658-ab-cf47c8d03152',
627+
'ip_address': '0.0.0.1'},
628+
{'subnet_id': '042eb10a-3a18-4658-ab-cf47c8d03152',
629+
'ip_address': '1.0.0.0'}],
630+
'binding:profile': {'batman': 'Joker', 'Superman': 'LexLuthor'}})
631+
self.fake_subnet = network_fakes.FakeSubnet.create_one_subnet(
632+
{'id': '042eb10a-3a18-4658-ab-cf47c8d03152'})
633+
self.network.find_subnet = mock.Mock(return_value=self.fake_subnet)
634+
self.network.find_port = mock.Mock(return_value=self._testport)
635+
self.network.update_port = mock.Mock(return_value=None)
636+
# Get the command object to test
637+
self.cmd = port.UnsetPort(self.app, self.namespace)
638+
639+
def test_unset_port_parameters(self):
640+
arglist = [
641+
'--fixed-ip',
642+
'subnet=042eb10a-3a18-4658-ab-cf47c8d03152,ip-address=1.0.0.0',
643+
'--binding-profile', 'Superman',
644+
self._testport.name,
645+
]
646+
verifylist = [
647+
('fixed_ip', [{
648+
'subnet': '042eb10a-3a18-4658-ab-cf47c8d03152',
649+
'ip-address': '1.0.0.0'}]),
650+
('binding_profile', ['Superman']),
651+
]
652+
653+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
654+
result = self.cmd.take_action(parsed_args)
655+
656+
attrs = {
657+
'fixed_ips': [{
658+
'subnet_id': '042eb10a-3a18-4658-ab-cf47c8d03152',
659+
'ip_address': '0.0.0.1'}],
660+
'binding:profile': {'batman': 'Joker'}
661+
}
662+
self.network.update_port.assert_called_once_with(
663+
self._testport, **attrs)
664+
self.assertIsNone(result)
665+
666+
def test_unset_port_fixed_ip_not_existent(self):
667+
arglist = [
668+
'--fixed-ip', 'ip-address=1.0.0.1',
669+
'--binding-profile', 'Superman',
670+
self._testport.name,
671+
]
672+
verifylist = [
673+
('fixed_ip', [{'ip-address': '1.0.0.1'}]),
674+
('binding_profile', ['Superman']),
675+
]
676+
677+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
678+
self.assertRaises(exceptions.CommandError,
679+
self.cmd.take_action,
680+
parsed_args)
681+
682+
def test_unset_port_binding_profile_not_existent(self):
683+
arglist = [
684+
'--fixed-ip', 'ip-address=1.0.0.0',
685+
'--binding-profile', 'Neo',
686+
self._testport.name,
687+
]
688+
verifylist = [
689+
('fixed_ip', [{'ip-address': '1.0.0.0'}]),
690+
('binding_profile', ['Neo']),
691+
]
692+
693+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
694+
self.assertRaises(exceptions.CommandError,
695+
self.cmd.take_action,
696+
parsed_args)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
Add a new command ``port unset`` to clear the information
5+
of fixed-ip and binding-profile from the port.
6+
[ Blueprint `network-property-unset <https://blueprints.launchpad.net/python-openstackclient/+spec/network-property-unset>`_]

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ openstack.network.v2 =
355355
port_list = openstackclient.network.v2.port:ListPort
356356
port_set = openstackclient.network.v2.port:SetPort
357357
port_show = openstackclient.network.v2.port:ShowPort
358+
port_unset = openstackclient.network.v2.port:UnsetPort
358359

359360
router_add_port = openstackclient.network.v2.router:AddPortToRouter
360361
router_add_subnet = openstackclient.network.v2.router:AddSubnetToRouter

0 commit comments

Comments
 (0)