--- /dev/null
+# Copyright (c) 2012 OpenStack, LLC.
+#
+# 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.
+
+import logging
+
+from quantum.db import db_base_plugin_v2
+from quantum.db import models_v2
+from quantum.plugins.linuxbridge.db import l2network_db as cdb
+
+LOG = logging.getLogger(__name__)
+
+
+class LinuxBridgePluginV2(db_base_plugin_v2.QuantumDbPluginV2):
+ """
+ LinuxBridgePlugin provides support for Quantum abstractions
+ using LinuxBridge. A new VLAN is created for each network.
+ It relies on an agent to perform the actual bridge configuration
+ on each host.
+ """
+
+ def __init__(self):
+ cdb.initialize(base=models_v2.model_base.BASEV2)
+ LOG.debug("Linux Bridge Plugin initialization complete")
+
+ def create_network(self, context, network):
+ new_network = super(LinuxBridgePluginV2, self).create_network(context,
+ network)
+ try:
+ vlan_id = cdb.reserve_vlanid()
+ cdb.add_vlan_binding(vlan_id, new_network['id'])
+ except:
+ super(LinuxBridgePluginV2, self).delete_network(context,
+ new_network['id'])
+ raise
+
+ return new_network
+
+ def delete_network(self, context, id):
+ vlan_binding = cdb.get_vlan_binding(id)
+ cdb.release_vlanid(vlan_binding[const.VLANID])
+ cdb.remove_vlan_binding(id)
+ return super(LinuxBridgePluginV2, self).delete_network(context, id)
class LinuxBridgeQuantumAgent:
def __init__(self, br_name_prefix, physical_interface, polling_interval,
- reconnect_interval, root_helper):
+ reconnect_interval, root_helper, target_v2_api):
self.polling_interval = polling_interval
self.reconnect_interval = reconnect_interval
self.root_helper = root_helper
self.setup_linux_bridge(br_name_prefix, physical_interface)
self.db_connected = False
+ self.target_v2_api = target_v2_api
def setup_linux_bridge(self, br_name_prefix, physical_interface):
self.linux_br = LinuxBridge(br_name_prefix, physical_interface,
all_bindings = {}
for bind in port_binds:
- all_bindings[bind.uuid] = bind
- entry = {'network_id': bind.network_id, 'state': bind.state,
- 'op_status': bind.op_status, 'uuid': bind.uuid,
- 'interface_id': bind.interface_id}
- if bind.state == 'ACTIVE':
+ append_entry = False
+ if self.target_v2_api:
+ all_bindings[bind.id] = bind
+ entry = {'network_id': bind.network_id,
+ 'uuid': bind.id,
+ 'status': bind.status,
+ 'interface_id': bind.id}
+ append_entry = bind.admin_state_up
+ else:
+ all_bindings[bind.uuid] = bind
+ entry = {'network_id': bind.network_id, 'state': bind.state,
+ 'op_status': bind.op_status, 'uuid': bind.uuid,
+ 'interface_id': bind.interface_id}
+ append_entry = bind.state == 'ACTIVE'
+ if append_entry:
port_bindings.append(entry)
plugged_interfaces = []
ports_string = ""
for pb in port_bindings:
ports_string = "%s %s" % (ports_string, pb)
- if pb['interface_id']:
- vlan_id = str(vlan_bindings[pb['network_id']]['vlan_id'])
- if self.process_port_binding(pb['uuid'],
- pb['network_id'],
- pb['interface_id'],
- vlan_id):
- all_bindings[pb['uuid']].op_status = OP_STATUS_UP
- plugged_interfaces.append(pb['interface_id'])
+ port_id = pb['uuid']
+ interface_id = pb['interface_id']
+
+ vlan_id = str(vlan_bindings[pb['network_id']]['vlan_id'])
+ if self.process_port_binding(port_id,
+ pb['network_id'],
+ interface_id,
+ vlan_id):
+ if self.target_v2_api:
+ all_bindings[port_id].status = OP_STATUS_UP
+ else:
+ all_bindings[port_id].op_status = OP_STATUS_UP
+
+ plugged_interfaces.append(interface_id)
if old_port_bindings != port_bindings:
LOG.debug("Port-bindings: %s" % ports_string)
root_helper = conf.AGENT.root_helper
'Establish database connection and load models'
db_connection_url = conf.DATABASE.sql_connection
- LOG.info("Connecting to %s" % (db_connection_url))
-
plugin = LinuxBridgeQuantumAgent(br_name_prefix, physical_interface,
polling_interval, reconnect_interval,
- root_helper)
+ root_helper, conf.AGENT.target_v2_api)
LOG.info("Agent initialized successfully, now running... ")
plugin.daemon_loop(db_connection_url)
agent_opts = [
cfg.IntOpt('polling_interval', default=2),
cfg.StrOpt('root_helper', default='sudo'),
+ cfg.BoolOpt('target_v2_api', default=False),
]
from quantum.plugins.linuxbridge.common import config
from quantum.plugins.linuxbridge.common import exceptions as c_exc
from quantum.plugins.linuxbridge.db import l2network_models
+from quantum.plugins.linuxbridge.db import l2network_models_v2
LOG = logging.getLogger(__name__)
CONF_FILE = find_config_file({'plugin': 'linuxbridge'},
"linuxbridge_conf.ini")
CONF = config.parse(CONF_FILE)
+# The global variable for the database version model
+L2_MODEL = l2network_models
-def initialize():
+
+def initialize(base=None):
+ global L2_MODEL
options = {"sql_connection": "%s" % CONF.DATABASE.sql_connection}
options.update({"reconnect_interval": CONF.DATABASE.reconnect_interval})
+ if base:
+ options.update({"base": base})
+ L2_MODEL = l2network_models_v2
db.configure_db(options)
create_vlanids()
start = CONF.VLANS.vlan_start
end = CONF.VLANS.vlan_end
try:
- vlanid = session.query(l2network_models.VlanID).one()
+ vlanid = session.query(L2_MODEL.VlanID).one()
except exc.MultipleResultsFound:
"""
TODO (Sumit): Salvatore rightly points out that this will not handle
Per Dan's suggestion we just throw a server exception for now.
"""
current_start = (
- int(session.query(func.min(l2network_models.VlanID.vlan_id)).
+ int(session.query(func.min(L2_MODEL.VlanID.vlan_id)).
one()[0]))
current_end = (
- int(session.query(func.max(l2network_models.VlanID.vlan_id)).
+ int(session.query(func.max(L2_MODEL.VlanID.vlan_id)).
one()[0]))
if current_start != start or current_end != end:
LOG.debug("Old VLAN range %s-%s" % (current_start, current_end))
except exc.NoResultFound:
LOG.debug("Setting VLAN range to %s-%s" % (start, end))
while start <= end:
- vlanid = l2network_models.VlanID(start)
+ vlanid = L2_MODEL.VlanID(start)
session.add(vlanid)
start += 1
session.flush()
LOG.debug("get_all_vlanids() called")
session = db.get_session()
try:
- vlanids = (session.query(l2network_models.VlanID).
+ vlanids = (session.query(L2_MODEL.VlanID).
all())
return vlanids
except exc.NoResultFound:
LOG.debug("is_vlanid_used() called")
session = db.get_session()
try:
- vlanid = (session.query(l2network_models.VlanID).
+ vlanid = (session.query(L2_MODEL.VlanID).
filter_by(vlan_id=vlan_id).
one())
return vlanid["vlan_used"]
LOG.debug("release_vlanid() called")
session = db.get_session()
try:
- vlanid = (session.query(l2network_models.VlanID).
+ vlanid = (session.query(L2_MODEL.VlanID).
filter_by(vlan_id=vlan_id).
one())
vlanid["vlan_used"] = False
LOG.debug("delete_vlanid() called")
session = db.get_session()
try:
- vlanid = (session.query(l2network_models.VlanID).
+ vlanid = (session.query(L2_MODEL.VlanID).
filter_by(vlan_id=vlan_id).
one())
session.delete(vlanid)
LOG.debug("reserve_vlanid() called")
session = db.get_session()
try:
- rvlan = (session.query(l2network_models.VlanID).
+ rvlan = (session.query(L2_MODEL.VlanID).
first())
if not rvlan:
create_vlanids()
- rvlan = (session.query(l2network_models.VlanID).
+ rvlan = (session.query(L2_MODEL.VlanID).
filter_by(vlan_used=False).
first())
if not rvlan:
raise c_exc.VlanIDNotAvailable()
- rvlanid = (session.query(l2network_models.VlanID).
+ rvlanid = (session.query(L2_MODEL.VlanID).
filter_by(vlan_id=rvlan["vlan_id"]).
one())
rvlanid["vlan_used"] = True
LOG.debug("get_all_vlanids() called")
session = db.get_session()
try:
- vlanids = (session.query(l2network_models.VlanID).
+ vlanids = (session.query(L2_MODEL.VlanID).
filter_by(vlan_used=True).
all())
return vlanids
LOG.debug("get_all_vlan_bindings() called")
session = db.get_session()
try:
- bindings = (session.query(l2network_models.VlanBinding).
+ bindings = (session.query(L2_MODEL.VlanBinding).
all())
return bindings
except exc.NoResultFound:
LOG.debug("get_vlan_binding() called")
session = db.get_session()
try:
- binding = (session.query(l2network_models.VlanBinding).
+ binding = (session.query(L2_MODEL.VlanBinding).
filter_by(network_id=netid).
one())
return binding
LOG.debug("add_vlan_binding() called")
session = db.get_session()
try:
- binding = (session.query(l2network_models.VlanBinding).
+ binding = (session.query(L2_MODEL.VlanBinding).
filter_by(vlan_id=vlanid).
one())
raise c_exc.NetworkVlanBindingAlreadyExists(vlan_id=vlanid,
network_id=netid)
except exc.NoResultFound:
- binding = l2network_models.VlanBinding(vlanid, netid)
+ binding = L2_MODEL.VlanBinding(vlanid, netid)
session.add(binding)
session.flush()
return binding
LOG.debug("remove_vlan_binding() called")
session = db.get_session()
try:
- binding = (session.query(l2network_models.VlanBinding).
+ binding = (session.query(L2_MODEL.VlanBinding).
filter_by(network_id=netid).
one())
session.delete(binding)
LOG.debug("update_vlan_binding() called")
session = db.get_session()
try:
- binding = (session.query(l2network_models.VlanBinding).
+ binding = (session.query(L2_MODEL.VlanBinding).
filter_by(network_id=netid).
one())
if newvlanid:
--- /dev/null
+# Copyright (c) 2012 OpenStack, LLC.
+#
+# 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.
+
+import sqlalchemy as sa
+from sqlalchemy import orm
+
+from quantum.db import model_base
+
+
+class VlanID(model_base.BASEV2):
+ """Represents a vlan_id usage"""
+ __tablename__ = 'vlan_ids'
+
+ vlan_id = sa.Column(sa.Integer, nullable=False, primary_key=True)
+ vlan_used = sa.Column(sa.Boolean, nullable=False)
+
+ def __init__(self, vlan_id):
+ self.vlan_id = vlan_id
+ self.vlan_used = False
+
+ def __repr__(self):
+ return "<VlanID(%d,%s)>" % (self.vlan_id, self.vlan_used)
+
+
+class VlanBinding(model_base.BASEV2):
+ """Represents a binding of vlan_id to network_id"""
+ __tablename__ = 'vlan_bindings'
+
+ network_id = sa.Column(sa.String(36), sa.ForeignKey('networks.id'),
+ primary_key=True)
+ vlan_id = sa.Column(sa.Integer, nullable=False)
+
+ def __init__(self, vlan_id, network_id):
+ self.vlan_id = vlan_id
+ self.network_id = network_id
+
+ def __repr__(self):
+ return "<VlanBinding(%d,%s)>" % (self.vlan_id, self.network_id)