Commit b4a22d18 authored by 黄智's avatar 黄智

Merge remote-tracking branch 'origin/dev' into dev

parents 0faaf323 44c265e1
......@@ -42,10 +42,13 @@ require (
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/goccy/go-json v0.10.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/henrylee2cn/ameda v1.5.0 // indirect
github.com/henrylee2cn/goutil v0.0.0-20220704075712-42f2ec55fe8d // indirect
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
......@@ -62,6 +65,7 @@ require (
github.com/nyaruka/phonenumbers v1.1.7 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.66.0 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/sirupsen/logrus v1.9.2 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
......@@ -75,11 +79,16 @@ require (
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.27.2 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect
)
This diff is collapsed.
......@@ -4,7 +4,6 @@ type AddHostManageReq struct {
HostName string `json:"host_name" binding:"required"` // 主机分组名称
HostFileUrl string `json:"host_file_url"` // 主机文件url
Uuid string `json:"uuid"` //临时缓存uuid
//HostManageList []HostManageList `json:"host_manage_list"` //主机列表
}
type HostManageList struct {
......@@ -20,11 +19,10 @@ type EditHostManageReq struct {
Id int `json:"id" binding:"required"` // 主键ID
HostFileUrl string `json:"host_file_url"` // 主机文件url
Uuid string `json:"uuid"` //临时缓存uuid
//HostManageList []HostManageList `json:"host_manage_list"` //主机列表
}
type DelHostManageReq struct {
Id []int `json:"id" vd:"len($)>0;msg:'请输入id'"` // 主键ID
Id []int `json:"id" binding:"required"` // 主键ID
}
type ListHostManageReq struct {
......
package request
type AddTaskManageReq struct {
TaskName string `json:"task_name" vd:"len($)>0;msg:'请输入任务名称'"` // 任务名称
TaskDesc string `json:"task_desc"` // 任务描述
YamlDesc string `json:"yaml_desc"` // yaml内容
YamlUrl string `json:"yaml_url"` // yaml文件url
HostGroupId int `json:"host_group_id" vd:"$>0;msg:'请选择主机分组'"` // 主机分组ID
TaskName string `json:"task_name" binding:"required"` // 任务名称
TaskDesc string `json:"task_desc"` // 任务描述
YamlDesc string `json:"yaml_desc"` // yaml内容
YamlUrl string `json:"yaml_url"` // yaml文件url
HostGroupId int `json:"host_group_id" binding:"required"` // 主机分组ID
}
type EditTaskManageReq struct {
Id int `json:"id" vd:"$>0;msg:'请输入id'"` // 主键ID
TaskDesc string `json:"task_desc"` // 任务描述
YamlDesc string `json:"yaml_desc"` // yaml内容
YamlUrl string `json:"yaml_url"` // yaml文件url
HostGroupId int `json:"host_group_id" vd:"$>0;msg:'请选择主机分组'"` // 主机分组ID
Id int `json:"id" binding:"required"` // 主键ID
TaskDesc string `json:"task_desc"` // 任务描述
YamlDesc string `json:"yaml_desc"` // yaml内容
YamlUrl string `json:"yaml_url"` // yaml文件url
HostGroupId int `json:"host_group_id" binding:"required"` // 主机分组ID
}
type DelTaskManageReq struct {
Id []int `json:"id" vd:"len($)>0;msg:'请输入id'"` // 主键ID
}
type DetailsTaskManageReq struct {
Id int `json:"id" vd:"$>0;msg:'请输入id'"` // 主键ID
Id []int `json:"id" binding:"required"` // 主键ID
}
type ListTaskManageReq struct {
......@@ -33,10 +29,7 @@ type ListTaskManageReq struct {
}
type ExecScriptReq struct {
TaskId int `form:"task_id" binding:"required"` //任务id
//HostGroupId int `form:"host_group_id" binding:"required"` //主机分组id
Type int `form:"type"` //脚本额外变量类型1yaml 2json
Value string `form:"value"` //脚本额外变量值
//Script string `form:"script"` //执行脚本
//YmlFileName string `form:"yml_file_name"` //执行脚本url
TaskId int `form:"task_id" binding:"required"` //任务id
Type int `form:"type"` //脚本额外变量类型1yaml 2json
Value string `form:"value"` //脚本额外变量值
}
......@@ -43,6 +43,9 @@ type Config struct {
SmsAccessSecret string
SmsTemplateLogin string
SmsSignName string
AweRestURL string
KubernetesToken string
}
const (
......
......@@ -10,53 +10,8 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
)
// ParsingHostFiles 解析主机文件
func ParsingHostFiles(c *gin.Context) (hostManageList []request.HostManageList, err error) {
//获取文件流
metaData, _, err := c.Request.FormFile("host_file")
if err != nil {
err = resp.GetFileStreamError.WithError(err)
return
}
xlsxData, err := excelize.OpenReader(metaData)
if err != nil {
err = resp.ReadFileError.WithError(err)
return
}
//读取工作簿
rows := xlsxData.GetRows("Sheet1")
if len(rows) > 1001 {
err = resp.FailedToParseFile.WithError(errors.New("ip数量不可超过1000"))
return
}
for i := 0; i < len(rows); i++ {
//默认跳过第一行
if i < 1 {
continue
}
var voucherType int
if rows[i][2] == "密码验证" {
voucherType = 0
} else {
voucherType = 1
}
hostManageList = append(hostManageList, request.HostManageList{
Ip: rows[i][0],
Port: rows[i][1],
VoucherType: voucherType,
UserName: rows[i][3],
Password: rows[i][4],
})
}
return
}
// GetMinioFiles 解析minio中xlsx类型文件
func GetMinioFiles(fileName string) (hostManageList []request.HostManageList, err error) {
......@@ -110,7 +65,7 @@ func AddHostManage(c *gin.Context) {
err error
)
if err = c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -119,20 +74,6 @@ func AddHostManage(c *gin.Context) {
SendJsonResponse(c, resp.InvalidParam.WithError(errors.New("主机分组名称为空")), nil)
return
}
//if len(req.HostManageList) == 0 {
// SendJsonResponse(c, resp.InvalidParam.WithError(errors.New("主机分组数量为0")), nil)
// return
//}
//for _, v := range req.HostManageList {
// if v.Ip == "" || v.UserName == "" {
// SendJsonResponse(c, resp.InvalidParam.WithError(errors.New("ip或用户名为空")), nil)
// return
// }
// if v.VoucherType == 0 && v.Password == "" {
// SendJsonResponse(c, resp.InvalidParam.WithError(errors.New("密码为空")), nil)
// return
// }
//}
hostManageSvc := service.HostManageSvc{User: header.GetUser(c)}
err = hostManageSvc.AddHostManage(req)
......@@ -150,26 +91,10 @@ func EditHostManage(c *gin.Context) {
err error
)
if err = c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
//参数校验
//if len(req.HostManageList) == 0 {
// SendJsonResponse(c, resp.InvalidParam.WithError(errors.New("主机分组数量为0")), nil)
// return
//}
//for _, v := range req.HostManageList {
// if v.Ip == "" || v.UserName == "" {
// SendJsonResponse(c, resp.InvalidParam.WithError(errors.New("ip或用户名为空")), nil)
// return
// }
// if v.VoucherType == 0 && v.Password == "" {
// SendJsonResponse(c, resp.InvalidParam.WithError(errors.New("密码为空")), nil)
// return
// }
//}
hostManageSvc := service.HostManageSvc{User: header.GetUser(c)}
err = hostManageSvc.EditHostManage(req)
if err != nil {
......@@ -183,12 +108,7 @@ func EditHostManage(c *gin.Context) {
func DelHostManage(c *gin.Context) {
var req request.DelHostManageReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
//参数校验
if err := util.ValidateSimple(req, "Id"); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -229,7 +149,7 @@ func DetailsHostManage(c *gin.Context) {
func PageListHostManage(c *gin.Context) {
var req request.ListHostManageReq
if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -249,7 +169,7 @@ func StateHostManage(c *gin.Context) {
err error
)
if err = c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -283,9 +203,7 @@ func StateHostManage(c *gin.Context) {
}
case 3:
//解析主机文件
//hostManageList, err = ParsingHostFiles(c)
hostManageList, err = GetMinioFiles(req.FileName)
if err != nil {
SendJsonResponse(c, resp.ReadFileError.WithError(errors.New("解析主机文件失败")), nil)
return
......@@ -325,7 +243,7 @@ func StateHostManage(c *gin.Context) {
func HostIpExceptionList(c *gin.Context) {
var req request.HostIpExceptionListReq
if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -361,7 +279,7 @@ func HostIpExceptionList(c *gin.Context) {
}
}
// 导出
// ExportIp 导出
func ExportIp(c *gin.Context) {
detectionType := c.Query("detection_type")
id := c.Query("id")
......
......@@ -13,7 +13,7 @@ import (
func TaskHistoryList(c *gin.Context) {
var req request.TaskHistoryReq
if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -30,7 +30,7 @@ func TaskHistoryList(c *gin.Context) {
func TaskInfoList(c *gin.Context) {
var req request.TaskInfoListReq
if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......
......@@ -14,7 +14,6 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"io"
"strings"
)
......@@ -23,12 +22,7 @@ import (
func AddTaskManage(c *gin.Context) {
var req request.AddTaskManageReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
//参数校验
if err := util.ValidateSimple(req, "TaskName,HostGroupId"); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -45,12 +39,7 @@ func AddTaskManage(c *gin.Context) {
func EditTaskManage(c *gin.Context) {
var req request.EditTaskManageReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
//参数校验
if err := util.ValidateSimple(req, "Id,HostGroupId"); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -67,12 +56,7 @@ func EditTaskManage(c *gin.Context) {
func DelTaskManage(c *gin.Context) {
var req request.DelTaskManageReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
//参数校验
if err := util.ValidateSimple(req, "Id"); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -113,7 +97,7 @@ func DetailsTaskManage(c *gin.Context) {
func ListTaskManage(c *gin.Context) {
var req request.ListTaskManageReq
if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -132,7 +116,7 @@ func ExecScript(c *gin.Context) {
err error
)
if err = c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......
......@@ -15,7 +15,7 @@ import (
func AddWorkOrderManage(c *gin.Context) {
var req request.AddWorkOrderReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -32,7 +32,7 @@ func AddWorkOrderManage(c *gin.Context) {
func EditWorkOrderManage(c *gin.Context) {
var req request.EditWorkOrderReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
//参数校验
......@@ -54,7 +54,7 @@ func EditWorkOrderManage(c *gin.Context) {
func StateWorkOrderManage(c *gin.Context) {
var req request.StateWorkOrderReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
//参数校验
......@@ -76,7 +76,7 @@ func StateWorkOrderManage(c *gin.Context) {
func DelWorkOrderManage(c *gin.Context) {
var req request.DelWorkOrderReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
//参数校验
......@@ -122,7 +122,7 @@ func DetailsWorkOrderManage(c *gin.Context) {
func ListWorkOrderManage(c *gin.Context) {
var req request.ListWorkOrderManageReq
if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -139,7 +139,7 @@ func ListWorkOrderManage(c *gin.Context) {
func PushWorkOrderManage(c *gin.Context) {
var req request.PushWorkOrderReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -156,7 +156,7 @@ func PushWorkOrderManage(c *gin.Context) {
func CloseWorkOrderIssuance(c *gin.Context) {
var req request.CloseWorkOrderReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -173,7 +173,7 @@ func CloseWorkOrderIssuance(c *gin.Context) {
func ListWorkOrderIssuance(c *gin.Context) {
var req request.ListWorkOrderReq
if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -214,7 +214,7 @@ func DetailsWorkOrderIssuance(c *gin.Context) {
func FeedbackWorkOrderMe(c *gin.Context) {
var req request.FeedbackWorkOrderReq
if err := c.ShouldBindJSON(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -231,7 +231,7 @@ func FeedbackWorkOrderMe(c *gin.Context) {
func ListWorkOrderMe(c *gin.Context) {
var req request.ListWorkOrderReq
if err := c.ShouldBind(&req); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil)
return
}
......@@ -244,7 +244,7 @@ func ListWorkOrderMe(c *gin.Context) {
SendJsonPageResponse(c, resp.OK, list, total)
}
// WorkOrderPushNoteMsg 我的业务工单列表
// WorkOrderPushNoteMsg 推送短信
func WorkOrderPushNoteMsg(c *gin.Context) {
phone := c.Query("phone")
......
......@@ -80,10 +80,12 @@ func initConfig() {
//PublicKeySSH: util.SetEnvStr("PUBLIC_KEY_SSH", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCw4WT05QHzCD19348MfJfycS1NI9Jlj62PGrZ1rU9/kWQif5TV1rqHZ6qjAX2WfK+W3u4SV51MhZBkMZZOgZgJmdGiaZJkSmj+8gj6XU/bxslUd+BYUKqbE18gFkVDgqs6n2tcqJ2at3x+WEr81Msk2qvKuGEiIOzcJPICWKxwiw== chenzilong@example.com\n"),
OrderDingTalkAccessToken: util.SetEnvStr("ORDER_DING_TALK_ACCESS_TOKEN", "203fe1644b446bba0a34e6e622c523d39ee9916fdad94b9c64224449f659e20b"),
OrderDingTalkSecret: util.SetEnvStr("ORDER_DING_TALK_SECRET", "SECa73d8372e336451c9daf29a99f750ee1bdd170c1dab910eab9cd06d729a831b7"),
SmsAccessKeyId: util.SetEnvStr("SMS_ACCESS_KEY", "LTAI4GBcVubRjzX7ABPcHnhB"), // 短信key
SmsAccessSecret: util.SetEnvStr("SMS_ACCESS_SECRET", "dYE2dtABFOqYtK1ijcrits0yedHkw7"), // 短信secret
SmsTemplateLogin: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_212925130"), // 短信验证码模板
SmsSignName: util.SetEnvStr("SMS_SIGN_NAME", "比格数据"), // 签名
SmsAccessKeyId: util.SetEnvStr("SMS_ACCESS_KEY", "LTAI4GBcVubRjzX7ABPcHnhB"), // 短信key
SmsAccessSecret: util.SetEnvStr("SMS_ACCESS_SECRET", "dYE2dtABFOqYtK1ijcrits0yedHkw7"), // 短信secret
SmsTemplateLogin: util.SetEnvStr("SMS_TEMPLATE_LOGIN", "SMS_212925130"), // 短信验证码模板
SmsSignName: util.SetEnvStr("SMS_SIGN_NAME", "比格数据"), // 签名
AweRestURL: util.SetEnvStr("AWE_REST_URL", "http://awecloud-rest/awecloud/rest"), // awecloud-rest
KubernetesToken: util.SetEnvStr("AWE_REST_K8S_TOKEN", "eyJhbGciOiJSUzI1NiIsImtpZCI6InJ1alJzNEVGamN5UC0wRU1rS1BKQ0JZVUtNNWpzR0t2bmlrSlJhY2Q3R00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJiZWFnbGUtc3lzdGVtIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InJvb3QiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicm9vdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRlMDM0OTI3LTc0ZTMtNDQ5Yy1hN2RlLWExMGE3MjU1NGYyMCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpiZWFnbGUtc3lzdGVtOnJvb3QifQ.YPLE_E2kIeo-YFQtKScBt5p4KhnniJF9n3iWN2i9UMYS06lIsq2-2wBrgON-YsJihWJupYyDQRiZ9h8bUWTrQzhnpsnuJ_aUclKyAw3QOT9rjvZhJp7qP--27dmdspSHncKtvIiprWE7UTUKzvF33WsMB0fSYFqYXOggNFMoT-fXmWwUXjgar3op0iOl3c3deJ_GeBzFyLSHEuGM7OVdjU8032aUmTen0Kji_P1yB4-O3Iqd0OdVs33BQy_tycjbxhQ8TDEpqrqhLnXjAwJCprLDEpFMx7ODZbjB9Wmuns8yJhaRDxTO47rTME7ZIAxjZ-zLR_QybtW97rlwnUTaNw"), // k8s token
}
}
......
......@@ -122,3 +122,13 @@ var OpTypeIntMap = map[OpType]int{
DownMove: 13,
Export: 14,
}
// RiskLevel 风险等级
type RiskLevel int
const (
RiskLevelLow RiskLevel = iota + 1 // 1:低风险
RiskLevelModerate // 1:一般风险
RiskLevelHigh // 3:较大风险
RiskLevelCritical // 4:重大风险
)
......@@ -12,7 +12,7 @@ import (
func InitWorkOrderRouter(e *gin.Engine) {
so := e.Group(fmt.Sprintf("%s/work_order", conf.Options.Prefix))
//预警工单管理
alert := so.Group("/alert")
alert := so.Group("/alert", header.SetContext)
{
alert.GET("", controller.DetailAlertList) // 详情
alert.GET("/list", controller.ListAlertList) // 列表
......
......@@ -14,6 +14,7 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"os/exec"
"strings"
"sync"
"time"
)
......@@ -381,7 +382,7 @@ func (h *HostManageSvc) PageListHostManage(req request.ListHostManageReq) (total
"task_manage tm WHERE tm.is_delete = 0 AND tm.host_group_id = hm.ID) AS task_cnt,(SELECT COUNT(*) FROM "+
"host_manage_list hml WHERE hml.is_delete = 0 AND hml.conn_status = 1 AND hml.host_group_id = hm.ID) AS "+
"ip_cnt_err,(SELECT COUNT(*) FROM host_manage_list hml WHERE hml.is_delete = 0 AND hml.host_group_id = hm.ID) AS ip_cnt").
Limit(req.PageSize, (req.Page-1)*req.PageSize).FindAndCount(&hostManageListRes)
OrderBy("hm.create_time desc").Limit(req.PageSize, (req.Page-1)*req.PageSize).FindAndCount(&hostManageListRes)
if err != nil {
err = resp.DbSelectError.WithError(err)
return
......@@ -453,25 +454,66 @@ func (h *HostManageSvc) ListStateHostManage(req request.StateHostManageReq) (err
return
}
for _, v := range hostManageList {
//修改状态
connStatus, err1 := StatusDetection(v.Ip)
if err1 != nil {
session.Rollback()
return err1
}
hostManageListConn := entity.HostManageList{
ConnStatus: connStatus,
}
// 使用协程批量执行 ping 命令
var wg sync.WaitGroup
var lock sync.Mutex
wg.Add(len(hostManageList))
successHost := make([]int, 0)
fail := make([]int, 0)
for i := 0; i < len(hostManageList); i++ {
go func(i int) {
//检测ip连通性
connStatus := StatusDetection(hostManageList[i].Ip)
if connStatus == 1 {
lock.Lock()
fail = append(fail, hostManageList[i].Id)
lock.Unlock()
} else {
lock.Lock()
successHost = append(successHost, hostManageList[i].Id)
lock.Unlock()
}
defer wg.Done()
}(i)
}
wg.Wait()
_, err = session.Table("host_manage_list").Where("is_delete = 0 AND id = ?", v.Id).
Cols("conn_status").Update(&hostManageListConn)
if err != nil {
err = resp.DbUpdateError.WithError(err)
session.Rollback()
return
}
// 批量更新主机连接状态-成功
_, err = session.Table("host_manage_list").Where("is_delete = 0").In("id", successHost).
Cols("conn_status").Update(&entity.HostManageList{
ConnStatus: 0,
})
if err != nil {
err = resp.DbUpdateError.WithError(err)
session.Rollback()
return
}
// 批量更新主机连接状态-失败
_, err = session.Table("host_manage_list").Where("is_delete = 0").In("id", fail).
Cols("conn_status").Update(&entity.HostManageList{
ConnStatus: 1,
})
if err != nil {
err = resp.DbUpdateError.WithError(err)
session.Rollback()
return
}
//for _, v := range hostManageList {
// //修改状态
// connStatus := StatusDetection(v.Ip)
// hostManageListConn := entity.HostManageList{
// ConnStatus: connStatus,
// }
//
// _, err = session.Table("host_manage_list").Where("is_delete = 0 AND id = ?", v.Id).
// Cols("conn_status").Update(&hostManageListConn)
// if err != nil {
// err = resp.DbUpdateError.WithError(err)
// session.Rollback()
// return
// }
//}
session.Commit()
return
}
......@@ -545,16 +587,27 @@ func (h *HostManageSvc) SaveStateHostManage(hostManageList []request.HostManageL
return
}
//状态检测
// 使用协程批量执行 ping 命令
var wg sync.WaitGroup
wg.Add(len(hostManageListCaches))
id = uuid.New().String()
for k, v := range hostManageListCaches {
//调用状态检测函数
hostManageListCaches[k].ConnStatus, err = StatusDetection(v.Ip)
if err != nil {
return
}
hostManageListCaches[k].Id = id
for i := 0; i < len(hostManageListCaches); i++ {
go func(i int) {
//检测ip连通性
hostManageListCaches[i].ConnStatus = StatusDetection(hostManageListCaches[i].Ip)
hostManageListCaches[i].Id = id
defer wg.Done()
}(i)
}
wg.Wait()
//状态检测
//id = uuid.New().String()
//for k, v := range hostManageListCaches {
// //调用状态检测函数
// hostManageListCaches[k].ConnStatus = StatusDetection(v.Ip)
// hostManageListCaches[k].Id = id
//}
//存入数据库
_, err = db.Table("host_manage_list_cache").Insert(&hostManageListCaches)
......@@ -621,35 +674,26 @@ func (h *HostManageSvc) SaveIpExceptionList(req request.HostIpExceptionListReq)
}
// StatusDetection 状态检测
func StatusDetection(ip string) (ipConn int, err error) {
func StatusDetection(ip string) (ipConn int) {
var cmd *exec.Cmd
cmd = exec.Command("ansible", fmt.Sprintf("%s", AnsibleIp+ip), "-m", "ping")
//执行cmd命令
if err = cmd.Start(); err != nil {
err = resp.CmdExecError.WithError(err)
return
}
if cmd.ProcessState.Success() {
return 0, nil
output, err := cmd.Output()
if err != nil {
fmt.Println("ping:", string(output))
fmt.Println("err:", err)
return 1
}
return 1, nil
//output, err := cmd.Output()
//if err != nil {
// fmt.Println("ping:", string(output))
// return 1
//}
//fmt.Println("ping:", string(output))
//return 0
fmt.Println("ping:", string(output))
return 0
}
// ExportIpStr 结果导出
type ExportIpStr struct {
Ip string `json:"ip" index:"0"` // ip
Port string `json:"port" index:"1"` // 端口
VoucherType string `json:"voucher_type" index:"2"` // 凭证类型
UserName string `json:"user_name" index:"3"` // 用户名
Password string `json:"password" index:"4"` // 密码
ConnStatus string `json:"conn_status" index:"5" ` // 连接状态
Ip string `json:"ip" index:"0"` // ip
Port string `json:"port" index:"1"` // 端口
VoucherType string `json:"voucher_type" index:"2"` // 凭证类型
UserName string `json:"user_name" index:"3"` // 用户名
Password string `json:"password" index:"4"` // 密码
}
// ExportIp 结果导出
......@@ -691,20 +735,12 @@ func (h *HostManageSvc) ExportIp(id, uuid string, detectionType int) (fileName s
case 1:
voucherType = "密钥验证"
}
connStatus := ""
switch v.ConnStatus {
case 0:
connStatus = "正常"
case 1:
connStatus = "异常"
}
staff := ExportIpStr{
Ip: v.Ip,
Port: v.Port,
VoucherType: voucherType,
UserName: v.UserName,
Password: v.Password,
ConnStatus: connStatus,
}
push = append(push, staff)
......@@ -722,7 +758,7 @@ func generatePushExportXlsx(push []ExportIpStr) (string, error) {
file := xlsx.NewFile()
sheet, _ := file.AddSheet("Sheet1")
titles := []string{"IP", "端口", "凭证类型", "用户名", "密码", "状态"}
titles := []string{"IP", "端口", "凭证类型", "用户名", "密码"}
row := sheet.AddRow()
var cell *xlsx.Cell
for _, title := range titles {
......@@ -776,30 +812,8 @@ func CronStatusDetection() {
return
}
//往hosts文件中写入主机组ip
//f, err := os.OpenFile("/etc/ansible/hosts", os.O_APPEND|os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
//if err != nil {
// fmt.Println("CronStatusDetection err:", err.Error())
// return
//}
//defer f.Close()
//_, err = f.Write([]byte(fmt.Sprintf("%s%d\n", AnsibleGroup, req.Id)))
//if err != nil {
// fmt.Println("CronStatusDetection err:", err.Error())
// return
//}
//for _, v := range hostManageList {
// _, err = f.Write([]byte(fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"\n", v.Ip, v.Ip, v.Port, v.UserName, v.Password)))
// if err != nil {
// fmt.Println("CronStatusDetection err:", err.Error())
// return
// }
//}
for _, v := range hostManageList {
connStatus, err1 := StatusDetection(v.Ip)
if err1 != nil {
fmt.Println("CronStatusDetection err:", err1.Error())
}
connStatus := StatusDetection(v.Ip)
//修改状态
_, err = db.Table("host_manage_list").Where("is_delete = 0 AND id = ?", v.Id).
Cols("conn_status").Update(&entity.HostManageList{
......
package k8s
import (
"encoding/json"
"fmt"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"github.com/pkg/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type K8sSvc struct {
Header map[string]string
}
type SendFile struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Content interface{} `json:"content"`
}
type K8sCsrfToken struct {
Token string `json:"token"`
}
type UploadFileObj struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Content Content `json:"content"`
}
type Content struct {
Kind string `json:"kind"`
ApiVersion string `json:"apiVersion"`
Metadata v1.ObjectMeta `json:"metadata"`
Spec interface{} `json:"spec"`
}
type AddBgObjectFile struct {
ApiVersion string `json:"apiVersion"`
Kind string `json:"kind"`
Metadata struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Annotations map[string]string `json:"annotations,omitempty"`
Labels map[string]string `json:"labels"`
} `json:"metadata"`
Spec interface{} `json:"spec"`
Data interface{} `json:"data"`
}
var KindBlackList = []string{"PersistentVolumeClaim", "PersistentVolume", "namespace"}
func (k *K8sSvc) SendFile(content *Content) (res string, err error) {
if err = k.checkK8sKind(content.Kind); err != nil {
return
}
csrfUrl := fmt.Sprintf("%s/kubernetes/api/v1/csrftoken/appdeploymentfromfile", conf.Options.AweRestURL)
sendUrl := fmt.Sprintf("%s/kubernetes/api/v1/appdeploymentfromfile", conf.Options.AweRestURL)
csrf, err := util.ProxySendRes("GET", csrfUrl, "", k.Header)
if err != nil {
return "", err
}
csrfToken := K8sCsrfToken{}
json.Unmarshal(csrf, &csrfToken)
if csrfToken.Token == "" {
err := errors.New("get csrfToken failed")
return "", err
}
k.Header["x-csrf-token"] = csrfToken.Token
k.Header["Content-Type"] = "application/json"
// sendFile
sendFile := SendFile{Name: content.Metadata.Name, Namespace: content.Metadata.Namespace}
c, _ := json.Marshal(content)
sendFile.Content = string(c)
sStr, _ := json.Marshal(sendFile)
k8sUserJwtRes, err := util.ProxySendRes("POST", sendUrl, string(sStr), k.Header)
if err != nil {
return "", err
}
res = string(k8sUserJwtRes)
//json.Unmarshal(k8sUserJwtRes, &res)
return
}
func (k *K8sSvc) checkK8sKind(kind string) (err error) {
for _, v := range KindBlackList {
if kind == v {
return errors.New("当前用户没有上传此类型资源的权限!")
}
}
return nil
}
package k8s
import (
"encoding/json"
"fmt"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"strings"
v1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
)
var (
PrometheusRuleGroup = "monitoring.beagle.io" // kubectl api-resources | grep -i prome
PrometheusRuleVersion = "v1"
PrometheusRuleKind = "PrometheusRule"
PrometheusRuleApiVersion = PrometheusRuleGroup + "/" + PrometheusRuleVersion
PrometheusRuleName = strings.ToLower(PrometheusRuleKind) + "s." + PrometheusRuleGroup
)
type PrometheusRule struct {
Header map[string]string
}
func (p PrometheusRule) Create(pRule *v1.PrometheusRule) error {
k8sSvc := K8sSvc{Header: p.Header}
c := &Content{Kind: PrometheusRuleKind, ApiVersion: PrometheusRuleApiVersion, Metadata: pRule.ObjectMeta, Spec: pRule.Spec}
_, err := k8sSvc.SendFile(c)
return err
}
func (p PrometheusRule) Delete(namespace string, name string) error {
delUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, PrometheusRuleName, namespace, name)
_, err := util.ProxySendRes("DELETE", delUrl, "", p.Header)
return err
}
func (p PrometheusRule) Update(pRule *v1.PrometheusRule) error {
updateUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, PrometheusRuleName, pRule.Namespace, pRule.Name)
body, _ := json.Marshal(pRule)
p.Header["Content-Type"] = "application/json"
_, err := util.ProxySendRes("PUT", updateUrl, string(body), p.Header)
return err
}
func (p PrometheusRule) Get(namespace string, name string) (obj *v1.PrometheusRule, err error) {
// http://awecloud-rest/awecloud/rest/kubernetes/api/v1/_raw/prometheusrules.monitoring.coreos.com/namespace/kube-public/name/nginx
getUrl := fmt.Sprintf("%s/kubernetes/api/v1/_raw/%s/namespace/%s/name/%s", conf.Options.AweRestURL, PrometheusRuleName, namespace, name)
res, err := util.ProxySendRes("GET", getUrl, "", p.Header)
if err != nil {
return
}
err = json.Unmarshal(res, &obj)
return
}
package k8s
import (
"fmt"
v1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"github.com/spf13/cast"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"k8s.io/apimachinery/pkg/util/intstr"
"log"
"testing"
"time"
)
var svc PrometheusRule
var obj v1.PrometheusRule
var AlertDefLabels = map[string]string{
"app": "prometheus",
"app.bd-apaas.com/cluster-component": "monitoring",
"prometheus-operator": "monitoring",
"release": "beagle-prometheus",
}
func init() {
conf.Options = &conf.Config{}
conf.Options.AweRestURL = "https://cloud.wodcloud.com/awecloud/rest"
conf.Options.KubernetesToken = "380e3557499a13c4ec4aa11d7456bb45ef2303c1"
header := make(map[string]string)
header["Authorization"] = "Bearer " + conf.Options.KubernetesToken
svc = PrometheusRule{Header: header}
obj = v1.PrometheusRule{}
obj.Name = "beagle-prometheus-operation-api-rules-101"
obj.Namespace = "beagle-monitoring"
obj.Labels = AlertDefLabels
}
func TestRule(t *testing.T) {
group := v1.RuleGroup{}
group.Name = "demo-group-1m"
rule := v1.Rule{}
rule.Alert = "kubernetes启动状态"
rule.Annotations = make(map[string]string)
rule.Annotations["value"] = "{{ $value }}"
rule.Annotations["message"] = "启动了"
rule.Expr = intstr.FromString(`up{endpoint="https", instance="192.168.1.244:6443", job="apiserver", namespace="default", service="kubernetes"} == 1`)
ruleFor := v1.Duration("1m")
rule.For = &ruleFor
rule.Labels = make(map[string]string)
rule.Labels["severity"] = "warning"
rule.Labels["severity_name"] = "一般风险"
rule.Labels["risk_level"] = cast.ToString(constant.RiskLevelLow)
rule.Labels["source"] = "so-operation-api"
rule.Labels["alert_id"] = "101"
group.Rules = append(group.Rules, rule)
obj.Spec.Groups = append(obj.Spec.Groups, group)
err := svc.Create(&obj)
if err != nil {
fmt.Println("添加失败" + err.Error())
} else {
fmt.Println("添加成功")
}
}
func TestGet(t *testing.T) {
// 获取对象
ruleObj, err := svc.Get(obj.Namespace, obj.Name)
if err != nil {
fmt.Println("获取失败" + err.Error())
} else {
fmt.Println("获取成功")
}
log.Printf("ruleObj:%+v\n", ruleObj)
}
func TestUpdate(t *testing.T) {
ruleObj, err := svc.Get(obj.Namespace, obj.Name)
if err != nil {
fmt.Println("获取失败" + err.Error())
} else {
fmt.Println("获取成功")
}
// 更新
ruleObj.Name = "galileo-101"
ruleObj.Spec.Groups[0].Rules[0].Alert = "请求次数大于10"
ruleObj.Spec.Groups[0].Name = "2分钟组"
ruleFor := v1.Duration("2m")
ruleObj.Spec.Groups[0].Rules[0].For = &ruleFor
ruleObj.Spec.Groups[0].Rules[0].Expr = intstr.FromString(`up{endpoint="https", instance="192.168.1.244:6443", job="apiserver", namespace="default", service="kubernetes"} == 0`)
err = svc.Update(ruleObj)
if err != nil {
fmt.Println("更新失败" + err.Error())
} else {
fmt.Println("更新成功")
}
}
func TestDelete(t *testing.T) {
// 删除
time.Sleep(time.Second * 10)
err := svc.Delete(obj.Namespace, obj.Name)
if err != nil {
fmt.Println("删除失败" + err.Error())
} else {
fmt.Println("删除成功")
}
}
......@@ -38,7 +38,7 @@ func (t *TaskHistorySvc) TaskHistoryList(req request.TaskHistoryReq) (total int6
}
//查询任务历史
total, err = finder.Select("t2.state,t2.task_id,t1.task_name,t2.exec_start_time,t2.exec_end_time,t2.create_user").
Limit(req.PageSize, (req.Page-1)*req.PageSize).FindAndCount(&taskHistoryListRes)
OrderBy("t2.exec_start_time desc").Limit(req.PageSize, (req.Page-1)*req.PageSize).FindAndCount(&taskHistoryListRes)
if err != nil {
err = resp.DbSelectError.WithError(err)
return
......
......@@ -133,11 +133,6 @@ func (t *TaskManageSvc) DetailsTaskManage(id int) (taskManageRes response.TaskMa
return
}
//err = db.Table("host_manage_list").Where("is_delete = 0 AND host_group_id = ?", id).Find(&hostList)
//if err != nil {
// err = resp.DbSelectError.WithError(err)
// return
//}
for _, v := range hostList {
if v.HostFileUrl != "" {
taskManageRes.HostFileUrl = v.HostFileUrl
......@@ -174,7 +169,7 @@ func (t *TaskManageSvc) ListTaskManage(req request.ListTaskManageReq) (total int
finder.OrderBy("tm.id")
//查询任务
total, err = finder.Select("tm.id,tm.task_name,tm.task_desc,(select count(*) from task_history th "+
"where th.task_id = tm.id) as exec_cnt,tm.create_user,tm.create_time").
"where th.task_id = tm.id) as exec_cnt,tm.create_user,tm.create_time").OrderBy("tm.create_time desc").
Limit(req.PageSize, (req.Page-1)*req.PageSize).FindAndCount(&taskManageListRes)
if err != nil {
err = resp.DbSelectError.WithError(err)
......@@ -245,7 +240,6 @@ func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq, script string) (id
}
defer hostsGroup.Close()
//_, err = hostsGroup.Write([]byte(hostsIp))
_, err = hostsGroup.Write([]byte(strings.Join(hosts, "\n")))
if err != nil {
err = resp.FileExecError.WithError(err)
......
......@@ -2,15 +2,20 @@ package util
import (
"crypto/tls"
"errors"
"github.com/valyala/fasthttp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"go.uber.org/zap"
"io"
"net"
"net/http"
"strings"
"sync"
"time"
)
var lock sync.RWMutex
const (
MediaTypeJSON = "application/json"
MediaTypeXML = "application/xml"
......@@ -121,3 +126,37 @@ func HttpSend(sendType string, url string, body string, header map[string]string
}
return response, err
}
func ProxySendRes(sendType string, url string, body string, header map[string]string) (result []byte, err error) {
client := &http.Client{}
var reqest *http.Request
if sendType == "GET" || sendType == "DELETE" {
reqest, _ = http.NewRequest(sendType, url, nil)
} else if sendType == "POST" || sendType == "PUT" {
reqest, _ = http.NewRequest(sendType, url, strings.NewReader(body))
}
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
lock.Lock()
if header == nil {
header = make(map[string]string)
}
reqest.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
reqest.Header.Set("Accept-Language", "ja,zh-CN;q=0.8,zh;q=0.6")
reqest.Header.Set("Connection", "keep-alive")
for k, v := range header {
reqest.Header.Set(k, v)
}
lock.Unlock()
response, errc := client.Do(reqest)
if errc != nil {
return nil, errc
} else {
defer response.Body.Close()
body, erra := io.ReadAll(response.Body)
if response.StatusCode >= 400 {
err = errors.New(string(body))
return
}
return body, erra
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment