Publish segment id in port responses
In this patchset, attribute 'ipam_segment_id' is added to ports to contain the id of the segment where the port is bound in the case of a routed network. This new attribute will be used by the Nova scheduler to place an instance using the port in a host bound to the segment Change-Id: Ide13a7c53c5f4a33894f459c38924830ba583f98 Partially-Implements: blueprint routed-networks
This commit is contained in:
parent
b555eed7fa
commit
b35d7fa3cb
@ -86,6 +86,7 @@
|
|||||||
"get_port:binding:vif_details": "rule:admin_only",
|
"get_port:binding:vif_details": "rule:admin_only",
|
||||||
"get_port:binding:host_id": "rule:admin_only",
|
"get_port:binding:host_id": "rule:admin_only",
|
||||||
"get_port:binding:profile": "rule:admin_only",
|
"get_port:binding:profile": "rule:admin_only",
|
||||||
|
"get_port:ipam_segment_id": "rule:admin_only",
|
||||||
"update_port": "rule:admin_or_owner or rule:context_is_advsvc",
|
"update_port": "rule:admin_or_owner or rule:context_is_advsvc",
|
||||||
"update_port:device_owner": "not rule:network_device or rule:context_is_advsvc or rule:admin_or_network_owner",
|
"update_port:device_owner": "not rule:network_device or rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||||
"update_port:mac_address": "rule:admin_only or rule:context_is_advsvc",
|
"update_port:mac_address": "rule:admin_only or rule:context_is_advsvc",
|
||||||
|
@ -31,6 +31,7 @@ SEGMENT_ID = 'segment_id'
|
|||||||
NETWORK_TYPE = 'network_type'
|
NETWORK_TYPE = 'network_type'
|
||||||
PHYSICAL_NETWORK = 'physical_network'
|
PHYSICAL_NETWORK = 'physical_network'
|
||||||
SEGMENTATION_ID = 'segmentation_id'
|
SEGMENTATION_ID = 'segmentation_id'
|
||||||
|
IPAM_SEGMENT_ID = 'ipam_segment_id'
|
||||||
|
|
||||||
# Attribute Map
|
# Attribute Map
|
||||||
RESOURCE_ATTRIBUTE_MAP = {
|
RESOURCE_ATTRIBUTE_MAP = {
|
||||||
@ -73,6 +74,10 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||||||
'validate': {'type:uuid_or_none': None},
|
'validate': {'type:uuid_or_none': None},
|
||||||
'is_visible': True, },
|
'is_visible': True, },
|
||||||
},
|
},
|
||||||
|
attributes.PORTS: {
|
||||||
|
IPAM_SEGMENT_ID: {'allow_post': False, 'allow_put': False,
|
||||||
|
'is_visible': True},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,16 +45,23 @@ def _extend_port_dict_binding(plugin, port_res, port_db):
|
|||||||
return
|
return
|
||||||
|
|
||||||
value = ip_allocation.IP_ALLOCATION_IMMEDIATE
|
value = ip_allocation.IP_ALLOCATION_IMMEDIATE
|
||||||
if not port_res.get('fixed_ips'):
|
segment_id = None
|
||||||
# NOTE Only routed network ports have deferred allocation. Check if it
|
# TODO(Carl) eliminate this query entirely and use optimistic joins
|
||||||
# is routed by looking for subnets associated with segments.
|
|
||||||
object_session = session.Session.object_session(port_db)
|
object_session = session.Session.object_session(port_db)
|
||||||
query = object_session.query(models_v2.Subnet)
|
query = object_session.query(models_v2.Subnet)
|
||||||
query = query.filter_by(network_id=port_db.network_id)
|
query = query.filter_by(network_id=port_db.network_id)
|
||||||
query = query.filter(models_v2.Subnet.segment_id.isnot(None))
|
query = query.filter(models_v2.Subnet.segment_id.isnot(None))
|
||||||
|
ips = port_res.get('fixed_ips')
|
||||||
|
if not ips:
|
||||||
if query.count():
|
if query.count():
|
||||||
value = ip_allocation.IP_ALLOCATION_DEFERRED
|
value = ip_allocation.IP_ALLOCATION_DEFERRED
|
||||||
|
else:
|
||||||
|
query = query.filter_by(id=ips[0]['subnet_id'])
|
||||||
|
routed_subnet = query.one_or_none()
|
||||||
|
if routed_subnet:
|
||||||
|
segment_id = routed_subnet[segment.SEGMENT_ID]
|
||||||
port_res[ip_allocation.IP_ALLOCATION] = value
|
port_res[ip_allocation.IP_ALLOCATION] = value
|
||||||
|
port_res[segment.IPAM_SEGMENT_ID] = segment_id
|
||||||
|
|
||||||
|
|
||||||
class Plugin(db.SegmentDbMixin, segment.SegmentPluginBase):
|
class Plugin(db.SegmentDbMixin, segment.SegmentPluginBase):
|
||||||
|
@ -86,6 +86,7 @@
|
|||||||
"get_port:binding:vif_details": "rule:admin_only",
|
"get_port:binding:vif_details": "rule:admin_only",
|
||||||
"get_port:binding:host_id": "rule:admin_only",
|
"get_port:binding:host_id": "rule:admin_only",
|
||||||
"get_port:binding:profile": "rule:admin_only",
|
"get_port:binding:profile": "rule:admin_only",
|
||||||
|
"get_port:ipam_segment_id": "rule:admin_only",
|
||||||
"update_port": "rule:admin_or_owner or rule:context_is_advsvc",
|
"update_port": "rule:admin_or_owner or rule:context_is_advsvc",
|
||||||
"update_port:device_owner": "not rule:network_device or rule:context_is_advsvc or rule:admin_or_network_owner",
|
"update_port:device_owner": "not rule:network_device or rule:context_is_advsvc or rule:admin_or_network_owner",
|
||||||
"update_port:mac_address": "rule:admin_only or rule:context_is_advsvc",
|
"update_port:mac_address": "rule:admin_only or rule:context_is_advsvc",
|
||||||
|
@ -720,7 +720,8 @@ class TestSegmentAwareIpam(SegmentTestCase):
|
|||||||
arg_list=(portbindings.HOST_ID,),
|
arg_list=(portbindings.HOST_ID,),
|
||||||
**{portbindings.HOST_ID: 'fakehost'})
|
**{portbindings.HOST_ID: 'fakehost'})
|
||||||
res = self.deserialize(self.fmt, response)
|
res = self.deserialize(self.fmt, response)
|
||||||
self._validate_immediate_ip_allocation(res['port']['id'])
|
self._validate_immediate_ip_allocation(
|
||||||
|
res['port']['id'], segment_id=segments[1]['segment']['id'])
|
||||||
|
|
||||||
# Since host mapped to middle segment, IP must come from middle subnet
|
# Since host mapped to middle segment, IP must come from middle subnet
|
||||||
self._assert_one_ip_in_subnet(response, subnets[1]['subnet']['cidr'])
|
self._assert_one_ip_in_subnet(response, subnets[1]['subnet']['cidr'])
|
||||||
@ -909,7 +910,7 @@ class TestSegmentAwareIpam(SegmentTestCase):
|
|||||||
ips = response['port']['fixed_ips']
|
ips = response['port']['fixed_ips']
|
||||||
self.assertEqual(0, len(ips))
|
self.assertEqual(0, len(ips))
|
||||||
|
|
||||||
def _validate_immediate_ip_allocation(self, port_id):
|
def _validate_immediate_ip_allocation(self, port_id, segment_id=None):
|
||||||
request = self.new_show_request('ports', port_id)
|
request = self.new_show_request('ports', port_id)
|
||||||
response = self.deserialize(self.fmt, request.get_response(self.api))
|
response = self.deserialize(self.fmt, request.get_response(self.api))
|
||||||
|
|
||||||
@ -917,6 +918,8 @@ class TestSegmentAwareIpam(SegmentTestCase):
|
|||||||
response['port'][ip_allocation.IP_ALLOCATION])
|
response['port'][ip_allocation.IP_ALLOCATION])
|
||||||
ips = response['port']['fixed_ips']
|
ips = response['port']['fixed_ips']
|
||||||
self.assertNotEqual(0, len(ips))
|
self.assertNotEqual(0, len(ips))
|
||||||
|
self.assertEqual(segment_id,
|
||||||
|
response['port'][ext_segment.IPAM_SEGMENT_ID])
|
||||||
|
|
||||||
def _create_deferred_ip_port(self, network):
|
def _create_deferred_ip_port(self, network):
|
||||||
response = self._create_port(self.fmt,
|
response = self._create_port(self.fmt,
|
||||||
|
Loading…
Reference in New Issue
Block a user