backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / services / protocols / ovsdb / api.py
1 # Copyright (c) 2014 Rackspace Hosting
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 import uuid
17
18 from ryu.lib import dpid as dpidlib
19 from ryu.services.protocols.ovsdb import event as ovsdb_event
20
21
22 def _get_table_row(table, attr_name, attr_value, tables):
23     sentinel = object()
24
25     for row in tables[table].rows.values():
26         if getattr(row, attr_name, sentinel) == attr_value:
27             return row
28
29
30 def _get_controller(tables, attr_val, attr_name='target'):
31     return _get_table_row('Controller', attr_name, attr_val, tables=tables)
32
33
34 def _get_bridge(tables, attr_val, attr_name='name'):
35     return _get_table_row('Bridge', attr_name, attr_val, tables=tables)
36
37
38 def _get_port(tables, attr_val, attr_name='name'):
39     return _get_table_row('Port', attr_name, attr_val, tables=tables)
40
41
42 def _get_iface(tables, attr_val, attr_name='name'):
43     return _get_table_row('Interface', attr_name, attr_val, tables=tables)
44
45
46 def match_row(manager, system_id, table, fn):
47     def _match_row(tables):
48         return next((r for r in tables[table].rows.values()
49                      if fn(r)), None)
50
51     request_to_get_tables = ovsdb_event.EventReadRequest(system_id,
52                                                          _match_row)
53     reply_to_get_tables = manager.send_request(request_to_get_tables)
54     return reply_to_get_tables.result
55
56
57 def match_rows(manager, system_id, table, fn):
58     def _match_rows(tables):
59         return (r for r in tables[table].rows.values() if fn(r))
60
61     request = ovsdb_event.EventReadRequest(system_id, _match_rows)
62     reply = manager.send_request(request)
63     return reply.result
64
65
66 def row_by_name(manager, system_id, name, table='Bridge', fn=None):
67     matched_row = match_row(manager, system_id, table,
68                             lambda row: row.name == name)
69
70     if fn is not None:
71         return fn(matched_row)
72
73     return matched_row
74
75
76 def rows_by_external_id(manager, system_id, key, value,
77                         table='Bridge', fn=None):
78     matched_rows = match_rows(manager, system_id, table,
79                               lambda r: (key in r.external_ids and
80                                          r.external_ids.get(key) == value))
81
82     if matched_rows and fn is not None:
83         return [fn(row) for row in matched_rows]
84
85     return matched_rows
86
87
88 def rows_by_other_config(manager, system_id, key, value,
89                          table='Bridge', fn=None):
90     matched_rows = match_rows(manager, system_id, table,
91                               lambda r: (key in r.other_config and
92                                          r.other_config.get(key) == value))
93
94     if matched_rows and fn is not None:
95         return [fn(row) for row in matched_rows]
96
97     return matched_rows
98
99
100 def get_column_value(manager, table, record, column):
101     """
102     Example : To get datapath_id from Bridge table
103     get_column_value('Bridge', <bridge name>, 'datapath_id').strip('"')
104     """
105     row = row_by_name(manager, record, table)
106     value = getattr(row, column, "")
107
108     if isinstance(value, list) and len(value) == 1:
109         value = value[0]
110
111     return str(value)
112
113
114 def get_iface_by_name(manager, system_id, name, fn=None):
115     iface = row_by_name(manager, system_id, name, 'Interface')
116
117     if fn is not None:
118         return fn(iface)
119
120     return iface
121
122
123 def get_ifaces_by_external_id(manager, system_id, key, value, fn=None):
124     return rows_by_external_id(manager, system_id, key, value,
125                                'Interface', fn)
126
127
128 def get_ifaces_by_other_config(manager, system_id, key, value, fn=None):
129     return rows_by_other_config(manager, system_id, key, value,
130                                 'Interface', fn)
131
132
133 def get_port_by_name(manager, system_id, name, fn=None):
134     port = row_by_name(manager, system_id, name, 'Port')
135
136     if fn is not None:
137         return fn(port)
138
139     return port
140
141
142 def get_bridge_for_iface_name(manager, system_id, iface_name, fn=None):
143     iface = row_by_name(manager, system_id, iface_name, 'Interface')
144     port = match_row(manager, system_id, 'Port',
145                      lambda x: iface in x.interfaces)
146     bridge = match_row(manager, system_id, 'Bridge',
147                        lambda x: port in x.ports)
148
149     if fn is not None:
150         return fn(bridge)
151
152     return bridge
153
154
155 def get_table(manager, system_id, name):
156     def _get_table(tables):
157         return tables[name]
158
159     request_to_get_tables = ovsdb_event.EventReadRequest(system_id,
160                                                          _get_table)
161     reply_to_get_tables = manager.send_request(request_to_get_tables)
162     return reply_to_get_tables.result
163
164
165 def get_bridge_by_datapath_id(manager, system_id, datapath_id, fn=None):
166     def _match_fn(row):
167         row_dpid = dpidlib.str_to_dpid(str(row.datapath_id[0]))
168         return row_dpid == datapath_id
169
170     bridge = match_row(manager, system_id, 'Bridge', _match_fn)
171
172     if fn is not None:
173         return fn(bridge)
174
175     return bridge
176
177
178 def get_datapath_ids_for_systemd_id(manager, system_id):
179     def _get_dp_ids(tables):
180         dp_ids = []
181
182         bridges = tables.get('Bridge')
183
184         if not bridges:
185             return dp_ids
186
187         for bridge in bridges.rows.values():
188             datapath_ids = bridge.datapath_id
189             dp_ids.extend(dpidlib.str_to_dpid(dp_id) for dp_id in datapath_ids)
190
191         return dp_ids
192
193     request = ovsdb_event.EventReadRequest(system_id, _get_dp_ids)
194     reply = manager.send_request(request)
195     return reply.result
196
197
198 def get_system_id_for_datapath_id(manager, datapath_id):
199     def _get_dp_ids(tables):
200         bridges = tables.get('Bridge')
201
202         if not bridges:
203             return None
204
205         for bridge in bridges.rows.values():
206             datapath_ids = [dpidlib.str_to_dpid(dp_id)
207                             for dp_id in bridge.datapath_id]
208
209             if datapath_id in datapath_ids:
210                 openvswitch = tables['Open_vSwitch'].rows
211
212                 if openvswitch:
213                     row = openvswitch.get(list(openvswitch.keys())[0])
214                     return row.external_ids.get('system-id')
215
216         return None
217
218     request = ovsdb_event.EventReadRequest(None, _get_dp_ids)
219     reply = manager.send_request(request)
220
221     # NOTE(jkoelker) Bulk reads return a tuple of (system_id, result)
222     for result in reply.result:
223         if result[1]:
224             return result[0]
225
226     return None
227
228
229 def get_bridges_by_system_id(manager, system_id, fn=None):
230     bridges = get_table(manager, system_id, 'Bridge').rows.values()
231
232     if fn is not None:
233         return fn(bridges)
234
235     return bridges
236
237
238 def bridge_exists(manager, system_id, bridge_name):
239     return bool(row_by_name(manager, system_id, bridge_name))
240
241
242 def port_exists(manager, system_id, port_name):
243     return bool(row_by_name(manager, system_id, port_name, 'Port'))
244
245
246 def set_external_id(manager, system_id, key, val, fn):
247     val = str(val)
248
249     def _set_iface_external_id(tables, *_):
250         row = fn(tables)
251
252         if not row:
253             return None
254
255         external_ids = row.external_ids
256         external_ids[key] = val
257         row.external_ids = external_ids
258
259     req = ovsdb_event.EventModifyRequest(system_id, _set_iface_external_id)
260     return manager.send_request(req)
261
262
263 def set_iface_external_id(manager, system_id, iface_name, key, val):
264     return set_external_id(manager, system_id, key, val,
265                            lambda tables: _get_iface(tables, iface_name))
266
267
268 def set_other_config(manager, system_id, key, val, fn):
269     val = str(val)
270
271     def _set_iface_other_config(tables, *_):
272         row = fn(tables)
273
274         if not row:
275             return None
276
277         other_config = row.other_config
278         other_config[key] = val
279         row.other_config = other_config
280
281     req = ovsdb_event.EventModifyRequest(system_id, _set_iface_other_config)
282     return manager.send_request(req)
283
284
285 def set_iface_other_config(manager, system_id, iface_name, key, val):
286     return set_other_config(manager, system_id, key, val,
287                             lambda tables: _get_iface(tables, iface_name))
288
289
290 def del_external_id(manager, system_id, key, fn):
291     def _del_iface_external_id(tables, *_):
292         row = fn(tables)
293
294         if not row:
295             return None
296
297         external_ids = row.external_ids
298         if key in external_ids:
299             external_ids.pop(key)
300             row.external_ids = external_ids
301
302     req = ovsdb_event.EventModifyRequest(system_id, _del_iface_external_id)
303     return manager.send_request(req)
304
305
306 def del_iface_external_id(manager, system_id, iface_name, key):
307     return del_external_id(manager, system_id, key,
308                            lambda tables: _get_iface(tables, iface_name))
309
310
311 def del_other_config(manager, system_id, key, fn):
312     def _del_iface_other_config(tables, *_):
313         row = fn(tables)
314
315         if not row:
316             return None
317
318         other_config = row.other_config
319         if key in other_config:
320             other_config.pop(key)
321             row.other_config = other_config
322
323     req = ovsdb_event.EventModifyRequest(system_id, _del_iface_other_config)
324     return manager.send_request(req)
325
326
327 def del_iface_other_config(manager, system_id, iface_name, key):
328     return del_other_config(manager, system_id, key,
329                             lambda tables: _get_iface(tables, iface_name))
330
331
332 def del_port(manager, system_id, bridge_name, fn):
333     def _delete_port(tables, *_):
334         bridge = _get_bridge(tables, bridge_name)
335
336         if not bridge:
337             return
338
339         port = fn(tables)
340
341         if not port:
342             return
343
344         ports = bridge.ports
345         ports.remove(port)
346         bridge.ports = ports
347
348     req = ovsdb_event.EventModifyRequest(system_id, _delete_port)
349
350     return manager.send_request(req)
351
352
353 def del_port_by_uuid(manager, system_id, bridge_name, port_uuid):
354     return del_port(manager, system_id, bridge_name,
355                     lambda tables: _get_port(tables, port_uuid,
356                                              attr_name='uuid'))
357
358
359 def del_port_by_name(manager, system_id, bridge_name, port_name):
360     return del_port(manager, system_id, bridge_name,
361                     lambda tables: _get_port(tables, port_name))
362
363
364 def set_controller(manager, system_id, bridge_name,
365                    target, controller_info=None):
366     controller_info = controller_info or {}
367
368     def _set_controller(tables, insert):
369         bridge = _get_bridge(tables, bridge_name)
370
371         controller = _get_controller(tables, target)
372         _uuid = None
373         if not controller:
374             _uuid = controller_info.get('uuid', uuid.uuid4())
375             controller = insert(tables['Controller'], _uuid)
376             controller.target = target
377             controller.connection_mode = ['out-of-band']
378
379         elif 'out-of-band' not in controller.connection_mode:
380             controller.connection_mode = ['out-of-band']
381
382         if controller_info:
383             for key, val in controller_info.items():
384                 setattr(controller, key, val)
385
386         bridge.controller = [controller]
387
388         return _uuid
389
390     req = ovsdb_event.EventModifyRequest(system_id, _set_controller)
391     return manager.send_request(req)
392
393
394 def create_port(manager, system_id, bridge_name, port_info, iface_info=None,
395                 port_insert_uuid=None, iface_insert_uuid=None):
396     if iface_info is None:
397         iface_info = {}
398
399     if not port_insert_uuid:
400         port_insert_uuid = uuid.uuid4()
401
402     if not iface_insert_uuid:
403         iface_insert_uuid = uuid.uuid4()
404
405     def _create_port(tables, insert):
406         bridge = _get_bridge(tables, bridge_name)
407
408         if not bridge:
409             return
410
411         default_port_name = 'port' + str(port_insert_uuid)
412
413         if 'name' not in iface_info:
414             iface_info['name'] = port_info.get('name', default_port_name)
415
416         if 'type' not in iface_info:
417             iface_info['type'] = 'internal'
418
419         if 'name' not in port_info:
420             port_info['name'] = default_port_name
421
422         iface = insert(tables['Interface'], iface_insert_uuid)
423         for key, val in iface_info.items():
424             setattr(iface, key, val)
425
426         port = insert(tables['Port'], port_insert_uuid)
427         for key, val in port_info.items():
428             setattr(port, key, val)
429
430         port.interfaces = [iface]
431
432         bridge.ports = bridge.ports + [port]
433
434         return port_insert_uuid, iface_insert_uuid
435
436     req = ovsdb_event.EventModifyRequest(system_id, _create_port)
437
438     return manager.send_request(req)