Add VPS-aware VPN IP allocation

This commit is contained in:
litoral05
2026-05-07 14:17:40 +01:00
parent a09587950e
commit c88ef29449
16 changed files with 592 additions and 1 deletions
@@ -0,0 +1,126 @@
package com.litoralregas.vpnprovisioner.vps;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.litoralregas.vpnprovisioner.config.VpsSshProperties;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
@Service
public class SshService {
private final VpsSshProperties properties;
public SshService(VpsSshProperties properties) {
this.properties = properties;
}
public SshCommandResult executeOnConfiguredVps(String command) {
validateConfiguredVps();
return execute(
properties.getHost(),
properties.getPort(),
properties.getUsername(),
properties.getPassword(),
properties.getPrivateKeyPath(),
command,
properties.getConnectTimeoutMs(),
properties.getCommandTimeoutMs()
);
}
public SshCommandResult execute(
String host,
int port,
String username,
String password,
String privateKeyPath,
String command,
int connectTimeoutMs,
int commandTimeoutMs
) {
Session session = null;
ChannelExec channel = null;
try {
JSch jsch = new JSch();
if (StringUtils.hasText(privateKeyPath)) {
jsch.addIdentity(privateKeyPath);
}
session = jsch.getSession(username, host, port);
if (StringUtils.hasText(password)) {
session.setPassword(password);
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(connectTimeoutMs);
channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(command);
channel.setInputStream(null);
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
channel.setOutputStream(stdout);
channel.setErrStream(stderr);
channel.connect(connectTimeoutMs);
long deadline = System.currentTimeMillis() + commandTimeoutMs;
while (!channel.isClosed()) {
if (System.currentTimeMillis() > deadline) {
throw new SshCommandException("SSH command timed out: " + command);
}
Thread.sleep(100);
}
return new SshCommandResult(
channel.getExitStatus(),
stdout.toString(StandardCharsets.UTF_8),
stderr.toString(StandardCharsets.UTF_8)
);
} catch (SshCommandException exception) {
throw exception;
} catch (Exception exception) {
throw new SshCommandException("SSH command failed: " + command, exception);
} finally {
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
private void validateConfiguredVps() {
if (!StringUtils.hasText(properties.getHost())) {
throw new SshCommandException("VPS SSH host is not configured");
}
if (!StringUtils.hasText(properties.getUsername())) {
throw new SshCommandException("VPS SSH username is not configured");
}
if (!StringUtils.hasText(properties.getPassword())
&& !StringUtils.hasText(properties.getPrivateKeyPath())) {
throw new SshCommandException("Either VPS SSH password or private key path must be configured");
}
}
}