modules/admin-full: live status, validation for dhcp leases
authorJo-Philipp Wich <jow@openwrt.org>
Sun, 7 Nov 2010 23:31:19 +0000 (23:31 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Sun, 7 Nov 2010 23:31:19 +0000 (23:31 +0000)
modules/admin-full/luasrc/controller/admin/network.lua
modules/admin-full/luasrc/model/cbi/admin_network/dhcpleases.lua
modules/admin-full/luasrc/view/admin_network/lease_status.htm [new file with mode: 0644]

index 9492e11..a6324f4 100644 (file)
@@ -87,6 +87,9 @@ function index()
                page.target = cbi("admin_network/dhcpleases")
                page.title  = i18n("DHCP Leases")
                page.order  = 30
                page.target = cbi("admin_network/dhcpleases")
                page.title  = i18n("DHCP Leases")
                page.order  = 30
+
+               page = entry({"admin", "network", "dhcplease_status"}, call("lease_status"), nil)
+               page.leaf = true
        end
 
        page  = node("admin", "network", "hosts")
        end
 
        page  = node("admin", "network", "hosts")
@@ -249,3 +252,43 @@ function wifi_status()
 
        luci.http.status(404, "No such device")
 end
 
        luci.http.status(404, "No such device")
 end
+
+function lease_status()
+       local rv = { }
+       local leasefile = "/var/dhcp.leases"
+
+       local uci = require "luci.model.uci".cursor()
+       local nfs = require "nixio.fs"
+
+       uci:foreach("dhcp", "dnsmasq",
+               function(s)
+                       if s.leasefile and nfs.access(s.leasefile) then
+                               leasefile = s.leasefile
+                               return false
+                       end
+               end)
+
+       local fd = io.open(leasefile, "r")
+       if fd then
+               while true do
+                       local ln = fd:read("*l")
+                       if not ln then
+                               break
+                       else
+                               local ts, mac, ip, name = ln:match("^(%d+) (%S+) (%S+) (%S+)")
+                               if ts and mac and ip and name then
+                                       rv[#rv+1] = {
+                                               expires  = os.difftime(tonumber(ts) or 0, os.time()),
+                                               macaddr  = mac,
+                                               ipaddr   = ip,
+                                               hostname = (name ~= "*") and name
+                                       }
+                               end
+                       end
+               end
+               fd:close()
+       end
+
+       luci.http.prepare_content("application/json")
+       luci.http.write_json(rv)
+end
index 70b49d7..3f631b3 100644 (file)
@@ -12,49 +12,14 @@ You may obtain a copy of the License at
 $Id$
 ]]--
 
 $Id$
 ]]--
 
-local uci = require "luci.model.uci".cursor()
 local sys = require "luci.sys"
 local sys = require "luci.sys"
-local wa  = require "luci.tools.webadmin"
-local fs  = require "nixio.fs"
 
 m2 = Map("dhcp", translate("DHCP Leases"),
        translate("Static leases are used to assign fixed IP addresses and symbolic hostnames to " ..
                "DHCP clients. They are also required for non-dynamic interface configurations where " ..
                "only hosts with a corresponding lease are served."))
 
 
 m2 = Map("dhcp", translate("DHCP Leases"),
        translate("Static leases are used to assign fixed IP addresses and symbolic hostnames to " ..
                "DHCP clients. They are also required for non-dynamic interface configurations where " ..
                "only hosts with a corresponding lease are served."))
 
