Add dependency for FIP if used network in port

Change-Id: I4fb108c46c950e588d630d2dcef925ce405b4e34
Closes-Bug: #1428434
This commit is contained in:
Sergey Kraynev 2015-03-27 11:55:14 +10:00 committed by Angus Salkeld
parent 449653e247
commit c9f32bfef0
3 changed files with 79 additions and 14 deletions

View File

@ -132,22 +132,34 @@ class FloatingIP(neutron.NeutronResource):
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):
fixed_ips = resource.properties.get(port.Port.FIXED_IPS)
if not fixed_ips:
p_net = (resource.properties.get(port.Port.NETWORK) or
resource.properties.get(port.Port.NETWORK_ID))
if p_net and p_net != 'None':
subnets = self.neutron().show_network(p_net)[
'network']['subnets']
return subnet in subnets
else:
for fixed_ip in resource.properties.get(
port.Port.FIXED_IPS):
port_subnet = (
fixed_ip.get(port.Port.FIXED_IP_SUBNET)
or fixed_ip.get(port.Port.FIXED_IP_SUBNET_ID))
return subnet == port_subnet
port_subnet = (
fixed_ip.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.graph()[self]:
if port_on_subnet(d, interface_subnet):
deps += (self, resource)
break
# during create we have only unresolved value for functions, so
# cat not use None value for building correct dependencies
if interface_subnet != 'None':
for d in deps.graph()[self]:
if port_on_subnet(d, interface_subnet):
deps += (self, resource)
break
# depend on Router with EXTERNAL_GATEWAY_NETWORK property
# this template with the same network_id as this
# floating_network_id

View File

@ -75,7 +75,10 @@ class Port(neutron.NeutronResource):
NETWORK: properties.Schema(
properties.Schema.STRING,
_('Network this port belongs to.'),
_('Network this port belongs to. If you plan to use current port '
'to assign Floating IP, you should specify %(fixed_ips)s '
'with %(subnet)s') % {'fixed_ips': FIXED_IPS,
'subnet': FIXED_IP_SUBNET},
support_status=support.SupportStatus(version='2014.2'),
constraints=[
constraints.CustomConstraint('neutron.network')

View File

@ -344,12 +344,23 @@ neutron_floating_no_assoc_template = '''
"Description" : "Template to test Neutron resources",
"Parameters" : {},
"Resources" : {
"network": {
"Type": "OS::Neutron::Net"
},
"subnet": {
"Type": "OS::Neutron::Subnet",
"Properties": {
"network": { "Ref" : "network" },
"cidr": "10.0.3.0/24",
}
},
"port_floating": {
"Type": "OS::Neutron::Port",
"Properties": {
"network": "xyz1234",
"network": { "Ref" : "network" },
"fixed_ips": [{
"subnet": "sub1234",
"subnet": { "Ref" : "subnet" },
"ip_address": "10.0.0.10"
}]
}
@ -368,7 +379,7 @@ neutron_floating_no_assoc_template = '''
"Type": "OS::Neutron::RouterInterface",
"Properties": {
"router_id": { "Ref" : "router" },
"subnet": "sub1234"
"subnet": { "Ref" : "subnet" }
}
},
"gateway": {
@ -2567,6 +2578,41 @@ class NeutronFloatingIPTest(common.HeatTestCase):
self.m.VerifyAll()
def test_floatip_port_dependency_subnet(self):
t = template_format.parse(neutron_floating_no_assoc_template)
stack = utils.parse_stack(t)
p_result = self.patchobject(cfn_funcs.ResourceRef, 'result')
p_result.return_value = 'subnet_uuid'
# check dependencies for fip resource
required_by = set(stack.dependencies.required_by(
stack['router_interface']))
self.assertIn(stack['floating_ip'], required_by)
def test_floatip_port_dependency_network(self):
t = template_format.parse(neutron_floating_no_assoc_template)
del t['Resources']['port_floating']['Properties']['fixed_ips']
stack = utils.parse_stack(t)
p_show = self.patchobject(neutronclient.Client, 'show_network')
p_show.return_value = {'network': {'subnets': ['subnet_uuid']}}
p_result = self.patchobject(cfn_funcs.ResourceRef, 'result',
autospec=True)
def return_uuid(self):
if self.args == 'network':
return 'net_uuid'
return 'subnet_uuid'
p_result.side_effect = return_uuid
# check dependencies for fip resource
required_by = set(stack.dependencies.required_by(
stack['router_interface']))
self.assertIn(stack['floating_ip'], required_by)
p_show.assert_called_once_with('net_uuid')
def test_floatip_port(self):
neutronV20.find_resourceid_by_name_or_id(
mox.IsA(neutronclient.Client),
@ -2650,6 +2696,10 @@ class NeutronFloatingIPTest(common.HeatTestCase):
self.m.ReplayAll()
t = template_format.parse(neutron_floating_no_assoc_template)
t['Resources']['port_floating']['Properties']['network'] = "xyz1234"
t['Resources']['port_floating']['Properties'][
'fixed_ips'][0]['subnet'] = "sub1234"
t['Resources']['router_interface']['Properties']['subnet'] = "sub1234"
stack = utils.parse_stack(t)
# check dependencies for fip resource