OSDN Git Service

ba64ab715a73b4b5648f3e1bb0e425efa6715f1c
[ti2/ti2.git] / linkpair / collect / agent / ovs_agent.py
1 # vim: tabstop=4 shiftwidth=4 softtabstop=4
2 # -*- coding: utf-8 -*-
3 #
4
5 __version__ = '1.1'
6
7 import re
8 from linkpair.device import Device
9 from linkpair.port import Port
10 from linkpair.collect.agent.base_agent import BaseAgent
11
12
13 class OVSAgent(BaseAgent):
14     '''
15     Open vSwitch Collector Agent
16     '''
17
18     def run(self):
19         self.get_configuration()
20
21     def get_bridge_metadata(self, br):
22         br_meta = {}
23         br_meta["dpid"] = ""
24         br_meta["controller"] = ""
25         br_meta["manager"] = ""
26
27         res_ctl = self._runner.exec_cmd("ovs-vsctl get-controller " + br)
28         for ctl in res_ctl:
29             br_meta["controller"] = self._u.str_join(
30                 br_meta["controller"], ctl.strip(), ", ")
31
32         res_mgr = self._runner.exec_cmd("ovs-vsctl get-manager")
33         for mgr in res_mgr:
34             br_meta["manager"] = self._u.str_join(
35                 br_meta["manager"], mgr.strip(), ", ")
36
37         res_ofsw = self._runner.exec_cmd("ovs-ofctl show " + br)
38         for ofsw_spec in res_ofsw:
39             ofsw_spec = ofsw_spec.strip()
40             if self._u.d_push(re.search(r': dpid:(.*)', ofsw_spec)) is not None:
41                 br_meta["dpid"] = self._u.d_pop().group(1).strip()
42             elif self._u.d_push(re.search(r'n_tables:(.*), n_buffers:(.*)', ofsw_spec)) is not None:
43                 match = self._u.d_pop()
44                 br_meta["tables"] = match.group(1).strip()
45                 br_meta["buffers"] = match.group(2).strip()
46             elif self._u.d_push(re.search(r'capabilities:(.*)', ofsw_spec)) is not None:
47                 br_meta["capabilities"] = self._u.d_pop().group(1).strip()
48             elif self._u.d_push(re.search(r'actions:(.*)', ofsw_spec)) is not None:
49                 br_meta["actions"] = self._u.d_pop().group(1).strip()
50
51         return br_meta
52
53     def get_port_metadata(self, port_name):
54         port_meta = {}
55         exist_port = self._cu.get_port(port_name)
56         if exist_port != self._cu.PORT_NOT_FOUND:
57             port_meta = exist_port.metadata
58
59         res_ovsport = self._runner.exec_cmd("ovs-vsctl show")
60         for i in range(0, len(res_ovsport)):
61             port_start = res_ovsport[i].strip()
62             if self._u.d_push(re.search(r'Port "?%s"?' % port_name, port_start)) is not None:
63                 for j in range(i + 1, len(res_ovsport)):
64                     port_spec = res_ovsport[j].strip()
65                     if self._u.d_push(re.search(r'tag: (.*)', port_spec)) is not None:
66                         port_meta["tag"] = self._u.d_pop().group(1).strip()
67                     elif self._u.d_push(re.search(r'type: (.*)', port_spec)) is not None:
68                         port_meta["type"] = self._u.d_pop().group(1).strip()
69                     elif self._u.d_push(re.search(r'options: {(.*)}', port_spec)) is not None:
70                         port_options = self._u.d_pop().group(
71                             1).strip().split(",")
72                         for port_option in port_options:
73                             (opt_name, opt_value) = port_option.split("=")
74                             opt_name = opt_name.strip()
75                             opt_value = opt_value.strip()
76                             port_meta[opt_name] = opt_value
77                     elif self._u.d_push(re.search(r'Port "*', port_spec)) is not None:
78                         break
79
80         return port_meta
81
82     def get_configuration(self):
83         patch_peers = {}
84         veth_peers = {}
85
86         result = self._runner.exec_cmd("ovs-vsctl list-br")
87         for br_src in result:
88             br_src = br_src.rstrip()
89             br_src_meta = self.get_bridge_metadata(br_src)
90             port_names = self._runner.exec_cmd(
91                 "ovs-vsctl list-ports " + br_src)
92             for port_name in port_names:
93                 port_name = port_name.rstrip()
94                 port_meta = self.get_port_metadata(port_name)
95
96                 # patch port
97                 if self._cu.get_port_type(port_meta) == "patch":
98                     patch_src = port_name
99                     patch_dst = self._cu.get_port_peer(port_meta)
100                     patch_peers[patch_src + ":" + patch_dst] = self.PEER_FOUND
101
102                     if patch_dst + ":" + patch_src in patch_peers:
103                         continue
104
105                     patch_src_meta = port_meta
106                     patch_dst_meta = self.get_port_metadata(patch_dst)
107                     result3 = self._runner.exec_cmd(
108                         "ovs-vsctl port-to-br " + patch_dst)
109                     if result3 is not None and len(result3) > 0:
110                         br_dst = result3[0].rstrip()
111                         br_dst_meta = self.get_bridge_metadata(br_dst)
112                         self._cu.add_linkpair(
113                             Device(br_src, Device.BR_TYPE, br_src_meta),
114                             Device(br_dst, Device.BR_TYPE, br_dst_meta),
115                             Port(patch_src, Port.DEFAULT_TYPE, patch_src_meta),
116                             Port(patch_dst, Port.DEFAULT_TYPE, patch_dst_meta),
117                             self._formatter.PATCH_FORMAT)
118                     else:
119                         self._cu.add_linkpair(
120                             Device(br_src, Device.BR_TYPE, br_src_meta),
121                             Device("NOT CONNECTED", Device.NOT_CONNECTED_TYPE),
122                             Port(patch_src, Port.DEFAULT_TYPE, patch_src_meta),
123                             Port(patch_dst, Port.DEFAULT_TYPE, patch_dst_meta),
124                             self._formatter.PATCH_FORMAT)
125
126                 # veth port
127                 elif self._cu.get_port_veth_peer(port_name) != self._cu.PORT_PEER_UNSPECIFIED:
128                     peer_src = port_name
129                     peer_dst = self._cu.get_port_veth_peer(port_name)
130                     veth_peers[peer_src + ":" + peer_dst] = self.PEER_FOUND
131
132                     if peer_dst + ":" + peer_src in veth_peers:
133                         continue
134
135                     peer_src_meta = port_meta
136                     peer_dst_meta = self.get_port_metadata(peer_dst)
137                     result3 = self._runner.exec_cmd(
138                         "ovs-vsctl port-to-br " + peer_dst)
139                     if result3 is not None and len(result3) > 0:
140                         br_dst = result3[0].rstrip()
141                         br_dst_meta = self.get_bridge_metadata(br_dst)
142                         self._cu.add_linkpair(
143                             Device(br_src, Device.BR_TYPE, br_src_meta),
144                             Device(br_dst, Device.BR_TYPE, br_dst_meta),
145                             Port(peer_src, Port.DEFAULT_TYPE, peer_src_meta),
146                             Port(peer_dst, Port.DEFAULT_TYPE, peer_dst_meta),
147                             self._formatter.VETH_FORMAT)
148                     else:
149                         self._cu.add_linkpair(
150                             Device(br_src, Device.BR_TYPE, br_src_meta),
151                             Device("NOT CONNECTED", Device.NOT_CONNECTED_TYPE),
152                             Port(peer_src, Port.DEFAULT_TYPE, peer_src_meta),
153                             Port(peer_dst, Port.DEFAULT_TYPE, peer_dst_meta),
154                             self._formatter.VETH_FORMAT)
155
156                 # none patch/veth port
157                 else:
158                     # NOT Internal Bridge Port.
159                     if self._cu.get_port_type(port_meta) != "internal":
160
161                         # physical interface
162                         if self._u.d_push(re.match(r'^eth\d+$', port_name)) \
163                             or self._u.d_push(re.match(r'^em\d+$', port_name)) \
164                                 or self._u.d_push(re.match(r'^igb\d+$', port_name)) \
165                                 or self._u.d_push(re.match(r'^bond\d+$', port_name)):
166                             self._cu._port_to_br[port_name] = br_src
167                             self._cu.add_linkpair(
168                                 Device(br_src, Device.BR_TYPE, br_src_meta),
169                                 Device("Physical NW", Device.PHYNET_TYPE),
170                                 Port(port_name, Port.DEFAULT_TYPE, port_meta),
171                                 Port(""))
172
173                         # tunnel port
174                         elif self._u.d_push(re.match(r'(vxlan\d+)', port_name)) \
175                             or self._cu.get_port_type(port_meta) == "gre" \
176                                 or self._cu.get_port_type(port_meta) == "stt":
177                             self._cu._port_to_br[port_name] = br_src
178                             self._cu.add_linkpair(
179                                 Device(br_src, Device.BR_TYPE, br_src_meta),
180                                 Device("OS Routing", Device.OS_ROUTE_TYPE),
181                                 Port(port_name, Port.DEFAULT_TYPE, port_meta),
182                                 Port(""),
183                                 self._formatter.OS_ROUTING_FORMAT)
184
185                         else:
186                             ## Other OVSPort
187                             #### VLAN interface
188                             if self._cu.get_port_vlan_master_if(port_meta) != self._cu.PORT_VLAN_UNSPECIFIED:
189                                 master_if = self._cu.get_port_vlan_master_if(
190                                     port_meta)
191                                 if master_if in self._cu._port_to_br:
192                                     self._cu._port_to_br[port_name] = br_src
193                                     port_src = port_name
194                                     port_src_meta = port_meta
195                                     port_dst = master_if
196                                     port_dst_obj = self._cu.get_port(master_if)
197                                     br_dst = self._cu._port_to_br[master_if]
198                                     br_dst_obj = self._cu.get_device(br_dst)
199                                     self._cu.add_linkpair(
200                                         Device(
201                                             br_src, Device.BR_TYPE, br_src_meta),
202                                         br_dst_obj,
203                                         Port(
204                                             port_src, Port.DEFAULT_TYPE, port_src_meta),
205                                         port_dst_obj,
206                                         self._formatter.VLAN_DIST_FORMAT)
207
208                                 elif self._u.d_push(re.match(r'^eth\d+$', master_if)) \
209                                     or self._u.d_push(re.match(r'^em\d+$', master_if)) \
210                                         or self._u.d_push(re.match(r'^igb\d+$', master_if)) \
211                                         or self._u.d_push(re.match(r'^bond\d+$', master_if)):
212                                     self._cu._port_to_br[port_name] = br_src
213                                     self._cu.add_linkpair(
214                                         Device(
215                                             br_src, Device.BR_TYPE, br_src_meta),
216                                         Device(
217                                             "Physical NW", Device.PHYNET_TYPE),
218                                         Port(
219                                             port_name, Port.DEFAULT_TYPE, port_meta),
220                                         Port(""))
221                             else:
222                                 self._cu._port_to_br[port_name] = br_src
223                                 self._cu.add_linkpair(
224                                     Device(
225                                         br_src, Device.BR_TYPE, br_src_meta),
226                                     Device(
227                                         "NOT CONNECTED", Device.NOT_CONNECTED_TYPE),
228                                     Port(
229                                         port_name, Port.DEFAULT_TYPE, port_meta),
230                                     Port(""))
231
232                     # internal
233                     elif self._cu.get_port_type(port_meta) == "internal":
234                         if port_name in self._iface_to_nss:
235                             self._cu.add_linkpair(
236                                 Device(br_src, Device.BR_TYPE, br_src_meta),
237                                 Device(self._iface_to_nss[
238                                        port], Device.NAMESPACE_TYPE),
239                                 Port(port_name, Port.DEFAULT_TYPE, port_meta),
240                                 Port(""),
241                                 self._formatter.NAMESPACE_FORMAT)
242                         else:
243                             self._cu.add_linkpair(
244                                 Device(br_src, Device.BR_TYPE, br_src_meta),
245                                 Device(
246                                     "INTERNAL", Device.OS_ROUTE_TYPE),
247                                 Port(port_name, Port.DEFAULT_TYPE, port_meta),
248                                 Port(""))
249                     # else:
250                     #        ## Other OVSPort
251                     #        self._cu._port_to_br[port_name] = br_src
252                     else:
253                         continue