luci-app-wireguard: add LuCI Wireguard status to 17.01 as well
authorStijn Segers <foss@volatilesystems.org>
Sat, 6 Jan 2018 20:02:40 +0000 (21:02 +0100)
committerStijn Segers <foss@volatilesystems.org>
Sat, 6 Jan 2018 20:02:40 +0000 (21:02 +0100)
Signed-off-by: Stijn Segers <foss@volatilesystems.org>
luci-app-wireguard/Makefile [new file with mode: 0644]
luci-app-wireguard/luasrc/controller/wireguard.lua [new file with mode: 0644]
luci-app-wireguard/luasrc/view/wireguard.htm [new file with mode: 0644]
luci-app-wireguard/po/ja/wireguard.po [new file with mode: 0644]
luci-app-wireguard/po/pt-br/wireguard.po [new file with mode: 0644]
luci-app-wireguard/po/sv/wireguard.po [new file with mode: 0644]
luci-app-wireguard/po/templates/wireguard.pot [new file with mode: 0644]
luci-app-wireguard/po/zh-cn/wireguard.po [new file with mode: 0644]

diff --git a/luci-app-wireguard/Makefile b/luci-app-wireguard/Makefile
new file mode 100644 (file)
index 0000000..92cdcf2
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2016-2017 Dan Luedtke <mail@danrl.com>
+#
+# This is free software, licensed under the Apache License, Version 2.0 .
+#
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:=WireGuard Status
+LUCI_DEPENDS:=+wireguard-tools +kmod-wireguard
+LUCI_PKGARCH:=all
+
+PKG_MAINTAINER:=Dan Luedtke <mail@danrl.com>
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/luci-app-wireguard/luasrc/controller/wireguard.lua b/luci-app-wireguard/luasrc/controller/wireguard.lua
new file mode 100644 (file)
index 0000000..68a82fe
--- /dev/null
@@ -0,0 +1,8 @@
+-- Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
+-- Licensed to the public under the Apache License 2.0.
+
+module("luci.controller.wireguard", package.seeall)
+
+function index()
+  entry({"admin", "status", "wireguard"}, template("wireguard"), _("WireGuard Status"), 92)
+end
diff --git a/luci-app-wireguard/luasrc/view/wireguard.htm b/luci-app-wireguard/luasrc/view/wireguard.htm
new file mode 100644 (file)
index 0000000..5af6232
--- /dev/null
@@ -0,0 +1,209 @@
+<%#
+ Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<%
+  local data = { }
+  local last_device = ""
+
+  local wg_dump = io.popen("wg show all dump")
+  if wg_dump then
+    local line
+    for line in wg_dump:lines() do
+      local line = string.split(line, "\t")
+      if not (last_device == line[1]) then
+        last_device = line[1]
+        data[line[1]] = {
+          name                 = line[1],
+          public_key           = line[3],
+          listen_port          = line[4],
+          fwmark               = line[5],
+          peers                = { }
+        }
+      else
+        local peer = {
+          public_key           = line[2],
+          endpoint             = line[4],
+          allowed_ips          = { },
+          latest_handshake     = line[6],
+          transfer_rx          = line[7],
+          transfer_tx          = line[8],
+          persistent_keepalive = line[9]
+        }
+        if not (line[4] == '(none)') then
+          for ipkey, ipvalue in pairs(string.split(line[5], ",")) do
+            if #ipvalue > 0 then
+              table.insert(peer['allowed_ips'], ipvalue)
+            end
+          end
+        end
+        table.insert(data[line[1]].peers, peer)
+      end
+    end
+  end
+
+  if luci.http.formvalue("status") == "1" then
+    luci.http.prepare_content("application/json")
+    luci.http.write_json(data)
+    return
+  end
+-%>
+
+<%+header%>
+
+<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
+<script type="text/javascript">//<![CDATA[
+
+  function bytes_to_str(bytes) {
+    bytes = parseFloat(bytes);
+    if (bytes < 1) { return "0 B"; }
+    var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'];
+    var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
+    return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
+  };
+
+  function timestamp_to_str(timestamp) {
+    if (timestamp < 1) {
+      return '<%:Never%>';
+    }
+    var now = new Date();
+    var seconds = (now.getTime() / 1000) - timestamp;
+    var ago = "";
+    if (seconds < 60) {
+      ago = parseInt(seconds) + '<%:s ago%>';
+    } else if (seconds < 3600) {
+      ago = parseInt(seconds / 60) + '<%:m ago%>';
+    } else if (seconds < 86401) {
+      ago = parseInt(seconds / 3600) + '<%:h ago%>';
+    } else {
+      ago = '<%:over a day ago%>';
+    }
+    var t = new Date(timestamp * 1000);
+    return t.toUTCString() + ' (' + ago + ')';
+  }
+
+  XHR.poll(5, '<%=REQUEST_URI%>', { status: 1 },
+   function(x, data) {
+    for (var key in data) {
+      if (!data.hasOwnProperty(key)) { continue; }
+      var ifname = key;
+      var iface = data[key];
+      var s = "";
+      if (iface.public_key == '(none)') {
+        s += '<em><%:Interface does not have a public key!%></em>';
+      } else {
+        s += String.format(
+          '<strong><%:Public Key%>: </strong>%s',
+          iface.public_key
+        );
+      }
+      if (iface.listen_port > 0) {
+        s += String.format(
+          '<br /><strong><%:Listen Port%>: </strong>%s',
+          iface.listen_port
+        );
+      }
+      if (iface.fwmark != 'off') {
+        s += String.format(
+          '<br /><strong><%:Firewall Mark%>: </strong>%s',
+          iface.fwmark
+        );
+      }
+      document.getElementById(ifname + "_info").innerHTML = s;
+      for (var i = 0, ilen = iface.peers.length; i < ilen; i++) {
+        var peer = iface.peers[i];
+        var s = String.format(
+          '<strong><%:Public Key%>: </strong>%s',
+          peer.public_key
+        );
+        if (peer.endpoint != '(none)') {
+          s += String.format(
+            '<br /><strong><%:Endpoint%>: </strong>%s',
+            peer.endpoint
+          );
+        }
+        if (peer.allowed_ips.length > 0) {
+          s += '<br /><strong><%:Allowed IPs%>:</strong>';
+          for (var k = 0, klen = peer.allowed_ips.length; k < klen; k++) {
+            s += '<br />&nbsp;&nbsp;&bull;&nbsp;' + peer.allowed_ips[k];
+          }
+        }
+        if (peer.persistent_keepalive != 'off') {
+          s += String.format(
+            '<br /><strong><%:Persistent Keepalive%>: </strong>%ss',
+            peer.persistent_keepalive
+          );
+        }
+        var icon = '<img src="<%=resource%>/icons/tunnel_disabled.png" />';
+        var now = new Date();
+        if (((now.getTime() / 1000) - peer.latest_handshake) < 140) {
+          icon = '<img src="<%=resource%>/icons/tunnel.png" />';
+        }
+        s += String.format(
+          '<br /><strong><%:Latest Handshake%>: </strong>%s',
+          timestamp_to_str(peer.latest_handshake)
+        );
+        s += String.format(
+          '<br /><strong><%:Data Received%>: </strong>%s' +
+          '<br /><strong><%:Data Transmitted%>: </strong>%s',
+          bytes_to_str(peer.transfer_rx),
+          bytes_to_str(peer.transfer_tx)
+        );
+        document.getElementById(ifname + "_" + peer.public_key + "_icon").innerHTML = icon;
+        document.getElementById(ifname + "_" + peer.public_key + "_info").innerHTML = s;
+      }
+    }
+  });
+//]]></script>
+
+<h2>WireGuard Status</h2>
+
+<fieldset class="cbi-section">
+<%-
+for ikey, iface in pairs(data) do
+  -%>
+  <legend><%:Interface%> <%=ikey%></legend>
+  <table width="100%" cellspacing="10">
+    <tr>
+      <td width="33%" style="vertical-align:top"><%:Configuration%></td>
+      <td>
+        <table>
+          <tr>
+            <td id="<%=ikey%>_icon" style="width:16px; text-align:center; padding:3px">
+              &nbsp;
+            </td>
+            <td id="<%=ikey%>_info" style="vertical-align:middle; padding: 3px">
+              <em><%:Collecting data...%></em>
+            </td>
+        </tr></table>
+      </td>
+    </tr>
+  <%-
+  for pkey, peer in pairs(iface.peers) do
+    -%>
+    <tr>
+      <td width="33%" style="vertical-align:top"><%:Peer%></td>
+      <td>
+        <table>
+          <tr>
+            <td id="<%=ikey%>_<%=peer.public_key%>_icon" style="width:16px; text-align:center; padding:3px">
+              <img src="<%=resource%>/icons/tunnel_disabled.png" /><br />
+              <small>?</small>
+            </td>
+            <td id="<%=ikey%>_<%=peer.public_key%>_info" style="vertical-align:middle; padding: 3px">
+              <em><%:Collecting data...%></em>
+            </td>
+        </tr></table>
+      </td>
+    </tr>
+    <%-
+  end
+  -%>
+  </table>
+  <%-
+end
+-%>
+</fieldset>
+
+<%+footer%>
diff --git a/luci-app-wireguard/po/ja/wireguard.po b/luci-app-wireguard/po/ja/wireguard.po
new file mode 100644 (file)
index 0000000..5cd7a90
--- /dev/null
@@ -0,0 +1,74 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2017-02-28 00:31+0900\n"
+"Last-Translator: INAGAKI Hiroshi <musashino.open@gmail.com>\n"
+"Language-Team: \n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.12\n"
+"X-Poedit-Basepath: .\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgid "Allowed IPs"
+msgstr "許可されたIP"
+
+msgid "Collecting data..."
+msgstr "データ収集中です..."
+
+msgid "Configuration"
+msgstr "設定"
+
+msgid "Data Received"
+msgstr "受信済みデータ"
+
+msgid "Data Transmitted"
+msgstr "送信済みデータ"
+
+msgid "Endpoint"
+msgstr "エンドポイント"
+
+msgid "Firewall Mark"
+msgstr "ファイアウォール マーク"
+
+msgid "Interface"
+msgstr "インターフェース"
+
+msgid "Interface does not have a public key!"
+msgstr "インターフェースに公開鍵がありません!"
+
+msgid "Latest Handshake"
+msgstr "最新のハンドシェイク"
+
+msgid "Listen Port"
+msgstr "待ち受けポート"
+
+msgid "Never"
+msgstr "無し"
+
+msgid "Peer"
+msgstr "ピア"
+
+msgid "Persistent Keepalive"
+msgstr "永続的なキープアライブ"
+
+msgid "Public Key"
+msgstr "公開鍵"
+
+msgid "WireGuard Status"
+msgstr "WireGuard ステータス"
+
+msgid "h ago"
+msgstr "時間前"
+
+msgid "m ago"
+msgstr "分前"
+
+msgid "over a day ago"
+msgstr "1日以上前"
+
+msgid "s ago"
+msgstr "秒前"
diff --git a/luci-app-wireguard/po/pt-br/wireguard.po b/luci-app-wireguard/po/pt-br/wireguard.po
new file mode 100644 (file)
index 0000000..d3b5059
--- /dev/null
@@ -0,0 +1,73 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.11\n"
+"Last-Translator: Luiz Angelo Daros de Luca <luizluca@gmail.com>\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"Language: pt_BR\n"
+
+msgid "Allowed IPs"
+msgstr "Endereços IP autorizados"
+
+msgid "Collecting data..."
+msgstr "Coletando dados..."
+
+msgid "Configuration"
+msgstr "Configuração"
+
+msgid "Data Received"
+msgstr "Dados Recebidos"
+
+msgid "Data Transmitted"
+msgstr "Dados Enviados"
+
+msgid "Endpoint"
+msgstr "Equipamento do ponto final"
+
+msgid "Firewall Mark"
+msgstr "Marca do Firewall"
+
+msgid "Interface"
+msgstr "Interface"
+
+msgid "Interface does not have a public key!"
+msgstr "A interface não tem uma chave pública!"
+
+msgid "Latest Handshake"
+msgstr "Última Negociação"
+
+msgid "Listen Port"
+msgstr "Porta de Escuta"
+
+msgid "Never"
+msgstr "Nunca"
+
+msgid "Peer"
+msgstr "Parceiro"
+
+msgid "Persistent Keepalive"
+msgstr "Manter Conexões Abertas (Keepalive)"
+
+msgid "Public Key"
+msgstr "Chave Pública"
+
+msgid "WireGuard Status"
+msgstr "Estado do WireGuard"
+
+msgid "h ago"
+msgstr "horas atrás"
+
+msgid "m ago"
+msgstr "meses atrás"
+
+msgid "over a day ago"
+msgstr "mais de um dia atrás"
+
+msgid "s ago"
+msgstr "segundos atrás"
diff --git a/luci-app-wireguard/po/sv/wireguard.po b/luci-app-wireguard/po/sv/wireguard.po
new file mode 100644 (file)
index 0000000..3422ae9
--- /dev/null
@@ -0,0 +1,62 @@
+msgid ""
+msgstr "Content-Type: text/plain; charset=UTF-8\n"
+
+msgid "Allowed IPs"
+msgstr "Tillåtna IP-adresser"
+
+msgid "Collecting data..."
+msgstr "Samlar in data..."
+
+msgid "Configuration"
+msgstr "Konfiguration"
+
+msgid "Data Received"
+msgstr "Mottagen data"
+
+msgid "Data Transmitted"
+msgstr "Överförd data"
+
+msgid "Endpoint"
+msgstr "Slutpunkt"
+
+msgid "Firewall Mark"
+msgstr "Brandväggsmarkering"
+
+msgid "Interface"
+msgstr "Gränssnitt"
+
+msgid "Interface does not have a public key!"
+msgstr "Gränssnittet har inte en publik nyckel!"
+
+msgid "Latest Handshake"
+msgstr "Senaste handskakning"
+
+msgid "Listen Port"
+msgstr "Lyssningsport"
+
+msgid "Never"
+msgstr "Aldrig"
+
+msgid "Peer"
+msgstr "Jämlike"
+
+msgid "Persistent Keepalive"
+msgstr "Hålla vid liv ständigt"
+
+msgid "Public Key"
+msgstr "Publik nyckel"
+
+msgid "WireGuard Status"
+msgstr "Status för WireGuard"
+
+msgid "h ago"
+msgstr "t sedan"
+
+msgid "m ago"
+msgstr "m sedan"
+
+msgid "over a day ago"
+msgstr "över en dag sedan"
+
+msgid "s ago"
+msgstr "s sedan"
diff --git a/luci-app-wireguard/po/templates/wireguard.pot b/luci-app-wireguard/po/templates/wireguard.pot
new file mode 100644 (file)
index 0000000..9ec5c60
--- /dev/null
@@ -0,0 +1,62 @@
+msgid ""
+msgstr "Content-Type: text/plain; charset=UTF-8"
+
+msgid "Allowed IPs"
+msgstr ""
+
+msgid "Collecting data..."
+msgstr ""
+
+msgid "Configuration"
+msgstr ""
+
+msgid "Data Received"
+msgstr ""
+
+msgid "Data Transmitted"
+msgstr ""
+
+msgid "Endpoint"
+msgstr ""
+
+msgid "Firewall Mark"
+msgstr ""
+
+msgid "Interface"
+msgstr ""
+
+msgid "Interface does not have a public key!"
+msgstr ""
+
+msgid "Latest Handshake"
+msgstr ""
+
+msgid "Listen Port"
+msgstr ""
+
+msgid "Never"
+msgstr ""
+
+msgid "Peer"
+msgstr ""
+
+msgid "Persistent Keepalive"
+msgstr ""
+
+msgid "Public Key"
+msgstr ""
+
+msgid "WireGuard Status"
+msgstr ""
+
+msgid "h ago"
+msgstr ""
+
+msgid "m ago"
+msgstr ""
+
+msgid "over a day ago"
+msgstr ""
+
+msgid "s ago"
+msgstr ""
diff --git a/luci-app-wireguard/po/zh-cn/wireguard.po b/luci-app-wireguard/po/zh-cn/wireguard.po
new file mode 100644 (file)
index 0000000..e873a83
--- /dev/null
@@ -0,0 +1,73 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.0.1\n"
+"Last-Translator: liushuyu <liushuyu011@gmail.com>\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"Language: zh_CN\n"
+
+msgid "Allowed IPs"
+msgstr "允许的 IP"
+
+msgid "Collecting data..."
+msgstr "正在收集数据..."
+
+msgid "Configuration"
+msgstr "配置"
+
+msgid "Data Received"
+msgstr "已接收"
+
+msgid "Data Transmitted"
+msgstr "已发送"
+
+msgid "Endpoint"
+msgstr "传输端点"
+
+msgid "Firewall Mark"
+msgstr "防火墙标识"
+
+msgid "Interface"
+msgstr "接口"
+
+msgid "Interface does not have a public key!"
+msgstr "接口没有配置公钥!"
+
+msgid "Latest Handshake"
+msgstr "上次握手"
+
+msgid "Listen Port"
+msgstr "监听端口"
+
+msgid "Never"
+msgstr "从不"
+
+msgid "Peer"
+msgstr "对端"
+
+msgid "Persistent Keepalive"
+msgstr "Keepalive 间隔(秒)"
+
+msgid "Public Key"
+msgstr "公钥"
+
+msgid "WireGuard Status"
+msgstr "WireGuard 状态"
+
+msgid "h ago"
+msgstr "小时前"
+
+msgid "m ago"
+msgstr "分钟前"
+
+msgid "over a day ago"
+msgstr "超过一天前"
+
+msgid "s ago"
+msgstr "秒前"