OSDN Git Service

add veth link features
authort.moriyama <t.moriyama@users.sourceforge.jp>
Sat, 8 Jun 2013 19:51:42 +0000 (04:51 +0900)
committert.moriyama <t.moriyama@users.sourceforge.jp>
Sat, 8 Jun 2013 19:51:42 +0000 (04:51 +0900)
linkpair/collect/agent/base_agent.py
linkpair/collect/agent/commandrunner.py
linkpair/collect/agent/ovs_agent.py
linkpair/collect/agent/veth_agent.py
linkpair/collect/collector.py
linkpair/collect/collector_dataset.py
linkpair/collect/utils.py
linkpair/linkobject.py
linkpair/port.py

index b9b475f..f31bd26 100755 (executable)
@@ -16,7 +16,7 @@ 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
+from linkpair.utils.common import CommonUtils
 
 
 class BaseAgent(object):
@@ -34,7 +34,7 @@ class BaseAgent(object):
         self._linkpairs = cd.linkpairs
         self._port_to_br = cd.port_to_br
         self._iface_to_nss = cd.iface_to_nss
-       self._veth_peer = cd.veth_peer
+        self._veth_peers = cd.veth_peers
         self._formatter = formatter
 
         self._u = CommonUtils()
index e40aca3..d50bdd1 100755 (executable)
@@ -11,8 +11,8 @@ from subprocess import Popen, PIPE
 from socket import gethostname
 import shlex
 import paramiko as ssh
-#import ssh
-from linkpair.commonutils import CommonUtils
+# import ssh
+from linkpair.utils.common import CommonUtils
 
 
 class CommandRunner(object):
index e2d3ff3..b22190e 100755 (executable)
@@ -14,6 +14,10 @@ class OVSAgent(BaseAgent):
     '''
     Open vSwitch Collector Agent
     '''
+
+    PORT_TYPE_UNSPECIFIED = "UNSPECIFIED"
+    PORT_PEER_UNSPECIFIED = "UNSPECIFIED"
+
     def run(self):
         self.get_configuration()
 
@@ -25,11 +29,13 @@ class OVSAgent(BaseAgent):
 
         res_ctl = self._runner.exec_cmd("ovs-vsctl get-controller " + br)
         for ctl in res_ctl:
-            br_meta["controller"] = self._u.str_join(br_meta["controller"], ctl.strip(), ", ")
-            
+            br_meta["controller"] = self._u.str_join(
+                br_meta["controller"], ctl.strip(), ", ")
+
         res_mgr = self._runner.exec_cmd("ovs-vsctl get-manager")
         for mgr in res_mgr:
-            br_meta["manager"] = self._u.str_join(br_meta["manager"], mgr.strip(), ", ")
+            br_meta["manager"] = self._u.str_join(
+                br_meta["manager"], mgr.strip(), ", ")
 
         res_ofsw = self._runner.exec_cmd("ovs-ofctl show " + br)
         for ofsw_spec in res_ofsw:
@@ -44,8 +50,7 @@ class OVSAgent(BaseAgent):
                 br_meta["capabilities"] = self._u.d_pop().group(1).strip()
             elif self._u.d_push(re.search(r'actions:(.*)', ofsw_spec)) is not None:
                 br_meta["actions"] = self._u.d_pop().group(1).strip()
-        
-        #print br_meta      
+
         return br_meta
 
     def get_port_metadata(self, port):
@@ -53,7 +58,7 @@ class OVSAgent(BaseAgent):
         res_ovsport = self._runner.exec_cmd("ovs-vsctl show")
         for i in range(0, len(res_ovsport)):
             port_start = res_ovsport[i].strip()
-            if self._u.d_push(re.search(r'Port "*%s"*' % port, port_start)) is not None:
+            if self._u.d_push(re.search(r'Port "?%s"?' % port, port_start)) is not None:
                 for j in range(i + 1, len(res_ovsport)):
                     port_spec = res_ovsport[j].strip()
                     if self._u.d_push(re.search(r'tag: (.*)', port_spec)) is not None:
