blob: 105c1416a3462c28ca8ce2201b05bca27493d31d [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"
Masayoshi Kobayashi5e91bdf2013-03-15 01:22:51 +000017controllers=["onosgui1", "onosgui2", "onosgui3", "onosgui4"]
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 = []
Ubuntu37ebda62013-03-01 00:35:31 +0000117 devices = []
Ubuntu82b8a832013-02-06 22:00:11 +0000118
119 for v in parsedResult:
120 if v.has_key('dpid'):
121# if v.has_key('dpid') and str(v['state']) == "ACTIVE":#;if you want only ACTIVE nodes
122 dpid = str(v['dpid'])
123 state = str(v['state'])
124 sw = {}
125 sw['name']=dpid
Ubuntu5b2b24a2013-02-27 09:51:13 +0000126 sw['group']= -1
Ubuntu37ebda62013-03-01 00:35:31 +0000127
128# if state == "ACTIVE":
129# if dpid.split(":")[5] == "0a":
130# sw['group']=1
131# if dpid.split(":")[5] == "0b":
132# sw['group']=2
133# if dpid.split(":")[5] == "0c":
134# sw['group']=3
135# if dpid.split(":")[5] == "0d":
136# sw['group']=4
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000137 if state == "INACTIVE":
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000138 sw['group']=0
Ubuntu82b8a832013-02-06 22:00:11 +0000139 switches.append(sw)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000140
Ubuntu37ebda62013-03-01 00:35:31 +0000141## Comment in if we need devies
142# sw_index = len(switches) - 1
143# for p in v['ports']:
144# for d in p['devices']:
145# device = {}
146# device['attached_switch']=dpid
147# device['name']=d['mac']
148# if d['state'] == "ACTIVE":
149# device['group']=1000
150# else:
151# device['group']=1001
152#
153# switches.append(device)
154# device_index = len (switches) -1
155# link = {}
156# link['source'] = device_index
157# link['target'] = sw_index
158# link['type'] = -1
159# links.append(link)
160# link = {}
161# link['source'] = sw_index
162# link['target'] = device_index
163# link['type'] = -1
164# links.append(link)
165
Ubuntu5b2b24a2013-02-27 09:51:13 +0000166# try:
167# command = "curl -s \'http://%s:%s/wm/registry/controllers/json\'" % (RestIP, RestPort)
168# result = os.popen(command).read()
169# controllers = json.loads(result)
170# except:
171# log_error("xx REST IF has issue: %s" % command)
172# log_error("%s" % result)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000173
174 try:
175 command = "curl -s \'http://%s:%s/wm/registry/switches/json\'" % (RestIP, RestPort)
176 result = os.popen(command).read()
177 parsedResult = json.loads(result)
178 except:
179 log_error("REST IF has issue: %s" % command)
180 log_error("%s" % result)
181
182 for key in parsedResult:
183 dpid = key
184 ctrl = parsedResult[dpid][0]['controllerId']
185 sw_id = node_id(switches, dpid)
186 if sw_id != -1:
187 if switches[sw_id]['group'] != 0:
188 switches[sw_id]['group'] = controllers.index(ctrl) + 1
189
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000190 try:
191 v1 = "00:00:00:00:00:0a:0d:00"
Ubuntu765deff2013-02-28 18:39:13 +0000192# v1 = "00:00:00:00:00:0d:00:d1"
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000193 p1=1
194 v2 = "00:00:00:00:00:0b:0d:03"
Ubuntu765deff2013-02-28 18:39:13 +0000195# v2 = "00:00:00:00:00:0d:00:d3"
196 p2=1
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000197 command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
198 result = os.popen(command).read()
199 parsedResult = json.loads(result)
200 except:
201 log_error("No route")
Ubuntu765deff2013-02-28 18:39:13 +0000202 parsedResult = {}
Ubuntu5b2b24a2013-02-27 09:51:13 +0000203
Ubuntu765deff2013-02-28 18:39:13 +0000204 path = []
205 if parsedResult.has_key('flowEntries'):
206 flowEntries= parsedResult['flowEntries']
207 for i, v in enumerate(flowEntries):
208 if i < len(flowEntries) - 1:
209 sdpid= flowEntries[i]['dpid']['value']
210 ddpid = flowEntries[i+1]['dpid']['value']
211 path.append( (sdpid, ddpid))
Ubuntu5b2b24a2013-02-27 09:51:13 +0000212
Ubuntu82b8a832013-02-06 22:00:11 +0000213 try:
214 command = "curl -s \'http://%s:%s/wm/core/topology/links/json\'" % (RestIP, RestPort)
215 result = os.popen(command).read()
216 parsedResult = json.loads(result)
217 except:
218 log_error("REST IF has issue: %s" % command)
219 log_error("%s" % result)
220 sys.exit(0)
221
222 for v in parsedResult:
223 link = {}
224 if v.has_key('dst-switch'):
225 dst_dpid = str(v['dst-switch'])
226 dst_id = node_id(switches, dst_dpid)
227 if v.has_key('src-switch'):
228 src_dpid = str(v['src-switch'])
229 src_id = node_id(switches, src_dpid)
230 link['source'] = src_id
231 link['target'] = dst_id
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000232
233 onpath = 0
234 for (s,d) in path:
235 if s == v['src-switch'] and d == v['dst-switch']:
236 onpath = 1
237 break
238 link['type'] = onpath
239
Ubuntu82b8a832013-02-06 22:00:11 +0000240 links.append(link)
241
242 topo['nodes'] = switches
243 topo['links'] = links
244
Ubuntu37ebda62013-03-01 00:35:31 +0000245 pp.pprint(topo)
Ubuntu82b8a832013-02-06 22:00:11 +0000246 js = json.dumps(topo)
247 resp = Response(js, status=200, mimetype='application/json')
248 return resp
249
Ubuntuaea2a682013-02-08 08:30:10 +0000250#@app.route("/wm/topology/toporoute/00:00:00:00:00:a1/2/00:00:00:00:00:c1/3/json")
251#@app.route("/wm/topology/toporoute/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
252@app.route("/wm/topology/toporoute/<v1>/<p1>/<v2>/<p2>/json")
253def shortest_path(v1, p1, v2, p2):
254 try:
255 command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
256 result = os.popen(command).read()
257 parsedResult = json.loads(result)
258 except:
259 log_error("REST IF has issue: %s" % command)
260 log_error("%s" % result)
261 sys.exit(0)
262
263 topo = {}
264 switches = []
265 links = []
266
267 for v in parsedResult:
268 if v.has_key('dpid'):
269 dpid = str(v['dpid'])
270 state = str(v['state'])
271 sw = {}
272 sw['name']=dpid
273 if str(v['state']) == "ACTIVE":
274 if dpid[-2:-1] == "a":
275 sw['group']=1
276 if dpid[-2:-1] == "b":
277 sw['group']=2
278 if dpid[-2:-1] == "c":
279 sw['group']=3
280 if str(v['state']) == "INACTIVE":
281 sw['group']=0
282
283 switches.append(sw)
284
285 try:
286 command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
287 result = os.popen(command).read()
288 parsedResult = json.loads(result)
289 except:
290 log_error("No route")
291 parsedResult = []
292# exit(1)
293
294 path = [];
295 for i, v in enumerate(parsedResult):
296 if i < len(parsedResult) - 1:
297 sdpid= parsedResult[i]['switch']
298 ddpid = parsedResult[i+1]['switch']
299 path.append( (sdpid, ddpid))
300
301 try:
302 command = "curl -s \'http://%s:%s/wm/core/topology/links/json\'" % (RestIP, RestPort)
303 result = os.popen(command).read()
304 parsedResult = json.loads(result)
305 except:
306 log_error("REST IF has issue: %s" % command)
307 log_error("%s" % result)
308 sys.exit(0)
309
310 for v in parsedResult:
311 link = {}
312 if v.has_key('dst-switch'):
313 dst_dpid = str(v['dst-switch'])
314 dst_id = node_id(switches, dst_dpid)
315 if v.has_key('src-switch'):
316 src_dpid = str(v['src-switch'])
317 src_id = node_id(switches, src_dpid)
318 link['source'] = src_id
319 link['target'] = dst_id
320 onpath = 0
321 for (s,d) in path:
322 if s == v['src-switch'] and d == v['dst-switch']:
323 onpath = 1
324 break
325
326 link['type'] = onpath
327 links.append(link)
328
329 topo['nodes'] = switches
330 topo['links'] = links
331
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000332# pp.pprint(topo)
Ubuntuaea2a682013-02-08 08:30:10 +0000333 js = json.dumps(topo)
334 resp = Response(js, status=200, mimetype='application/json')
335 return resp
336
Ubuntu82b8a832013-02-06 22:00:11 +0000337@app.route("/wm/core/controller/switches/json")
338def query_switch():
339 try:
340 command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
341# http://localhost:8080/wm/core/topology/switches/active/json
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000342 print command
Ubuntu82b8a832013-02-06 22:00:11 +0000343 result = os.popen(command).read()
344 parsedResult = json.loads(result)
345 except:
346 log_error("REST IF has issue: %s" % command)
347 log_error("%s" % result)
348 sys.exit(0)
349
350# print command
351# print result
352 switches_ = []
353 for v in parsedResult:
354 if v.has_key('dpid'):
355 if v.has_key('dpid') and str(v['state']) == "ACTIVE":#;if you want only ACTIVE nodes
356 dpid = str(v['dpid'])
357 state = str(v['state'])
358 sw = {}
359 sw['dpid']=dpid
360 sw['active']=state
361 switches_.append(sw)
362
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000363# pp.pprint(switches_)
Ubuntu82b8a832013-02-06 22:00:11 +0000364 js = json.dumps(switches_)
365 resp = Response(js, status=200, mimetype='application/json')
366 return resp
367
368@app.route("/wm/device/")
369def devices():
370 try:
371 command = "curl -s http://%s:%s/graphs/%s/vertices\?key=type\&value=device" % (RestIP, RestPort, DBName)
372 result = os.popen(command).read()
373 parsedResult = json.loads(result)['results']
374 except:
375 log_error("REST IF has issue: %s" % command)
376 log_error("%s" % result)
377 sys.exit(0)
378
379 devices = []
380 for v in parsedResult:
381 dl_addr = v['dl_addr']
382 nw_addr = v['nw_addr']
383 vertex = v['_id']
384 mac = []
385 mac.append(dl_addr)
386 ip = []
387 ip.append(nw_addr)
388 device = {}
389 device['entryClass']="DefaultEntryClass"
390 device['mac']=mac
391 device['ipv4']=ip
392 device['vlan']=[]
393 device['lastSeen']=0
394 attachpoints =[]
395
396 port, dpid = deviceV_to_attachpoint(vertex)
397 attachpoint = {}
398 attachpoint['port']=port
399 attachpoint['switchDPID']=dpid
400 attachpoints.append(attachpoint)
401 device['attachmentPoint']=attachpoints
402 devices.append(device)
403
404 print devices
405 js = json.dumps(devices)
406 resp = Response(js, status=200, mimetype='application/json')
407 return resp
408
409#{"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}
410
411
412## return fake stat for now
413@app.route("/wm/core/switch/<switchId>/<statType>/json")
414def switch_stat(switchId, statType):
415 if statType == "desc":
416 desc=[{"length":1056,"serialNumber":"None","manufacturerDescription":"Nicira Networks, Inc.","hardwareDescription":"Open vSwitch","softwareDescription":"1.4.0+build0","datapathDescription":"None"}]
417 ret = {}
418 ret[switchId]=desc
419 elif statType == "aggregate":
420 aggr = {"packetCount":0,"byteCount":0,"flowCount":0}
421 ret = {}
422 ret[switchId]=aggr
423 else:
424 ret = {}
425
426 js = json.dumps(ret)
427 resp = Response(js, status=200, mimetype='application/json')
428 return resp
429
430
431@app.route("/wm/topology/links/json")
432def query_links():
433 try:
434 command = 'curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=port' % (RestIP, RestPort, DBName)
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000435 print command
Ubuntu82b8a832013-02-06 22:00:11 +0000436 result = os.popen(command).read()
437 parsedResult = json.loads(result)['results']
438 except:
439 log_error("REST IF has issue: %s" % command)
440 log_error("%s" % result)
441 sys.exit(0)
442
443 debug("query_links %s" % command)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000444# pp.pprint(parsedResult)
Ubuntu82b8a832013-02-06 22:00:11 +0000445 sport = []
446 links = []
447 for v in parsedResult:
448 srcport = v['_id']
449 try:
450 command = "curl -s http://%s:%s/graphs/%s/vertices/%d/out?_label=link" % (RestIP, RestPort, DBName, srcport)
451 print command
452 result = os.popen(command).read()
453 linkResults = json.loads(result)['results']
454 except:
455 log_error("REST IF has issue: %s" % command)
456 log_error("%s" % result)
457 sys.exit(0)
458
459 for p in linkResults:
460 if p.has_key('type') and p['type'] == "port":
461 dstport = p['_id']
462 (sport, sdpid) = portV_to_port_dpid(srcport)
463 (dport, ddpid) = portV_to_port_dpid(dstport)
464 link = {}
465 link["src-switch"]=sdpid
466 link["src-port"]=sport
467 link["src-port-state"]=0
468 link["dst-switch"]=ddpid
469 link["dst-port"]=dport
470 link["dst-port-state"]=0
471 link["type"]="internal"
472 links.append(link)
473
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000474# pp.pprint(links)
Ubuntu82b8a832013-02-06 22:00:11 +0000475 js = json.dumps(links)
476 resp = Response(js, status=200, mimetype='application/json')
477 return resp
478
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000479topo_less = {
480 "nodes" : [
481 {"name" : "00:a0", "group" : 1},
482 {"name" : "00:a1", "group" : 1},
483 {"name" : "00:a2", "group" : 1},
484 ],
485 "links" : [
486 {"source" :0, "target": 1},
487 {"source" :1, "target": 0},
488 {"source" :0, "target": 2},
489 {"source" :2, "target": 0},
490 {"source" :1, "target": 2},
491 {"source" :2, "target": 1},
492 ]
493}
494
495topo_more = {
496 "nodes" : [
497 {"name" : "00:a3", "group" : 2},
498 {"name" : "00:a0", "group" : 1},
499 {"name" : "00:a1", "group" : 1},
500 {"name" : "00:a2", "group" : 1},
501 ],
502 "links" : [
503 {"source" :1, "target": 2},
504 {"source" :2, "target": 1},
505 {"source" :1, "target": 3},
506 {"source" :3, "target": 1},
507 {"source" :2, "target": 3},
508 {"source" :3, "target": 2},
509 {"source" :0, "target": 2},
510 ]
511}
512
513@app.route("/topology_more")
514def topology_more():
515 topo = topo_more
516 js = json.dumps(topo)
517 resp = Response(js, status=200, mimetype='application/json')
518 return resp
519
520@app.route("/topology_less")
521def topology_less():
522 topo = topo_less
523 js = json.dumps(topo)
524 resp = Response(js, status=200, mimetype='application/json')
525 return resp
526
527cont_status1 = [
528 {"name":"onos9vpc", "onos": 1, "cassandra": 1},
529 {"name":"onos10vpc", "onos": 0, "cassandra": 1},
530 {"name":"onos11vpc", "onos": 1, "cassandra": 0},
531 {"name":"onos12vpc", "onos": 1, "cassandra": 0}]
532
533cont_status2 = [
534 {"name":"onos9vpc", "onos": 0, "cassandra": 1},
535 {"name":"onos10vpc", "onos": 0, "cassandra": 1},
536 {"name":"onos11vpc", "onos": 0, "cassandra": 1},
537 {"name":"onos12vpc", "onos": 0, "cassandra": 1}]
538
539@app.route("/controller_status1")
540def controller_status1():
541 status = cont_status1
542 js = json.dumps(status)
543 resp = Response(js, status=200, mimetype='application/json')
544 pp.pprint(resp)
545 return resp
546
547@app.route("/controller_status2")
548def controller_status2():
549 status = cont_status2
550 js = json.dumps(status)
551 resp = Response(js, status=200, mimetype='application/json')
552 pp.pprint(resp)
553 return resp
554
Ubuntuc016ba12013-02-27 21:53:41 +0000555@app.route("/controller_status")
556def controller_status():
557 onos_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh status | awk '{print $1}'"
558 #cassandra_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-cassandra.sh status"
559
560 cont_status=[]
561 for i in controllers:
562 status={}
563 onos=os.popen(onos_check % i).read()[:-1]
564 status["name"]=i
565 status["onos"]=onos
Masayoshi Kobayashi5e91bdf2013-03-15 01:22:51 +0000566 status["cassandra"]=0
Ubuntuc016ba12013-02-27 21:53:41 +0000567 cont_status.append(status)
568
569 js = json.dumps(cont_status)
570 resp = Response(js, status=200, mimetype='application/json')
571 pp.pprint(js)
572 return resp
573
574
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000575
Ubuntu82b8a832013-02-06 22:00:11 +0000576if __name__ == "__main__":
577 if len(sys.argv) > 1 and sys.argv[1] == "-d":
578 print "-- query all switches --"
579 query_switch()
580 print "-- query topo --"
581 topology_for_gui()
582# print "-- query all links --"
583# query_links()
584# print "-- query all devices --"
585# devices()
586 else:
587 app.debug = True
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000588 app.run(threaded=True, host="0.0.0.0", port=9000)