主机配置添加系统类型.

This commit is contained in:
lijiahangmax
2024-04-17 00:10:44 +08:00
parent a3e354cea9
commit 7f1f286a7d
11 changed files with 115 additions and 33 deletions

View File

@@ -3,9 +3,22 @@
> sql 脚本 - DDL > sql 脚本 - DDL
```sql ```sql
ALTER TABLE `exec_log`
ADD COLUMN `script_exec` tinyint(0) NULL DEFAULT 0 COMMENT '是否使用脚本执行' AFTER `timeout`;
ALTER TABLE `exec_job`
ADD COLUMN `script_exec` tinyint(0) NULL DEFAULT 0 COMMENT '是否使用脚本执行' AFTER `timeout`;
ALTER TABLE `exec_template`
ADD COLUMN `script_exec` tinyint(0) NULL DEFAULT 0 COMMENT '是否使用脚本执行' AFTER `timeout`;
ALTER TABLE `exec_host_log`
ADD COLUMN `script_path` varchar(512) NULL COMMENT '脚本路径' AFTER `log_path`;
``` ```
> sql 脚本 - DML > sql 脚本 - DML
```sql ```sql
-- 设置主机配置中的 osType
UPDATE host_config SET config = JSON_SET(config, '$.osType', 'LINUX') WHERE type = 'ssh' AND deleted = 0;
``` ```

View File

@@ -0,0 +1,44 @@
package com.orion.ops.module.asset.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 主机系统类型
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/4/16 21:58
*/
@Getter
@AllArgsConstructor
public enum HostSshOsTypeEnum {
/**
* linux
*/
LINUX(".sh"),
/**
* windows
*/
WINDOWS(".cmd"),
;
private final String scriptSuffix;
public static HostSshOsTypeEnum of(String type) {
if (type == null) {
return null;
}
for (HostSshOsTypeEnum value : values()) {
if (value.name().equals(type)) {
return value;
}
}
return null;
}
}

View File

@@ -38,8 +38,14 @@ public class HostSshConfigModel implements GenericsDataModel, UpdatePasswordActi
@NotBlank @NotBlank
@Size(max = 12) @Size(max = 12)
@Schema(description = "认证方式")
private String authType; private String authType;
@NotBlank
@Size(max = 12)
@Schema(description = "系统类型")
private String osType;
@Schema(description = "密码") @Schema(description = "密码")
private String password; private String password;

View File