@@ -61,40 +66,63 @@ class OVSAgent(BaseAgent):
                     elif self._u.d_push(re.search(r'type: (.*)', port_spec)) is not None:
                         port_meta["type"] = self._u.d_pop().group(1).strip()
                     elif self._u.d_push(re.search(r'options: {(.*)}', port_spec)) is not None:
-                        port_options = self._u.d_pop().group(1).strip().split(",")
+                        port_options = self._u.d_pop().group(
+                            1).strip().split(",")
                         for port_option in port_options:
                             (opt_name, opt_value) = port_option.split("=")
                             port_meta[opt_name] = opt_value
                     elif self._u.d_push(re.search(r'Port "*', port_spec)) is not None:
                         break
-                        
-        #print port_meta
+
         return port_meta
+
+    def get_port_type(self, port_meta):
+        if "type" in port_meta:
+            return port_meta["type"]
+        else:
+            return self.PORT_TYPE_UNSPECIFIED
+
+    def get_port_peer(self, port_meta):
+        if self.get_port_type(port_meta) == "patch":
+            return port_meta["peer"]
+        else:
+            return self.PORT_TYPE_UNSPECIFIED
     
+    def get_port_veth_peer(self, port_name):
+        port = self._cu.get_port(port_name)
+        if port != self._cu.PORT_NOT_FOUND:
+            port_meta = port.metadata
+            if port_meta.has_key("veth_peer"):
+                return port_meta["veth_peer"]
+            else:
+                return self.PORT_PEER_UNSPECIFIED
+        else:
+            return self.PORT_PEER_UNSPECIFIED
+            
     def get_configuration(self):
         patch_peers = {}
-
+        veth_peers = {}
+        
         result = self._runner.exec_cmd("ovs-vsctl list-br")
         for br_src in result:
             br_src = br_src.rstrip()
             br_src_meta = self.get_bridge_metadata(br_src)
-            result2 = self._runner.exec_cmd("ovs-dpctl show " + br_src)
-            for port_desc in result2:
-                port_desc = port_desc.rstrip()
-                
+            port_names = self._runner.exec_cmd(
+                "ovs-vsctl list-ports " + br_src)
+            for port_name in port_names:
+                port_name = port_name.rstrip()
+                port_meta = self.get_port_metadata(port_name)
+
                 # patch port
-                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)
+                if self.get_port_type(port_meta) == "patch":
+                    patch_src = port_name
+                    patch_dst = self.get_port_peer(port_meta)
                     patch_peers[patch_src + ":" + patch_dst] = self.PEER_FOUND
 
                     if patch_dst + ":" + patch_src in patch_peers:
                         continue
-                        
-                    patch_src_meta = self.get_port_metadata(patch_src)
+
+                    patch_src_meta = port_meta
                     patch_dst_meta = self.get_port_metadata(patch_dst)
                     result3 = self._runner.exec_cmd(
                         "ovs-vsctl port-to-br " + patch_dst)
@@ -115,62 +143,88 @@ class OVSAgent(BaseAgent):
                             Port(patch_dst, Port.DEFAULT_TYPE, patch_dst_meta),
                             self._formatter.PATCH_FORMAT)
 
+                # veth port
+                elif self.get_port_veth_peer(port_name) != self.PORT_PEER_UNSPECIFIED:
+                    peer_src = port_name
+                    peer_dst = self.get_port_veth_peer(port_name)
+                    veth_peers[peer_src + ":" + peer_dst] = self.PEER_FOUND
+
+                    if peer_dst + ":" + peer_src in veth_peers:
+                        continue
+
+                    peer_src_meta = port_meta
+                    peer_dst_meta = self.get_port_metadata(peer_dst)
+                    result3 = self._runner.exec_cmd(
+                        "ovs-vsctl port-to-br " + peer_dst)
+                    if result3 is not None and len(result3) > 0:
+                        br_dst = result3[0].rstrip()
+                        br_dst_meta = self.get_bridge_metadata(br_dst)
+                        self._cu.add_linkpair(
+                            Device(br_src, Device.BR_TYPE, br_src_meta),
+                            Device(br_dst, Device.BR_TYPE, br_dst_meta),
+                            Port(peer_src, Port.DEFAULT_TYPE, peer_src_meta),
+                            Port(peer_dst, Port.DEFAULT_TYPE, peer_dst_meta),
+                            self._formatter.VETH_FORMAT)
+                    else:
+                        self._cu.add_linkpair(
+                            Device(br_src, Device.BR_TYPE, br_src_meta),
+                            Device("NOT CONNECTED", Device.NOT_CONNECTED_TYPE),
+                            Port(peer_src, Port.DEFAULT_TYPE, peer_src_meta),
+                            Port(peer_dst, Port.DEFAULT_TYPE, peer_dst_meta),
+                            self._formatter.VETH_FORMAT)
+                    
+
                 # none patch port
                 else:
                     # NOT Internal Bridge Port.
