Fill in trunk_details on port resource

This patch fills in the trunk_details field with trunk_id and
sub_ports, exposing trunk-related information on the ports
resource to consumers of the Neutron API.

Change-Id: I1678301734e7f945e6f0400e62970b908da77a71
Partially-implements: blueprint vlan-aware-vms
This commit is contained in:
Ryan Tidwell 2016-06-28 16:10:32 -07:00
parent 698e601364
commit 3f570567ad
3 changed files with 77 additions and 0 deletions

View File

@ -32,6 +32,8 @@ class Trunk(model_base.HasStandardAttributes, model_base.BASEV2,
backref=sa.orm.backref('trunk_port', lazy='joined', uselist=False,
cascade='delete'))
sub_ports = sa.orm.relationship('SubPort', lazy='joined', uselist=True)
class SubPort(model_base.BASEV2):

View File

@ -15,11 +15,13 @@
from oslo_log import log as logging
from oslo_utils import uuidutils
from neutron.api.v2 import attributes
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.db import api as db_api
from neutron.db import common_db_mixin
from neutron.db import db_base_plugin_common
from neutron.db import db_base_plugin_v2
from neutron.objects import base as objects_base
from neutron.objects import trunk as trunk_objects
from neutron.services import service_base
@ -30,12 +32,28 @@ from neutron.services.trunk import rules
LOG = logging.getLogger(__name__)
def _extend_port_trunk_details(core_plugin, port_res, port_db):
"""Add trunk details to a port."""
if port_db.trunk_port:
subports = [{'segmentation_id': x.segmentation_id,
'segmentation_type': x.segmentation_type,
'port_id': x.port_id}
for x in port_db.trunk_port.sub_ports]
trunk_details = {'trunk_id': port_db.trunk_port.id,
'sub_ports': subports}
port_res['trunk_details'] = trunk_details
return port_res
class TrunkPlugin(service_base.ServicePluginBase,
common_db_mixin.CommonDbMixin):
supported_extension_aliases = ["trunk", "trunk-details"]
def __init__(self):
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
attributes.PORTS, [_extend_port_trunk_details])
self._segmentation_types = {}
registry.notify(constants.TRUNK_PLUGIN, events.AFTER_INIT, self)
LOG.debug('Trunk plugin loaded')

View File

@ -0,0 +1,57 @@
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
#
# 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 tempest import test
from neutron.tests.tempest.api import test_trunk
class TestTrunkDetailsJSON(test_trunk.TrunkTestJSONBase):
extension = 'trunk-details'
@test.idempotent_id('f0bed24f-d36a-498b-b4e7-0d66e3fb7308')
def test_port_resource_trunk_details_no_subports(self):
trunk = self._create_trunk_with_network_and_parent([])
port = self.client.show_port(trunk['trunk']['port_id'])
expected_trunk_details = {'sub_ports': [],
'trunk_id': trunk['trunk']['id']}
observed_trunk_details = port['port'].get('trunk_details')
self.assertIsNotNone(observed_trunk_details)
self.assertEqual(expected_trunk_details,
observed_trunk_details)
@test.idempotent_id('544bcaf2-86fb-4930-93ab-ece1c3cc33df')
def test_port_resource_trunk_details_with_subport(self):
subport_network = self.create_network()
parent_port = self.create_port(subport_network)
subport_data = {'port_id': parent_port['id'],
'segmentation_type': 'vlan',
'segmentation_id': 2}
trunk = self._create_trunk_with_network_and_parent([subport_data])
port = self.client.show_port(trunk['trunk']['port_id'])
expected_trunk_details = {'sub_ports': [subport_data],
'trunk_id': trunk['trunk']['id']}
observed_trunk_details = port['port'].get('trunk_details')
self.assertIsNotNone(observed_trunk_details)
self.assertEqual(expected_trunk_details,
observed_trunk_details)
@test.idempotent_id('fe6d865f-1d5c-432e-b65d-904157172f24')
def test_port_resource_empty_trunk_details(self):
network = self.create_network()
port = self.create_port(network)
port = self.client.show_port(port['id'])
observed_trunk_details = port['port'].get('trunk_details')
self.assertIsNone(observed_trunk_details)