Skip to content

Commit 80726b1

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge ""floating ip set/unset port" for OSC"
2 parents 8983373 + 763c8c5 commit 80726b1

6 files changed

Lines changed: 365 additions & 25 deletions

File tree

doc/source/command-objects/floating-ip.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,32 @@ List floating IP(s)
143143
144144
*Network version 2 only*
145145
146+
floating ip set
147+
---------------
148+
149+
Set floating IP properties
150+
151+
.. program:: floating ip set
152+
.. code:: bash
153+
154+
openstack floating ip set
155+
--port <port>
156+
[--fixed-ip-address <ip-address>]
157+
<floating-ip>
158+
159+
.. option:: --port <port>
160+
161+
Assocaite the floating IP with port (name or ID)
162+
163+
.. option:: --fixed-ip-address <ip-address>
164+
165+
Fixed IP of the port (required only if port has multiple IPs)
166+
167+
.. _floating_ip_set-floating-ip:
168+
.. describe:: <floating-ip>
169+
170+
Floating IP to associate (IP address or ID)
171+
146172
floating ip show
147173
----------------
148174
@@ -156,3 +182,24 @@ Display floating IP details
156182
.. describe:: <floating-ip>
157183
158184
Floating IP to display (IP address or ID)
185+
186+
floating ip unset
187+
-----------------
188+
189+
Unset floating IP Properties
190+
191+
.. program:: floating ip unset
192+
.. code:: bash
193+
194+
openstack floating ip unset
195+
--port
196+
<floating-ip>
197+
198+
.. option:: --port
199+
200+
Disassociate any port associated with the floating IP
201+
202+
.. _floating_ip_unset-floating-ip:
203+
.. describe:: <floating-ip>
204+
205+
Floating IP to disassociate (IP address or ID)

openstackclient/network/v2/floating_ip.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
from openstack import exceptions as sdk_exceptions
1919
from openstack.network.v2 import floating_ip as _floating_ip
20+
from osc_lib.command import command
2021
from osc_lib import utils
2122

2223
from openstackclient.i18n import _
@@ -446,6 +447,47 @@ def take_action_compute(self, client, parsed_args):
446447
client, parsed_args)
447448

448449

450+
class SetFloatingIP(command.Command):
451+
_description = _("Set floating IP Properties")
452+
453+
def get_parser(self, prog_name):
454+
parser = super(SetFloatingIP, self).get_parser(prog_name)
455+
parser.add_argument(
456+
'floating_ip',
457+
metavar='<floating-ip>',
458+
help=_("Floating IP to associate (IP address or ID)"))
459+
parser.add_argument(
460+
'--port',
461+
metavar='<port>',
462+
required=True,
463+
help=_("Assocaite the floating IP with port (name or ID)")),
464+
parser.add_argument(
465+
'--fixed-ip-address',
466+
metavar='<ip-address>',
467+
dest='fixed_ip_address',
468+
help=_("Fixed IP of the port "
469+
"(required only if port has multiple IPs)")
470+
)
471+
return parser
472+
473+
def take_action(self, parsed_args):
474+
client = self.app.client_manager.network
475+
attrs = {}
476+
# TODO(sindhu) Use client.find_ip() once SDK 0.9.15 is released
477+
obj = _find_floating_ip(
478+
self.app.client_manager.sdk_connection.session,
479+
parsed_args.floating_ip,
480+
ignore_missing=False,
481+
)
482+
port = client.find_port(parsed_args.port,
483+
ignore_missing=False)
484+
attrs['port_id'] = port.id
485+
if parsed_args.fixed_ip_address:
486+
attrs['fixed_ip_address'] = parsed_args.fixed_ip_address
487+
488+
client.update_ip(obj, **attrs)
489+
490+
449491
class ShowFloatingIP(common.NetworkAndComputeShowOne):
450492
_description = _("Display floating IP details")
451493

@@ -499,3 +541,35 @@ def take_action_compute(self, client, parsed_args):
499541
'Please use "floating ip show" instead.'))
500542
return super(ShowIPFloating, self).take_action_compute(
501543
client, parsed_args)
544+
545+
546+
class UnsetFloatingIP(command.Command):
547+
_description = _("Unset floating IP Properties")
548+
549+
def get_parser(self, prog_name):
550+
parser = super(UnsetFloatingIP, self).get_parser(prog_name)
551+
parser.add_argument(
552+
'floating_ip',
553+
metavar='<floating-ip>',
554+
help=_("Floating IP to disassociate (IP address or ID)"))
555+
parser.add_argument(
556+
'--port',
557+
action='store_true',
558+
default=False,
559+
help=_("Disassociate any port associated with the floating IP")
560+
)
561+
return parser
562+
563+
def take_action(self, parsed_args):
564+
client = self.app.client_manager.network
565+
# TODO(sindhu) Use client.find_ip() once SDK 0.9.15 is released
566+
obj = _find_floating_ip(
567+
self.app.client_manager.sdk_connection.session,
568+
parsed_args.floating_ip,
569+
ignore_missing=False,
570+
)
571+
if parsed_args.port:
572+
attrs = {
573+
'port_id': None,
574+
}
575+
client.update_ip(obj, **attrs)

openstackclient/tests/functional/network/v2/test_floating_ip.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ class FloatingIpTests(base.TestCase):
2121
"""Functional tests for floating ip"""
2222
SUBNET_NAME = uuid.uuid4().hex
2323
NETWORK_NAME = uuid.uuid4().hex
24+
PRIVATE_NETWORK_NAME = uuid.uuid4().hex
25+
PRIVATE_SUBNET_NAME = uuid.uuid4().hex
26+
ROUTER = uuid.uuid4().hex
27+
PORT_NAME = uuid.uuid4().hex
2428