-                    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()
-                            port_meta = self.get_port_metadata(port)
-                            
-                            # physical interface
-                            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)) \
-                                        or self._u.d_push(re.match(r'^bond\d+$', port)):
-                                self._cu._port_to_br[port] = br_src
-                                self._cu.add_linkpair(
-                                    Device(br_src, Device.BR_TYPE, br_src_meta),
-                                    Device("Physical NW", Device.PHYNET_TYPE),
-                                    Port(port, Port.DEFAULT_TYPE, port_meta),
-                                    Port(""))
-                            
-                            # tunnel 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)
-                                port2_meta = self.get_port_metadata(port2)
-                                self._cu._port_to_br[port2] = br_src
-                                self._cu.add_linkpair(
-                                    Device(br_src, Device.BR_TYPE, br_src_meta),
-                                    Device("OS Routing", Device.OS_ROUTE_TYPE),
-                                    Port(port, Port.DEFAULT_TYPE, port_meta),
-                                    Port(""))
-
-                            # internal
-                            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, br_src_meta),
-                                        Device(self._iface_to_nss[
-                                               port], Device.NAMESPACE_TYPE),
-                                        Port(port, Port.DEFAULT_TYPE, port_meta),
-                                        Port(""),
-                                        self._formatter.NAMESPACE_FORMAT)
-                                else:
-                                    self._cu.add_linkpair(
-                                        Device(br_src, Device.BR_TYPE, br_src_meta),
-                                        Device(
-                                            "INTERNAL", Device.OS_ROUTE_TYPE),
-                                        Port(port, Port.DEFAULT_TYPE, port_meta),
-                                        Port(""))
-                            else:
-                                ## Other OVSPort
-                                self._cu._port_to_br[port] = br_src
+                    if self.get_port_type(port_meta) != "internal":
+
+                        # physical interface
+                        if self._u.d_push(re.match(r'^eth\d+$', port_name)) \
+                            or self._u.d_push(re.match(r'^em\d+$', port_name)) \
+                                or self._u.d_push(re.match(r'^igb\d+$', port_name)) \
+                                or self._u.d_push(re.match(r'^bond\d+$', port_name)):
+                            self._cu._port_to_br[port_name] = br_src
+                            self._cu.add_linkpair(
+                                Device(br_src, Device.BR_TYPE, br_src_meta),
+                                Device("Physical NW", Device.PHYNET_TYPE),
+                                Port(port_name, Port.DEFAULT_TYPE, port_meta),
+                                Port(""))
+
+                        # tunnel port
+                        elif self._u.d_push(re.match(r'(vxlan\d+)', port_name)) \
+                            or self._u.d_push(re.match(r'(gre\d+)', port_name)) \
+                                or self._u.d_push(re.match(r'(gre-\d+)', port_name)):
+                            self._cu._port_to_br[port_name] = br_src
+                            self._cu.add_linkpair(
+                                Device(br_src, Device.BR_TYPE, br_src_meta),
+                                Device("OS Routing", Device.OS_ROUTE_TYPE),
+                                Port(port_name, Port.DEFAULT_TYPE, port_meta),
+                                Port(""))
+
                         else:
