feature: the status page shows the Router Manager's version.
Release / release (push) Successful in 12s
Release / release (push) Successful in 12s
This commit is contained in:
1 parent
af3127d1e8
commit
17331eea37
3 files changed
+35
-7
No files matched your search
@@ -526,10 +526,12 @@ curl http://10.0.0.4:17081/
|
|||||||
| `/users` | The users of OpenVPN and road-warrior access; needs a token |
|
| `/users` | The users of OpenVPN and road-warrior access; needs a token |
|
||||||
| `/groups` | The groups of users; needs a token |
|
| `/groups` | The groups of users; needs a token |
|
||||||
|
|
||||||
The status holds the state of `vpn-router-setup` and `slapd`, of `strongswan` when site-to-site or
|
The status holds the state of `vpn-router-setup`, `slapd` and each PostgreSQL cluster unit
|
||||||
|
(`postgresql@<version>-<cluster>`, or `postgresql` as `no cluster` without one), of `strongswan` when site-to-site or
|
||||||
road-warrior access is configured, of `wg-quick@wg0` when WireGuard is, and of
|
road-warrior access is configured, of `wg-quick@wg0` when WireGuard is, and of
|
||||||
`openvpn-server@vpn-router` when OpenVPN is; the number of connected
|
`openvpn-server@vpn-router` when OpenVPN is; the number of connected
|
||||||
OpenVPN clients, from the server's status file, which OpenVPN rewrites every minute; the package version; whether
|
OpenVPN clients, from the server's status file, which OpenVPN rewrites every minute; the package version and,
|
||||||
|
as `manager_version`, the installed version of `vpn-router-manager` (`null`, shown as not installed, without it); whether
|
||||||
Docker is installed, and when it is, the state of `docker.service` and of `vpn-router-docker`
|
Docker is installed, and when it is, the state of `docker.service` and of `vpn-router-docker`
|
||||||
(the Docker rules), which do not change `status`; whether the
|
(the Docker rules), which do not change `status`; whether the
|
||||||
site-to-site tunnel is established; the number of connected road-warrior (IPsec P2S) clients; and
|
site-to-site tunnel is established; the number of connected road-warrior (IPsec P2S) clients; and
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
|
vpn-router (0.11.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
feature: the status page shows the Router Manager's version.
|
||||||
|
|
||||||
|
* / and /status show the installed version of vpn-router-manager, as
|
||||||
|
manager_version in JSON, or that it is not installed.
|
||||||
|
* The services show the state of each PostgreSQL cluster, as
|
||||||
|
postgresql@<version>-<cluster>, or postgresql: no cluster without one.
|
||||||
|
|
||||||
|
-- Slawomir Koszewski <slawek@koszewscy.waw.pl> Sun, 25 Oct 2026 09:00:00 +0200
|
||||||
|
|
||||||
vpn-router (0.10.0-1) unstable; urgency=medium
|
vpn-router (0.10.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
feature: Manager-only accounts, and the Router Manager's first administrator.
|
feature: Manager-only accounts, and the Router Manager's first administrator.
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ served (404) while the key does not exist. /auth is limited to AUTH_LIMIT calls
|
|||||||
address in AUTH_WINDOW seconds; the address of a call from one of web.trusted_proxies, by
|
address in AUTH_WINDOW seconds; the address of a call from one of web.trusted_proxies, by
|
||||||
default the address the service listens on, is the last entry of its X-Forwarded-For header.
|
default the address the service listens on, is the last entry of its X-Forwarded-For header.
|
||||||
|
|
||||||
/ and /status show only the status: whether the services run, the package version, whether
|
/ and /status show only the status: whether the services run, the package version and the
|
||||||
|
installed version of vpn-router-manager (manager_version, null when it is not installed), whether
|
||||||
Docker is installed, and the state of site-to-site, road-warrior (IPsec P2S), OpenVPN and
|
Docker is installed, and the state of site-to-site, road-warrior (IPsec P2S), OpenVPN and
|
||||||
WireGuard. No configuration data, key or address is shown.
|
WireGuard. No configuration data, key or address is shown.
|
||||||
|
|
||||||
@@ -143,9 +144,10 @@ def unit_state(unit):
|
|||||||
return result.stdout.strip() if result and result.stdout.strip() else 'unknown'
|
return result.stdout.strip() if result and result.stdout.strip() else 'unknown'
|
||||||
|
|
||||||
|
|
||||||
def package_version():
|
def package_version(package='vpn-router'):
|
||||||
result = run('dpkg-query', '-W', '-f=${Version}', 'vpn-router')
|
"""The installed version of the package, or None when it is not installed."""
|
||||||
return result.stdout.strip() if result and result.returncode == 0 else None
|
result = run('dpkg-query', '-W', '-f=${Version}', package)
|
||||||
|
return (result.stdout.strip() or None) if result and result.returncode == 0 else None
|
||||||
|
|
||||||
|
|
||||||
def docker_status():
|
def docker_status():
|
||||||
@@ -239,9 +241,20 @@ def openvpn_clients():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def postgresql_clusters():
|
||||||
|
"""The state of each PostgreSQL cluster unit (postgresql@<version>-<name>), or {'postgresql': 'no cluster'} without one.
|
||||||
|
|
||||||
|
postgresql.service, which only runs /bin/true, is not reported.
|
||||||
|
"""
|
||||||
|
lines = lines_of('systemctl', 'list-units', 'postgresql@*.service', '--all', '--plain', '--no-legend') or []
|
||||||
|
names = [line.split()[0].removesuffix('.service') for line in lines if line.strip()]
|
||||||
|
return {name: unit_state(f'{name}.service') for name in names} or {'postgresql': 'no cluster'}
|
||||||
|
|
||||||
|
|
||||||
def collect(state):
|
def collect(state):
|
||||||
"""The status document. state says which features the router has."""
|
"""The status document. state says which features the router has."""
|
||||||
units = {'vpn-router-setup': unit_state('vpn-router-setup.service'), 'slapd': unit_state('slapd.service')}
|
units = {'vpn-router-setup': unit_state('vpn-router-setup.service'), 'slapd': unit_state('slapd.service'),
|
||||||
|
**postgresql_clusters()}
|
||||||
if state.get('site_to_site') or state.get('p2s'):
|
if state.get('site_to_site') or state.get('p2s'):
|
||||||
units['strongswan'] = unit_state('strongswan.service')
|
units['strongswan'] = unit_state('strongswan.service')
|
||||||
if state.get('wireguard'):
|
if state.get('wireguard'):
|
||||||
@@ -252,6 +265,7 @@ def collect(state):
|
|||||||
status = {
|
status = {
|
||||||
'status': 'ok' if all(value == 'active' for value in units.values()) else 'degraded',
|
'status': 'ok' if all(value == 'active' for value in units.values()) else 'degraded',
|
||||||
'version': package_version(),
|
'version': package_version(),
|
||||||
|
'manager_version': package_version('vpn-router-manager'),
|
||||||
'time': time.strftime('%Y-%m-%dT%H:%M:%S%z'),
|
'time': time.strftime('%Y-%m-%dT%H:%M:%S%z'),
|
||||||
'units': units,
|
'units': units,
|
||||||
'docker': docker_status(),
|
'docker': docker_status(),
|
||||||
@@ -327,6 +341,7 @@ def details(state):
|
|||||||
def text_of(status):
|
def text_of(status):
|
||||||
"""The status for people, as plain text."""
|
"""The status for people, as plain text."""
|
||||||
lines = ['VPN Router', f'Status: {status["status"]}', f'Version: {status["version"] or "unknown"}', '']
|
lines = ['VPN Router', f'Status: {status["status"]}', f'Version: {status["version"] or "unknown"}', '']
|
||||||
|
lines.append(f'Router Manager: {status["manager_version"] or "not installed"}')
|
||||||
lines += [f'{name}: {value}' for name, value in status['units'].items()]
|
lines += [f'{name}: {value}' for name, value in status['units'].items()]
|
||||||
docker = status['docker']
|
docker = status['docker']
|
||||||
lines.append('Docker: not installed' if not docker['installed']
|
lines.append('Docker: not installed' if not docker['installed']
|
||||||
|
|||||||
Reference in new issue
Block a user