mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 22:18:07 +08:00
feat: ssh 登录日志增加概览显示 (#2347)
This commit is contained in:
parent
a520bdbe56
commit
017eb3814b
@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Load host ssh setting info
|
// @Summary Load host SSH setting info
|
||||||
// @Description 加载 SSH 配置信息
|
// @Description 加载 SSH 配置信息
|
||||||
// @Success 200 {object} dto.SSHInfo
|
// @Success 200 {object} dto.SSHInfo
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
@ -24,7 +24,7 @@ func (b *BaseApi) GetSSHInfo(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Operate ssh
|
// @Summary Operate SSH
|
||||||
// @Description 修改 SSH 服务状态
|
// @Description 修改 SSH 服务状态
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.Operate true "request"
|
// @Param request body dto.Operate true "request"
|
||||||
@ -50,7 +50,7 @@ func (b *BaseApi) OperateSSH(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Update host ssh setting
|
// @Summary Update host SSH setting
|
||||||
// @Description 更新 SSH 配置
|
// @Description 更新 SSH 配置
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.SettingUpdate true "request"
|
// @Param request body dto.SettingUpdate true "request"
|
||||||
@ -77,7 +77,7 @@ func (b *BaseApi) UpdateSSH(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Update host ssh setting by file
|
// @Summary Update host SSH setting by file
|
||||||
// @Description 上传文件更新 SSH 配置
|
// @Description 上传文件更新 SSH 配置
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.SSHConf true "request"
|
// @Param request body dto.SSHConf true "request"
|
||||||
@ -104,8 +104,8 @@ func (b *BaseApi) UpdateSSHByfile(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Generate host ssh secret
|
// @Summary Generate host SSH secret
|
||||||
// @Description 生成 ssh 密钥
|
// @Description 生成 SSH 密钥
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.GenerateSSH true "request"
|
// @Param request body dto.GenerateSSH true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
@ -131,8 +131,8 @@ func (b *BaseApi) GenerateSSH(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Load host ssh secret
|
// @Summary Load host SSH secret
|
||||||
// @Description 获取 ssh 密钥
|
// @Description 获取 SSH 密钥
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.GenerateLoad true "request"
|
// @Param request body dto.GenerateLoad true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
@ -158,13 +158,40 @@ func (b *BaseApi) LoadSSHSecret(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Load host ssh logs
|
// @Summary Analysis host SSH logs
|
||||||
// @Description 获取 ssh 登录日志
|
// @Description 分析 SSH 登录日志
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.SearchForAnalysis true "request"
|
||||||
|
// @Success 200 {array} dto.SSHLogAnalysis
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /host/ssh/log/analysis [post]
|
||||||
|
func (b *BaseApi) AnalysisLog(c *gin.Context) {
|
||||||
|
var req dto.SearchForAnalysis
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := sshService.AnalysisLog(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags SSH
|
||||||
|
// @Summary Load host SSH logs
|
||||||
|
// @Description 获取 SSH 登录日志
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.SearchSSHLog true "request"
|
// @Param request body dto.SearchSSHLog true "request"
|
||||||
// @Success 200 {object} dto.SSHLog
|
// @Success 200 {object} dto.SSHLog
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /host/ssh/logs [post]
|
// @Router /host/ssh/log [post]
|
||||||
func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
|
func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
|
||||||
var req dto.SearchSSHLog
|
var req dto.SearchSSHLog
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
@ -185,8 +212,8 @@ func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Load host ssh conf
|
// @Summary Load host SSH conf
|
||||||
// @Description 获取 ssh 配置文件
|
// @Description 获取 SSH 配置文件
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /host/ssh/conf [get]
|
// @Router /host/ssh/conf [get]
|
||||||
|
@ -36,6 +36,19 @@ type SSHLog struct {
|
|||||||
SuccessfulCount int `json:"successfulCount"`
|
SuccessfulCount int `json:"successfulCount"`
|
||||||
FailedCount int `json:"failedCount"`
|
FailedCount int `json:"failedCount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SearchForAnalysis struct {
|
||||||
|
OrderBy string `json:"orderBy" validate:"required,oneof=Success Failed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SSHLogAnalysis struct {
|
||||||
|
Address string `json:"address"`
|
||||||
|
Area string `json:"area"`
|
||||||
|
SuccessfulCount int `json:"successfulCount"`
|
||||||
|
FailedCount int `json:"failedCount"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
type SSHHistory struct {
|
type SSHHistory struct {
|
||||||
Date time.Time `json:"date"`
|
Date time.Time `json:"date"`
|
||||||
DateStr string `json:"dateStr"`
|
DateStr string `json:"dateStr"`
|
||||||
|
@ -608,3 +608,21 @@ func (u *FirewallService) addAddressRecord(req dto.AddrRuleOperate) error {
|
|||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func listIpRules(strategy string) ([]string, error) {
|
||||||
|
client, err := firewall.NewFirewallClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
addrs, err := client.ListAddress()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var rules []string
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if addr.Strategy == strategy {
|
||||||
|
rules = append(rules, addr.Address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rules, nil
|
||||||
|
}
|
||||||
|
@ -32,6 +32,7 @@ type ISSHService interface {
|
|||||||
UpdateByFile(value string) error
|
UpdateByFile(value string) error
|
||||||
Update(key, value string) error
|
Update(key, value string) error
|
||||||
GenerateSSH(req dto.GenerateSSH) error
|
GenerateSSH(req dto.GenerateSSH) error
|
||||||
|
AnalysisLog(req dto.SearchForAnalysis) ([]dto.SSHLogAnalysis, error)
|
||||||
LoadSSHSecret(mode string) (string, error)
|
LoadSSHSecret(mode string) (string, error)
|
||||||
LoadLog(req dto.SearchSSHLog) (*dto.SSHLog, error)
|
LoadLog(req dto.SearchSSHLog) (*dto.SSHLog, error)
|
||||||
|
|
||||||
@ -303,6 +304,70 @@ func (u *SSHService) LoadLog(req dto.SearchSSHLog) (*dto.SSHLog, error) {
|
|||||||
return &data, nil
|
return &data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *SSHService) AnalysisLog(req dto.SearchForAnalysis) ([]dto.SSHLogAnalysis, error) {
|
||||||
|
var fileList []string
|
||||||
|
baseDir := "/var/log"
|
||||||
|
if err := filepath.Walk(baseDir, func(pathItem string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !info.IsDir() && strings.HasPrefix(info.Name(), "secure") || strings.HasPrefix(info.Name(), "auth") {
|
||||||
|
if !strings.HasSuffix(info.Name(), ".gz") {
|
||||||
|
fileList = append(fileList, pathItem)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
itemFileName := strings.TrimSuffix(pathItem, ".gz")
|
||||||
|
if _, err := os.Stat(itemFileName); err != nil && os.IsNotExist(err) {
|
||||||
|
if err := handleGunzip(pathItem); err == nil {
|
||||||
|
fileList = append(fileList, itemFileName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
command := ""
|
||||||
|
sortMap := make(map[string]dto.SSHLogAnalysis)
|
||||||
|
for _, file := range fileList {
|
||||||
|
commandItem := ""
|
||||||
|
if strings.HasPrefix(path.Base(file), "secure") {
|
||||||
|
commandItem = fmt.Sprintf("cat %s | grep -aE '(Failed password for|Accepted)' | grep -v 'invalid' %s", file, command)
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(path.Base(file), "auth.log") {
|
||||||
|
commandItem = fmt.Sprintf("cat %s | grep -aE \"(Connection closed by authenticating user|Accepted)\" | grep -v 'invalid' %s", file, command)
|
||||||
|
}
|
||||||
|
loadSSHDataForAnalysis(sortMap, commandItem)
|
||||||
|
}
|
||||||
|
var sortSlice []dto.SSHLogAnalysis
|
||||||
|
for key, value := range sortMap {
|
||||||
|
sortSlice = append(sortSlice, dto.SSHLogAnalysis{Address: key, SuccessfulCount: value.SuccessfulCount, FailedCount: value.FailedCount, Status: "accept"})
|
||||||
|
}
|
||||||
|
if req.OrderBy == constant.StatusSuccess {
|
||||||
|
sort.Slice(sortSlice, func(i, j int) bool {
|
||||||
|
return sortSlice[i].SuccessfulCount > sortSlice[j].SuccessfulCount
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
sort.Slice(sortSlice, func(i, j int) bool {
|
||||||
|
return sortSlice[i].FailedCount > sortSlice[j].FailedCount
|
||||||
|
})
|
||||||
|
}
|
||||||
|
qqWry, _ := qqwry.NewQQwry()
|
||||||
|
rules, _ := listIpRules("drop")
|
||||||
|
for i := 0; i < len(sortSlice); i++ {
|
||||||
|
sortSlice[i].Area = qqWry.Find(sortSlice[i].Address).Area
|
||||||
|
for _, rule := range rules {
|
||||||
|
if sortSlice[i].Address == rule {
|
||||||
|
sortSlice[i].Status = "drop"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *SSHService) LoadSSHConf() (string, error) {
|
func (u *SSHService) LoadSSHConf() (string, error) {
|
||||||
if _, err := os.Stat("/etc/ssh/sshd_config"); err != nil {
|
if _, err := os.Stat("/etc/ssh/sshd_config"); err != nil {
|
||||||
return "", buserr.New("ErrHttpReqNotFound")
|
return "", buserr.New("ErrHttpReqNotFound")
|
||||||
@ -412,6 +477,47 @@ func loadSSHData(command string, showCountFrom, showCountTo, currentYear int, qq
|
|||||||
return datas, successCount, failedCount
|
return datas, successCount, failedCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadSSHDataForAnalysis(analysisMap map[string]dto.SSHLogAnalysis, commandItem string) {
|
||||||
|
stdout, err := cmd.Exec(commandItem)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(stdout), "\n")
|
||||||
|
for i := len(lines) - 1; i >= 0; i-- {
|
||||||
|
var itemData dto.SSHHistory
|
||||||
|
switch {
|
||||||
|
case strings.Contains(lines[i], "Failed password for"):
|
||||||
|
itemData = loadFailedSecureDatas(lines[i])
|
||||||
|
case strings.Contains(lines[i], "Connection closed by authenticating user"):
|
||||||
|
itemData = loadFailedAuthDatas(lines[i])
|
||||||
|
case strings.Contains(lines[i], "Accepted "):
|
||||||
|
itemData = loadSuccessDatas(lines[i])
|
||||||
|
}
|
||||||
|
if len(itemData.Address) != 0 {
|
||||||
|
if val, ok := analysisMap[itemData.Address]; ok {
|
||||||
|
if itemData.Status == constant.StatusSuccess {
|
||||||
|
val.SuccessfulCount++
|
||||||
|
} else {
|
||||||
|
val.FailedCount++
|
||||||
|
}
|
||||||
|
analysisMap[itemData.Address] = val
|
||||||
|
} else {
|
||||||
|
item := dto.SSHLogAnalysis{
|
||||||
|
Address: itemData.Address,
|
||||||
|
SuccessfulCount: 0,
|
||||||
|
FailedCount: 0,
|
||||||
|
}
|
||||||
|
if itemData.Status == constant.StatusSuccess {
|
||||||
|
item.SuccessfulCount = 1
|
||||||
|
} else {
|
||||||
|
item.FailedCount = 1
|
||||||
|
}
|
||||||
|
analysisMap[itemData.Address] = item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func loadSuccessDatas(line string) dto.SSHHistory {
|
func loadSuccessDatas(line string) dto.SSHHistory {
|
||||||
var data dto.SSHHistory
|
var data dto.SSHHistory
|
||||||
parts := strings.Fields(line)
|
parts := strings.Fields(line)
|
||||||
|
@ -126,3 +126,7 @@ var (
|
|||||||
ErrOSSConn = "ErrOSSConn"
|
ErrOSSConn = "ErrOSSConn"
|
||||||
ErrEntrance = "ErrEntrance"
|
ErrEntrance = "ErrEntrance"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrFirewall = "ErrFirewall"
|
||||||
|
)
|
||||||
|
@ -112,3 +112,6 @@ ErrConfigIsNull: "The configuration file is not allowed to be empty"
|
|||||||
ErrConfigDirNotFound: "The running directory does not exist"
|
ErrConfigDirNotFound: "The running directory does not exist"
|
||||||
ErrConfigAlreadyExist: "A configuration file with the same name already exists"
|
ErrConfigAlreadyExist: "A configuration file with the same name already exists"
|
||||||
ErrUserFindErr: "Failed to find user {{ .name }} {{ .err }}"
|
ErrUserFindErr: "Failed to find user {{ .name }} {{ .err }}"
|
||||||
|
|
||||||
|
#ssh
|
||||||
|
ErrFirewall: "No firewalld or ufw service is detected. Please check and try again!"
|
@ -112,3 +112,6 @@ ErrConfigIsNull: "配置文件不允許為空"
|
|||||||
ErrConfigDirNotFound: "運行目錄不存在"
|
ErrConfigDirNotFound: "運行目錄不存在"
|
||||||
ErrConfigAlreadyExist: "已存在同名配置文件"
|
ErrConfigAlreadyExist: "已存在同名配置文件"
|
||||||
ErrUserFindErr: "用戶 {{ .name }} 查找失敗 {{ .err }}"
|
ErrUserFindErr: "用戶 {{ .name }} 查找失敗 {{ .err }}"
|
||||||
|
|
||||||
|
#ssh
|
||||||
|
ErrFirewall: "當前未檢測到系統 firewalld 或 ufw 服務,請檢查後重試!"
|
@ -112,3 +112,6 @@ ErrConfigIsNull: "配置文件不允许为空"
|
|||||||
ErrConfigDirNotFound: "运行目录不存在"
|
ErrConfigDirNotFound: "运行目录不存在"
|
||||||
ErrConfigAlreadyExist: "已存在同名配置文件"
|
ErrConfigAlreadyExist: "已存在同名配置文件"
|
||||||
ErrUserFindErr: "用户 {{ .name }} 查找失败 {{ .err }}"
|
ErrUserFindErr: "用户 {{ .name }} 查找失败 {{ .err }}"
|
||||||
|
|
||||||
|
#ssh
|
||||||
|
ErrFirewall: "当前未检测到系统 firewalld 或 ufw 服务,请检查后重试!"
|
||||||
|
@ -41,6 +41,7 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) {
|
|||||||
hostRouter.POST("/ssh/generate", baseApi.GenerateSSH)
|
hostRouter.POST("/ssh/generate", baseApi.GenerateSSH)
|
||||||
hostRouter.POST("/ssh/secret", baseApi.LoadSSHSecret)
|
hostRouter.POST("/ssh/secret", baseApi.LoadSSHSecret)
|
||||||
hostRouter.POST("/ssh/log", baseApi.LoadSSHLogs)
|
hostRouter.POST("/ssh/log", baseApi.LoadSSHLogs)
|
||||||
|
hostRouter.POST("/ssh/log/analysis", baseApi.AnalysisLog)
|
||||||
hostRouter.POST("/ssh/conffile/update", baseApi.UpdateSSHByfile)
|
hostRouter.POST("/ssh/conffile/update", baseApi.UpdateSSHByfile)
|
||||||
hostRouter.POST("/ssh/operate", baseApi.OperateSSH)
|
hostRouter.POST("/ssh/operate", baseApi.OperateSSH)
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package firewall
|
package firewall
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/firewall/client"
|
"github.com/1Panel-dev/1Panel/backend/utils/firewall/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,5 +31,5 @@ func NewFirewallClient() (FirewallClient, error) {
|
|||||||
if _, err := os.Stat("/usr/sbin/ufw"); err == nil {
|
if _, err := os.Stat("/usr/sbin/ufw"); err == nil {
|
||||||
return client.NewUfw()
|
return client.NewUfw()
|
||||||
}
|
}
|
||||||
return nil, errors.New("no such type")
|
return nil, buserr.New(constant.ErrFirewall)
|
||||||
}
|
}
|
||||||
|
@ -5907,7 +5907,7 @@ const docTemplate = `{
|
|||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Update host ssh setting by file",
|
"summary": "Update host SSH setting by file",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -5940,11 +5940,11 @@ const docTemplate = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "获取 ssh 配置文件",
|
"description": "获取 SSH 配置文件",
|
||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Load host ssh conf",
|
"summary": "Load host SSH conf",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK"
|
"description": "OK"
|
||||||
@ -5959,14 +5959,14 @@ const docTemplate = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "生成 ssh 密钥",
|
"description": "生成 SSH 密钥",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Generate host ssh secret",
|
"summary": "Generate host SSH secret",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -5992,21 +5992,21 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/host/ssh/logs": {
|
"/host/ssh/log": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "获取 ssh 登录日志",
|
"description": "获取 SSH 登录日志",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Load host ssh logs",
|
"summary": "Load host SSH logs",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -6028,6 +6028,45 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/host/ssh/log/analysis": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "分析 SSH 登录日志",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SSH"
|
||||||
|
],
|
||||||
|
"summary": "Analysis host SSH logs",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.SearchForAnalysis"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.SSHLogAnalysis"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/host/ssh/operate": {
|
"/host/ssh/operate": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -6042,7 +6081,7 @@ const docTemplate = `{
|
|||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Operate ssh",
|
"summary": "Operate SSH",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -6077,7 +6116,7 @@ const docTemplate = `{
|
|||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Load host ssh setting info",
|
"summary": "Load host SSH setting info",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
@ -6095,14 +6134,14 @@ const docTemplate = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "获取 ssh 密钥",
|
"description": "获取 SSH 密钥",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Load host ssh secret",
|
"summary": "Load host SSH secret",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -6135,7 +6174,7 @@ const docTemplate = `{
|
|||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Update host ssh setting",
|
"summary": "Update host SSH setting",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -14456,6 +14495,26 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.SSHLogAnalysis": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"area": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"failedCount": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"successfulCount": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.SSLUpdate": {
|
"dto.SSLUpdate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@ -14486,6 +14545,21 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.SearchForAnalysis": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"orderBy"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"orderBy": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Success",
|
||||||
|
"Failed"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.SearchForTree": {
|
"dto.SearchForTree": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -14656,6 +14730,9 @@ const docTemplate = `{
|
|||||||
"complexityVerification": {
|
"complexityVerification": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"defaultNetwork": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"dingVars": {
|
"dingVars": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -16305,6 +16382,9 @@ const docTemplate = `{
|
|||||||
"resource": {
|
"resource": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"source": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -16364,6 +16444,9 @@ const docTemplate = `{
|
|||||||
"rebuild": {
|
"rebuild": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"source": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"version": {
|
"version": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
@ -5900,7 +5900,7 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Update host ssh setting by file",
|
"summary": "Update host SSH setting by file",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -5933,11 +5933,11 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "获取 ssh 配置文件",
|
"description": "获取 SSH 配置文件",
|
||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Load host ssh conf",
|
"summary": "Load host SSH conf",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK"
|
"description": "OK"
|
||||||
@ -5952,14 +5952,14 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "生成 ssh 密钥",
|
"description": "生成 SSH 密钥",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Generate host ssh secret",
|
"summary": "Generate host SSH secret",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -5985,21 +5985,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/host/ssh/logs": {
|
"/host/ssh/log": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "获取 ssh 登录日志",
|
"description": "获取 SSH 登录日志",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Load host ssh logs",
|
"summary": "Load host SSH logs",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -6021,6 +6021,45 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/host/ssh/log/analysis": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "分析 SSH 登录日志",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SSH"
|
||||||
|
],
|
||||||
|
"summary": "Analysis host SSH logs",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.SearchForAnalysis"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/dto.SSHLogAnalysis"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/host/ssh/operate": {
|
"/host/ssh/operate": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -6035,7 +6074,7 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Operate ssh",
|
"summary": "Operate SSH",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -6070,7 +6109,7 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Load host ssh setting info",
|
"summary": "Load host SSH setting info",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
@ -6088,14 +6127,14 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "获取 ssh 密钥",
|
"description": "获取 SSH 密钥",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Load host ssh secret",
|
"summary": "Load host SSH secret",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -6128,7 +6167,7 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"SSH"
|
"SSH"
|
||||||
],
|
],
|
||||||
"summary": "Update host ssh setting",
|
"summary": "Update host SSH setting",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"description": "request",
|
"description": "request",
|
||||||
@ -14449,6 +14488,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.SSHLogAnalysis": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"area": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"failedCount": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"successfulCount": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.SSLUpdate": {
|
"dto.SSLUpdate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@ -14479,6 +14538,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.SearchForAnalysis": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"orderBy"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"orderBy": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Success",
|
||||||
|
"Failed"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.SearchForTree": {
|
"dto.SearchForTree": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -14649,6 +14723,9 @@
|
|||||||
"complexityVerification": {
|
"complexityVerification": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"defaultNetwork": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"dingVars": {
|
"dingVars": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -16298,6 +16375,9 @@
|
|||||||
"resource": {
|
"resource": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"source": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -16357,6 +16437,9 @@
|
|||||||
"rebuild": {
|
"rebuild": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"source": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"version": {
|
"version": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
@ -1855,6 +1855,19 @@ definitions:
|
|||||||
totalCount:
|
totalCount:
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
dto.SSHLogAnalysis:
|
||||||
|
properties:
|
||||||
|
address:
|
||||||
|
type: string
|
||||||
|
area:
|
||||||
|
type: string
|
||||||
|
failedCount:
|
||||||
|
type: integer
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
successfulCount:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
dto.SSLUpdate:
|
dto.SSLUpdate:
|
||||||
properties:
|
properties:
|
||||||
cert:
|
cert:
|
||||||
@ -1875,6 +1888,16 @@ definitions:
|
|||||||
required:
|
required:
|
||||||
- ssl
|
- ssl
|
||||||
type: object
|
type: object
|
||||||
|
dto.SearchForAnalysis:
|
||||||
|
properties:
|
||||||
|
orderBy:
|
||||||
|
enum:
|
||||||
|
- Success
|
||||||
|
- Failed
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- orderBy
|
||||||
|
type: object
|
||||||
dto.SearchForTree:
|
dto.SearchForTree:
|
||||||
properties:
|
properties:
|
||||||
info:
|
info:
|
||||||
@ -1989,6 +2012,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
complexityVerification:
|
complexityVerification:
|
||||||
type: string
|
type: string
|
||||||
|
defaultNetwork:
|
||||||
|
type: string
|
||||||
dingVars:
|
dingVars:
|
||||||
type: string
|
type: string
|
||||||
email:
|
email:
|
||||||
@ -3089,6 +3114,8 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
resource:
|
resource:
|
||||||
type: string
|
type: string
|
||||||
|
source:
|
||||||
|
type: string
|
||||||
type:
|
type:
|
||||||
type: string
|
type: string
|
||||||
version:
|
version:
|
||||||
@ -3128,6 +3155,8 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
rebuild:
|
rebuild:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
source:
|
||||||
|
type: string
|
||||||
version:
|
version:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
@ -7804,7 +7833,7 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Update host ssh setting by file
|
summary: Update host SSH setting by file
|
||||||
tags:
|
tags:
|
||||||
- SSH
|
- SSH
|
||||||
x-panel-log:
|
x-panel-log:
|
||||||
@ -7815,20 +7844,20 @@ paths:
|
|||||||
paramKeys: []
|
paramKeys: []
|
||||||
/host/ssh/conf:
|
/host/ssh/conf:
|
||||||
get:
|
get:
|
||||||
description: 获取 ssh 配置文件
|
description: 获取 SSH 配置文件
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Load host ssh conf
|
summary: Load host SSH conf
|
||||||
tags:
|
tags:
|
||||||
- SSH
|
- SSH
|
||||||
/host/ssh/generate:
|
/host/ssh/generate:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: 生成 ssh 密钥
|
description: 生成 SSH 密钥
|
||||||
parameters:
|
parameters:
|
||||||
- description: request
|
- description: request
|
||||||
in: body
|
in: body
|
||||||
@ -7841,7 +7870,7 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Generate host ssh secret
|
summary: Generate host SSH secret
|
||||||
tags:
|
tags:
|
||||||
- SSH
|
- SSH
|
||||||
x-panel-log:
|
x-panel-log:
|
||||||
@ -7850,11 +7879,11 @@ paths:
|
|||||||
formatEN: generate SSH secret
|
formatEN: generate SSH secret
|
||||||
formatZH: '生成 SSH 密钥 '
|
formatZH: '生成 SSH 密钥 '
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
/host/ssh/logs:
|
/host/ssh/log:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: 获取 ssh 登录日志
|
description: 获取 SSH 登录日志
|
||||||
parameters:
|
parameters:
|
||||||
- description: request
|
- description: request
|
||||||
in: body
|
in: body
|
||||||
@ -7869,7 +7898,31 @@ paths:
|
|||||||
$ref: '#/definitions/dto.SSHLog'
|
$ref: '#/definitions/dto.SSHLog'
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Load host ssh logs
|
summary: Load host SSH logs
|
||||||
|
tags:
|
||||||
|
- SSH
|
||||||
|
/host/ssh/log/analysis:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 分析 SSH 登录日志
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.SearchForAnalysis'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/dto.SSHLogAnalysis'
|
||||||
|
type: array
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Analysis host SSH logs
|
||||||
tags:
|
tags:
|
||||||
- SSH
|
- SSH
|
||||||
/host/ssh/operate:
|
/host/ssh/operate:
|
||||||
@ -7887,7 +7940,7 @@ paths:
|
|||||||
responses: {}
|
responses: {}
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Operate ssh
|
summary: Operate SSH
|
||||||
tags:
|
tags:
|
||||||
- SSH
|
- SSH
|
||||||
x-panel-log:
|
x-panel-log:
|
||||||
@ -7907,14 +7960,14 @@ paths:
|
|||||||
$ref: '#/definitions/dto.SSHInfo'
|
$ref: '#/definitions/dto.SSHInfo'
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Load host ssh setting info
|
summary: Load host SSH setting info
|
||||||
tags:
|
tags:
|
||||||
- SSH
|
- SSH
|
||||||
/host/ssh/secret:
|
/host/ssh/secret:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: 获取 ssh 密钥
|
description: 获取 SSH 密钥
|
||||||
parameters:
|
parameters:
|
||||||
- description: request
|
- description: request
|
||||||
in: body
|
in: body
|
||||||
@ -7927,7 +7980,7 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Load host ssh secret
|
summary: Load host SSH secret
|
||||||
tags:
|
tags:
|
||||||
- SSH
|
- SSH
|
||||||
/host/ssh/update:
|
/host/ssh/update:
|
||||||
@ -7947,7 +8000,7 @@ paths:
|
|||||||
description: OK
|
description: OK
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Update host ssh setting
|
summary: Update host SSH setting
|
||||||
tags:
|
tags:
|
||||||
- SSH
|
- SSH
|
||||||
x-panel-log:
|
x-panel-log:
|
||||||
|
@ -141,6 +141,13 @@ export namespace Host {
|
|||||||
successfulCount: number;
|
successfulCount: number;
|
||||||
failedCount: number;
|
failedCount: number;
|
||||||
}
|
}
|
||||||
|
export interface logAnalysis {
|
||||||
|
address: string;
|
||||||
|
area: string;
|
||||||
|
successfulCount: number;
|
||||||
|
failedCount: number;
|
||||||
|
status: string;
|
||||||
|
}
|
||||||
export interface sshHistory {
|
export interface sshHistory {
|
||||||
date: Date;
|
date: Date;
|
||||||
area: string;
|
area: string;
|
||||||
|
@ -123,3 +123,6 @@ export const loadSecret = (mode: string) => {
|
|||||||
export const loadSSHLogs = (params: Host.searchSSHLog) => {
|
export const loadSSHLogs = (params: Host.searchSSHLog) => {
|
||||||
return http.post<Host.sshLog>(`/hosts/ssh/log`, params);
|
return http.post<Host.sshLog>(`/hosts/ssh/log`, params);
|
||||||
};
|
};
|
||||||
|
export const loadAnalysis = (orderBy: string) => {
|
||||||
|
return http.post<Array<Host.logAnalysis>>(`/hosts/ssh/log/analysis`, { orderBy: orderBy }, TimeoutEnum.T_40S);
|
||||||
|
};
|
||||||
|
@ -221,7 +221,9 @@ const message = {
|
|||||||
upgrading: 'Upgrading',
|
upgrading: 'Upgrading',
|
||||||
upgradeerr: 'Upgrade Error',
|
upgradeerr: 'Upgrade Error',
|
||||||
pullerr: 'Pull Image Error',
|
pullerr: 'Pull Image Error',
|
||||||
rebuilding: '重建中',
|
rebuilding: 'ReBuilding',
|
||||||
|
deny: 'Denied',
|
||||||
|
accept: 'Accepted',
|
||||||
},
|
},
|
||||||
units: {
|
units: {
|
||||||
second: 'Second',
|
second: 'Second',
|
||||||
@ -950,6 +952,14 @@ const message = {
|
|||||||
useDNS: 'useDNS',
|
useDNS: 'useDNS',
|
||||||
dnsHelper:
|
dnsHelper:
|
||||||
'Controls whether the DNS resolution function is enabled on the SSH server to verify the identity of the connection.',
|
'Controls whether the DNS resolution function is enabled on the SSH server to verify the identity of the connection.',
|
||||||
|
analysis: 'Statistical information',
|
||||||
|
denyHelper:
|
||||||
|
"Performing a 'deny' operation on the following addresses. After setting, the IP will be prohibited from accessing the server. Do you want to continue?",
|
||||||
|
acceptHelper:
|
||||||
|
"Performing an 'accept' operation on the following addresses. After setting, the IP will regain normal access. Do you want to continue?",
|
||||||
|
noAddrWarning: 'No [{0}] addresses are currently selected. Please check and try again!',
|
||||||
|
successful: 'Success',
|
||||||
|
failed: 'Failed',
|
||||||
loginLogs: 'SSH login log',
|
loginLogs: 'SSH login log',
|
||||||
loginMode: 'Login mode',
|
loginMode: 'Login mode',
|
||||||
authenticating: 'Key',
|
authenticating: 'Key',
|
||||||
|
@ -220,6 +220,8 @@ const message = {
|
|||||||
upgradeerr: '升級失敗',
|
upgradeerr: '升級失敗',
|
||||||
pullerr: '鏡像拉取失敗',
|
pullerr: '鏡像拉取失敗',
|
||||||
rebuilding: '重建中',
|
rebuilding: '重建中',
|
||||||
|
deny: '已屏蔽',
|
||||||
|
accept: '已放行',
|
||||||
},
|
},
|
||||||
units: {
|
units: {
|
||||||
second: '秒',
|
second: '秒',
|
||||||
@ -912,6 +914,12 @@ const message = {
|
|||||||
keyAuthHelper: '是否啟用密鑰認證,默認啟用。',
|
keyAuthHelper: '是否啟用密鑰認證,默認啟用。',
|
||||||
useDNS: '反向解析',
|
useDNS: '反向解析',
|
||||||
dnsHelper: '控製 SSH 服務器是否啟用 DNS 解析功能,從而驗證連接方的身份。',
|
dnsHelper: '控製 SSH 服務器是否啟用 DNS 解析功能,從而驗證連接方的身份。',
|
||||||
|
analysis: '統計信息',
|
||||||
|
denyHelper: '將對下列地址進行【屏蔽】操作,設置後該 IP 將禁止訪問服務器,是否繼續?',
|
||||||
|
acceptHelper: '將對下列地址進行【放行】操作,設置後該 IP 將恢復正常訪問,是否繼續?',
|
||||||
|
noAddrWarning: '當前未選中任何可【{0}】地址,請檢查後重試!',
|
||||||
|
successful: '成功',
|
||||||
|
failed: '失敗',
|
||||||
loginLogs: 'SSH 登錄日誌',
|
loginLogs: 'SSH 登錄日誌',
|
||||||
loginMode: '登錄方式',
|
loginMode: '登錄方式',
|
||||||
authenticating: '密鑰',
|
authenticating: '密鑰',
|
||||||
|
@ -220,6 +220,8 @@ const message = {
|
|||||||
upgradeerr: '升级失败',
|
upgradeerr: '升级失败',
|
||||||
pullerr: '镜像拉取失败',
|
pullerr: '镜像拉取失败',
|
||||||
rebuilding: '重建中',
|
rebuilding: '重建中',
|
||||||
|
deny: '已屏蔽',
|
||||||
|
accept: '已放行',
|
||||||
},
|
},
|
||||||
units: {
|
units: {
|
||||||
second: '秒',
|
second: '秒',
|
||||||
@ -912,6 +914,12 @@ const message = {
|
|||||||
keyAuthHelper: '是否启用密钥认证,默认启用。',
|
keyAuthHelper: '是否启用密钥认证,默认启用。',
|
||||||
useDNS: '反向解析',
|
useDNS: '反向解析',
|
||||||
dnsHelper: '控制 SSH 服务器是否启用 DNS 解析功能,从而验证连接方的身份。',
|
dnsHelper: '控制 SSH 服务器是否启用 DNS 解析功能,从而验证连接方的身份。',
|
||||||
|
analysis: '统计信息',
|
||||||
|
denyHelper: '将对下列地址进行【屏蔽】操作,设置后该 IP 将禁止访问服务器,是否继续?',
|
||||||
|
acceptHelper: '将对下列地址进行【放行】操作,设置后该 IP 将恢复正常访问,是否继续?',
|
||||||
|
noAddrWarning: '当前未选中任何可【{0}】地址,请检查后重试!',
|
||||||
|
successful: '成功',
|
||||||
|
failed: '失败',
|
||||||
loginLogs: '登录日志',
|
loginLogs: '登录日志',
|
||||||
loginMode: '登录方式',
|
loginMode: '登录方式',
|
||||||
authenticating: '密钥',
|
authenticating: '密钥',
|
||||||
|
244
frontend/src/views/host/ssh/log/analysis/index.vue
Normal file
244
frontend/src/views/host/ssh/log/analysis/index.vue
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-drawer v-model="drawerVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%">
|
||||||
|
<template #header>
|
||||||
|
<DrawerHeader :header="$t('menu.home')" :back="handleClose" />
|
||||||
|
</template>
|
||||||
|
<div v-loading="loading">
|
||||||
|
<el-form label-position="top" class="ml-5">
|
||||||
|
<el-row type="flex" justify="center" :gutter="20">
|
||||||
|
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
|
<el-form-item>
|
||||||
|
<template #label>
|
||||||
|
<span class="status-label">{{ $t('ssh.successful') }}</span>
|
||||||
|
</template>
|
||||||
|
<span class="status-count">{{ successfulTotalCount }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
|
||||||
|
<el-form-item>
|
||||||
|
<template #label>
|
||||||
|
<span class="status-label">{{ $t('ssh.failed') }}</span>
|
||||||
|
</template>
|
||||||
|
<span class="status-count">{{ failedTotalCount }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-button type="primary" @click="onChangeStatus('accept', null)" :disabled="selects.length === 0">
|
||||||
|
{{ $t('firewall.allow') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" @click="onChangeStatus('drop', null)" :disabled="selects.length === 0">
|
||||||
|
{{ $t('firewall.deny') }}
|
||||||
|
</el-button>
|
||||||
|
<ComplexTable v-model:selects="selects" class="mt-5" :data="data" @header-click="changeSort">
|
||||||
|
<el-table-column type="selection" fix :selectable="selectable" />
|
||||||
|
<el-table-column :label="$t('logs.loginIP')" prop="address" min-width="40" />
|
||||||
|
<el-table-column :label="$t('ssh.belong')" prop="area" min-width="40" />
|
||||||
|
<el-table-column prop="successfulCount" min-width="20">
|
||||||
|
<template #header>
|
||||||
|
{{ $t('ssh.successful') }}
|
||||||
|
<el-icon style="cursor: pointer" @click="search('Success')"><CaretBottom /></el-icon>
|
||||||
|
</template>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" link>{{ row.successfulCount }}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="failedCount" min-width="20">
|
||||||
|
<template #header>
|
||||||
|
{{ $t('ssh.failed') }}
|
||||||
|
<el-icon style="cursor: pointer" @click="search('Failed')"><CaretBottom /></el-icon>
|
||||||
|
</template>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button type="danger" link>{{ row.failedCount }}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :min-width="30" :label="$t('commons.table.status')" prop="strategy">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button
|
||||||
|
v-if="row.status === 'accept'"
|
||||||
|
:disabled="!selectable(row)"
|
||||||
|
@click="onChangeStatus('drop', row)"
|
||||||
|
link
|
||||||
|
type="success"
|
||||||
|
>
|
||||||
|
{{ $t('commons.status.accept') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
link
|
||||||
|
:disabled="!selectable(row)"
|
||||||
|
type="danger"
|
||||||
|
@click="onChangeStatus('accept', row)"
|
||||||
|
>
|
||||||
|
{{ $t('commons.status.deny') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ComplexTable>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="drawerVisiable = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="$t('firewall.' + (operation === 'drop' ? 'deny' : 'allow'))"
|
||||||
|
width="30%"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="20" :offset="2">
|
||||||
|
<el-alert :title="msg" show-icon type="error" :closable="false"></el-alert>
|
||||||
|
<div class="resource">
|
||||||
|
<table>
|
||||||
|
<tr v-for="(row, index) in operationList" :key="index">
|
||||||
|
<td>
|
||||||
|
<span>{{ row }}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false" :disabled="loading">
|
||||||
|
{{ $t('commons.button.cancel') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" @click="submitOperation" v-loading="loading">
|
||||||
|
{{ $t('commons.button.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
|
import { loadAnalysis, operateIPRule } from '@/api/modules/host';
|
||||||
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
import { Host } from '@/api/interface/host';
|
||||||
|
|
||||||
|
const drawerVisiable = ref();
|
||||||
|
const loading = ref();
|
||||||
|
const data = ref();
|
||||||
|
const successfulTotalCount = ref();
|
||||||
|
const failedTotalCount = ref();
|
||||||
|
const selects = ref<any>([]);
|
||||||
|
|
||||||
|
const dialogVisible = ref();
|
||||||
|
const msg = ref();
|
||||||
|
const operation = ref();
|
||||||
|
const operationList = ref();
|
||||||
|
|
||||||
|
const acceptParams = (): void => {
|
||||||
|
search('Failed');
|
||||||
|
drawerVisiable.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const search = async (status: string) => {
|
||||||
|
loading.value = true;
|
||||||
|
loadAnalysis(status)
|
||||||
|
.then((res) => {
|
||||||
|
loading.value = false;
|
||||||
|
data.value = res.data || [];
|
||||||
|
successfulTotalCount.value = 0;
|
||||||
|
failedTotalCount.value = 0;
|
||||||
|
for (const item of data.value) {
|
||||||
|
successfulTotalCount.value += item.successfulCount;
|
||||||
|
failedTotalCount.value += item.failedCount;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function selectable(row: any): boolean {
|
||||||
|
return row.address !== '127.0.0.1' && row.address !== '::1';
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeSort = (column: any) => {
|
||||||
|
switch (column.property) {
|
||||||
|
case 'successfulCount':
|
||||||
|
search('Success');
|
||||||
|
return;
|
||||||
|
case 'failedCount':
|
||||||
|
search('Failed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChangeStatus = async (status: string, row: Host.logAnalysis | null) => {
|
||||||
|
operationList.value = [];
|
||||||
|
if (row) {
|
||||||
|
if (row.status !== status) {
|
||||||
|
operationList.value.push(row.address);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const item of selects.value) {
|
||||||
|
if (item.status !== status) {
|
||||||
|
operationList.value.push(item.address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (operationList.value.length === 0) {
|
||||||
|
MsgError(
|
||||||
|
i18n.global.t('ssh.noAddrWarning', [i18n.global.t('firewall.' + (status === 'drop' ? 'deny' : 'allow'))]),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
operation.value = status;
|
||||||
|
msg.value = status === 'drop' ? i18n.global.t('ssh.denyHelper') : i18n.global.t('ssh.acceptHelper');
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitOperation = async () => {
|
||||||
|
const pros = [];
|
||||||
|
for (const item of operationList.value) {
|
||||||
|
pros.push(
|
||||||
|
operateIPRule({
|
||||||
|
operation: operation.value === 'drop' ? 'add' : 'remove',
|
||||||
|
address: item,
|
||||||
|
strategy: 'drop',
|
||||||
|
description: '',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
loading.value = true;
|
||||||
|
Promise.all(pros)
|
||||||
|
.then(() => {
|
||||||
|
loading.value = false;
|
||||||
|
dialogVisible.value = false;
|
||||||
|
search('Failed');
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
drawerVisiable.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.resource {
|
||||||
|
margin-top: 10px;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
@ -4,23 +4,24 @@
|
|||||||
<template #prompt>
|
<template #prompt>
|
||||||
<el-alert type="info" :title="$t('ssh.sshAlert')" :closable="false" />
|
<el-alert type="info" :title="$t('ssh.sshAlert')" :closable="false" />
|
||||||
</template>
|
</template>
|
||||||
|
<template #search>
|
||||||
|
<el-select v-model="searchStatus" @change="search()">
|
||||||
|
<template #prefix>{{ $t('commons.table.status') }}</template>
|
||||||
|
<el-option :label="$t('commons.table.all')" value="All"></el-option>
|
||||||
|
<el-option :label="$t('commons.status.success')" value="Success"></el-option>
|
||||||
|
<el-option :label="$t('commons.status.failed')" value="Failed"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
<template #toolbar>
|
<template #toolbar>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :xs="24" :sm="16" :md="16" :lg="16" :xl="16">
|
<el-col :xs="24" :sm="16" :md="16" :lg="16" :xl="16">
|
||||||
<el-select v-model="searchStatus" @change="search()">
|
<el-button
|
||||||
<template #prefix>{{ $t('commons.table.status') }}</template>
|
type="primary"
|
||||||
<el-option :label="$t('commons.table.all')" value="All"></el-option>
|
@click="onLoadAnalysis"
|
||||||
<el-option :label="$t('commons.status.success')" value="Success"></el-option>
|
:disabled="data?.length === 0"
|
||||||
<el-option :label="$t('commons.status.failed')" value="Failed"></el-option>
|
style="margin-left: 5px"
|
||||||
</el-select>
|
>
|
||||||
<el-tag v-if="searchStatus === 'All'" type="success" size="large" style="margin-left: 15px">
|
{{ $t('ssh.analysis') }}
|
||||||
{{ $t('commons.status.success') }}: {{ successfulCount }}
|
|
||||||
</el-tag>
|
|
||||||
<el-tag v-if="searchStatus === 'All'" type="danger" size="large" style="margin-left: 5px">
|
|
||||||
{{ $t('commons.status.failed') }}: {{ faliedCount }}
|
|
||||||
</el-tag>
|
|
||||||
<el-button plain @click="onDeny" :disabled="selects.length === 0" style="margin-left: 5px">
|
|
||||||
{{ $t('firewall.deny') }}
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
|
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8">
|
||||||
@ -41,13 +42,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #main>
|
<template #main>
|
||||||
<ComplexTable
|
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search">
|
||||||
:pagination-config="paginationConfig"
|
|
||||||
v-model:selects="selects"
|
|
||||||
:data="data"
|
|
||||||
@search="search"
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" :selectable="selectable" fix />
|
|
||||||
<el-table-column min-width="80" :label="$t('logs.loginIP')" prop="address" />
|
<el-table-column min-width="80" :label="$t('logs.loginIP')" prop="address" />
|
||||||
<el-table-column min-width="60" :label="$t('ssh.belong')" prop="area" />
|
<el-table-column min-width="60" :label="$t('ssh.belong')" prop="area" />
|
||||||
<el-table-column min-width="60" :label="$t('commons.table.port')" prop="port" />
|
<el-table-column min-width="60" :label="$t('commons.table.port')" prop="port" />
|
||||||
@ -78,6 +73,8 @@
|
|||||||
</ComplexTable>
|
</ComplexTable>
|
||||||
</template>
|
</template>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
|
|
||||||
|
<Analysis ref="analysisRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -86,9 +83,7 @@ import TableSetting from '@/components/table-setting/index.vue';
|
|||||||
import { dateFormat } from '@/utils/util';
|
import { dateFormat } from '@/utils/util';
|
||||||
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
import { onMounted, reactive, ref } from '@vue/runtime-core';
|
||||||
import { loadSSHLogs } from '@/api/modules/host';
|
import { loadSSHLogs } from '@/api/modules/host';
|
||||||
import { operateIPRule } from '@/api/modules/host';
|
import Analysis from '@/views/host/ssh/log/analysis/index.vue';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
|
||||||
import i18n from '@/lang';
|
|
||||||
|
|
||||||
const loading = ref();
|
const loading = ref();
|
||||||
const data = ref();
|
const data = ref();
|
||||||
@ -100,29 +95,10 @@ const paginationConfig = reactive({
|
|||||||
});
|
});
|
||||||
const searchInfo = ref();
|
const searchInfo = ref();
|
||||||
const searchStatus = ref('All');
|
const searchStatus = ref('All');
|
||||||
const successfulCount = ref(0);
|
const analysisRef = ref();
|
||||||
const faliedCount = ref(0);
|
|
||||||
const selects = ref<any>([]);
|
|
||||||
|
|
||||||
function selectable(row: any): boolean {
|
const onLoadAnalysis = () => {
|
||||||
return row.address !== '127.0.0.1' && row.address !== '::1';
|
analysisRef.value.acceptParams();
|
||||||
}
|
|
||||||
|
|
||||||
function select2address(): string {
|
|
||||||
let res = [];
|
|
||||||
selects.value.forEach((item: any) => {
|
|
||||||
if (!res.includes(item.address)) res.push(item.address);
|
|
||||||
});
|
|
||||||
return res.join(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
const onDeny = async () => {
|
|
||||||
let address = select2address();
|
|
||||||
if (!address) return;
|
|
||||||
await operateIPRule({ operation: 'add', address: address, strategy: 'drop', description: '' }).then(() => {
|
|
||||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
|
||||||
search();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const search = async () => {
|
const search = async () => {
|
||||||
@ -137,8 +113,6 @@ const search = async () => {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
data.value = res.data?.logs || [];
|
data.value = res.data?.logs || [];
|
||||||
faliedCount.value = res.data.failedCount;
|
|
||||||
successfulCount.value = res.data.successfulCount;
|
|
||||||
if (searchStatus.value === 'Success') {
|
if (searchStatus.value === 'Success') {
|
||||||
paginationConfig.total = res.data.successfulCount;
|
paginationConfig.total = res.data.successfulCount;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,6 @@ const formRef = ref<FormInstance>();
|
|||||||
|
|
||||||
const acceptParams = (params: DialogProps): void => {
|
const acceptParams = (params: DialogProps): void => {
|
||||||
form.defaultNetwork = params.defaultNetwork;
|
form.defaultNetwork = params.defaultNetwork;
|
||||||
console.log(form.defaultNetwork);
|
|
||||||
loadNetworkOptions();
|
loadNetworkOptions();
|
||||||
drawerVisiable.value = true;
|
drawerVisiable.value = true;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user