Skip to content
Snippets Groups Projects
Commit 47cdd904 authored by Ryan Izard's avatar Ryan Izard
Browse files

Merge pull request #660 from rizard/master

Update to a new web user interface
parents 3a516e9e 1fd8ef35
No related branches found
No related tags found
No related merge requests found
Showing
with 4 additions and 4880 deletions
[submodule "src/main/resources/web"]
path = src/main/resources/web
url = https://github.com/floodlight/floodlight-webui
Subproject commit 7c0483d222465d42b8cb3fd0ab3613b1b8736f82
This diff is collapsed.
.dropdown-menu {
max-height: 400px;
overflow-y: scroll;
width: 220px;
}
.list-item {
padding-top: 6px;
padding-left: 56px;
}
.no-reports {
display: none;
}
\ No newline at end of file
src/main/resources/web/img/floodlight.png

7.79 KiB

src/main/resources/web/img/glyphicons-halflings-white.png

4.25 KiB

src/main/resources/web/img/glyphicons-halflings.png

4.25 KiB

src/main/resources/web/img/logo.jpg

40.9 KiB

src/main/resources/web/img/openflow-logo-40px.png

3.46 KiB

src/main/resources/web/img/server.png

442 B

src/main/resources/web/img/switch.png

2.01 KiB

