blob: 1b4fdca777171eabe843f6e772ad327a87218551 [file] [log] [blame]
Ubuntu82b8a832013-02-06 22:00:11 +00001#! /usr/bin/env python
2import pprint
3import os
4import sys
5import subprocess
6import json
7import argparse
8import io
9import time
10
11from flask import Flask, json, Response, render_template, make_response, request
12
13## Global Var ##
Ubuntuf6ce96c2013-02-07 01:45:07 +000014RestIP="localhost"
Ubuntu82b8a832013-02-06 22:00:11 +000015RestPort=8080
16#DBName="onos-network-map"
Ubuntu5b2b24a2013-02-27 09:51:13 +000017controllers=["onos9vpc", "onos10vpc", "onos11vpc", "onos12vpc"]
Ubuntu82b8a832013-02-06 22:00:11 +000018
19DEBUG=1
20pp = pprint.PrettyPrinter(indent=4)
21
22app = Flask(__name__)
23
24## Worker Functions ##
25def log_error(txt):
26 print '%s' % (txt)
27
28def debug(txt):
29 if DEBUG:
30 print '%s' % (txt)
31
32## Rest APIs ##
33### File Fetch ###
34@app.route('/ui/img/<filename>', methods=['GET'])
35@app.route('/img/<filename>', methods=['GET'])
36@app.route('/css/<filename>', methods=['GET'])
37@app.route('/js/models/<filename>', methods=['GET'])
38@app.route('/js/views/<filename>', methods=['GET'])
39@app.route('/js/<filename>', methods=['GET'])
40@app.route('/lib/<filename>', methods=['GET'])
41@app.route('/', methods=['GET'])
42@app.route('/<filename>', methods=['GET'])
43@app.route('/tpl/<filename>', methods=['GET'])
44def return_file(filename="index.html"):
45 if request.path == "/":
46 fullpath = "./index.html"
47 else:
48 fullpath = str(request.path)[1:]
49
50 response = make_response(open(fullpath).read())
51 suffix = fullpath.split(".")[-1]
52
53 if suffix == "html" or suffix == "htm":
54 response.headers["Content-type"] = "text/html"
55 elif suffix == "js":
56 response.headers["Content-type"] = "application/javascript"
57 elif suffix == "css":
58 response.headers["Content-type"] = "text/css"
59 elif suffix == "png":
60 response.headers["Content-type"] = "image/png"
61
62 return response
63
64init_topo1 = {
65 "nodes" : [
66 {"name" : "sw0", "group" : 0},
67 {"name" : "sw1", "group" : 0},
68 {"name" : "sw2", "group" : 0},
69 {"name" : "sw3", "group" : 0},
70 {"name" : "sw4", "group" : 0},
71 {"name" : "sw5", "group" : 0},
72 {"name" : "host0", "group" : 1}
73 ],
74 "links" : [
75 {"source" :0, "target": 1},
76 {"source" :1, "target": 0},
77 {"source" :0, "target": 2},
78 {"source" :2, "target": 0},
79 {"source" :1, "target": 3},
80 {"source" :3, "target": 1},
81 {"source" :2, "target": 3},
82 {"source" :3, "target": 2},
83 {"source" :2, "target": 4},
84 {"source" :4, "target": 2},
85 {"source" :3, "target": 5},
86 {"source" :5, "target": 3},
87 {"source" :4, "target": 5},
88 {"source" :5, "target": 4},
89 {"source" :6, "target": 0},
90 {"source" :0, "target": 6}
91 ]
92}
93
94def node_id(switch_array, dpid):
95 id = -1
96 for i, val in enumerate(switch_array):
97 if val['name'] == dpid:
98 id = i
99 break
100
101 return id
102
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000103@app.route('/topology', methods=['GET'])
Ubuntu82b8a832013-02-06 22:00:11 +0000104def topology_for_gui():
105 try:
106 command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
107 result = os.popen(command).read()
108 parsedResult = json.loads(result)
109 except:
110 log_error("REST IF has issue: %s" % command)
111 log_error("%s" % result)
112 sys.exit(0)
113
114 topo = {}
115 switches = []
116 links = []
117
118 for v in parsedResult:
119 if v.has_key('dpid'):
120# if v.has_key('dpid') and str(v['state']) == "ACTIVE":#;if you want only ACTIVE nodes
121 dpid = str(v['dpid'])
122 state = str(v['state'])
123 sw = {}
124 sw['name']=dpid
Ubuntu5b2b24a2013-02-27 09:51:13 +0000125 sw['group']= -1
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000126 if state == "ACTIVE":
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000127 if dpid.split(":")[5] == "0a":
128 sw['group']=1
129 if dpid.split(":")[5] == "0b":
130 sw['group']=2
131 if dpid.split(":")[5] == "0c":
132 sw['group']=3
Ubuntu5b2b24a2013-02-27 09:51:13 +0000133 if dpid.split(":")[5] == "0d":
134 sw['group']=4
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000135 if state == "INACTIVE":
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000136 sw['group']=0
Ubuntu82b8a832013-02-06 22:00:11 +0000137 switches.append(sw)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000138
Ubuntu5b2b24a2013-02-27 09:51:13 +0000139# try:
140# command = "curl -s \'http://%s:%s/wm/registry/controllers/json\'" % (RestIP, RestPort)
141# result = os.popen(command).read()
142# controllers = json.loads(result)
143# except:
144# log_error("xx REST IF has issue: %s" % command)
145# log_error("%s" % result)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000146
147 try:
148 command = "curl -s \'http://%s:%s/wm/registry/switches/json\'" % (RestIP, RestPort)
149 result = os.popen(command).read()
150 parsedResult = json.loads(result)
151 except:
152 log_error("REST IF has issue: %s" % command)
153 log_error("%s" % result)
154
155 for key in parsedResult:
156 dpid = key
157 ctrl = parsedResult[dpid][0]['controllerId']
158 sw_id = node_id(switches, dpid)
159 if sw_id != -1:
160 if switches[sw_id]['group'] != 0:
161 switches[sw_id]['group'] = controllers.index(ctrl) + 1
162
Ubuntu5b2b24a2013-02-27 09:51:13 +0000163
164
165
Ubuntu82b8a832013-02-06 22:00:11 +0000166 try:
167 command = "curl -s \'http://%s:%s/wm/core/topology/links/json\'" % (RestIP, RestPort)
168 result = os.popen(command).read()
169 parsedResult = json.loads(result)
170 except:
171 log_error("REST IF has issue: %s" % command)
172 log_error("%s" % result)
173 sys.exit(0)
174
175 for v in parsedResult:
176 link = {}
177 if v.has_key('dst-switch'):
178 dst_dpid = str(v['dst-switch'])
179 dst_id = node_id(switches, dst_dpid)
180 if v.has_key('src-switch'):
181 src_dpid = str(v['src-switch'])
182 src_id = node_id(switches, src_dpid)
183 link['source'] = src_id
184 link['target'] = dst_id
185 links.append(link)
186
187 topo['nodes'] = switches
188 topo['links'] = links
189
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000190# pp.pprint(topo)
Ubuntu82b8a832013-02-06 22:00:11 +0000191 js = json.dumps(topo)
192 resp = Response(js, status=200, mimetype='application/json')
193 return resp
194
195
Ubuntuaea2a682013-02-08 08:30:10 +0000196#@app.route("/wm/topology/toporoute/00:00:00:00:00:a1/2/00:00:00:00:00:c1/3/json")
197#@app.route("/wm/topology/toporoute/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
198@app.route("/wm/topology/toporoute/<v1>/<p1>/<v2>/<p2>/json")
199def shortest_path(v1, p1, v2, p2):
200 try:
201 command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
202 result = os.popen(command).read()
203 parsedResult = json.loads(result)
204 except:
205 log_error("REST IF has issue: %s" % command)
206 log_error("%s" % result)
207 sys.exit(0)
208
209 topo = {}
210 switches = []
211 links = []
212
213 for v in parsedResult:
214 if v.has_key('dpid'):
215 dpid = str(v['dpid'])
216 state = str(v['state'])
217 sw = {}
218 sw['name']=dpid
219 if str(v['state']) == "ACTIVE":
220 if dpid[-2:-1] == "a":
221 sw['group']=1
222 if dpid[-2:-1] == "b":
223 sw['group']=2
224 if dpid[-2:-1] == "c":
225 sw['group']=3
226 if str(v['state']) == "INACTIVE":
227 sw['group']=0
228
229 switches.append(sw)
230
231 try:
232 command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
233 result = os.popen(command).read()
234 parsedResult = json.loads(result)
235 except:
236 log_error("No route")
237 parsedResult = []
238# exit(1)
239
240 path = [];
241 for i, v in enumerate(parsedResult):
242 if i < len(parsedResult) - 1:
243 sdpid= parsedResult[i]['switch']
244 ddpid = parsedResult[i+1]['switch']
245 path.append( (sdpid, ddpid))
246
247 try:
248 command = "curl -s \'http://%s:%s/wm/core/topology/links/json\'" % (RestIP, RestPort)
249 result = os.popen(command).read()
250 parsedResult = json.loads(result)
251 except:
252 log_error("REST IF has issue: %s" % command)
253 log_error("%s" % result)
254 sys.exit(0)
255
256 for v in parsedResult:
257 link = {}
258 if v.has_key('dst-switch'):
259 dst_dpid = str(v['dst-switch'])
260 dst_id = node_id(switches, dst_dpid)
261 if v.has_key('src-switch'):
262 src_dpid = str(v['src-switch'])
263 src_id = node_id(switches, src_dpid)
264 link['source'] = src_id
265 link['target'] = dst_id
266 onpath = 0
267 for (s,d) in path:
268 if s == v['src-switch'] and d == v['dst-switch']:
269 onpath = 1
270 break
271
272 link['type'] = onpath
273 links.append(link)
274
275 topo['nodes'] = switches
276 topo['links'] = links
277
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000278# pp.pprint(topo)
Ubuntuaea2a682013-02-08 08:30:10 +0000279 js = json.dumps(topo)
280 resp = Response(js, status=200, mimetype='application/json')
281 return resp
282
Ubuntu82b8a832013-02-06 22:00:11 +0000283@app.route("/wm/core/controller/switches/json")
284def query_switch():
285 try:
286 command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
287# http://localhost:8080/wm/core/topology/switches/active/json
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000288 print command
Ubuntu82b8a832013-02-06 22:00:11 +0000289 result = os.popen(command).read()
290 parsedResult = json.loads(result)
291 except:
292 log_error("REST IF has issue: %s" % command)
293 log_error("%s" % result)
294 sys.exit(0)
295
296# print command
297# print result
298 switches_ = []
299 for v in parsedResult:
300 if v.has_key('dpid'):
301 if v.has_key('dpid') and str(v['state']) == "ACTIVE":#;if you want only ACTIVE nodes
302 dpid = str(v['dpid'])
303 state = str(v['state'])
304 sw = {}
305 sw['dpid']=dpid
306 sw['active']=state
307 switches_.append(sw)
308
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000309# pp.pprint(switches_)
Ubuntu82b8a832013-02-06 22:00:11 +0000310 js = json.dumps(switches_)
311 resp = Response(js, status=200, mimetype='application/json')
312 return resp
313
314@app.route("/wm/device/")
315def devices():
316 try:
317 command = "curl -s http://%s:%s/graphs/%s/vertices\?key=type\&value=device" % (RestIP, RestPort, DBName)
318 result = os.popen(command).read()
319 parsedResult = json.loads(result)['results']
320 except:
321 log_error("REST IF has issue: %s" % command)
322 log_error("%s" % result)
323 sys.exit(0)
324
325 devices = []
326 for v in parsedResult:
327 dl_addr = v['dl_addr']
328 nw_addr = v['nw_addr']
329 vertex = v['_id']
330 mac = []
331 mac.append(dl_addr)
332 ip = []
333 ip.append(nw_addr)
334 device = {}
335 device['entryClass']="DefaultEntryClass"
336 device['mac']=mac
337 device['ipv4']=ip
338 device['vlan']=[]
339 device['lastSeen']=0
340 attachpoints =[]
341
342 port, dpid = deviceV_to_attachpoint(vertex)
343 attachpoint = {}
344 attachpoint['port']=port
345 attachpoint['switchDPID']=dpid
346 attachpoints.append(attachpoint)
347 device['attachmentPoint']=attachpoints
348 devices.append(device)
349
350 print devices
351 js = json.dumps(devices)
352 resp = Response(js, status=200, mimetype='application/json')
353 return resp
354
355#{"entityClass":"DefaultEntityClass","mac":["7c:d1:c3:e0:8c:a3"],"ipv4":["192.168.2.102","10.1.10.35"],"vlan":[],"attachmentPoint":[{"port":13,"switchDPID":"00:01:00:12:e2:78:32:44","errorStatus":null}],"lastSeen":1357333593496}
356
357
358## return fake stat for now
359@app.route("/wm/core/switch/<switchId>/<statType>/json")
360def switch_stat(switchId, statType):
361 if statType == "desc":
362 desc=[{"length":1056,"serialNumber":"None","manufacturerDescription":"Nicira Networks, Inc.","hardwareDescription":"Open vSwitch","softwareDescription":"1.4.0+build0","datapathDescription":"None"}]
363 ret = {}
364 ret[switchId]=desc
365 elif statType == "aggregate":
366 aggr = {"packetCount":0,"byteCount":0,"flowCount":0}
367 ret = {}
368 ret[switchId]=aggr
369 else:
370 ret = {}
371
372 js = json.dumps(ret)
373 resp = Response(js, status=200, mimetype='application/json')
374 return resp
375
376
377@app.route("/wm/topology/links/json")
378def query_links():
379 try:
380 command = 'curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=port' % (RestIP, RestPort, DBName)
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000381 print command
Ubuntu82b8a832013-02-06 22:00:11 +0000382 result = os.popen(command).read()
383 parsedResult = json.loads(result)['results']
384 except:
385 log_error("REST IF has issue: %s" % command)
386 log_error("%s" % result)
387 sys.exit(0)
388
389 debug("query_links %s" % command)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000390# pp.pprint(parsedResult)
Ubuntu82b8a832013-02-06 22:00:11 +0000391 sport = []
392 links = []
393 for v in parsedResult:
394 srcport = v['_id']
395 try:
396 command = "curl -s http://%s:%s/graphs/%s/vertices/%d/out?_label=link" % (RestIP, RestPort, DBName, srcport)
397 print command
398 result = os.popen(command).read()
399 linkResults = json.loads(result)['results']
400 except:
401 log_error("REST IF has issue: %s" % command)
402 log_error("%s" % result)
403 sys.exit(0)
404
405 for p in linkResults:
406 if p.has_key('type') and p['type'] == "port":
407 dstport = p['_id']
408 (sport, sdpid) = portV_to_port_dpid(srcport)
409 (dport, ddpid) = portV_to_port_dpid(dstport)
410 link = {}
411 link["src-switch"]=sdpid
412 link["src-port"]=sport
413 link["src-port-state"]=0
414 link["dst-switch"]=ddpid
415 link["dst-port"]=dport
416 link["dst-port-state"]=0
417 link["type"]="internal"
418 links.append(link)
419
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000420# pp.pprint(links)
Ubuntu82b8a832013-02-06 22:00:11 +0000421 js = json.dumps(links)
422 resp = Response(js, status=200, mimetype='application/json')
423 return resp
424
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000425topo_less = {
426 "nodes" : [
427 {"name" : "00:a0", "group" : 1},
428 {"name" : "00:a1", "group" : 1},
429 {"name" : "00:a2", "group" : 1},
430 ],
431 "links" : [
432 {"source" :0, "target": 1},
433 {"source" :1, "target": 0},
434 {"source" :0, "target": 2},
435 {"source" :2, "target": 0},
436 {"source" :1, "target": 2},
437 {"source" :2, "target": 1},
438 ]
439}
440
441topo_more = {
442 "nodes" : [
443 {"name" : "00:a3", "group" : 2},
444 {"name" : "00:a0", "group" : 1},
445 {"name" : "00:a1", "group" : 1},
446 {"name" : "00:a2", "group" : 1},
447 ],
448 "links" : [
449 {"source" :1, "target": 2},
450 {"source" :2, "target": 1},
451 {"source" :1, "target": 3},
452 {"source" :3, "target": 1},
453 {"source" :2, "target": 3},
454 {"source" :3, "target": 2},
455 {"source" :0, "target": 2},
456 ]
457}
458
459@app.route("/topology_more")
460def topology_more():
461 topo = topo_more
462 js = json.dumps(topo)
463 resp = Response(js, status=200, mimetype='application/json')
464 return resp
465
466@app.route("/topology_less")
467def topology_less():
468 topo = topo_less
469 js = json.dumps(topo)
470 resp = Response(js, status=200, mimetype='application/json')
471 return resp
472
473cont_status1 = [
474 {"name":"onos9vpc", "onos": 1, "cassandra": 1},
475 {"name":"onos10vpc", "onos": 0, "cassandra": 1},
476 {"name":"onos11vpc", "onos": 1, "cassandra": 0},
477 {"name":"onos12vpc", "onos": 1, "cassandra": 0}]
478
479cont_status2 = [
480 {"name":"onos9vpc", "onos": 0, "cassandra": 1},
481 {"name":"onos10vpc", "onos": 0, "cassandra": 1},
482 {"name":"onos11vpc", "onos": 0, "cassandra": 1},
483 {"name":"onos12vpc", "onos": 0, "cassandra": 1}]
484
485@app.route("/controller_status1")
486def controller_status1():
487 status = cont_status1
488 js = json.dumps(status)
489 resp = Response(js, status=200, mimetype='application/json')
490 pp.pprint(resp)
491 return resp
492
493@app.route("/controller_status2")
494def controller_status2():
495 status = cont_status2
496 js = json.dumps(status)
497 resp = Response(js, status=200, mimetype='application/json')
498 pp.pprint(resp)
499 return resp
500
501
Ubuntu82b8a832013-02-06 22:00:11 +0000502if __name__ == "__main__":
503 if len(sys.argv) > 1 and sys.argv[1] == "-d":
504 print "-- query all switches --"
505 query_switch()
506 print "-- query topo --"
507 topology_for_gui()
508# print "-- query all links --"
509# query_links()
510# print "-- query all devices --"
511# devices()
512 else:
513 app.debug = True
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000514 app.run(threaded=True, host="0.0.0.0", port=9000)