diff --git a/go.mod b/go.mod index fbef97035c6155540e5c81873355ac043b5d27c3..7d58b7ae7e5b2f98b2825144917527a973e258db 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module gitlab.wodcloud.com/smart-operation/so-operation-api go 1.19 require ( - github.com/Luzifer/go-openssl/v4 v4.1.0 github.com/360EntSecGroup-Skylar/excelize v1.4.1 + github.com/Luzifer/go-openssl/v4 v4.1.0 github.com/bytedance/go-tagexpr v2.7.4+incompatible github.com/gin-gonic/gin v1.9.0 github.com/go-playground/locales v0.14.1 @@ -41,6 +41,7 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/henrylee2cn/ameda v1.5.0 // indirect github.com/henrylee2cn/goutil v0.0.0-20220704075712-42f2ec55fe8d // indirect + github.com/jinzhu/copier v0.3.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect diff --git a/go.sum b/go.sum index b0898fbef28c3c69c9e3dfd00b7fbc773c37a7bb..f939272446a08044b4db91029d284b9f3db3da10 100644 --- a/go.sum +++ b/go.sum @@ -228,6 +228,8 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= +github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -313,10 +315,10 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= -github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= +github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= diff --git a/src/bean/entity/metric_config.go b/src/bean/entity/metric_config.go new file mode 100644 index 0000000000000000000000000000000000000000..984e79c34c59967a3f440b9baa33beec0b269fc4 --- /dev/null +++ b/src/bean/entity/metric_config.go @@ -0,0 +1,33 @@ +package entity + +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" + +type MetricConfig struct { + Id string `json:"id" xorm:"'id' pk"` // 主键id + ClassId int `json:"class_id" xorm:"'class_id'"` // 预警对象分类id + MetricName string `json:"metric_name" xorm:"'metric_name'"` // 指标名称 + Expr string `json:"expr" xorm:"'expr'"` // 指标表达式(PromQL语句) + AlertRange string `json:"alert_range" xorm:"'alert_range'"` // 预警范围 字典值 + Duration int `json:"duration" xorm:"'duration'"` // 持续时间 + DurationUnit string `json:"duration_unit" xorm:"'duration_unit'"` // 持续时间单位 s m h + CheckPeriod int `json:"check_period" xorm:"'check_period'"` // 检查周期 单位:分钟 + IsEnabled int `json:"is_enabled" xorm:"'is_enabled'"` // 是否开启 0:关闭 1:启动 + AlertRuleType string `json:"alert_rule_type" xorm:"'alert_rule_type'"` // 预警规则类型 关联字典表 + CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人 + CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间 + UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人 + UpdatedAt jsontime.Time `json:"updated_at" xorm:"'updated_at'"` // 更新时间 +} + +type AlertRange struct { + VariableName string `json:"variable_name" binding:"required"` + MetricName string `json:"metric_name" binding:"required"` + MetricLabel string `json:"metric_label" binding:"required"` + ChineseName string `json:"chinese_name" binding:"required"` + IsRequired bool `json:"is_required"` + IsLinked bool `json:"is_linked"` +} + +func (m *MetricConfig) TableName() string { + return "metric_config" +} diff --git a/src/bean/vo/request/metric_config.go b/src/bean/vo/request/metric_config.go new file mode 100644 index 0000000000000000000000000000000000000000..40f85f194f8234d75d9c13cde24e66c605cd767a --- /dev/null +++ b/src/bean/vo/request/metric_config.go @@ -0,0 +1,36 @@ +package request + +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + +type AddMetricConfig struct { + ClassId int `json:"class_id" form:"class_id" binding:"required"` // 预警对象分类id + MetricName string `json:"metric_name" form:"metric_name" binding:"required"` // 指标名称 + Expr string `json:"expr" form:"expr" binding:"required"` // 指标表达式(PromQL语句) + AlertRange []entity.AlertRange `json:"alert_range" form:"alert_range" binding:"required,dive"` // 预警范围 字典值 + Duration int `json:"duration" form:"duration"` // 持续时间 + DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"required"` // 持续时间单位 s m h + CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 + IsEnabled int `json:"is_enabled" form:"is_enabled" ` // 是否开启 0:关闭 1:启动 + AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type" binding:"required"` // 预警规则类型 关联字典表 +} + +type UpdateMetricConfig struct { + Id string `json:"id" form:"id" binding:"required"` // 主键id + ClassId int `json:"class_id" form:"class_id" binding:"required"` // 预警对象分类id + MetricName string `json:"metric_name" form:"metric_name" binding:"required"` // 指标名称 + Expr string `json:"expr" form:"expr" binding:"required"` // 指标表达式(PromQL语句) + AlertRange []entity.AlertRange `json:"alert_range" form:"alert_range" binding:"required,dive"` // 预警范围 字典值 + Duration int `json:"duration" form:"duration"` // 持续时间 + DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"required"` // 持续时间单位 s m h + CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 + IsEnabled int `json:"is_enabled" form:"is_enabled" ` // 是否开启 0:关闭 1:启动 + AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type" binding:"required"` // 预警规则类型 关联字典表 +} + +type GetMetricConfig struct { + Id string `json:"id" form:"id" binding:"required"` // 主键id +} + +type DeleteMetricConfig struct { + Id string `json:"id" form:"id" binding:"required"` // 主键id +} diff --git a/src/bean/vo/response/metric_config.go b/src/bean/vo/response/metric_config.go new file mode 100644 index 0000000000000000000000000000000000000000..88973644fe201618b3f723902d1fb23a82030b45 --- /dev/null +++ b/src/bean/vo/response/metric_config.go @@ -0,0 +1,13 @@ +package response + +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + +type MetricConfigItem struct { + entity.MetricConfig `xorm:"extends"` + AlertRange []entity.AlertRange `json:"alert_range" xorm:"alert_range"` +} + +type UnitsList struct { + TotalCount int `json:"total_count"` + List []MetricConfigItem `json:"list"` +} diff --git a/src/controller/host_manage.go b/src/controller/host_manage.go index 945493f43e0ce2f0ddba113d5d74fb4f60fafd3a..1b024a75ba2e2b33b1a786ddb83ca8e4842810d4 100644 --- a/src/controller/host_manage.go +++ b/src/controller/host_manage.go @@ -1,10 +1,10 @@ package controller import ( - "encoding/json" "errors" "github.com/360EntSecGroup-Skylar/excelize" "github.com/gin-gonic/gin" + json "github.com/json-iterator/go" "github.com/spf13/cast" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" diff --git a/src/controller/metric_config.go b/src/controller/metric_config.go new file mode 100644 index 0000000000000000000000000000000000000000..6d82fb61ea8829414374653d140e7f23a86a0730 --- /dev/null +++ b/src/controller/metric_config.go @@ -0,0 +1,73 @@ +package controller + +import ( + "github.com/gin-gonic/gin" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service" +) + +// AddMetricConfig 新增任务 +func AddMetricConfig(c *gin.Context) { + var req request.AddMetricConfig + if err := c.ShouldBindJSON(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.MetricConfigSvc{} + err := svc.Add(req) + if err != nil { + SendJsonResponse(c, err, nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func UpdateMetricConfig(c *gin.Context) { + var req request.UpdateMetricConfig + if err := c.ShouldBindJSON(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.MetricConfigSvc{} + err := svc.Update(req) + if err != nil { + SendJsonResponse(c, err, nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func DetailMetricConfig(c *gin.Context) { + var req request.GetMetricConfig + if err := c.ShouldBindJSON(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.MetricConfigSvc{} + data, err := svc.GetDataById(req) + if err != nil { + SendJsonResponse(c, err, nil) + return + } + SendJsonResponse(c, resp.OK, data) +} + +func DeleteMetricConfig(c *gin.Context) { + var req request.DeleteMetricConfig + if err := c.ShouldBindJSON(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.MetricConfigSvc{} + err := svc.DeleteDataById(req) + if err != nil { + SendJsonResponse(c, err, nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} diff --git a/src/pkg/beagle/jsontime/jsonTime.go b/src/pkg/beagle/jsontime/jsonTime.go index 2ef14340f9d63809000f33cc7b4a54c3927791d5..1412c815961fe4c37056d6f202d3e35fdd7fbaa7 100644 --- a/src/pkg/beagle/jsontime/jsonTime.go +++ b/src/pkg/beagle/jsontime/jsonTime.go @@ -16,6 +16,10 @@ var CSTZone = time.FixedZone("CST", 8*3600) // 固定东八区(CST: China Standa // 设置当前时间: jsonDate := Time(time.Now()) type Time time.Time +func Now() Time { + return Time(time.Now()) +} + // MarshalJSON JsonDate序列化 func (t Time) MarshalJSON() ([]byte, error) { b := make([]byte, 0, len("2006-01-02 15:04:05")+2) diff --git a/src/router/metricconfigrouter.go b/src/router/metricconfigrouter.go new file mode 100644 index 0000000000000000000000000000000000000000..3d9f0039deaf711c3933f0c254eedec076087f43 --- /dev/null +++ b/src/router/metricconfigrouter.go @@ -0,0 +1,19 @@ +package router + +import ( + "fmt" + "github.com/gin-gonic/gin" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller" +) + +// InitMetricConfigRouter 初始化指标配置路由 +func InitMetricConfigRouter(e *gin.Engine) { + base := e.Group(fmt.Sprintf("%s/metric_config", conf.Options.Prefix)) + { + base.POST("", controller.AddMetricConfig) + base.PUT("", controller.UpdateMetricConfig) + base.GET("", controller.DetailMetricConfig) + base.DELETE("", controller.DeleteMetricConfig) + } +} diff --git a/src/router/router.go b/src/router/router.go index 2cd6b1d7bb32c61df8bac3b1b900960a8229bac2..cbdf27a6f6638f4c0e7b397a68b84c623679a22b 100644 --- a/src/router/router.go +++ b/src/router/router.go @@ -34,4 +34,6 @@ func Load(r *gin.Engine, middleware ...gin.HandlerFunc) { InitAutomatedMaintenRouter(r) // 初始化登录路由 InitSystemLoginRouter(r) + // 初始化指标配置路由 + InitMetricConfigRouter(r) } diff --git a/src/service/metric_config.go b/src/service/metric_config.go new file mode 100644 index 0000000000000000000000000000000000000000..780addf2ee3899fda20f50778d60a4016f3bd386 --- /dev/null +++ b/src/service/metric_config.go @@ -0,0 +1,80 @@ +package service + +import ( + "github.com/google/uuid" + "github.com/jinzhu/copier" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/util" +) + +type MetricConfigSvc struct { + User *entity.SystemUser +} + +func (m *MetricConfigSvc) Add(req request.AddMetricConfig) error { + db, err := client.GetDbClient() + if err != nil { + err = resp.DbConnectError.WithError(err) + return err + } + now := jsontime.Now() + mc := entity.MetricConfig{ + Id: uuid.New().String(), + CreatedBy: "", + CreatedAt: now, + UpdatedBy: "", + UpdatedAt: now, + } + _ = copier.Copy(&mc, &req) + mc.AlertRange = util.ConvertToString(req.AlertRange) + + _, err = db.NewSession().Insert(&mc) + if err != nil { + return err + } + return nil +} + +func (m *MetricConfigSvc) Update(req request.UpdateMetricConfig) error { + db, err := client.GetDbClient() + if err != nil { + err = resp.DbConnectError.WithError(err) + return err + } + now := jsontime.Now() + mc := entity.MetricConfig{ + UpdatedBy: "", + UpdatedAt: now, + } + _ = copier.Copy(&mc, &req) + mc.AlertRange = util.ConvertToString(req.AlertRange) + + _, err = db.NewSession().ID(req.Id).Update(&mc) + if err != nil { + return err + } + return nil +} + +func (m *MetricConfigSvc) GetDataById(req request.GetMetricConfig) (resp response.MetricConfigItem, err error) { + db, err := client.GetDbClient() + if err != nil { + return + } + _, err = db.NewSession().Table(resp.TableName()).Where("id = ?", req.Id).Get(&resp) + return +} + +func (m *MetricConfigSvc) DeleteDataById(req request.DeleteMetricConfig) (err error) { + db, err := client.GetDbClient() + if err != nil { + return + } + _, err = db.NewSession().Where("id = ?", req.Id).Delete(&entity.MetricConfig{}) + return +} diff --git a/src/util/serialize.go b/src/util/serialize.go new file mode 100644 index 0000000000000000000000000000000000000000..218429d302227b58bd15648494a575f7d4014bbb --- /dev/null +++ b/src/util/serialize.go @@ -0,0 +1,15 @@ +package util + +import ( + "fmt" + json "github.com/json-iterator/go" +) + +// ConvertToString 将数据转换为字符串 +func ConvertToString(v interface{}) string { + jsonData, err := json.Marshal(v) + if err != nil { + return fmt.Sprintf("%v", v) + } + return string(jsonData) +}