-                            continue
+                            ## Other OVSPort
+                            self._cu._port_to_br[port_name] = br_src
+
+                    # internal
+                    elif self.get_port_type(port_meta) == "internal":
+                        if port_name in self._iface_to_nss:
+                            self._cu.add_linkpair(
+                                Device(br_src, Device.BR_TYPE, br_src_meta),
+                                Device(self._iface_to_nss[
+                                       port], Device.NAMESPACE_TYPE),
+                                Port(port_name, Port.DEFAULT_TYPE, port_meta),
+                                Port(""),
+                                self._formatter.NAMESPACE_FORMAT)
+                        else:
+                            self._cu.add_linkpair(
+                                Device(br_src, Device.BR_TYPE, br_src_meta),
+                                Device(
+                                    "INTERNAL", Device.OS_ROUTE_TYPE),
+                                Port(port_name, Port.DEFAULT_TYPE, port_meta),
+                                Port(""))
+                    # else:
+                    #        ## Other OVSPort
+                    #        self._cu._port_to_br[port_name] = br_src
+                    else:
+                        continue
index 72b7df3..7ef470c 100755 (executable)
@@ -36,5 +36,8 @@ class VethAgent(BaseAgent):
                             if self._u.d_push(re.match(r'^%s:\s(\S+):' % peer_if_no, ip_link_line)) is not None:
                                 match = self._u.d_pop()
                                 peer_if = match.group(1)
-                                self._veth_peer[if_name] = peer_if
-
+                                self._veth_peers[if_name] = peer_if
+                                port_meta = {"veth_peer":peer_if}
+                                self._cu.add_port(Port(if_name, Port.DEFAULT_TYPE, port_meta))
+                                port_meta2 = {"veth_peer":if_name}
+                                self._cu.add_port(Port(peer_if, Port.DEFAULT_TYPE, port_meta2))
index 17ce670..ebd6953 100755 (executable)
@@ -11,7 +11,7 @@ from linkpair.device import Device
 from linkpair.port import Port
 from linkpair.linkpair import LinkPair
 from linkpair.formatter.grapheasy import GraphEasyFormatter
-from linkpair.commonutils import CommonUtils
+from linkpair.utils.common import CommonUtils
 from linkpair.dbutils import DBUtils
 from linkpair.collect.utils import CollectUtils
 from linkpair.collect.collector_dataset import CollectorDataset
@@ -33,6 +33,8 @@ class Collector(object):
     PEER_FOUND = 1
 
     def __init__(self, remote_desc, dbu, formatter=GraphEasyFormatter()):
+        self._devices = {}
+        self._ports = {}
         self._os_info = {}
         self._linkpairs = []
         self._port_to_br = {}
