L2-Adjacency support
The following patch adds the support for L2-Adjacency to indicate if there is L2 adjacency between the ports on a network. Partially-Implements: blueprint routed-networks Change-Id: Id2d4331568886bee52e78e1c138f1475cc89342b
This commit is contained in:
parent
451193c850
commit
6cb0c49857
58
neutron/extensions/l2_adjacency.py
Normal file
58
neutron/extensions/l2_adjacency.py
Normal file
@ -0,0 +1,58 @@
|
||||
# Copyright (c) 2016 NEC Technologies Ltd.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron.api import extensions
|
||||
|
||||
|
||||
L2_ADJACENCY = 'l2_adjacency'
|
||||
EXTENDED_ATTRIBUTES_2_0 = {
|
||||
'networks': {
|
||||
L2_ADJACENCY: {'allow_post': False,
|
||||
'allow_put': False,
|
||||
'is_visible': True}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class L2_adjacency(extensions.ExtensionDescriptor):
|
||||
"""Extension class supporting L2 Adjacency for Routed Networks
|
||||
|
||||
The following class is used by neutron's extension framework
|
||||
to provide metadata related to the L2 Adjacency for Neutron
|
||||
Routed Network, exposing the same to clients.
|
||||
No new resources have been defined by this extension.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "L2 Adjacency"
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
return "l2_adjacency"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return "Display L2 Adjacency for Neutron Networks."
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2016-04-12T16:00:00-00:00"
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
if version == "2.0":
|
||||
return EXTENDED_ATTRIBUTES_2_0
|
||||
else:
|
||||
return {}
|
@ -20,11 +20,22 @@ from neutron.api.v2 import attributes
|
||||
from neutron.db import common_db_mixin
|
||||
from neutron.db import models_v2
|
||||
from neutron.extensions import ip_allocation
|
||||
from neutron.extensions import l2_adjacency
|
||||
from neutron.extensions import segment
|
||||
from neutron import manager
|
||||
from neutron.services.segments import db
|
||||
|
||||
|
||||
def _extend_network_dict_binding(plugin, network_res, network_db):
|
||||
if not manager.NeutronManager.get_service_plugins().get('segments'):
|
||||
return
|
||||
|
||||
# TODO(carl_baldwin) Make this work with service subnets when it's a thing.
|
||||
is_adjacent = (not network_db.subnets
|
||||
or not network_db.subnets[0].segment_id)
|
||||
network_res[l2_adjacency.L2_ADJACENCY] = is_adjacent
|
||||
|
||||
|
||||
def _extend_subnet_dict_binding(plugin, subnet_res, subnet_db):
|
||||
subnet_res['segment_id'] = subnet_db.get('segment_id')
|
||||
|
||||
@ -50,9 +61,11 @@ class Plugin(db.SegmentDbMixin, segment.SegmentPluginBase):
|
||||
|
||||
_instance = None
|
||||
|
||||
supported_extension_aliases = ["segment", "ip_allocation"]
|
||||
supported_extension_aliases = ["segment", "ip_allocation", "l2_adjacency"]
|
||||
|
||||
def __init__(self):
|
||||
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
|
||||
attributes.NETWORKS, [_extend_network_dict_binding])
|
||||
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
|
||||
attributes.SUBNETS, [_extend_subnet_dict_binding])
|
||||
common_db_mixin.CommonDbMixin.register_dict_extend_funcs(
|
||||
|
@ -30,6 +30,7 @@ from neutron.db import db_base_plugin_v2
|
||||
from neutron.db import portbindings_db
|
||||
from neutron.db import segments_db
|
||||
from neutron.extensions import ip_allocation
|
||||
from neutron.extensions import l2_adjacency
|
||||
from neutron.extensions import portbindings
|
||||
from neutron.extensions import segment as ext_segment
|
||||
from neutron.plugins.common import constants as p_constants
|
||||
@ -670,6 +671,8 @@ class TestSegmentAwareIpam(SegmentTestCase):
|
||||
segment_id=segment['segment']['id'],
|
||||
ip_version=ip_version,
|
||||
cidr=cidr) as subnet:
|
||||
self._validate_l2_adjacency(network['network']['id'],
|
||||
is_adjacent=False)
|
||||
return network, segment, subnet
|
||||
|
||||
def _create_test_segments_with_subnets(self, num):
|
||||
@ -753,6 +756,8 @@ class TestSegmentAwareIpam(SegmentTestCase):
|
||||
network_id=network['network']['id'],
|
||||
physical_network='physnet')
|
||||
|
||||
self._validate_l2_adjacency(network['network']['id'], is_adjacent=True)
|
||||
|
||||
# Map the host to the segment
|
||||
self._setup_host_mappings([(segment['segment']['id'], 'fakehost')])
|
||||
|
||||
@ -877,6 +882,8 @@ class TestSegmentAwareIpam(SegmentTestCase):
|
||||
with self.subnet(network=network,
|
||||
segment_id=segment['segment']['id']) as subnet:
|
||||
self._validate_deferred_ip_allocation(port['port']['id'])
|
||||
self._validate_l2_adjacency(network['network']['id'],
|
||||
is_adjacent=False)
|
||||
# Try requesting an IP (but the only subnet is on a segment)
|
||||
data = {'port': {
|
||||
'fixed_ips': [{'subnet_id': subnet['subnet']['id']}]}}
|
||||
@ -888,6 +895,12 @@ class TestSegmentAwareIpam(SegmentTestCase):
|
||||
self.assertEqual(webob.exc.HTTPOk.code, response.status_int)
|
||||
self._assert_one_ip_in_subnet(response, subnet['subnet']['cidr'])
|
||||
|
||||
def _validate_l2_adjacency(self, network_id, is_adjacent):
|
||||
request = self.new_show_request('networks', network_id)
|
||||
response = self.deserialize(self.fmt, request.get_response(self.api))
|
||||
self.assertEqual(is_adjacent,
|
||||
response['network'][l2_adjacency.L2_ADJACENCY])
|
||||
|
||||
def _validate_deferred_ip_allocation(self, port_id):
|
||||
request = self.new_show_request('ports', port_id)
|
||||
response = self.deserialize(self.fmt, request.get_response(self.api))
|
||||
|
7
releasenotes/notes/l2_adjacency-e6e54e5ff9aad9b7.yaml
Normal file
7
releasenotes/notes/l2_adjacency-e6e54e5ff9aad9b7.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The new l2_adjacency extension adds an l2_adjacency field to the network,
|
||||
to indicate whether or not there is guaranteed L2 adjacency between the
|
||||
ports on that Network. Routed network implementations would typically set
|
||||
l2_adjacency to False.
|
Loading…
Reference in New Issue
Block a user