Skip to content

Commit 0d78a25

Browse files
Jenkinsopenstack-gerrit
Jenkins
authored andcommitted
Merge "Replace binding:capabilities with binding:vif_details"
2 parents 8a70bfd + be8a068 commit 0d78a25

28 files changed

+231
-79
lines changed

etc/policy.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"get_port": "rule:admin_or_owner",
5353
"get_port:queue_id": "rule:admin_only",
5454
"get_port:binding:vif_type": "rule:admin_only",
55-
"get_port:binding:capabilities": "rule:admin_only",
55+
"get_port:binding:vif_details": "rule:admin_only",
5656
"get_port:binding:host_id": "rule:admin_only",
5757
"get_port:binding:profile": "rule:admin_only",
5858
"get_port:binding:vnic_type": "rule:admin_or_owner",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2+
#
3+
# Copyright 2014 OpenStack Foundation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
#
17+
18+
"""ml2 binding:vif_details
19+
20+
Revision ID: 50d5ba354c23
21+
Revises: 27cc183af192
22+
Create Date: 2014-02-11 23:21:59.577972
23+
24+
"""
25+
26+
# revision identifiers, used by Alembic.
27+
revision = '50d5ba354c23'
28+
down_revision = '27cc183af192'
29+
30+
# Change to ['*'] if this migration applies to all plugins
31+
32+
migration_for_plugins = [
33+
'neutron.plugins.ml2.plugin.Ml2Plugin'
34+
]
35+
36+
from alembic import op
37+
import sqlalchemy as sa
38+
39+
from neutron.db import migration
40+
41+
42+
def upgrade(active_plugins=None, options=None):
43+
if not migration.should_run(active_plugins, migration_for_plugins):
44+
return
45+
46+
op.add_column('ml2_port_bindings',
47+
sa.Column('vif_details', sa.String(length=4095),
48+
nullable=False, server_default=''))
49+
op.drop_column('ml2_port_bindings', 'cap_port_filter')
50+
51+
52+
def downgrade(active_plugins=None, options=None):
53+
if not migration.should_run(active_plugins, migration_for_plugins):
54+
return
55+
56+
op.add_column('ml2_port_bindings',
57+
sa.Column('cap_port_filter', sa.Boolean(),
58+
nullable=False, server_default=False))
59+
op.drop_column('ml2_port_bindings', 'vif_details')

neutron/extensions/portbindings.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,27 @@
2222
VNIC_TYPE = 'binding:vnic_type'
2323
# The service will return the vif type for the specific port.
2424
VIF_TYPE = 'binding:vif_type'
25+
# The service may return a dictionary containing additional
26+
# information needed by the interface driver. The set of items
27+
# returned may depend on the value of VIF_TYPE.
28+
VIF_DETAILS = 'binding:vif_details'
2529
# In some cases different implementations may be run on different hosts.
2630
# The host on which the port will be allocated.
2731
HOST_ID = 'binding:host_id'
2832
# The profile will be a dictionary that enables the application running
2933
# on the specific host to pass and receive vif port specific information to
3034
# the plugin.
3135
PROFILE = 'binding:profile'
32-
# The capabilities will be a dictionary that enables pass information about
33-
# functionalies neutron provides. The following value should be provided.
36+
37+
# The keys below are used in the VIF_DETAILS attribute to convey
38+
# information to the VIF driver.
39+
40+
# TODO(rkukura): Replace CAP_PORT_FILTER, which nova no longer
41+
# understands, with the new set of VIF security details to be used in
42+
# the VIF_DETAILS attribute.
43+
#
3444
# - port_filter : Boolean value indicating Neutron provides port filtering
3545
# features such as security group and anti MAC/IP spoofing
36-
CAPABILITIES = 'binding:capabilities'
3746
CAP_PORT_FILTER = 'port_filter'
3847

3948
VIF_TYPE_UNBOUND = 'unbound'
@@ -63,6 +72,10 @@
6372
'default': attributes.ATTR_NOT_SPECIFIED,
6473
'enforce_policy': True,
6574
'is_visible': True},
75+
VIF_DETAILS: {'allow_post': False, 'allow_put': False,
76+
'default': attributes.ATTR_NOT_SPECIFIED,
77+
'enforce_policy': True,
78+
'is_visible': True},
6679
VNIC_TYPE: {'allow_post': True, 'allow_put': True,
6780
'default': VNIC_NORMAL,
6881
'is_visible': True,
@@ -77,10 +90,6 @@
7790
'enforce_policy': True,
7891
'validate': {'type:dict_or_none': None},
7992
'is_visible': True},
80-
CAPABILITIES: {'allow_post': False, 'allow_put': False,
81-
'default': attributes.ATTR_NOT_SPECIFIED,
82-
'enforce_policy': True,
83-
'is_visible': True},
8493
}
8594
}
8695

