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:
Sergey Ponomarev 2024-02-03 22:06:36 +02:00 committed by Paul Donald
parent 4bbdf8d31e
commit b8a4328fcf
4 changed files with 125 additions and 3 deletions

View file

@ -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),
]);
}
});

View file

@ -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 ""

View file

@ -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"

View file

@ -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" ],