Added Plexxi Driver

Change-Id: Iee629b199ce8c4251d7c2aea27877fc88b46990d
This commit is contained in:
Conner Ferguson 2014-11-11 16:58:04 -05:00
parent 58d10be4d6
commit 046516109b
5 changed files with 884 additions and 0 deletions

View File

@ -0,0 +1,540 @@
#!/usr/bin/env python
# Copyright (c) 2014 Marist SDN Innovation lab Joint with Plexxi 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.
#
import json
import requests
try:
from plexxi.core.api.binding import AffinityGroup
from plexxi.core.api.binding import Job
from plexxi.core.api.binding import PhysicalPort
from plexxi.core.api.binding import PlexxiSwitch
from plexxi.core.api.binding import VirtualizationHost
from plexxi.core.api.binding import VirtualMachine
from plexxi.core.api.binding import VirtualSwitch
from plexxi.core.api.binding import VmwareVirtualMachine
from plexxi.core.api.session import CoreSession
except ImportError:
pass
from congress.datasources.datasource_driver import DataSourceDriver
from congress.datasources import datasource_utils
from congress.openstack.common import log as logging
from oslo.config import cfg
LOG = logging.getLogger(__name__)
def d6service(name, keys, inbox, datapath, args):
"""This method is called by d6cage to create a dataservice instance.
"""
return PlexxiDriver(name, keys, inbox, datapath, args)
class PlexxiDriver(DataSourceDriver):
HOSTS = "hosts"
HOST_MACS = HOSTS + '.macs'
HOST_GUESTS = HOSTS + '.guests'
VMS = "vms"
VM_MACS = VMS + '.macs'
AFFINITIES = "affinities"
VSWITCHES = "vswitches"
PLEXXISWITCHES = "plexxiswitches"
PORTS = "ports"
PORT_LINKS = PORTS + '.links'
NETWORKLINKS = "networklinks"
def __init__(self, name='', keys='', inbox=None, datapath=None, args=None,
session=None):
args['tenant_name'] = None
super(PlexxiDriver, self).__init__(name, keys, inbox, datapath, args)
self.exchange = session
self.creds = datasource_utils.get_credentials(name, args)
self.raw_state = {}
self.key_index = self.create_index()
self.name_rule = False
self.cooldown = 0
try:
self.unique_names = self.string_to_bool(args['unique_names'])
except KeyError:
LOG.warning("unique_names has not been configured in "
"datasources.conf, defaulting to False.")
self.unique_names = False
port = str(cfg.CONF.bind_port)
host = str(cfg.CONF.bind_host)
self.api_address = "http://" + host + ":" + port + "/v1"
def update_from_datasource(self):
"""Called when it is time to pull new data from this datasource.
Pulls lists of objects from PlexxiCore, if the data does not match
the correspondig table in the driver's raw state or has not yet been
added to the state, the driver calls methods to parse this data.
Once all data has been updated,sets
self.state[tablename] = <list of tuples of strings/numbers>
for every tablename exported by PlexxiCore.
"""
# Initialize instance variables that get set during update
self.hosts = []
self.mac_list = []
self.guest_list = []
self.plexxi_switches = []
self.affinities = []
self.vswitches = []
self.vms = []
self.vm_macs = []
self.ports = []
self.network_links = []
if self.exchange is None:
self.connect_to_plexxi(self.creds)
# Get host data from PlexxiCore
hosts = VirtualizationHost.getAll(session=self.exchange)
if (self.HOSTS not in self.state or
hosts != self.raw_state[self.HOSTS]):
self._translate_hosts(hosts)
self.raw_state[self.HOSTS] = hosts
else:
self.hosts = self.state[self.HOSTS]
self.mac_list = self.state[self.HOST_MACS]
self.guest_list = self.state[self.HOST_GUESTS]
# Get PlexxiSwitch Data from PlexxiCore
plexxiswitches = PlexxiSwitch.getAll(session=self.exchange)
if (self.PLEXXISWITCHES not in self.state or
plexxiswitches != self.raw_state[self.PLEXXISWITCHES]):
self._translate_pswitches(plexxiswitches)
self.raw_state[self.PLEXXISWITCHES] = plexxiswitches
else:
self.plexxi_switches = self.state[self.PLEXXISWITCHES]
# Get affinity data from PlexxiCore
affinities = AffinityGroup.getAll(session=self.exchange)
if (self.AFFINITIES not in self.state or
affinities != self.raw_state[self.AFFINITIES]):
if AffinityGroup.getCount(session=self.exchange) == 0:
self.state[self.AFFINITIES] = ['No Affinities found']
else:
self._translate_affinites(affinities)
self.raw_state[self.AFFINITIES] = affinities
else:
self.affinties = self.state[self.AFFINITIES]
# Get vswitch data from PlexxiCore
vswitches = VirtualSwitch.getAll(session=self.exchange)
if (self.VSWITCHES not in self.state or
vswitches != self.raw_state[self.VSWITCHES]):
self._translate_vswitches(vswitches)
self.raw_state[self.VSWITCHES] = vswitches
else:
self.vswitches = self.state[self.VSWITCHES]
# Get virtual machine data from PlexxiCore
vms = VirtualMachine.getAll(session=self.exchange)
if (self.VMS not in self.state or
vms != self.raw_state[self.VMS]):
self._translate_vms(vms)
self.raw_state[self.VMS] = set(vms)
else:
self.vms = self.state[self.VMS]
self.vm_macs = self.state[self.VMS_MACS]
# Get port data from PlexxiCore
ports = PhysicalPort.getAll(session=self.exchange)
if(self.PORTS not in self.state or
ports != self.raw_state[self.PORTS]):
self._translate_ports(ports)
self.raw_state[self.PORTS] = set(ports)
else:
self.ports = self.state[self.PORTS]
self.network_links = self.state[self.PORT_LINKS]
LOG.debug("Setting Plexxi State")
self.state = {}
self.state['key_index'] = self.key_index
self.state[self.HOSTS] = set(self.hosts)
self.state[self.HOST_MACS] = set(self.mac_list)
self.state[self.HOST_GUESTS] = set(self.guest_list)
self.state[self.PLEXXISWITCHES] = set(self.plexxi_switches)
self.state[self.PLEXXISWITCHES + '.macs'] = set(self.ps_macs)
self.state[self.AFFINITIES] = set(self.affinities)
self.state[self.VSWITCHES] = set(self.vswitches)
self.state[self.VMS] = set(self.vms)
self.state[self.VM_MACS] = set(self.vm_macs)
self.state[self.PORTS] = set(self.ports)
self.state[self.PORT_LINKS] = set(self.network_links)
# Create Rules
if self.name_rule is False:
self.create_rule_table()
# Act on Policy
if self.unique_names is True:
if self.cooldown == 0:
self.name_response()
else:
self.cooldown -= 1
@classmethod
def get_schema(cls):
"""Creates a table schema for incoming data from PlexxiCore.
Returns a dictionary map of tablenames corresponding to column names
for that table. Both tableNames and columnnames are strings.
"""
d = {}
d[cls.HOSTS] = ("uuid", "name", "mac_count", "vmcount")
d[cls.VMS] = ("uuid", "name", "host_uuid", "ip", "mac_count")
d[cls.AFFINITIES] = ("uuid", "name")
d[cls.VSWITCHES] = ("uuid", "host_count", "vnic_count")
d[cls.PLEXXISWITCHES] = ("uuid", "ip", "status")
d[cls.PORTS] = ("uuid", "name")
d[cls.NETWORKLINKS] = ("uuid", "name", "port_uuid", "start_uuid",
"start_name", "stop_uuid", "stop_name")
return d
def _translate_hosts(self, hosts):
"""Translates data about Hosts from PlexxiCore for Congress.
Responsible for the states 'hosts','hosts.macs' and 'hosts.guests'
"""
row_keys = self.get_column_map(self.HOSTS)
hostlist = []
maclist = []
vm_uuids = []
for host in hosts:
row = ['None'] * (max(row_keys.values()) + 1)
hostID = host.getForeignUuid()
row[row_keys['uuid']] = hostID
row[row_keys['name']] = host.getName()
pnics = host.getPhysicalNetworkInterfaces()
if pnics:
for pnic in pnics:
mac = str(pnic.getMacAddress())
tuple_mac = (hostID, mac)
maclist.append(tuple_mac)
mac_count = len(maclist)
if (mac_count > 0):
row[row_keys['mac_count']] = mac_count
vmCount = host.getVirtualMachineCount()
row[row_keys['vmcount']] = vmCount
if vmCount != 0:
vms = host.getVirtualMachines()
for vm in vms:
tuple_vmid = (hostID, vm.getForeignUuid())
vm_uuids.append(tuple_vmid)
hostlist.append(tuple(row))
self.hosts = hostlist
self.mac_list = maclist
self.guest_list = vm_uuids
def _translate_pswitches(self, plexxi_switches):
"""Translates data on Plexxi Switches from PlexxiCore for Congress.
Responsible for state 'Plexxi_swtiches' and 'Plexxi_switches.macs'
"""
row_keys = self.get_column_map(self.PLEXXISWITCHES)
pslist = []
maclist = []
for switch in plexxi_switches:
row = ['None'] * (max(row_keys.values()) + 1)
psuuid = str(switch.getUuid())
row[row_keys['uuid']] = psuuid
psip = str(switch.getIpAddress())
row[row_keys['ip']] = psip
psstatus = str(switch.getStatus())
row[row_keys['status']] = psstatus
pnics = switch.getPhysicalNetworkInterfaces()
for pnic in pnics:
mac = str(pnic.getMacAddress())
macrow = [psuuid, mac]
maclist.append(tuple(macrow))
pslist.append(tuple(row))
self.plexxi_switches = pslist
self.ps_macs = maclist
def _translate_affinites(self, affinites):
"""Translates data about affinites from PlexxiCore for Congress.
Responsible for state 'affinities'
"""
row_keys = self.get_column_map(self.AFFINITIES)
affinitylist = []
for affinity in affinites:
row = ['None'] * (max(row_keys.values()) + 1)
uuid = str(affinity.getUuid())
row[row_keys['uuid']] = uuid
row[row_keys['name']] = affinity.getName()
affinitylist.append(tuple(row))
self.affinities = affinitylist
def _translate_vswitches(self, vswitches):
"""Translates data about vswitches from PlexxiCore for Congress.
Responsible for states vswitchlist,vswitch_macs,vswitch_hosts
"""
# untested
row_keys = self.get_column_map(self.VSWITCHES)
vswitchlist = []
tuple_macs = []
vswitch_host_list = []
for vswitch in vswitches:
row = ['None'] * (max(row_keys.values()) + 1)
vswitchID = vswitch.getForeignUuid()
row[row_keys['uuid']] = vswitchID
vSwitchHosts = vswitch.getVirtualizationHosts()
try:
host_count = len(vSwitchHosts)
except TypeError:
host_count = 0
row[row_keys['host_count']] = host_count
if host_count != 0:
for host in vSwitchHosts:
hostuuid = host.getForeignUuid()
hostrow = [vswitchID, hostuuid]
vswitch_host_list.append(tuple(hostrow))
vswitch_vnics = vswitch.getVirtualNetworkInterfaces()
try:
vnic_count = len(vswitch_vnics)
except TypeError:
vnic_count = 0
row[row_keys['vnic_count']] = vnic_count
if vnic_count != 0:
for vnic in vswitch_vnics:
mac = vnic.getMacAddress()
macrow = [vswitchID, str(mac)]
tuple_macs.append(tuple(macrow))
vswitchlist.append(tuple(row))
self.vswitches = vswitchlist
self.vswitch_macs = tuple_macs
self.vswitch_hosts = vswitch_host_list
def _translate_vms(self, vms):
"""Translate data on VMs from PlexxiCore for Congress.
Responsible for states 'vms' and 'vms.macs'
"""
row_keys = self.get_column_map(self.VMS)
vmlist = []
maclist = []
for vm in vms:
row = ['None'] * (max(row_keys.values()) + 1)
vmID = vm.getForeignUuid()
row[row_keys['uuid']] = vmID
vmName = vm.getName()
row[row_keys['name']] = vmName
try:
vmhost = vm.getVirtualizationHost()
vmhostuuid = vmhost.getForeignUuid()
row[row_keys['host_uuid']] = vmhostuuid
except AttributeError:
LOG.debug("The host for " + vmName + " could not be found")
vmIP = vm.getIpAddress()
if vmIP:
row[row_keys['ip']] = vmIP
vmVnics = vm.getVirtualNetworkInterfaces()
mac_count = 0
for vnic in vmVnics:
mac = str(vnic.getMacAddress())
tuple_mac = (vmID, mac)
maclist.append(tuple_mac)
mac_count += 1
row[row_keys['mac_count']] = mac_count
vmlist.append(tuple(row))
self.vms = vmlist
self.vm_macs = maclist
def _translate_ports(self, ports):
"""Translate data about ports from PlexxiCore for Congress.
Responsible for states 'ports' and 'ports.links'
"""
row_keys = self.get_column_map(self.PORTS)
link_keys = self.get_column_map(self.NETWORKLINKS)
port_list = []
link_list = []
for port in ports:
row = ['None'] * (max(row_keys.values()) + 1)
portID = str(port.getUuid())
row[row_keys['uuid']] = portID
portName = str(port.getName())
row[row_keys['name']] = portName
links = port.getNetworkLinks()
if links:
link_keys = self.get_column_map(self.NETWORKLINKS)
for link in links:
link_row = self._translate_network_link(link, link_keys,
portID)
link_list.append(tuple(link_row))
port_list.append(tuple(row))
self.ports = port_list
self.network_links = link_list
def _translate_network_link(self, link, row_keys, sourcePortUuid):
"""Translates data about network links from PlexxiCore for Congress.
Subfunction of translate_ports,each handles a set of network links
attached to a port. Directly responsible for the state of
'ports.links'
"""
row = ['None'] * (max(row_keys.values()) + 1)
linkID = str(link.getUuid())
row[row_keys['uuid']] = linkID
row[row_keys['port_uuid']] = sourcePortUuid
linkName = str(link.getName())
row[row_keys['name']] = linkName
linkStartObj = link.getStartNetworkInterface()
linkStartName = str(linkStartObj.getName())
row[row_keys['start_name']] = linkStartName
linkStartUuid = str(linkStartObj.getUuid())
row[row_keys['start_uuid']] = linkStartUuid
linkStopObj = link.getStopNetworkInterface()
linkStopUuid = str(linkStopObj.getUuid())
row[row_keys['stop_uuid']] = linkStopUuid
linkStopName = str(linkStopObj.getName())
row[row_keys['stop_name']] = linkStopName
return row
def string_to_bool(self, string):
"""Used for parsing boolean variables stated in datasources.conf.
"""
string = string.strip()
s = string.lower()
if s in['true', 'yes', 'on']:
return True
else:
return False
def create_index(self):
"""Creates key_index table
The key_index table is used expose the table schema through the API.
The CONGRESS_INDEX_ID field contains the name of the table the rest
of the data is pertaining to.The other values give the names
columns paired with their position in the table.
"""
key_index = []
row_keys = self.get_schema()
for key in row_keys.keys():
key_map = self.get_column_map(key)
key_map['CONGRESS_INDEX_ID'] = key
key_index.append(key_map)
return key_index
def connect_to_plexxi(self, creds):
"""Create a CoreSession connecting congress to PlexxiCore using
credentials provided in datasources.conf
"""
if 'auth_url' not in creds:
LOG.error("Plexxi url not supplied. Could not start Plexxi" +
"connection driver")
if 'username' not in creds:
LOG.error("Plexxi username not supplied. Could not start " +
"Plexxi connection driver")
if 'password' not in creds:
LOG.error("Plexxi password not supplied. Could not start " +
"Plexxi connection driver")
try:
self.exchange = CoreSession.connect(
baseUrl=creds['auth_url'],
allowUntrusted=True,
username=creds['username'],
password=creds['password'])
except requests.exceptions.HTTPError as error:
if int(error.response.status_code) == 401 or\
int(error.response.status_code) == 403:
msg = "Incorrect username/password combination. Passed" + \
"in username was " + creds['username'] + ", " + \
"password was " + creds['password']
raise Exception(requests.exceptions.HTTPErrror(msg))
else:
raise Exception(requests.exceptions.HTTPError(error))
except requests.exceptions.ConnectionError:
msg = "Cannot connect to PlexxiCore at " + creds['auth_url'] + \
" with the username " + creds['username'] + " and the " + \
"password " + creds['password']
raise Exception(requests.exceptions.ConnectionError(msg))
def create_rule_table(self):
"""Creates RepeatedName table for unique names policy.
The RepeatedName table contains the name and plexxiUuid of
VMs that have the same name in the Plexxi table and the Nova Table.
"""
repeated_name_rule = '{"rule": "RepeatedName(vname,pvuuid)' +\
':- plexxi:vms(pvuuid,vname,phuuid,pvip,pvmaccount,pvaffin),' +\
'nova:servers(nvuuid,vname,a,nstatus,b,c,d,num)"}'
try:
requests.post(self.api_address + '/policies/classification/rules',
data=repeated_name_rule)
self.name_rule = False
except Exception:
LOG.exception("Could not create Repeated Name table")
def name_response(self):
"""Checks for any entries in the RepeatedName table.
For all entries found in the RepeatedName table, the corresponding
VM will be then prefixed with 'conflict-' in PlexxiCore.
"""
vmname = False
vmuuid = False
json_response = []
self.cooldown += 1
try:
plexxivms = VmwareVirtualMachine.getAll(session=self.exchange)
table = requests.get(self.api_address + "/policies/" +
"classification/tables/RepeatedName/rows")
json_response = json.loads(table.text)
for row in json_response['results']:
vmname = row['data'][0]
vmuuid = row['data'][1]
if vmname and vmuuid:
for plexxivm in plexxivms:
if (plexxivm.getForeignUuid() == vmuuid):
new_vm_name = "Conflict-" + vmname
desc = "Congress has found a VM with the same " +\
"name on the nova network. This vm " +\
"will now be renamed to " + new_vm_name
job_name = " Congress Driver:Changing virtual" +\
"machine, " + vmname + "\'s name"
changenamejob = Job.create(name=job_name,
description=desc + ".",
session=self.exchange)
changenamejob.begin()
plexxivm.setName(new_vm_name)
changenamejob.commit()
LOG.info(desc + " in PlexxiCore.")
except Exception:
LOG.exception("error in name_response")

