blob: ce6b2d744ff4c52c6bf520b50382b38a1f8b4313 [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
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000163 try:
164 v1 = "00:00:00:00:00:0a:0d:00"
Ubuntu765deff2013-02-28 18:39:13 +0000165# v1 = "00:00:00:00:00:0d:00:d1"
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000166 p1=1
167 v2 = "00:00:00:00:00:0b:0d:03"
Ubuntu765deff2013-02-28 18:39:13 +0000168# v2 = "00:00:00:00:00:0d:00:d3"
169 p2=1
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000170 command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
171 result = os.popen(command).read()
172 parsedResult = json.loads(result)
173 except:
174 log_error("No route")
Ubuntu765deff2013-02-28 18:39:13 +0000175 parsedResult = {}
Ubuntu5b2b24a2013-02-27 09:51:13 +0000176
Ubuntu765deff2013-02-28 18:39:13 +0000177 path = []
178 if parsedResult.has_key('flowEntries'):
179 flowEntries= parsedResult['flowEntries']
180 for i, v in enumerate(flowEntries):
181 if i < len(flowEntries) - 1:
182 sdpid= flowEntries[i]['dpid']['value']
183 ddpid = flowEntries[i+1]['dpid']['value']
184 path.append( (sdpid, ddpid))
Ubuntu5b2b24a2013-02-27 09:51:13 +0000185
Ubuntu82b8a832013-02-06 22:00:11 +0000186 try:
187 command = "curl -s \'http://%s:%s/wm/core/topology/links/json\'" % (RestIP, RestPort)
188 result = os.popen(command).read()
189 parsedResult = json.loads(result)
190 except:
191 log_error("REST IF has issue: %s" % command)
192 log_error("%s" % result)
193 sys.exit(0)
194
195 for v in parsedResult:
196 link = {}
197 if v.has_key('dst-switch'):
198 dst_dpid = str(v['dst-switch'])
199 dst_id = node_id(switches, dst_dpid)
200 if v.has_key('src-switch'):
201 src_dpid = str(v['src-switch'])
202 src_id = node_id(switches, src_dpid)
203 link['source'] = src_id
204 link['target'] = dst_id
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000205
206 onpath = 0
207 for (s,d) in path:
208 if s == v['src-switch'] and d == v['dst-switch']:
209 onpath = 1
210 break
211 link['type'] = onpath
212
Ubuntu82b8a832013-02-06 22:00:11 +0000213 links.append(link)
214
215 topo['nodes'] = switches
216 topo['links'] = links
217
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000218# pp.pprint(topo)
Ubuntu82b8a832013-02-06 22:00:11 +0000219 js = json.dumps(topo)
220 resp = Response(js, status=200, mimetype='application/json')
221 return resp
222
223
Ubuntuaea2a682013-02-08 08:30:10 +0000224#@app.route("/wm/topology/toporoute/00:00:00:00:00:a1/2/00:00:00:00:00:c1/3/json")
225#@app.route("/wm/topology/toporoute/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
226@app.route("/wm/topology/toporoute/<v1>/<p1>/<v2>/<p2>/json")
227def shortest_path(v1, p1, v2, p2):
228 try:
229 command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
230 result = os.popen(command).read()
231 parsedResult = json.loads(result)
232 except:
233 log_error("REST IF has issue: %s" % command)
234 log_error("%s" % result)
235 sys.exit(0)
236
237 topo = {}
238 switches = []
239 links = []
240
241 for v in parsedResult:
242 if v.has_key('dpid'):
243 dpid = str(v['dpid'])
244 state = str(v['state'])
245 sw = {}
246 sw['name']=dpid
247 if str(v['state']) == "ACTIVE":
248 if dpid[-2:-1] == "a":
249 sw['group']=1
250 if dpid[-2:-1] == "b":
251 sw['group']=2
252 if dpid[-2:-1] == "c":
253 sw['group']=3
254 if str(v['state']) == "INACTIVE":
255 sw['group']=0
256
257 switches.append(sw)
258
259 try:
260 command = "curl -s http://%s:%s/wm/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
261 result = os.popen(command).read()
262 parsedResult = json.loads(result)
263 except:
264 log_error("No route")
265 parsedResult = []
266# exit(1)
267
268 path = [];
269 for i, v in enumerate(parsedResult):
270 if i < len(parsedResult) - 1:
271 sdpid= parsedResult[i]['switch']
272 ddpid = parsedResult[i+1]['switch']
273 path.append( (sdpid, ddpid))
274
275 try:
276 command = "curl -s \'http://%s:%s/wm/core/topology/links/json\'" % (RestIP, RestPort)
277 result = os.popen(command).read()
278 parsedResult = json.loads(result)
279 except:
280 log_error("REST IF has issue: %s" % command)
281 log_error("%s" % result)
282 sys.exit(0)
283
284 for v in parsedResult:
285 link = {}
286 if v.has_key('dst-switch'):
287 dst_dpid = str(v['dst-switch'])
288 dst_id = node_id(switches, dst_dpid)
289 if v.has_key('src-switch'):
290 src_dpid = str(v['src-switch'])
291 src_id = node_id(switches, src_dpid)
292 link['source'] = src_id
293 link['target'] = dst_id
294 onpath = 0
295 for (s,d) in path:
296 if s == v['src-switch'] and d == v['dst-switch']:
297 onpath = 1
298 break
299
300 link['type'] = onpath
301 links.append(link)
302
303 topo['nodes'] = switches
304 topo['links'] = links
305
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000306# pp.pprint(topo)
Ubuntuaea2a682013-02-08 08:30:10 +0000307 js = json.dumps(topo)
308 resp = Response(js, status=200, mimetype='application/json')
309 return resp
310
Ubuntu82b8a832013-02-06 22:00:11 +0000311@app.route("/wm/core/controller/switches/json")
312def query_switch():
313 try:
314 command = "curl -s \'http://%s:%s/wm/core/topology/switches/all/json\'" % (RestIP, RestPort)
315# http://localhost:8080/wm/core/topology/switches/active/json
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000316 print command
Ubuntu82b8a832013-02-06 22:00:11 +0000317 result = os.popen(command).read()
318 parsedResult = json.loads(result)
319 except:
320 log_error("REST IF has issue: %s" % command)
321 log_error("%s" % result)
322 sys.exit(0)
323
324# print command
325# print result
326 switches_ = []
327 for v in parsedResult:
328 if v.has_key('dpid'):
329 if v.has_key('dpid') and str(v['state']) == "ACTIVE":#;if you want only ACTIVE nodes
330 dpid = str(v['dpid'])
331 state = str(v['state'])
332 sw = {}
333 sw['dpid']=dpid
334 sw['active']=state
335 switches_.append(sw)
336
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000337# pp.pprint(switches_)
Ubuntu82b8a832013-02-06 22:00:11 +0000338 js = json.dumps(switches_)
339 resp = Response(js, status=200, mimetype='application/json')
340 return resp
341
342@app.route("/wm/device/")
343def devices():
344 try:
345 command = "curl -s http://%s:%s/graphs/%s/vertices\?key=type\&value=device" % (RestIP, RestPort, DBName)
346 result = os.popen(command).read()
347 parsedResult = json.loads(result)['results']
348 except:
349 log_error("REST IF has issue: %s" % command)
350 log_error("%s" % result)
351 sys.exit(0)
352
353 devices = []
354 for v in parsedResult:
355 dl_addr = v['dl_addr']
356 nw_addr = v['nw_addr']
357 vertex = v['_id']
358 mac = []
359 mac.append(dl_addr)
360 ip = []
361 ip.append(nw_addr)
362 device = {}
363 device['entryClass']="DefaultEntryClass"
364 device['mac']=mac
365 device['ipv4']=ip
366 device['vlan']=[]
367 device['lastSeen']=0
368 attachpoints =[]
369
370 port, dpid = deviceV_to_attachpoint(vertex)
371 attachpoint = {}
372 attachpoint['port']=port
373 attachpoint['switchDPID']=dpid
374 attachpoints.append(attachpoint)
375 device['attachmentPoint']=attachpoints
376 devices.append(device)
377
378 print devices
379 js = json.dumps(devices)
380 resp = Response(js, status=200, mimetype='application/json')
381 return resp
382
383#{"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}
384
385
386## return fake stat for now
387@app.route("/wm/core/switch/<switchId>/<statType>/json")
388def switch_stat(switchId, statType):
389 if statType == "desc":
390 desc=[{"length":1056,"serialNumber":"None","manufacturerDescription":"Nicira Networks, Inc.","hardwareDescription":"Open vSwitch","softwareDescription":"1.4.0+build0","datapathDescription":"None"}]
391 ret = {}
392 ret[switchId]=desc
393 elif statType == "aggregate":
394 aggr = {"packetCount":0,"byteCount":0,"flowCount":0}
395 ret = {}
396 ret[switchId]=aggr
397 else:
398 ret = {}
399
400 js = json.dumps(ret)
401 resp = Response(js, status=200, mimetype='application/json')
402 return resp
403
404
405@app.route("/wm/topology/links/json")
406def query_links():
407 try:
408 command = 'curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=port' % (RestIP, RestPort, DBName)
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000409 print command
Ubuntu82b8a832013-02-06 22:00:11 +0000410 result = os.popen(command).read()
411 parsedResult = json.loads(result)['results']
412 except:
413 log_error("REST IF has issue: %s" % command)
414 log_error("%s" % result)
415 sys.exit(0)
416
417 debug("query_links %s" % command)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000418# pp.pprint(parsedResult)
Ubuntu82b8a832013-02-06 22:00:11 +0000419 sport = []
420 links = []
421 for v in parsedResult:
422 srcport = v['_id']
423 try:
424 command = "curl -s http://%s:%s/graphs/%s/vertices/%d/out?_label=link" % (RestIP, RestPort, DBName, srcport)
425 print command
426 result = os.popen(command).read()
427 linkResults = json.loads(result)['results']
428 except:
429 log_error("REST IF has issue: %s" % command)
430 log_error("%s" % result)
431 sys.exit(0)
432
433 for p in linkResults:
434 if p.has_key('type') and p['type'] == "port":
435 dstport = p['_id']
436 (sport, sdpid) = portV_to_port_dpid(srcport)
437 (dport, ddpid) = portV_to_port_dpid(dstport)
438 link = {}
439 link["src-switch"]=sdpid
440 link["src-port"]=sport
441 link["src-port-state"]=0
442 link["dst-switch"]=ddpid
443 link["dst-port"]=dport
444 link["dst-port-state"]=0
445 link["type"]="internal"
446 links.append(link)
447
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000448# pp.pprint(links)
Ubuntu82b8a832013-02-06 22:00:11 +0000449 js = json.dumps(links)
450 resp = Response(js, status=200, mimetype='application/json')
451 return resp
452
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000453topo_less = {
454 "nodes" : [
455 {"name" : "00:a0", "group" : 1},
456 {"name" : "00:a1", "group" : 1},
457 {"name" : "00:a2", "group" : 1},
458 ],
459 "links" : [
460 {"source" :0, "target": 1},
461 {"source" :1, "target": 0},
462 {"source" :0, "target": 2},
463 {"source" :2, "target": 0},
464 {"source" :1, "target": 2},
465 {"source" :2, "target": 1},
466 ]
467}
468
469topo_more = {
470 "nodes" : [
471 {"name" : "00:a3", "group" : 2},
472 {"name" : "00:a0", "group" : 1},
473 {"name" : "00:a1", "group" : 1},
474 {"name" : "00:a2", "group" : 1},
475 ],
476 "links" : [
477 {"source" :1, "target": 2},
478 {"source" :2, "target": 1},
479 {"source" :1, "target": 3},
480 {"source" :3, "target": 1},
481 {"source" :2, "target": 3},
482 {"source" :3, "target": 2},
483 {"source" :0, "target": 2},
484 ]
485}
486
487@app.route("/topology_more")
488def topology_more():
489 topo = topo_more
490 js = json.dumps(topo)
491 resp = Response(js, status=200, mimetype='application/json')
492 return resp
493
494@app.route("/topology_less")
495def topology_less():
496 topo = topo_less
497 js = json.dumps(topo)
498 resp = Response(js, status=200, mimetype='application/json')
499 return resp
500
501cont_status1 = [
502 {"name":"onos9vpc", "onos": 1, "cassandra": 1},
503 {"name":"onos10vpc", "onos": 0, "cassandra": 1},
504 {"name":"onos11vpc", "onos": 1, "cassandra": 0},
505 {"name":"onos12vpc", "onos": 1, "cassandra": 0}]
506
507cont_status2 = [
508 {"name":"onos9vpc", "onos": 0, "cassandra": 1},
509 {"name":"onos10vpc", "onos": 0, "cassandra": 1},
510 {"name":"onos11vpc", "onos": 0, "cassandra": 1},
511 {"name":"onos12vpc", "onos": 0, "cassandra": 1}]
512
513@app.route("/controller_status1")
514def controller_status1():
515 status = cont_status1
516 js = json.dumps(status)
517 resp = Response(js, status=200, mimetype='application/json')
518 pp.pprint(resp)
519 return resp
520
521@app.route("/controller_status2")
522def controller_status2():
523 status = cont_status2
524 js = json.dumps(status)
525 resp = Response(js, status=200, mimetype='application/json')
526 pp.pprint(resp)
527 return resp
528
Ubuntuc016ba12013-02-27 21:53:41 +0000529@app.route("/controller_status")
530def controller_status():
531 onos_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh status | awk '{print $1}'"
532 #cassandra_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-cassandra.sh status"
533
534 cont_status=[]
535 for i in controllers:
536 status={}
537 onos=os.popen(onos_check % i).read()[:-1]
538 status["name"]=i
539 status["onos"]=onos
540 status["cassandra"]=1
541 cont_status.append(status)
542
543 js = json.dumps(cont_status)
544 resp = Response(js, status=200, mimetype='application/json')
545 pp.pprint(js)
546 return resp
547
548
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000549
Ubuntu82b8a832013-02-06 22:00:11 +0000550if __name__ == "__main__":
551 if len(sys.argv) > 1 and sys.argv[1] == "-d":
552 print "-- query all switches --"
553 query_switch()
554 print "-- query topo --"
555 topology_for_gui()
556# print "-- query all links --"
557# query_links()
558# print "-- query all devices --"
559# devices()
560 else:
561 app.debug = True
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000562 app.run(threaded=True, host="0.0.0.0", port=9000)