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