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