Skip to content

Commit 1fc41f3

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Introduce overwrite functionality in osc port set"
2 parents 40cc493 + b38be94 commit 1fc41f3

4 files changed

Lines changed: 78 additions & 15 deletions

File tree

doc/source/command-objects/port.rst

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,13 @@ Set port properties
144144
.. code:: bash
145145
146146
os port set
147-
[--fixed-ip subnet=<subnet>,ip-address=<ip-address> | --no-fixed-ip]
147+
[--fixed-ip subnet=<subnet>,ip-address=<ip-address>]
148+
[--no-fixed-ip]
148149
[--device <device-id>]
149150
[--device-owner <device-owner>]
150151
[--vnic-type <vnic-type>]
151-
[--binding-profile <binding-profile> | --no-binding-profile]
152+
[--binding-profile <binding-profile>]
153+
[--no-binding-profile]
152154
[--host <host-id>]
153155
[--enable | --disable]
154156
[--name <name>]
@@ -162,7 +164,9 @@ Set port properties
162164
163165
.. option:: --no-fixed-ip
164166
165-
Clear existing information of fixed IP addresses
167+
Clear existing information of fixed IP addresses.
168+
Specify both --fixed-ip and --no-fixed-ip
169+
to overwrite the current fixed IP addresses.
166170
167171
.. option:: --device <device-id>
168172
@@ -186,7 +190,9 @@ Set port properties
186190
187191
.. option:: --no-binding-profile
188192
189-
Clear existing information of binding:profile
193+
Clear existing information of binding:profile.
194+
Specify both --binding-profile and --no-binding-profile
195+
to overwrite the current binding:profile information.
190196
191197
.. option:: --host <host-id>
192198

openstackclient/network/v2/port.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ def _get_attrs(client_manager, parsed_args):
109109
'The --host-id option is deprecated, '
110110
'please use --host instead.'
111111
))
112-
113112
if parsed_args.fixed_ip is not None:
114113
attrs['fixed_ips'] = parsed_args.fixed_ip
115114
if parsed_args.device:
@@ -428,8 +427,7 @@ def get_parser(self, prog_name):
428427
metavar="<name>",
429428
help=_("Set port name")
430429
)
431-
fixed_ip = parser.add_mutually_exclusive_group()
432-
fixed_ip.add_argument(
430+
parser.add_argument(
433431
'--fixed-ip',
434432
metavar='subnet=<subnet>,ip-address=<ip-address>',
435433
action=parseractions.MultiKeyValueAction,
@@ -438,24 +436,27 @@ def get_parser(self, prog_name):
438436
"subnet=<subnet>,ip-address=<ip-address> "
439437
"(repeat option to set multiple fixed IP addresses)")
440438
)
441-
fixed_ip.add_argument(
439+
parser.add_argument(
442440
'--no-fixed-ip',
443441
action='store_true',
444-
help=_("Clear existing information of fixed IP addresses")
442+
help=_("Clear existing information of fixed IP addresses."
443+
"Specify both --fixed-ip and --no-fixed-ip "
444+
"to overwrite the current fixed IP addresses.")
445445
)
446-
binding_profile = parser.add_mutually_exclusive_group()
447-
binding_profile.add_argument(
446+
parser.add_argument(
448447
'--binding-profile',
449448
metavar='<binding-profile>',
450449
action=JSONKeyValueAction,
451450
help=_("Custom data to be passed as binding:profile. Data may "
452451
"be passed as <key>=<value> or JSON. "
453452
"(repeat option to set multiple binding:profile data)")
454453
)
455-
binding_profile.add_argument(
454+
parser.add_argument(
456455
'--no-binding-profile',
457456
action='store_true',
458-
help=_("Clear existing information of binding:profile")
457+
help=_("Clear existing information of binding:profile."
458+
"Specify both --binding-profile and --no-binding-profile "
459+
"to overwrite the current binding:profile information.")
459460
)
460461
parser.add_argument(
461462
'port',
@@ -471,7 +472,11 @@ def take_action(self, parsed_args):
471472
attrs = _get_attrs(self.app.client_manager, parsed_args)
472473
obj = client.find_port(parsed_args.port, ignore_missing=False)
473474
if 'binding:profile' in attrs:
474-
attrs['binding:profile'].update(obj.binding_profile)
475+
# Do not modify attrs if both binding_profile/no_binding given
476+
if not parsed_args.no_binding_profile:
477+
tmp_binding_profile = copy.deepcopy(obj.binding_profile)
478+
tmp_binding_profile.update(attrs['binding:profile'])
479+
attrs['binding:profile'] = tmp_binding_profile
475480
elif parsed_args.no_binding_profile:
476481
attrs['binding:profile'] = {}
477482
if 'fixed_ips' in attrs:
@@ -480,7 +485,9 @@ def take_action(self, parsed_args):
480485
# would therefore add an empty dictionary, while we need
481486
# to append the attrs['fixed_ips'] iff there is some info
482487
# in the obj.fixed_ips. Therefore I have opted for this `for` loop
483-
attrs['fixed_ips'] += [ip for ip in obj.fixed_ips if ip]
488+
# Do not modify attrs if fixed_ip/no_fixed_ip given
489+
if not parsed_args.no_fixed_ip:
490+
attrs['fixed_ips'] += [ip for ip in obj.fixed_ips if ip]
484491
elif parsed_args.no_fixed_ip:
485492
attrs['fixed_ips'] = []
486493

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,50 @@ def test_append_fixed_ip(self):
494494
self.network.update_port.assert_called_once_with(_testport, **attrs)
495495
self.assertIsNone(result)
496496

497+
def test_overwrite_binding_profile(self):
498+
_testport = network_fakes.FakePort.create_one_port(
499+
{'binding_profile': {'lok_i': 'visi_on'}})
500+
self.network.find_port = mock.Mock(return_value=_testport)
501+
arglist = [
502+
'--binding-profile', 'lok_i=than_os',
503+
'--no-binding-profile',
504+
_testport.name,
505+
]
506+
verifylist = [
507+
('binding_profile', {'lok_i': 'than_os'}),
508+
('no_binding_profile', True)
509+
]
510+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
511+
result = self.cmd.take_action(parsed_args)
512+
attrs = {
513+
'binding:profile':
514+
{'lok_i': 'than_os'},
515+
}
516+
self.network.update_port.assert_called_once_with(_testport, **attrs)
517+
self.assertIsNone(result)
518+
519+
def test_overwrite_fixed_ip(self):
520+
_testport = network_fakes.FakePort.create_one_port(
521+
{'fixed_ips': [{'ip_address': '0.0.0.1'}]})
522+
self.network.find_port = mock.Mock(return_value=_testport)
523+
arglist = [
524+
'--fixed-ip', 'ip-address=10.0.0.12',
525+
'--no-fixed-ip',
526+
_testport.name,
527+
]
528+
verifylist = [
529+
('fixed_ip', [{'ip-address': '10.0.0.12'}]),
530+
('no_fixed_ip', True)
531+
]
532+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
533+
result = self.cmd.take_action(parsed_args)
534+
attrs = {
535+
'fixed_ips': [
536+
{'ip_address': '10.0.0.12'}],
537+
}
538+
self.network.update_port.assert_called_once_with(_testport, **attrs)
539+
self.assertIsNone(result)
540+
497541
def test_set_this(self):
498542
arglist = [
499543
'--disable',
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
``port set`` command now allows the user to overwrite fixed-ips or binding-profile
5+
of a port.
6+
[ Blueprint `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>` _]

0 commit comments

Comments
 (0)