@@ -12,6 +12,7 @@ import com.orion.ops.framework.common.security.PasswordModifier;
import com.orion.ops.framework.common.utils.Valid; import com.orion.ops.framework.common.utils.Valid;
import com.orion.ops.module.asset.dao.HostIdentityDAO; import com.orion.ops.module.asset.dao.HostIdentityDAO;
import com.orion.ops.module.asset.dao.HostKeyDAO; import com.orion.ops.module.asset.dao.HostKeyDAO;
import com.orion.ops.module.asset.enums.HostSshOsTypeEnum;
import com.orion.ops.module.asset.enums.HostSshAuthTypeEnum; import com.orion.ops.module.asset.enums.HostSshAuthTypeEnum;
import com.orion.ops.module.asset.handler.host.config.model.HostSshConfigModel; import com.orion.ops.module.asset.handler.host.config.model.HostSshConfigModel;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -45,6 +46,7 @@ public class HostSshConfigStrategy implements MapDataStrategy<HostSshConfigModel
.port(SSH_PORT) .port(SSH_PORT)
.username(USERNAME) .username(USERNAME)
.authType(HostSshAuthTypeEnum.PASSWORD.name()) .authType(HostSshAuthTypeEnum.PASSWORD.name())
.osType(HostSshOsTypeEnum.LINUX.name())
.connectTimeout(Const.MS_S_10) .connectTimeout(Const.MS_S_10)
.charset(Const.UTF_8) .charset(Const.UTF_8)
.fileNameCharset(Const.UTF_8) .fileNameCharset(Const.UTF_8)
@@ -56,6 +58,8 @@ public class HostSshConfigStrategy implements MapDataStrategy<HostSshConfigModel
public void preValid(HostSshConfigModel model) { public void preValid(HostSshConfigModel model) {
// 验证认证类型 // 验证认证类型
Valid.valid(HostSshAuthTypeEnum::of, model.getAuthType()); Valid.valid(HostSshAuthTypeEnum::of, model.getAuthType());
// 验证系统版本
Valid.valid(HostSshOsTypeEnum::of, model.getOsType());
// 验证编码格式 // 验证编码格式
this.validCharset(model.getCharset()); this.validCharset(model.getCharset());
this.validCharset(model.getFileNameCharset()); this.validCharset(model.getFileNameCharset());

View File

@@ -21,7 +21,7 @@ import lombok.NoArgsConstructor;
@Schema(name = "HostExtraSshModel", description = "主机拓展信息 - color 模型") @Schema(name = "HostExtraSshModel", description = "主机拓展信息 - color 模型")
public class HostColorExtraModel implements GenericsDataModel { public class HostColorExtraModel implements GenericsDataModel {
@Schema(description = "颜色") @Schema(description = "标签 tab 颜色")
private String color; private String color;
} }

View File

@@ -8,8 +8,8 @@
<a-switch v-model="config.status" <a-switch v-model="config.status"
:disabled="loading" :disabled="loading"
type="round" type="round"
:checked-value="1" :checked-value="EnabledStatus.ENABLED"
:unchecked-value="0" :unchecked-value="EnabledStatus.DISABLED"
:before-change="s => updateStatus(s as number)" /> :before-change="s => updateStatus(s as number)" />
</div> </div>
</template> </template>
@@ -18,14 +18,20 @@
<a-form :model="formModel" <a-form :model="formModel"
ref="formRef" ref="formRef"
label-align="right" label-align="right"
:label-col-props="{ span: 6 }" :auto-label-width="true"
:wrapper-col-props="{ span: 18 }"
:rules="rules"> :rules="rules">
<!-- 系统类型 -->
<a-form-item field="osType"
label="系统类型"
:hide-asterisk="true">
<a-select v-model="formModel.osType"
:options="toOptions(sshOsTypeKey)"
placeholder="请选择系统类型" />
</a-form-item>
<!-- 用户名 --> <!-- 用户名 -->
<a-form-item field="username" <a-form-item field="username"
label="用户名" label="用户名"
:rules="usernameRules" :rules="usernameRules"
label-col-flex="60px"
:help="SshAuthType.IDENTITY === formModel.authType ? '将使用主机身份的用户名' : undefined"> :help="SshAuthType.IDENTITY === formModel.authType ? '将使用主机身份的用户名' : undefined">
<a-input v-model="formModel.username" <a-input v-model="formModel.username"
:disabled="SshAuthType.IDENTITY === formModel.authType" :disabled="SshAuthType.IDENTITY === formModel.authType"
@@ -34,8 +40,7 @@
<!-- SSH 端口 --> <!-- SSH 端口 -->
<a-form-item field="port" <a-form-item field="port"
label="SSH端口" label="SSH端口"
:hide-asterisk="true" :hide-asterisk="true">
label-col-flex="60px">
<a-input-number v-model="formModel.port" <a-input-number v-model="formModel.port"
placeholder="请输入SSH端口" placeholder="请输入SSH端口"
hide-button /> hide-button />
@@ -43,8 +48,7 @@
<!-- 验证方式 --> <!-- 验证方式 -->
<a-form-item field="authType" <a-form-item field="authType"
label="验证方式" label="验证方式"
:hide-asterisk="true" :hide-asterisk="true">
label-col-flex="60px">
<a-radio-group type="button" <a-radio-group type="button"
class="auth-type-group usn" class="auth-type-group usn"
v-model="formModel.authType" v-model="formModel.authType"
@@ -54,8 +58,7 @@
<a-form-item v-if="SshAuthType.PASSWORD === formModel.authType" <a-form-item v-if="SshAuthType.PASSWORD === formModel.authType"
field="password" field="password"
label="主机密码" label="主机密码"
:rules="passwordRules" :rules="passwordRules">
label-col-flex="60px">
<a-input-password v-model="formModel.password" <a-input-password v-model="formModel.password"
:disabled="!formModel.useNewPassword && formModel.hasPassword" :disabled="!formModel.useNewPassword && formModel.hasPassword"
placeholder="主机密码" /> placeholder="主机密码" />
@@ -70,23 +73,20 @@
<a-form-item v-if="SshAuthType.KEY === formModel.authType" <a-form-item v-if="SshAuthType.KEY === formModel.authType"
field="keyId" field="keyId"
label="主机秘钥" label="主机秘钥"
:hide-asterisk="true" :hide-asterisk="true">
label-col-flex="60px">
<host-key-selector v-model="formModel.keyId" /> <host-key-selector v-model="formModel.keyId" />
</a-form-item> </a-form-item>
<!-- 主机身份 --> <!-- 主机身份 -->
<a-form-item v-if="SshAuthType.IDENTITY === formModel.authType" <a-form-item v-if="SshAuthType.IDENTITY === formModel.authType"
field="identityId" field="identityId"
label="主机身份" label="主机身份"
:hide-asterisk="true" :hide-asterisk="true">
label-col-flex="60px">
<host-identity-selector v-model="formModel.identityId" /> <host-identity-selector v-model="formModel.identityId" />
</a-form-item> </a-form-item>
<!-- 用户名 --> <!-- 用户名 -->
<a-form-item field="connectTimeout" <a-form-item field="connectTimeout"
label="连接超时时间" label="连接超时时间"
:hide-asterisk="true" :hide-asterisk="true">
label-col-flex="86px">
<a-input-number v-model="formModel.connectTimeout" <a-input-number v-model="formModel.connectTimeout"
placeholder="请输入连接超时时间" placeholder="请输入连接超时时间"
hide-button> hide-button>
@@ -98,22 +98,19 @@
<!-- SSH输出编码 --> <!-- SSH输出编码 -->
<a-form-item field="charset" <a-form-item field="charset"
label="SSH输出编码" label="SSH输出编码"
:hide-asterisk="true" :hide-asterisk="true">
label-col-flex="86px">
<a-input v-model="formModel.charset" placeholder="请输入 SSH 输出编码" /> <a-input v-model="formModel.charset" placeholder="请输入 SSH 输出编码" />
</a-form-item> </a-form-item>
<!-- 文件名称编码 --> <!-- 文件名称编码 -->
<a-form-item field="fileNameCharset" <a-form-item field="fileNameCharset"
label="文件名称编码" label="文件名称编码"
:hide-asterisk="true" :hide-asterisk="true">
label-col-flex="86px">
<a-input v-model="formModel.fileNameCharset" placeholder="请输入 SFTP 文件名称编码" /> <a-input v-model="formModel.fileNameCharset" placeholder="请输入 SFTP 文件名称编码" />
</a-form-item> </a-form-item>
<!-- 文件内容编码 --> <!-- 文件内容编码 -->
<a-form-item field="fileContentCharset" <a-form-item field="fileContentCharset"
label="文件内容编码" label="文件内容编码"
:hide-asterisk="true" :hide-asterisk="true">
label-col-flex="86px">
<a-input v-model="formModel.fileContentCharset" placeholder="请输入 SFTP 文件内容编码" /> <a-input v-model="formModel.fileContentCharset" placeholder="请输入 SFTP 文件内容编码" />
</a-form-item> </a-form-item>
</a-form> </a-form>
@@ -146,7 +143,7 @@
import type { HostSshConfig } from './types/const'; import type { HostSshConfig } from './types/const';
import { reactive, ref, watch } from 'vue'; import { reactive, ref, watch } from 'vue';
import { updateHostConfigStatus, updateHostConfig } from '@/api/asset/host-config'; import { updateHostConfigStatus, updateHostConfig } from '@/api/asset/host-config';
import { sshAuthTypeKey, SshAuthType } from './types/const'; import { sshAuthTypeKey, sshOsTypeKey, SshAuthType, SshOsType } from './types/const';
import rules from './types/form.rules'; import rules from './types/form.rules';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading'; import useLoading from '@/hooks/loading';
@@ -157,7 +154,7 @@
import HostIdentitySelector from '@/components/asset/host-identity/selector/index.vue'; import HostIdentitySelector from '@/components/asset/host-identity/selector/index.vue';
const { loading, setLoading } = useLoading(); const { loading, setLoading } = useLoading();
const { toRadioOptions } = useDictStore(); const { toOptions, toRadioOptions } = useDictStore();
const props = defineProps<{ const props = defineProps<{
content: any; content: any;
@@ -173,6 +170,7 @@
const formRef = ref(); const formRef = ref();
const formModel = ref<HostSshConfig>({ const formModel = ref<HostSshConfig>({
osType: SshOsType.LINUX,
username: undefined, username: undefined,
port: undefined, port: undefined,
password: undefined, password: undefined,

View File

@@ -1,5 +1,6 @@
// 主机 SSH 配置 // 主机 SSH 配置
export interface HostSshConfig { export interface HostSshConfig {
osType?: string;
port?: number; port?: number;
username?: string; username?: string;
password?: string; password?: string;
@@ -14,7 +15,7 @@ export interface HostSshConfig {
hasPassword?: boolean; hasPassword?: boolean;
} }
// 主机 ssh 验证方式 // 主机验证方式
export const SshAuthType = { export const SshAuthType = {
// 密码验证 // 密码验证
PASSWORD: 'PASSWORD', PASSWORD: 'PASSWORD',
@@ -24,8 +25,17 @@ export const SshAuthType = {
IDENTITY: 'IDENTITY' IDENTITY: 'IDENTITY'
}; };
// 主机系统版本
export const SshOsType = {
LINUX: 'LINUX',
WINDOWS: 'WINDOWS',
};
// 主机验证方式 字典项 // 主机验证方式 字典项
export const sshAuthTypeKey = 'hostSshAuthType'; export const sshAuthTypeKey = 'hostSshAuthType';
// 主机系统类型 字典项
export const sshOsTypeKey = 'hostSshOsType';
// 加载的字典值 // 加载的字典值
export const dictKeys = [sshAuthTypeKey]; export const dictKeys = [sshAuthTypeKey, sshOsTypeKey];

View File

@@ -1,5 +1,10 @@
import type { FieldRule } from '@arco-design/web-vue'; import type { FieldRule } from '@arco-design/web-vue';
export const osType = [{
required: true,
message: '请选择系统类型'
}] as FieldRule[];
export const port = [{ export const port = [{
required: true, required: true,
message: '请输入SSH端口' message: '请输入SSH端口'
@@ -60,6 +65,7 @@ export const fileContentCharset = [{
}] as FieldRule[]; }] as FieldRule[];
export default { export default {
osType,
port, port,
authType, authType,
keyId, keyId,

View File

@@ -1,7 +1,7 @@
<template> <template>
<a-drawer v-model:visible="visible" <a-drawer v-model:visible="visible"
class="host-group-drawer" class="host-group-drawer"
:width="1120" width="70%"
title="主机分组配置" title="主机分组配置"
:esc-to-close="false" :esc-to-close="false"
:mask-closable="false" :mask-closable="false"
@@ -131,7 +131,7 @@
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@tree-width: 30%; @tree-width: 33%;
.host-group-container { .host-group-container {
width: 100%; width: 100%;

View File

@@ -78,7 +78,7 @@
:bordered="false"> :bordered="false">
<!-- 配置项 --> <!-- 配置项 -->
<template #keyName="{ record }"> <template #keyName="{ record }">
<span class="text-copy" @click="copy(record.keyName)">{{ record.keyName }}</span> <span class="text-copy span-blue" @click="copy(record.keyName)">{{ record.keyName }}</span>
</template> </template>
<!-- 配置值类型 --> <!-- 配置值类型 -->
<template #valueType="{ record }"> <template #valueType="{ record }">

View File

@@ -7,17 +7,18 @@
<a-form :model="formModel" <a-form :model="formModel"
ref="formRef" ref="formRef"
label-align="left" label-align="left"
:auto-label-width="true"
@keyup.enter="loadMenuData"> @keyup.enter="loadMenuData">
<a-row :gutter="32"> <a-row :gutter="32">
<!-- 菜单名称 --> <!-- 菜单名称 -->
<a-col :span="12"> <a-col :span="12">
<a-form-item field="name" label="菜单名称" label-col-flex="60px"> <a-form-item field="name" label="菜单名称">
<a-input v-model="formModel.name" placeholder="请输入菜单名称" allow-clear /> <a-input v-model="formModel.name" placeholder="请输入菜单名称" allow-clear />
</a-form-item> </a-form-item>
</a-col> </a-col>
<!-- 菜单状态 --> <!-- 菜单状态 -->
<a-col :span="12"> <a-col :span="12">
<a-form-item field="status" label="菜单状态" label-col-flex="60px"> <a-form-item field="status" label="菜单状态">
<a-select v-model="formModel.status" <a-select v-model="formModel.status"
:options="toOptions(menuStatusKey)" :options="toOptions(menuStatusKey)"
placeholder="请选择菜单状态" placeholder="请选择菜单状态"