Merge "Implementation of the BP services-insertion-wrapper inside the Cisco Plugin"

This commit is contained in:
Jenkins 2011-12-14 00:56:21 +00:00 committed by Gerrit Code Review
commit 47767d4f52
10 changed files with 816 additions and 0 deletions

View File

@ -94,6 +94,17 @@ def network_list(tenant_id):
all()
def network_id(net_name):
session = get_session()
try:
return session.query(models.Network).\
options(joinedload(models.Network.ports)). \
filter_by(name=net_name).\
all()
except exc.NoResultFound, e:
raise q_exc.NetworkNotFound(net_name=net_name)
def network_get(net_id):
session = get_session()
try:

View File

@ -26,6 +26,7 @@ import logging as LOG
import quantum.plugins.cisco.db.api as db
import quantum.plugins.cisco.db.nexus_db as ndb
import quantum.plugins.cisco.db.ucs_db as udb
import quantum.plugins.cisco.db.services_db as sdb
def initialize():

View File

@ -0,0 +1,78 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011, Cisco Systems, Inc.
#
# 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: Edgar Magana, Cisco Systems, Inc.
import logging as LOG
from sqlalchemy.orm import exc
import quantum.plugins.cisco.db.api as db
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
from quantum.plugins.cisco.db import services_models
def get_all_services_bindings():
"""Lists all the services bindings"""
LOG.debug("get_all_services_bindings() called")
session = db.get_session()
try:
bindings = session.query(services_models.ServicesBinding).\
all()
return bindings
except exc.NoResultFound:
return []
def get_service_bindings(service_id):
"""Lists services bindings for a service_id"""
LOG.debug("get_service_bindings() called")
session = db.get_session()
try:
bindings = session.query(services_models.ServicesBinding).\
filter_by(service_id=service_id).\
one()
return bindings
except exc.NoResultFound:
return []
def add_services_binding(service_id, mngnet_id, nbnet_id, sbnet_id):
"""Adds a services binding"""
LOG.debug("add_services_binding() called")
session = db.get_session()
binding = services_models.ServicesBinding(service_id, mngnet_id, \
nbnet_id, sbnet_id)
session.add(binding)
session.flush()
return binding
def remove_services_binding(service_id):
"""Removes a services binding"""
LOG.debug("remove_services_binding() called")
session = db.get_session()
try:
binding = session.query(services_models.ServicesBinding).\
filter_by(service_id=service_id).\
all()
for bind in binding:
session.delete(bind)
session.flush()
return binding
except exc.NoResultFound:
pass

View File

@ -0,0 +1,42 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011, Cisco Systems, Inc.
#
# 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: Edgar Magana, Cisco Systems, Inc.
from sqlalchemy import Column, Integer, String
from quantum.plugins.cisco.db.l2network_models import L2NetworkBase
from quantum.plugins.cisco.db.models import BASE
class ServicesBinding(BASE, L2NetworkBase):
"""Represents a binding of L2 services to networks"""
__tablename__ = 'services_bindings'
id = Column(Integer, primary_key=True, autoincrement=True)
service_id = Column(String(255))
mngnet_id = Column(String(255))
nbnet_id = Column(String(255))
sbnet_id = Column(String(255))
def __init__(self, service_id, mngnet_id, nbnet_id, sbnet_id):
self.service_id = service_id
self.mngnet_id = mngnet_id
self.nbnet_id = nbnet_id
self.sbnet_id = sbnet_id
def __repr__(self):
return "<ServicesBinding (%s,%d)>" % \
(self.service_id, self.mngnet_id, self.nbnet_id, self.sbnet_id)

View File

