mirror of
https://github.com/LamGC/Oracle-Sentry.git
synced 2025-04-29 22:27:34 +00:00
docs: 补充文档.
This commit is contained in:
parent
882eabbc71
commit
c92c491bd8
@ -19,6 +19,10 @@ public class ApplicationMain {
|
||||
@SuppressWarnings("AlibabaConstantFieldShouldBeUpperCase")
|
||||
private final static Object mainThreadWaiter = new Object();
|
||||
|
||||
/**
|
||||
* 程序入口.
|
||||
* @param args 程序参数.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ApplicationMain.class, args);
|
||||
|
||||
|
@ -37,6 +37,10 @@ public class ComputeInstanceManager {
|
||||
sshIdentityProvider.loadAuthInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实例 SSH 认证配置提供器.
|
||||
* @return 返回 SSH 认证配置提供器.
|
||||
*/
|
||||
public SshAuthIdentityProvider getSshIdentityProvider() {
|
||||
return sshIdentityProvider;
|
||||
}
|
||||
|
@ -10,6 +10,9 @@ import org.springframework.stereotype.Component;
|
||||
@Component("sentry.constants")
|
||||
public final class Constants {
|
||||
|
||||
/**
|
||||
* 本类唯一实例, 请不要进行设置.
|
||||
*/
|
||||
public static Constants instance;
|
||||
|
||||
private Constants() {
|
||||
@ -21,6 +24,10 @@ public final class Constants {
|
||||
private String firstConnectionPolicy;
|
||||
|
||||
|
||||
/**
|
||||
* 获取 SSH 首次连接策略.
|
||||
* @return 返回策略值.
|
||||
*/
|
||||
@NonNull
|
||||
public String getFirstConnectionPolicy() {
|
||||
return firstConnectionPolicy;
|
||||
|
@ -87,7 +87,9 @@ public final class OracleIdentityManager {
|
||||
|
||||
/**
|
||||
* 通过配置文件加载身份信息.
|
||||
* <p> 加载成功后, 将会注册到身份管理器中.
|
||||
* @param identityConfig 身份信息文件.
|
||||
* @return 返回已成功加载后, 配置文件对应的身份配置提供器.
|
||||
* @throws IOException 如果读取文件发生问题时将抛出该异常.
|
||||
*/
|
||||
public AuthenticationDetailsProvider loadFromConfigFile(File identityConfig) throws IOException {
|
||||
|
@ -4,10 +4,20 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* 输入流包装器.
|
||||
* <p> 准确来说只是屏蔽了 {@link InputStream#close()} 而已,
|
||||
* 尝试修复 SSH 命令执行会话可能会关闭设置的输入流的问题.
|
||||
* @author LamGC
|
||||
*/
|
||||
public class InputStreamWrapper extends InputStream {
|
||||
|
||||
private final InputStream source;
|
||||
|
||||
/**
|
||||
* 包装一个输入流.
|
||||
* @param source 输入源.
|
||||
*/
|
||||
public InputStreamWrapper(InputStream source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
@ -3,10 +3,20 @@ package net.lamgc.oracle.sentry.common;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* 输出流包装器.
|
||||
* <p> 准确来说只是屏蔽了 {@link OutputStream#close()} 而已,
|
||||
* 尝试修复 SSH 命令执行会话可能会关闭设置的输出流的问题.
|
||||
* @author LamGC
|
||||
*/
|
||||
public class OutputStreamWrapper extends OutputStream {
|
||||
|
||||
private final OutputStream target;
|
||||
|
||||
/**
|
||||
* 包装一个输出流.
|
||||
* @param target 目标输出流.
|
||||
*/
|
||||
public OutputStreamWrapper(OutputStream target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
package net.lamgc.oracle.sentry.oci.compute;
|
||||
|
||||
/**
|
||||
* 实例动作.
|
||||
* <p> 可对实例执行的操作.
|
||||
* @author LamGC
|
||||
*/
|
||||
public enum InstanceAction {
|
||||
/**
|
||||
* 启动实例.
|
||||
@ -30,6 +35,10 @@ public enum InstanceAction {
|
||||
this.actionValue = actionValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取动作的 API 调用值.
|
||||
* @return 返回 API 所规定的对应值.
|
||||
*/
|
||||
public String getActionValue() {
|
||||
return actionValue;
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ public final class CommandExecSession implements Closeable {
|
||||
/**
|
||||
* 设置输入流.
|
||||
* <p> 设置待执行命令的输入流.
|
||||
* @param in 待设置的输入流。
|
||||
*/
|
||||
public void setIn(InputStream in) {
|
||||
channelExec.setIn(new InputStreamWrapper(in));
|
||||
@ -79,6 +80,7 @@ public final class CommandExecSession implements Closeable {
|
||||
/**
|
||||
* 设置标准输出流.
|
||||
* <p> 对应待执行命令的 Stdout.
|
||||
* @param out 设置标准输出的输出流.
|
||||
*/
|
||||
public void setOut(OutputStream out) {
|
||||
channelExec.setOut(new OutputStreamWrapper(out));
|
||||
@ -87,6 +89,7 @@ public final class CommandExecSession implements Closeable {
|
||||
/**
|
||||
* 设置错误输出流.
|
||||
* <p> 如果命令使用到, 错误信息会从该输出流输出.
|
||||
* @param err 设置错误输出的输出流.
|
||||
*/
|
||||
public void setErr(OutputStream err) {
|
||||
channelExec.setErr(new OutputStreamWrapper(err));
|
||||
|
@ -16,6 +16,12 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 实例 SSH 客户端.
|
||||
* <p> 包装并简化了 SSH 会话的创建流程.
|
||||
* @author LamGC
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class InstanceSsh implements AutoCloseable {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(InstanceSsh.class);
|
||||
@ -24,6 +30,11 @@ public class InstanceSsh implements AutoCloseable {
|
||||
private final SshAuthInfo authInfo;
|
||||
private final SshClient sshClient;
|
||||
|
||||
/**
|
||||
* 创建连接实例用的 SSH 客户端.
|
||||
* @param instance SSH 客户端对应的计算实例.
|
||||
* @param authInfo SSH 认证配置.
|
||||
*/
|
||||
public InstanceSsh(ComputeInstance instance, SshAuthInfo authInfo) {
|
||||
this.instance = Objects.requireNonNull(instance);
|
||||
this.authInfo = Objects.requireNonNull(authInfo);
|
||||
@ -43,6 +54,12 @@ public class InstanceSsh implements AutoCloseable {
|
||||
sshClient.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 SSH 会话.
|
||||
* <p> 允许创建多个 SSH 会话.
|
||||
* @return 返回新的 SSH 会话.
|
||||
* @throws IOException 会话创建失败时将抛出异常.
|
||||
*/
|
||||
public SshSession createSession() throws IOException {
|
||||
Set<String> instancePublicIps = instance.network().getInstancePublicIp();
|
||||
if (instancePublicIps.stream().findFirst().isEmpty()) {
|
||||
@ -75,7 +92,6 @@ public class InstanceSsh implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
sshClient.stop();
|
||||
|
@ -12,10 +12,18 @@ public class PasswordAuthInfo extends SshAuthInfo {
|
||||
return AuthType.PASSWORD;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 SSH 登录密码.
|
||||
* @return 返回登录密码.
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 SSH 登录密码.
|
||||
* @param password 新的登录密码.
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
@ -5,6 +5,10 @@ import org.apache.sshd.common.config.keys.FilePasswordProvider;
|
||||
import java.io.File;
|
||||
import java.security.KeyPair;
|
||||
|
||||
/**
|
||||
* 公钥登录认证配置.
|
||||
* @author LamGC
|
||||
*/
|
||||
public class PublicKeyAuthInfo extends SshAuthInfo{
|
||||
|
||||
private File privateKeyPath;
|
||||
@ -15,18 +19,36 @@ public class PublicKeyAuthInfo extends SshAuthInfo{
|
||||
return AuthType.PUBLIC_KEY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取私钥路径.
|
||||
* <p> 注意: 该路径由 SSH 认证配置文件提供, 不保证私钥的存在.
|
||||
* @return 返回私钥所在路径.
|
||||
*/
|
||||
public File getPrivateKeyPath() {
|
||||
return privateKeyPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置私钥路径.
|
||||
* @param privateKeyPath 私钥路径.
|
||||
*/
|
||||
public void setPrivateKeyPath(File privateKeyPath) {
|
||||
this.privateKeyPath = privateKeyPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取私钥密码.
|
||||
* @return 如果有, 返回非 {@code null} 值.
|
||||
*/
|
||||
public String getKeyPassword() {
|
||||
return keyPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置私钥密码.
|
||||
* <p> 如果私钥存在密码但未提供密码, 将无法使用私钥验证会话.
|
||||
* @param keyPassword 私钥密码.
|
||||
*/
|
||||
public void setKeyPassword(String keyPassword) {
|
||||
this.keyPassword = keyPassword;
|
||||
}
|
||||
|
@ -51,7 +51,11 @@ public final class SshAuthIdentityProvider {
|
||||
.build());
|
||||
private final AtomicBoolean needSave = new AtomicBoolean(false);
|
||||
|
||||
|
||||
/**
|
||||
* 创建 SSH 认证配置提供器.
|
||||
* @param instanceManager 所属实例管理器.
|
||||
* @param identityJson 认证配置文件对象.
|
||||
*/
|
||||
public SshAuthIdentityProvider(ComputeInstanceManager instanceManager, File identityJson) {
|
||||
this.instanceManager = instanceManager;
|
||||
this.identityJsonFile = identityJson;
|
||||
@ -69,6 +73,11 @@ public final class SshAuthIdentityProvider {
|
||||
}, 60, 10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 SSH 认证配置.
|
||||
* @param instanceId 配置对应的实例 Id.
|
||||
* @param authInfo SSH 认证配置对象.
|
||||
*/
|
||||
public void addSshAuthIdentity(String instanceId, SshAuthInfo authInfo) {
|
||||
authInfoMap.put(instanceId, authInfo);
|
||||
}
|
||||
@ -157,6 +166,7 @@ public final class SshAuthIdentityProvider {
|
||||
|
||||
/**
|
||||
* 获取所有不存在 SSH 配置的实例 Id.
|
||||
* @return 返回所有不存在对应 SSH 认证配置的实例 Id.
|
||||
*/
|
||||
private Set<String> checkForMissingInstances() {
|
||||
Set<String> instanceIdSet = instanceManager.getComputeInstances().stream()
|
||||
|
@ -29,14 +29,28 @@ public abstract class SshAuthInfo {
|
||||
*/
|
||||
public abstract AuthType getType();
|
||||
|
||||
/**
|
||||
* 获取 SSH 登录用户名.
|
||||
* @return 返回 SSH 登录用户名.
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务器公钥.
|
||||
* <p> 用于认证服务器身份, 在首次登录成功后设置.
|
||||
* @return 如果之前认证成功并保存过, 则不为 {@code null}, 否则需要进行首次连接确认.
|
||||
*/
|
||||
public PublicKey getServerKey() {
|
||||
return serverKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置服务器公钥.
|
||||
* <p> 如果本对象有关联的 {@link SshAuthIdentityProvider}, 则会通知 Provider 保存 SSH 认证配置文件.
|
||||
* @param serverKey 服务器公钥.
|
||||
*/
|
||||
public void setServerKey(PublicKey serverKey) {
|
||||
this.serverKey = serverKey;
|
||||
if (this.provider != null) {
|
||||
@ -44,14 +58,27 @@ public abstract class SshAuthInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 SSH 登录用户名.
|
||||
* @param username 登录 SSH 的用户名.
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 SSH 认证配置提供器.
|
||||
* <p> 设置后, 可在首次连接认证通过后, 保存服务器公钥到文件中.
|
||||
* @param provider 所属提供器对象.
|
||||
*/
|
||||
void setProvider(SshAuthIdentityProvider provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证类型.
|
||||
* <p> 如果没有所需认证类型, 就是没支持.
|
||||
*/
|
||||
public enum AuthType {
|
||||
/**
|
||||
* 密码认证.
|
||||
@ -68,6 +95,10 @@ public abstract class SshAuthInfo {
|
||||
this.targetClass = targetClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型所属的认证配置类.
|
||||
* @return 返回认证配置类.
|
||||
*/
|
||||
public Class<? extends SshAuthInfo> getTargetClass() {
|
||||
return targetClass;
|
||||
}
|
||||
|
@ -23,6 +23,10 @@ import java.util.Collections;
|
||||
*/
|
||||
public final class SshAuthInfoSerializer implements JsonSerializer<SshAuthInfo>, JsonDeserializer<SshAuthInfo> {
|
||||
|
||||
/**
|
||||
* 本类唯一实例.
|
||||
* <p> 序列化器支持多用.
|
||||
*/
|
||||
public final static SshAuthInfoSerializer INSTANCE = new SshAuthInfoSerializer();
|
||||
|
||||
private SshAuthInfoSerializer() {}
|
||||
|
@ -23,6 +23,11 @@ public final class ScriptManager {
|
||||
|
||||
private final Map<ScriptInfo, Script> scripts = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 创建新的脚本管理器.
|
||||
* @param scriptsLocation 脚本加载路径.
|
||||
* @param components 脚本组件.
|
||||
*/
|
||||
public ScriptManager(File scriptsLocation, ScriptComponents components) {
|
||||
this.scriptsLocation = scriptsLocation;
|
||||
this.context = components;
|
||||
|
@ -19,11 +19,21 @@ public class GroovyDslDelegate implements Script {
|
||||
private final ScriptHttpClient HTTP;
|
||||
private final ComputeInstanceManager InstanceManager;
|
||||
|
||||
/**
|
||||
* 构建一个 DSL Delegate, 并传入可操作对象.
|
||||
* @param httpClient Http 客户端.
|
||||
* @param instanceManager 实例管理器.
|
||||
*/
|
||||
public GroovyDslDelegate(ScriptHttpClient httpClient, ComputeInstanceManager instanceManager) {
|
||||
HTTP = httpClient;
|
||||
InstanceManager = instanceManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册触发器.
|
||||
* @param triggerName 触发器名称.
|
||||
* @param closure 待执行闭包.
|
||||
*/
|
||||
private void trigger(String triggerName, Closure<?> closure){
|
||||
DefaultGroovyMethods.with(GroovyTriggerProvider.INSTANCE.getTriggerByName(triggerName), closure);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Groovy 脚本加载器.
|
||||
* @author LamGC
|
||||
*/
|
||||
@SuppressWarnings("MapOrSetKeyShouldOverrideHashCodeEquals")
|
||||
@ -30,6 +31,10 @@ public class GroovyScriptLoader implements ScriptLoader {
|
||||
|
||||
private final Map<Script, ScriptInfo> scriptInfoMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 构造一个新的脚本加载器.
|
||||
* <p> 每个加载器所使用的 {@link GroovyClassLoader} 实例是不一样的.
|
||||
*/
|
||||
public GroovyScriptLoader() {
|
||||
CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
|
||||
compilerConfiguration.setScriptBaseClass(DelegatingScript.class.getName());
|
||||
|
@ -18,6 +18,9 @@ public class GroovyTriggerProvider {
|
||||
|
||||
private final Map<String, ServiceLoader.Provider<GroovyTrigger>> triggerProviderMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Trigger Provider 唯一实例.
|
||||
*/
|
||||
public final static GroovyTriggerProvider INSTANCE = new GroovyTriggerProvider();
|
||||
|
||||
private GroovyTriggerProvider() {
|
||||
@ -40,6 +43,12 @@ public class GroovyTriggerProvider {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 Trigger 名称获取新的 Trigger.
|
||||
* @param triggerName Trigger 名称.
|
||||
* @return 返回指定 Trigger 的新实例.
|
||||
* @throws NoSuchElementException 当指定的 Trigger 名称没有对应 Trigger 时抛出该异常.
|
||||
*/
|
||||
public GroovyTrigger getTriggerByName(String triggerName) {
|
||||
if (!triggerProviderMap.containsKey(triggerName.toLowerCase())) {
|
||||
throw new NoSuchElementException("The specified trigger could not be found: " + triggerName);
|
||||
|
@ -13,6 +13,11 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TriggerName {
|
||||
|
||||
/**
|
||||
* Trigger 名称.
|
||||
* <p> 需保证唯一性.
|
||||
* @return 返回 Trigger 名称.
|
||||
*/
|
||||
String value();
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,8 @@ import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
*
|
||||
* Http 访问对象.
|
||||
* <p> 该对象可以复用.
|
||||
* @author LamGC
|
||||
*/
|
||||
public class HttpAccess {
|
||||
@ -23,12 +24,23 @@ public class HttpAccess {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以 Get 方法发起 Http 请求.
|
||||
* @return 返回 Http 响应对象.
|
||||
* @throws IOException 当请求发送失败时抛出异常.
|
||||
*/
|
||||
public HttpAccessResponse get() throws IOException {
|
||||
HttpGet request = new HttpGet(url);
|
||||
HttpResponse response = client.execute(request);
|
||||
return new HttpAccessResponse(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 以 Post 方法发起 Http 请求.
|
||||
* @param body Post 请求体.
|
||||
* @return 返回 Http 响应对象.
|
||||
* @throws IOException 当请求发送失败时抛出异常.
|
||||
*/
|
||||
public HttpAccessResponse post(String body) throws IOException {
|
||||
HttpPost request = new HttpPost(url);
|
||||
request.setEntity(new StringEntity(body, StandardCharsets.UTF_8));
|
||||
|
@ -32,18 +32,35 @@ public final class HttpAccessResponse {
|
||||
this.entity = response.getEntity();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取响应状态行.
|
||||
* @return 返回响应状态行, 包括响应码和信息.
|
||||
*/
|
||||
public StatusLine getStatusLine() {
|
||||
return statusLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取语言.
|
||||
* @return 返回 Locale 对象.
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 ResponseBody 转为字符串并返回.
|
||||
* @return 返回字符串形式的响应体.
|
||||
* @throws IOException 当接收失败时抛出异常.
|
||||
*/
|
||||
public String getContentToString() throws IOException {
|
||||
return EntityUtils.toString(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取响应体实体, 可手动接收 Http Response Body.
|
||||
* @return 返回 Http 实体.
|
||||
*/
|
||||
public HttpEntity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
@ -2,10 +2,19 @@ package net.lamgc.oracle.sentry.script.tools.http;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
|
||||
/**
|
||||
* 创建脚本使用的 HttpClient 包装对象.
|
||||
* <p> 可根据脚本需要优化和简化步骤.
|
||||
* @author LamGC
|
||||
*/
|
||||
public class ScriptHttpClient {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
/**
|
||||
* 包装并构造一个脚本 Http 客户端.
|
||||
* @param httpClient 原始 Http 客户端.
|
||||
*/
|
||||
public ScriptHttpClient(HttpClient httpClient) {
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
@ -13,6 +22,7 @@ public class ScriptHttpClient {
|
||||
/**
|
||||
* 打开一个连接.
|
||||
* @param url 要访问的 Url.
|
||||
* @return 返回 Http 访问对象(可重复使用).
|
||||
*/
|
||||
public HttpAccess create(String url) {
|
||||
return new HttpAccess(httpClient, url);
|
||||
|
Loading…
Reference in New Issue
Block a user