@@ -112,7 +121,7 @@ def get_namespace(cls):
112121

113122
@classmethod
114123
def get_updated(cls):
115-
return "2012-11-14T10:00:00-00:00"
124+
return "2014-02-03T10:00:00-00:00"
116125

117126
def get_extended_resources(self, version):
118127
if version == "2.0":

neutron/plugins/bigswitch/plugin.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ def _extend_port_dict_binding(self, context, port):
300300
cfg_vif_type = override
301301
port[portbindings.VIF_TYPE] = cfg_vif_type
302302

303-
port[portbindings.CAPABILITIES] = {
303+
port[portbindings.VIF_DETAILS] = {
304+
# TODO(rkukura): Replace with new VIF security details
304305
portbindings.CAP_PORT_FILTER:
305306
'security-group' in self.supported_extension_aliases}
306307
return port

neutron/plugins/brocade/NeutronPlugin.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,8 @@ def _notify_port_updated(self, context, port):
478478
def _get_base_binding_dict(self):
479479
binding = {
480480
portbindings.VIF_TYPE: portbindings.VIF_TYPE_BRIDGE,
481-
portbindings.CAPABILITIES: {
481+
portbindings.VIF_DETAILS: {
482+
# TODO(rkukura): Replace with new VIF security details
482483
portbindings.CAP_PORT_FILTER:
483484
'security-group' in self.supported_extension_aliases}}
484485
return binding

neutron/plugins/linuxbridge/lb_neutron_plugin.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ def __init__(self):
255255
super(LinuxBridgePluginV2, self).__init__()
256256
self.base_binding_dict = {
257257
portbindings.VIF_TYPE: portbindings.VIF_TYPE_BRIDGE,
258-
portbindings.CAPABILITIES: {
258+
portbindings.VIF_DETAILS: {
259+
# TODO(rkukura): Replace with new VIF security details
259260
portbindings.CAP_PORT_FILTER:
260261
'security-group' in self.supported_extension_aliases}}
261262
self._parse_network_vlan_ranges()

neutron/plugins/midonet/plugin.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ def __init__(self):
234234

235235
self.base_binding_dict = {
236236
portbindings.VIF_TYPE: portbindings.VIF_TYPE_MIDONET,
237-
portbindings.CAPABILITIES: {
237+
portbindings.VIF_DETAILS: {
238+
# TODO(rkukura): Replace with new VIF security details
238239
portbindings.CAP_PORT_FILTER:
239240
'security-group' in self.supported_extension_aliases}}
240241

neutron/plugins/ml2/db.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ def ensure_port_binding(session, port_id):
6666
record = models.PortBinding(
6767
port_id=port_id,
6868
host='',
69-
vif_type=portbindings.VIF_TYPE_UNBOUND,
70-
cap_port_filter=False)
69+
vif_type=portbindings.VIF_TYPE_UNBOUND)
7170
session.add(record)
7271
return record
7372

neutron/plugins/ml2/driver_api.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,12 @@ def host_agents(self, agent_type):
246246
pass
247247

248248
@abstractmethod
249-
def set_binding(self, segment_id, vif_type, cap_port_filter):
249+
def set_binding(self, segment_id, vif_type, vif_details):
250250
"""Set the binding for the port.
251251
252252
:param segment_id: Network segment bound for the port.
253253
:param vif_type: The VIF type for the bound port.
254-
:param cap_port_filter: True if the bound port filters.
254+
:param vif_details: Dictionary with details for VIF driver.
255255
256256
Called by MechanismDriver.bind_port to indicate success and
257257
specify binding details to use for port. The segment_id must

neutron/plugins/ml2/driver_context.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# License for the specific language governing permissions and limitations
1414
# under the License.
1515

16+
from neutron.openstack.common import jsonutils
1617
from neutron.plugins.ml2 import db
1718
from neutron.plugins.ml2 import driver_api as api
1819

@@ -103,12 +104,8 @@ def host_agents(self, agent_type):
103104
filters={'agent_type': [agent_type],
104105
'host': [self._binding.host]})
105106

106-
def set_binding(self, segment_id, vif_type, cap_port_filter):
107-
# REVISIT(rkukura): Pass extensible list of capabilities? Move
108-
# vif_type and capabilities to methods on the bound mechanism
109-
# driver?
110-
107+
def set_binding(self, segment_id, vif_type, vif_details):
111108
# TODO(rkukura) Verify binding allowed, segment in network
112109
self._binding.segment = segment_id
113110
self._binding.vif_type = vif_type
114-
self._binding.cap_port_filter = cap_port_filter
111+
self._binding.vif_details = jsonutils.dumps(vif_details)

neutron/plugins/ml2/drivers/mech_agent.py

+70-15
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,19 @@ class AgentMechanismDriverBase(api.MechanismDriver):
3434
running on the port's host, and that agent to have connectivity to
3535
at least one segment of the port's network.
3636
37-
MechanismDrivers using this base class must pass the agent type
38-
and VIF type constants to __init__(), and must implement
37+
MechanismDrivers using this base class must pass the agent type to
38+
__init__(), and must implement try_to_bind_segment_for_agent() and
3939
check_segment_for_agent().
4040
"""
4141

42-
def __init__(self, agent_type, vif_type, cap_port_filter,
42+
def __init__(self, agent_type,
4343
supported_vnic_types=[portbindings.VNIC_NORMAL]):
4444
"""Initialize base class for specific L2 agent type.
4545
4646
:param agent_type: Constant identifying agent type in agents_db
47-
:param vif_type: Value for binding:vif_type to when bound
47+
:param supported_vnic_types: The binding:vnic_type values we can bind
4848
"""
4949
self.agent_type = agent_type
50-
self.vif_type = vif_type
51-
self.cap_port_filter = cap_port_filter
5250
self.supported_vnic_types = supported_vnic_types
5351

5452
def initialize(self):
@@ -69,10 +67,8 @@ def bind_port(self, context):
6967
LOG.debug(_("Checking agent: %s"), agent)
7068
if agent['alive']:
7169
for segment in context.network.network_segments:
72-
if self.check_segment_for_agent(segment, agent):
73-
context.set_binding(segment[api.ID],
74-
self.vif_type,
75-
self.cap_port_filter)
70+
if self.try_to_bind_segment_for_agent(context, segment,
71+
agent):
7672
LOG.debug(_("Bound using segment: %s"), segment)
7773
return
7874
else:
@@ -99,6 +95,25 @@ def unbind_port(self, context):
9995
{'port': context.current['id'],
10096
'network': context.network.current['id']})
10197

98+
@abstractmethod
99+
def try_to_bind_segment_for_agent(self, context, segment, agent):
100+
"""Try to bind with segment for agent.
101+
102+
:param context: PortContext instance describing the port
103+
:param segment: segment dictionary describing segment to bind
104+
:param agent: agents_db entry describing agent to bind
105+
:returns: True iff segment has been bound for agent
106+
107+
Called inside transaction during bind_port() so that derived
108+
MechanismDrivers can use agent_db data along with built-in
109+
knowledge of the corresponding agent's capabilities to attempt
110+
to bind to the specified network segment for the agent.
111+
112+
If the segment can be bound for the agent, this function must
113+
call context.set_binding() with appropriate values and then
114+
return True. Otherwise, it must return False.
115+
"""
116+
102117
@abstractmethod
103118
def check_segment_for_agent(self, segment, agent):
104119
"""Check if segment can be bound for agent.
@@ -107,9 +122,49 @@ def check_segment_for_agent(self, segment, agent):
107122
:param agent: agents_db entry describing agent to bind
108123
:returns: True iff segment can be bound for agent
109124
110-
Called inside transaction during bind_port() and
111-
validate_port_binding() so that derived MechanismDrivers can
112-
use agent_db data along with built-in knowledge of the
113-
corresponding agent's capabilities to determine whether or not
114-
the specified network segment can be bound for the agent.
125+
Called inside transaction during validate_port_binding() so
126+
that derived MechanismDrivers can use agent_db data along with
127+
built-in knowledge of the corresponding agent's capabilities
128+
to determine whether or not the specified network segment can
129+
be bound for the agent.
115130
"""
131+
132+
133+
@six.add_metaclass(ABCMeta)
134+
class SimpleAgentMechanismDriverBase(AgentMechanismDriverBase):
135+
"""Base class for simple drivers using an L2 agent.
136+
137+
The SimpleAgentMechanismDriverBase provides common code for
138+
mechanism drivers that integrate the ml2 plugin with L2 agents,
139+
where the binding:vif_type and binding:vif_details values are the
140+
same for all bindings. Port binding with this driver requires the
141+
driver's associated agent to be running on the port's host, and
142+
that agent to have connectivity to at least one segment of the
143+
port's network.
144+
145+
MechanismDrivers using this base class must pass the agent type
146+
and the values for binding:vif_type and binding:vif_details to
147+
__init__(). They must implement check_segment_for_agent() as
148+
defined in AgentMechanismDriverBase, which will be called during
149+
both binding establishment and validation.
150+
"""
151+
152+
def __init__(self, agent_type, vif_type, vif_details,
153+
supported_vnic_types=[portbindings.VNIC_NORMAL]):
154+
"""Initialize base class for specific L2 agent type.
155+
156+
:param agent_type: Constant identifying agent type in agents_db
157+
:param vif_type: Value for binding:vif_type when bound
158+
:param vif_details: Dictionary with details for VIF driver when bound
159+
:param supported_vnic_types: The binding:vnic_type values we can bind
160+
"""
161+
super(SimpleAgentMechanismDriverBase, self).__init__(
162+
agent_type, supported_vnic_types)
163+
self.vif_type = vif_type
164+
self.vif_details = vif_details
165+
166+
def try_to_bind_segment_for_agent(self, context, segment, agent):
167+
if self.check_segment_for_agent(segment, agent):
168+
context.set_binding(segment[api.ID],
169+
self.vif_type,
170+
self.vif_details)

neutron/plugins/ml2/drivers/mech_hyperv.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
LOG = log.getLogger(__name__)
2525

2626

27-
class HypervMechanismDriver(mech_agent.AgentMechanismDriverBase):
27+
class HypervMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
2828
"""Attach to networks using hyperv L2 agent.
2929
3030
The HypervMechanismDriver integrates the ml2 plugin with the
@@ -37,7 +37,7 @@ def __init__(self):
3737
super(HypervMechanismDriver, self).__init__(
3838
constants.AGENT_TYPE_HYPERV,
3939
portbindings.VIF_TYPE_HYPERV,
40-
False)
40+
{portbindings.CAP_PORT_FILTER: False})
4141

4242
def check_segment_for_agent(self, segment, agent):
4343
mappings = agent['configurations'].get('vswitch_mappings', {})

neutron/plugins/ml2/drivers/mech_linuxbridge.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
LOG = log.getLogger(__name__)
2323

2424

25-
class LinuxbridgeMechanismDriver(mech_agent.AgentMechanismDriverBase):
25+
class LinuxbridgeMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
2626
"""Attach to networks using linuxbridge L2 agent.
2727
2828
The LinuxbridgeMechanismDriver integrates the ml2 plugin with the
@@ -36,7 +36,7 @@ def __init__(self):
3636
super(LinuxbridgeMechanismDriver, self).__init__(
3737
constants.AGENT_TYPE_LINUXBRIDGE,
3838
portbindings.VIF_TYPE_BRIDGE,
39-
True)
39+
{portbindings.CAP_PORT_FILTER: True})
4040

4141
def check_segment_for_agent(self, segment, agent):
4242
mappings = agent['configurations'].get('interface_mappings', {})

neutron/plugins/ml2/drivers/mech_openvswitch.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
LOG = log.getLogger(__name__)
2323

2424

25-
class OpenvswitchMechanismDriver(mech_agent.AgentMechanismDriverBase):
25+
class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
2626
"""Attach to networks using openvswitch L2 agent.
2727
2828
The OpenvswitchMechanismDriver integrates the ml2 plugin with the
@@ -36,7 +36,7 @@ def __init__(self):
3636
super(OpenvswitchMechanismDriver, self).__init__(
3737
constants.AGENT_TYPE_OVS,
3838
portbindings.VIF_TYPE_OVS,
39-
True)
39+
{portbindings.CAP_PORT_FILTER: True})
4040

4141
def check_segment_for_agent(self, segment, agent):
4242
mappings = agent['configurations'].get('bridge_mappings', {})

0 commit comments

Comments
 (0)