@ -0,0 +1,70 @@
=========================================================================================
README: L2 Network Services Insertion Utility
=========================================================================================
:Authors: Edgar Magana, Mani Ramasamy, Ram Durairaj
:Collaborators: Deepak Khanorkar, Sumit Naiksatam, Nat Chidambaram, Dan Wendlandt
:Contact: netstack@lists.launchpad.net
:Web site: https://blueprints.launchpad.net/quantum/+spec/services-insertion-wrapper
Introduction
------------
This utility offers a simplify way to insert and remove network services
in the path of the traffic to the server VMs, by splitting the network into two,
and having the service bridge between the two, in the process applying the service.
This model is called In-Path (Bump in the Wire)
Pre-requisites
--------------
This integration uses Quantum APIs offered on diablo realease and Nova compute
functionality, basically to create new service instances.
Instructions
------------------------------------------------------
This utility offer four functionalities:
1. insert_inpath_service <tenant_id> <service_image_id>
<management_net_name> <northbound_net_name> <southbound_net_name>
Creates two networks and insert a service vm between them bridging the traffic
path. It also creates a management network to access the service configuration.
2. delete_service <tenant_id> <service_instance_id>
Deletes the service prevopusly inserted as well as the network dependencies.
connect_vm <tenant_id> <vm_image_id> <service_instance_id>
Instanciate a VM which is connected to the southbound network created by
insert_inpath_service. Facilitates the connections of server vms into the
tenant's network.
4. disconnect_vm <vm_instance_id>
Disconnect from the southbound network and terminates the server vm.
Example
------------------------------------------------------
Let's insert a Firewall service between northbound and southbound networks,
the management network will be called mng_net:
#PYTHONPATH=. python quantum/services/service_insertion.py insert_inpath_service
naas ami-00000029 mng_net northnet southnet
"ami-00000029" is the reference id provided by Glance for the Firewall image
service instance id: i-00000091
Now, we can connect a fresh web server in to the southbound network with:
#PYTHONPATH=. python quantum/services/service_insertion.py connect_vm
naas ami-0000002b i-00000091
"ami-0000002b" is the reference id provided by Glace for the Web Server image
and "i-00000091" is the instance id provided by Nova for the FW service instance
previously created.
server instance id: i-00000092
If we want to disconnect and shutdown the vm instance server:
#PYTHONPATH=. python quantum/plugins/cisco/services/service_insertion.py disconnect_vm i-00000092
We can delete the service instance and the network configuration with:
#PYTHONPATH=. python quantum/plugins/cisco/services/service_insertion.py delete_service naas i-00000091
Caveats
------------------------------------------------------
nova-compute service should be running in the same server that Quantum.
Nova API calls will be implemented in the next release (essex-3)

View File

@ -0,0 +1,19 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 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.
#
# @author: Edgar Magana, Cisco Systems
"""
L2 Network Services Insertion Utility
"""

View File

