diff --git a/doc/api_samples/all_extensions/extensions-get-resp.json b/doc/api_samples/all_extensions/extensions-get-resp.json
index df8ed83e53d3..d7c2a646c780 100644
--- a/doc/api_samples/all_extensions/extensions-get-resp.json
+++ b/doc/api_samples/all_extensions/extensions-get-resp.json
@@ -232,6 +232,14 @@
"namespace": "http://docs.openstack.org/compute/ext/evacuate/api/v2",
"updated": "2013-01-06T00:00:00+00:00"
},
+ {
+ "alias": "os-extended-floating-ips",
+ "description": "Adds optional fixed_address to the add floating IP command.",
+ "links": [],
+ "name": "ExtendedFloatingIps",
+ "namespace": "http://docs.openstack.org/compute/ext/extended_floating_ips/api/v2",
+ "updated": "2013-04-19T00:00:00+00:00"
+ },
{
"alias": "os-fixed-ips",
"description": "Fixed IPs support.",
diff --git a/doc/api_samples/all_extensions/extensions-get-resp.xml b/doc/api_samples/all_extensions/extensions-get-resp.xml
index 1ec2010dc3ac..f6213a3a92eb 100644
--- a/doc/api_samples/all_extensions/extensions-get-resp.xml
+++ b/doc/api_samples/all_extensions/extensions-get-resp.xml
@@ -103,6 +103,9 @@
Enables server evacuation.
+
+ Adds optional fixed_address to the add floating IP command.
+
Fixed IPs support.
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-create-nopool-req.json b/doc/api_samples/os-extended-floating-ips/floating-ips-create-nopool-req.json
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-create-nopool-req.xml b/doc/api_samples/os-extended-floating-ips/floating-ips-create-nopool-req.xml
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-create-req.json b/doc/api_samples/os-extended-floating-ips/floating-ips-create-req.json
new file mode 100644
index 000000000000..511b009bede9
--- /dev/null
+++ b/doc/api_samples/os-extended-floating-ips/floating-ips-create-req.json
@@ -0,0 +1,3 @@
+{
+ "pool": "nova"
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-create-req.xml b/doc/api_samples/os-extended-floating-ips/floating-ips-create-req.xml
new file mode 100644
index 000000000000..f77525e74983
--- /dev/null
+++ b/doc/api_samples/os-extended-floating-ips/floating-ips-create-req.xml
@@ -0,0 +1,2 @@
+
+nova
\ No newline at end of file
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-create-resp.json b/doc/api_samples/os-extended-floating-ips/floating-ips-create-resp.json
new file mode 100644
index 000000000000..fe161a7dd129
--- /dev/null
+++ b/doc/api_samples/os-extended-floating-ips/floating-ips-create-resp.json
@@ -0,0 +1,9 @@
+{
+ "floating_ip": {
+ "fixed_ip": null,
+ "id": 1,
+ "instance_id": null,
+ "ip": "10.10.10.1",
+ "pool": "nova"
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-create-resp.xml b/doc/api_samples/os-extended-floating-ips/floating-ips-create-resp.xml
new file mode 100644
index 000000000000..e0f68ef503a6
--- /dev/null
+++ b/doc/api_samples/os-extended-floating-ips/floating-ips-create-resp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.json b/doc/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.json
new file mode 100644
index 000000000000..121dbd084e87
--- /dev/null
+++ b/doc/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.json
@@ -0,0 +1,3 @@
+{
+ "floating_ips": []
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.xml b/doc/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.xml
new file mode 100644
index 000000000000..da6f0d4ce993
--- /dev/null
+++ b/doc/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-list-resp.json b/doc/api_samples/os-extended-floating-ips/floating-ips-list-resp.json
new file mode 100644
index 000000000000..4d58e0676a93
--- /dev/null
+++ b/doc/api_samples/os-extended-floating-ips/floating-ips-list-resp.json
@@ -0,0 +1,18 @@
+{
+ "floating_ips": [
+ {
+ "fixed_ip": null,
+ "id": 1,
+ "instance_id": null,
+ "ip": "10.10.10.1",
+ "pool": "nova"
+ },
+ {
+ "fixed_ip": null,
+ "id": 2,
+ "instance_id": null,
+ "ip": "10.10.10.2",
+ "pool": "nova"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-extended-floating-ips/floating-ips-list-resp.xml b/doc/api_samples/os-extended-floating-ips/floating-ips-list-resp.xml
new file mode 100644
index 000000000000..78348be553d1
--- /dev/null
+++ b/doc/api_samples/os-extended-floating-ips/floating-ips-list-resp.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/nova/api/openstack/compute/contrib/extended_floating_ips.py b/nova/api/openstack/compute/contrib/extended_floating_ips.py
new file mode 100644
index 000000000000..06f1fa903412
--- /dev/null
+++ b/nova/api/openstack/compute/contrib/extended_floating_ips.py
@@ -0,0 +1,27 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License
+
+from nova.api.openstack import extensions
+
+
+class Extended_floating_ips(extensions.ExtensionDescriptor):
+ """Adds optional fixed_address to the add floating IP command."""
+
+ name = "ExtendedFloatingIps"
+ alias = "os-extended-floating-ips"
+ namespace = ("http://docs.openstack.org/compute/ext/"
+ "extended_floating_ips/api/v2")
+ updated = "2013-04-19T00:00:00+00:00"
diff --git a/nova/api/openstack/compute/contrib/floating_ips.py b/nova/api/openstack/compute/contrib/floating_ips.py
index bf1246ccba73..32cf1eecec58 100644
--- a/nova/api/openstack/compute/contrib/floating_ips.py
+++ b/nova/api/openstack/compute/contrib/floating_ips.py
@@ -198,10 +198,11 @@ class FloatingIPController(object):
class FloatingIPActionController(wsgi.Controller):
- def __init__(self, *args, **kwargs):
+ def __init__(self, ext_mgr=None, *args, **kwargs):
super(FloatingIPActionController, self).__init__(*args, **kwargs)
self.compute_api = compute.API()
self.network_api = network.API()
+ self.ext_mgr = ext_mgr
@wsgi.action('addFloatingIp')
def _add_floating_ip(self, req, id, body):
@@ -230,18 +231,27 @@ class FloatingIPActionController(wsgi.Controller):
msg = _('No fixed ips associated to instance')
raise webob.exc.HTTPBadRequest(explanation=msg)
- # TODO(tr3buchet): this will associate the floating IP with the
- # first fixed_ip an instance has. This should be
- # changed to support specifying a particular fixed_ip if
- # multiple exist.
- if len(fixed_ips) > 1:
- msg = _('multiple fixed_ips exist, using the first: %s')
- LOG.warning(msg, fixed_ips[0]['address'])
+ fixed_address = None
+ if self.ext_mgr.is_loaded('os-extended-floating-ips'):
+ if 'fixed_address' in body['addFloatingIp']:
+ fixed_address = body['addFloatingIp']['fixed_address']
+ for fixed in fixed_ips:
+ if fixed['address'] == fixed_address:
+ break
+ else:
+ msg = _('Specified fixed address not assigned to instance')
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ if not fixed_address:
+ fixed_address = fixed_ips[0]['address']
+ if len(fixed_ips) > 1:
+ msg = _('multiple fixed_ips exist, using the first: %s')
+ LOG.warning(msg, fixed_address)
try:
self.network_api.associate_floating_ip(context, instance,
floating_address=address,
- fixed_address=fixed_ips[0]['address'])
+ fixed_address=fixed_address)
except exception.FloatingIpAssociated:
msg = _('floating ip is already associated')
raise webob.exc.HTTPBadRequest(explanation=msg)
@@ -318,6 +328,6 @@ class Floating_ips(extensions.ExtensionDescriptor):
return resources
def get_controller_extensions(self):
- controller = FloatingIPActionController()
+ controller = FloatingIPActionController(self.ext_mgr)
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
diff --git a/nova/tests/api/openstack/compute/contrib/test_floating_ips.py b/nova/tests/api/openstack/compute/contrib/test_floating_ips.py
index 00759a7ef613..2dc6f29568b4 100644
--- a/nova/tests/api/openstack/compute/contrib/test_floating_ips.py
+++ b/nova/tests/api/openstack/compute/contrib/test_floating_ips.py
@@ -20,6 +20,7 @@ from lxml import etree
import webob
from nova.api.openstack.compute.contrib import floating_ips
+from nova.api.openstack import extensions
from nova import compute
from nova.compute import utils as compute_utils
from nova import context
@@ -154,8 +155,10 @@ class FloatingIpTest(test.TestCase):
self.context = context.get_admin_context()
self._create_floating_ips()
+ self.ext_mgr = extensions.ExtensionManager()
+ self.ext_mgr.extensions = {}
self.controller = floating_ips.FloatingIPController()
- self.manager = floating_ips.FloatingIPActionController()
+ self.manager = floating_ips.FloatingIPActionController(self.ext_mgr)
def tearDown(self):
self._delete_floating_ip()
@@ -315,8 +318,10 @@ class FloatingIpTest(test.TestCase):
self.controller.delete(req, 1)
def test_floating_ip_associate(self):
+ fixed_address = '192.168.1.100'
+
def fake_associate_floating_ip(*args, **kwargs):
- pass
+ self.assertEqual(fixed_address, kwargs['fixed_address'])
self.stubs.Set(network.api.API, "associate_floating_ip",
fake_associate_floating_ip)
@@ -326,8 +331,26 @@ class FloatingIpTest(test.TestCase):
rsp = self.manager._add_floating_ip(req, 'test_inst', body)
self.assertTrue(rsp.status_int == 202)
- def test_associate_not_allocated_floating_ip_to_instance(self):
+ def test_not_extended_floating_ip_associate_fixed(self):
+ # Check that fixed_address is ignored if os-extended-floating-ips
+ # is not loaded
+ fixed_address_requested = '192.168.1.101'
+ fixed_address_allocated = '192.168.1.100'
+ def fake_associate_floating_ip(*args, **kwargs):
+ self.assertEqual(fixed_address_allocated,
+ kwargs['fixed_address'])
+
+ self.stubs.Set(network.api.API, "associate_floating_ip",
+ fake_associate_floating_ip)
+ body = dict(addFloatingIp=dict(address=self.floating_ip,
+ fixed_address=fixed_address_requested))
+
+ req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
+ rsp = self.manager._add_floating_ip(req, 'test_inst', body)
+ self.assertTrue(rsp.status_int == 202)
+
+ def test_associate_not_allocated_floating_ip_to_instance(self):
def fake_associate_floating_ip(self, context, instance,
floating_address, fixed_address,
affect_auto_assigned=False):
@@ -510,6 +533,106 @@ class FloatingIpTest(test.TestCase):
body)
+class ExtendedFloatingIpTest(test.TestCase):
+ floating_ip = "10.10.10.10"
+ floating_ip_2 = "10.10.10.11"
+
+ def _create_floating_ips(self, floating_ips=None):
+ """Create a floating ip object."""
+ if floating_ips is None:
+ floating_ips = [self.floating_ip]
+ elif not isinstance(floating_ips, (list, tuple)):
+ floating_ips = [floating_ips]
+
+ def make_ip_dict(ip):
+ """Shortcut for creating floating ip dict."""
+ return
+
+ dict_ = {'pool': 'nova', 'host': 'fake_host'}
+ return db.floating_ip_bulk_create(
+ self.context, [dict(address=ip, **dict_) for ip in floating_ips],
+ )
+
+ def _delete_floating_ip(self):
+ db.floating_ip_destroy(self.context, self.floating_ip)
+
+ def setUp(self):
+ super(ExtendedFloatingIpTest, self).setUp()
+ self.stubs.Set(compute.api.API, "get",
+ compute_api_get)
+ self.stubs.Set(network.api.API, "get_floating_ip",
+ network_api_get_floating_ip)
+ self.stubs.Set(network.api.API, "get_floating_ip_by_address",
+ network_api_get_floating_ip_by_address)
+ self.stubs.Set(network.api.API, "get_floating_ips_by_project",
+ network_api_get_floating_ips_by_project)
+ self.stubs.Set(network.api.API, "release_floating_ip",
+ network_api_release)
+ self.stubs.Set(network.api.API, "disassociate_floating_ip",
+ network_api_disassociate)
+ self.stubs.Set(network.api.API, "get_instance_id_by_floating_address",
+ get_instance_by_floating_ip_addr)
+ self.stubs.Set(compute_utils, "get_nw_info_for_instance",
+ stub_nw_info(self.stubs))
+ self.flags(
+ osapi_compute_extension=[
+ 'nova.api.openstack.compute.contrib.select_extensions'],
+ osapi_compute_ext_list=['Floating_ips', 'Extended_floating_ips'])
+
+ fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs,
+ spectacular=True)
+ self.stubs.Set(db, 'instance_get',
+ fake_instance_get)
+
+ self.context = context.get_admin_context()
+ self._create_floating_ips()
+
+ self.ext_mgr = extensions.ExtensionManager()
+ self.ext_mgr.extensions = {}
+ self.ext_mgr.extensions['os-floating-ips'] = True
+ self.ext_mgr.extensions['os-extended-floating-ips'] = True
+ self.controller = floating_ips.FloatingIPController()
+ self.manager = floating_ips.FloatingIPActionController(self.ext_mgr)
+
+ def tearDown(self):
+ self._delete_floating_ip()
+ super(ExtendedFloatingIpTest, self).tearDown()
+
+ def test_extended_floating_ip_associate_fixed(self):
+ fixed_address = '192.168.1.101'
+
+ def fake_associate_floating_ip(*args, **kwargs):
+ self.assertEqual(fixed_address, kwargs['fixed_address'])
+
+ self.stubs.Set(network.api.API, "associate_floating_ip",
+ fake_associate_floating_ip)
+ body = dict(addFloatingIp=dict(address=self.floating_ip,
+ fixed_address=fixed_address))
+
+ req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
+ rsp = self.manager._add_floating_ip(req, 'test_inst', body)
+ self.assertTrue(rsp.status_int == 202)
+
+ def test_extended_floating_ip_associate_fixed_not_allocated(self):
+ def fake_associate_floating_ip(*args, **kwargs):
+ pass
+
+ self.stubs.Set(network.api.API, "associate_floating_ip",
+ fake_associate_floating_ip)
+ body = dict(addFloatingIp=dict(address=self.floating_ip,
+ fixed_address='11.11.11.11'))
+
+ req = webob.Request.blank('/v2/fake/servers/test_inst/action')
+ req.method = "POST"
+ req.body = jsonutils.dumps(body)
+ req.headers["content-type"] = "application/json"
+ resp = req.get_response(fakes.wsgi_app(init_only=('servers',)))
+ res_dict = jsonutils.loads(resp.body)
+ self.assertEqual(resp.status_int, 400)
+ self.assertEqual(res_dict['badRequest']['message'],
+ "Specified fixed address not assigned to instance")
+
+
class FloatingIpSerializerTest(test.TestCase):
def test_default_serializer(self):
serializer = floating_ips.FloatingIPTemplate()
diff --git a/nova/tests/api/openstack/compute/test_extensions.py b/nova/tests/api/openstack/compute/test_extensions.py
index 658d0c474dda..6e400a075cec 100644
--- a/nova/tests/api/openstack/compute/test_extensions.py
+++ b/nova/tests/api/openstack/compute/test_extensions.py
@@ -167,6 +167,7 @@ class ExtensionControllerTest(ExtensionTestCase):
"DeferredDelete",
"DiskConfig",
"ExtendedAvailabilityZone",
+ "ExtendedFloatingIps",
"ExtendedIps",
"ExtendedIpsMac",
"ExtendedVIFNet",
diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl
index 1d3d2ea90047..d559b4890f22 100644
--- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl
+++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.json.tpl
@@ -232,6 +232,14 @@
"namespace": "http://docs.openstack.org/compute/ext/evacuate/api/v2",
"updated": "%(timestamp)s"
},
+ {
+ "alias": "os-extended-floating-ips",
+ "description": "%(text)s",
+ "links": [],
+ "name": "ExtendedFloatingIps",
+ "namespace": "http://docs.openstack.org/compute/ext/extended_floating_ips/api/v2",
+ "updated": "%(timestamp)s"
+ },
{
"alias": "os-fixed-ips",
"description": "Fixed IPs support.",
diff --git a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl
index 440996966e12..cc9ae4c02685 100644
--- a/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl
+++ b/nova/tests/integrated/api_samples/all_extensions/extensions-get-resp.xml.tpl
@@ -87,6 +87,9 @@
%(text)s
+
+ %(text)s
+
Fixed IPs support.
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-nopool-req.json.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-nopool-req.json.tpl
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-nopool-req.xml.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-nopool-req.xml.tpl
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-req.json.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-req.json.tpl
new file mode 100644
index 000000000000..24129f4958e0
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-req.json.tpl
@@ -0,0 +1,3 @@
+{
+ "pool": "%(pool)s"
+}
\ No newline at end of file
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-req.xml.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-req.xml.tpl
new file mode 100644
index 000000000000..a80147389daa
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-req.xml.tpl
@@ -0,0 +1,2 @@
+
+%(pool)s
\ No newline at end of file
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-resp.json.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-resp.json.tpl
new file mode 100644
index 000000000000..10ee8d9bd402
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-resp.json.tpl
@@ -0,0 +1,9 @@
+{
+ "floating_ip": {
+ "fixed_ip": null,
+ "id": 1,
+ "instance_id": null,
+ "ip": "10.10.10.1",
+ "pool": "nova"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-resp.xml.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-resp.xml.tpl
new file mode 100644
index 000000000000..e0f68ef503a6
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-create-resp.xml.tpl
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-get-resp.json.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-get-resp.json.tpl
new file mode 100644
index 000000000000..10ee8d9bd402
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-get-resp.json.tpl
@@ -0,0 +1,9 @@
+{
+ "floating_ip": {
+ "fixed_ip": null,
+ "id": 1,
+ "instance_id": null,
+ "ip": "10.10.10.1",
+ "pool": "nova"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-get-resp.xml.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-get-resp.xml.tpl
new file mode 100644
index 000000000000..e0f68ef503a6
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-get-resp.xml.tpl
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.json.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.json.tpl
new file mode 100644
index 000000000000..12f118da50dd
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.json.tpl
@@ -0,0 +1,3 @@
+{
+ "floating_ips": []
+}
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.xml.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.xml.tpl
new file mode 100644
index 000000000000..da6f0d4ce993
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-empty-resp.xml.tpl
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-resp.json.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-resp.json.tpl
new file mode 100644
index 000000000000..06f57451c9d8
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-resp.json.tpl
@@ -0,0 +1,19 @@
+{
+ "floating_ips": [
+ {
+ "fixed_ip": null,
+ "id": 1,
+ "instance_id": null,
+ "ip": "10.10.10.1",
+ "pool": "nova"
+ },
+ {
+ "fixed_ip": null,
+ "id": 2,
+ "instance_id": null,
+ "ip": "10.10.10.2",
+ "pool": "nova"
+ }
+ ]
+}
+
diff --git a/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-resp.xml.tpl b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-resp.xml.tpl
new file mode 100644
index 000000000000..bbd0b117ef61
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-extended-floating-ips/floating-ips-list-resp.xml.tpl
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/nova/tests/integrated/test_api_samples.py b/nova/tests/integrated/test_api_samples.py
index 188f96055d9a..32ee8816e03e 100644
--- a/nova/tests/integrated/test_api_samples.py
+++ b/nova/tests/integrated/test_api_samples.py
@@ -83,12 +83,15 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
extension_name = None
def setUp(self):
+ extends = []
self.flags(use_ipv6=False,
osapi_compute_link_prefix=self._get_host(),
osapi_glance_link_prefix=self._get_glance_host())
if not self.all_extensions:
+ if hasattr(self, 'extends_name'):
+ extends = [self.extends_name]
ext = [self.extension_name] if self.extension_name else []
- self.flags(osapi_compute_extension=ext)
+ self.flags(osapi_compute_extension=ext + extends)
super(ApiSampleTestBase, self).setUp()
fake_network.stub_compute_with_ips(self.stubs)
self.generate_samples = os.getenv('GENERATE_SAMPLES') is not None
@@ -1351,10 +1354,21 @@ class FloatingIpsJsonTest(ApiSampleTestBase):
self.assertEqual(response.status, 202)
+class ExtendedFloatingIpsJsonTest(FloatingIpsJsonTest):
+ extends_name = ("nova.api.openstack.compute.contrib."
+ "floating_ips.Floating_ips")
+ extension_name = ("nova.api.openstack.compute.contrib."
+ "extended_floating_ips.Extended_floating_ips")
+
+
class FloatingIpsXmlTest(FloatingIpsJsonTest):
ctype = 'xml'
+class ExtendedFloatingIpsXmlTest(ExtendedFloatingIpsJsonTest):
+ ctype = 'xml'
+
+
class FloatingIpsBulkJsonTest(ApiSampleTestBase):
extension_name = "nova.api.openstack.compute.contrib." \
"floating_ips_bulk.Floating_ips_bulk"