1 # vim: tabstop=4 shiftwidth=4 softtabstop=4
2 # -*- coding: utf-8 -*-
8 from linkpair.device import Device
9 from linkpair.port import Port
10 from linkpair.collect.agent.base_agent import BaseAgent
13 class OVSAgent(BaseAgent):
15 Open vSwitch Collector Agent
18 PORT_TYPE_UNSPECIFIED = "UNSPECIFIED"
19 PORT_PEER_UNSPECIFIED = "UNSPECIFIED"
22 self.get_configuration()
24 def get_bridge_metadata(self, br):
27 br_meta["controller"] = ""
28 br_meta["manager"] = ""
30 res_ctl = self._runner.exec_cmd("ovs-vsctl get-controller " + br)
32 br_meta["controller"] = self._u.str_join(
33 br_meta["controller"], ctl.strip(), ", ")
35 res_mgr = self._runner.exec_cmd("ovs-vsctl get-manager")
37 br_meta["manager"] = self._u.str_join(
38 br_meta["manager"], mgr.strip(), ", ")
40 res_ofsw = self._runner.exec_cmd("ovs-ofctl show " + br)
41 for ofsw_spec in res_ofsw:
42 ofsw_spec = ofsw_spec.strip()
43 if self._u.d_push(re.search(r': dpid:(.*)', ofsw_spec)) is not None:
44 br_meta["dpid"] = self._u.d_pop().group(1).strip()
45 elif self._u.d_push(re.search(r'n_tables:(.*), n_buffers:(.*)', ofsw_spec)) is not None:
46 match = self._u.d_pop()
47 br_meta["tables"] = match.group(1).strip()
48 br_meta["buffers"] = match.group(2).strip()
49 elif self._u.d_push(re.search(r'capabilities:(.*)', ofsw_spec)) is not None:
50 br_meta["capabilities"] = self._u.d_pop().group(1).strip()
51 elif self._u.d_push(re.search(r'actions:(.*)', ofsw_spec)) is not None:
52 br_meta["actions"] = self._u.d_pop().group(1).strip()
56 def get_port_metadata(self, port):
58 res_ovsport = self._runner.exec_cmd("ovs-vsctl show")
59 for i in range(0, len(res_ovsport)):
60 port_start = res_ovsport[i].strip()
61 if self._u.d_push(re.search(r'Port "?%s"?' % port, port_start)) is not None:
62 for j in range(i + 1, len(res_ovsport)):
63 port_spec = res_ovsport[j].strip()
64 if self._u.d_push(re.search(r'tag: (.*)', port_spec)) is not None:
65 port_meta["tag"] = self._u.d_pop().group(1).strip()
66 elif self._u.d_push(re.search(r'type: (.*)', port_spec)) is not None:
67 port_meta["type"] = self._u.d_pop().group(1).strip()
68 elif self._u.d_push(re.search(r'options: {(.*)}', port_spec)) is not None:
69 port_options = self._u.d_pop().group(
71 for port_option in port_options:
72 (opt_name, opt_value) = port_option.split("=")
73 port_meta[opt_name] = opt_value
74 elif self._u.d_push(re.search(r'Port "*', port_spec)) is not None:
79 def get_port_type(self, port_meta):
80 if "type" in port_meta:
81 return port_meta["type"]
83 return self.PORT_TYPE_UNSPECIFIED
85 def get_port_peer(self, port_meta):
86 if self.get_port_type(port_meta) == "patch":
87 return port_meta["peer"]
89 return self.PORT_TYPE_UNSPECIFIED
91 def get_port_veth_peer(self, port_name):
92 port = self._cu.get_port(port_name)
93 if port != self._cu.PORT_NOT_FOUND:
94 port_meta = port.metadata
95 if "veth_peer" in port_meta:
96 return port_meta["veth_peer"]
98 return self.PORT_PEER_UNSPECIFIED
100 return self.PORT_PEER_UNSPECIFIED
102 def get_configuration(self):
106 result = self._runner.exec_cmd("ovs-vsctl list-br")
107 for br_src in result:
108 br_src = br_src.rstrip()
109 br_src_meta = self.get_bridge_metadata(br_src)
110 port_names = self._runner.exec_cmd(
111 "ovs-vsctl list-ports " + br_src)
112 for port_name in port_names:
113 port_name = port_name.rstrip()
114 port_meta = self.get_port_metadata(port_name)
117 if self.get_port_type(port_meta) == "patch":
118 patch_src = port_name
119 patch_dst = self.get_port_peer(port_meta)
120 patch_peers[patch_src + ":" + patch_dst] = self.PEER_FOUND
122 if patch_dst + ":" + patch_src in patch_peers:
125 patch_src_meta = port_meta
126 patch_dst_meta = self.get_port_metadata(patch_dst)
127 result3 = self._runner.exec_cmd(
128 "ovs-vsctl port-to-br " + patch_dst)
129 if result3 is not None and len(result3) > 0:
130 br_dst = result3[0].rstrip()
131 br_dst_meta = self.get_bridge_metadata(br_dst)
132 self._cu.add_linkpair(
133 Device(br_src, Device.BR_TYPE, br_src_meta),
134 Device(br_dst, Device.BR_TYPE, br_dst_meta),
135 Port(patch_src, Port.DEFAULT_TYPE, patch_src_meta),
136 Port(patch_dst, Port.DEFAULT_TYPE, patch_dst_meta),
137 self._formatter.PATCH_FORMAT)
139 self._cu.add_linkpair(
140 Device(br_src, Device.BR_TYPE, br_src_meta),
141 Device("NOT CONNECTED", Device.NOT_CONNECTED_TYPE),
142 Port(patch_src, Port.DEFAULT_TYPE, patch_src_meta),
143 Port(patch_dst, Port.DEFAULT_TYPE, patch_dst_meta),
144 self._formatter.PATCH_FORMAT)
147 elif self.get_port_veth_peer(port_name) != self.PORT_PEER_UNSPECIFIED:
149 peer_dst = self.get_port_veth_peer(port_name)
150 veth_peers[peer_src + ":" + peer_dst] = self.PEER_FOUND
152 if peer_dst + ":" + peer_src in veth_peers:
155 peer_src_meta = port_meta
156 peer_dst_meta = self.get_port_metadata(peer_dst)
157 result3 = self._runner.exec_cmd(
158 "ovs-vsctl port-to-br " + peer_dst)
159 if result3 is not None and len(result3) > 0:
160 br_dst = result3[0].rstrip()
161 br_dst_meta = self.get_bridge_metadata(br_dst)
162 self._cu.add_linkpair(
163 Device(br_src, Device.BR_TYPE, br_src_meta),
164 Device(br_dst, Device.BR_TYPE, br_dst_meta),
165 Port(peer_src, Port.DEFAULT_TYPE, peer_src_meta),
166 Port(peer_dst, Port.DEFAULT_TYPE, peer_dst_meta),
167 self._formatter.VETH_FORMAT)
169 self._cu.add_linkpair(
170 Device(br_src, Device.BR_TYPE, br_src_meta),
171 Device("NOT CONNECTED", Device.NOT_CONNECTED_TYPE),
172 Port(peer_src, Port.DEFAULT_TYPE, peer_src_meta),
173 Port(peer_dst, Port.DEFAULT_TYPE, peer_dst_meta),
174 self._formatter.VETH_FORMAT)
178 # NOT Internal Bridge Port.
179 if self.get_port_type(port_meta) != "internal":
182 if self._u.d_push(re.match(r'^eth\d+$', port_name)) \
183 or self._u.d_push(re.match(r'^em\d+$', port_name)) \
184 or self._u.d_push(re.match(r'^igb\d+$', port_name)) \
185 or self._u.d_push(re.match(r'^bond\d+$', port_name)):
186 self._cu._port_to_br[port_name] = br_src
187 self._cu.add_linkpair(
188 Device(br_src, Device.BR_TYPE, br_src_meta),
189 Device("Physical NW", Device.PHYNET_TYPE),
190 Port(port_name, Port.DEFAULT_TYPE, port_meta),
194 elif self._u.d_push(re.match(r'(vxlan\d+)', port_name)) \
195 or self._u.d_push(re.match(r'(gre\d+)', port_name)) \
196 or self._u.d_push(re.match(r'(gre-\d+)', port_name)):
197 self._cu._port_to_br[port_name] = br_src
198 self._cu.add_linkpair(
199 Device(br_src, Device.BR_TYPE, br_src_meta),
200 Device("OS Routing", Device.OS_ROUTE_TYPE),
201 Port(port_name, Port.DEFAULT_TYPE, port_meta),
206 self._cu._port_to_br[port_name] = br_src
209 elif self.get_port_type(port_meta) == "internal":
210 if port_name in self._iface_to_nss:
211 self._cu.add_linkpair(
212 Device(br_src, Device.BR_TYPE, br_src_meta),
213 Device(self._iface_to_nss[
214 port], Device.NAMESPACE_TYPE),
215 Port(port_name, Port.DEFAULT_TYPE, port_meta),
217 self._formatter.NAMESPACE_FORMAT)
219 self._cu.add_linkpair(
220 Device(br_src, Device.BR_TYPE, br_src_meta),
222 "INTERNAL", Device.OS_ROUTE_TYPE),
223 Port(port_name, Port.DEFAULT_TYPE, port_meta),
227 # self._cu._port_to_br[port_name] = br_src