2529
@classmethod
2630
def setUpClass(cls):
@@ -30,13 +34,21 @@ def setUpClass(cls):
3034
cls.re_fixed_ip = re.compile("fixed_ip_address\s+\|\s+(\S+)")
3135
cls.re_description = re.compile("description\s+\|\s+([^|]+?)\s+\|")
3236
cls.re_network_id = re.compile("floating_network_id\s+\|\s+(\S+)")
37+
cls.re_port_id = re.compile("\s+id\s+\|\s+(\S+)")
38+
cls.re_fp_port_id = re.compile("\s+port_id\s+\|\s+(\S+)")
3339

3440
# Create a network for the floating ip
3541
raw_output = cls.openstack(
3642
'network create --external ' + cls.NETWORK_NAME
3743
)
3844
cls.network_id = re.search(cls.re_id, raw_output).group(1)
3945

46+
# Create a private network for the port
47+
raw_output = cls.openstack(
48+
'network create ' + cls.PRIVATE_NETWORK_NAME
49+
)
50+
cls.private_network_id = re.search(cls.re_id, raw_output).group(1)
51+
4052
# Try random subnet range for subnet creating
4153
# Because we can not determine ahead of time what subnets are already
4254
# in use, possibly by another test running in parallel, try 4 times
@@ -46,6 +58,10 @@ def setUpClass(cls):
4658
str,
4759
(random.randint(0, 223) for _ in range(3))
4860
)) + ".0/26"
61+
cls.private_subnet = ".".join(map(
62+
str,
63+
(random.randint(0, 223) for _ in range(3))
64+
)) + ".0/26"
4965
try:
5066
# Create a subnet for the network
5167
raw_output = cls.openstack(
@@ -54,6 +70,13 @@ def setUpClass(cls):
5470
'--subnet-range ' + cls.subnet + ' ' +
5571
cls.SUBNET_NAME
5672
)
73+
# Create a subnet for the private network
74+
priv_raw_output = cls.openstack(
75+
'subnet create ' +
76+
'--network ' + cls.PRIVATE_NETWORK_NAME + ' ' +
77+
'--subnet-range ' + cls.private_subnet + ' ' +
78+
cls.PRIVATE_SUBNET_NAME
79+
)
5780
except Exception:
5881
if (i == 3):
5982
# raise the exception at the last time
@@ -64,13 +87,19 @@ def setUpClass(cls):
6487
break
6588

6689
cls.subnet_id = re.search(cls.re_id, raw_output).group(1)
90+
cls.private_subnet_id = re.search(cls.re_id, priv_raw_output).group(1)
6791

6892
@classmethod
6993
def tearDownClass(cls):
7094
raw_output = cls.openstack('subnet delete ' + cls.SUBNET_NAME)
7195
cls.assertOutput('', raw_output)
96+
raw_output = cls.openstack('subnet delete ' + cls.PRIVATE_SUBNET_NAME)
97+
cls.assertOutput('', raw_output)
7298
raw_output = cls.openstack('network delete ' + cls.NETWORK_NAME)
7399
cls.assertOutput('', raw_output)
100+
raw_output = cls.openstack(
101+
'network delete ' + cls.PRIVATE_NETWORK_NAME)
102+
cls.assertOutput('', raw_output)
74103

75104
def test_floating_ip_delete(self):
76105
"""Test create, delete multiple"""
@@ -168,3 +197,50 @@ def test_floating_ip_show(self):
168197
# re.search(self.re_floating_ip, raw_output).group(1),
169198
# )
170199
self.assertIsNotNone(re.search(self.re_network_id, raw_output))
200+
201+
def test_floating_ip_set_and_unset_port(self):
202+
"""Test Floating IP Set and Unset port"""
203+
raw_output = self.openstack(
204+
'floating ip create ' +
205+
'--description shosho ' +
206+
self.NETWORK_NAME
207+
)
208+
re_ip = re.search(self.re_floating_ip, raw_output)
209+
fp_ip = re_ip.group(1)
210+
self.addCleanup(self.openstack, 'floating ip delete ' + fp_ip)
211+
self.assertIsNotNone(fp_ip)
212+
213+
raw_output1 = self.openstack(
214+
'port create --network ' + self.PRIVATE_NETWORK_NAME
215+
+ ' --fixed-ip subnet=' + self.PRIVATE_SUBNET_NAME +
216+
' ' + self.PORT_NAME
217+
)
218+
re_port_id = re.search(self.re_port_id, raw_output1)
219+
self.assertIsNotNone(re_port_id)
220+
port_id = re_port_id.group(1)
221+
222+
router = self.openstack('router create ' + self.ROUTER)
223+
self.assertIsNotNone(router)
224+
self.addCleanup(self.openstack, 'router delete ' + self.ROUTER)
225+
226+
self.openstack('router add port ' + self.ROUTER +
227+
' ' + port_id)
228+
self.openstack('router set --external-gateway ' + self.NETWORK_NAME +
229+
' ' + self.ROUTER)
230+
231+
self.addCleanup(self.openstack, 'router unset --external-gateway '
232+
+ self.ROUTER)
233+
self.addCleanup(self.openstack, 'router remove port ' + self.ROUTER
234+
+ ' ' + port_id)
235+
236+
raw_output = self.openstack(
237+
'floating ip set ' +
238+
fp_ip + ' --port ' + port_id)
239+
self.addCleanup(self.openstack, 'floating ip unset --port ' + fp_ip)
240+
241+
show_output = self.openstack(
242+
'floating ip show ' + fp_ip)
243+
244+
self.assertEqual(
245+
port_id,
246+
re.search(self.re_fp_port_id, show_output).group(1))

0 commit comments

Comments
 (0)