Add VPS-aware VPN IP allocation
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user