Open Kilda Java Documentation
lockkeeper.py
Go to the documentation of this file.
1 import os
2 
3 import paramiko
4 from flask import Flask
5 from flask import jsonify
6 from flask import request
7 
8 app = Flask(__name__)
9 
10 HOST = os.environ.get("LOCK_KEEPER_HOST")
11 USER = os.environ.get("LOCK_KEEPER_USER")
12 SECRET = os.environ.get("LOCK_KEEPER_SECRET")
13 PORT = 22
14 
15 
17  client = paramiko.SSHClient()
18  client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
19  client.connect(hostname=HOST, username=USER, password=SECRET, port=PORT)
20  data = []
21  for command in commands:
22  stdin, stdout, stderr = client.exec_command(command)
23  data.append((stdout.read() + stderr.read()).decode('utf-8'))
24  client.close()
25  return data
26 
27 
29  return execute_remote_commands([command])[0]
30 
31 
32 def change_ports_state(ports, port_state):
33  """Common port states: up, down."""
34  commands = ["ovs-ofctl mod-port br0 {} {}".format(str(port), port_state)
35  for port in ports]
36  return execute_remote_commands(commands)
37 
38 
40  test_data = ('NXST_FLOW reply (xid=0x4):\n cookie=0x15, duration=422883.97'
41  '5s, table=0, n_packets=70278, n_bytes=17499222, idle_age=5, '
42  'hard_age=65534, in_port=7 actions=output:8\n cookie=0x16, du'
43  'ration=422884.022s, table=0, n_packets=69701, n_bytes=173555'
44  '49, idle_age=4, hard_age=65534, in_port=51 actions=output:52'
45  '\n')
46 
47  assert parse_dump_flows(test_data) == [
48  {
49  'in_port': 7,
50  'out_port': 8
51  }, {
52  'in_port': 51,
53  'out_port': 52
54  }
55  ]
56 
57 
58 def int_from_str_by_pattern(string, pattern):
59  start = string.find(pattern)
60  end = string.find(' ', start)
61  if end == -1:
62  end = None
63  return int(string[start + len(pattern):end])
64 
65 
67  data = raw[raw.find('\n') + 1:]
68  return [{'in_port': int_from_str_by_pattern(x, 'in_port='),
69  'out_port': int_from_str_by_pattern(x, 'actions=output:')}
70  for x in data.split('\n') if x]
71 
72 
73 @app.route('/flows', methods=['GET'])
75  flows = execute_remote_command('ovs-ofctl dump-flows br0')
76  return jsonify(parse_dump_flows(flows))
77 
78 
79 @app.route('/flows', methods=['POST'])
81  payload = request.get_json()
82  commands = ['ovs-ofctl add-flow br0 in_port={in_port},' \
83  'actions=output={out_port}'.format(**flow) for flow in payload]
84  execute_remote_commands(commands)
85  return jsonify({'status': 'ok'})
86 
87 
88 @app.route('/flows', methods=['DELETE'])
90  payload = request.get_json()
91  commands = ['ovs-ofctl del-flows br0 in_port={in_port}'.format(**flow)
92  for flow in payload]
93  execute_remote_commands(commands)
94  return jsonify({'status': 'ok'})
95 
96 
97 @app.route('/ports', methods=['POST'])
98 def ports_up():
99  change_ports_state(request.get_json(), "up")
100  return jsonify({'status': 'ok'})
101 
102 
103 @app.route('/ports', methods=['DELETE'])
105  change_ports_state(request.get_json(), "down")
106  return jsonify({'status': 'ok'})
def ports_down()
Definition: lockkeeper.py:104
def execute_remote_commands(commands)
Definition: lockkeeper.py:16
def ports_up()
Definition: lockkeeper.py:98
def post_flows_route()
Definition: lockkeeper.py:80
def parse_dump_flows(raw)
Definition: lockkeeper.py:66
def get_flows_route()
Definition: lockkeeper.py:74
def delete_flows_route()
Definition: lockkeeper.py:89
def test_answer()
Definition: lockkeeper.py:39
def execute_remote_command(command)
Definition: lockkeeper.py:28
def change_ports_state(ports, port_state)
Definition: lockkeeper.py:32
def int_from_str_by_pattern(string, pattern)
Definition: lockkeeper.py:58