blob: 64f6275e444acc6eba188c408a7572a33bfcc964 [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
Masayoshi Kobayashi2ae891a2013-04-05 02:16:19 +000010import random
Masayoshi Kobayashi51011522013-03-27 00:18:12 +000011import re
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -080012from urllib2 import Request, urlopen, URLError, HTTPError
Masayoshi Kobayashi51011522013-03-27 00:18:12 +000013
Ubuntu82b8a832013-02-06 22:00:11 +000014from flask import Flask, json, Response, render_template, make_response, request
15
Pavlin Radoslavov092d0e22013-04-07 05:42:51 +000016CONFIG_FILE=os.getenv("HOME") + "/ONOS/web/config.json"
Masayoshi Kobayashi8158d442013-04-09 02:43:39 +000017LINK_FILE=os.getenv("HOME") + "/ONOS/web/link.json"
Masayoshi Kobayashi7fa3fb82013-06-20 18:10:46 -070018ONOSDIR=os.getenv("HOME") + "/ONOS"
Pavlin Radoslavov092d0e22013-04-07 05:42:51 +000019
Naoki Shiotad5d0e942014-03-27 18:57:32 -070020## Global Var for this proxy script setting.
21# "0.0.0.0" means any interface
22ProxyIP="0.0.0.0"
23ProxyPort=9000
24
Masayoshi Kobayashi2ae891a2013-04-05 02:16:19 +000025## Global Var for ON.Lab local REST ##
Ubuntuf6ce96c2013-02-07 01:45:07 +000026RestIP="localhost"
Ubuntu82b8a832013-02-06 22:00:11 +000027RestPort=8080
Masayoshi Kobayashi2ae891a2013-04-05 02:16:19 +000028ONOS_DEFAULT_HOST="localhost" ;# Has to set if LB=False
Ubuntu82b8a832013-02-06 22:00:11 +000029DEBUG=1
Ubuntu82b8a832013-02-06 22:00:11 +000030
Masayoshi Kobayashi8158d442013-04-09 02:43:39 +000031pp = pprint.PrettyPrinter(indent=4)
32app = Flask(__name__)
33
Pavlin Radoslavov092d0e22013-04-07 05:42:51 +000034def read_config():
Jonathan Hartb2554482013-04-08 13:40:31 -070035 global LB, TESTBED, controllers, core_switches, ONOS_GUI3_HOST, ONOS_GUI3_CONTROL_HOST
Pavlin Radoslavov092d0e22013-04-07 05:42:51 +000036 f = open(CONFIG_FILE)
37 conf = json.load(f)
38 LB = conf['LB']
Jonathan Hartb2554482013-04-08 13:40:31 -070039 TESTBED = conf['TESTBED']
Pavlin Radoslavov092d0e22013-04-07 05:42:51 +000040 controllers = conf['controllers']
Jonathan Hartb2554482013-04-08 13:40:31 -070041 core_switches=conf['core_switches']
Pavlin Radoslavov092d0e22013-04-07 05:42:51 +000042 ONOS_GUI3_HOST=conf['ONOS_GUI3_HOST']
43 ONOS_GUI3_CONTROL_HOST=conf['ONOS_GUI3_CONTROL_HOST']
44 f.close()
Tim Lindberg201ade22013-04-05 11:52:08 -070045
Ubuntu82b8a832013-02-06 22:00:11 +000046## Worker Functions ##
47def log_error(txt):
48 print '%s' % (txt)
49
50def debug(txt):
51 if DEBUG:
52 print '%s' % (txt)
53
Ubuntu82b8a832013-02-06 22:00:11 +000054### File Fetch ###
55@app.route('/ui/img/<filename>', methods=['GET'])
56@app.route('/img/<filename>', methods=['GET'])
57@app.route('/css/<filename>', methods=['GET'])
58@app.route('/js/models/<filename>', methods=['GET'])
59@app.route('/js/views/<filename>', methods=['GET'])
60@app.route('/js/<filename>', methods=['GET'])
61@app.route('/lib/<filename>', methods=['GET'])
Masayoshi Kobayashi3d049312013-04-02 22:15:16 +000062@app.route('/log/<filename>', methods=['GET'])
Ubuntu82b8a832013-02-06 22:00:11 +000063@app.route('/', methods=['GET'])
64@app.route('/<filename>', methods=['GET'])
65@app.route('/tpl/<filename>', methods=['GET'])
66def return_file(filename="index.html"):
67 if request.path == "/":
68 fullpath = "./index.html"
69 else:
70 fullpath = str(request.path)[1:]
71
Paul Greysonc090d142013-04-09 16:59:03 -070072 try:
Masayoshi Kobayashi03e64b42013-04-05 05:56:27 +000073 open(fullpath)
74 except:
75 response = make_response("Cannot find a file: %s" % (fullpath), 500)
76 response.headers["Content-type"] = "text/html"
77 return response
78
Ubuntu82b8a832013-02-06 22:00:11 +000079 response = make_response(open(fullpath).read())
80 suffix = fullpath.split(".")[-1]
81
82 if suffix == "html" or suffix == "htm":
83 response.headers["Content-type"] = "text/html"
84 elif suffix == "js":
85 response.headers["Content-type"] = "application/javascript"
86 elif suffix == "css":
87 response.headers["Content-type"] = "text/css"
88 elif suffix == "png":
89 response.headers["Content-type"] = "image/png"
Paul Greyson2913af82013-03-27 14:53:17 -070090 elif suffix == "svg":
91 response.headers["Content-type"] = "image/svg+xml"
Ubuntu82b8a832013-02-06 22:00:11 +000092
93 return response
94
Tim Lindberg9ec5e222013-04-12 10:46:02 -070095###### ONOS REST API ##############################
Masayoshi Kobayashi2ae891a2013-04-05 02:16:19 +000096## Worker Func ###
97def get_json(url):
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -080098 code = 200;
Masayoshi Kobayashi2ae891a2013-04-05 02:16:19 +000099 try:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800100 response = urlopen(url)
101 except URLError, e:
102 print "get_json: REST IF %s has issue. Reason: %s" % (url, e.reason)
Masayoshi Kobayashi2ae891a2013-04-05 02:16:19 +0000103 result = ""
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800104 return (500, result)
105 except HTTPError, e:
106 print "get_json: REST IF %s has issue. Code %s" % (url, e.code)
107 result = ""
108 return (e.code, result)
Masayoshi Kobayashi2ae891a2013-04-05 02:16:19 +0000109
Naoki Shiotad5d0e942014-03-27 18:57:32 -0700110 print response
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800111 result = response.read()
112# parsedResult = json.loads(result)
Masayoshi Kobayashi2ae891a2013-04-05 02:16:19 +0000113 return (code, result)
114
Masayoshi Kobayashi13e2ebe2013-03-26 18:38:41 +0000115
Ubuntu82b8a832013-02-06 22:00:11 +0000116def node_id(switch_array, dpid):
117 id = -1
118 for i, val in enumerate(switch_array):
119 if val['name'] == dpid:
120 id = i
121 break
122
123 return id
124
Masayoshi Kobayashi13e2ebe2013-03-26 18:38:41 +0000125## API for ON.Lab local GUI ##
Masayoshi Kobayashif63ef2f2013-02-20 21:47:21 +0000126@app.route('/topology', methods=['GET'])
Ubuntu82b8a832013-02-06 22:00:11 +0000127def topology_for_gui():
128 try:
Jonathan Hart5caa0442014-03-19 15:20:07 -0700129 url="http://%s:%s/wm/onos/topology/switches/json" % (RestIP, RestPort)
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800130 (code, result) = get_json(url)
Ubuntu82b8a832013-02-06 22:00:11 +0000131 parsedResult = json.loads(result)
132 except:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800133 log_error("REST IF has issue: %s" % url)
Ubuntu82b8a832013-02-06 22:00:11 +0000134 log_error("%s" % result)
Masayoshi Kobayashi7fa3fb82013-06-20 18:10:46 -0700135 return
Ubuntu82b8a832013-02-06 22:00:11 +0000136
137 topo = {}
138 switches = []
139 links = []
Ubuntu37ebda62013-03-01 00:35:31 +0000140 devices = []
Ubuntu82b8a832013-02-06 22:00:11 +0000141
142 for v in parsedResult:
143 if v.has_key('dpid'):
144# if v.has_key('dpid') and str(v['state']) == "ACTIVE":#;if you want only ACTIVE nodes
145 dpid = str(v['dpid'])
146 state = str(v['state'])
147 sw = {}
148 sw['name']=dpid
Ubuntu5b2b24a2013-02-27 09:51:13 +0000149 sw['group']= -1
Ubuntu37ebda62013-03-01 00:35:31 +0000150
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000151 if state == "INACTIVE":
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000152 sw['group']=0
Ubuntu82b8a832013-02-06 22:00:11 +0000153 switches.append(sw)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000154
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000155 try:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800156 url="http://%s:%s/wm/onos/registry/switches/json" % (RestIP, RestPort)
157 (code, result) = get_json(url)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000158 parsedResult = json.loads(result)
159 except:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800160 log_error("REST IF has issue: %s" % url)
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000161 log_error("%s" % result)
162
163 for key in parsedResult:
164 dpid = key
165 ctrl = parsedResult[dpid][0]['controllerId']
166 sw_id = node_id(switches, dpid)
167 if sw_id != -1:
168 if switches[sw_id]['group'] != 0:
169 switches[sw_id]['group'] = controllers.index(ctrl) + 1
170
Ubuntu82b8a832013-02-06 22:00:11 +0000171 try:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800172 url = "http://%s:%s/wm/onos/topology/links/json" % (RestIP, RestPort)
173 (code, result) = get_json(url)
Ubuntu82b8a832013-02-06 22:00:11 +0000174 parsedResult = json.loads(result)
175 except:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800176 log_error("REST IF has issue: %s" % url)
Ubuntu82b8a832013-02-06 22:00:11 +0000177 log_error("%s" % result)
Masayoshi Kobayashi7fa3fb82013-06-20 18:10:46 -0700178 return
179# sys.exit(0)
Ubuntu82b8a832013-02-06 22:00:11 +0000180
181 for v in parsedResult:
182 link = {}
183 if v.has_key('dst-switch'):
184 dst_dpid = str(v['dst-switch'])
185 dst_id = node_id(switches, dst_dpid)
186 if v.has_key('src-switch'):
187 src_dpid = str(v['src-switch'])
188 src_id = node_id(switches, src_dpid)
189 link['source'] = src_id
190 link['target'] = dst_id
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000191
Jonathan Hartbf66dff2013-10-28 14:07:41 -0700192 #onpath = 0
193 #for (s,d) in path:
194 # if s == v['src-switch'] and d == v['dst-switch']:
195 # onpath = 1
196 # break
197 #link['type'] = onpath
Masayoshi Kobayashi3bc5fde2013-02-28 01:02:54 +0000198
Ubuntu82b8a832013-02-06 22:00:11 +0000199 links.append(link)
200
201 topo['nodes'] = switches
202 topo['links'] = links
203
Ubuntu82b8a832013-02-06 22:00:11 +0000204 js = json.dumps(topo)
205 resp = Response(js, status=200, mimetype='application/json')
206 return resp
207
Naoki Shiota862cc3b2013-12-13 15:42:50 -0800208@app.route("/wm/floodlight/topology/toporoute/<v1>/<p1>/<v2>/<p2>/json")
Ubuntuaea2a682013-02-08 08:30:10 +0000209def shortest_path(v1, p1, v2, p2):
210 try:
Jonathan Hart5caa0442014-03-19 15:20:07 -0700211 url = "http://%s:%s/wm/onos/topology/switches/json" % (RestIP, RestPort)
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800212 (code, result) = get_json(url)
Ubuntuaea2a682013-02-08 08:30:10 +0000213 parsedResult = json.loads(result)
214 except:
215 log_error("REST IF has issue: %s" % command)
216 log_error("%s" % result)
Masayoshi Kobayashi7fa3fb82013-06-20 18:10:46 -0700217 return
Ubuntuaea2a682013-02-08 08:30:10 +0000218
219 topo = {}
220 switches = []
221 links = []
222
223 for v in parsedResult:
224 if v.has_key('dpid'):
225 dpid = str(v['dpid'])
226 state = str(v['state'])
227 sw = {}
228 sw['name']=dpid
229 if str(v['state']) == "ACTIVE":
230 if dpid[-2:-1] == "a":
231 sw['group']=1
232 if dpid[-2:-1] == "b":
233 sw['group']=2
234 if dpid[-2:-1] == "c":
235 sw['group']=3
236 if str(v['state']) == "INACTIVE":
237 sw['group']=0
238
239 switches.append(sw)
240
241 try:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800242 url = "http://%s:%s/wm/onos/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
243 (code, result) = get_json(url)
Ubuntuaea2a682013-02-08 08:30:10 +0000244 parsedResult = json.loads(result)
245 except:
246 log_error("No route")
247 parsedResult = []
Ubuntuaea2a682013-02-08 08:30:10 +0000248
Paul Greyson4e6dc3a2013-03-27 11:37:14 -0700249 path = [];
Ubuntuaea2a682013-02-08 08:30:10 +0000250 for i, v in enumerate(parsedResult):
251 if i < len(parsedResult) - 1:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800252 sdpid= parsedResult['flowEntries'][i]['dpid']['value']
253 ddpid= parsedResult['flowEntries'][i+1]['dpid']['value']
Paul Greyson4e6dc3a2013-03-27 11:37:14 -0700254 path.append( (sdpid, ddpid))
Ubuntuaea2a682013-02-08 08:30:10 +0000255
256 try:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800257 url = "http://%s:%s/wm/onos/topology/links/json" % (RestIP, RestPort)
258 (code, result) = get_json(url)
Ubuntuaea2a682013-02-08 08:30:10 +0000259 parsedResult = json.loads(result)
260 except:
261 log_error("REST IF has issue: %s" % command)
262 log_error("%s" % result)
Masayoshi Kobayashi7fa3fb82013-06-20 18:10:46 -0700263 return
Ubuntuaea2a682013-02-08 08:30:10 +0000264
265 for v in parsedResult:
266 link = {}
267 if v.has_key('dst-switch'):
268 dst_dpid = str(v['dst-switch'])
269 dst_id = node_id(switches, dst_dpid)
270 if v.has_key('src-switch'):
271 src_dpid = str(v['src-switch'])
272 src_id = node_id(switches, src_dpid)
273 link['source'] = src_id
274 link['target'] = dst_id
275 onpath = 0
276 for (s,d) in path:
277 if s == v['src-switch'] and d == v['dst-switch']:
278 onpath = 1
279 break
280
281 link['type'] = onpath
282 links.append(link)
283
284 topo['nodes'] = switches
285 topo['links'] = links
286
Ubuntuaea2a682013-02-08 08:30:10 +0000287 js = json.dumps(topo)
288 resp = Response(js, status=200, mimetype='application/json')
289 return resp
290
Naoki Shiota862cc3b2013-12-13 15:42:50 -0800291@app.route("/wm/floodlight/core/controller/switches/json")
Ubuntu82b8a832013-02-06 22:00:11 +0000292def query_switch():
293 try:
Jonathan Hart5caa0442014-03-19 15:20:07 -0700294 url = "http://%s:%s/wm/onos/topology/switches/json" % (RestIP, RestPort)
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800295 (code, result) = get_json(url)
Ubuntu82b8a832013-02-06 22:00:11 +0000296 parsedResult = json.loads(result)
297 except:
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800298 log_error("REST IF has issue: %s" % url)
Ubuntu82b8a832013-02-06 22:00:11 +0000299 log_error("%s" % result)
Masayoshi Kobayashi7fa3fb82013-06-20 18:10:46 -0700300 return
301# sys.exit(0)
Ubuntu82b8a832013-02-06 22:00:11 +0000302
303# print command
304# print result
305 switches_ = []
306 for v in parsedResult:
307 if v.has_key('dpid'):
308 if v.has_key('dpid') and str(v['state']) == "ACTIVE":#;if you want only ACTIVE nodes
309 dpid = str(v['dpid'])
310 state = str(v['state'])
311 sw = {}
312 sw['dpid']=dpid
313 sw['active']=state
314 switches_.append(sw)
315
Masayoshi Kobayashi1407a502013-02-27 06:23:08 +0000316# pp.pprint(switches_)
Ubuntu82b8a832013-02-06 22:00:11 +0000317 js = json.dumps(switches_)
318 resp = Response(js, status=200, mimetype='application/json')
319 return resp
320
Ubuntu82b8a832013-02-06 22:00:11 +0000321## return fake stat for now
Naoki Shiota862cc3b2013-12-13 15:42:50 -0800322@app.route("/wm/floodlight/core/switch/<switchId>/<statType>/json")
Ubuntu82b8a832013-02-06 22:00:11 +0000323def switch_stat(switchId, statType):
324 if statType == "desc":
325 desc=[{"length":1056,"serialNumber":"None","manufacturerDescription":"Nicira Networks, Inc.","hardwareDescription":"Open vSwitch","softwareDescription":"1.4.0+build0","datapathDescription":"None"}]
326 ret = {}
327 ret[switchId]=desc
328 elif statType == "aggregate":
329 aggr = {"packetCount":0,"byteCount":0,"flowCount":0}
330 ret = {}
331 ret[switchId]=aggr
332 else:
Paul Greyson4e6dc3a2013-03-27 11:37:14 -0700333 ret = {}
Ubuntu82b8a832013-02-06 22:00:11 +0000334
335 js = json.dumps(ret)
336 resp = Response(js, status=200, mimetype='application/json')
337 return resp
338
Masayoshi Kobayashibcb03c02014-01-22 15:18:49 -0800339@app.route("/controller_status")
340def controller_status():
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800341 url= "http://%s:%d/wm/onos/registry/controllers/json" % (RestIP, RestPort)
Masayoshi Kobayashibcb03c02014-01-22 15:18:49 -0800342 (code, result) = get_json(url)
343 parsedResult = json.loads(result)
344
345 cont_status=[]
346 for i in controllers:
347 status={}
348 if i in parsedResult:
349 onos=1
350 else:
351 onos=0
352 status["name"]=i
353 status["onos"]=onos
354 status["cassandra"]=0
355 cont_status.append(status)
356
357 js = json.dumps(cont_status)
358 resp = Response(js, status=200, mimetype='application/json')
359 return resp
360
Ubuntu82b8a832013-02-06 22:00:11 +0000361if __name__ == "__main__":
Masayoshi Kobayashi2ae891a2013-04-05 02:16:19 +0000362 random.seed()
Pavlin Radoslavov092d0e22013-04-07 05:42:51 +0000363 read_config()
Ubuntu82b8a832013-02-06 22:00:11 +0000364 if len(sys.argv) > 1 and sys.argv[1] == "-d":
Masayoshi Kobayashi640ad692014-01-22 23:37:59 -0800365 # for debugging
366 #add_flow("00:00:00:00:00:00:02:02", 1, "00:00:00:00:00:00:03:02", 1, "00:00:00:00:02:02", "00:00:00:00:03:0c")
367 #proxy_link_change("up", "00:00:00:00:ba:5e:ba:11", 1, "00:00:00:00:00:00:00:00", 1)
368 #proxy_link_change("down", "00:00:20:4e:7f:51:8a:35", 1, "00:00:00:00:00:00:00:00", 1)
369 #proxy_link_change("up", "00:00:00:00:00:00:02:03", 1, "00:00:00:00:00:00:00:00", 1)
370 #proxy_link_change("down", "00:00:00:00:00:00:07:12", 1, "00:00:00:00:00:00:00:00", 1)
371 #print "-- query all switches --"
372 #query_switch()
373 #print "-- query topo --"
374 #topology_for_gui()
375 ##print "-- query all links --"
376 ##query_links()
377 #print "-- query all devices --"
378 #devices()
379 #links()
380 #switches()
381 #reset_demo()
382 pass
Ubuntu82b8a832013-02-06 22:00:11 +0000383 else:
384 app.debug = True
Naoki Shiotad5d0e942014-03-27 18:57:32 -0700385 app.run(threaded=True, host=ProxyIP, port=ProxyPort)