vmware-nsx/quantum/plugins/openvswitch/ovs_quantum_plugin.py
Brad Hall 9bab0960b6 Second round of packaging changes
This change condenses the directory structure to something more similar to
what we had before while producing similar packages.

It also introduces version.py which allows us to get the version from git tags
(or a fallback version if not available).

Fixes lp bug 889336
Fixes lp bug 888795

Change-Id: I86136bd9dbabb5eb1f8366ed665ed9b54f695124
2011-11-28 10:33:52 -08:00

199 lines
7.3 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 Nicira Networks, Inc.
# 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.
# @author: Somik Behera, Nicira Networks, Inc.
# @author: Brad Hall, Nicira Networks, Inc.
# @author: Dan Wendlandt, Nicira Networks, Inc.
import ConfigParser
import logging as LOG
from optparse import OptionParser
import os
import sys
from quantum.common import exceptions as q_exc
from quantum.common.config import find_config_file
from quantum.quantum_plugin_base import QuantumPluginBase
import quantum.db.api as db
import ovs_db
CONF_FILE = find_config_file(
{"config_file": "etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini"},
None, "ovs_quantum_plugin.ini")
LOG.basicConfig(level=LOG.WARN)
LOG.getLogger("ovs_quantum_plugin")
class VlanMap(object):
vlans = {}
def __init__(self):
for x in xrange(2, 4094):
self.vlans[x] = None
def set(self, vlan_id, network_id):
self.vlans[vlan_id] = network_id
def acquire(self, network_id):
for x in xrange(2, 4094):
if self.vlans[x] == None:
self.vlans[x] = network_id
# LOG.debug("VlanMap::acquire %s -> %s" % (x, network_id))
return x
raise Exception("No free vlans..")
def get(self, vlan_id):
return self.vlans[vlan_id]
def release(self, network_id):
for x in self.vlans.keys():
if self.vlans[x] == network_id:
self.vlans[x] = None
# LOG.debug("VlanMap::release %s" % (x))
return
LOG.error("No vlan found with network \"%s\"" % network_id)
class OVSQuantumPlugin(QuantumPluginBase):
def __init__(self, configfile=None):
config = ConfigParser.ConfigParser()
if configfile == None:
if os.path.exists(CONF_FILE):
configfile = CONF_FILE
else:
configfile = find_config(os.path.abspath(
os.path.dirname(__file__)))
if configfile == None:
raise Exception("Configuration file \"%s\" doesn't exist" %
(configfile))
LOG.debug("Using configuration file: %s" % configfile)
config.read(configfile)
LOG.debug("Config: %s" % config)
DB_NAME = config.get("DATABASE", "name")
DB_USER = config.get("DATABASE", "user")
DB_PASS = config.get("DATABASE", "pass")
DB_HOST = config.get("DATABASE", "host")
options = {"sql_connection": "mysql://%s:%s@%s/%s" % (DB_USER,
DB_PASS, DB_HOST, DB_NAME)}
db.configure_db(options)
self.vmap = VlanMap()
# Populate the map with anything that is already present in the
# database
vlans = ovs_db.get_vlans()
for x in vlans:
vlan_id, network_id = x
# LOG.debug("Adding already populated vlan %s -> %s"
# % (vlan_id, network_id))
self.vmap.set(vlan_id, network_id)
def get_all_networks(self, tenant_id):
nets = []
for x in db.network_list(tenant_id):
LOG.debug("Adding network: %s" % x.uuid)
nets.append(self._make_net_dict(str(x.uuid), x.name, None))
return nets
def _make_net_dict(self, net_id, net_name, ports):
res = {'net-id': net_id,
'net-name': net_name}
if ports:
res['net-ports'] = ports
return res
def create_network(self, tenant_id, net_name, **kwargs):
net = db.network_create(tenant_id, net_name)
LOG.debug("Created network: %s" % net)
vlan_id = self.vmap.acquire(str(net.uuid))
ovs_db.add_vlan_binding(vlan_id, str(net.uuid))
return self._make_net_dict(str(net.uuid), net.name, [])
def delete_network(self, tenant_id, net_id):
net = db.network_get(net_id)
# Verify that no attachments are plugged into the network
for port in db.port_list(net_id):
if port.interface_id:
raise q_exc.NetworkInUse(net_id=net_id)
net = db.network_destroy(net_id)
ovs_db.remove_vlan_binding(net_id)
self.vmap.release(net_id)
return self._make_net_dict(str(net.uuid), net.name, [])
def get_network_details(self, tenant_id, net_id):
net = db.network_get(net_id)
ports = self.get_all_ports(tenant_id, net_id)
return self._make_net_dict(str(net.uuid), net.name, ports)
def update_network(self, tenant_id, net_id, **kwargs):
net = db.network_update(net_id, tenant_id, **kwargs)
return self._make_net_dict(str(net.uuid), net.name, None)
def _make_port_dict(self, port_id, port_state, net_id, attachment):
return {'port-id': port_id,
'port-state': port_state,
'net-id': net_id,
'attachment': attachment}
def get_all_ports(self, tenant_id, net_id):
ids = []
ports = db.port_list(net_id)
for p in ports:
LOG.debug("Appending port: %s" % p.uuid)
d = self._make_port_dict(str(p.uuid), p.state, p.network_id,
p.interface_id)
ids.append(d)
return ids
def create_port(self, tenant_id, net_id, port_state=None, **kwargs):
LOG.debug("Creating port with network_id: %s" % net_id)
port = db.port_create(net_id, port_state)
return self._make_port_dict(str(port.uuid), port.state,
port.network_id, port.interface_id)
def delete_port(self, tenant_id, net_id, port_id):
port = db.port_destroy(port_id, net_id)
return self._make_port_dict(str(port.uuid), port.state,
port.network_id, port.interface_id)
def update_port(self, tenant_id, net_id, port_id, **kwargs):
"""
Updates the state of a port on the specified Virtual Network.
"""
LOG.debug("update_port() called\n")
port = db.port_get(port_id, net_id)
db.port_update(port_id, net_id, **kwargs)
return self._make_port_dict(str(port.uuid), port.state,
port.network_id, port.interface_id)
def get_port_details(self, tenant_id, net_id, port_id):
port = db.port_get(port_id, net_id)
return self._make_port_dict(str(port.uuid), port.state,
port.network_id, port.interface_id)
def plug_interface(self, tenant_id, net_id, port_id, remote_iface_id):
db.port_set_attachment(port_id, net_id, remote_iface_id)
def unplug_interface(self, tenant_id, net_id, port_id):
db.port_set_attachment(port_id, net_id, "")
def get_interface_details(self, tenant_id, net_id, port_id):
res = db.port_get(port_id, net_id)
return res.interface_id