From: t.moriyama Date: Fri, 19 Apr 2013 09:23:03 +0000 (+0900) Subject: add LinuxBridge, OVS, LibVirt agents X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ff8054c79467db38de19b714a74f7e4c311146d7;p=ti2%2Fti2.git add LinuxBridge, OVS, LibVirt agents --- diff --git a/linkpair/collect/agent/libvirt_agent.py b/linkpair/collect/agent/libvirt_agent.py new file mode 100755 index 0000000..433594c --- /dev/null +++ b/linkpair/collect/agent/libvirt_agent.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# + +__version__ = '1.1' + +import sys +import os +import re +from xml.dom import minidom +from subprocess import Popen, PIPE +from socket import gethostname +import shlex +import libvirt +from linkpair.device import Device +from linkpair.port import Port +from linkpair.linkpair import LinkPair +from linkpair.collect.utils import CollectUtils +from linkpair.collect.agent.commandrunner import CommandRunner +from linkpair.formatter.grapheasy import GraphEasyFormatter +from linkpair.commonutils import CommonUtils + + +class LibvirtAgent(object): + ''' + Libvirt Collector Agent + ''' + + def __init__(self, runner, cu, linkpairs, port_to_br, iface_to_nss, remote_desc, formatter=GraphEasyFormatter()): + self._runner = runner + self._cu = cu + self._linkpairs = linkpairs + self._port_to_br = port_to_br + self._iface_to_nss = iface_to_nss + self._remote_desc = remote_desc + self._u = CommonUtils() + + ''' set parameters ''' + self._formatter = formatter + + def run(self): + self.pick_libvirt_configuration() + + def pick_libvirt_configuration(self): + virt_conn = self.get_libvirt_conn() + for id in virt_conn.listDomainsID(): + vm = virt_conn.lookupByID(id) + vmXMLDesc = minidom.parseString(vm.XMLDesc(0)) + for iface in vmXMLDesc.getElementsByTagName("interface"): + [device, bridge] = self.pick_libvirt_iface_configuration(iface) + mac = iface.getElementsByTagName( + "mac")[0].getAttribute("address") + device = iface.getElementsByTagName( + "target")[0].getAttribute("dev") + bridge = self.regist_to_port2br(device, bridge) + self._cu.add_linkpair( + Device(str(vm.name()), Device.VM_TYPE), + Device(bridge, Device.BR_TYPE), + Port(device), + Port("")) + + def pick_libvirt_iface_configuration(self, iface): + ifaceType = iface.getAttribute("type") + bridge = "" + device = "" + if ifaceType == "network": + network = iface.getElementsByTagName( + "source")[0].getAttribute("network") + netXMLDesc = minidom.parseString( + virt_conn.networkLookupByName(network).XMLDesc(0)) + bridge = netXMLDesc.getElementsByTagName( + "bridge")[0].getAttribute("name") + elif ifaceType == "bridge": + bridge = iface.getElementsByTagName( + "source")[0].getAttribute("bridge") + return [device, bridge] + + def get_libvirt_conn(self): + if self._remote_desc is not None: + conn = libvirt.open("qemu+ssh://" + self._remote_desc + "/system") + else: + conn = libvirt.open("qemu:///system") + return conn diff --git a/linkpair/collect/agent/linuxbridge_agent.py b/linkpair/collect/agent/linuxbridge_agent.py new file mode 100755 index 0000000..92fa2d1 --- /dev/null +++ b/linkpair/collect/agent/linuxbridge_agent.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# + +__version__ = '1.1' + +import sys +import os +import re +from xml.dom import minidom +from subprocess import Popen, PIPE +from socket import gethostname +from linkpair.device import Device +from linkpair.port import Port +from linkpair.linkpair import LinkPair +from linkpair.collect.utils import CollectUtils +from linkpair.collect.agent.commandrunner import CommandRunner +from linkpair.formatter.grapheasy import GraphEasyFormatter +from linkpair.commonutils import CommonUtils + + +class LinuxBridgeAgent(object): + ''' + Linux bridge Collector Agent + ''' + + PEER_FOUND = 1 + + def __init__(self, runner, cu, linkpairs, port_to_br, iface_to_nss, formatter=GraphEasyFormatter()): + self._runner = runner + self._cu = cu + self._linkpairs = linkpairs + self._port_to_br = port_to_br + self._iface_to_nss = iface_to_nss + self._u = CommonUtils() + + ''' set parameters ''' + self._formatter = formatter + + def run(self): + self.pick_bridge_configuration() + + def pick_bridge_configuration(self): + br_name = "" + result = self._runner.exec_cmd("brctl show") + for br_line in result: + br_line = br_line.rstrip() + if self._u.d_push(re.match(r'^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$', br_line)) is not None: + match = self._u.d_pop() + br_name = match.group(1) + port = match.group(4) + if port not in self._port_to_br and br_name != "": + self._port_to_br[port] = br_name + ## for OpenStack quntum... + if self._u.d_push(re.match(r'^qvb(.+)', port)): + quantum_idprefix = self._u.d_pop().group(1) + if "qvo" + quantum_idprefix in self._port_to_br: + self._cu.add_linkpair( + Device(br_name, Device.BR_TYPE), + Device(self._port_to_br[ + "qvo" + quantum_idprefix], Device.BR_TYPE), + Port(port), + Port("qvo" + quantum_idprefix), + self._formatter.VETH_FORMAT) + else: + self._cu.add_linkpair( + Device(br_name), + Device("INTERNAL", Device.OS_ROUTE_TYPE), + Port(port), + Port("")) + # else: + # print self._port_to_br.keys() + # if self._u.d_push(re.match(r'^qvo(.+)', port)): + # continue + # add_linkpair(self.DEFAULT_FORMAT, br_name, self.DEFAULT_TYPE, port, \ + # "INTERNAL", self.OS_ROUTE_TYPE ) + + elif self._u.d_push(re.match(r'^\s+(\S+)$', br_line)) is not None: + port = self._u.d_pop().group(1) + if port not in self._port_to_br and br_name != "": + self._port_to_br[port] = br_name + ## for OpenStack quntum... + if self._u.d_push(re.match(r'^qvb(.+)', port)): + quantum_idprefix = self._u.d_pop().group(1) + if "qvo" + quantum_idprefix in self._port_to_br: + self._cu.add_linkpair( + Device(br_name, Device.BR_TYPE), + Device(self._port_to_br[ + "qvo" + quantum_idprefix], Device.BR_TYPE), + Port(port), + Port("qvo" + quantum_idprefix), + self._formatter.VETH_FORMAT) + else: + if self._u.d_push(re.match(r'^qvo(.+)', port)): + continue + self._cu.add_linkpair( + Device(br_name), + Device("INTERNAL", Device.OS_ROUTE_TYPE), + Port(port), + Port("")) + diff --git a/linkpair/collect/agent/ovs_agent.py b/linkpair/collect/agent/ovs_agent.py new file mode 100755 index 0000000..16c4fb2 --- /dev/null +++ b/linkpair/collect/agent/ovs_agent.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# + +__version__ = '1.1' + +import sys +import os +import re +from xml.dom import minidom +from subprocess import Popen, PIPE +from socket import gethostname +from linkpair.device import Device +from linkpair.port import Port +from linkpair.linkpair import LinkPair +from linkpair.collect.utils import CollectUtils +from linkpair.collect.agent.commandrunner import CommandRunner +from linkpair.formatter.grapheasy import GraphEasyFormatter +from linkpair.commonutils import CommonUtils + + +class OVSAgent(object): + ''' + Open vSwitch Collector Agent + ''' + + PEER_FOUND = 1 + + def __init__(self, runner, cu, linkpairs, port_to_br, iface_to_nss, formatter=GraphEasyFormatter()): + self._runner = runner + self._cu = cu + self._linkpairs = linkpairs + self._port_to_br = port_to_br + self._iface_to_nss = iface_to_nss + self._u = CommonUtils() + + ''' set parameters ''' + self._formatter = formatter + + def run(self): + self.get_configuration() + + def get_configuration(self): + patch_peers = {} + + result = self._runner.exec_cmd("ovs-vsctl list-br") + for br_src in result: + br_src = br_src.rstrip() + result2 = self._runner.exec_cmd("ovs-dpctl show " + br_src) + for port_desc in result2: + port_desc = port_desc.rstrip() + if self._u.d_push( + re.search(r'port \d+: (.*?) \(patch: peer=(.*?)\)', + port_desc)) is not None: + match = self._u.d_pop() + patch_src = match.group(1) + patch_dst = match.group(2) + patch_peers[patch_src + ":" + patch_dst] = self.PEER_FOUND + + if patch_dst + ":" + patch_src in patch_peers: + continue + + result3 = self._runner.exec_cmd( + "ovs-vsctl port-to-br " + patch_dst) + if result3 is not None and len(result3) > 0: + br_dst = result3[0].rstrip() + self._cu.add_linkpair( + Device(br_src, Device.BR_TYPE), + Device(br_dst, Device.BR_TYPE), + Port(patch_src), + Port(patch_dst), + self._formatter.PATCH_FORMAT) + else: + self._cu.add_linkpair( + Device(br_src, Device.BR_TYPE), + Device("NOT CONNECTED", Device.NOT_CONNECTED_TYPE), + Port(patch_src), + Port(patch_dst), + self._formatter.PATCH_FORMAT) + + else: + # Internal OVSPort. + if self._u.d_push( + re.search( + r'port \d+: ' + br_src + ' \(internal\)', + port_desc)) is None: + if self._u.d_push(re.search(r'port \d+: (.*)', port_desc)) is not None: + port = self._u.d_pop().group(1).rstrip() + if self._u.d_push(re.match(r'^eth\d+$', port)) \ + or self._u.d_push(re.match(r'^em\d+$', port)) \ + or self._u.d_push(re.match(r'^igb\d+$', port)): + self._cu._port_to_br[port] = br_src + self._cu.add_linkpair( + Device(br_src, Device.BR_TYPE), + Device("Physical NW", Device.PHYNET_TYPE), + Port(port), + Port("")) + elif self._u.d_push(re.match(r'(vxlan\d+)', port)) \ + or self._u.d_push(re.match(r'(gre\d+)', port)) \ + or self._u.d_push(re.match(r'(gre-\d+)', port)): + port2 = self._u.d_pop().group(1) + self._cu._port_to_br[port2] = br_src + self._cu.add_linkpair( + Device(br_src, Device.BR_TYPE), + Device("OS Routing", Device.OS_ROUTE_TYPE), + Port(port), + Port("")) + elif re.search(r' \(internal\)', port): + port = re.sub(r' \(internal\)', '', port) + if port in self._iface_to_nss: + self._cu.add_linkpair( + Device(br_src, Device.BR_TYPE), + Device(self._iface_to_nss[ + port], Device.NAMESPACE_TYPE), + Port(port), + Port(""), + self._formatter.NAMESPACE_FORMAT) + else: + self._cu.add_linkpair( + Device(br_src, Device.BR_TYPE), + Device( + "INTERNAL", Device.OS_ROUTE_TYPE), + Port(port), + Port("")) + else: + ## Other OVSPort + self._cu._port_to_br[port] = br_src + else: + continue