View File

@ -0,0 +1,174 @@
#!/usr/bin/env python
# Copyright (c) 2014 Marist SDN Innovation lab Joint with Plexxi 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.
class MockAffinity(object):
def __init__(self, uuid, name):
self.uuid = uuid
self.name = name
def getUuid(self):
return self.uuid
def getName(self):
return self.name
class MockCoreSession(object):
def __init__(self):
pass
def disconnect():
pass
class MockHost(object):
def __init__(self, uuid, name, mac_count, pnics):
self.uuid = uuid
self.name = name
self.mac_count = mac_count
self.pnics = pnics
self.vms = []
def addvm(self, vm):
self.vms.append(vm)
def getForeignUuid(self):
return self.uuid
def getUuid(self):
return self.uuid
def getName(self):
return self.name
def getPhysicalNetworkInterfaces(self):
return self.pnics
def getVirtualMachineCount(self):
return len(self.vms)
def getVirtualMachines(self):
return self.vms
class MockNetworkLink(object):
def __init__(self, uuid, name, stopint, startint):
self.uuid = uuid
self.name = name
self.startint = startint
self.stopint = stopint
def getUuid(self):
return self.uuid
def getName(self):
return self.name
def getStartNetworkInterface(self):
return self.startint
def getStopNetworkInterface(self):
return self.stopint
class MockNIC(object):
def __init__(self, uuid, mac):
self.uuid = uuid
self.mac = mac
def getMacAddress(self):
return self.mac
class MockPort(object):
def __init__(self, uuid, name, networklinks):
self.uuid = uuid
self.name = name
self.networklinks = networklinks
def getUuid(self):
return self.uuid
def getName(self):
return self.name
def getNetworkLinks(self):
return self.networklinks
class MockSwitch(object):
def __init__(self, uuid, ip, name, status, pnics):
self.uuid = uuid
self.ip = ip
self.status = status
self.pnics = pnics
self.name = name
def getUuid(self):
return self.uuid
def getName(self):
return self.name
def getIpAddress(self):
return self.ip
def getStatus(self):
return self.status
def getPhysicalNetworkInterfaces(self):
return self.pnics
class MockVM(object):
def __init__(self, uuid, ip, name, host, vnics):
self.uuid = uuid
self.ip = ip
self.host = host
self.name = name
self.vnics = vnics
def getForeignUuid(self):
return self.uuid
def getVirtualizationHost(self):
return self.host
def getName(self):
return self.name
def getIpAddress(self):
return self.ip
def getVirtualNetworkInterfaces(self):
return self.vnics
class MockVSwitch(object):
def __init__(self, uuid, hosts, vnics):
self.uuid = uuid
self.hosts = hosts
self.vnics = vnics
def getForeignUuid(self):
return self.uuid
def getVirtualizationHosts(self):
return self.hosts
def getVirtualNetworkInterfaces(self):
return self.vnics