@ -0,0 +1,318 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, 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: Edgar Magana, Cisco Systems
#
"""
Network Library to insert services using Quantum APIs
Currently has four functionalities:
1. insert_inpath_service <tenant_id> <service_image_id>
<management_net_name> <northbound_net_name> <southbound_net_name>
2. delete_service <tenant_id> <service_instance_id>
3. connect_vm <tenant_id> <vm_image_id> <service_instance_id>
4. disconnect_vm <vm_instance_id>
"""
import logging
import logging.handlers
import os
import subprocess
import re
import sys
from optparse import OptionParser
from quantum.client import Client
from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.db import l2network_db as l2db
from quantum.plugins.cisco.db import services_db as sdb
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.services import services_constants as servconts
from quantum.plugins.cisco.services import services_logistics as servlogcs
LOG = logging.getLogger(__name__)
def insert_inpath_service(tenant_id, service_image_id,
management_net_name, northbound_net_name,
southbound_net_name, *args):
"""Inserting a network service between two networks"""
print ("Creating Network for Services and Servers")
service_logic = servlogcs.ServicesLogistics()
net_list = {}
multiport_net_list = []
networks_name_list = [management_net_name, northbound_net_name, \
southbound_net_name]
client = Client(HOST, PORT, USE_SSL, format='json', tenant=tenant_id)
for net in networks_name_list:
data = {servconts.NETWORK: {servconts.NAME: net}}
net_list[net] = client.create_network(data)
net_list[net][servconts.PORTS] = []
LOG.debug("Network %s Created with ID: %s " % (net, \
net_list[net][servconts.NETWORK][servconts.ID]))
print "Completed"
print ("Creating Ports on Services and Server Networks")
LOG.debug("Operation 'create_port' executed.")
if not service_logic.verify_plugin(const.UCS_PLUGIN):
for net in networks_name_list:
net_list[net][servconts.PORTS].append
(client.create_port
(net_list[net][servconts.NETWORK][servconts.ID]))
LOG.debug("Operation 'create_port' executed.")
else:
for net in networks_name_list:
nets = net_list[net][servconts.NETWORK][servconts.ID]
multiport_net_list.append(nets)
data = create_multiport(tenant_id, multiport_net_list)
net_idx = 0
for net in networks_name_list:
port_id = data[servconts.PORTS][net_idx][servconts.ID]
net_list[net][servconts.PORTS].append(port_id)
LOG.debug("Port UUID: %s on network: %s" % \
(data[servconts.PORTS][net_idx][servconts.ID], net))
net_idx = net_idx + 1
print "Completed"
try:
create_vm_args = []
create_vm_args.append(servconts.CREATE_VM_CMD)
create_vm_args.append(service_image_id)
print ("Creating VM with image: %s" % (service_image_id))
process = subprocess.Popen(create_vm_args, stdout=subprocess.PIPE)
result = process.stdout.readlines()
tokens = re.search("i-[a-f0-9]*", str(result[1]))
service_vm_name = tokens.group(0)
print ("Image: %s instantiated successfully" % (service_vm_name))
except Exception as exc:
print exc
service_logic.image_status(service_vm_name)
print "Completed"
print "Attaching Ports To VM Service interfaces"
try:
idx = 0
for net in networks_name_list:
network_id = net_list[net][servconts.NETWORK][servconts.ID]
port_id = net_list[net][servconts.PORTS][idx]
attachment = client.show_port_attachment(network_id, port_id)
attachment = attachment[servconts.ATTACHMENT][servconts.ID][:36]
LOG.debug("Plugging virtual interface: %s of VM %s \
into port: %s on network: %s" %
(attachment, service_vm_name, port_id, net))
attach_data = {servconts.ATTACHMENT: {servconts.ID: '%s' %
attachment}}
client.attach_resource(network_id, port_id, attach_data)
except Exception as exc:
print exc
print "Completed"
try:
LOG.debug("Registering Service in DB")
l2db.initialize()
for uuid_net in db.network_id(networks_name_list[0]):
mngnet_id = str(uuid_net.uuid)
for uuid_net in db.network_id(networks_name_list[1]):
nbnet_id = str(uuid_net.uuid)
for uuid_net in db.network_id(networks_name_list[2]):
sbnet_id = str(uuid_net.uuid)
sdb.add_services_binding(service_vm_name, mngnet_id, nbnet_id,
sbnet_id)
except Exception as exc:
print exc
def delete_service(tenant_id, service_instance_id, *args):
"""
Removes a service and all the network configuration
"""
l2db.initialize()
print ("Terminating Service VM")
service_logic = servlogcs.ServicesLogistics()
vms_list = []
vms_list.append(servconts.DELETE_VM_CMD)
vms_list.append(service_instance_id)
if not service_logic.image_exist(service_instance_id):
print ("Service VM does not exist")
sys.exit()
result = subprocess.call(vms_list)
service_logic.image_shutdown_verification(service_instance_id)
client = Client(HOST, PORT, USE_SSL, format='json', tenant=tenant_id)
service_nets = sdb.get_service_bindings(service_instance_id)
print ("Terminating Ports and Networks")
network_name = db.network_get(service_nets.mngnet_id)
port_id_net = db.port_list(service_nets.mngnet_id)
for ports_uuid in port_id_net:
client.delete_port(service_nets.mngnet_id, ports_uuid.uuid)
client.delete_network(service_nets.mngnet_id)
network_name = db.network_get(service_nets.nbnet_id)
port_id_net = db.port_list(service_nets.nbnet_id)
for ports_uuid in port_id_net:
client.delete_port(service_nets.nbnet_id, ports_uuid.uuid)
client.delete_network(service_nets.nbnet_id)
network_name = db.network_get(service_nets.sbnet_id)
port_id_net = db.port_list(service_nets.sbnet_id)
for ports_uuid in port_id_net:
client.delete_port(service_nets.sbnet_id, ports_uuid.uuid)
client.delete_network(service_nets.sbnet_id)
service_list = sdb.remove_services_binding(service_instance_id)
print ("Configuration Removed Successfully")
def disconnect_vm(vm_instance_id, *args):
"""
Deletes VMs and Port connection
"""
l2db.initialize()
print ("Terminating Service VM")
service_logic = servlogcs.ServicesLogistics()
vms_list = []
vms_list.append(servconts.DELETE_VM_CMD)
vms_list.append(vm_instance_id)
result = subprocess.call(vms_list)
service_logic.image_shutdown_verification(vm_instance_id)
print ("VM Server Off")
def connect_vm(tenant_id, vm_image_id, service_instance_id, *args):
"""
Starts a VMs and is connected to southbound network
"""
l2db.initialize()
client = Client(HOST, PORT, USE_SSL, format='json', tenant=tenant_id)
print ("Connecting %s to Service %s " % (vm_image_id, service_instance_id))
service_logic = servlogcs.ServicesLogistics()
service_nets = sdb.get_service_bindings(service_instance_id)
client.create_port(service_nets.mngnet_id)
client.create_port(service_nets.nbnet_id)
sb_port_id = client.create_port(service_nets.sbnet_id)
LOG.debug("Operation 'create_port' executed.")
new_port_id = sb_port_id[servconts.PORT][servconts.ID]
try:
create_vm_args = []
create_vm_args.append(servconts.CREATE_VM_CMD)
create_vm_args.append(vm_image_id)
print ("Creating VM with image: %s" % (vm_image_id))
process = subprocess.Popen(create_vm_args, stdout=subprocess.PIPE)
result = process.stdout.readlines()
tokens = re.search("i-[a-f0-9]*", str(result[1]))
vm_name = tokens.group(0)
print ("Image: %s instantiated successfully" % (vm_name))
except Exception as exc:
print exc
service_logic.image_status(vm_name)
print "Completed"
print "Attaching Ports To VM Service interfaces"
south_net = service_nets.sbnet_id
attachment = client.show_port_attachment(south_net, new_port_id)
attachment = attachment[servconts.ATTACHMENT][servconts.ID][:36]
LOG.debug("Plugging virtual interface: %s of VM %s \
into port: %s on network: %s" %
(attachment, vm_name, new_port_id, service_nets.sbnet_id))
attach_data = {servconts.ATTACHMENT: {servconts.ID: '%s' % attachment}}
client.attach_resource(service_nets.sbnet_id, new_port_id, attach_data)
print ("Connect VM Ended")
def create_multiport(tenant_id, networks_list, *args):
"""Creates ports on a single host"""
ports_info = {'multiport': \
{'status': 'ACTIVE',
'net_id_list': networks_list,
'ports_desc': {'key': 'value'}}}
request_url = "/multiport"
client = Client(HOST, PORT, USE_SSL, format='json', tenant=tenant_id,
action_prefix=servconts.ACTION_PREFIX_CSCO)
data = client.do_request('POST', request_url, body=ports_info)
return data
def build_args(cmd, cmdargs, arglist):
"""Building the list of args for a particular CLI"""
args = []
orig_arglist = arglist[:]
try:
for cmdarg in cmdargs:
args.append(arglist[0])
del arglist[0]
except:
LOG.debug("Not enough arguments for \"%s\" (expected: %d, got: %d)"
% (cmd, len(cmdargs), len(orig_arglist)))
print "Service Insertion Usage:\n %s %s" % (cmd,
" ".join(["<%s>" % y for y in SERVICE_COMMANDS[cmd]["args"]]))
sys.exit()
if len(arglist) > 0:
LOG.debug("Too many arguments for \"%s\" (expected: %d, got: %d)" \
% (cmd, len(cmdargs), len(orig_arglist)))
print "Service Insertion Usage:\n %s %s" % (cmd,
" ".join(["<%s>" % y for y in SERVICE_COMMANDS[cmd]["args"]]))
sys.exit()
return args
SERVICE_COMMANDS = {
"insert_inpath_service": {
"func": insert_inpath_service,
"args": ["tenant_id", "service_image_id",
"management_net_name", "northbound_net_name",
"southbound_net_name"]},
"delete_service": {
"func": delete_service,
"args": ["tenant_id", "service_instance_id"]},
"connect_vm": {
"func": connect_vm,
"args": ["tenant_id", "vm_image_id",
"service_instance_id"]},
"disconnect_vm": {
"func": disconnect_vm,
"args": ["vm_instance_id"]}}
if __name__ == "__main__":
os.system("clear")
usagestr = "Usage: %prog [OPTIONS] <command> [args]"
PARSER = OptionParser(usage=usagestr)
PARSER.add_option("-H", "--host", dest="host",
type="string", default="127.0.0.1", help="ip address of api host")
PARSER.add_option("-p", "--port", dest="port",
type="int", default=9696, help="api port")
PARSER.add_option("-s", "--ssl", dest="ssl",
action="store_true", default=False, help="use ssl")
PARSER.add_option("-v", "--verbose", dest="verbose",
action="store_true", default=False, help="turn on verbose logging")
PARSER.add_option("-f", "--logfile", dest="logfile",
type="string", default="syslog", help="log file path")
options, args = PARSER.parse_args()
if options.verbose:
LOG.setLevel(logging.DEBUG)
else:
LOG.setLevel(logging.WARN)
if options.logfile == "syslog":
LOG.addHandler(logging.handlers.SysLogHandler(address='/dev/log'))
else:
LOG.addHandler(logging.handlers.WatchedFileHandler(options.logfile))
os.chmod(options.logfile, 0644)
service_logic = servlogcs.ServicesLogistics()
HOST = options.host
PORT = options.port
USE_SSL = options.ssl
CMD = args[0]
args = build_args(CMD, SERVICE_COMMANDS[CMD]["args"], args[1:])
SERVICE_COMMANDS[CMD]["func"](*args)
sys.exit(0)

