Merge "Only ports on routed networks are deferred"

This commit is contained in:
Jenkins 2016-07-26 19:50:31 +00:00 committed by Gerrit Code Review
commit 414f2ffc8d
2 changed files with 34 additions and 7 deletions

View File

@ -14,9 +14,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from sqlalchemy.orm import session
from neutron.api.v2 import attributes from neutron.api.v2 import attributes
from neutron.db import common_db_mixin from neutron.db import common_db_mixin
from neutron.db import models_v2
from neutron.extensions import ip_allocation from neutron.extensions import ip_allocation
from neutron.extensions import segment from neutron.extensions import segment
from neutron import manager from neutron import manager
@ -31,9 +33,15 @@ def _extend_port_dict_binding(plugin, port_res, port_db):
if not manager.NeutronManager.get_service_plugins().get('segments'): if not manager.NeutronManager.get_service_plugins().get('segments'):
return return
if port_res.get('fixed_ips'):
value = ip_allocation.IP_ALLOCATION_IMMEDIATE value = ip_allocation.IP_ALLOCATION_IMMEDIATE
else: if not port_res.get('fixed_ips'):
# NOTE Only routed network ports have deferred allocation. Check if it
# is routed by looking for subnets associated with segments.
object_session = session.Session.object_session(port_db)
query = object_session.query(models_v2.Subnet)
query = query.filter_by(network_id=port_db.network_id)
query = query.filter(models_v2.Subnet.segment_id.isnot(None))
if query.count():
value = ip_allocation.IP_ALLOCATION_DEFERRED value = ip_allocation.IP_ALLOCATION_DEFERRED
port_res[ip_allocation.IP_ALLOCATION] = value port_res[ip_allocation.IP_ALLOCATION] = value

View File

@ -830,6 +830,24 @@ class TestSegmentAwareIpam(SegmentTestCase):
# Gets bad request because there are no eligible subnets. # Gets bad request because there are no eligible subnets.
self.assertEqual(webob.exc.HTTPBadRequest.code, response.status_int) self.assertEqual(webob.exc.HTTPBadRequest.code, response.status_int)
def test_port_without_ip_not_deferred(self):
"""Ports without addresses on non-routed networks are not deferred"""
with self.network() as network:
pass
# Create a bound port with no IP address (since there is no subnet)
response = self._create_port(self.fmt,
net_id=network['network']['id'],
tenant_id=network['network']['tenant_id'],
arg_list=(portbindings.HOST_ID,),
**{portbindings.HOST_ID: 'fakehost'})
port = self.deserialize(self.fmt, response)
request = self.new_show_request('ports', port['port']['id'])
response = self.deserialize(self.fmt, request.get_response(self.api))
self.assertEqual(ip_allocation.IP_ALLOCATION_IMMEDIATE,
response['port'][ip_allocation.IP_ALLOCATION])
def test_port_update_is_host_aware(self): def test_port_update_is_host_aware(self):
"""Binding information is provided, subnets on segments""" """Binding information is provided, subnets on segments"""
with self.network() as network: with self.network() as network:
@ -847,11 +865,11 @@ class TestSegmentAwareIpam(SegmentTestCase):
arg_list=(portbindings.HOST_ID,), arg_list=(portbindings.HOST_ID,),
**{portbindings.HOST_ID: 'fakehost'}) **{portbindings.HOST_ID: 'fakehost'})
port = self.deserialize(self.fmt, response) port = self.deserialize(self.fmt, response)
self._validate_deferred_ip_allocation(port['port']['id'])
# Create the subnet and try to update the port to get an IP # Create the subnet and try to update the port to get an IP
with self.subnet(network=network, with self.subnet(network=network,
segment_id=segment['segment']['id']) as subnet: segment_id=segment['segment']['id']) as subnet:
self._validate_deferred_ip_allocation(port['port']['id'])
# Try requesting an IP (but the only subnet is on a segment) # Try requesting an IP (but the only subnet is on a segment)
data = {'port': { data = {'port': {
'fixed_ips': [{'subnet_id': subnet['subnet']['id']}]}} 'fixed_ips': [{'subnet_id': subnet['subnet']['id']}]}}
@ -889,8 +907,6 @@ class TestSegmentAwareIpam(SegmentTestCase):
ips = port['port']['fixed_ips'] ips = port['port']['fixed_ips']
self.assertEqual(0, len(ips)) self.assertEqual(0, len(ips))
self._validate_deferred_ip_allocation(port['port']['id'])
return port return port
def test_port_update_deferred_allocation(self): def test_port_update_deferred_allocation(self):
@ -901,6 +917,7 @@ class TestSegmentAwareIpam(SegmentTestCase):
self._setup_host_mappings([(segment['segment']['id'], 'fakehost')]) self._setup_host_mappings([(segment['segment']['id'], 'fakehost')])
port = self._create_deferred_ip_port(network) port = self._create_deferred_ip_port(network)
self._validate_deferred_ip_allocation(port['port']['id'])
# Try requesting an IP (but the only subnet is on a segment) # Try requesting an IP (but the only subnet is on a segment)
data = {'port': {portbindings.HOST_ID: 'fakehost'}} data = {'port': {portbindings.HOST_ID: 'fakehost'}}
@ -980,6 +997,7 @@ class TestSegmentAwareIpam(SegmentTestCase):
network, segment, subnet = self._create_test_segment_with_subnet() network, segment, subnet = self._create_test_segment_with_subnet()
port = self._create_deferred_ip_port(network) port = self._create_deferred_ip_port(network)
self._validate_deferred_ip_allocation(port['port']['id'])
# Try requesting an IP (but the only subnet is on a segment) # Try requesting an IP (but the only subnet is on a segment)
data = {'port': {portbindings.HOST_ID: 'fakehost'}} data = {'port': {portbindings.HOST_ID: 'fakehost'}}
@ -998,6 +1016,7 @@ class TestSegmentAwareIpam(SegmentTestCase):
network, segments, _s = self._create_test_segments_with_subnets(2) network, segments, _s = self._create_test_segments_with_subnets(2)
port = self._create_deferred_ip_port(network) port = self._create_deferred_ip_port(network)
self._validate_deferred_ip_allocation(port['port']['id'])
# This host is bound to multiple segments # This host is bound to multiple segments
self._setup_host_mappings([(segments[0]['segment']['id'], 'fakehost'), self._setup_host_mappings([(segments[0]['segment']['id'], 'fakehost'),