Associate floating IP with router interface
This change will create a dependency from a FloatingIP to a RouterInterface in this template which interfaces with the same subnet that this FloatingIP's port is assigned to. It would be preferable to add the dependency based on matching FloatingIP floating_network_id and Router external_gateway_info network, but there is a valid use-case for the Router being external to the template, so the dependency is matched on the internal subnet instead, which is available from the RouterInterface property. Change-Id: Iedff00b382b4fcda741ca5c9b4adc23b176ec48c Closes-Bug: #1299259
This commit is contained in:
parent
68f78c8edb
commit
5c158edac6
@ -14,6 +14,7 @@
|
||||
from heat.engine import attributes
|
||||
from heat.engine import properties
|
||||
from heat.engine.resources.neutron import neutron
|
||||
from heat.engine.resources.neutron import port
|
||||
from heat.engine.resources.neutron import router
|
||||
from heat.engine import support
|
||||
|
||||
@ -93,9 +94,10 @@ class FloatingIP(neutron.NeutronResource):
|
||||
|
||||
def add_dependencies(self, deps):
|
||||
super(FloatingIP, self).add_dependencies(deps)
|
||||
|
||||
for resource in self.stack.itervalues():
|
||||
# depend on any RouterGateway in this template with the same
|
||||
# network_id as this floating_network_id
|
||||
for resource in self.stack.itervalues():
|
||||
if resource.has_interface('OS::Neutron::RouterGateway'):
|
||||
gateway_network = resource.properties.get(
|
||||
router.RouterGateway.NETWORK) or resource.properties.get(
|
||||
@ -106,6 +108,31 @@ class FloatingIP(neutron.NeutronResource):
|
||||
if gateway_network == floating_network:
|
||||
deps += (self, resource)
|
||||
|
||||
# depend on any RouterInterface in this template which interfaces
|
||||
# with the same subnet that this floating IP's port is assigned
|
||||
# to
|
||||
elif resource.has_interface('OS::Neutron::RouterInterface'):
|
||||
|
||||
def port_on_subnet(resource, subnet):
|
||||
if not resource.has_interface('OS::Neutron::Port'):
|
||||
return False
|
||||
for fixed_ip in resource.properties.get(
|
||||
port.Port.FIXED_IPS):
|
||||
|
||||
port_subnet = (
|
||||
fixed_ip.properties.get(port.Port.FIXED_IP_SUBNET)
|
||||
or fixed_ip.get(port.Port.FIXED_IP_SUBNET_ID))
|
||||
return subnet == port_subnet
|
||||
return False
|
||||
|
||||
interface_subnet = (
|
||||
resource.properties.get(router.RouterInterface.SUBNET) or
|
||||
resource.properties.get(router.RouterInterface.SUBNET_ID))
|
||||
for d in deps.required_by(self):
|
||||
if port_on_subnet(d, interface_subnet):
|
||||
deps += (self, resource)
|
||||
break
|
||||
|
||||
def validate(self):
|
||||
super(FloatingIP, self).validate()
|
||||
self._validate_depr_property_required(
|
||||
|
@ -269,6 +269,13 @@ neutron_floating_template_deprecated = '''
|
||||
"router": {
|
||||
"Type": "OS::Neutron::Router"
|
||||
},
|
||||
"router_interface": {
|
||||
"Type": "OS::Neutron::RouterInterface",
|
||||
"Properties": {
|
||||
"router_id": { "Ref" : "router" },
|
||||
"subnet": "sub1234"
|
||||
}
|
||||
},
|
||||
"gateway": {
|
||||
"Type": "OS::Neutron::RouterGateway",
|
||||
"Properties": {
|
||||
@ -312,6 +319,13 @@ neutron_floating_template = '''
|
||||
"router": {
|
||||
"Type": "OS::Neutron::Router"
|
||||
},
|
||||
"router_interface": {
|
||||
"Type": "OS::Neutron::RouterInterface",
|
||||
"Properties": {
|
||||
"router_id": { "Ref" : "router" },
|
||||
"subnet": "sub1234"
|
||||
}
|
||||
},
|
||||
"gateway": {
|
||||
"Type": "OS::Neutron::RouterGateway",
|
||||
"Properties": {
|
||||
@ -1927,6 +1941,9 @@ class NeutronFloatingIPTest(HeatTestCase):
|
||||
|
||||
self.assertIn(stack['floating_ip'], deps)
|
||||
|
||||
deps = stack.dependencies[stack['router_interface']]
|
||||
self.assertIn(stack['floating_ip'], deps)
|
||||
|
||||
fip = stack['floating_ip']
|
||||
scheduler.TaskRunner(fip.create)()
|
||||
self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
|
||||
|
Loading…
Reference in New Issue
Block a user