mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: 增加主机测试连接按钮
This commit is contained in:
parent
0fdf519808
commit
3c770ce63b
@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func (b *BaseApi) CreateCommand(c *gin.Context) {
|
||||
var req dto.CommandCreate
|
||||
var req dto.CommandOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@ -45,7 +45,7 @@ func (b *BaseApi) SearchCommand(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) ListCommand(c *gin.Context) {
|
||||
list, err := commandService.Search()
|
||||
list, err := commandService.List()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@ -55,7 +55,7 @@ func (b *BaseApi) ListCommand(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteCommand(c *gin.Context) {
|
||||
var req dto.DeleteByName
|
||||
var req dto.BatchDeleteReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@ -65,7 +65,7 @@ func (b *BaseApi) DeleteCommand(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := commandService.Delete(req.Name); err != nil {
|
||||
if err := commandService.Delete(req.Ids); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
@ -73,7 +73,7 @@ func (b *BaseApi) DeleteCommand(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) UpdateCommand(c *gin.Context) {
|
||||
var req dto.CommandUpdate
|
||||
var req dto.CommandOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@ -90,6 +90,7 @@ func (b *BaseApi) UpdateCommand(c *gin.Context) {
|
||||
|
||||
upMap := make(map[string]interface{})
|
||||
upMap["name"] = req.Name
|
||||
upMap["command"] = req.Command
|
||||
if err := commandService.Update(id, upMap); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/constant"
|
||||
"github.com/1Panel-dev/1Panel/global"
|
||||
"github.com/1Panel-dev/1Panel/utils/copier"
|
||||
"github.com/1Panel-dev/1Panel/utils/ssh"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@ -27,6 +28,32 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
|
||||
helper.SuccessWithData(c, host)
|
||||
}
|
||||
|
||||
func (b *BaseApi) TestConn(c *gin.Context) {
|
||||
var req dto.HostOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
var connInfo ssh.ConnInfo
|
||||
if err := copier.Copy(&connInfo, &req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, constant.ErrStructTransform)
|
||||
return
|
||||
}
|
||||
client, err := connInfo.NewClient()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) HostTree(c *gin.Context) {
|
||||
var req dto.SearchForTree
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@ -63,17 +90,13 @@ func (b *BaseApi) GetHostInfo(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteHost(c *gin.Context) {
|
||||
var req dto.BatchDeleteReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := hostService.BatchDelete(req.Ids); err != nil {
|
||||
if err := hostService.Delete(id); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ func (b *BaseApi) WsSsh(c *gin.Context) {
|
||||
defer wsConn.Close()
|
||||
|
||||
client, err := connInfo.NewClient()
|
||||
if wshandleError(wsConn, errors.WithMessage(err, " Failed to set up the connection. Please check the host information")) {
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "failed to set up the connection. Please check the host information")) {
|
||||
return
|
||||
}
|
||||
defer client.Close()
|
||||
|
@ -1,16 +1,12 @@
|
||||
package dto
|
||||
|
||||
type CommandCreate struct {
|
||||
type CommandOperate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Command string `json:"command" validate:"required"`
|
||||
}
|
||||
|
||||
type CommandUpdate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type CommandInfo struct {
|
||||
ID string `json:"id"`
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Command string `json:"command"`
|
||||
}
|
||||
|
@ -11,18 +11,18 @@ import (
|
||||
type CommandService struct{}
|
||||
|
||||
type ICommandService interface {
|
||||
Search() ([]model.Command, error)
|
||||
List() ([]model.Command, error)
|
||||
SearchWithPage(search dto.SearchWithPage) (int64, interface{}, error)
|
||||
Create(commandDto dto.CommandCreate) error
|
||||
Create(commandDto dto.CommandOperate) error
|
||||
Update(id uint, upMap map[string]interface{}) error
|
||||
Delete(name string) error
|
||||
Delete(ids []uint) error
|
||||
}
|
||||
|
||||
func NewICommandService() ICommandService {
|
||||
return &CommandService{}
|
||||
}
|
||||
|
||||
func (u *CommandService) Search() ([]model.Command, error) {
|
||||
func (u *CommandService) List() ([]model.Command, error) {
|
||||
commands, err := commandRepo.GetList()
|
||||
if err != nil {
|
||||
return nil, constant.ErrRecordNotFound
|
||||
@ -43,7 +43,7 @@ func (u *CommandService) SearchWithPage(search dto.SearchWithPage) (int64, inter
|
||||
return total, dtoCommands, err
|
||||
}
|
||||
|
||||
func (u *CommandService) Create(commandDto dto.CommandCreate) error {
|
||||
func (u *CommandService) Create(commandDto dto.CommandOperate) error {
|
||||
command, _ := commandRepo.Get(commonRepo.WithByName(commandDto.Name))
|
||||
if command.ID != 0 {
|
||||
return constant.ErrRecordExist
|
||||
@ -57,12 +57,15 @@ func (u *CommandService) Create(commandDto dto.CommandCreate) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *CommandService) Delete(name string) error {
|
||||
command, _ := commandRepo.Get(commonRepo.WithByName(name))
|
||||
if command.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
func (u *CommandService) Delete(ids []uint) error {
|
||||
if len(ids) == 1 {
|
||||
command, _ := commandRepo.Get(commonRepo.WithByID(ids[0]))
|
||||
if command.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
}
|
||||
return commandRepo.Delete(commonRepo.WithByID(ids[0]))
|
||||
}
|
||||
return commandRepo.Delete(commonRepo.WithByID(command.ID))
|
||||
return commandRepo.Delete(commonRepo.WithIdsIn(ids))
|
||||
}
|
||||
|
||||
func (u *CommandService) Update(id uint, upMap map[string]interface{}) error {
|
||||
|
@ -17,7 +17,7 @@ type IHostService interface {
|
||||
SearchForTree(search dto.SearchForTree) ([]dto.HostTree, error)
|
||||
Create(hostDto dto.HostOperate) (*dto.HostInfo, error)
|
||||
Update(id uint, upMap map[string]interface{}) error
|
||||
BatchDelete(ids []uint) error
|
||||
Delete(id uint) error
|
||||
}
|
||||
|
||||
func NewIHostService() IHostService {
|
||||
@ -75,14 +75,12 @@ func (u *HostService) Create(hostDto dto.HostOperate) (*dto.HostInfo, error) {
|
||||
return &hostinfo, nil
|
||||
}
|
||||
|
||||
func (u *HostService) BatchDelete(ids []uint) error {
|
||||
if len(ids) == 1 {
|
||||
host, _ := hostRepo.Get(commonRepo.WithByID(ids[0]))
|
||||
if host.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
}
|
||||
func (u *HostService) Delete(id uint) error {
|
||||
host, _ := hostRepo.Get(commonRepo.WithByID(id))
|
||||
if host.ID == 0 {
|
||||
return constant.ErrRecordNotFound
|
||||
}
|
||||
return hostRepo.Delete(commonRepo.WithIdsIn(ids))
|
||||
return hostRepo.Delete(commonRepo.WithByID(id))
|
||||
}
|
||||
|
||||
func (u *HostService) Update(id uint, upMap map[string]interface{}) error {
|
||||
|
@ -16,8 +16,9 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) {
|
||||
{
|
||||
withRecordRouter.POST("", baseApi.CreateHost)
|
||||
withRecordRouter.DELETE(":id", baseApi.DeleteHost)
|
||||
withRecordRouter.PUT(":id", baseApi.UpdateHost)
|
||||
hostRouter.POST("/search", baseApi.HostTree)
|
||||
hostRouter.POST("/testconn", baseApi.TestConn)
|
||||
hostRouter.GET(":id", baseApi.GetHostInfo)
|
||||
hostRouter.PUT(":id", baseApi.UpdateHost)
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,10 @@ export const addHost = (params: Host.HostOperate) => {
|
||||
return http.post<Host.HostOperate>(`/hosts`, params);
|
||||
};
|
||||
|
||||
export const testConn = (params: Host.HostOperate) => {
|
||||
return http.post<Host.HostOperate>(`/hosts/testconn`, params);
|
||||
};
|
||||
|
||||
export const editHost = (params: Host.HostOperate) => {
|
||||
console.log(params.id);
|
||||
return http.put(`/hosts/` + params.id, params);
|
||||
|
@ -90,8 +90,16 @@ export default {
|
||||
logout: 'Logout',
|
||||
},
|
||||
terminal: {
|
||||
connHistory: 'historys',
|
||||
hostHistory: 'History record',
|
||||
conn: 'connection',
|
||||
testConn: 'Test connection',
|
||||
connTestOk: 'Connection information available',
|
||||
hostList: 'Host information',
|
||||
createConn: 'Create a connection',
|
||||
createGroup: 'Create a group',
|
||||
expand: 'Expand all',
|
||||
fold: 'All contract',
|
||||
groupDeleteHelper:
|
||||
'After the group is removed, all connections in the group will be migrated to the default group. Confirm the information',
|
||||
addHost: 'Add Host',
|
||||
localhost: 'Localhost',
|
||||
name: 'Name',
|
||||
@ -108,6 +116,8 @@ export default {
|
||||
detail: {
|
||||
users: 'User',
|
||||
hosts: 'Host',
|
||||
groups: 'Group',
|
||||
commands: 'Command',
|
||||
auth: 'User',
|
||||
login: ' login',
|
||||
logout: ' logout',
|
||||
|
@ -94,7 +94,14 @@ export default {
|
||||
},
|
||||
terminal: {
|
||||
conn: '连接',
|
||||
testConn: '连接测试',
|
||||
connTestOk: '连接信息可用',
|
||||
hostList: '主机信息',
|
||||
createConn: '创建连接',
|
||||
createGroup: '创建分组',
|
||||
expand: '全部展开',
|
||||
fold: '全部收缩',
|
||||
groupDeleteHelper: '移除组后,组内所有连接将迁移到 default 组内,是否确认',
|
||||
quickCmd: '快捷命令',
|
||||
command: '命令',
|
||||
addHost: '添加主机',
|
||||
@ -114,7 +121,7 @@ export default {
|
||||
users: '用户',
|
||||
hosts: '主机',
|
||||
groups: '组',
|
||||
command: '快捷命令',
|
||||
commands: '快捷命令',
|
||||
auth: '用户',
|
||||
post: '创建',
|
||||
put: '更新',
|
||||
|
@ -83,7 +83,6 @@ const submitAddCommand = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
console.log(commandInfo.id);
|
||||
if (operate.value === 'create') {
|
||||
await addCommand(commandInfo);
|
||||
} else {
|
||||
@ -97,12 +96,11 @@ const submitAddCommand = (formEl: FormInstance | undefined) => {
|
||||
|
||||
const onEdit = async (row: Command.CommandInfo | null) => {
|
||||
if (row !== null) {
|
||||
console.log(row.id);
|
||||
// commandInfo.id = row.id;
|
||||
// commandInfo.name = row.name;
|
||||
// commandInfo.command = row.command;
|
||||
// operate.value = 'edit';
|
||||
// cmdVisiable.value = true;
|
||||
commandInfo.id = row.id;
|
||||
commandInfo.name = row.name;
|
||||
commandInfo.command = row.command;
|
||||
operate.value = 'edit';
|
||||
cmdVisiable.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
@ -142,9 +140,6 @@ const search = async () => {
|
||||
commandSearch.pageSize = paginationConfig.pageSize;
|
||||
const res = await getCommandPage(commandSearch);
|
||||
data.value = res.data.items;
|
||||
for (const d of data.value) {
|
||||
d.id = d.id + '';
|
||||
}
|
||||
paginationConfig.total = res.data.total;
|
||||
};
|
||||
|
||||
|
@ -2,16 +2,16 @@
|
||||
<el-row style="margin: 20px; margin-left: 20px" class="row-box" :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-card class="el-card">
|
||||
<el-tooltip class="box-item" effect="dark" content="创建连接" placement="top-start">
|
||||
<el-tooltip class="box-item" effect="dark" :content="$t('terminal.createConn')" placement="top-start">
|
||||
<el-button icon="Plus" @click="restHostForm" size="small" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="box-item" effect="dark" content="创建分组" placement="top-start">
|
||||
<el-tooltip class="box-item" effect="dark" :content="$t('terminal.createGroup')" placement="top-start">
|
||||
<el-button icon="FolderAdd" @click="onGroupCreate" size="small" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="box-item" effect="dark" content="展开" placement="top-start">
|
||||
<el-tooltip class="box-item" effect="dark" :content="$t('terminal.expand')" placement="top-start">
|
||||
<el-button icon="Expand" @click="setTreeStatus(true)" size="small" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="box-item" effect="dark" content="收缩" placement="top-start">
|
||||
<el-tooltip class="box-item" effect="dark" :content="$t('terminal.fold')" placement="top-start">
|
||||
<el-button icon="Fold" @click="setTreeStatus(false)" size="small" />
|
||||
</el-tooltip>
|
||||
<el-input
|
||||
@ -69,7 +69,7 @@
|
||||
<el-input clearable v-model="hostInfo.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.table.group')" prop="groupBelong">
|
||||
<el-select v-model="hostInfo.groupBelong" clearable style="width: 100%">
|
||||
<el-select filterable v-model="hostInfo.groupBelong" clearable style="width: 100%">
|
||||
<el-option v-for="item in groupList" :key="item.id" :label="item.name" :value="item.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@ -105,10 +105,21 @@
|
||||
<el-button @click="restHostForm">
|
||||
{{ $t('commons.button.reset') }}
|
||||
</el-button>
|
||||
<el-button v-if="hostOperation === 'create'" type="primary" @click="submitAddHost(hostInfoRef)">
|
||||
<el-button @click="submitAddHost(hostInfoRef, 'testconn')">
|
||||
{{ $t('terminal.testConn') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="hostOperation === 'create'"
|
||||
type="primary"
|
||||
@click="submitAddHost(hostInfoRef, 'create')"
|
||||
>
|
||||
{{ $t('commons.button.create') }}
|
||||
</el-button>
|
||||
<el-button v-if="hostOperation === 'edit'" type="primary" @click="submitAddHost(hostInfoRef)">
|
||||
<el-button
|
||||
v-if="hostOperation === 'edit'"
|
||||
type="primary"
|
||||
@click="submitAddHost(hostInfoRef, 'edit')"
|
||||
>
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
@ -124,7 +135,7 @@ import type { ElForm } from 'element-plus';
|
||||
import { Rules } from '@/global/form-rues';
|
||||
import { Host } from '@/api/interface/host';
|
||||
import { Group } from '@/api/interface/group';
|
||||
import { getHostList, getHostInfo, addHost, editHost, deleteHost } from '@/api/modules/host';
|
||||
import { testConn, getHostList, getHostInfo, addHost, editHost, deleteHost } from '@/api/modules/host';
|
||||
import { getGroupList, addGroup, editGroup, deleteGroup } from '@/api/modules/group';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
import { ElMessage } from 'element-plus';
|
||||
@ -203,18 +214,29 @@ function restHostForm() {
|
||||
}
|
||||
}
|
||||
|
||||
const submitAddHost = (formEl: FormInstance | undefined) => {
|
||||
const submitAddHost = (formEl: FormInstance | undefined, ops: string) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
if (hostOperation.value === 'create') {
|
||||
await addHost(hostInfo);
|
||||
} else {
|
||||
await editHost(hostInfo);
|
||||
console.log(ops);
|
||||
switch (ops) {
|
||||
case 'create':
|
||||
await addHost(hostInfo);
|
||||
restHostForm();
|
||||
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||
loadHostTree();
|
||||
break;
|
||||
case 'edit':
|
||||
await editHost(hostInfo);
|
||||
restHostForm();
|
||||
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||
loadHostTree();
|
||||
break;
|
||||
case 'testconn':
|
||||
await testConn(hostInfo);
|
||||
ElMessage.success(i18n.global.t('terminal.connTestOk'));
|
||||
break;
|
||||
}
|
||||
restHostForm();
|
||||
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
|
||||
loadHostTree();
|
||||
});
|
||||
};
|
||||
|
||||
@ -224,7 +246,6 @@ const onGroupCreate = () => {
|
||||
groupOperation.value = 'create';
|
||||
};
|
||||
const onCreateGroup = async () => {
|
||||
console.log(groupOperation.value);
|
||||
if (groupOperation.value === 'create') {
|
||||
let group = { id: 0, name: groupInputValue.value, type: 'host' };
|
||||
await addGroup(group);
|
||||
@ -246,7 +267,7 @@ const onDelete = async (node: Node, data: Tree) => {
|
||||
return;
|
||||
}
|
||||
if (node.level === 1) {
|
||||
await useDeleteData(deleteGroup, data.id - 10000, '移除组后,组内所有连接将迁移到 default 组内,是否确认?');
|
||||
await useDeleteData(deleteGroup, data.id - 10000, i18n.global.t('terminal.groupDeleteHelper'));
|
||||
loadGroups();
|
||||
} else {
|
||||
await useDeleteData(deleteHost, data.id, 'commons.msg.delete');
|
||||
@ -259,13 +280,11 @@ const onEdit = async (node: Node, data: Tree) => {
|
||||
if (node.level === 1 && data.label === 'default') {
|
||||
return;
|
||||
}
|
||||
console.log(node.level === 1);
|
||||
if (node.level === 1) {
|
||||
groupInputShow.value = true;
|
||||
groupInputValue.value = data.label;
|
||||
currentGroupID.value = data.id - 10000;
|
||||
groupOperation.value = 'edit';
|
||||
console.log(groupOperation.value);
|
||||
return;
|
||||
} else {
|
||||
const res = await getHostInfo(data.id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user