View File

@ -0,0 +1,35 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 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.
#
# @author: Edgar Magana, Cisco Systems
#
"""
Services Constants for the Services insertion Library
"""
FORMAT = 'json'
ACTION_PREFIX_EXT = '/v1.0'
ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + \
'/extensions/csco/tenants/{tenant_id}'
NETWORK = 'network'
ID = 'id'
PORTS = 'ports'
PORT = 'port'
NAME = 'name'
ATTACHMENT = 'attachment'
CREATE_VM_CMD = '/usr/bin/euca-run-instances'
DELETE_VM_CMD = '/usr/bin/euca-terminate-instances'
DESCRIBE_VM_CMD = '/usr/bin/euca-describe-instances'

View File

@ -0,0 +1,122 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, 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: Edgar Magana, Cisco Systems
"""
Logistic components for Service Insertion utility
"""
import logging
import subprocess
import re
import time
from quantum.common import utils
from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum.plugins.cisco.db import services_db as sdb
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.services import services_constants as servconts
LOG = logging.getLogger(__name__)
class ServicesLogistics():
"""
Services Logistics Modules
"""
def __init__(self):
pass
def image_shutdown_verification(self, image_name):
"""
Verifies that the VM has been properly shutdown
"""
try:
service_args = []
service_args.append(servconts.DESCRIBE_VM_CMD)
service_args.append(image_name)
counter = 0
flag = False
while flag == False and counter <= 5:
counter = counter + 1
time.sleep(2.5)
process = subprocess.Popen(service_args, \
stdout=subprocess.PIPE)
result = process.stdout.readlines()
if not result:
flag = True
except Exception, exc:
print exc
def image_status(self, image_name):
"""
Checks the status of the image
"""
try:
service_args = []
service_args.append(servconts.DESCRIBE_VM_CMD)
service_args.append(image_name)
counter = 0
flag = False
while flag == False and counter <= 10:
counter = counter + 1
time.sleep(2.5)
process = subprocess.Popen(service_args, \
stdout=subprocess.PIPE)
result = process.stdout.readlines()
if result:
tokens = re.search("running", str(result[1]))
if tokens:
service_status = tokens.group(0)
if service_status == "running":
flag = True
except Exception as exc:
print exc
def image_exist(self, image_name):
"""
Verifies that the image id is available
"""
try:
service_vm = sdb.get_service_bindings(image_name)
if service_vm:
return True
else:
return False
except Exception as exc:
print exc
def verify_plugin(self, plugin_key):
"""
Verifies the PlugIn available
"""
_plugins = {}
for key in conf.PLUGINS[const.PLUGINS].keys():
_plugins[key] = \
utils.import_object(conf.PLUGINS[const.PLUGINS][key])
if not plugin_key in _plugins.keys():
LOG.debug("No %s Plugin loaded" % plugin_key)
return False
else:
LOG.debug("Plugin %s founded" % const.UCS_PLUGIN)
return True
def press_key(self):
"""
Waits for en external input
"""
key = raw_input("Press any key to continue")
return key