View File

@ -0,0 +1,158 @@
#!/usr/bin/env python
# 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 congress.datasources import plexxi_driver
from congress.datasources.tests.unit.plexxi_fakes import MockAffinity
from congress.datasources.tests.unit.plexxi_fakes import MockCoreSession
from congress.datasources.tests.unit.plexxi_fakes import MockHost
from congress.datasources.tests.unit.plexxi_fakes import MockNetworkLink
from congress.datasources.tests.unit.plexxi_fakes import MockNIC
from congress.datasources.tests.unit.plexxi_fakes import MockPort
from congress.datasources.tests.unit.plexxi_fakes import MockSwitch
from congress.datasources.tests.unit.plexxi_fakes import MockVM
from congress.datasources.tests.unit.plexxi_fakes import MockVSwitch
from congress.tests import base
from congress.tests import helper
class TestPlexxiDriver(base.TestCase):
def setUp(self):
super(TestPlexxiDriver, self).setUp()
args = helper.datasource_openstack_args()
args['unique_names'] = 'False'
session = MockCoreSession()
self.driver = plexxi_driver.PlexxiDriver(args=args, session=session)
self.driver.exchange = True
vnic1 = MockNIC(uuid='f318ac0a-9255-4af0-8a41-6f3fbc06c8aa',
mac='B8:ED:0A:4D:82:91')
vnic2 = MockNIC(uuid='f318ac0a-9255-4af0-8a41-6f3fbc06c8a2',
mac='B8:ED:0A:4D:82:99')
pnic1 = MockNIC(uuid='f318ac0a-9255-4af0-8a41-6f3fbc06c8ab',
mac='B8:ED:0A:4D:82:92')
pnic2 = MockNIC(uuid='f318ac0a-9255-4af0-8a41-6f3fbc06c8ac',
mac='B8:ED:0A:4D:82:93')
host1 = MockHost('eed4ebfc-25e5-4a65-9f37-b70b8e8219d3',
'mock1',
1,
[pnic1])
vm1 = MockVM('2ca924f6-90aa-4ce8-a986-f62f8f64d14b',
'192.168.90.2',
'namevm',
host1,
[vnic1])
host1.addvm(vm1)
switch1 = MockSwitch('12da13e3-ecb2-4c26-98a0-26cb07f9c33d',
'192.168.90.3',
'switch1',
'HEALTHY',
[pnic2])
affinity = MockAffinity('fd487ecf-5279-4d3c-9378-7fb214f5dd5a',
'Testfinnity')
affinity2 = MockAffinity('fd487ecf-5279-4d3c-9378-7fb214f5dd5b',
'Testfinnity2')
vswitch = MockVSwitch('fd487ecf-5279-4d3c-9378-7fb214f5dd5c',
[host1],
[vnic2])
link1 = MockNetworkLink('fd487ecf-5279-4d3c-9378-7fb214f5dd5f',
'Link1',
host1,
switch1)
port = MockPort('fd487ecf-5279-4d3c-9378-7fb214f5dd5d',
'Port1',
[link1])
port2 = MockPort('fd487ecf-5279-4d3c-9378-7fb214f5dd5e',
'Port2',
None)
self.hosts = [host1]
self.pswitches = [switch1]
self.affinites = [affinity, affinity2]
self.vswitches = [vswitch]
self.vms = [vm1]
self.ports = [port, port2]
def test_translate_hosts(self):
self.driver._translate_hosts(self.hosts)
ExpectedHosts = [('eed4ebfc-25e5-4a65-9f37-b70b8e8219d3',
'mock1',
1,
1)]
self.assertEqual(self.driver.hosts, ExpectedHosts)
ExpectedHost_Macs = [('eed4ebfc-25e5-4a65-9f37-b70b8e8219d3',
'B8:ED:0A:4D:82:92')]
self.assertEqual(self.driver.mac_list, ExpectedHost_Macs)
ExpectedGuests = [('eed4ebfc-25e5-4a65-9f37-b70b8e8219d3',
'2ca924f6-90aa-4ce8-a986-f62f8f64d14b')]
self.assertEqual(self.driver.guest_list, ExpectedGuests)
def test_translate_pswitches(self):
self.driver._translate_pswitches(self.pswitches)
ExpectedpSwitches = [('12da13e3-ecb2-4c26-98a0-26cb07f9c33d',
'192.168.90.3',
'HEALTHY')]
self.assertEqual(self.driver.plexxi_switches, ExpectedpSwitches)
ExpectedPSmacs = [('12da13e3-ecb2-4c26-98a0-26cb07f9c33d',
'B8:ED:0A:4D:82:93')]
self.assertEqual(self.driver.ps_macs, ExpectedPSmacs)
def test_translate_affinites(self):
self.driver._translate_affinites(self.affinites)
ExpectedAffinities = [('fd487ecf-5279-4d3c-9378-7fb214f5dd5a',
'Testfinnity'),
('fd487ecf-5279-4d3c-9378-7fb214f5dd5b',
'Testfinnity2')]
self.assertEqual(self.driver.affinities, ExpectedAffinities)
def test_translate_vswitches(self):
self.driver._translate_vswitches(self.vswitches)
ExpectedvSwitches = [('fd487ecf-5279-4d3c-9378-7fb214f5dd5c',
1,
1)]
self.assertEqual(self.driver.vswitches, ExpectedvSwitches)
ExpectedvSwitch_macs = [('fd487ecf-5279-4d3c-9378-7fb214f5dd5c',
'B8:ED:0A:4D:82:99')]
self.assertEqual(self.driver.vswitch_macs, ExpectedvSwitch_macs)
ExpectedvSwitch_hosts = [('fd487ecf-5279-4d3c-9378-7fb214f5dd5c',
'eed4ebfc-25e5-4a65-9f37-b70b8e8219d3')]
self.assertEqual(self.driver.vswitch_hosts, ExpectedvSwitch_hosts)
def test_translate_vms(self):
self.driver._translate_vms(self.vms)
ExpectedVMs = [('2ca924f6-90aa-4ce8-a986-f62f8f64d14b',
'namevm',
'eed4ebfc-25e5-4a65-9f37-b70b8e8219d3',
'192.168.90.2',
1)]
self.assertEqual(self.driver.vms, ExpectedVMs)
Expectedvm_macs = [('2ca924f6-90aa-4ce8-a986-f62f8f64d14b',
'B8:ED:0A:4D:82:91')]
self.assertEqual(self.driver.vm_macs, Expectedvm_macs)
def test_translate_ports(self):
self.driver._translate_ports(self.ports)
ExpectedPorts = [('fd487ecf-5279-4d3c-9378-7fb214f5dd5d',
'Port1'),
('fd487ecf-5279-4d3c-9378-7fb214f5dd5e',
'Port2')]
self.assertEqual(self.driver.ports, ExpectedPorts)
ExpectedLinks = [('fd487ecf-5279-4d3c-9378-7fb214f5dd5f',
'Link1',
'fd487ecf-5279-4d3c-9378-7fb214f5dd5d',
'12da13e3-ecb2-4c26-98a0-26cb07f9c33d',
'switch1',
'eed4ebfc-25e5-4a65-9f37-b70b8e8219d3',
'mock1')]
self.assertEqual(self.driver.network_links, ExpectedLinks)

View File

@ -46,3 +46,11 @@ username: admin
password: password
auth_url: http://127.0.0.1:5000/v2.0
tenant_name: admin
#[plexxi]
#module:datasources/plexxi_driver.py
#username: plexxiCore_username
#password: plexxiCore_password
#auth_url: http://PlexxiCoreURL/PlexxiCore/api
#unique_names: False

4
thirdparty/plexxi_setup.sh vendored Normal file
View File

@ -0,0 +1,4 @@
#!/bin/bash
# Replace 2.0.2-sp2 with your repective plexxicore verison
# This can be checked at http://PlexxiCoreURL:8080/PlexxiCore/
pip install -v --index-url http://pypi.plexxi.com plexxi==2.0.2-sp2