-local leasefn, leasefp, leases
-uci:foreach("dhcp", "dnsmasq",
- function(section)
-       leasefn = section.leasefile
- end
-) 
-local leasefp = leasefn and fs.access(leasefn) and io.lines(leasefn)
-if leasefp then
-       leases = {}
-       for lease in leasefp do
-               table.insert(leases, luci.util.split(lease, " "))
-       end
-end
-
-if leases then
-       v = m2:section(Table, leases, translate("Active Leases"))
-
-       name = v:option(DummyValue, 4, translate("Hostname"))
-       function name.cfgvalue(self, ...)
-               local value = DummyValue.cfgvalue(self, ...)
-               return (value == "*") and "?" or value
-       end
-
-       ip = v:option(DummyValue, 3, translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
-       
-       mac  = v:option(DummyValue, 2, translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
-       
-       ltime = v:option(DummyValue, 1, translate("Leasetime remaining"))
-       function ltime.cfgvalue(self, ...)
-               local value = DummyValue.cfgvalue(self, ...)
-               return wa.date_format(os.difftime(tonumber(value), os.time()))
-       end
-end
+m2:section(SimpleSection).template = "admin_network/lease_status"
 
 s = m2:section(TypedSection, "host", translate("Static Leases"),
        translate("Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</em> " ..
 
 s = m2:section(TypedSection, "host", translate("Static Leases"),
        translate("Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</em> " ..
@@ -66,8 +31,13 @@ s.anonymous = true
 s.template = "cbi/tblsection"
 
 name = s:option(Value, "name", translate("Hostname"))
 s.template = "cbi/tblsection"
 
 name = s:option(Value, "name", translate("Hostname"))
+
 mac = s:option(Value, "mac", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
 mac = s:option(Value, "mac", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
+mac.datatype = "macaddr"
+
 ip = s:option(Value, "ip", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
 ip = s:option(Value, "ip", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
+ip.datatype = "ip4addr"
+
 sys.net.arptable(function(entry)
        ip:value(entry["IP address"])
        mac:value(
 sys.net.arptable(function(entry)
        ip:value(entry["IP address"])
        mac:value(
@@ -76,5 +46,5 @@ sys.net.arptable(function(entry)
        )
 end)
 
        )
 end)
 
-       
+
 return m2
 return m2
diff --git a/modules/admin-full/luasrc/view/admin_network/lease_status.htm b/modules/admin-full/luasrc/view/admin_network/lease_status.htm
new file mode 100644 (file)
index 0000000..9555d14
--- /dev/null
@@ -0,0 +1,97 @@
+<script type="text/javascript"><![CDATA[
+       var stxhr = new XHR();
+       (function() {
+               stxhr.get('<%=luci.dispatcher.build_url("admin", "network", "dhcplease_status")%>', null,
+                       function(x)
+                       {
+                               var st = x.responseText ? eval('(' + x.responseText + ')') : null;
+                               var tb = document.getElementById('lease_status_table');
+
+                               if (st && tb)
+                               {
+                                       /* clear all rows */
+                                       while( tb.rows.length > 1 )
+                                               tb.rows[1].parentNode.removeChild(tb.rows[1]);
+
+                                       for( var i = 0; i < st.length; i++ )
+                                       {
+                                               var timestr;
+
+                                               if (st[i].expires <= 0)
+                                               {
+                                                       timestr = '<em><%:expired%></em>';
+                                               }
+                                               else
+                                               {
+                                                       var d = 0;
+                                                       var h = 0;
+                                                       var m = 0;
+                                                       var s = st[i].expires;
+
+                                                       if (s > 60) {
+                                                               m = Math.floor(s / 60);
+                                                               s = (s % 60);
+                                                       }
+
+                                                       if (m > 60) {
+                                                               h = Math.floor(m / 60);
+                                                               m = (m % 60);
+                                                       }
+
+                                                       if (h > 24) {
+                                                               d = Math.floor(h / 24);
+                                                               h = (h % 24);
+                                                       }
+
+                                                       timestr = (d > 0)
+                                                               ? String.format('%dd %dh %dm %ds', d, h, m, s)
+                                                               : String.format('%dh %dm %ds', h, m, s);
+                                               }
+
+                                               var tr = document.createElement('tr');
+                                                       tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
+
+                                               tr.innerHTML = String.format(
+                                                       '<td class="cbi-section-table-cell">%s</td>' +
+                                                       '<td class="cbi-section-table-cell">%s</td>' +
+                                                       '<td class="cbi-section-table-cell">%s</td>' +
+                                                       '<td class="cbi-section-table-cell">%s</td>',
+                                                               st[i].hostname ? st[i].hostname : '?',
+                                                               st[i].ipaddr,
+                                                               st[i].macaddr,
+                                                               timestr
+                                               );
+
+                                               tb.rows[0].parentNode.appendChild(tr);
+                                       }
+
+                                       if( tb.rows.length == 1 )
+                                       {
+                                               var tr = document.createElement('tr');
+                                                       tr.className = 'cbi-section-table-row';
+                                                       tr.innerHTML = '<td colspan="5"><em><br /><%:There are no active leases.%></em></td>';
+
+                                               tb.rows[0].parentNode.appendChild(tr);
+                                       }
+                               }
+                       }
+               )
+
+               window.setTimeout(arguments.callee, 5000);
+       })();
+]]></script>
+
+<fieldset class="cbi-section">
+       <legend><%:Active Leases%></legend>
+       <table class="cbi-section-table" id="lease_status_table">
+               <tr class="cbi-section-table-titles">
+                       <th class="cbi-section-table-cell"><%:Hostname%></th>
+                       <th class="cbi-section-table-cell"><%:IPv4-Address%></th>
+                       <th class="cbi-section-table-cell"><%:MAC-Address%></th>
+                       <th class="cbi-section-table-cell"><%:Leasetime remaining%></th>
+               </tr>
+               <tr class="cbi-section-table-row">
+                       <td colspan="5"><em><br /><%:Collecting data...%></em></td>
+               </tr>
+       </table>
+</fieldset>