Added health endpoint
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
package com.litoralregas.openvpn.health;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/health")
|
||||||
|
public class HealthController {
|
||||||
|
|
||||||
|
private final OpenVpnHealthService openVpnHealthService;
|
||||||
|
|
||||||
|
public HealthController(OpenVpnHealthService openVpnHealthService) {
|
||||||
|
this.openVpnHealthService = openVpnHealthService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/openvpn")
|
||||||
|
public OpenVpnHealthResponse getOpenVpnHealth() {
|
||||||
|
return openVpnHealthService.checkHealth();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.litoralregas.openvpn.health;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public record OpenVpnHealthResponse(
|
||||||
|
String status,
|
||||||
|
List<OpenVpnServerHealth> servers
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package com.litoralregas.openvpn.health;
|
||||||
|
|
||||||
|
import com.litoralregas.openvpn.ssh.SshCommandResult;
|
||||||
|
import com.litoralregas.openvpn.ssh.SshService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class OpenVpnHealthService {
|
||||||
|
|
||||||
|
private final SshService sshService;
|
||||||
|
|
||||||
|
public OpenVpnHealthService(SshService sshService) {
|
||||||
|
this.sshService = sshService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenVpnHealthResponse checkHealth() {
|
||||||
|
OpenVpnServerHealth serverHealth = checkConfiguredVps();
|
||||||
|
|
||||||
|
String overallStatus;
|
||||||
|
|
||||||
|
if (!serverHealth.reachable()) {
|
||||||
|
overallStatus = "OFFLINE";
|
||||||
|
} else if (!serverHealth.openvpnServiceActive()) {
|
||||||
|
overallStatus = "DEGRADED";
|
||||||
|
} else {
|
||||||
|
overallStatus = "ONLINE";
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OpenVpnHealthResponse(
|
||||||
|
overallStatus,
|
||||||
|
List.of(serverHealth)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OpenVpnServerHealth checkConfiguredVps() {
|
||||||
|
String checkedAt = Instant.now().toString();
|
||||||
|
|
||||||
|
SshCommandResult serviceResult = sshService.executeOnConfiguredVps(
|
||||||
|
"""
|
||||||
|
if systemctl is-active --quiet openvpn-server@server; then
|
||||||
|
echo ACTIVE
|
||||||
|
elif systemctl is-active --quiet openvpn@server; then
|
||||||
|
echo ACTIVE
|
||||||
|
elif systemctl is-active --quiet openvpn; then
|
||||||
|
echo ACTIVE
|
||||||
|
else
|
||||||
|
echo INACTIVE
|
||||||
|
systemctl list-units --type=service --all | grep -i openvpn || true
|
||||||
|
fi
|
||||||
|
"""
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean reachable = serviceResult.exitCode() != -1;
|
||||||
|
boolean active = serviceResult.stdout().contains("ACTIVE");
|
||||||
|
|
||||||
|
Integer activeClients = null;
|
||||||
|
|
||||||
|
if (reachable && active) {
|
||||||
|
activeClients = getActiveClientCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
String error = null;
|
||||||
|
|
||||||
|
if (!reachable) {
|
||||||
|
error = serviceResult.stderr();
|
||||||
|
} else if (!active) {
|
||||||
|
error = cleanOutput(serviceResult.stdout() + "\n" + serviceResult.stderr());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OpenVpnServerHealth(
|
||||||
|
"Configured VPS",
|
||||||
|
reachable,
|
||||||
|
active,
|
||||||
|
activeClients,
|
||||||
|
checkedAt,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer getActiveClientCount() {
|
||||||
|
SshCommandResult result = sshService.executeOnConfiguredVps(
|
||||||
|
"""
|
||||||
|
if [ -f /var/log/openvpn/status.log ]; then
|
||||||
|
grep -A 100 "Common Name" /var/log/openvpn/status.log | grep -v "Common Name" | grep -v "ROUTING TABLE" | grep -v "GLOBAL STATS" | grep -v "^$" | wc -l
|
||||||
|
elif [ -f /run/openvpn-server/status-server.log ]; then
|
||||||
|
grep -A 100 "Common Name" /run/openvpn-server/status-server.log | grep -v "Common Name" | grep -v "ROUTING TABLE" | grep -v "GLOBAL STATS" | grep -v "^$" | wc -l
|
||||||
|
else
|
||||||
|
echo 0
|
||||||
|
fi
|
||||||
|
"""
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.exitCode() != 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(result.stdout().trim());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cleanOutput(String value) {
|
||||||
|
if (value == null || value.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.litoralregas.openvpn.health;
|
||||||
|
|
||||||
|
public record OpenVpnServerHealth(
|
||||||
|
String name,
|
||||||
|
boolean reachable,
|
||||||
|
boolean openvpnServiceActive,
|
||||||
|
Integer activeClients,
|
||||||
|
String checkedAt,
|
||||||
|
String error
|
||||||
|
) {
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user