diff --git a/src/bean/entity/alert_list.go b/src/bean/entity/alert_list.go index 0829ffc99c5100397d7c37bb3123182eb3374048..73a8e8905e99372340d26d1ae85cf0dd4ea0cc11 100644 --- a/src/bean/entity/alert_list.go +++ b/src/bean/entity/alert_list.go @@ -5,29 +5,31 @@ import ( ) type AlertList struct { - Id int `json:"id"` // 预警列表ID,主键,自增长 - AlertPoint string `json:"alert_point"` // 预警点 - AlertRulesId string `json:"alert_rules_id"` // 告警规则id - RiskLevel int `json:"risk_level"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险 - AlertTime jsontime.Time `json:"alert_time"` // 预警时间 - ClassId int `json:"class_id" xorm:"'class_id'"` // 预警对象id(级联:预警分类/预警对象) - ClassParentName string `json:"class_parent_name" xorm:"class_parent_name"` // 预警分类名称 TODO 该字段做关联存储或查询 - ClassName string `json:"class_name" xorm:"class_name"` // 预警对象名称 TODO 该字段做关联存储或查询 - MetricConfigId string `json:"metric_config_id"` // 预警指标id // 预警指标 - MetricConfigName string `json:"metric_config_name" xorm:"metric_config_name"` // 预警指标名称 - AlertRuleType string `json:"alert_rule_type" xorm:"alert_rule_type"` // 预警规则类型 TODO 该字段做关联存储或查询 - CurrentValue float64 `json:"current_value"` // 当前报警值 - AlertCondition string `json:"alert_condition" xorm:"'alert_condition'"` // 预警规则(预警阈值) 字典值 - NotificationCount int `json:"notification_count"` // 通知人数 - PushCount int `json:"push_count"` // 推送次数 - LastPushTime jsontime.Time `json:"last_push_time"` // 最近推送时间 - Status int `json:"status"` // 状态,1:已恢复 2:未恢复 3:已关闭 - IsDisposed int `json:"is_disposed"` // 是否处置(工单管理),1:已处置,2:未处置 - DisposalContent string `json:"disposal_content"` // 处置内容(工单管理,结果反馈) - 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'"` // 更新时间 + Id int `json:"id"` // 预警列表ID,主键,自增长 + AlertPoint string `json:"alert_point"` // 预警点 + AlertRulesId string `json:"alert_rules_id"` // 告警规则id + RiskLevel int `json:"risk_level"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险 + AlertTime jsontime.Time `json:"alert_time"` // 预警时间 + ClassId int `json:"class_id" xorm:"'class_id'"` // 预警对象id(级联:预警分类/预警对象) + ClassParentName string `json:"class_parent_name" xorm:"class_parent_name"` // 预警分类名称 TODO 该字段做关联存储或查询 + ClassName string `json:"class_name" xorm:"class_name"` // 预警对象名称 TODO 该字段做关联存储或查询 + MetricConfigId string `json:"metric_config_id"` // 预警指标id // 预警指标 + MetricConfigName string `json:"metric_config_name" xorm:"metric_config_name"` // 预警指标名称 + AlertRuleType string `json:"alert_rule_type" xorm:"alert_rule_type"` // 预警规则类型id TODO 该字段做关联存储或查询 + AlertRuleTypeName string `json:"alert_rule_type_name" xorm:"alert_rule_type_name"` // 预警规则类型名称 TODO 该字段做关联存储或查询 + CurrentValue float64 `json:"current_value"` // 当前报警值 + AlertCondition string `json:"alert_condition" xorm:"'alert_condition'"` // 预警规则(预警阈值) 字典值 + NotificationCount int `json:"notification_count"` // 通知人数 + PushCount int `json:"push_count"` // 推送次数 + LastPushTime jsontime.Time `json:"last_push_time"` // 最近推送时间 + Status int `json:"status"` // 状态,1:已恢复 2:未恢复 3:已关闭 + IsDisposed int `json:"is_disposed"` // 是否处置(工单管理),1:已处置,2:未处置 + DisposalContent string `json:"disposal_content"` // 处置内容(工单管理,结果反馈) + CloseRemark string `json:"close_remark"` // 关闭备注,预警关闭提醒 + 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'"` // 更新时间 } func (a *AlertList) TableName() string { diff --git a/src/bean/entity/alert_overview.go b/src/bean/entity/alert_overview.go index af85db31d6455d3e99ed6fde5b65fdb58b7c6b53..b29b092a7b1a10532b0feaddb3372ea53729e366 100644 --- a/src/bean/entity/alert_overview.go +++ b/src/bean/entity/alert_overview.go @@ -45,5 +45,5 @@ type AlertFrequencyDistribution struct { } func (a *AlertOverview) TableName() string { - return "alert_overview.go" + return "alert_overview" } diff --git a/src/bean/entity/alert_rules.go b/src/bean/entity/alert_rules.go index 65960812abeb457439310c4ec8f89d25d15a65f9..1033f80882f37ddfe161f5296a66b0ed9698332f 100644 --- a/src/bean/entity/alert_rules.go +++ b/src/bean/entity/alert_rules.go @@ -14,7 +14,7 @@ type AlertRules struct { 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'"` // 检查周期 单位:分钟 - NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 all dingtalk sms + NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 dingtalk sms NotifyRecipients string `json:"notify_recipients" xorm:"notify_recipients"` // 预警推送用户 NotifyPushCount int `json:"notify_push_count" xorm:"'notify_push_count'"` // 消息推送次数 NotifyPushFrequency int `json:"notify_push_frequency" xorm:"'notify_push_frequency'"` // 消息推送频率 分钟 @@ -44,5 +44,5 @@ type AlertCondition struct { type NotifyRecipients struct { SystemAccount string `json:"system_account" form:"system_account" binding:"required"` UserName string `json:"user_name" form:"user_name" binding:"required"` - Phone string `json:"phone" form:"phone" binding:"required"` + Phone string `json:"phone" form:"phone" binding:"required,phone"` } diff --git a/src/bean/entity/push_record.go b/src/bean/entity/push_record.go index fafad4ff7395b1ef388c4b4d8ce8b4665c52f49f..e9ebce39f3be05c4eb3fa1cfb5a344e9baacdb6d 100644 --- a/src/bean/entity/push_record.go +++ b/src/bean/entity/push_record.go @@ -6,8 +6,8 @@ type PushRecord struct { Id int `json:"id" xorm:"'id' pk autoincr"` // 主键id AlertRulesId string `json:"alert_rules_id" xorm:"'alert_rules_id'"` // 告警规则id RiskLevel int `json:"risk_level" xorm:"'risk_level'"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险 - NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 all dingtalk sms - SystemAccount string `json:"system_account" xorm:"system_account"` // 预警推送用户(NotifyRecipient) // 账号 + NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 dingtalk sms + SystemAccount string `json:"system_account" xorm:"system_account"` // 预警推送用户 PushTime jsontime.Time `json:"push_time" xorm:"'push_time'"` // 推送时间 PushType int `json:"push_type" xorm:"'push_type'"` // 推送类型,1:自动推送,2:手动推送 Status int `json:"status" xorm:"'status'"` // 推送状态,1:成功,2:失败 diff --git a/src/bean/vo/request/alert_list.go b/src/bean/vo/request/alert_list.go index cd84c796e7fbac83001944edbd68910867364458..4e10d2af6d729ffc8e4d33026e4a01c4749971bf 100644 --- a/src/bean/vo/request/alert_list.go +++ b/src/bean/vo/request/alert_list.go @@ -1,5 +1,7 @@ package request +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + type DetailAlertList struct { Id int `json:"id" form:"id" binding:"required"` } @@ -10,6 +12,20 @@ type UpdateAlertList struct { Keyword string `json:"keyword" form:"keyword"` // 预警点/分类/指标 } +type BatchPushAlertList struct { + Id string `json:"id" form:"id"` + Ids []string `json:"ids" form:"ids" binding:"required_without=Id"` // 预警ids + NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 dingtalk sms + NotifyRecipients []entity.NotifyRecipients `json:"notify_recipients" form:"notify_recipients" binding:"dive"` // 预警推送用户 +} + +type BatchCloseAlertList struct { + Id string `json:"id" form:"id"` + Ids []string `json:"ids" form:"ids" binding:"required_without=Id"` // 预警ids + CloseRemark string `json:"close_remark" form:"close_remark" binding:"required"` // 关闭备注 + DeferPush int `json:"defer_push" form:"defer_push" binding:"omitempty,oneof=0 1"` // 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现 +} + type ListAlertList struct { Id int `json:"id" form:"id"` RiskLevel int `json:"risk_level" form:"risk_level" binding:"omitempty,oneof=1 2 3 4"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险 diff --git a/src/bean/vo/request/alert_rules.go b/src/bean/vo/request/alert_rules.go index 388aed62fa07ac40c85f947485ee73e79517bd3f..2b624fea143605befbbf7a26a7b4991db82b2985 100644 --- a/src/bean/vo/request/alert_rules.go +++ b/src/bean/vo/request/alert_rules.go @@ -19,7 +19,7 @@ type AddAlertRules struct { Duration int `json:"duration" form:"duration" binding:"gte=0"` // 持续时间 DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"oneof=s m h"` // 持续时间单位 s m h CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 - NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 all dingtalk sms + NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 dingtalk sms NotifyRecipients []entity.NotifyRecipients `json:"notify_recipients" form:"notify_recipients" binding:"dive"` // 预警推送用户 NotifyPushCount int `json:"notify_push_count" form:"notify_push_count" binding:"gte=1"` // 消息推送次数 NotifyPushFrequency int `json:"notify_push_frequency" form:"notify_push_frequency" binding:"gte=1"` // 消息推送频率 分钟 @@ -42,7 +42,7 @@ type UpdateAlertRules struct { Duration int `json:"duration" form:"duration" binding:"gte=0"` // 持续时间 DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"oneof=s m h"` // 持续时间单位 s m h CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 - NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 all dingtalk sms + NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 dingtalk sms NotifyRecipients []entity.NotifyRecipients `json:"notify_recipients" form:"notify_recipients" binding:"dive"` // 预警推送用户 NotifyPushCount int `json:"notify_push_count" form:"notify_push_count" binding:"gte=1"` // 消息推送次数 NotifyPushFrequency int `json:"notify_push_frequency" form:"notify_push_frequency" binding:"gte=1"` // 消息推送频率 分钟 @@ -66,7 +66,7 @@ type DetailAlertRules struct { type ListAlertRules struct { // 请输入预警规则名称/预警对象/预警分类/预警指标 Id string `json:"id" form:"id"` - NotifyMethod string `json:"notify_method" form:"notify_method" binding:"omitempty,oneof=all dingtalk sms"` // 预警通知方式 all dingtalk sms + NotifyMethod string `json:"notify_method" form:"notify_method" binding:"omitempty,oneof=all dingtalk sms"` // 预警通知方式 dingtalk sms IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=1 2"` // 是否开启 1:是 2:否 Keyword string `json:"keyword" form:"keyword"` // 预警规则名称(指标名称) StartTime string `json:"start_time" form:"start_time" binding:"omitempty,datetime=2006-01-02 15:04:05"` diff --git a/src/bean/vo/request/push_record.go b/src/bean/vo/request/push_record.go new file mode 100644 index 0000000000000000000000000000000000000000..1248e98989b27217411d20b8e664ee2350850e56 --- /dev/null +++ b/src/bean/vo/request/push_record.go @@ -0,0 +1,43 @@ +package request + +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + +type AddPushRecord 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,oneof=s m h"` // 持续时间单位 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" binding:"omitempty,oneof=1 2"` // 是否开启 1:是 2:否 + AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type" binding:"required"` // 预警规则类型 关联字典表 + SourceFrom int `json:"source_from" form:"source_from" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义 +} + +type UpdatePushRecord struct { + Id string `json:"id" form:"id" binding:"required"` // 主键id + ClassId int `json:"class_id" form:"class_id"` // 预警对象分类id + MetricName string `json:"metric_name" form:"metric_name"` // 指标名称 + Expr string `json:"expr" form:"expr"` // 指标表达式(PromQL语句) + AlertRange []entity.AlertRange `json:"alert_range" form:"alert_range"` // 预警范围 字典值 + Duration int `json:"duration" form:"duration"` // 持续时间 + DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"omitempty,oneof=s m h"` // 持续时间单位 s m h + CheckPeriod int `json:"check_period" form:"check_period" binding:"omitempty,oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 + IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=1 2"` // 是否开启 1:是 2:否 + AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type"` // 预警规则类型 关联字典表 + SourceFrom int `json:"source_from" form:"source_from" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义 +} + +type DeletePushRecord struct { + Id string `json:"id" form:"id"` + Ids []string `json:"ids" form:"ids" binding:"required_without=Id"` +} + +type DetailPushRecord struct { + Id string `json:"id" form:"id" binding:"required"` +} + +type ListPushRecord struct { + AlertListId int `json:"alert_list_id" form:"alert_list_id" binding:"required"` // 预警列表id +} diff --git a/src/bean/vo/request/work_order.go b/src/bean/vo/request/work_order.go index 45505722f1b3a3f258b0a356017e738e340485fd..5a2534713d6669aa856d087e23dc59b66f0f18a4 100644 --- a/src/bean/vo/request/work_order.go +++ b/src/bean/vo/request/work_order.go @@ -1,6 +1,7 @@ package request type AddWorkOrderReq struct { + IsPush int `json:"is_push"` // 是否立刻下发(0否 1是) OrderName string `json:"order_name" binding:"required"` // 工单名称 OrderLevel int `json:"order_level" binding:"oneof=1 2 3"` // 工单等级(1紧急任务 2重要任务 3一般任务) OrderDesc string `json:"order_desc" binding:"required"` // 工单描述 @@ -35,6 +36,7 @@ type TimingCustom struct { } type EditWorkOrderReq struct { + IsPush int `json:"is_push" binding:"required"` // 是否立刻下发(0否 1是) Id int `json:"id" binding:"required"` // 主键id OrderLevel int `json:"order_level" binding:"oneof=1 2 3"` // 工单等级(1紧急任务 2重要任务 3一般任务) OrderDesc string `json:"order_desc" binding:"required"` // 工单描述 diff --git a/src/bean/vo/response/alert_class_test.go b/src/bean/vo/response/alert_class_test.go deleted file mode 100644 index cdb03d5a91962faae25546e6c9e4ea3e1ad0a20f..0000000000000000000000000000000000000000 --- a/src/bean/vo/response/alert_class_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package response - -import ( - "fmt" - json "github.com/json-iterator/go" - "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" - "sort" - "testing" -) - -func BuildTree(nodes []entity.AlertClass) ([]*AlertClassNode, error) { - nodeMap := make(map[int]*AlertClassNode) - - // 创建所有节点并存储到映射表中 - for _, node := range nodes { - tree := &AlertClassNode{ - AlertClass: node, - Children: []*AlertClassNode{}, - } - nodeMap[node.ClassId] = tree - } - - var rootNodes []*AlertClassNode - for _, node := range nodes { - if node.ParentId == 0 { - rootNodes = append(rootNodes, nodeMap[node.ClassId]) - } else { - parent := nodeMap[node.ParentId] - if parent == nil { - return nil, fmt.Errorf("parent node not found for ClassId: %d", node.ClassId) - } - parent.Children = append(parent.Children, nodeMap[node.ClassId]) - } - } - sortTree(rootNodes) - - return rootNodes, nil -} - -func sortTree(nodes []*AlertClassNode) { - sort.Slice(nodes, func(i, j int) bool { - return nodes[i].SortOrder < nodes[j].SortOrder - }) - for _, node := range nodes { - sortTree(node.Children) - } -} - -func TestTree(t *testing.T) { - // 示例数据 - data := []entity.AlertClass{ - {ClassId: 1, ClassName: "Root", ParentId: 0, SortOrder: 0}, - {ClassId: 2, ClassName: "Child 1", ParentId: 1, SortOrder: 0}, - {ClassId: 3, ClassName: "Child 2", ParentId: 1, SortOrder: 0}, - {ClassId: 4, ClassName: "Grandchild 3", ParentId: 2, SortOrder: 3}, - {ClassId: 5, ClassName: "Grandchild 1", ParentId: 2, SortOrder: 1}, - {ClassId: 6, ClassName: "Grandchild 2", ParentId: 2, SortOrder: 2}, - } - - rootNodes, err := BuildTree(data) - if err != nil { - fmt.Println("Failed to build tree:", err) - return - } - - // 将树形结构转换为 JSON 字符串 - jsonData, err := json.Marshal(rootNodes) - if err != nil { - fmt.Println("Failed to marshal tree:", err) - return - } - - fmt.Println(string(jsonData)) -} diff --git a/src/bean/vo/response/push_record.go b/src/bean/vo/response/push_record.go new file mode 100644 index 0000000000000000000000000000000000000000..c3a85e2dbc5aebd7db835a8705dd7734f3b04346 --- /dev/null +++ b/src/bean/vo/response/push_record.go @@ -0,0 +1,13 @@ +package response + +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + +type PushRecordItem struct { + entity.PushRecord `xorm:"extends"` + NotifyMethod []string `json:"notify_method" xorm:"notify_method"` // 预警通知方式 dingtalk sms +} + +type PushRecordList struct { + TotalCount int64 `json:"total_count"` + List []PushRecordItem `json:"list"` +} diff --git a/src/common/conf/options.go b/src/common/conf/options.go index 75fd0fe9e353f8e021de1ef0b5664c5f5821e7fa..3b8fff9d96a5156cdcc9c3075b2b0f1f4e23d98b 100644 --- a/src/common/conf/options.go +++ b/src/common/conf/options.go @@ -35,9 +35,8 @@ type Config struct { AccessRuleModeKey string LocationUrl string LocationKey string - - PrivateKeySSH string - PublicKeySSH string + PrivateKeySSH string + PublicKeySSH string } const ( diff --git a/src/controller/alert_list.go b/src/controller/alert_list.go index aa21524220d60c5b24e647547b5118ff0ba20716..770e25f95b87951408224d9dd82e438648e4ff6d 100644 --- a/src/controller/alert_list.go +++ b/src/controller/alert_list.go @@ -30,6 +30,48 @@ func UpdateAlertList(c *gin.Context) { SendJsonResponse(c, resp.OK, nil) } +func BatchPushAlertList(c *gin.Context) { + var req request.BatchPushAlertList + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.AlertListSvc{User: header.GetUser(c)} + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + err = svc.BatchPushAlertList(db.NewSession(), req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func BatchCloseAlertList(c *gin.Context) { + var req request.BatchCloseAlertList + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.AlertListSvc{User: header.GetUser(c)} + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + err = svc.BatchCloseAlertList(db.NewSession(), req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + func DetailAlertList(c *gin.Context) { var req request.DetailAlertList if err := c.ShouldBind(&req); err != nil { diff --git a/src/controller/push_record.go b/src/controller/push_record.go new file mode 100644 index 0000000000000000000000000000000000000000..0bfa1e16dc26ea9ebc368941b075747af9fdf9e9 --- /dev/null +++ b/src/controller/push_record.go @@ -0,0 +1,109 @@ +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/common/client" + "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" +) + +// AddPushRecord 新增任务 +func AddPushRecord(c *gin.Context) { + var req request.AddPushRecord + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.PushRecordSvc{User: header.GetUser(c)} + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + _, err = svc.Add(db.NewSession(), req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func UpdatePushRecord(c *gin.Context) { + var req request.UpdatePushRecord + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.PushRecordSvc{User: header.GetUser(c)} + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + err = svc.Update(db.NewSession(), req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func DeletePushRecord(c *gin.Context) { + var req request.DeletePushRecord + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + var ids []string + switch len(req.Ids) { + case 0: + ids = append(ids, req.Id) + default: + ids = req.Ids + } + + svc := service.PushRecordSvc{User: header.GetUser(c)} + err := svc.Delete(ids) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func DetailPushRecord(c *gin.Context) { + var req request.DetailPushRecord + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.PushRecordSvc{User: header.GetUser(c)} + data, err := svc.GetDataById(req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, data) +} + +func ListPushRecord(c *gin.Context) { + var req request.ListPushRecord + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.PushRecordSvc{User: header.GetUser(c)} + data, err := svc.List(req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, data) +} diff --git a/src/controller/task_manage.go b/src/controller/task_manage.go index 2dfda13135e6e67484855efc297160e778d63581..ad37a4bb63e6499b601433cee3c292d0563b40ca 100644 --- a/src/controller/task_manage.go +++ b/src/controller/task_manage.go @@ -125,10 +125,10 @@ func ExecScript(c *gin.Context) { } taskManageSvc := service.TaskManageSvc{} - data, err := taskManageSvc.ExecScript(req) + err := taskManageSvc.ExecScript(req) if err != nil { SendJsonResponse(c, err, nil) return } - SendJsonResponse(c, nil, data) + SendJsonResponse(c, nil, nil) } diff --git a/src/main.go b/src/main.go index 951e8b97f79d6c9100a6421e9dc3c3b5ed36cfc6..91b4705473b3eebead40fe87edb52d8ff3e896dd 100644 --- a/src/main.go +++ b/src/main.go @@ -77,9 +77,8 @@ func initConfig() { AccessRuleModeKey: "accessRuleMode", LocationUrl: util.SetEnvStr("LOCATION_URL", "https://apis.map.qq.com/ws/location/v1/ip"), LocationKey: util.SetEnvStr("LOCATION_KEY", "QKFBZ-PGGWJ-VZQFF-FHPA7-QWT5H-YHF4T"), - - PrivateKeySSH: util.SetEnvStr("PRIVATE_KEY_SSH", "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAIEAsOFk9OUB8wg9fd+PDHyX8nEtTSPSZY+tjxq2da1Pf5FkIn+U1da6\nh2eqowF9lnyvlt7uEledTIWQZDGWToGYCZnRommSZEpo/vII+l1P28bJVHfgWFCqmxNfIB\nZFQ4KrOp9rXKidmrd8flhK/NTLJNqryrhhIiDs3CTyAliscIsAAAIQTuM2gU7jNoEAAAAH\nc3NoLXJzYQAAAIEAsOFk9OUB8wg9fd+PDHyX8nEtTSPSZY+tjxq2da1Pf5FkIn+U1da6h2\neqowF9lnyvlt7uEledTIWQZDGWToGYCZnRommSZEpo/vII+l1P28bJVHfgWFCqmxNfIBZF\nQ4KrOp9rXKidmrd8flhK/NTLJNqryrhhIiDs3CTyAliscIsAAAADAQABAAAAgDjcfGPtqq\n7CG2J3l7jf5MjfcTy3I0/a3GSApd82k7PivVoJwYLswJH+1XAJbqIN+zR4/fePitWqqjxL\nZJJgPstuXpBZuJDvGwMqfl7wHRL2Qx34sRG02hG5e3uIfMxe5lHcPba0qsVQt+vOhu9MUb\nsYF/mfuQJKt/Oi8nA1BbrBAAAAQFQPrap7AtYWEoCIY7gtpFMW51iDTAv5GN99DsKNuBby\nwQX2S0Wg/da75m/emJn/2IbmaKApvrx8LbenpyywfBkAAABBAN6xiYQ2j7eRjLV4h4Hbie\nVwlPYP4otKHdF5meObr+2ifYiMktdv/44V1XWKhgavjGFNWx2sHgj7byb51e/bi3MAAABB\nAMtVxa55G0wS9Yw1WK2F4JdYZ65ZAnUuo2rbA2dMDQxsOQxgel5Ox2XmC7e0GKrO9BJKPo\nR2fHEOdm9KOmoB8IkAAAAWY2hlbnppbG9uZ0BleGFtcGxlLmNvbQECAwQF\n-----END OPENSSH PRIVATE KEY-----"), - PublicKeySSH: util.SetEnvStr("PUBLIC_KEY_SSH", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCw4WT05QHzCD19348MfJfycS1NI9Jlj62PGrZ1rU9/kWQif5TV1rqHZ6qjAX2WfK+W3u4SV51MhZBkMZZOgZgJmdGiaZJkSmj+8gj6XU/bxslUd+BYUKqbE18gFkVDgqs6n2tcqJ2at3x+WEr81Msk2qvKuGEiIOzcJPICWKxwiw== chenzilong@example.com"), + PrivateKeySSH: util.SetEnvStr("PRIVATE_KEY_SSH", "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAIEAsOFk9OUB8wg9fd+PDHyX8nEtTSPSZY+tjxq2da1Pf5FkIn+U1da6\nh2eqowF9lnyvlt7uEledTIWQZDGWToGYCZnRommSZEpo/vII+l1P28bJVHfgWFCqmxNfIB\nZFQ4KrOp9rXKidmrd8flhK/NTLJNqryrhhIiDs3CTyAliscIsAAAIQTuM2gU7jNoEAAAAH\nc3NoLXJzYQAAAIEAsOFk9OUB8wg9fd+PDHyX8nEtTSPSZY+tjxq2da1Pf5FkIn+U1da6h2\neqowF9lnyvlt7uEledTIWQZDGWToGYCZnRommSZEpo/vII+l1P28bJVHfgWFCqmxNfIBZF\nQ4KrOp9rXKidmrd8flhK/NTLJNqryrhhIiDs3CTyAliscIsAAAADAQABAAAAgDjcfGPtqq\n7CG2J3l7jf5MjfcTy3I0/a3GSApd82k7PivVoJwYLswJH+1XAJbqIN+zR4/fePitWqqjxL\nZJJgPstuXpBZuJDvGwMqfl7wHRL2Qx34sRG02hG5e3uIfMxe5lHcPba0qsVQt+vOhu9MUb\nsYF/mfuQJKt/Oi8nA1BbrBAAAAQFQPrap7AtYWEoCIY7gtpFMW51iDTAv5GN99DsKNuBby\nwQX2S0Wg/da75m/emJn/2IbmaKApvrx8LbenpyywfBkAAABBAN6xiYQ2j7eRjLV4h4Hbie\nVwlPYP4otKHdF5meObr+2ifYiMktdv/44V1XWKhgavjGFNWx2sHgj7byb51e/bi3MAAABB\nAMtVxa55G0wS9Yw1WK2F4JdYZ65ZAnUuo2rbA2dMDQxsOQxgel5Ox2XmC7e0GKrO9BJKPo\nR2fHEOdm9KOmoB8IkAAAAWY2hlbnppbG9uZ0BleGFtcGxlLmNvbQECAwQF\n-----END OPENSSH PRIVATE KEY-----\n"), + PublicKeySSH: util.SetEnvStr("PUBLIC_KEY_SSH", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCw4WT05QHzCD19348MfJfycS1NI9Jlj62PGrZ1rU9/kWQif5TV1rqHZ6qjAX2WfK+W3u4SV51MhZBkMZZOgZgJmdGiaZJkSmj+8gj6XU/bxslUd+BYUKqbE18gFkVDgqs6n2tcqJ2at3x+WEr81Msk2qvKuGEiIOzcJPICWKxwiw== chenzilong@example.com\n"), } } @@ -151,7 +150,7 @@ func initAnsibleSSH() { if err != nil { fmt.Println("创建目录失败!") } - f, err := os.Create("/root/.ssh/chenzilong") + f, err := os.Create("/root/.ssh/id_rsa") defer f.Close() if err != nil { fmt.Println(err.Error()) @@ -161,7 +160,7 @@ func initAnsibleSSH() { fmt.Println(err.Error()) } } - f2, err := os.Create("/root/.ssh/chenzilong.pub") + f2, err := os.Create("/root/.ssh/id_rsa.pub") defer f2.Close() if err != nil { fmt.Println(err.Error()) diff --git a/src/router/alertlistrouter.go.go b/src/router/alertlistrouter.go.go index 8bc089b3225e2f015f3a0f9f4927b2b3eedbe717..da144bfbf24f40d84997cf74d9718243de45b92f 100644 --- a/src/router/alertlistrouter.go.go +++ b/src/router/alertlistrouter.go.go @@ -14,5 +14,7 @@ func InitAlertListRouter(e *gin.Engine) { group.GET("", controller.DetailAlertList) group.GET("list", controller.ListAlertList) group.PUT("", controller.UpdateAlertList) + group.PUT("batch/push", controller.BatchPushAlertList) + group.PUT("batch/close", controller.BatchCloseAlertList) } } diff --git a/src/router/pushrecordrouter.go b/src/router/pushrecordrouter.go new file mode 100644 index 0000000000000000000000000000000000000000..a141f37f192fd0da84353f1a940bcf601371c917 --- /dev/null +++ b/src/router/pushrecordrouter.go @@ -0,0 +1,18 @@ +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" +) + +// InitPushRecordRouter 初始化推送记录配置路由 +func InitPushRecordRouter(e *gin.Engine) { + group := e.Group(fmt.Sprintf("%s/push_record", conf.Options.Prefix)) + { + group.GET("", controller.DetailPushRecord) + group.GET("list", controller.ListPushRecord) + group.PUT("", controller.UpdatePushRecord) + } +} diff --git a/src/router/router.go b/src/router/router.go index 0856e5324b3ed53ab024e41df299cbd8441fc7be..d73f6aec610a450083823bbd8067deccc1445eeb 100644 --- a/src/router/router.go +++ b/src/router/router.go @@ -61,6 +61,8 @@ func Load(r *gin.Engine, middleware ...gin.HandlerFunc) { InitPrometheusRouter(r) // 初始化预警总览配置路由 InitAlertOverviewRouter(r) + // 初始化推送记录配置路由 + InitPushRecordRouter(r) // 初始化工单管理路由 InitWorkOrderRouter(r) } diff --git a/src/service/alert_list.go b/src/service/alert_list.go index c597a122015af061868896f2aa108ffd7cab473f..d10c1201e43dfd988a7a8a78efbd2c9df40bd49b 100644 --- a/src/service/alert_list.go +++ b/src/service/alert_list.go @@ -5,7 +5,9 @@ import ( "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/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" + "go.uber.org/zap" "xorm.io/xorm" ) @@ -27,6 +29,22 @@ func (a *AlertListSvc) Update(session *xorm.Session, req request.UpdateAlertList return nil } +func (a *AlertListSvc) BatchPushAlertList(session *xorm.Session, req request.BatchPushAlertList) error { + now := jsontime.Now() + _ = now + // TODO 批量推送用户告警 + conf.Logger.Info("batch push", zap.Any("payload", req)) + return nil +} + +func (a *AlertListSvc) BatchCloseAlertList(session *xorm.Session, req request.BatchCloseAlertList) error { + now := jsontime.Now() + _ = now + // TODO 批量推送用户告警 + conf.Logger.Info("batch close", zap.Any("payload", req)) + return nil +} + func (a *AlertListSvc) GetDataById(req request.DetailAlertList) (resp response.AlertListItem, err error) { now := jsontime.Now() data := response.AlertListItem{ @@ -42,6 +60,7 @@ func (a *AlertListSvc) GetDataById(req request.DetailAlertList) (resp response.A MetricConfigId: "d773b37b-dbb4-4a7b-be11-ab40f8acc00e", MetricConfigName: "CPU负载过高", AlertRuleType: "51a2cc1e-eb24-4b16-b106-3dc9db963a49", + AlertRuleTypeName: "%", CurrentValue: 85, NotificationCount: 3, PushCount: 3, @@ -79,6 +98,7 @@ func (a *AlertListSvc) List(req request.ListAlertList) (resp response.AlertListL MetricConfigId: "d773b37b-dbb4-4a7b-be11-ab40f8acc00e", MetricConfigName: "磁盘空间不足", AlertRuleType: "51a2cc1e-eb24-4b16-b106-3dc9db963a49", + AlertRuleTypeName: "%", CurrentValue: 85, NotificationCount: 3, PushCount: 3, @@ -110,6 +130,7 @@ func (a *AlertListSvc) List(req request.ListAlertList) (resp response.AlertListL MetricConfigId: "d773b37b-dbb4-4a7b-be11-ab40f8acc00e", MetricConfigName: "响应时间超时", AlertRuleType: "51a2cc1e-eb24-4b16-b106-3dc9db963a49", + AlertRuleTypeName: "%", CurrentValue: 85, NotificationCount: 1, PushCount: 1, diff --git a/src/service/host_manage.go b/src/service/host_manage.go index 789d1706c29f515a4f91fd6b103834b650dc106e..1f9cb9eb6dc3c75adc8db02e5b89486c2af765ff 100644 --- a/src/service/host_manage.go +++ b/src/service/host_manage.go @@ -119,10 +119,10 @@ func (h *HostManageSvc) AddHostManage(req request.AddHostManageReq) (err error) hostsIp := "" if v.VoucherType == 0 { - hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"", + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\" ansible_host_key_checking=false", AnsibleIp+fmt.Sprintf("%d", hostManageList.Id), v.Ip, v.Port, v.UserName, v.Password) } else { - hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\"", + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_private_key_file=/root/.ssh/id_rsa ansible_host_key_checking=false", AnsibleIp+fmt.Sprintf("%d", hostManageList.Id), v.Ip, v.Port, v.UserName) } @@ -228,10 +228,10 @@ func (h *HostManageSvc) EditHostManage(req request.EditHostManageReq) (err error hostsIp := "" if v.VoucherType == 0 { - hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"", + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\" ansible_host_key_checking=false", AnsibleIp+fmt.Sprintf("%d", hostManageList.Id), v.Ip, v.Port, v.UserName, v.Password) } else { - hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\"", + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_private_key_file=/root/.ssh/id_rsa ansible_host_key_checking=false", AnsibleIp+fmt.Sprintf("%d", hostManageList.Id), v.Ip, v.Port, v.UserName) } @@ -425,10 +425,10 @@ func (h *HostManageSvc) ListStateHostManage(req request.StateHostManageReq) (err for _, v := range hostManageList { hostsIp := "" if v.VoucherType == 0 { - hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"", + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\" ansible_host_key_checking=false", AnsibleIp+fmt.Sprintf("%d", v.Id), v.Ip, v.Port, v.UserName, v.Password) } else { - hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\"", + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_private_key_file=/root/.ssh/id_rsa ansible_host_key_checking=false", AnsibleIp+fmt.Sprintf("%d", v.Id), v.Ip, v.Port, v.UserName) } @@ -513,10 +513,10 @@ func (h *HostManageSvc) SaveStateHostManage(hostManageList []request.HostManageL hostsIp := "" if v.VoucherType == 0 { - hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\"", + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_pass=\"%s\" ansible_host_key_checking=false", AnsibleIp+v.Ip, v.Ip, v.Port, v.UserName, v.Password) } else { - hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\"", + hostsIp = fmt.Sprintf("%s ansible_ssh_host=%s ansible_ssh_port=%s ansible_ssh_user=\"%s\" ansible_ssh_private_key_file=/root/.ssh/id_rsa ansible_host_key_checking=false", AnsibleIp+v.Ip, v.Ip, v.Port, v.UserName) } flag := 0 diff --git a/src/service/push_record.go b/src/service/push_record.go new file mode 100644 index 0000000000000000000000000000000000000000..c832f73c70d9e3cf74a3ea3b63725c55906720de --- /dev/null +++ b/src/service/push_record.go @@ -0,0 +1,115 @@ +package service + +import ( + "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" + "xorm.io/xorm" +) + +type PushRecordSvc struct { + User entity.SystemUserInfo +} + +func (m *PushRecordSvc) Add(session *xorm.Session, req request.AddPushRecord) (id string, err error) { + now := jsontime.Now() + data := entity.PushRecord{ + CreatedBy: m.User.SystemAccount, + CreatedAt: now, + UpdatedBy: m.User.SystemAccount, + UpdatedAt: now, + } + _ = copier.Copy(&data, &req) + _, err = session.Insert(&data) + if err != nil { + return + } + return +} + +func (m *PushRecordSvc) Update(session *xorm.Session, req request.UpdatePushRecord) error { + now := jsontime.Now() + data := entity.PushRecord{ + UpdatedBy: m.User.SystemAccount, + UpdatedAt: now, + } + _ = copier.Copy(&data, &req) + _, err := session.ID(req.Id).Update(&data) + if err != nil { + return err + } + return nil +} + +func (m *PushRecordSvc) GetDataById(req request.DetailPushRecord) (resp response.PushRecordItem, err error) { + now := jsontime.Time{} + data := response.PushRecordItem{ + PushRecord: entity.PushRecord{ + Id: 1, + AlertRulesId: "83343ef6-4a99-47bd-abb4-bcff52feb2ec", + RiskLevel: 1, + SystemAccount: "xiaowang", + PushTime: now, + PushType: 1, + Status: 1, + CreatedBy: "admin", + CreatedAt: now, + UpdatedBy: "admin", + UpdatedAt: now, + }, + NotifyMethod: []string{"dingtalk", "sms"}, + } + resp = data + return +} + +func (m *PushRecordSvc) List(req request.ListPushRecord) (resp response.PushRecordList, err error) { + now := jsontime.Time{} + data1 := response.PushRecordItem{ + PushRecord: entity.PushRecord{ + Id: 1, + AlertRulesId: "83343ef6-4a99-47bd-abb4-bcff52feb2ec", + RiskLevel: 1, + SystemAccount: "xiaowang", + PushTime: now, + PushType: 1, + Status: 1, + CreatedBy: "admin", + CreatedAt: now, + UpdatedBy: "admin", + UpdatedAt: now, + }, + NotifyMethod: []string{"dingtalk", "sms"}, + } + data2 := response.PushRecordItem{ + PushRecord: entity.PushRecord{ + Id: 1, + AlertRulesId: "83343ef6-4a99-47bd-abb4-bcff52feb2ec", + RiskLevel: 2, + SystemAccount: "xiaozhang", + PushTime: now, + PushType: 2, + Status: 2, + CreatedBy: "admin", + CreatedAt: now, + UpdatedBy: "admin", + UpdatedAt: now, + }, + NotifyMethod: []string{"dingtalk", "sms"}, + } + resp.List = append(resp.List, data1, data2) + resp.TotalCount = int64(len(resp.List)) + return +} + +func (m *PushRecordSvc) Delete(ids []string) (err error) { + db, err := client.GetDbClient() + if err != nil { + return + } + _, err = db.NewSession().In("id", ids).Delete(new(entity.PushRecord)) + return +} diff --git a/src/service/task_manage.go b/src/service/task_manage.go index f64e1542e535bd01b6c1a0ae1ea5fe31385de010..9a0b182854313c3d15e0b3770def6692892b78fa 100644 --- a/src/service/task_manage.go +++ b/src/service/task_manage.go @@ -5,8 +5,6 @@ import ( "context" "errors" "fmt" - "github.com/ghodss/yaml" - json "github.com/json-iterator/go" "github.com/minio/minio-go/v7" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" @@ -187,84 +185,125 @@ func (t *TaskManageSvc) ListTaskManage(req request.ListTaskManageReq) (total int return } -func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq) (data map[string]interface{}, err error) { +func (t *TaskManageSvc) ExecScript(req request.ExecScriptReq) (err error) { if req.ScriptUrl != "" { minioClient, err := client.GetMinioConnect() if err != nil { - return nil, resp.DbConnectError.WithError(err) + return resp.DbConnectError.WithError(err) } object, err := minioClient.GetObject(context.Background(), conf.Options.MinioBucket, req.ScriptUrl, minio.GetObjectOptions{}) if err != nil { - return nil, resp.FileExecError.WithError(err) + return resp.FileExecError.WithError(err) } obj, err := io.ReadAll(object) if err != nil { - return nil, resp.FileExecError.WithError(err) + return resp.FileExecError.WithError(err) } req.Script = string(obj) } - var script map[string]interface{} - j2, err := yaml.YAMLToJSON([]byte(req.Script)) - if err != nil { - return nil, resp.YamlAnalysisError.WithError(err) - } - err = json.Unmarshal(j2, &script) - if err != nil { - return nil, resp.MarshalError.WithError(errors.New("yaml格式错误")) - } - script["host"] = fmt.Sprintf("%s%d", AnsibleGroup, req.HostGroupId) - j, err := json.Marshal(script) - if err != nil { - return nil, resp.MarshalError.WithError(err) - } - y, err := yaml.JSONToYAML(j) - if err != nil { - return nil, resp.YamlAnalysisError.WithError(err) - } - req.Script = string(y) + //var scripts []map[string]interface{} + //var script map[string]interface{} + //j2, err := yaml.YAMLToJSON([]byte(req.Script)) + //if err != nil { + // return nil, resp.YamlAnalysisError.WithError(err) + //} + //err = json.Unmarshal(j2, &scripts) + //if err != nil { + // return nil, resp.MarshalError.WithError(errors.New("yaml格式错误")) + //} + //script = scripts[0] + //script["host"] = fmt.Sprintf("%s%d", AnsibleGroup, req.HostGroupId) + //j, err := json.Marshal(script) + //if err != nil { + // return nil, resp.MarshalError.WithError(err) + //} + //y, err := yaml.JSONToYAML(j) + //if err != nil { + // return nil, resp.YamlAnalysisError.WithError(err) + //} + //req.Script = string(y) //写入执行脚本 + fmt.Println("1111111111111111111111") f2, err := os.Create("/etc/ansible/ansible.yml") if err != nil { - return nil, resp.FileExecError.WithError(err) + return resp.FileExecError.WithError(err) } defer f2.Close() _, err = f2.Write([]byte(req.Script)) if err != nil { - return nil, resp.FileExecError.WithError(err) + return resp.FileExecError.WithError(err) } + fmt.Println("2222222222222") //写入额外yml参数 if req.Type == 1 { //写入执行脚本 f3, err := os.Create("/etc/ansible/ansible_extra.yml") if err != nil { - return nil, resp.FileExecError.WithError(err) + return resp.FileExecError.WithError(err) } defer f3.Close() _, err = f3.Write([]byte(req.Value)) if err != nil { - return nil, resp.FileExecError.WithError(err) + return resp.FileExecError.WithError(err) } req.Value = fmt.Sprintf("@/etc/ansible/ansible_extra.yml") } var cmd *exec.Cmd if req.Value != "" { - cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts", "/etc/ansible/ansible.yml", "--extra-vars", req.Value) + cmd = exec.Command("ansible-playbook", "/etc/ansible/ansible.yml", "--extra-vars", req.Value) } else { - cmd = exec.Command("ansible-playbook", "-i", "/etc/ansible/hosts", "/etc/ansible/ansible.yml") + cmd = exec.Command("ansible-playbook", "/etc/ansible/ansible.yml") } + fmt.Println("333333333333333") + //捕获正常日志 stdout, err := cmd.StdoutPipe() if err != nil { - return nil, resp.CmdExecError.WithError(err) + return resp.CmdExecError.WithError(err) + } + //捕获异常日志 + stderr, err := cmd.StderrPipe() + if err != nil { + return resp.CmdExecError.WithError(err) + } + //执行cmd命令 + if err = cmd.Start(); err != nil { + return resp.CmdExecError.WithError(err) } + fmt.Println("4444444444444444444") + //获取正常/异常 输出流 outputBuf := bufio.NewReader(stdout) - output, isPrefix, err := outputBuf.ReadLine() - //output, err := cmd.Output() - //if err != nil { - // err = resp.CmdExecError.WithError(err) - // return - //} - //fmt.Println(string(output)) - data["step"] = isPrefix - data["output"] = string(output) - return data, nil + readerr := bufio.NewReader(stderr) + + var out, outErr int + for { + fmt.Println("666666666666666") + //逐行打印日志 + lineOut, err1 := outputBuf.ReadString('\n') + if (err1 != nil || io.EOF == err1) && out == 0 { + fmt.Println("捕获标准输出line:", lineOut) + fmt.Println("捕获标准输出err:", err1) + out = 1 + //break + } else if out == 0 { + fmt.Println("输出正常日志:", lineOut) + } + + lineErr, err2 := readerr.ReadString('\n') + if (err2 != nil || io.EOF == err2) && outErr == 0 { + fmt.Println("捕获标准错误line:", lineErr) + fmt.Println("捕获标准错误err:", err) + outErr = 1 + //break + } else if outErr == 0 { + fmt.Println("输出错误日志:", lineErr) + } + if out == 1 && outErr == 1 { + break + } + } + fmt.Println("55555555555555") + cmd.Wait() + + fmt.Println("执行结束") + return nil } diff --git a/src/service/work_order.go b/src/service/work_order.go index 9d8abf0134fe77e49b9be0da50c40a2612b81b03..c8182b1e7ffd68e727d15bbc2d15954cbda6a40b 100644 --- a/src/service/work_order.go +++ b/src/service/work_order.go @@ -75,6 +75,16 @@ func (w *WorkOrderManageSvc) AddWorkOrderManage(req request.AddWorkOrderReq) (er err = resp.DbInsertError.WithError(err) return } + + //是否立刻下发 + if req.IsPush == 1 { + push := request.PushWorkOrderReq{ + Id: workOrder.Id, + PushObj: req.PushObj, + } + w.PushWorkOrderManage(push) + } + return } @@ -123,6 +133,15 @@ func (w *WorkOrderManageSvc) EditWorkOrderManage(req request.EditWorkOrderReq) ( err = resp.DbUpdateError.WithError(err) return } + + //是否立刻下发 + if req.IsPush == 1 { + push := request.PushWorkOrderReq{ + Id: req.Id, + PushObj: req.PushObj, + } + w.PushWorkOrderManage(push) + } return } diff --git a/src/util/uuid.go b/src/util/uuid.go deleted file mode 100644 index 4509538811da8760ba6a29a81265826ddf96679b..0000000000000000000000000000000000000000 --- a/src/util/uuid.go +++ /dev/null @@ -1,15 +0,0 @@ -package util - -import ( - "github.com/google/uuid" - "strings" -) - -func NewUUID() string { - return uuid.New().String() -} - -func NewUUIDNoHyphens() string { - id := uuid.New().String() - return strings.Replace(id, "-", "", -1) -} diff --git a/src/util/valid.go b/src/util/valid.go index 352dae4f40b17157abdee828fd2b3dc7a7636879..a93fd793ebed36e71cfaa988abc2731cc8941c9d 100644 --- a/src/util/valid.go +++ b/src/util/valid.go @@ -7,7 +7,10 @@ import ( ut "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" translations "github.com/go-playground/validator/v10/translations/zh" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" + "go.uber.org/zap" "reflect" + "regexp" ) var ( @@ -34,5 +37,35 @@ func RegValid() { return fld.Name }) - //validate.RegisterValidation("required_if", requiredIf) + err := validate.RegisterValidation("phone", validatePhone) + if err != nil { + conf.Logger.Info("validate register failed", zap.Error(err)) + } + setTranslation(validate, Trans) +} + +// 校验手机号 +func validatePhone(fl validator.FieldLevel) bool { + phone := fl.Field().String() + pattern := "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$" + regex, err := regexp.Compile(pattern) + if err != nil { + return false + } + isValid := regex.MatchString(phone) + return isValid +} + +// 中文翻译 +func setTranslation(validate *validator.Validate, trans ut.Translator) { + validate.RegisterTranslation( + "phone", + trans, + func(ut ut.Translator) error { + return ut.Add("phone", "{0}不是一个有效的手机号码!", true) + }, + func(ut ut.Translator, fe validator.FieldError) string { + return fmt.Sprintf("%s不是一个有效的手机号码!", fe.Field()) + }, + ) }