summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-09-27 16:38:38 +0000
committerGerrit Code Review <review@openstack.org>2014-09-27 16:38:38 +0000
commit3061bf3dc4a69b4abc575b93a4eabf60a02d3e3b (patch)
tree72c54e4b8ba1e69556a92afd7a1433137a8fa34a
parent4e943613f819e18a477d95abbfbf1b29cf527322 (diff)
parentd0d925f45170634a7ef8b11f15b7971513fa9227 (diff)
downloadheat-3061bf3dc4a69b4abc575b93a4eabf60a02d3e3b.tar.gz
Merge "FloatingIP updateable port_id, fixed_ip_address"
-rw-r--r--heat/engine/resources/neutron/floatingip.py24
-rw-r--r--heat/tests/test_neutron.py155
2 files changed, 176 insertions, 3 deletions
diff --git a/heat/engine/resources/neutron/floatingip.py b/heat/engine/resources/neutron/floatingip.py
index f3a22f1c4..cfea9d34c 100644
--- a/heat/engine/resources/neutron/floatingip.py
+++ b/heat/engine/resources/neutron/floatingip.py
@@ -58,11 +58,13 @@ class FloatingIP(neutron.NeutronResource):
PORT_ID: properties.Schema(
properties.Schema.STRING,
_('ID of an existing port with at least one IP address to '
- 'associate with this floating IP.')
+ 'associate with this floating IP.'),
+ update_allowed=True
),
FIXED_IP_ADDRESS: properties.Schema(
properties.Schema.STRING,
- _('IP address to use if the port has multiple addresses.')
+ _('IP address to use if the port has multiple addresses.'),
+ update_allowed=True
),
}
@@ -131,6 +133,24 @@ class FloatingIP(neutron.NeutronResource):
except Exception as ex:
self.client_plugin().ignore_not_found(ex)
+ def handle_update(self, json_snippet, tmpl_diff, prop_diff):
+ if prop_diff:
+ neutron_client = self.neutron()
+
+ port_id = prop_diff.get(self.PORT_ID,
+ self.properties.get(self.PORT_ID))
+
+ fixed_ip_address = prop_diff.get(
+ self.FIXED_IP_ADDRESS,
+ self.properties.get(self.FIXED_IP_ADDRESS))
+
+ request_body = {
+ 'floatingip': {
+ 'port_id': port_id,
+ 'fixed_ip_address': fixed_ip_address}}
+
+ neutron_client.update_floatingip(self.resource_id, request_body)
+
class FloatingIPAssociation(neutron.NeutronResource):
PROPERTIES = (
diff --git a/heat/tests/test_neutron.py b/heat/tests/test_neutron.py
index dcd5ff12c..b8d25ca2f 100644
--- a/heat/tests/test_neutron.py
+++ b/heat/tests/test_neutron.py
@@ -323,6 +323,43 @@ neutron_floating_template = '''
}
'''
+neutron_floating_no_assoc_template = '''
+{
+ "AWSTemplateFormatVersion" : "2010-09-09",
+ "Description" : "Template to test Neutron resources",
+ "Parameters" : {},
+ "Resources" : {
+ "port_floating": {
+ "Type": "OS::Neutron::Port",
+ "Properties": {
+ "network": "xyz1234",
+ "fixed_ips": [{
+ "subnet": "sub1234",
+ "ip_address": "10.0.0.10"
+ }]
+ }
+ },
+ "floating_ip": {
+ "Type": "OS::Neutron::FloatingIP",
+ "Properties": {
+ "floating_network": "abcd1234",
+ "port_id": { "Ref" : "port_floating" }
+ }
+ },
+ "router": {
+ "Type": "OS::Neutron::Router"
+ },
+ "gateway": {
+ "Type": "OS::Neutron::RouterGateway",
+ "Properties": {
+ "router_id": { "Ref" : "router" },
+ "network": "abcd1234"
+ }
+ }
+ }
+}
+'''
+
neutron_port_template_deprecated = '''
{
"AWSTemplateFormatVersion" : "2010-09-09",
@@ -2043,7 +2080,7 @@ class NeutronFloatingIPTest(HeatTestCase):
self.m.VerifyAll()
- def test_floatip_port(self):
+ def test_floatip_association_port(self):
neutronV20.find_resourceid_by_name_or_id(
mox.IsA(neutronclient.Client),
'network',
@@ -2240,6 +2277,122 @@ class NeutronFloatingIPTest(HeatTestCase):
self.m.VerifyAll()
+ def test_floatip_port(self):
+ neutronV20.find_resourceid_by_name_or_id(
+ mox.IsA(neutronclient.Client),
+ 'network',
+ 'xyz1234'
+ ).AndReturn('xyz1234')
+ neutronV20.find_resourceid_by_name_or_id(
+ mox.IsA(neutronclient.Client),
+ 'subnet',
+ 'sub1234'
+ ).AndReturn('sub1234')
+ neutronclient.Client.create_port({'port': {
+ 'network_id': u'xyz1234',
+ 'fixed_ips': [
+ {'subnet_id': u'sub1234', 'ip_address': u'10.0.0.10'}
+ ],
+ 'name': utils.PhysName('test_stack', 'port_floating'),
+ 'admin_state_up': True}}
+ ).AndReturn({'port': {
+ "status": "BUILD",
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
+ }})
+ neutronclient.Client.show_port(
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
+ ).AndReturn({'port': {
+ "status": "ACTIVE",
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
+ }})
+ neutronV20.find_resourceid_by_name_or_id(
+ mox.IsA(neutronclient.Client),
+ 'network',
+ 'abcd1234'
+ ).AndReturn('abcd1234')
+ neutronclient.Client.create_floatingip({
+ 'floatingip': {
+ 'floating_network_id': u'abcd1234',
+ 'port_id': u'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
+ }
+ }).AndReturn({'floatingip': {
+ "status": "ACTIVE",
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
+ }})
+
+ # update with new port_id
+ neutronclient.Client.update_floatingip(
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
+ {
+ 'floatingip': {
+ 'port_id': u'2146dfbf-ba77-4083-8e86-d052f671ece5',
+ 'fixed_ip_address': None}}
+ ).AndReturn({'floatingip': {
+ "status": "ACTIVE",
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
+ }})
+
+ # update with None port_id
+ neutronclient.Client.update_floatingip(
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
+ {
+ 'floatingip': {
+ 'port_id': None,
+ 'fixed_ip_address': None}}
+ ).AndReturn({'floatingip': {
+ "status": "ACTIVE",
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
+ }})
+
+ neutronclient.Client.delete_floatingip(
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
+ ).AndReturn(None)
+
+ neutronclient.Client.delete_port(
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
+ ).AndReturn(None)
+
+ neutronclient.Client.show_port(
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
+ ).AndRaise(qe.PortNotFoundClient(status_code=404))
+
+ self.m.ReplayAll()
+
+ t = template_format.parse(neutron_floating_no_assoc_template)
+ stack = utils.parse_stack(t)
+
+ p = stack['port_floating']
+ scheduler.TaskRunner(p.create)()
+ self.assertEqual((p.CREATE, p.COMPLETE), p.state)
+
+ fip = stack['floating_ip']
+ scheduler.TaskRunner(fip.create)()
+ self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
+
+ # test update FloatingIp with port_id
+ props = copy.deepcopy(fip.properties.data)
+ update_port_id = '2146dfbf-ba77-4083-8e86-d052f671ece5'
+ props['port_id'] = update_port_id
+ update_snippet = rsrc_defn.ResourceDefinition(fip.name, fip.type(),
+ stack.t.parse(stack,
+ props))
+ scheduler.TaskRunner(fip.update, update_snippet)()
+ self.assertEqual((fip.UPDATE, fip.COMPLETE), fip.state)
+
+ # test update FloatingIp with None port_id
+ props = copy.deepcopy(fip.properties.data)
+ del(props['port_id'])
+ update_snippet = rsrc_defn.ResourceDefinition(fip.name, fip.type(),
+ stack.t.parse(stack,
+ props))
+ scheduler.TaskRunner(fip.update, update_snippet)()
+ self.assertEqual((fip.UPDATE, fip.COMPLETE), fip.state)
+
+ scheduler.TaskRunner(fip.delete)()
+ scheduler.TaskRunner(p.delete)()
+
+ self.m.VerifyAll()
+
class NeutronPortTest(HeatTestCase):