table on topology views add and start router controller
authorFelix <josuer08@gmail.com>
Tue, 3 Dec 2019 01:39:40 +0000 (01:39 +0000)
committerFelix <josuer08@gmail.com>
Tue, 3 Dec 2019 01:39:40 +0000 (01:39 +0000)
18 files changed:
img/toporouting.png [new file with mode: 0644]
js/topology/cards.js [new file with mode: 0644]
js/topology/main.js [new file with mode: 0644]
js/topology/mainmenu.js [new file with mode: 0644]
js/topology/modules.js [new file with mode: 0644]
js/topology/topology.js
npm-debug.log
partials/header.ejs
src/routes/index.js
src/views/access.ejs
src/views/index.ejs
src/views/starter.ejs
src/views/topology.ejs
styles/cards.css [new file with mode: 0644]
styles/main.css
styles/starter.css
styles/style.css
styles/topology.css

diff --git a/img/toporouting.png b/img/toporouting.png
new file mode 100644 (file)
index 0000000..41ac9ef
Binary files /dev/null and b/img/toporouting.png differ
diff --git a/js/topology/cards.js b/js/topology/cards.js
new file mode 100644 (file)
index 0000000..04c0606
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright (c) 2018 Maen Artimy\r
+// \r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+// \r
+//   http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+\r
+var BAR_IDX = 1;\r
+var CONTAINER_IDX = 2;\r
+\r
+var cardControl = ( function() {\r
+       console.log("cardControl");\r
+       var expand = function(e) {\r
+               var size = e.parentElement.parentElement.parentElement.style.width;\r
+               if(size==='96%') { // first value of size is ""\r
+                       e.parentElement.parentElement.parentElement.style.width = '45%';\r
+               } else {\r
+                       e.parentElement.parentElement.parentElement.style.width = '96%';\r
+               }\r
+               //e.classList.toggle("active");\r
+       };\r
+\r
+       var collapse = function(e) {\r
+               var c = e.parentElement.parentElement.parentElement.childNodes.item(CONTAINER_IDX);\r
+               var disp = c.style.display;\r
+               if(disp == "none") {\r
+                       c.style.display = "block"\r
+               } else {\r
+                       c.style.display = "none";\r
+               }\r
+       };\r
+\r
+       return {\r
+               expand: expand,\r
+               collapse: collapse\r
+       }\r
+})();\r
+\r
+// Generate cards dynamicly based on the template given by local 'html' variable\r
+// and data from the 'views' list. Cards are added to the 'parent' element\r
+// passed as argument.\r
+var generateCards = ( function() {\r
+       console.log("generateCards");\r
+       var html =      "<div class=\"header\"><h1>{Title}</h1> \\r
+                       <div class=\"topnav\"><a href=\"javascript:void(0)\" onclick=\"cardControl.collapse(this)\">&#8722;</a> \\r
+                       <a href=\"javascript:void(0)\" onclick=\"cardControl.expand(this)\">&#8596;</a> \\r
+                       </div></div><div class=\"bar\"></div><div class=\"container\"><p>No data to display...</p> \\r
+                       </div><div class=\"footing\"></div>";\r
+\r
+       // <a href=\"#refresh\">&#8634;</a>\r
+\r
+       var run = function(views, parent) {\r
+               console.log("generateCards.run");\r
+               var doc = document.getElementById(parent);\r
+               doc.innerHTML = "";\r
+               for (var idx in views) {\r
+                       var d = document.createElement("div");\r
+                       d.id = views[idx].id;\r
+                       d.classList.add("card");\r
+                       var card = html.replace("{Title}", views[idx].dsc);\r
+                       d.innerHTML = card;\r
+                       doc.appendChild(d);\r
+               }\r
+       };\r
+\r
+       /*var loadModules = function(views) {\r
+               for (var idx in views) {\r
+                       if(views[idx].call) {\r
+                               var card = document.getElementById(views[idx].id);\r
+                               var container = card.childNodes.item(CONTAINER_IDX)\r
+\r
+                               var myModule = new BaseModule(views[idx].cmd);\r
+                               myModule.callback = views[idx].call;\r
+                               myModule.run(container);\r
+                       }\r
+               }\r
+       };*/\r
+\r
+       return {\r
+               run: run\r
+       }\r
+})();\r
+\r
+var views = [\r
+{id:"mSwitch", cmd:"/listswitch", dsc:"Open V Switch ID(s)", call:dpList, ref:true},\r
+{id:"mTableStats", cmd:"/tablestatus?tablestat=<dpid>", dsc:"Table stats", call:dpTable, ref:true},\r
+{id:"mPortDesc", cmd:"/portsdesc?portdesc=<dpid>", dsc:"Port Desc", call:dpTable, ref:true},\r
+{id:"mPorts", cmd:"/portsstat?portstat=<dpid>", dsc:"Ports stats", call:dpTable, ref:true},\r
+//{id:"mTableFeature", cmd:"/data?tablefeature=<dpid>", dsc:"Table Features", call:dpTable, ref:true},\r
+//{id:"mQueueStats", cmd:"/data?queuestat=<dpid>", dsc:"Queue Stats", call:dpTable, ref:true},\r
+//{id:"mQueueConfig", cmd:"/data?queueconfig=<dpid>", dsc:"Queue Configuration", call:dpTable, ref:true},\r
+//{id:"mMeters", cmd:"/data?meterstat=<dpid>", dsc:"Meter stats", call:dpTable, ref:true}\r
+];\r
diff --git a/js/topology/main.js b/js/topology/main.js
new file mode 100644 (file)
index 0000000..de882e5
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright (c) 2018 Maen Artimy\r
+// \r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+// \r
+//   http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+/**\r
+ * All global objects are here.\r
+ *\r
+ **/\r
+var myGlobalObject = (function () {\r
+       console.log("myGlobalObject");\r
+       var dpid = 1; //current datapath (switch) ID\r
+       var myMasterURL = ""; //"http://localhost:8080";\r
+\r
+       // returns full url for the command sent to the SDN controller\r
+       var url = function(command) {\r
+               var cmd = command.replace("<dpid>",dpid); //dpidStr(dpid));\r
+               return myMasterURL + cmd;\r
+       };\r
+\r
+       // sends asynchronous request to the SDN controller\r
+       function httpGetAsync(command, callback, element) {\r
+               //console.log("httpGetAsync");\r
+               var COMPLETE = 4;\r
+               var OK = 200;\r
+               var NOTFOUND = 404;\r
+               var UNAVAILABLE = 503;\r
+               // this script is for sending a GET request to a server\r
+               var xmlHttp = new XMLHttpRequest();\r
+               xmlHttp.onreadystatechange = function() {\r
+                       if (xmlHttp.readyState == COMPLETE) {\r
+                               if(xmlHttp.status == OK) {\r
+                                       callback(xmlHttp.responseText, element);\r
+                               } else {\r
+                                       console.log(xmlHttp.status);\r
+                               }\r
+                       }\r
+               }\r
+               xmlHttp.open("GET", url(command), true); // true for asynchronous\r
+               xmlHttp.send(null);\r
+       }\r
+\r
+       function httpPostAsync(command, parm, callback, element) {\r
+               //console.log("httpPostAsync");\r
+               var COMPLETE = 4;\r
+               var OK = 200;\r
+               var NOTFOUND = 404;\r
+               var UNAVAILABLE = 503;\r
+               // this script is for sending a GET request to a server\r
+               var xmlHttp = new XMLHttpRequest();\r
+               xmlHttp.onreadystatechange = function() {\r
+                       if (xmlHttp.readyState == COMPLETE) {\r
+                               if(xmlHttp.status == OK) {\r
+                                       callback(xmlHttp.responseText, element);\r
+                               } else {\r
+                                       console.log(xmlHttp.status);\r
+                               }\r
+                       }\r
+               }\r
+               xmlHttp.open("POST", url(command), true); // true for asynchronous\r
+               //xmlHttp.setRequestHeader("Content-Type", "application/json");\r
+               xmlHttp.setRequestHeader("Content-Type", "plain/text");\r
+               xmlHttp.send(parm);\r
+       }\r
+\r
+       function dpidStr(dpid) {\r
+               return ("000000000000000" + dpid.toString(16)).substr(-16);\r
+       }\r
+\r
+       function setDPID(str) {\r
+               dpid = parseInt(str);\r
+       }\r
+\r
+       function getDPID() {\r
+               return dpid;\r
+       }\r
+\r
+       // these are the public objects\r
+       return {\r
+               dpid: getDPID,\r
+               setDPID: setDPID,\r
+               httpGetAsync: httpGetAsync,\r
+               httpPostAsync: httpPostAsync,\r
+       }\r
+})();\r
diff --git a/js/topology/mainmenu.js b/js/topology/mainmenu.js
new file mode 100644 (file)
index 0000000..8296288
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (c) 2018 Maen Artimy
+// 
+// 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.
+
+$(function () {
+  var path = window.location.pathname;
+  var url  = window.location.href;
+
+  var menu = '<div class="menuitem"> \
+  <a href="index.html">Home</a> \
+  <a href="flows.html">Flows</a> \
+  <a href="groups.html">Groups</a> \
+  <a href="meters.html">Meters</a> \
+  <a href="flowform.html">Flow Control</a> \
+  <a href="groupform.html">Group Control</a> \
+  <a href="meterform.html">Meter Control</a> \
+  <a href="topology.html">Topology</a> \
+  <a href="messages.html">Messages</a> \
+  <a href="config.html">Configuration</a> \
+  <a href="about.html">About</a> \
+  </div>'
+
+/*  <div class="topmenu"> \
+  <a href="#home">Flow Control</a> \
+  <div id="myLinks"> \
+    <a href="flowform.html">Flow Entry</a> \
+    <a href="flowupload.html">Flow Upload</a> \
+  </div> \
+</div> \*/
+
+  //var logo = '<div class="logowrapper"></div>';
+
+  var hashtag = url.lastIndexOf('#')
+  var slash = url.lastIndexOf('/') + 1
+  var filename = hashtag < 0 ? url.substring(slash) : url.substring(slash, hashtag);
+
+  $('#menu').html(menu);
+  var $link = $('a[href="' + filename + '"]');
+  $link.addClass("active");
+  $link.parent().show();
+
+  $(".topmenu").click(function() {
+    //$("#myLinks").show();
+    $("#myLinks").animate({height: "toggle"}, 120);
+  })
+
+
+});
diff --git a/js/topology/modules.js b/js/topology/modules.js
new file mode 100644 (file)
index 0000000..4d05772
--- /dev/null
@@ -0,0 +1,252 @@
+// Copyright (c) 2018 Maen Artimy\r
+// \r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+// \r
+//   http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+/**\r
+ * Definition of modules.\r
+ *\r
+ **/\r
+\r
+// Makes a GET request to the controller\r
+function BaseModule(command) {\r
+       var cmd = command;\r
+       var go = myGlobalObject;\r
+\r
+       var run = function(element) {\r
+               go.httpGetAsync(cmd, this.callback, element);\r
+       };\r
+\r
+       var callback = function(jsondata, element) {\r
+               console.log(element);\r
+       }\r
+\r
+       return {\r
+               callback: callback,\r
+               run: run\r
+       }\r
+}\r
+\r
+// Makes a POST request to the controller\r
+function BasePostModule(command) {\r
+       var cmd = command;\r
+       var go = myGlobalObject;\r
+       var idx;\r
+       var parm = "";\r
+\r
+       var dpInFilter = function (e, x) {\r
+               idx = x;\r
+               e.innerHTML ="Filter: <input class=\"filterInput\" size=20><button onClick=\"mainFilterFunc(this.parentElement,"+idx+")\">Send</button>";\r
+       };\r
+\r
+       var run = function(element) {\r
+               go.httpPostAsync(cmd, this.param, this.callback, element);\r
+       };\r
+\r
+       var callback = function(jsondata, element) {\r
+               console.log(element);\r
+       }\r
+\r
+       return {\r
+               idx: this.idx,\r
+               param: this.param,\r
+               dpInFilter: dpInFilter,\r
+               callback: callback,\r
+               run: run\r
+       }\r
+}\r
+\r
+function hc(myString) {\r
+       return myString.replace("_"," ").replace(/\b\w/g, l => l.toUpperCase())\r
+}\r
+\r
+// Populates the Switch ID card\r
+var dpList = function (jsondata, element) {\r
+       var switches = JSON.parse(jsondata);\r
+       var found = false;\r
+\r
+       //var html = "";\r
+       element.innerHTML = "";\r
+       var ul = document.createElement("ul");\r
+       ul.setAttribute("id", "swlist");\r
+       for(var s in switches) {\r
+               var num = +switches[s]; //("000000000000000" + switches[s].toString(16)).substr(-16);\r
+               //html += num + "<br>";\r
+\r
+               var li = document.createElement("li");\r
+               li.innerHTML = num;\r
+               if(switches[s] === myGlobalObject.dpid()) {\r
+                       li.classList.add("selected");\r
+                       found = true;\r
+               }\r
+               li.addEventListener("click", clickMe);\r
+               ul.appendChild(li);\r
+       }\r
+       element.appendChild(ul);\r
+       //element.innerHTML = html;\r
+       if (!found && document.getElementById("swlist").firstChild) {\r
+               var name  = document.getElementById("swlist").firstChild.innerHTML\r
+               myGlobalObject.setDPID(name)\r
+               moduleManager.loadModules(views);\r
+       }\r
+};\r
+\r
+var dpStruct = function (jsondata, element) {\r
+       var jsonobj = JSON.parse(jsondata);\r
+       if(!jsonobj) return;\r
+       var switchName = Object.keys(jsonobj);\r
+       var struct = jsonobj[switchName];\r
+       var html = "";\r
+       for(var key in struct) {\r
+               html += hc(key) + " : " + struct[key] + "<br>";\r
+       }\r
+       element.innerHTML = html;\r
+};\r
+\r
+var dpTable = function (jsondata, element) {\r
+       var dispObj = function(obj) {\r
+               // JSON to string?\r
+               var str = "";\r
+               if(Array.isArray(obj)) {\r
+                       for(var item in obj) {\r
+                               if(obj[item] instanceof Object) {\r
+\r
+                               }       else {\r
+                                       str += obj[item].replace(":","=") + "<br>";\r
+                               }\r
+                       }\r
+                       return str;\r
+               } else {\r
+                       var allKeys = Object.keys(obj);\r
+                       for(var key in allKeys) {\r
+                               str += allKeys[key] + " = " + obj[allKeys[key]] + "<br>";\r
+                       }\r
+               }\r
+               return str;\r
+       };\r
+\r
+       var jsonobj = JSON.parse(jsondata);\r
+       if(!jsonobj) return;\r
+\r
+       var switchName = Object.keys(jsonobj);\r
+\r
+       // extract the flows\r
+       var rows = jsonobj[switchName];\r
+\r
+       // get the headers\r
+       var col = [];\r
+       for (var c in rows[0]) {\r
+               col.push(c);\r
+       }\r
+       col.sort(); // A, B, C, ...\r
+       col.reverse(); // ..., C, B, A\r
+\r
+       // CREATE DYNAMIC TABLE.\r
+       var table = document.createElement("table");\r
+       //table.classList.add("fixed_headers");\r
+\r
+       // CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.\r
+       var tr = table.insertRow(-1);                   // TABLE ROW.\r
+       for (var i = 0; i < col.length; i++) {\r
+               var th = document.createElement("th");      // TABLE HEADER.\r
+               th.innerHTML = col[i].replace("_","<br>");\r
+               tr.appendChild(th);\r
+       }\r
+\r
+       // ADD JSON DATA TO THE TABLE AS ROWS.\r
+       for (var i = 0; i < rows.length; i++) {\r
+               tr = table.insertRow(-1);\r
+               for (var j = 0; j < col.length; j++) {\r
+                       var tabCell = tr.insertCell(-1);\r
+\r
+                       if(typeof rows[i][col[j]] === 'object') {\r
+                               //tabCell.innerHTML = dispObj(rows[i][col[j]]);\r
+                               tabCell.innerHTML = JSON.stringify(rows[i][col[j]]);\r
+                       } else {\r
+                               tabCell.innerHTML = rows[i][col[j]];\r
+                       }\r
+               }\r
+       }\r
+       element.innerHTML = "";\r
+       table.align = "center";\r
+       element.appendChild(table);\r
+}\r
+\r
+// Populate the cards with data\r
+var moduleManager = (function () {\r
+       var time = 15000; //10 sec\r
+       var myViews = [];\r
+\r
+       var loadModules = function(views) {\r
+               myViews.length = 0; // it is supposed to be the best way to clear an array\r
+               self.clearInterval();\r
+\r
+               for (var idx in views) {\r
+                       if(views[idx].call) {\r
+                               var card = document.getElementById(views[idx].id);\r
+                               var container = card.childNodes.item(CONTAINER_IDX);\r
+\r
+                               var myModule;\r
+                               if(views[idx].post) {\r
+                                       myModule = new BasePostModule(views[idx].cmd);\r
+                                       var bar = card.childNodes.item(BAR_IDX);\r
+                                       myModule.dpInFilter(bar, idx);\r
+                               } else {\r
+                                       myModule = new BaseModule(views[idx].cmd);\r
+                               }\r
+                               myModule.callback = views[idx].call;\r
+                               myModule.run(container);\r
+                               views[idx].module = myModule;           // we need this to refresh\r
+                               views[idx].container = container;       // we need this to refresh\r
+\r
+                               if(views[idx].ref) { // refresh is required\r
+                                       myViews.push(views[idx]);\r
+                               };\r
+                       }\r
+               }\r
+               //myViews = views;\r
+       };\r
+\r
+       var refreshModules = function() {\r
+               for (var idx in myViews) {\r
+                       myViews[idx].module.run(myViews[idx].container);\r
+               }\r
+       }\r
+\r
+       var interval = self.setInterval(refreshModules,time);\r
+\r
+       var setInterval = function(newtime) {\r
+               time = newtime;\r
+               interval = self.setInterval(loadModules,time);\r
+       }\r
+\r
+       var getInterval = function() {\r
+               console.log(time);\r
+       }\r
+\r
+       return {\r
+               setInterval: setInterval,\r
+               loadModules: loadModules\r
+       }\r
+})();\r
+\r
+function clickMe(e) {\r
+       //console.log(e);\r
+       myGlobalObject.setDPID(e.currentTarget.innerHTML);\r
+       moduleManager.loadModules(views);\r
+}\r
+\r
+function mainFilterFunc(element, idx) {\r
+       var str = element.getElementsByClassName("filterInput")[0].value;\r
+       views[idx].module.param = str;\r
+       views[idx].module.run(views[idx].container);\r
+}\r
index 45040e107c1709d4bfd6353d5f94950520fc3a07..ebd33a0b841a27791cbfdef010b7ed8be29fdd29 100644 (file)
@@ -294,22 +294,18 @@ $(function () {
 // La funcion jsonget fue creada para sustituir el metodo json de D3
 
         function jsonget() {
-
           let xhr = new XMLHttpRequest();
           xhr.open('GET', "/gettopo" , true);
           //console.log(xhr); //para ver en la consola
           xhr.onload = function() {
             if (xhr.status == 200) { //can use this.status instead
               //console.log(xhr.responseText);// para ver en la consola
-
-              listTopology(JSON.parse(xhr.responseText));
               plotGraph(toGraph(JSON.parse(xhr.responseText)));
             }
           }
           xhr.send();
         }
-
-        jsonget();
+      jsonget();
 
 
 
index 54b150b6732b90ca9fb0a5cef0ca442b1cae7ca4..a2cfa34731f57141a69381f9c9a151dc3122b6ce 100644 (file)
@@ -8,7 +8,7 @@
 7 verbose unsafe-perm in lifecycle true
 8 info web@1.0.0 Failed to exec start script
 9 error web@1.0.0 start: `node src/index.js`
-9 error Exit status 143
+9 error Exit status 1
 10 error Failed at the web@1.0.0 start script.
 10 error This is most likely a problem with the web package,
 10 error not with npm itself.
index 9d98aa536f37a703343313c2fd9f36c6e3ea4148..d7e6f35b7afefb378da4aff871266aad388d0472 100644 (file)
@@ -7,13 +7,14 @@
   <span></span>
 
   <ul id="menu">
-    <a href="/"><li>Salud</li></a>
-    <a href="/topology"><li>Visualizador</li></a>
-    <a href="/stats"><li>Estadisticas</li></a>
-    <a href="/starter"><li>Inicializador</li></a>
-    <a href="/access"><li>Acceso</li></a>
-    <a href="/topologyMaker"><li>Crear topologia</li></a>
-    <a style= "display: flex;" href="https://localhost:8080/" target="_blank"><li>Pagina local</li> <img id="ctl00_XXX" src="https://upload.wikimedia.org/wikipedia/commons/4/44/Icon_External_Link.svg" style="width:0.8em; height:0.8em; border-width:0px;" /></a>
+    <a href="/"><li>Health</li></a>
+    <a href="/topology"><li>Viewer</li></a>
+    <a href="/stats"><li>Flow Tables</li></a>
+    <a href="/starter"><li>Topology Starter</li></a>
+    <a href="/access"><li>Documentation</li></a>
+    <a style= "display: flex;" href="https://github.com/josuer08/VSoRC" target="_blank"><li>GitHub web</li> <img id="ctl00_XXX" src="https://upload.wikimedia.org/wikipedia/commons/4/44/Icon_External_Link.svg" style="width:0.8em; height:0.8em; border-width:0px;" /></a>
+    <a style= "display: flex;" href="https://github.com/josuer08/vsorcdistro" target="_blank"><li>GitHub distro</li> <img id="ctl00_XXX" src="https://upload.wikimedia.org/wikipedia/commons/4/44/Icon_External_Link.svg" style="width:0.8em; height:0.8em; border-width:0px;" /></a>
+
   </ul>
 </div>
 <form class="form-inline">
index 0084754861ae7c4e74a69dc46c054abe8280a06d..d9abe2e6e2bb630e64cd22fca6b466e838b3a049 100644 (file)
@@ -4,6 +4,7 @@ const {
 const router = new Router();
 
 
+
 //renders de las paginas web
 router.get("/", (req, res) => {
   res.render("index")
@@ -40,6 +41,18 @@ router.get('/free', (req, res) => {
   });
 });
 
+router.post('/flowdel', (req, res) => {
+  var sys = require('sys')
+  var exec = require('child_process').exec;
+  var child;
+  var flow = JSON.stringify(req.body);
+  child = exec("curl -X POST -d "+req.body+"localhost:8080/flowdel", function(error, stdout, stderr) {
+    console.log(stdout);
+    console.log(req.body);
+    res.send(req.body);
+  });
+});
+
 
 router.get('/mpstat', (req, res) => {
   var sys = require('sys')
@@ -51,7 +64,6 @@ router.get('/mpstat', (req, res) => {
   });
 });
 
-
 router.get('/ifstat', (req, res) => {
   var sys = require('sys')
   var exec = require('child_process').exec;
@@ -66,8 +78,8 @@ router.get('/showtemp', (req, res) => {
   var sys = require('sys')
   var exec = require('child_process').exec;
   var child;
-  child = exec("cd /home/pi/scripts && ./gettemp.sh", function(error, stdout, stderr) {
-    console.log("show temp");
+  child = exec("cd /home/pi/scripts && (./multissh.sh  \"$(echo $(cat geteverything.sh))\" |grep -v rpi | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4)", function(error, stdout, stderr) {
+    console.log("show temp");//this was modified
     res.send(stdout);
   });
 });
@@ -178,16 +190,26 @@ router.get('/getvsorcdata', (req, res) => {
     console.log("getting vsorc data");
     res.send(stdout+"^"+isVsorcUP);
   });
-
 });
 router.get('/getcontrollerdata', (req, res) => {
   var sys = require('sys')
   var exec = require('child_process').exec;
   var child;
+  var child2;
+  child2 = exec("ps aux | grep python | grep ryu | grep -v grep |awk {'print $2'}", function(error, stdout, stderr) {
+    console.log(stdout);
+    console.log("view status controller");
+    if (stdout === ""){
+      isControllerUP = false;
+    }else {
+      isControllerUP = true;
+    }
+  });
   child = exec("cd /home/pi/scripts && cat controllerout 2>/dev/null", function(error, stdout, stderr) {
     console.log("getting controller data");
-    res.send(stdout+"^"+isControllerUP);
+    res.send(stdout+"^"+isControllerUP);//Send controller data and UP or DOWN separate by ^
   });
+
 });
 router.get('/listswitch', (req, res) => {
   var sys = require('sys')
@@ -199,15 +221,17 @@ router.get('/listswitch', (req, res) => {
     let value = '';
     try {
       value = JSON.parse(stdout)
+      res.send(value);
     }
     catch(error) {
-      console.error(error);
+      //console.error(error);
       console.log("no response from server");
       // expected output: ReferenceError: nonExistentFunction is not defined
       // Note - error messages will vary depending on browser
+      res.send("No response from server");
     }
 
-    res.send(value);
+
   });
 });
 
@@ -225,6 +249,76 @@ router.get('/status', (req, res) => {
   });
 });
 
+router.get('/tablestatus', (req, res) => {
+  var sys = require('sys')
+  var exec = require('child_process').exec;
+  var child;
+       console.log(req.query);
+               child = exec("curl \"localhost:8080/data?tablestat="+req.query.tablestat+"\"", function(error, stdout, stderr) {
+               console.log("table status");
+               console.log(stdout);
+    let value = '';
+    try {
+      value = JSON.parse(stdout)
+      res.send(value);
+    }
+    catch(error) {
+      //console.error(error);
+      console.log("no response from server");
+      // expected output: ReferenceError: nonExistentFunction is not defined
+      // Note - error messages will vary depending on browser
+      let er = "No response from server";
+      res.send(JSON.stringify(er));
+    }
+                       });
+});
+
+router.get('/portsdesc', (req, res) => {
+  var sys = require('sys')
+  var exec = require('child_process').exec;
+  var child;
+        console.log(req.query);
+                child = exec("curl \"localhost:8080/data?portdesc="+req.query.portdesc+"\"", function(error, stdout, stderr) {
+                console.log("port desc");
+                let value = '';
+                try {
+                  value = JSON.parse(stdout)
+                  res.send(value);
+                }
+                catch(error) {
+                  //console.error(error);
+                  console.log("no response from server");
+                  // expected output: ReferenceError: nonExistentFunction is not defined
+                  // Note - error messages will vary depending on browser
+                  let er = "No response from server";
+                  res.send(JSON.stringify(er));
+                }
+  });
+});
+
+router.get('/portsstat', (req, res) => {
+  var sys = require('sys')
+  var exec = require('child_process').exec;
+  var child;
+        console.log(req.query);
+                child = exec("curl \"localhost:8080/data?portstat="+req.query.portstat+"\"", function(error, stdout, stderr) {
+                console.log("port status");
+                console.log(stdout);
+                let value = '';
+                try {
+                  value = JSON.parse(stdout)
+                  res.send(value);
+                }
+                catch(error) {
+                  //console.error(error);
+                  console.log("no response from server");
+                  // expected output: ReferenceError: nonExistentFunction is not defined
+                  // Note - error messages will vary depending on browser
+                  let er = "No response from server";
+                  res.send(JSON.stringify(er));
+                }
+  });
+});
 
 router.get('/startcontroller', (req, res) => {
   isControllerUP = true;
@@ -239,6 +333,17 @@ router.get('/startcontroller', (req, res) => {
   });
 });
 
+router.get('/startcontrollerrouter', (req, res) => {
+  isControllerUP = true;
+  var sys = require('sys')
+  var exec = require('child_process').exec;
+  var child;
+  child = exec("cd /home/pi/scripts && touch controllerout && ./ryurouter.sh > controllerout 2>&1 &", function(error, stdout, stderr) {
+    console.log("controller REST Router started");
+    res.send(stdout);
+  });
+});
+
 router.get('/stopcontroller', (req, res) => {
   isControllerUP = false;
   var sys = require('sys')
@@ -320,7 +425,7 @@ router.get('/stopvsorc', (req,res) =>{
 
   //antes, en ves de echo exit > fifo, estaba sudo kill $(ps aux | grep GRE| grep sudo|awk {'print $2'})
   console.log("Exiting...");
-  child2 = exec("cd /home/pi/scripts && echo exit > fifo && rm fifo", function(error, stdout, stderr) {
+  child2 = exec("cd /home/pi/scripts && echo exit > fifo && rm fifo && sudo killall tail", function(error, stdout, stderr) {
     console.log(stdout);
     payload+="killed\n\n"+stdout;
   });
index 578847b264a592f413af8b756d5cbd6396ffd72f..06b901e73dff59d905cd60f37f9232c846b56321 100644 (file)
     <%include ../../partials/header%>
   </header>
   <div class="Terminal">
-
+    <h4>Topologia para practica de Routing</h4>
+    <img id="imgtoporouting" src="img/toporouting.png">
+    <p>
+      Esta practica consiste en crear una topologia como la mostrada en esta imagen, asi como las
+      direcciones IP de los hosts y enrutamiento estatico, de modo que exista conectividad entre las redes de h1 y h2 como de h3 y h2,
+      pero no de las redes de h1 a h3.
+      Para esto, utiliza la API rest_router del controlador RYU.
+    </p>
   </div>
 </body>
 <footer>
index 0d3b5f0743d7187c2b23885b6fa9fcafc45a4f2f..c592c86c219d8552ece33ced43a2ba733877137b 100644 (file)
     </div>
 
     <div class="wrapper TRAFFIC">
-      <div class="navbar navbar-dark bg-light"><span>Trafico de la Red</span></div>
+      <div class="navbar navbar-dark bg-light"><span>Trafico de la Red Kbps</span></div>
       <div id="trafico"></div>
       <script>
         Plotly.plot('trafico', [{
     </div>
 
     <div class="wrapper TEMP">
-      <div class="navbar navbar-dark bg-light"><span>Temperatura de los equipos</span></div>
+      <div class="navbar navbar-dark bg-light"><span>Informacion de los equipos</span></div>
       <div id="temp">
         <textarea class="text" rows="20" cols="7" id="temperatura"></textarea>
       </div>
index 07d5f07c532b8afeb9f955de0d57db1267941d99..0c76240dcac4dba2e93d121b2be79e59e342ab4b 100644 (file)
@@ -30,7 +30,8 @@
         <div class="buttons">
           <button id="btnstartvsorc" type="button" name="button" onclick="startvsorc()">Iniciar VSoRC</button>
           <button id="btnstopvsorc" type="button" name="button" onclick="stopvsorc()">Detener VSoRC</button>
-          <button id="btnstartcontroller" type="button" name="button" onclick="startcontroller()">Iniciar controlador</button>
+          <button id="btnstartcontroller" type="button" name="button" onclick="startcontroller()">Iniciar controlador Simple Switch</button>
+          <button id="btnstartcontrollerrouter" type="button" name="button" onclick="startcontrollerrouter()">Iniciar controlador REST Router</button>
           <button id="btnstopcontroller" type="button" name="button" onclick="stopcontroller()">Detener controlador</button>
         </div>
       </div>
         </div>
       </div>
       <div class="panel">
-        <textarea class="text" style="font-size: 12px;" rows="20" cols="7" id="vsorccommand" placeholder="Enviar comandos a la terminal"></textarea>
+       <input type="text" id="vsorccommand" style="background-color: rgba(255,255,255,0.8); font-size: 12px;" placeholder="Enviar comandos a la terminal"></input>
+       <!-- <textarea class="text" style="font-size: 12px;" rows="1" cols="20" id="vsorccommand" placeholder="Enviar comandos a la terminal"></textarea> -->
         <div class="buttons">
-        <button type="button" name="button" onclick="sendcommand()">Send</button>
-        <!-- <button type="button" name="button" onclick="cancel()">Cancel</button> -->
+        <button type="button" name="button" onclick="sendcommand()" id="btnsend">Send</button>
       </div>
       </div>
     </div>
       let controllerout = document.getElementById('controllerout'); //salida del controlador
       let raspberry = document.getElementById('raspberrys'); //monitor de las rpi disponibles
 
+  comando.addEventListener('keypress', function(event) {
+        if (event.keyCode == 13) {
+            event.preventDefault();
+               if(comando.value != ""){
+           document.getElementById('btnsend').click();
+}
+        }
+    });
+
+
+
       let timeVsorc = 1000;
       let timeController = 1000;
       let timeping = 5000;
 
       intervalVsorc = setInterval(getvsorcdata, timeVsorc);
       intervalController=setInterval(getcontrollerdata, timeController);
-      setInterval(rpiping,timeping);
+      setInterval(rpiping,timeping); //Para ver que rpi estan UP
+
+
       function rpiping() {
         let xhr = new XMLHttpRequest();
         xhr.open('GET', '/rpiping', true);
           }
         }
         xhr.send();
-
+      }
+      function startcontrollerrouter() {
+        let xhr = new XMLHttpRequest();
+        xhr.open('GET', '/startcontrollerrouter', true);
+        //console.log(xhr); //para ver en la consola
+        xhr.onload = function() {
+          if (xhr.status == 200) { //can use this.status instead
+            console.log("controller started router");
+          }
+        }
+        xhr.send();
       }
       function cancel() {
         let xhr = new XMLHttpRequest();
         xhr.onload = function() {
           if (xhr.status == 200) { //can use this.status instead
             //console.log(xhr.responseText);// para ver en la consola
-            let controllerstat = xhr.response.split('^');
+
+            let controllerstat = xhr.response.split('^'); //La data del controlador y el estado de este llegan separados por ^
             if(controllerstat[1] === "true"){
             document.getElementById('btnstopcontroller').disabled = false;
             document.getElementById('btnstartcontroller').disabled = true;
+            document.getElementById('btnstartcontrollerrouter').disabled = true;
             }else{
               document.getElementById('btnstopcontroller').disabled = true;
               document.getElementById('btnstartcontroller').disabled = false;
+              document.getElementById('btnstartcontrollerrouter').disabled = false;
             }
             controllerout.value=controllerstat[0];
             console.log("getting controller data");
+            console.log(controllerstat);
           }
         }
         xhr.send();
index 528502231f98d069cd770e28dbf348eb61dab2ef..3c8d230512f600306590c897a6c6db0a55e65850 100644 (file)
 
 
   <title>Topology</title>
-       <!-- <link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon"> -->
-       <!-- <link rel="stylesheet" type="text/css" href="css\style.css?v2"> -->
-       <!-- <link rel="stylesheet" type="text/css" href="css\table.css?v2"> -->
-       <!-- <link rel="stylesheet" type="text/css" href="css\cards.css?v1"> -->
-       <!-- <link rel="stylesheet" type="text/css" href="css\tabs.css?v1"> -->
-       <!-- <link rel="stylesheet" type="text/css" href="css\menu.css?v2"> -->
        <link rel="stylesheet" type="text/css" href="styles\topology.css?v3">
        <script src="js/topology/jquery-3.3.1.min.js"></script>
-       <!--script src="https://d3js.org/d3.v4.min.js"></script-->
        <script src="js/topology/d3.min.js"></script>
+
+       <!-- <link rel="stylesheet" type="text/css" href="styles\style.css"> -->
+       <link rel="stylesheet" type="text/css" href="styles\cards.css"> 
+       <!-- <link rel="stylesheet" type="text/css" href="styles\table.css"> --> 
+       <!-- <link rel="stylesheet" type="text/css" href="styles\menu.css"> -->
+        <script src="js/topology/main.js"></script> 
+         <script src="js/topology/modules.js"></script>
+         <script src="js/topology/cards.js"></script> 
+
+
 </head>
-<body>
+<body onload="generateCards.run(views, 'cards');moduleManager.loadModules(views)">
 <div class="container_16">
        <div id="header" class="grid_16">
        <h1>Topology</h1>
        </div>
        <!-- <div id="menu" class="grid_2"></div> -->
        <div id="main" class="grid_14"></div>
+       <div id="cards" class="grid_14"></div>
+
 </div>
-<!-- <script src="js/mainmenu.js"></script> -->
+
+<!-- <script src="js/topology/mainmenu.js"></script> -->
 <script src="js/topology/common.js"></script>
 <script src="js/topology/topology.js"></script>
 
diff --git a/styles/cards.css b/styles/cards.css
new file mode 100644 (file)
index 0000000..405579c
--- /dev/null
@@ -0,0 +1,151 @@
+/*\r
+    Copyright (c) Maen Artimy, 2018\r
+*/\r
+\r
+.card {\r
+       background-color: transparent;\r
+       float: left;\r
+    /*box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);*/\r
+    transition: 0.3s;\r
+    width: 430px;\r
+    font-size: 14px;\r
+    margin: 0px 10px 20px 10px;\r
+}\r
+\r
+.card:nth-of-type(even) {\r
+    clear: right;\r
+ }\r
+\r
+.card .header {\r
+    border-style: solid;\r
+    border-color: var(--scolor-3);\r
+    border-width: 2px 0 2px 0;\r
+       padding: 0px 16px;\r
+}\r
+\r
+.container {\r
+    overflow-x: auto;\r
+}\r
+\r
+.card .container {\r
+       width: 100%;\r
+       transition: 1s;\r
+       /*overflow: auto;*/\r
+\r
+       height: 150px;\r
+    padding: 8px 16px;\r
+}\r
+\r
+.card.bar {\r
+    padding: 0px 16px;\r
+}\r
+\r
+.card.bar button {\r
+       margin: 2px 8px;\r
+}\r
+\r
+.card.wide {\r
+       float: none;\r
+    width: 1100px; /*needs to be fixed*/\r
+}\r
+\r
+.card.wide .container{\r
+    height: auto;\r
+    padding: 8px 16px;\r
+}\r
+\r
+.card:hover {\r
+    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);\r
+}\r
+\r
+.card .header button {\r
+    background-color: transparent;\r
+    color: black;\r
+    cursor: pointer;\r
+    padding: 18px;\r
+    width: 100%;\r
+    border: none;\r
+    text-align: left;\r
+    outline: none;\r
+    font-size: 15px;\r
+    transition: 0.4s;\r
+}\r
+\r
+.card .header button::after {\r
+    content: '\002B';\r
+    color: black;\r
+    font-weight: bold;\r
+    float: right;\r
+    margin-left: 5px;\r
+}\r
+\r
+.card .header button.active::after {\r
+    content: "\2212";\r
+}\r
+\r
+.card .header h1 {\r
+       color: var(--scolor-4);\r
+       float: left;\r
+       font-size: 16px;\r
+       display: block;\r
+}\r
+\r
+/*temp*/\r
+.card.wide .header h1 {\r
+    /*float: none;*/\r
+    float: left;\r
+}\r
+\r
+.card ul {\r
+    list-style-type: none;\r
+    margin: 0;\r
+    padding: 0;\r
+}\r
+.card li {\r
+    padding: 2px;\r
+    margin-bottom: 2px;\r
+       border-bottom: 1px solid lightgray;\r
+}\r
+.card li::before {\r
+       content: "# ";\r
+}\r
+.card li.selected::before{\r
+       content: "#>";\r
+}\r
+\r
+.card li:hover {\r
+    background-color: #EEE;\r
+}\r
+\r
+.card .footing {\r
+    padding-bottom: 5px;\r
+    color: red;\r
+}\r
+/*\r
+Card top navigation\r
+probably not all are used.\r
+*/\r
+\r
+/* Add a black background color to the top navigation */\r
+.topnav {\r
+    /*background-color: #333;*/\r
+    background-color: transparent;\r
+    overflow: hidden;\r
+}\r
+\r
+/* Style the links inside the navigation bar */\r
+.topnav a {\r
+    float: right;\r
+    /*display: inline-block;*/\r
+    color: var(--scolor-3);\r
+    text-align: center;\r
+    padding: 12px 8px;\r
+    text-decoration: none;\r
+       font-size: 16px;\r
+}\r
+\r
+/* Add a color to the active/current link */\r
+.topnav a.active {\r
+    background-color: #4CAF50;\r
+    color: var(--scolor-3);\r
+}\r
index 0b3d0f0913e5892cc7983b95c661efbfed38dca2..98ab5ee9d483cef1162c24960b625d8ec2c62525 100644 (file)
@@ -28,8 +28,8 @@ body {
     linear-gradient(100deg, rgba(220, 220, 220, 0.07) 0%, rgba(220, 220, 220, 0.07) 50%, rgba(65, 65, 65, 0.07) 50%, rgba(65, 65, 65, 0.07) 100%),
     linear-gradient(190deg, rgba(194, 194, 194, 0.03) 0%, rgba(194, 194, 194, 0.03) 50%, rgba(206, 206, 206, 0.03) 50%, rgba(206, 206, 206, 0.03) 100%),
     linear-gradient(320deg, rgba(10, 10, 10, 0.08) 0%, rgba(10, 10, 10, 0.08) 50%, rgba(231, 231, 231, 0.08) 50%, rgba(231, 231, 231, 0.08) 100%),
-    linear-gradient(90deg, rgb(10, 147, 39), rgb(235, 252, 123)); */\r
-  display: flex;\r
+    linear-gradient(90deg, rgb(10, 147, 39), rgb(235, 252, 123)); */
+  display: flex;
   flex-direction: column;
   font-family: helvetica;
   padding-top: 10vh;
@@ -88,69 +88,87 @@ flex-grow: 1;
   align-content: stretch; */
   width: 100%;
   display: flex;
-  flex-flow: row wrap\r
-}\r
-.RAM{\r
-  flex-basis: 60%\r
-}\r
-.CPU{\r
-  flex-basis: 30%;\r
-  flex-grow: 1;\r
-}\r
-.TRAFFIC{\r
-  flex-basis: 100%\r
-}\r
-\r
-\r
-\r
-.navbar{\r
-  width: auto;\r
-}\r
-\r
-\r
-#main{\r
-  padding: 0em 10vw;\r
-}\r
-/* H1 to H6 */\r
-h1, h2, h3, h4, h5, h6, p, label, span{\r
-color: white;\r
-font-weight: bold;\r
-line-height: 1.5;\r
-}\r
-/* formularios */\r
-.form{\r
-  width: 100%;\r
-}\r
-fieldset{\r
-  width: 100%;\r
-  display: flex;\r
-  flex-flow: column wrap;\r
-  justify-content: flex-start;\r
-  align-items: stretch;\r
-  border: 0;\r
-}\r
-\r
-select{\r
-background-color: rgba(200,200,200,0.5);\r
-border: 0;\r
-border-bottom: 2px black solid;\r
-overflow: hidden;\r
-width: 15em;\r
-}\r
-/* some hacky shit for hidind the arrow */\r
-select {\r
-  /* for Firefox */\r
-  -moz-appearance: none;\r
-  /* for Chrome */\r
-  -webkit-appearance: none;\r
-}\r
-\r
-/* For IE10 */\r
-select::-ms-expand {\r
-  display: none;\r
-}\r
-\r
-input[type=text]{\r
-border-radius: 0;\r
-border: 0;\r
-}\r
+  flex-flow: row wrap
+}
+.RAM{
+  flex-basis: 60%
+}
+.CPU{
+  flex-basis: 30%;
+  flex-grow: 1;
+}
+.TRAFFIC{
+  flex-basis: 100%
+}
+.TEMP{
+flex-basis: 100%;
+}
+#temperatura{
+width: 100%;
+align-self: center;
+background-color: transparent;
+color: white;
+font-size: 1.6vw;
+font-weight: 900;
+}
+@media (max-width: 800px){
+ #temperatura{
+  font-size:16px;
+ }
+}
+
+.navbar{
+  width: auto;
+}
+
+
+#main{
+  padding: 0em 10vw;
+  padding-left: 20px;
+}
+/* H1 to H6 */
+h1, h2, h3, h4, h5, h6, p, label, span{
+color: white;
+font-weight: bold;
+line-height: 1.5;
+}
+/* formularios */
+.form{
+  width: 100%;
+}
+fieldset{
+  width: 100%;
+  display: flex;
+  flex-flow: column wrap;
+  justify-content: flex-start;
+  align-items: stretch;
+  border: 0;
+}
+
+select{
+background-color: rgba(200,200,200,0.5);
+border: 0;
+border-bottom: 2px black solid;
+overflow: hidden;
+width: 15em;
+}
+/* some hacky shit for hidind the arrow */
+select {
+  /* for Firefox */
+  -moz-appearance: none;
+  /* for Chrome */
+  -webkit-appearance: none;
+}
+
+/* For IE10 */
+select::-ms-expand {
+  display: none;
+}
+
+input[type=text]{
+border-radius: 0;
+border: 0;
+}
+#imgtoporouting{
+  width: 500px;
+}
index 23b0a26e63f6d433b2d95be3c494e4f5b94e3c2f..dcd660f0376107257b7925700d7bbd6dca8e40ed 100644 (file)
@@ -60,8 +60,9 @@ textarea {
   border-right: 2px black solid;
 }
 #vsorccommand {
-  width: 83%;
+  width: 100%;
   height: 2em;
+  resize: none;
 
 }
 #raspberrys{
index 5763334eb7a5fc65872155e4e98e111db9c67007..64df0e86437d7c87cb8f55db8ca6f3e5fd4ecbf5 100644 (file)
 }\r
 \r
 .grid_14 { /*main*/\r
-       margin-left: 150px;\r
+       margin-left: 0px;\r
        margin-right: 0px;\r
        padding-top: 10px;\r
        width: 1130px;\r
+       padding-left: 0px;\r
 }\r
 \r
 \r
index 0cd945d49eaff2a58dbd40c82e833203a494f84a..13d8d63ab59f0bb517f507cf092272fd324ebe1f 100644 (file)
@@ -54,13 +54,16 @@ text.start, text.end {
   stroke-width: 1px;
 }
 
-div.tooltip {  
-  position: absolute;                  
-  text-align: left;                            
+div.tooltip {
+  position: absolute;
+  text-align: left;
   padding: 5px;
   color: white;
-  background: var(--scolor-3);                 
-  border: 0px;         
-  border-radius: 2px;                  
-  pointer-events: none;                        
+  background: var(--scolor-3);
+  border: 0px;
+  border-radius: 2px;
+  pointer-events: none;
+}
+.tab-list{
+  display: none;
 }