@@ -59,7 +61,8 @@ class Collector(object):
 
     def run(self):
         cd = CollectorDataset(
-            self._os_info, self._linkpairs, self._port_to_br, self._iface_to_nss, self._veth_peer)
+            self._devices, self._ports, self._os_info, self._linkpairs,
+            self._port_to_br, self._iface_to_nss, self._veth_peer)
         cu = CollectUtils(
             cd, self._dbu, self._formatter)
         os_agent = LinuxAgent(
index 4a95cd0..4ad69bf 100755 (executable)
@@ -9,9 +9,11 @@ from linkpair.linkpair import LinkPair
 
 class CollectorDataset(object):
 
-    def __init__(self, os_info, linkpairs, port_to_br, iface_to_nss, veth_peer):
+    def __init__(self, devices, ports, os_info, linkpairs, port_to_br, iface_to_nss, veth_peers):
+        self.devices = devices
+        self.ports = ports
         self.os_info = os_info
         self.linkpairs = linkpairs
         self.port_to_br = port_to_br
         self.iface_to_nss = iface_to_nss
-        self.veth_peer = veth_peer
+        self.veth_peers = veth_peers
index bd345fd..bc94a29 100755 (executable)
@@ -12,7 +12,7 @@ from linkpair.device import Device
 from linkpair.port import Port
 from linkpair.linkpair import LinkPair
 from linkpair.formatter.grapheasy import GraphEasyFormatter
-from linkpair.commonutils import CommonUtils
+from linkpair.utils.common import CommonUtils
 from linkpair.dbutils import DBUtils
 from linkpair.collect.agent.commandrunner import CommandRunner
 
@@ -24,36 +24,80 @@ class CollectUtils(object):
     '''
 
     PEER_FOUND = 1
+    DEVICE_NOT_FOUND = -1
+    PORT_NOT_FOUND = -1
 
     def __init__(self, cd, dbu, formatter=GraphEasyFormatter()):
+        self._devices = cd.devices
+        self._ports = cd.ports
         self._linkpairs = cd.linkpairs
         self._port_to_br = cd.port_to_br
         self._iface_to_nss = cd.iface_to_nss
-        self._veth_peer = cd.veth_peer
+        self._veth_peers = cd.veth_peers
         self._u = CommonUtils()
         self._db_enable = False
         self._dbu = dbu
         self._formatter = formatter
 
     def add_linkpair(self, dev1, dev2, port1, port2, format=""):
+        if self._devices.has_key(dev1.label):
+            self._devices[dev1.label].metadata.update(dev1.metadata)
+        else:
+            self.add_device(dev1)
+        if self._devices.has_key(dev2.label):
+            self._devices[dev2.label].metadata.update(dev2.metadata)
+        else:
+            self.add_device(dev2)
+        if self._ports.has_key(port1.label):
+            self._ports[port1.label].metadata.update(port1.metadata)
+        else:
+            self.add_port(port1)
+        if self._ports.has_key(port2.label):
+            self._ports[port2.label].metadata.update(port2.metadata)
+        else:
+            self.add_port(port2)
         if format == "":
             format = self._formatter.DEFAULT_FORMAT
+
         self._linkpairs.append(
-            LinkPair(dev1, dev2, port1, port2, format))
+            LinkPair(
+                self._devices[dev1.label],
+                self._devices[dev2.label],
+                self._ports[port1.label],
+                self._ports[port2.label],
+                format))
 #        if self._dbu.enable_db:
 #            insert_record(fmt, src, src_style, label, dst, dst_style)
 
+    def add_device(self, device):
+        if self._devices.has_key(device.label):
+            self._devices[device.label].metadata.update(device.metadata)
+        else:
+            self._devices[device.label] = device
+        
+    def add_port(self, port):
+        if self._ports.has_key(port.label):
+            self._ports[port.label].metadata.update(port.metadata)
+        else:
+            self._ports[port.label] = port
+            
+    def get_port(self, port_name):
+        if self._ports.has_key(port_name):
+            return self._ports[port_name]
+        else:
+            return self.PORT_NOT_FOUND
+            
     def get_linkpairs(self):
         return self._linkpairs
 
     def drop_linkpairs(self):
         self._linkpairs = []
 
-    def get_veth_peer(self):
-        return self._veth_peer
+    def get_veth_peers(self):
+        return self._veth_peers
 
     def drop_veth_peer(self):
-        self._veth_peer = []
+        self._veth_peers = []
 
     def regist_to_port2br(self, device, bridge):
         if device in self._port_to_br:
@@ -64,4 +108,3 @@ class CollectUtils(object):
         else:
             self._port_to_br[device] = bridge
             return bridge
-
index f8ff911..c40fcad 100755 (executable)
@@ -33,10 +33,10 @@ class LinkObject(object):
     def attr():
         def get(self, attr):
             return self.metadata[attr]
-        
+
         def set(self, attr, attr_value):
             self.metadata[attr] = attr_value
-    
+
     @apply
     def type():
         def get(self):
index 6635ee3..35e5db3 100755 (executable)
@@ -10,7 +10,7 @@ from linkobject import LinkObject
 class Port(LinkObject):
     DEFAULT_TYPE = 1
 
-    def __init__(self, label, type=DEFAULT_TYPE , metadata={}):
+    def __init__(self, label, type=DEFAULT_TYPE, metadata={}):
         self.label = label
         self.type = type
         self.metadata = metadata