View File

@ -27,6 +27,7 @@ from quantum.plugins.cisco.common import cisco_constants as const
import quantum.plugins.cisco.db.api as db
import quantum.plugins.cisco.db.l2network_db as l2network_db
import quantum.plugins.cisco.db.nexus_db as nexus_db
import quantum.plugins.cisco.db.services_db as services_db
import quantum.plugins.cisco.db.ucs_db as ucs_db
@ -191,6 +192,59 @@ class NexusDB(object):
% str(exc))
class ServicesDB(object):
"""Class consisting of methods to call services db methods"""
def get_all_servicesbindings(self):
"""get all services port bindings"""
bindings = []
try:
for bind in services_db.get_all_services_bindings():
LOG.debug("Getting services bindings : %s" % bind.service_id)
bind_dict = {}
bind_dict["service_id"] = str(bind.service_id)
bind_dict["mngnet_id"] = str(bind.mngnet_id)
bind_dict["nbnet_id"] = str(bind.nbnet_id)
bind_dict["sbnet_id"] = str(bind.sbnet_id)
bindings.append(bind_dict)
except Exception, exc:
LOG.error("Failed to get all bindings: %s" % str(exc))
return bindings
def get_servicebindings(self, service_id):
"""get service binding"""
try:
bind = services_db.get_service_bindings(service_id)
LOG.debug("Getting service binding : %s" % bind.service_id)
return bind
except Exception, exc:
LOG.error("Failed to get service binding: %s" % str(exc))
def create_servicebinding(self, service_id, mngnet_id, nbnet_id, sbnet_id):
"""create service binding"""
bind_dict = {}
try:
res = services_db.add_services_binding(service_id, mngnet_id, \
nbnet_id, sbnet_id)
LOG.debug("Created service binding : %s" % res.service_id)
bind_dict["service_id"] = str(res.service_id)
bind_dict["mngnet_id"] = str(res.mngnet_id)
bind_dict["nbnet_id"] = str(res.nbnet_id)
bind_dict["sbnet_id"] = str(res.sbnet_id)
return bind_dict
except Exception, exc:
LOG.error("Failed to create service binding: %s" % str(exc))
def delete_servicebinding(self, service_id):
"""delete service binding"""
try:
bind = services_db.remove_services_binding(service_id)
for res in bind:
LOG.debug("Deleted service binding: %s" % res.service_id)
except Exception, exc:
raise Exception("Failed to delete service binding: %s"
% str(exc))
class L2networkDB(object):
"""Class conisting of methods to call L2network db methods"""
def get_all_vlan_bindings(self):
@ -741,6 +795,72 @@ class NexusDBTest(unittest.TestCase):
self.dbtest.delete_nexusportbinding(vlan_id)
class ServicesDBTest(unittest.TestCase):
"""Class conisting of services DB unit tests"""
def setUp(self):
"""Setup for services db tests"""
l2network_db.initialize()
self.dbtest = ServicesDB()
LOG.debug("Setup")
def tearDown(self):
"""Tear Down"""
db.clear_db()
def testa_create_servicebinding(self):
"""create service binding"""
service_id = self.dbtest.create_servicebinding("i-00001", \
"mng_net", "northb_net", "northb_net")
self.assertTrue(service_id["service_id"] == "i-00001")
self.tearDown_servicebinding()
def testb_get_servicesbindings(self):
"""get all services binding"""
service_id = self.dbtest.create_servicebinding("i-00001", \
"mng_net", "northb_net", "northb_net")
bindings = self.dbtest.get_servicebindings("i-00001")
count = 0
if bindings:
count += 1
self.assertTrue(count == 1)
self.tearDown_servicebinding()
def testb_getall_servicesbindings(self):
"""get all services binding"""
service_id = self.dbtest.create_servicebinding("i-00001", \
"mng_net", "northb_net", "northb_net")
service_id = self.dbtest.create_servicebinding("i-00002", \
"mng_net", "northb_net", "northb_net")
bindings = self.dbtest.get_all_servicesbindings()
count = 0
for bind in bindings:
if "mng_net" in bind["mngnet_id"]:
count += 1
self.assertTrue(count == 2)
self.tearDown_servicebinding()
def testc_delete_servicesbinding(self):
"""delete services binding"""
binding_serv = self.dbtest.create_servicebinding("i-00001", \
"mng_net", "northb_net", "northb_net")
self.dbtest.delete_servicebinding("i-00001")
bindings = self.dbtest.get_all_servicesbindings()
count = 0
for bind in bindings:
if "mng_net" in bind["mngnet_id"]:
count += 1
self.assertTrue(count == 0)
self.tearDown_servicebinding()
def tearDown_servicebinding(self):
"""tear down nexusport binding table"""
LOG.debug("Tearing Down Nexus port Bindings")
binds = self.dbtest.get_all_servicesbindings()
for bind in binds:
service_id = bind["service_id"]
self.dbtest.delete_servicebinding(service_id)
class L2networkDBTest(unittest.TestCase):
"""Class conisting of L2network DB unit tests"""
def setUp(self):