<!DOCTYPE html>
<!-- template from Christophe Coenraets -->
<!--
Copyright 2012 IBM
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Floodlight</title>
<meta name="description" content="">
<meta name="author" content="">
<!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<!-- Place this tag in your head or just before your close body tag -->
<![endif]-->
<!-- Le styles -->
<style>
body {
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
}
</style>
<link href="css/bootstrap.css" rel="stylesheet">
<link href="css/styles.css" rel="stylesheet">
<!-- Le fav and touch icons -->
<!-- TODO create some icons
<link rel="shortcut icon" href="/img/favicon.ico">
<link rel="apple-touch-icon" href="/img/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="72x72" href="/img/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="114x114" href="/img/apple-touch-icon-114x114.png">
-->
</head>
<body>
<div class="header"></div>
<div class="container">
<div id="content"></div>
<hr>
<footer class="footer">
<p><a href="http://floodlight.openflowhub.org/">Floodlight </a> &copy; <a href="http://www.bigswitch.com/">Big Switch Networks</a>, <a href="http://www.research.ibm.com/arl/">IBM</a>, et. al.
Powered by <a href="http://documentcloud.github.com/backbone/">Backbone.js</a>, <a href="http://twitter.github.com/bootstrap/">Bootstrap</a>, <a href="http://jquery.com/">jQuery</a>, <a href="http://mbostock.github.com/d3/">D3.js</a>, etc.</p>
</footer>
</div> <!-- /container -->
<script src="lib/jquery.min.js"></script>
<script src="lib/underscore-min.js"></script>
<script src="lib/backbone-min.js"></script>
<script src="lib/d3.v2.min.js"></script>
<script src="lib/bootstrap-dropdown.js"></script>
<script src="lib/bootstrap-alert.js"></script>
<script src="js/utils.js"></script>
<script src="js/models/hostmodel.js"></script>
<script src="js/models/topologymodel.js"></script>
<script src="js/models/statusmodel.js"></script>
<script src="js/models/switchmodel.js"></script>
<script src="js/models/portmodel.js"></script>
<script src="js/models/flowmodel.js"></script>
<script src="js/views/header.js"></script>
<script src="js/views/home.js"></script>
<script src="js/views/status.js"></script>
<script src="js/views/host.js"></script>
<script src="js/views/switch.js"></script>
<script src="js/views/topology.js"></script>
<script src="js/views/port.js"></script>
<script src="js/views/flow.js"></script>
<script src="js/main.js"></script>
</body>
</html>
/*
Copyright 2012 IBM
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var hackBase = ""; // put a URL here to access a different REST server
var AppRouter = Backbone.Router.extend({
routes:{
"":"home",
"topology":"topology",
"switches":"switchList",
"switch/:id":"switchDetails",
"switch/:id/port/:p":"portDetails", // not clear if needed
"hosts":"hostList",
"host/:id":"hostDetails",
// "vlans":"vlanList" // maybe one day
// "vlan/:id":"vlanDetails"
},
initialize:function () {
this.headerView = new HeaderView();
$('.header').html(this.headerView.render().el);
// Close the search dropdown on click anywhere in the UI
$('body').click(function () {
$('.dropdown').removeClass("open");
});
},
home:function () {
$('#content').html(new HomeView().render().el);
$('ul[class="nav"] > li').removeClass('active');
$('a[href="/"]').parent().addClass('active');
},
topology:function () {
//console.log("switching to topology view");
var topo = new Topology();
$('#content').html(new TopologyView({model:topo, hosts:hl}).render().el);
// TODO factor this code out
$('ul.nav > li').removeClass('active');
$('li > a[href*="topology"]').parent().addClass('active');
},
switchDetails:function (id) {
//console.log("switching [sic] to single switch view");
var sw = swl.get(id);
$('#content').html(new SwitchView({model:sw}).render().el);
$('ul.nav > li').removeClass('active');
$('li > a[href*="/switches"]').parent().addClass('active');
},
switchList:function () {
//console.log("switching [sic] to switch list view");
$('#content').html(new SwitchListView({model:swl}).render().el);
$('ul.nav > li').removeClass('active');
$('li > a[href*="/switches"]').parent().addClass('active');
},
hostDetails:function (id) {
//console.log("switching to single host view");
var h = hl.get(id);
$('#content').html(new HostView({model:h}).render().el);
$('ul.nav > li').removeClass('active');
$('li > a[href*="/hosts"]').parent().addClass('active');
},
hostList:function () {
//console.log("switching to host list view");
$('#content').html(new HostListView({model:hl}).render().el);
$('ul.nav > li').removeClass('active');
$('li > a[href*="/hosts"]').parent().addClass('active');
},
});
// load global models and reuse them
var swl = new SwitchCollection();
var hl = new HostCollection();
var updating = true;
tpl.loadTemplates(['home', 'status', 'topology', 'header', 'switch', 'switch-list', 'switch-list-item', 'host', 'host-list', 'host-list-item', 'port-list', 'port-list-item', 'flow-list', 'flow-list-item'],
function () {
app = new AppRouter();
Backbone.history.start({pushState: true});
//console.log("started history")
$(document).ready(function () {
// trigger Backbone routing when clicking on links, thanks to Atinux and pbnv
app.navigate("", true);
window.document.addEventListener('click', function(e) {
e = e || window.event
var target = e.target || e.srcElement
if ( target.nodeName.toLowerCase() === 'a' ) {
e.preventDefault()
var uri = target.getAttribute('href')
if (uri.substr(0,4) !== 'http') {
app.navigate(uri.substr(1), true)
}
else {
parent.window.location.assign(uri)
}
}
});
window.addEventListener('popstate', function(e) {
app.navigate(location.pathname.substr(1), true);
});
// wait for the page to be rendered before loading any data
swl.fetch();
hl.fetch();
setInterval(function () {
if(updating) {
swl.fetch();
hl.fetch();
}
}, 3000);
});
});
/*
Copyright 2012 IBM
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
window.Flow = Backbone.Model.extend({
defaults: {
receiveBytes: 0,
receivePackets: 0,
transmitBytes: 0,
transmitPackets: 0,
},
// initialize:function () {}
});
window.FlowCollection = Backbone.Collection.extend({
model:Flow,
// instead of the collection loading its children, the switch will load them
// initialize:function () {}
});
\ No newline at end of file
/*
Copyright 2012 IBM
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
window.Host = Backbone.Model.extend({
defaults: {
// vlan: -1,
lastSeen: 'never',
ip: ' ',
swport: ' ',
},
// initialize:function () {}
});
window.HostCollection = Backbone.Collection.extend({
model:Host,
fetch:function () {
var self = this;
//console.log("fetching host list")
$.ajax({
url:hackBase + "/wm/device/",
dataType:"json",
success:function (data) {
//console.log("fetched host list: " + data.length);
// console.log(data);
// data is a list of device hashes
var old_ids = self.pluck('id');
//console.log("old_ids" + old_ids);
_.each(data, function(h) {
h.id = h.mac[0];
old_ids = _.without(old_ids, h.id);
if (h['attachmentPoint'].length > 0) {
h.swport = _.reduce(h['attachmentPoint'], function(memo, ap) {
return memo + ap.switchDPID + "-" + ap.port + " "}, "");
//console.log(h.swport);
h.lastSeen = new Date(h.lastSeen).toLocaleString();
self.add(h, {silent: true});
}
});
// old_ids now holds hosts that no longer exist; remove them
//console.log("old_ids" + old_ids);
_.each(old_ids, function(h) {
console.log("---removing host " + h);
self.remove({id:h});
});
self.trigger('add'); // batch redraws
}
});
},
/*
* findByName:function (key) { // TODO: Modify service to include firstName
* in search var url = (key == '') ? '/host/' : "/host/search/" + key;
* console.log('findByName: ' + key); var self = this; $.ajax({ url:url,
* dataType:"json", success:function (data) { console.log("search success: " +
* data.length); self.reset(data); } }); }
*/
});
/*
Copyright 2012 IBM
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
window.Port = Backbone.Model.extend({
defaults: {
name: '',
receiveBytes: 0,
receivePackets: 0,
transmitBytes: 0,
transmitPackets: 0,
dropped: 0,
errors: 0,
},
initialize:function () {
// TODO hook up associated hosts
}
});
window.PortCollection = Backbone.Collection.extend({
model:Port,
// instead of the collection loading its children, the switch will load them
initialize:function () {}
});
\ No newline at end of file
/*
Copyright 2012 IBM
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
window.Status = Backbone.Model.extend({
defaults: {
host: 'localhost',
ofport: 6633,
uptime: 'unknown',
free: 0,
total: 0,
healthy: 'unknown',
modules: [],
moduleText: ''
},
initialize:function () {
var self = this;
console.log("fetching controller status");
$.ajax({
url:hackBase + "/wm/core/health/json",
dataType:"json",
success:function (data) {
console.log("fetched controller status: health");
self.set(data);
// console.log(self.toJSON());
}
});
$.ajax({
url:hackBase + "/wm/core/system/uptime/json",
dataType:"json",
success:function (data) {
console.log("fetched controller status: uptime");
self.set({uptime:(Math.round(data.systemUptimeMsec / 1000) + ' s')});
// console.log(self.toJSON());
}
});
$.ajax({
url:hackBase + "/wm/core/memory/json",
dataType:"json",
success:function (data) {
console.log("fetched controller status: memory");
self.set(data);
// console.log(self.toJSON());
}
});
$.ajax({
url:hackBase + "/wm/core/module/loaded/json",
dataType:"json",
success:function (data) {
console.log("fetched controller status: modules loaded");
// console.log(data);
self.set({modules:_.keys(data)});
self.set({moduleText:_.reduce(_.keys(data), function(s, m)
{return s+m.replace("net.floodlightcontroller", "n.f")+", "}, '')});
}
});
}
});
\ No newline at end of file
This diff is collapsed.
/*
Copyright 2012 IBM
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
window.Topology = Backbone.Model.extend({
url:"/wm/topology/links/json",
defaults:{
nodes: [],
links: [],
},
initialize:function () {
var self = this;
console.log("fetching topology")
$.ajax({
url:hackBase + self.url,
dataType:"json",
success:function (data) {
console.log("fetched topology: " + data.length);
// console.log(data);
self.nodes = {};
self.links = [];
// step 1: build unique array of switch IDs
/* this doesn't work if there's only one switch,
because there are no switch-switch links
_.each(data, function (l) {
self.nodes[l['src-switch']] = true;
self.nodes[l['dst-switch']] = true;
});
// console.log(self.nodes);
var nl = _.keys(self.nodes);
*/
var nl = swl.pluck('id');
self.nodes = _.map(nl, function (n) {return {name:n}});
// step 2: build array of links in format D3 expects
_.each(data, function (l) {
self.links.push({source:nl.indexOf(l['src-switch']),
target:nl.indexOf(l['dst-switch']),
value:10});
});
// console.log(self.nodes);
// console.log(self.links);
self.trigger('change');
//self.set(data);
}
});
}
});
\ No newline at end of file
// template loader from Christophe Coenraets
tpl = {
// Hash of preloaded templates for the app
templates:{},
// Recursively pre-load all the templates for the app.
// This implementation should be changed in a production environment. All the template files should be
// concatenated in a single file.
loadTemplates:function (names, callback) {
var that = this;
var loadTemplate = function (index) {
var name = names[index];
console.log('Loading template: ' + name);
$.get('tpl/' + name + '.html', function (data) {
that.templates[name] = data;
index++;
if (index < names.length) {
loadTemplate(index);
} else {
callback();
}
});
}
loadTemplate(0);
},
// Get template by name from hash of preloaded templates
get:function (name) {
return this.templates[name];
}
};
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment