luci-app-cloudflared: add Tunnels status page
The page allows to see if the tunnel has connections. This can be used for a basic troubleshooting without opening the Cloudflare dashboard. Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
This commit is contained in:
parent
4bbdf8d31e
commit
b8a4328fcf
4 changed files with 125 additions and 3 deletions
|
@ -0,0 +1,86 @@
|
|||
/* This is free software, licensed under the Apache License, Version 2.0
|
||||
*
|
||||
* Copyright (C) 2024 Sergey Ponomarev <stokito@gmail.com>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
'require view';
|
||||
'require fs';
|
||||
|
||||
function listTunnels() {
|
||||
let command = '/usr/bin/cloudflared';
|
||||
let commandArgs = ['tunnel', 'list', '-o', 'json'];
|
||||
return fs.exec(command, commandArgs).then(function (res) {
|
||||
if (res.code === 0) {
|
||||
return JSON.parse(res.stdout);
|
||||
} else {
|
||||
throw new Error(res.stdout + ' ' + res.stderr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return view.extend({
|
||||
handleSaveApply: null,
|
||||
handleSave: null,
|
||||
handleReset: null,
|
||||
|
||||
load: function () {
|
||||
return Promise.all([
|
||||
listTunnels()
|
||||
]);
|
||||
},
|
||||
|
||||
render: function (data) {
|
||||
var tunnels = data[0];
|
||||
|
||||
var tunnelsElList = [];
|
||||
for (var tunnel of tunnels) {
|
||||
var connectionsSection = [];
|
||||
if (tunnel.connections.length > 0) {
|
||||
var connectionsElList = [];
|
||||
for (let connection of tunnel.connections) {
|
||||
var dateOpenedAt = new Date(connection.opened_at).toLocaleString();
|
||||
connectionsElList.push(
|
||||
E('tr', [
|
||||
E('td', connection.id),
|
||||
E('td', connection.origin_ip),
|
||||
E('td', dateOpenedAt),
|
||||
E('td', connection.colo_name)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
connectionsSection = [
|
||||
E('h5', _('Connections')),
|
||||
E('table', {'class': 'table cbi-section-table'}, [
|
||||
E('thead', [
|
||||
E('tr', {'class': 'tr table-titles'}, [
|
||||
E('th', {'class': 'th'}, 'ID'),
|
||||
E('th', {'class': 'th'}, _('Origin IP')),
|
||||
E('th', {'class': 'th'}, _('Opened At')),
|
||||
E('th', {'class': 'th'}, _('Data center')),
|
||||
]),
|
||||
]),
|
||||
E('tbody', connectionsElList)
|
||||
])
|
||||
];
|
||||
} else {
|
||||
connectionsSection = [E('em', _('No connections'))];
|
||||
}
|
||||
|
||||
var tunnelEl = E('div', [
|
||||
E('h4', tunnel.name),
|
||||
E('span', 'ID '),
|
||||
E('span', tunnel.id),
|
||||
E('div', connectionsSection)
|
||||
]
|
||||
);
|
||||
tunnelsElList.push(tunnelEl);
|
||||
}
|
||||
return E([], [
|
||||
E('h2', {'class': 'section-title'}, _('Tunnels')),
|
||||
E('div', {'id': 'tunnels'}, tunnelsElList),
|
||||
]);
|
||||
}
|
||||
});
|
|
@ -35,12 +35,20 @@ msgstr ""
|
|||
msgid "Configuration"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/tunnels.js:55
|
||||
msgid "Connections"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/config.js:54
|
||||
msgid ""
|
||||
"Create and manage your network on the <a %s>Cloudflare Zero Trust</a> "
|
||||
"dashboard."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/tunnels.js:62
|
||||
msgid "Data center"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/config.js:113
|
||||
msgid "Debug"
|
||||
msgstr ""
|
||||
|
@ -91,10 +99,14 @@ msgstr ""
|
|||
msgid "Log Direction:"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/root/usr/share/luci/menu.d/luci-app-cloudflared.json:22
|
||||
#: applications/luci-app-cloudflared/root/usr/share/luci/menu.d/luci-app-cloudflared.json:30
|
||||
msgid "Logs"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/tunnels.js:69
|
||||
msgid "No connections"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/config.js:36
|
||||
msgid "Not Running"
|
||||
msgstr ""
|
||||
|
@ -103,6 +115,14 @@ msgstr ""
|
|||
msgid "Obtain a certificate <a %s>here</a>."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/tunnels.js:61
|
||||
msgid "Opened At"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/tunnels.js:60
|
||||
msgid "Origin IP"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/config.js:102
|
||||
msgid "Region"
|
||||
msgstr ""
|
||||
|
@ -138,6 +158,11 @@ msgstr ""
|
|||
msgid "Token"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/tunnels.js:82
|
||||
#: applications/luci-app-cloudflared/root/usr/share/luci/menu.d/luci-app-cloudflared.json:22
|
||||
msgid "Tunnels"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-cloudflared/htdocs/luci-static/resources/view/cloudflared/log.js:33
|
||||
msgid "Unable to read the interface info from /var/log/cloudflared.log."
|
||||
msgstr ""
|
||||
|
|
|
@ -18,9 +18,17 @@
|
|||
"path": "cloudflared/config"
|
||||
}
|
||||
},
|
||||
"admin/vpn/cloudflared/tunnels": {
|
||||
"title": "Tunnels",
|
||||
"order": 20,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "cloudflared/tunnels"
|
||||
}
|
||||
},
|
||||
"admin/vpn/cloudflared/log": {
|
||||
"title": "Logs",
|
||||
"order": 20,
|
||||
"order": 30,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "cloudflared/log"
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
"ubus": {
|
||||
"service": [ "list" ]
|
||||
},
|
||||
"file": [ "/var/log/cloudflared.log" ]
|
||||
"file": {
|
||||
"/var/log/cloudflared.log": [ "read" ],
|
||||
"/usr/bin/cloudflared *": [ "exec" ]
|
||||
}
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "cloudflared" ],
|
||||
|
|
Loading…
Reference in a new issue