mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 06:09:39 +08:00
chore(monitor): delete suggestion files
1. 移除优化建议相关内容 2. mcclient中新增baseManager:SuggestionManager,修改优化建议相关的manager
This commit is contained in:
@@ -1,102 +0,0 @@
|
||||
package dbinit
|
||||
|
||||
import (
|
||||
monitor "yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
)
|
||||
|
||||
var DiskUnusedCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
var EipUnusedCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
var LbUnusedCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
var OssSecAclCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
var RdsUnReasonableCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
var RedisUnReasonableCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
var OssUnReasonableCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
var ScaleDownCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
var SecGroupRuleInCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
var SnapShotUnusedCreateInput *monitor.SuggestSysRuleCreateInput
|
||||
|
||||
var InitRuleCreateInputMap = make(map[string]*monitor.SuggestSysRuleCreateInput)
|
||||
|
||||
func init() {
|
||||
ignoreTimeFrom := true
|
||||
diskSetting := new(monitor.SSuggestSysAlertSetting)
|
||||
diskSetting.DiskUnused = new(monitor.DiskUnused)
|
||||
DiskUnusedCreateInput = NewRule("未挂载的云硬盘", "12h", "336h", monitor.DISK_UNUSED, diskSetting, nil)
|
||||
|
||||
eipSetting := new(monitor.SSuggestSysAlertSetting)
|
||||
eipSetting.EIPUnused = new(monitor.EIPUnused)
|
||||
EipUnusedCreateInput = NewRule("未挂载的弹性公网IP", "12h", "336h", monitor.EIP_UNUSED, eipSetting, nil)
|
||||
|
||||
lbSetting := new(monitor.SSuggestSysAlertSetting)
|
||||
lbSetting.LBUnused = new(monitor.LBUnused)
|
||||
LbUnusedCreateInput = NewRule("未使用的负载均衡实例", "12h", "336h", monitor.LB_UNUSED, lbSetting, nil)
|
||||
|
||||
OssSecAclCreateInput = NewRule("对象存储权限为开放读、写的存储桶和文件", "12h", "336h", monitor.OSS_SEC_ACL,
|
||||
new(monitor.SSuggestSysAlertSetting), &ignoreTimeFrom)
|
||||
|
||||
redisSetting := new(monitor.SSuggestSysAlertSetting)
|
||||
scaleRule := monitor.Scale{
|
||||
Database: "telegraf",
|
||||
Measurement: "dcs_cachekeys",
|
||||
Operator: "and",
|
||||
Field: "key_count",
|
||||
EvalType: "<",
|
||||
Threshold: 100,
|
||||
}
|
||||
redisSetting.ScaleRule = &monitor.ScaleRule{scaleRule}
|
||||
RedisUnReasonableCreateInput = NewRule("空闲的redis", "12h", "336h", monitor.REDIS_UNREASONABLE, redisSetting, nil)
|
||||
|
||||
rdsSetting := new(monitor.SSuggestSysAlertSetting)
|
||||
rdsSetting.ScaleRule = &monitor.ScaleRule{monitor.Scale{
|
||||
Database: "telegraf",
|
||||
Measurement: "rds_cpu",
|
||||
Operator: "and",
|
||||
Field: "usage_active",
|
||||
EvalType: "<",
|
||||
Threshold: 5,
|
||||
}}
|
||||
RdsUnReasonableCreateInput = NewRule("空闲的rds", "12h", "336h", monitor.RDS_UNREASONABLE, rdsSetting, nil)
|
||||
|
||||
ossSetting := new(monitor.SSuggestSysAlertSetting)
|
||||
ossSetting.ScaleRule = &monitor.ScaleRule{monitor.Scale{
|
||||
Database: "telegraf",
|
||||
Measurement: "oss_req",
|
||||
Operator: "and",
|
||||
Field: "req_count",
|
||||
EvalType: "<",
|
||||
Threshold: 100,
|
||||
}}
|
||||
OssUnReasonableCreateInput = NewRule("空闲的oss", "12h", "336h", monitor.OSS_UNREASONABLE, ossSetting, nil)
|
||||
|
||||
serversetting := new(monitor.SSuggestSysAlertSetting)
|
||||
serversetting.ScaleRule = &monitor.ScaleRule{monitor.Scale{
|
||||
Database: "telegraf",
|
||||
Measurement: "vm_cpu",
|
||||
Operator: "and",
|
||||
Field: "usage_active",
|
||||
EvalType: "<",
|
||||
Threshold: 5,
|
||||
}}
|
||||
ScaleDownCreateInput = NewRule("低负载的虚拟机", "12h", "336h", monitor.SCALE_DOWN, serversetting, nil)
|
||||
|
||||
SecGroupRuleInCreateInput = NewRule("安全组规则的in规则为全开放的主机", "12h", "336h",
|
||||
monitor.SECGROUPRULEINSERVER_ALLIN, &monitor.SSuggestSysAlertSetting{}, &ignoreTimeFrom)
|
||||
|
||||
SnapShotUnusedCreateInput = NewRule("未使用的快照", "12h", "336h", monitor.SNAPSHOT_UNUSED,
|
||||
&monitor.SSuggestSysAlertSetting{}, nil)
|
||||
}
|
||||
|
||||
func NewRule(name, period, timeFrom string, typ monitor.SuggestDriverType, setting *monitor.SSuggestSysAlertSetting,
|
||||
ignore *bool) *monitor.
|
||||
SuggestSysRuleCreateInput {
|
||||
rule := new(monitor.SuggestSysRuleCreateInput)
|
||||
enable := false
|
||||
rule.Name = name
|
||||
rule.Type = string(typ)
|
||||
rule.Period = period
|
||||
rule.TimeFrom = timeFrom
|
||||
rule.Setting = setting
|
||||
rule.Enabled = &enable
|
||||
rule.IgnoreTimeFrom = ignore
|
||||
return rule
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
merrors "yunion.io/x/onecloud/pkg/monitor/errors"
|
||||
"yunion.io/x/onecloud/pkg/monitor/validators"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
@@ -992,6 +993,11 @@ func (alert *SCommonAlert) PerformConfig(ctx context.Context, userCred mcclient.
|
||||
return jsonutils.Marshal(alert), err
|
||||
}
|
||||
|
||||
func PerformConfigLog(model db.IModel, userCred mcclient.TokenCredential) {
|
||||
db.OpsLog.LogEvent(model, db.ACT_UPDATE_RULE, "", userCred)
|
||||
logclient.AddSimpleActionLog(model, logclient.ACT_UPDATE_RULE, nil, userCred, true)
|
||||
}
|
||||
|
||||
func (alert *SCommonAlert) AllowPerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformDisableInput) bool {
|
||||
return db.IsProjectAllowPerform(userCred, alert, "disable")
|
||||
}
|
||||
|
||||
@@ -1,591 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
merrors "yunion.io/x/onecloud/pkg/monitor/errors"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
var (
|
||||
SuggestSysAlertManager *SSuggestSysAlertManager
|
||||
)
|
||||
|
||||
func init() {
|
||||
SuggestSysAlertManager = &SSuggestSysAlertManager{
|
||||
SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
|
||||
&SSuggestSysAlert{},
|
||||
"suggestsysalert_tbl",
|
||||
"suggestsysalert",
|
||||
"suggestsysalerts",
|
||||
),
|
||||
}
|
||||
SuggestSysAlertManager.SetVirtualObject(SuggestSysAlertManager)
|
||||
}
|
||||
|
||||
// +onecloud:swagger-gen-model-singular=suggestsysalert
|
||||
// +onecloud:swagger-gen-model-plural=suggestsysalerts
|
||||
type SSuggestSysAlertManager struct {
|
||||
db.SVirtualResourceBaseManager
|
||||
db.SEnabledResourceBaseManager
|
||||
}
|
||||
|
||||
type SSuggestSysAlert struct {
|
||||
db.SVirtualResourceBase
|
||||
db.SEnabledResourceBase
|
||||
|
||||
//监控规则对应的json对象
|
||||
RuleName string `list:"user" update:"user"`
|
||||
MonitorConfig jsonutils.JSONObject `list:"user" update:"user"`
|
||||
//监控规则type:Rule Type
|
||||
Type string `width:"256" charset:"ascii" list:"user" update:"user"`
|
||||
ResMeta jsonutils.JSONObject `list:"user" update:"user"`
|
||||
//problem may have more than one ,so the problem instanceof jsonutils.jsonArray
|
||||
Problem jsonutils.JSONObject `list:"user" update:"user"`
|
||||
//Suggest string `width:"256" list:"user" update:"user"`
|
||||
Action string `width:"256" charset:"ascii" list:"user" update:"user"`
|
||||
ResId string `width:"256" charset:"ascii" list:"user" update:"user"`
|
||||
|
||||
//
|
||||
CloudEnv string `list:"user" update:"user"`
|
||||
Provider string `list:"user" update:"user"`
|
||||
Project string `list:"user" update:"user"`
|
||||
Cloudaccount string `list:"user" update:"user"`
|
||||
|
||||
//费用
|
||||
Amount float64 `list:"user" update:"user"`
|
||||
//币种
|
||||
Currency string `list:"user" update:"user"`
|
||||
}
|
||||
|
||||
func NewSuggestSysAlertManager(dt interface{}, keyword, keywordPlural string) *SSuggestSysAlertManager {
|
||||
man := &SSuggestSysAlertManager{
|
||||
SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
|
||||
dt,
|
||||
"sugalart_tbl",
|
||||
keyword,
|
||||
keywordPlural,
|
||||
),
|
||||
}
|
||||
man.SetVirtualObject(man)
|
||||
return man
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysAlertManager) ListItemFilter(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
query monitor.SuggestSysAlertListInput) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
q, err = manager.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SEnabledResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SEnabledResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
if len(query.Type) > 0 {
|
||||
q = q.Equals("type", query.Type)
|
||||
}
|
||||
if len(query.ResId) > 0 {
|
||||
q = q.Equals("res_id", query.ResId)
|
||||
}
|
||||
//if len(query.Project) > 0 {
|
||||
//
|
||||
// q = q.Equals("project", query.Project)
|
||||
//}
|
||||
if len(query.Providers) > 0 {
|
||||
q = q.In("provider", query.Providers)
|
||||
}
|
||||
if len(query.Brands) > 0 {
|
||||
q = q.In("provider", query.Brands)
|
||||
}
|
||||
if len(query.CloudaccountId) > 0 {
|
||||
q.In("cloudaccount", query.CloudaccountId)
|
||||
}
|
||||
if len(query.CloudEnv) > 0 {
|
||||
q = q.Equals("cloud_env", query.CloudEnv)
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysAlertManager) CustomizeFilterList(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*db.CustomizeListFilters, error) {
|
||||
filters := db.NewCustomizeListFilters()
|
||||
listInput := new(monitor.SuggestSysAlertListInput)
|
||||
if err := query.Unmarshal(listInput); err != nil {
|
||||
return filters, errors.Wrap(err, "unmarshal list input")
|
||||
}
|
||||
scope := rbacutils.ScopeProject
|
||||
if listInput.Scope != "" {
|
||||
scope = rbacutils.TRbacScope(listInput.Scope)
|
||||
}
|
||||
scopeFilter := func(obj jsonutils.JSONObject) (bool, error) {
|
||||
ignoreConfigs, err := SuggestSysRuleConfigManager.GetConfigsByScope(scope, userCred, true)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
alert := new(SSuggestSysAlert)
|
||||
if err := obj.Unmarshal(alert); err != nil {
|
||||
return false, errors.Wrap(err, "unmarshal suggest alert")
|
||||
}
|
||||
for _, conf := range ignoreConfigs {
|
||||
if conf.ShouldIgnoreAlert(alert) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
filters.Append(scopeFilter)
|
||||
return filters, nil
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysAlertManager) GetAlert(id string) (*SSuggestSysAlert, error) {
|
||||
obj, err := manager.FetchById(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*SSuggestSysAlert), nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysAlertManager) OrderByExtraFields(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
input monitor.SuggestSysAlertListInput,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
q, err = man.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, input.VirtualResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysAlertManager) ValidateCreateData(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject,
|
||||
data monitor.SuggestSysAlertCreateInput) (monitor.SuggestSysAlertCreateInput, error) {
|
||||
//rule 查询到资源信息后没有将资源id,进行转换
|
||||
if len(data.ResID) == 0 {
|
||||
return data, httperrors.NewInputParameterError("not found res_id %q", data.ResID)
|
||||
}
|
||||
if len(data.Type) == 0 {
|
||||
return data, httperrors.NewInputParameterError("not found type %q", data.Type)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysAlertManager) FetchCustomizeColumns(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
objs []interface{},
|
||||
fields stringutils2.SSortedStrings,
|
||||
isList bool,
|
||||
) []monitor.SuggestSysAlertDetails {
|
||||
rows := make([]monitor.SuggestSysAlertDetails, len(objs))
|
||||
virtRows := man.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
for i := range rows {
|
||||
rows[i] = monitor.SuggestSysAlertDetails{
|
||||
VirtualResourceDetails: virtRows[i],
|
||||
}
|
||||
rows[i] = objs[i].(*SSuggestSysAlert).getMoreDetails(rows[i])
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleManager) GetDriver(drvType monitor.SuggestDriverType) ISuggestSysRuleDriver {
|
||||
return GetSuggestSysRuleDrivers()[drvType]
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) GetDriver() ISuggestSysRuleDriver {
|
||||
return SuggestSysRuleManager.GetDriver(self.GetType())
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) GetType() monitor.SuggestDriverType {
|
||||
return monitor.SuggestDriverType(self.Type)
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) getMoreDetails(out monitor.SuggestSysAlertDetails) monitor.SuggestSysAlertDetails {
|
||||
err := self.ResMeta.Unmarshal(&out)
|
||||
if err != nil {
|
||||
log.Errorln("SSuggestSysAlert getMoreDetails's error:", err)
|
||||
}
|
||||
drv := self.GetDriver()
|
||||
out.Account = self.Cloudaccount
|
||||
out.ResType = string(drv.GetResourceType())
|
||||
out.RuleName = strings.ToLower(string(drv.GetType()))
|
||||
out.ShowName = self.Name
|
||||
out.Suggest = string(drv.GetSuggest())
|
||||
out.ResName = SuggestSysAlertManager.getOriName(self.Name, self.Type)
|
||||
return out
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlertManager) getOriName(name, typ string) string {
|
||||
lastIndex := strings.LastIndex(name, fmt.Sprintf("-%s", typ))
|
||||
if lastIndex == -1 || lastIndex == 0 {
|
||||
lastIndex = len(name)
|
||||
}
|
||||
return name[:lastIndex]
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysAlertManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
q, err = manager.SVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
switch field {
|
||||
case "account":
|
||||
q.AppendField(sqlchemy.DISTINCT(field, q.Field("cloudaccount"))).Distinct()
|
||||
q.NotEquals("cloudaccount", "")
|
||||
return q, nil
|
||||
}
|
||||
return q, httperrors.ErrNotFound
|
||||
}
|
||||
|
||||
func (alert *SSuggestSysAlert) ValidateUpdateData(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data monitor.SuggestSysAlertUpdateInput) (monitor.SuggestSysAlertUpdateInput, error) {
|
||||
//rule 查询到资源信息后没有将资源id,进行转换
|
||||
if len(data.ResID) == 0 {
|
||||
return data, merrors.NewArgIsEmptyErr("res_id")
|
||||
}
|
||||
if len(data.Type) == 0 {
|
||||
return data, merrors.NewArgIsEmptyErr("type")
|
||||
}
|
||||
var err error
|
||||
data.VirtualResourceBaseUpdateInput, err = alert.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query,
|
||||
data.VirtualResourceBaseUpdateInput)
|
||||
if err != nil {
|
||||
return data, errors.Wrap(err, "SVirtualResourceBase.ValidateUpdateData")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) GetExtraDetails(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
isList bool,
|
||||
) (monitor.SuggestSysAlertDetails, error) {
|
||||
return monitor.SuggestSysAlertDetails{}, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) PostDelete(ctx context.Context, userCred mcclient.TokenCredential) {
|
||||
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
return self.StartDeleteTask(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
log.Infof("SSuggestSysAlert delete do nothing")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return self.SVirtualResourceBase.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) StartDeleteTask(
|
||||
ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
params := jsonutils.NewDict()
|
||||
|
||||
return self.GetDriver().StartResolveTask(ctx, userCred, self, params)
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlertManager) GetResources(tp ...monitor.SuggestDriverType) ([]SSuggestSysAlert, error) {
|
||||
resources := make([]SSuggestSysAlert, 0)
|
||||
query := self.Query()
|
||||
if len(tp) > 0 {
|
||||
query.In("type", tp)
|
||||
}
|
||||
err := db.FetchModelObjects(self, query, &resources)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysAlertManager) GetExportExtraKeys(ctx context.Context, keys stringutils2.SSortedStrings, rowMap map[string]string) *jsonutils.JSONDict {
|
||||
alert := new(SSuggestSysAlert)
|
||||
manager.Query().RowMap2Struct(rowMap, alert)
|
||||
input := monitor.SuggestSysAlertDetails{}
|
||||
input = alert.getMoreDetails(input)
|
||||
res := jsonutils.Marshal(&input)
|
||||
dic := res.(*jsonutils.JSONDict)
|
||||
dic.Add(jsonutils.NewString(input.Account), "manager")
|
||||
dic.Add(jsonutils.NewString(alert.Provider), "hypervisor")
|
||||
return dic
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) AllowPerformIgnore(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return db.IsProjectAllowPerform(userCred, self, "ignore")
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) GetSuggestConfig(scope rbacutils.TRbacScope, domainId string, projectId string,
|
||||
batchIgnore bool) (*SSuggestSysRuleConfig, error) {
|
||||
if scope == "" {
|
||||
scope = rbacutils.ScopeSystem
|
||||
}
|
||||
drv := self.GetDriver()
|
||||
resType := drv.GetResourceType()
|
||||
resId := self.ResId
|
||||
drvType := drv.GetType()
|
||||
scopeId := ""
|
||||
if scope == rbacutils.ScopeDomain {
|
||||
scopeId = domainId
|
||||
} else if scope == rbacutils.ScopeProject {
|
||||
scopeId = projectId
|
||||
}
|
||||
q := SuggestSysRuleConfigManager.Query().Equals("type", drvType).Equals("resource_type", resType)
|
||||
if !batchIgnore {
|
||||
q = q.Equals("resource_id", resId)
|
||||
} else {
|
||||
q = q.IsNull("resource_id")
|
||||
}
|
||||
q = SuggestSysRuleConfigManager.FilterByScope(q, scope, scopeId)
|
||||
configs := make([]SSuggestSysRuleConfig, 0)
|
||||
if err := db.FetchModelObjects(SuggestSysRuleConfigManager, q, &configs); err != nil {
|
||||
return nil, errors.Wrap(err, "fetch suggest config")
|
||||
}
|
||||
if len(configs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
config := configs[0]
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlert) PerformIgnore(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONDict, data monitor.SuggestAlertIngoreInput) (jsonutils.JSONObject, error) {
|
||||
if data.Scope == "" {
|
||||
data.Scope = string(rbacutils.ScopeSystem)
|
||||
}
|
||||
config, err := self.GetSuggestConfig(rbacutils.TRbacScope(data.Scope), data.ProjectDomainId, data.ProjectId, data.BatchIgnore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
drv := self.GetDriver()
|
||||
drvType := drv.GetType()
|
||||
resType := drv.GetResourceType()
|
||||
if config == nil {
|
||||
createData := new(monitor.SuggestSysRuleConfigCreateInput)
|
||||
createData.Name = self.Name
|
||||
createData.ScopedResourceCreateInput = data.ScopedResourceCreateInput
|
||||
createData.Type = &drvType
|
||||
createData.ResourceType = &resType
|
||||
if !data.BatchIgnore {
|
||||
createData.ResourceId = &self.ResId
|
||||
}
|
||||
createData.IgnoreAlert = true
|
||||
data := createData.JSON(createData)
|
||||
conf, err := db.DoCreate(SuggestSysRuleConfigManager, ctx, userCred, nil, data, userCred)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func() {
|
||||
lockman.LockObject(ctx, conf)
|
||||
defer lockman.ReleaseObject(ctx, conf)
|
||||
|
||||
conf.PostCreate(ctx, userCred, userCred, nil, data)
|
||||
}()
|
||||
} else {
|
||||
if _, err := db.Update(config, func() error {
|
||||
config.IgnoreAlert = true
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type SuggestAlertCost struct {
|
||||
CostType string
|
||||
Amount float64
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlertManager) AllowGetPropertyCost(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlertManager) GetPropertyCost(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
costData := jsonutils.NewDict()
|
||||
suggestAlertCosts, err := self.getSuggestAlertCosts(ctx, userCred, query)
|
||||
if err != nil {
|
||||
return jsonutils.NewDict(), err
|
||||
}
|
||||
costData.Add(jsonutils.Marshal(&suggestAlertCosts), "suggest_cost")
|
||||
details, _ := query.Bool("details")
|
||||
if details {
|
||||
return costData, nil
|
||||
}
|
||||
meterCost, err := self.getMeterForcastCosts(ctx, userCred, query)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return costData, nil
|
||||
}
|
||||
costData.Add(jsonutils.Marshal(&meterCost), "meter_forcast_cost")
|
||||
return costData, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlertManager) getSuggestAlertCosts(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) ([]SuggestAlertCost, error) {
|
||||
suggestAlertCosts := make([]SuggestAlertCost, 0)
|
||||
details, _ := query.Bool("details")
|
||||
if details {
|
||||
return self.getDetailCosts(ctx, userCred, query)
|
||||
}
|
||||
cost, err := self.getCostWithSuggestAlertType("", ctx, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typeCost := SuggestAlertCost{
|
||||
Amount: cost,
|
||||
CostType: "all",
|
||||
}
|
||||
suggestAlertCosts = append(suggestAlertCosts, typeCost)
|
||||
return suggestAlertCosts, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlertManager) getDetailCosts(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) ([]SuggestAlertCost, error) {
|
||||
suggestAlertCosts := make([]SuggestAlertCost, 0)
|
||||
types, err := self.getSuggestAlertTypes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allTypeCost := SuggestAlertCost{
|
||||
CostType: "all",
|
||||
Amount: 0,
|
||||
}
|
||||
|
||||
for _, typ := range types {
|
||||
cost, err := self.getCostWithSuggestAlertType(typ, ctx, userCred, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
typeCost := SuggestAlertCost{
|
||||
Amount: cost,
|
||||
CostType: typ,
|
||||
}
|
||||
allTypeCost.Amount += cost
|
||||
suggestAlertCosts = append(suggestAlertCosts, typeCost)
|
||||
}
|
||||
suggestAlertCosts = append(suggestAlertCosts, allTypeCost)
|
||||
return suggestAlertCosts, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlertManager) getMeterForcastCosts(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) (SuggestAlertCost, error) {
|
||||
meterCost := SuggestAlertCost{
|
||||
CostType: "",
|
||||
Amount: 0,
|
||||
}
|
||||
domainId := ""
|
||||
projectId := ""
|
||||
reqScope, _ := query.GetString("scope")
|
||||
switch reqScope {
|
||||
case "system":
|
||||
case "domain":
|
||||
domainId = userCred.GetDomainId()
|
||||
default:
|
||||
projectId = userCred.GetProjectId()
|
||||
}
|
||||
session := auth.GetAdminSession(ctx, "", "")
|
||||
param := jsonutils.NewDict()
|
||||
if len(domainId) > 0 {
|
||||
param.Add(jsonutils.NewString(domainId), "domain_id")
|
||||
}
|
||||
if len(projectId) > 0 {
|
||||
param.Add(jsonutils.NewString(projectId), "project_id")
|
||||
}
|
||||
meterRtn, err := modules.AmountEstimations.GetById(session, "month", param)
|
||||
if err != nil {
|
||||
return meterCost, err
|
||||
}
|
||||
amount, _ := meterRtn.Float("amount")
|
||||
meterCost.Amount = amount
|
||||
return meterCost, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlertManager) getCostWithSuggestAlertType(typ string, ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
param jsonutils.JSONObject) (float64, error) {
|
||||
typeCost := float64(0)
|
||||
queryScope := rbacutils.ScopeProject
|
||||
suggestAlerts := make([]SSuggestSysAlert, 0)
|
||||
query := self.Query("amount")
|
||||
if len(typ) > 0 {
|
||||
query.Equals("type", typ)
|
||||
}
|
||||
reqScope, _ := param.GetString("scope")
|
||||
if len(reqScope) > 0 {
|
||||
queryScope = rbacutils.String2Scope(reqScope)
|
||||
}
|
||||
query = self.FilterByOwner(query, userCred, queryScope)
|
||||
err := db.FetchModelObjects(self, query, &suggestAlerts)
|
||||
if err != nil {
|
||||
log.Errorln(errors.Wrap(err, "getCostWithSuggestAlertType"))
|
||||
return 0, err
|
||||
}
|
||||
for _, suggestAlert := range suggestAlerts {
|
||||
typeCost += suggestAlert.Amount
|
||||
}
|
||||
return typeCost, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysAlertManager) getSuggestAlertTypes() ([]string, error) {
|
||||
suggestAlerts := make([]SSuggestSysAlert, 0)
|
||||
query := self.Query("type").Distinct()
|
||||
|
||||
err := db.FetchModelObjects(self, query, &suggestAlerts)
|
||||
if err != nil {
|
||||
log.Errorln(errors.Wrap(err, "getSuggestAlertTypes"))
|
||||
return nil, err
|
||||
}
|
||||
types := make([]string, 0)
|
||||
for _, suggestAlert := range suggestAlerts {
|
||||
types = append(types, suggestAlert.Type)
|
||||
}
|
||||
return types, nil
|
||||
}
|
||||
@@ -1,701 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/cronman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
merrors "yunion.io/x/onecloud/pkg/monitor/errors"
|
||||
"yunion.io/x/onecloud/pkg/monitor/registry"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
const (
|
||||
SUGGESTRULE_METADATA_IGNORETIME = "ignore_time_from"
|
||||
)
|
||||
|
||||
var (
|
||||
SuggestSysRuleManager *SSuggestSysRuleManager
|
||||
)
|
||||
|
||||
func init() {
|
||||
SuggestSysRuleManager = &SSuggestSysRuleManager{
|
||||
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
|
||||
&SSuggestSysRule{},
|
||||
"suggestsysrule_tbl",
|
||||
"suggestsysrule",
|
||||
"suggestsysrules",
|
||||
),
|
||||
}
|
||||
SuggestSysRuleManager.SetVirtualObject(SuggestSysRuleManager)
|
||||
registry.RegisterService(SuggestSysRuleManager)
|
||||
}
|
||||
|
||||
// +onecloud:swagger-gen-model-singular=suggestsysrule
|
||||
// +onecloud:swagger-gen-model-plural=suggestsysrules
|
||||
type SSuggestSysRuleManager struct {
|
||||
db.SStandaloneResourceBaseManager
|
||||
db.SEnabledResourceBaseManager
|
||||
}
|
||||
|
||||
type SSuggestSysRule struct {
|
||||
db.SStandaloneResourceBase
|
||||
db.SEnabledResourceBase
|
||||
|
||||
Type string `width:"256" charset:"ascii" list:"user" update:"user"`
|
||||
Period string `width:"256" charset:"ascii" list:"user" update:"user"`
|
||||
TimeFrom string `width:"256" charset:"ascii" list:"user" update:"user"`
|
||||
Setting jsonutils.JSONObject `list:"user" update:"user"`
|
||||
ExecTime time.Time `list:"user" update:"user"`
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleManager) FetchSuggestSysAlertSettings(ruleTypes ...monitor.SuggestDriverType) (map[monitor.SuggestDriverType]*monitor.SuggestSysRuleDetails, error) {
|
||||
suggestSysAlerSettingMap := make(map[monitor.SuggestDriverType]*monitor.SuggestSysRuleDetails, 0)
|
||||
|
||||
rules, err := man.GetRules(ruleTypes...)
|
||||
if err != nil {
|
||||
return suggestSysAlerSettingMap, errors.Wrap(err, "FetchSuggestSysAlartSettings")
|
||||
}
|
||||
for _, config := range rules {
|
||||
suggestSysRuleDetails := config.getMoreDetails(monitor.SuggestSysRuleDetails{})
|
||||
if err != nil {
|
||||
return suggestSysAlerSettingMap, errors.Wrap(err, "FetchSuggestSysAlartSettings")
|
||||
}
|
||||
suggestSysAlerSettingMap[config.GetType()] = &suggestSysRuleDetails
|
||||
}
|
||||
return suggestSysAlerSettingMap, nil
|
||||
}
|
||||
|
||||
func (rule *SSuggestSysRule) GetType() monitor.SuggestDriverType {
|
||||
return monitor.SuggestDriverType(rule.Type)
|
||||
}
|
||||
|
||||
//根据数据库中查询得到的信息进行适配转换,同时更新drivers中的内容
|
||||
func (rule *SSuggestSysRule) getSuggestSysAlertSetting() (*monitor.SSuggestSysAlertSetting, error) {
|
||||
setting := new(monitor.SSuggestSysAlertSetting)
|
||||
if rule.Setting == nil {
|
||||
rule.Setting = jsonutils.NewDict()
|
||||
}
|
||||
err := rule.Setting.Unmarshal(setting)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SSuggestSysRule getSuggestSysAlertSetting error")
|
||||
}
|
||||
return setting, nil
|
||||
}
|
||||
|
||||
type DiskUnsed struct {
|
||||
Status string
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysRuleManager) ListItemFilter(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
query monitor.SuggestSysRuleListInput) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
q, err = manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StandaloneResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SEnabledResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SEnabledResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleManager) ValidateCreateData(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject,
|
||||
data monitor.SuggestSysRuleCreateInput) (monitor.SuggestSysRuleCreateInput, error) {
|
||||
if data.Period == "" {
|
||||
data.Period = "12h"
|
||||
} else {
|
||||
data.Period = parseDuration(data.Period)
|
||||
}
|
||||
if data.TimeFrom == "" {
|
||||
data.TimeFrom = "24h"
|
||||
} else {
|
||||
data.TimeFrom = parseDuration(data.TimeFrom)
|
||||
}
|
||||
if data.Enabled == nil {
|
||||
enable := true
|
||||
data.Enabled = &enable
|
||||
}
|
||||
if _, err := time.ParseDuration(data.Period); err != nil {
|
||||
return data, httperrors.NewInputParameterError("Invalid period format: %s", data.Period)
|
||||
}
|
||||
if _, err := time.ParseDuration(data.TimeFrom); err != nil {
|
||||
return data, httperrors.NewInputParameterError("Invalid period format: %s", data.TimeFrom)
|
||||
}
|
||||
if dri, ok := suggestSysRuleDrivers[monitor.SuggestDriverType(data.Type)]; !ok {
|
||||
return data, httperrors.NewInputParameterError("not support type %q", data.Type)
|
||||
} else {
|
||||
// Type is uniq
|
||||
if err := db.NewNameValidator(man, ownerId, data.Type, nil); err != nil {
|
||||
return data, err
|
||||
}
|
||||
if rule, err := man.GetRuleByType(monitor.SuggestDriverType(data.Type)); err != nil {
|
||||
if errors.Cause(err) != sql.ErrNoRows {
|
||||
return data, err
|
||||
}
|
||||
} else if rule != nil {
|
||||
return data, httperrors.NewDuplicateResourceError("type %s rule already exists", data.Type)
|
||||
}
|
||||
|
||||
drvType := monitor.SuggestDriverType(data.Type)
|
||||
if drvType == monitor.SCALE_DOWN || drvType == monitor.SCALE_UP {
|
||||
if data.Setting == nil {
|
||||
return data, httperrors.NewInputParameterError("no found rule setting")
|
||||
}
|
||||
}
|
||||
if data.Setting != nil {
|
||||
if err := dri.ValidateSetting(data.Setting); err != nil {
|
||||
return data, errors.Wrap(err, "validate setting error")
|
||||
}
|
||||
} else {
|
||||
data.Setting = new(monitor.SSuggestSysAlertSetting)
|
||||
}
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (rule *SSuggestSysRule) GetDriver() ISuggestSysRuleDriver {
|
||||
return GetSuggestSysRuleDrivers()[rule.GetType()]
|
||||
}
|
||||
|
||||
func (rule *SSuggestSysRule) ValidateUpdateData(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
data monitor.SuggestSysRuleUpdateInput) (monitor.SuggestSysRuleUpdateInput, error) {
|
||||
if data.Period == "" {
|
||||
// default 30s
|
||||
data.Period = "30s"
|
||||
}
|
||||
if data.Enabled != nil {
|
||||
rule.SetEnabled(*data.Enabled)
|
||||
}
|
||||
if _, err := time.ParseDuration(data.Period); err != nil {
|
||||
return data, httperrors.NewInputParameterError("Invalid period format: %s", data.Period)
|
||||
}
|
||||
if data.Setting != nil {
|
||||
err := rule.GetDriver().ValidateSetting(data.Setting)
|
||||
if err != nil {
|
||||
return data, errors.Wrap(err, "validate setting error")
|
||||
}
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleManager) FetchCustomizeColumns(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
objs []interface{},
|
||||
fields stringutils2.SSortedStrings,
|
||||
isList bool,
|
||||
) []monitor.SuggestSysRuleDetails {
|
||||
rows := make([]monitor.SuggestSysRuleDetails, len(objs))
|
||||
virtRows := man.SStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
for i := range rows {
|
||||
rows[i] = monitor.SuggestSysRuleDetails{
|
||||
StandaloneResourceDetails: virtRows[i],
|
||||
}
|
||||
rows[i] = objs[i].(*SSuggestSysRule).getMoreDetails(rows[i])
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) getMoreDetails(out monitor.SuggestSysRuleDetails) monitor.SuggestSysRuleDetails {
|
||||
var err error
|
||||
out.Setting, err = self.getSuggestSysAlertSetting()
|
||||
if err != nil {
|
||||
log.Errorln("getMoreDetails err:", err)
|
||||
}
|
||||
out.ID = self.Id
|
||||
out.Name = self.Name
|
||||
out.Enabled = self.GetEnabled()
|
||||
self.Period = showDuration(self.Period)
|
||||
self.TimeFrom = showDuration(self.TimeFrom)
|
||||
ignore, _ := strconv.ParseBool(self.getIgnoreTimeFrom())
|
||||
if ignore {
|
||||
self.TimeFrom = ""
|
||||
}
|
||||
self.getMetricDetails(&out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) getMetricDetails(out *monitor.SuggestSysRuleDetails) {
|
||||
if out.Setting.ScaleRule != nil {
|
||||
scaleRule := *out.Setting.ScaleRule
|
||||
commonAlertMetricDetails := make([]*monitor.CommonAlertMetricDetails, len(scaleRule))
|
||||
for i, rule := range scaleRule {
|
||||
metricDetails := monitor.CommonAlertMetricDetails{
|
||||
Comparator: rule.EvalType,
|
||||
Threshold: rule.Threshold,
|
||||
DB: rule.Database,
|
||||
Measurement: rule.Measurement,
|
||||
Field: rule.Field,
|
||||
}
|
||||
getMetricDescriptionDetails(&metricDetails)
|
||||
commonAlertMetricDetails[i] = &metricDetails
|
||||
}
|
||||
out.CommonAlertMetricDetails = commonAlertMetricDetails
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) GetExtraDetails(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
isList bool,
|
||||
) (monitor.SuggestSysRuleDetails, error) {
|
||||
return monitor.SuggestSysRuleDetails{}, nil
|
||||
}
|
||||
|
||||
// after create, update Cronjob's info
|
||||
func (self *SSuggestSysRule) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
self.SStandaloneResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
|
||||
ignore, err := data.GetString("ignore_time_from")
|
||||
if err == nil {
|
||||
self.setIgnoreTimeFrom(ctx, userCred, ignore)
|
||||
}
|
||||
self.updateCronjob()
|
||||
}
|
||||
|
||||
// after update, update Cronjob's info
|
||||
func (self *SSuggestSysRule) PostUpdate(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
ignore, err := data.GetString("ignore_time_from")
|
||||
if err == nil {
|
||||
self.setIgnoreTimeFrom(ctx, userCred, ignore)
|
||||
}
|
||||
self.updateCronjob()
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) setIgnoreTimeFrom(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
ignore string) error {
|
||||
return self.SetMetadata(ctx, SUGGESTRULE_METADATA_IGNORETIME, ignore, userCred)
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) getIgnoreTimeFrom() string {
|
||||
return self.GetMetadata(SUGGESTRULE_METADATA_IGNORETIME, nil)
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) updateCronjob() {
|
||||
cronman.GetCronJobManager().Remove(self.Type)
|
||||
if self.Enabled.Bool() {
|
||||
dur, _ := time.ParseDuration(self.Period)
|
||||
cronman.GetCronJobManager().AddJobAtIntervalsWithStartRun(self.Type, dur,
|
||||
self.GetDriver().DoSuggestSysRule, true)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) AllowPerformEnable(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return db.IsAdminAllowPerform(userCred, self, "Enable")
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) PerformEnable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
err := db.EnabledPerformEnable(self, ctx, userCred, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "EnabledPerformEnable")
|
||||
}
|
||||
self.updateCronjob()
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) AllowPerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return db.IsAdminAllowPerform(userCred, self, "disable")
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) PerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
err := db.EnabledPerformEnable(self, ctx, userCred, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "EnabledPerformEnable")
|
||||
}
|
||||
self.updateCronjob()
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) AllowPerformConfig(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return db.IsAdminAllowPerform(userCred, self, "config")
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) PerformConfig(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
period, _ := data.GetString("period")
|
||||
timeFrom, _ := data.GetString("time_from")
|
||||
if len(period) != 0 {
|
||||
period = parseDuration(period)
|
||||
if _, err := time.ParseDuration(period); err != nil {
|
||||
return data, httperrors.NewInputParameterError("Invalid period format: %s", period)
|
||||
}
|
||||
}
|
||||
if len(timeFrom) != 0 {
|
||||
timeFrom = parseDuration(timeFrom)
|
||||
if _, err := time.ParseDuration(timeFrom); err != nil {
|
||||
return data, httperrors.NewInputParameterError("Invalid time_from format: %s", timeFrom)
|
||||
}
|
||||
}
|
||||
db.Update(self, func() error {
|
||||
if len(period) != 0 {
|
||||
self.Period = period
|
||||
}
|
||||
if len(timeFrom) != 0 {
|
||||
self.TimeFrom = timeFrom
|
||||
|
||||
}
|
||||
return nil
|
||||
})
|
||||
PerformConfigLog(self, userCred)
|
||||
self.updateCronjob()
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func PerformConfigLog(model db.IModel, userCred mcclient.TokenCredential) {
|
||||
db.OpsLog.LogEvent(model, db.ACT_UPDATE_RULE, "", userCred)
|
||||
logclient.AddSimpleActionLog(model, logclient.ACT_UPDATE_RULE, nil, userCred, true)
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRuleManager) AllowGetPropertyRuleType(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRuleManager) GetPropertyRuleType(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
ret := jsonutils.NewDict()
|
||||
ruleArr := jsonutils.NewArray()
|
||||
ret.Add(ruleArr, "rule-type")
|
||||
rules, err := self.GetRules()
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
drivers := GetSuggestSysRuleDrivers()
|
||||
dbTypes := make(map[monitor.SuggestDriverType]string, 0)
|
||||
for _, rule := range rules {
|
||||
if _, ok := drivers[rule.GetType()]; !ok {
|
||||
return nil, fmt.Errorf("have invalid rule type :%s", string(rule.GetType()))
|
||||
}
|
||||
dbTypes[rule.GetType()] = ""
|
||||
}
|
||||
if len(dbTypes) == len(drivers) {
|
||||
return ret, nil
|
||||
}
|
||||
for typ, driver := range drivers {
|
||||
if _, ok := dbTypes[typ]; ok {
|
||||
continue
|
||||
}
|
||||
ruleArr.Add(jsonutils.NewString(string(driver.GetType())))
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRuleManager) AllowGetPropertyDatabases(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
func (self *SSuggestSysRuleManager) GetPropertyDatabases(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
return DataSourceManager.GetDatabases()
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRuleManager) AllowGetPropertyMeasurements(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRuleManager) GetPropertyMeasurements(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
ruleType, err := query.GetString("type")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := monitor.FilterSuggestRuleMeasureMentMap[monitor.SuggestDriverType(ruleType)]; !ok {
|
||||
return nil, fmt.Errorf("param type: %s is invalid", ruleType)
|
||||
}
|
||||
measurementFilter := getMeasurementFilter(monitor.FilterSuggestRuleMeasureMentMap[monitor.SuggestDriverType(ruleType)])
|
||||
return DataSourceManager.GetMeasurements(query, measurementFilter, "")
|
||||
}
|
||||
|
||||
func getMeasurementFilter(filter string) string {
|
||||
return fmt.Sprintf(" MEASUREMENT =~ /%s.*/", filter)
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRuleManager) AllowGetPropertyMetricMeasurement(ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRuleManager) GetPropertyMetricMeasurement(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
return self.GetMetricMeasurement(query)
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRuleManager) GetMetricMeasurement(query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
database, _ := query.GetString("database")
|
||||
if database == "" {
|
||||
return jsonutils.JSONNull, merrors.NewArgIsEmptyErr("database")
|
||||
}
|
||||
measurement, _ := query.GetString("measurement")
|
||||
if measurement == "" {
|
||||
return jsonutils.JSONNull, merrors.NewArgIsEmptyErr("measurement")
|
||||
}
|
||||
dataSource, err := DataSourceManager.GetDefaultSource()
|
||||
if err != nil {
|
||||
return jsonutils.JSONNull, errors.Wrap(err, "s.GetDefaultSource")
|
||||
}
|
||||
|
||||
db := influxdb.NewInfluxdb(dataSource.Url)
|
||||
db.SetDatabase(database)
|
||||
output := new(monitor.InfluxMeasurement)
|
||||
output.Measurement = measurement
|
||||
output.Database = database
|
||||
err = getAttributesOnMeasurement(database, monitor.METRIC_FIELD, output, db)
|
||||
if err != nil {
|
||||
return jsonutils.JSONNull, errors.Wrap(err, "getAttributesOnMeasurement error")
|
||||
}
|
||||
return jsonutils.Marshal(output), nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleManager) GetRuleByType(tp monitor.SuggestDriverType) (*SSuggestSysRule, error) {
|
||||
query := man.Query().Equals("type", tp)
|
||||
rules := make([]SSuggestSysRule, 0)
|
||||
if err := db.FetchModelObjects(man, query, &rules); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(rules) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if len(rules) != 1 {
|
||||
return nil, errors.Wrapf(sqlchemy.ErrDuplicateEntry, "found %d type %s rules", len(rules), tp)
|
||||
}
|
||||
return &rules[0], nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRuleManager) GetRules(tp ...monitor.SuggestDriverType) ([]SSuggestSysRule, error) {
|
||||
rules := make([]SSuggestSysRule, 0)
|
||||
query := self.Query()
|
||||
if len(tp) > 0 {
|
||||
query.In("type", tp)
|
||||
}
|
||||
err := db.FetchModelObjects(self, query, &rules)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return rules, errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func (self *SSuggestSysRule) UpdateExecTime() {
|
||||
db.Update(self, func() error {
|
||||
self.ExecTime = time.Now()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysRuleManager) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ruleInfo struct {
|
||||
insertRuleTypes []string
|
||||
updateRules map[string]*SSuggestSysRule
|
||||
deleteRules map[string]*SSuggestSysRule
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleManager) Run(ctx context.Context) (err error) {
|
||||
sysRules, err := man.GetRules()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ruleOptor := getRuleInfo(sysRules)
|
||||
err = man.initDeleteDefaultRule(ruleOptor)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
log.Errorln("ruleTypes", ruleOptor.insertRuleTypes)
|
||||
err = man.initCreateDefaultRule(ruleOptor)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = man.initUpdateDefaultRule(ruleOptor)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleManager) initUpdateDefaultRule(rule ruleInfo) error {
|
||||
for ruleType, suggestRule := range rule.updateRules {
|
||||
ruleDris := GetSuggestSysRuleDrivers()
|
||||
if dri, ok := ruleDris[monitor.SuggestDriverType(ruleType)]; ok {
|
||||
ruleCreateInput := dri.GetDefaultRule()
|
||||
_, err := db.Update(suggestRule, func() error {
|
||||
suggestRule.Name = ruleCreateInput.Name
|
||||
suggestRule.Setting = jsonutils.Marshal(ruleCreateInput.Setting)
|
||||
suggestRule.TimeFrom = ruleCreateInput.TimeFrom
|
||||
suggestRule.Period = ruleCreateInput.Period
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "initUpdateDefaultRule error")
|
||||
}
|
||||
if ruleCreateInput.IgnoreTimeFrom != nil {
|
||||
suggestRule.setIgnoreTimeFrom(context.Background(), auth.AdminCredential(),
|
||||
strconv.FormatBool(*ruleCreateInput.IgnoreTimeFrom))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleManager) initCreateDefaultRule(rule ruleInfo) error {
|
||||
adminCredential := auth.AdminCredential()
|
||||
for _, ruleType := range rule.insertRuleTypes {
|
||||
ruleDris := GetSuggestSysRuleDrivers()
|
||||
if dri, ok := ruleDris[monitor.SuggestDriverType(ruleType)]; ok {
|
||||
createInput := dri.GetDefaultRule()
|
||||
_, err := db.DoCreate(man, context.Background(), adminCredential, nil, jsonutils.Marshal(&createInput),
|
||||
adminCredential)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "initCreateDefaultRule error")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleManager) initDeleteDefaultRule(rule ruleInfo) error {
|
||||
ctx := context.Background()
|
||||
adminCredential := auth.AdminCredential()
|
||||
for key, _ := range rule.deleteRules {
|
||||
err := db.DeleteModel(ctx, adminCredential, rule.deleteRules[key])
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "initDeleteDefaultRule")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRuleInfo(rules []SSuggestSysRule) (rul ruleInfo) {
|
||||
dbRules := make(map[string]*SSuggestSysRule)
|
||||
for i, _ := range rules {
|
||||
dbRules[rules[i].Type] = &rules[i]
|
||||
}
|
||||
defaultRules := GetSuggestSysRuleDriverTypes()
|
||||
for ruleType, _ := range dbRules {
|
||||
if defaultRules.Has(ruleType) {
|
||||
if rul.updateRules == nil {
|
||||
rul.updateRules = make(map[string]*SSuggestSysRule)
|
||||
}
|
||||
rul.updateRules[ruleType] = dbRules[ruleType]
|
||||
defaultRules.Delete(ruleType)
|
||||
delete(dbRules, ruleType)
|
||||
}
|
||||
}
|
||||
rul.insertRuleTypes = defaultRules.List()
|
||||
rul.deleteRules = dbRules
|
||||
return
|
||||
}
|
||||
|
||||
func parseDuration(dur string) string {
|
||||
var hourInt int64
|
||||
if strings.Contains(dur, "d") {
|
||||
durDay := strings.Split(dur, "d")[0]
|
||||
dur = strings.Split(dur, "d")[1]
|
||||
durDayInt, _ := strconv.ParseInt(durDay, 10, 64)
|
||||
hourInt = durDayInt * 24
|
||||
|
||||
}
|
||||
if strings.Contains(dur, "h") {
|
||||
durHour := strings.Split(dur, "h")[0]
|
||||
dur = strings.Split(dur, "h")[1]
|
||||
durHourInt, _ := strconv.ParseInt(durHour, 10, 64)
|
||||
hourInt += durHourInt
|
||||
}
|
||||
if hourInt != 0 {
|
||||
dur = fmt.Sprintf("%dh%s", hourInt, dur)
|
||||
}
|
||||
return dur
|
||||
}
|
||||
|
||||
func showDuration(dur string) string {
|
||||
var durStr string
|
||||
if strings.Contains(dur, "h") {
|
||||
durInt, _ := strconv.ParseInt(strings.Split(dur, "h")[0], 10, 64)
|
||||
durStr = showDuration_(durInt, "h")
|
||||
}
|
||||
if strings.Contains(dur, "m") {
|
||||
durInt, _ := strconv.ParseInt(strings.Split(dur, "m")[0], 10, 64)
|
||||
durStr = showDuration_(durInt, "m")
|
||||
}
|
||||
if strings.Contains(dur, "s") {
|
||||
durInt, _ := strconv.ParseInt(strings.Split(dur, "s")[0], 10, 64)
|
||||
durStr = showDuration_(durInt, "s")
|
||||
}
|
||||
return durStr
|
||||
}
|
||||
|
||||
func showDuration_(dur int64, sign string) string {
|
||||
var durUp, durSign int64
|
||||
var upSign, durStr string
|
||||
if sign == "s" && dur >= 60 {
|
||||
upSign = "m"
|
||||
durUp = dur / 60
|
||||
durSign = dur % 60
|
||||
durStr = showDuration_(durUp, upSign)
|
||||
}
|
||||
if sign == "m" && dur >= 60 {
|
||||
upSign = "h"
|
||||
durUp = dur / 60
|
||||
durSign = dur % 60
|
||||
durStr = showDuration_(durUp, upSign)
|
||||
}
|
||||
if sign == "h" && dur >= 24 {
|
||||
upSign = "d"
|
||||
durUp = dur / 24
|
||||
durSign = dur % 24
|
||||
}
|
||||
|
||||
if len(upSign) != 0 {
|
||||
durBuf := strings.Builder{}
|
||||
durBuf.WriteString(fmt.Sprintf("%s%d%s", durStr, durUp, upSign))
|
||||
if durSign != 0 {
|
||||
durBuf.WriteString(fmt.Sprintf("%d%s", durSign, sign))
|
||||
}
|
||||
return durBuf.String()
|
||||
}
|
||||
return fmt.Sprintf("%d%s", dur, sign)
|
||||
}
|
||||
@@ -1,543 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
var (
|
||||
SuggestSysRuleConfigManager *SSuggestSysRuleConfigManager
|
||||
)
|
||||
|
||||
func init() {
|
||||
SuggestSysRuleConfigManager = &SSuggestSysRuleConfigManager{
|
||||
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
|
||||
&SSuggestSysRuleConfig{},
|
||||
"suggestsysruleconfig_tbl",
|
||||
"suggestsysruleconfig",
|
||||
"suggestsysruleconfigs",
|
||||
),
|
||||
}
|
||||
SuggestSysRuleConfigManager.SetVirtualObject(SuggestSysRuleConfigManager)
|
||||
}
|
||||
|
||||
// +onecloud:swagger-gen-model-singular=suggestsysruleconfig
|
||||
// +onecloud:swagger-gen-model-plural=suggestsysruleconfigs
|
||||
type SSuggestSysRuleConfigManager struct {
|
||||
db.SStandaloneResourceBaseManager
|
||||
SMonitorScopedResourceManager
|
||||
}
|
||||
|
||||
type SSuggestSysRuleConfig struct {
|
||||
db.SStandaloneResourceBase
|
||||
SMonitorScopedResource
|
||||
|
||||
// RuleId is SSuggestSysRule model object id
|
||||
// RuleId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
// Type is suggestsysrules driver type
|
||||
Type string `width:"256" charset:"ascii" list:"user" create:"optional"`
|
||||
// ResourceType is suggestsysrules driver resource type
|
||||
ResourceType string `width:"256" charset:"ascii" list:"user" create:"optional"`
|
||||
// ResourceId is suggest alert result resource id
|
||||
ResourceId string `width:"256" charset:"ascii" list:"user" create:"optional"`
|
||||
// IgnoreAlert means whether or not show SSuggestSysAlert results for current scope
|
||||
IgnoreAlert bool `nullable:"false" default:"false" list:"user" create:"optional" update:"user"`
|
||||
}
|
||||
|
||||
// InitInitScopeSuggestConfigs init default configs to project, domain and system scope
|
||||
func (man *SSuggestSysRuleConfigManager) InitScopeConfigs(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
if err := man.InitSystemScopeConfig(ctx, userCred); err != nil {
|
||||
log.Errorf("init system scope suggest config error: %v", err)
|
||||
}
|
||||
domains, projects, err := FetchAllRemoteDomainProjects(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("fetch remote domain projects: %v", err)
|
||||
return
|
||||
}
|
||||
if err := man.InitDomainScopeConfig(ctx, userCred, domains); err != nil {
|
||||
log.Errorf("init domain scope suggest config error: %v", err)
|
||||
}
|
||||
if err := man.InitProjectScopeConfig(ctx, userCred, projects); err != nil {
|
||||
log.Errorf("init project scope suggest config error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysRuleConfigManager) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) Run(ctx context.Context) error {
|
||||
return man.deleteUnusedConfig()
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysRuleConfigManager) deleteUnusedConfig() error {
|
||||
userCred := auth.AdminCredential()
|
||||
configs, err := manager.GetConfigsByScope(rbacutils.ScopeNone, userCred, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SSuggestSysRuleConfigManager get ignore is false configs error")
|
||||
}
|
||||
for i, _ := range configs {
|
||||
err := (&configs[i]).CustomizeDelete(context.Background(), userCred, jsonutils.NewDict(),
|
||||
jsonutils.NewDict())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "init CustomizeDelete SuggestSysRuleConfig error")
|
||||
}
|
||||
err = (&configs[i]).Delete(context.Background(), userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "init Delete SuggestSysRuleConfig error")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
SUGGEST_SCOPE_CONFIG = "suggest_scope_config"
|
||||
)
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) initScopeConfig(ctx context.Context, userCred mcclient.TokenCredential, scope rbacutils.TRbacScope, tenant *db.STenant) error {
|
||||
drivers := GetSuggestSysRuleDrivers()
|
||||
config := jsonutils.NewDict()
|
||||
configJSON := tenant.GetMetadataJson(SUGGEST_SCOPE_CONFIG, userCred)
|
||||
if configJSON != nil {
|
||||
if err := configJSON.Unmarshal(config); err != nil {
|
||||
return errors.Wrap(err, "unmarshal metadata config")
|
||||
}
|
||||
}
|
||||
for _, drv := range drivers {
|
||||
if ok, _ := config.Bool(string(drv.GetType())); ok {
|
||||
continue
|
||||
}
|
||||
if err := man.createFromDriver(ctx, scope, drv, tenant); err != nil {
|
||||
return errors.Wrapf(err, "init scope %s from driver %s", scope, drv.GetType())
|
||||
}
|
||||
config.Set(string(drv.GetType()), jsonutils.JSONTrue)
|
||||
}
|
||||
|
||||
if err := tenant.SetMetadata(ctx, SUGGEST_SCOPE_CONFIG, config, userCred); err != nil {
|
||||
return errors.Wrap(err, "set suggest scope config metadata")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) InitSystemScopeConfig(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
systemFakeTenantId := "monitor.fake.tenant"
|
||||
systemFakeTenant, err := db.TenantCacheManager.Save(ctx, systemFakeTenantId, systemFakeTenantId, systemFakeTenantId, systemFakeTenantId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "save system fake tenant")
|
||||
}
|
||||
return man.initScopeConfig(ctx, userCred, rbacutils.ScopeSystem, systemFakeTenant)
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) InitDomainScopeConfig(ctx context.Context, userCred mcclient.TokenCredential, domains []*db.STenant) error {
|
||||
errs := make([]error, 0)
|
||||
for _, domain := range domains {
|
||||
if err := man.initScopeConfig(ctx, userCred, rbacutils.ScopeDomain, domain); err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "init domain %s", domain.GetId()))
|
||||
}
|
||||
}
|
||||
return errors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) InitProjectScopeConfig(ctx context.Context, userCred mcclient.TokenCredential, projects []*db.STenant) error {
|
||||
for _, project := range projects {
|
||||
if err := man.initScopeConfig(ctx, userCred, rbacutils.ScopeProject, project); err != nil {
|
||||
return errors.Wrapf(err, "init project %v", project)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) createFromDriver(ctx context.Context, scope rbacutils.TRbacScope, drv ISuggestSysRuleDriver, project *db.STenant) error {
|
||||
config := new(SSuggestSysRuleConfig)
|
||||
drvType := string(drv.GetType())
|
||||
name := fmt.Sprintf("%s-%s", strings.ToLower(drvType), scope)
|
||||
if scope != rbacutils.ScopeSystem && project == nil {
|
||||
return errors.Errorf("scope %s not allow nil project", scope)
|
||||
}
|
||||
config.Name = name
|
||||
config.Type = drvType
|
||||
config.ResourceType = string(drv.GetResourceType())
|
||||
config.IgnoreAlert = false
|
||||
switch scope {
|
||||
case rbacutils.ScopeDomain:
|
||||
config.DomainId = project.GetId()
|
||||
case rbacutils.ScopeProject:
|
||||
config.DomainId = project.GetDomainId()
|
||||
config.ProjectId = project.GetId()
|
||||
}
|
||||
config.SetModelManager(man, config)
|
||||
|
||||
ownerId := config.SMonitorScopedResource.GetOwnerId()
|
||||
data := monitor.SuggestSysRuleConfigCreateInput{}
|
||||
data.Scope = string(scope)
|
||||
data.ProjectDomainId = ownerId.GetProjectDomainId()
|
||||
data.ProjectId = ownerId.GetProjectId()
|
||||
// HACK parentId, ref SScopedResourceBaseManager.FetchUniqValues
|
||||
uniqValues := man.FetchUniqValues(ctx, data.JSON(data))
|
||||
if err := db.NewNameValidator(man, ownerId, name, uniqValues); err != nil {
|
||||
return errors.Wrapf(err, "validate name for %q, domain %q, project %q", scope, ownerId.GetProjectDomainId(), ownerId.GetProjectId())
|
||||
}
|
||||
|
||||
if err := man.TableSpec().Insert(ctx, config); err != nil {
|
||||
return errors.Wrapf(err, "insert config %#v", config)
|
||||
}
|
||||
if _, err := db.Update(config, func() error {
|
||||
if scope == rbacutils.ScopeSystem {
|
||||
config.DomainId = ""
|
||||
config.ProjectId = ""
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "update scope info")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) AllowGetPropertySupportTypes(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) GetPropertySupportTypes(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) (*monitor.SuggestSysRuleConfigSupportTypes, error) {
|
||||
ret := &monitor.SuggestSysRuleConfigSupportTypes{
|
||||
Types: make([]monitor.SuggestDriverType, 0),
|
||||
ResourceTypes: make([]string, 0),
|
||||
}
|
||||
drivers := GetSuggestSysRuleDrivers()
|
||||
for _, drv := range drivers {
|
||||
ret.Types = append(ret.Types, drv.GetType())
|
||||
}
|
||||
ret.ResourceTypes = GetSuggestSysRuleResourceTypes().List()
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) AllowGetPropertyTypeInfo(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) GetPropertyTypeInfo(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject) (*monitor.SuggestSysRuleConfigTypeInfo, error) {
|
||||
searchInput := new(monitor.SuggestSysRuleConfigListInput)
|
||||
err := query.Unmarshal(searchInput)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("GetPropertyTypeInfo Unmarshal error:%v", err)
|
||||
}
|
||||
if searchInput.Type == nil {
|
||||
return nil, httperrors.NewInputParameterError("SuggestSysRuleConfig type is empty")
|
||||
}
|
||||
ownerId, err := man.FetchOwnerId(ctx, query)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("SSuggestSysRuleConfigManager FetchOwnerId error:%v", err)
|
||||
}
|
||||
if ownerId == nil {
|
||||
return nil, httperrors.NewInputParameterError("project or domain is empty")
|
||||
}
|
||||
configs, err := man.getConfigsOfBatchType(rbacutils.TRbacScope(searchInput.Scope), ownerId, string(*searchInput.Type))
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("SSuggestSysRuleConfigManager getConfigsOfBatchType error:%v", err)
|
||||
}
|
||||
typeInfo := new(monitor.SuggestSysRuleConfigTypeInfo)
|
||||
if len(configs) != 0 {
|
||||
typeInfo.Name = configs[0].Name
|
||||
}
|
||||
return typeInfo, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) getConfigsQueryByScope(scope rbacutils.TRbacScope,
|
||||
ownerId mcclient.IIdentityProvider) *sqlchemy.SQuery {
|
||||
query := man.Query()
|
||||
switch scope {
|
||||
case rbacutils.ScopeSystem:
|
||||
query = query.IsNullOrEmpty("domain_id").IsNullOrEmpty("tenant_id")
|
||||
case rbacutils.ScopeDomain:
|
||||
query = query.Equals("domain_id", ownerId.GetProjectDomainId()).IsNullOrEmpty("tenant_id")
|
||||
case rbacutils.ScopeProject:
|
||||
query = query.Equals("tenant_id", ownerId.GetProjectId())
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) getConfigsOfBatchType(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, Typ string) ([]SSuggestSysRuleConfig, error) {
|
||||
query := man.getConfigsQueryByScope(scope, ownerId)
|
||||
query = query.Equals("type", Typ).IsNullOrEmpty("resource_id")
|
||||
configs := make([]SSuggestSysRuleConfig, 0)
|
||||
if err := db.FetchModelObjects(man, query, &configs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) NamespaceScope() rbacutils.TRbacScope {
|
||||
return rbacutils.ScopeNone
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) GetConfigsByScope(scope rbacutils.TRbacScope, userCred mcclient.TokenCredential, ignoreAlert bool) ([]SSuggestSysRuleConfig, error) {
|
||||
q := man.getConfigsQueryByScope(scope, userCred)
|
||||
q = q.Equals("ignore_alert", ignoreAlert)
|
||||
configs := make([]SSuggestSysRuleConfig, 0)
|
||||
if err := db.FetchModelObjects(man, q, &configs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input *monitor.SuggestSysRuleConfigCreateInput) (*monitor.SuggestSysRuleConfigCreateInput, error) {
|
||||
var err error
|
||||
input.StandaloneResourceCreateInput, err = man.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StandaloneResourceCreateInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
input.ScopedResourceCreateInput, err = man.SScopedResourceBaseManager.ValidateCreateData(man, ctx, userCred, ownerId, query, input.ScopedResourceCreateInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if input.Type != nil {
|
||||
drvs := GetSuggestSysRuleDrivers()
|
||||
if _, ok := drvs[*input.Type]; !ok {
|
||||
if err != nil {
|
||||
return nil, httperrors.NewNotFoundError("not found type %q", *input.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
if input.ResourceType != nil {
|
||||
if !GetSuggestSysRuleResourceTypes().Has(string(*input.ResourceType)) {
|
||||
return nil, httperrors.NewNotFoundError("not found resource_type %q", *input.ResourceType)
|
||||
}
|
||||
if input.Type != nil {
|
||||
drv := SuggestSysRuleManager.GetDriver(*input.Type)
|
||||
if drv == nil {
|
||||
return nil, httperrors.NewNotFoundError("not found driver by type %q", *input.Type)
|
||||
}
|
||||
if drv.GetResourceType() != *input.ResourceType {
|
||||
return nil, httperrors.NewNotAcceptableError("resource type %q of driver does not match input %q", drv.GetType(), *input.ResourceType)
|
||||
}
|
||||
}
|
||||
}
|
||||
if input.ResourceId != nil && input.ResourceType == nil {
|
||||
return nil, httperrors.NewNotAcceptableError("resource type must provided when resource_id specified")
|
||||
}
|
||||
if input.Type == nil && input.ResourceType == nil {
|
||||
return nil, httperrors.NewNotAcceptableError("type or resource_type must provided")
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) GetRuleByType(drvType monitor.SuggestDriverType) (*SSuggestSysRule, error) {
|
||||
drv := SuggestSysRuleManager.GetDriver(drvType)
|
||||
if drv == nil {
|
||||
return nil, httperrors.NewInputParameterError("not support type %q", drvType)
|
||||
}
|
||||
rule, err := SuggestSysRuleManager.GetRuleByType(drvType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rule == nil {
|
||||
return nil, httperrors.NewNotFoundError("not found rule by type %q", drvType)
|
||||
}
|
||||
return rule, nil
|
||||
}
|
||||
|
||||
func (conf *SSuggestSysRuleConfig) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
if err := conf.SStandaloneResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := conf.SScopedResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (conf *SSuggestSysRuleConfig) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
scope, _ := data.GetString("scope")
|
||||
_, err := db.Update(conf, func() error {
|
||||
switch rbacutils.TRbacScope(scope) {
|
||||
case rbacutils.ScopeSystem:
|
||||
conf.DomainId = ""
|
||||
conf.ProjectId = ""
|
||||
case rbacutils.ScopeDomain:
|
||||
conf.ProjectId = ""
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("post update %s scope info error: %v", conf.GetName(), err)
|
||||
}
|
||||
}
|
||||
|
||||
func (conf *SSuggestSysRuleConfig) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *monitor.SuggestSysRuleConfigUpdateInput) (*monitor.SuggestSysRuleConfigUpdateInput, error) {
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) FetchCustomizeColumns(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
objs []interface{},
|
||||
fields stringutils2.SSortedStrings,
|
||||
isList bool,
|
||||
) []monitor.SuggestSysRuleConfigDetails {
|
||||
rows := make([]monitor.SuggestSysRuleConfigDetails, len(objs))
|
||||
stdRows := man.SStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
scopedRows := man.SScopedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
for i := range rows {
|
||||
rows[i] = monitor.SuggestSysRuleConfigDetails{
|
||||
StandaloneResourceDetails: stdRows[i],
|
||||
ScopedResourceBaseInfo: scopedRows[i],
|
||||
}
|
||||
rows[i] = objs[i].(*SSuggestSysRuleConfig).getMoreColumns(rows[i])
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
func (conf *SSuggestSysRuleConfig) getMoreColumns(out monitor.SuggestSysRuleConfigDetails) monitor.SuggestSysRuleConfigDetails {
|
||||
if conf.Type != "" {
|
||||
rule, err := conf.GetRule()
|
||||
if err != nil {
|
||||
log.Errorf("Get config %q rule error: %v", conf.GetName(), err)
|
||||
return out
|
||||
}
|
||||
if rule == nil {
|
||||
return out
|
||||
}
|
||||
out.RuleId = rule.GetId()
|
||||
out.Rule = rule.GetName()
|
||||
out.RuleEnabled = rule.GetEnabled()
|
||||
if len(conf.ResourceId) != 0 {
|
||||
out.ResName = SuggestSysAlertManager.getOriName(conf.Name, conf.Type)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (conf *SSuggestSysRuleConfig) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, isList bool) (monitor.SuggestSysRuleConfigDetails, error) {
|
||||
return monitor.SuggestSysRuleConfigDetails{}, nil
|
||||
}
|
||||
|
||||
func (conf *SSuggestSysRuleConfig) GetRule() (*SSuggestSysRule, error) {
|
||||
if conf.Type == "" {
|
||||
return nil, nil
|
||||
}
|
||||
return SuggestSysRuleManager.GetRuleByType(monitor.SuggestDriverType(conf.Type))
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query monitor.SuggestSysRuleConfigListInput) (*sqlchemy.SQuery, error) {
|
||||
q, err := man.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StandaloneResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = man.SScopedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ScopedResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SScopedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
if query.Type != nil {
|
||||
q.Equals("type", *query.Type)
|
||||
}
|
||||
if query.ResourceType != nil {
|
||||
q.Equals("resource_type", *query.ResourceType)
|
||||
}
|
||||
q.IsTrue("ignore_alert")
|
||||
if query.IgnoreAlert != nil {
|
||||
if *query.IgnoreAlert {
|
||||
q.IsTrue("ignore_alert")
|
||||
} else {
|
||||
q.IsFalse("ignore_alert")
|
||||
}
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (man *SSuggestSysRuleConfigManager) OrderByExtraFields(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query monitor.SuggestSysRuleConfigListInput) (*sqlchemy.SQuery, error) {
|
||||
q, err := man.SStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StandaloneResourceListInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
q, err = man.SScopedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ScopedResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (conf *SSuggestSysRuleConfig) AllowPerformToggleAlert(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return conf.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, conf, "toggle-alert")
|
||||
}
|
||||
|
||||
func (conf *SSuggestSysRuleConfig) PerformToggleAlert(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONDict, data jsonutils.JSONDict) (jsonutils.JSONObject, error) {
|
||||
var ignoreAlert bool
|
||||
if conf.IgnoreAlert {
|
||||
ignoreAlert = false
|
||||
} else {
|
||||
ignoreAlert = true
|
||||
}
|
||||
if _, err := db.Update(conf, func() error {
|
||||
conf.IgnoreAlert = ignoreAlert
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (conf *SSuggestSysRuleConfig) ShouldIgnoreAlert(alert *SSuggestSysAlert) bool {
|
||||
if !conf.IgnoreAlert {
|
||||
return false
|
||||
}
|
||||
drv := alert.GetDriver()
|
||||
if conf.ResourceId == "" {
|
||||
if conf.Type == alert.Type {
|
||||
return true
|
||||
}
|
||||
if conf.ResourceType == string(drv.GetResourceType()) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if conf.ResourceId != alert.ResId {
|
||||
return false
|
||||
}
|
||||
if conf.ResourceType == string(drv.GetResourceType()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (manager *SSuggestSysRuleConfigManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
q, err = manager.SStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = manager.SScopedResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
return q, httperrors.ErrNotFound
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/util/sets"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
var (
|
||||
//存储初始化的内容,同时起到默认配置的作用。
|
||||
suggestSysRuleDrivers = make(map[monitor.SuggestDriverType]ISuggestSysRuleDriver, 0)
|
||||
)
|
||||
|
||||
type ISuggestSysRuleDriver interface {
|
||||
GetType() monitor.SuggestDriverType
|
||||
GetResourceType() monitor.MonitorResourceType
|
||||
GetAction() monitor.SuggestDriverAction
|
||||
GetSuggest() monitor.MonitorSuggest
|
||||
GetDefaultRule() monitor.SuggestSysRuleCreateInput
|
||||
// validate on create
|
||||
ValidateSetting(input *monitor.SSuggestSysAlertSetting) error
|
||||
|
||||
// method call for cronjob
|
||||
DoSuggestSysRule(ctx context.Context, userCred mcclient.TokenCredential, isStart bool)
|
||||
Run(rule *SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting)
|
||||
|
||||
// resolve thing for the rule
|
||||
StartResolveTask(ctx context.Context, userCred mcclient.TokenCredential, suggestSysAlert *SSuggestSysAlert,
|
||||
params *jsonutils.JSONDict) error
|
||||
Resolve(data *SSuggestSysAlert) error
|
||||
}
|
||||
|
||||
func RegisterSuggestSysRuleDrivers(drvs ...ISuggestSysRuleDriver) {
|
||||
for _, drv := range drvs {
|
||||
suggestSysRuleDrivers[drv.GetType()] = drv
|
||||
}
|
||||
}
|
||||
|
||||
func GetSuggestSysRuleDrivers() map[monitor.SuggestDriverType]ISuggestSysRuleDriver {
|
||||
return suggestSysRuleDrivers
|
||||
}
|
||||
|
||||
func GetSuggestSysRuleResourceTypes() sets.String {
|
||||
result := sets.NewString()
|
||||
for _, drv := range suggestSysRuleDrivers {
|
||||
result.Insert(string(drv.GetResourceType()))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func GetSuggestSysRuleDriverTypes() sets.String {
|
||||
result := sets.NewString()
|
||||
for _, drv := range suggestSysRuleDrivers {
|
||||
result.Insert(string(drv.GetType()))
|
||||
}
|
||||
return result
|
||||
|
||||
}
|
||||
@@ -55,10 +55,7 @@ func InitHandlers(app *appsrv.Application) {
|
||||
models.NodeAlertManager,
|
||||
models.MeterAlertManager,
|
||||
models.NotificationManager,
|
||||
models.SuggestSysRuleManager,
|
||||
models.SuggestSysAlertManager,
|
||||
models.CommonAlertManager,
|
||||
models.SuggestSysRuleConfigManager,
|
||||
models.MetricMeasurementManager,
|
||||
models.MetricFieldManager,
|
||||
models.AlertRecordManager,
|
||||
|
||||
@@ -38,7 +38,6 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/monitor/options"
|
||||
"yunion.io/x/onecloud/pkg/monitor/registry"
|
||||
"yunion.io/x/onecloud/pkg/monitor/subscriptionmodel"
|
||||
"yunion.io/x/onecloud/pkg/monitor/suggestsysdrivers"
|
||||
_ "yunion.io/x/onecloud/pkg/monitor/tasks"
|
||||
_ "yunion.io/x/onecloud/pkg/monitor/tsdb/driver/influxdb"
|
||||
)
|
||||
@@ -64,7 +63,6 @@ func StartService() {
|
||||
go startServices()
|
||||
|
||||
cron := cronman.InitCronJobManager(true, opts.CronJobWorkerCount)
|
||||
suggestsysdrivers.InitSuggestSysRuleCronjob()
|
||||
cron.AddJobAtIntervalsWithStartRun("InitAlertResourceAdminRoleUsers", time.Duration(opts.InitAlertResourceAdminRoleUsersIntervalSeconds)*time.Second, models.GetAlertResourceManager().GetAdminRoleUsers, true)
|
||||
cron.Start()
|
||||
defer cron.Stop()
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
)
|
||||
|
||||
type baseDriver struct {
|
||||
driverType monitor.SuggestDriverType
|
||||
resourceType monitor.MonitorResourceType
|
||||
action monitor.SuggestDriverAction
|
||||
suggest monitor.MonitorSuggest
|
||||
defRule monitor.SuggestSysRuleCreateInput
|
||||
}
|
||||
|
||||
func newBaseDriver(
|
||||
drvType monitor.SuggestDriverType,
|
||||
resType monitor.MonitorResourceType,
|
||||
action monitor.SuggestDriverAction,
|
||||
suggest monitor.MonitorSuggest,
|
||||
defRule monitor.SuggestSysRuleCreateInput,
|
||||
) *baseDriver {
|
||||
return &baseDriver{
|
||||
driverType: drvType,
|
||||
resourceType: resType,
|
||||
action: action,
|
||||
suggest: suggest,
|
||||
defRule: defRule,
|
||||
}
|
||||
}
|
||||
|
||||
func (drv baseDriver) GetType() monitor.SuggestDriverType {
|
||||
return drv.driverType
|
||||
}
|
||||
|
||||
func (drv baseDriver) GetResourceType() monitor.MonitorResourceType {
|
||||
return drv.resourceType
|
||||
}
|
||||
|
||||
func (drv baseDriver) GetAction() monitor.SuggestDriverAction {
|
||||
return drv.action
|
||||
}
|
||||
|
||||
func (drv baseDriver) GetSuggest() monitor.MonitorSuggest {
|
||||
return drv.suggest
|
||||
}
|
||||
|
||||
func (drv baseDriver) GetDefaultRule() monitor.SuggestSysRuleCreateInput {
|
||||
return drv.defRule
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
mod "yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type logInput struct {
|
||||
ObjId string `json:"obj_id"`
|
||||
ObjType string `json:"obj_type"`
|
||||
Action string `json:"action"`
|
||||
Scope string `json:"scope"`
|
||||
Limit string `json:"limit"`
|
||||
}
|
||||
|
||||
func DealAlertData(drvType monitor.SuggestDriverType, oldAlerts []models.SSuggestSysAlert, newAlerts []jsonutils.JSONObject) {
|
||||
rules, err := models.SuggestSysRuleManager.GetRules(drvType)
|
||||
if err != nil {
|
||||
log.Errorf("get suggest rule by type %q error: %v", drvType, err)
|
||||
return
|
||||
}
|
||||
if len(rules) == 0 {
|
||||
log.Errorf("not found suggest rule by type %q", drvType)
|
||||
return
|
||||
}
|
||||
|
||||
rules[0].UpdateExecTime()
|
||||
adminCredential := auth.AdminCredential()
|
||||
|
||||
oldMap := make(map[string]models.SSuggestSysAlert, 0)
|
||||
for _, alert := range oldAlerts {
|
||||
oldMap[alert.ResId] = alert
|
||||
}
|
||||
for _, newAlert := range newAlerts {
|
||||
res_id, _ := newAlert.GetString("res_id")
|
||||
if oldAlert, ok := oldMap[res_id]; ok {
|
||||
//更新的alert
|
||||
_, err := db.Update(&oldAlert, func() error {
|
||||
err := newAlert.Unmarshal(&oldAlert)
|
||||
if err != nil {
|
||||
errMsg := fmt.Sprintf("unmarshal fail: %s", err)
|
||||
log.Errorf(errMsg)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorln("更新alert失败", err)
|
||||
}
|
||||
delete(oldMap, res_id)
|
||||
} else {
|
||||
//新增的alert
|
||||
ownerId, err := models.SuggestSysAlertManager.FetchOwnerId(context.Background(), newAlert)
|
||||
if err != nil {
|
||||
log.Errorf("create SuggestSysAlert FetchOwnerId param:%v. error:%v", newAlert, err)
|
||||
continue
|
||||
}
|
||||
_, err = db.DoCreate(models.SuggestSysAlertManager, context.Background(), adminCredential, nil, newAlert,
|
||||
ownerId)
|
||||
if err != nil {
|
||||
log.Errorf("create new suggest alert %v error: %v", newAlert, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, oldAlert := range oldMap {
|
||||
err := oldAlert.RealDelete(context.Background(), adminCredential)
|
||||
if err != nil {
|
||||
log.Errorln("删除旧alert数据失败", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func doSuggestSysRule(ctx context.Context, userCred mcclient.TokenCredential, isStart bool, drv models.ISuggestSysRuleDriver) {
|
||||
var instance *monitor.SSuggestSysAlertSetting
|
||||
suggestSysSettingMap, err := models.SuggestSysRuleManager.FetchSuggestSysAlertSettings(drv.GetType())
|
||||
if err != nil {
|
||||
log.Errorf("DoSuggestSysRule error: %v", err)
|
||||
return
|
||||
}
|
||||
if details, ok := suggestSysSettingMap[drv.GetType()]; ok {
|
||||
instance = details.Setting
|
||||
}
|
||||
rule, err := models.SuggestSysRuleManager.GetRuleByType(drv.GetType())
|
||||
if err != nil {
|
||||
log.Errorf("Get rule by type %s: %v", drv.GetType(), err)
|
||||
return
|
||||
}
|
||||
drv.Run(rule, instance)
|
||||
}
|
||||
|
||||
func getLastAlerts(rule models.ISuggestSysRuleDriver) ([]models.SSuggestSysAlert, error) {
|
||||
oldAlert, err := models.SuggestSysAlertManager.GetResources(rule.GetType())
|
||||
if err != nil {
|
||||
return oldAlert, errors.Wrapf(err, "get last alerts by type %s", rule.GetType())
|
||||
}
|
||||
return oldAlert, nil
|
||||
}
|
||||
|
||||
type iRuleDriver interface {
|
||||
models.ISuggestSysRuleDriver
|
||||
GetLatestAlerts(rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) ([]jsonutils.JSONObject, error)
|
||||
}
|
||||
|
||||
func Run(drv iRuleDriver, rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) {
|
||||
oldAlert, err := getLastAlerts(drv)
|
||||
if err != nil {
|
||||
log.Errorf("get %s old alert result: %v", drv.GetType(), err)
|
||||
return
|
||||
}
|
||||
|
||||
newAlerts, err := drv.GetLatestAlerts(rule, setting)
|
||||
if err != nil {
|
||||
log.Errorf("get %s latest alert results: %v", drv.GetType(), err)
|
||||
return
|
||||
}
|
||||
DealAlertData(drv.GetType(), oldAlert, newAlerts)
|
||||
}
|
||||
|
||||
func getSuggestSysAlertFromJson(obj jsonutils.JSONObject, rule models.ISuggestSysRuleDriver) (*models.SSuggestSysAlert, error) {
|
||||
suggestSysAlert := new(models.SSuggestSysAlert)
|
||||
alertData := jsonutils.DeepCopy(obj).(*jsonutils.JSONDict)
|
||||
id, _ := alertData.GetString("id")
|
||||
alertData.Add(jsonutils.NewString(id), "res_id")
|
||||
alertData.Remove("id")
|
||||
|
||||
err := alertData.Unmarshal(suggestSysAlert)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getSuggestSysAlertFromJson's alertData Unmarshal error")
|
||||
}
|
||||
if val, err := alertData.GetString("account"); err == nil {
|
||||
suggestSysAlert.Cloudaccount = val
|
||||
}
|
||||
suggestSysAlert.Type = string(rule.GetType())
|
||||
suggestSysAlert.Name = fmt.Sprintf("%s-%s", suggestSysAlert.Name, suggestSysAlert.Type)
|
||||
suggestSysAlert.ResMeta = obj
|
||||
suggestSysAlert.Action = string(rule.GetAction())
|
||||
suggestSysAlert.Status = monitor.SUGGEST_ALERT_READY
|
||||
getResourceAmount(suggestSysAlert, time.Now().Add(-30*24*time.Hour))
|
||||
return suggestSysAlert, nil
|
||||
}
|
||||
|
||||
func getResourceObjLatestUsedTime(resObj jsonutils.JSONObject, param logInput) (time.Time, error) {
|
||||
logActions := getResourceObjLogOfAction(param)
|
||||
latestTime, err := getLatestActionTimeFromLogs(logActions)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
||||
if latestTime == nil {
|
||||
createdAt, _ := resObj.GetTime("created_at")
|
||||
latestTime = &createdAt
|
||||
}
|
||||
return *latestTime, nil
|
||||
}
|
||||
|
||||
func getResourceObjLogOfAction(param logInput) []jsonutils.JSONObject {
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
list, err := mod.Logs.List(session, jsonutils.Marshal(¶m))
|
||||
if err != nil {
|
||||
log.Errorln("get Logs err", err)
|
||||
return []jsonutils.JSONObject{}
|
||||
}
|
||||
if list == nil || len(list.Data) == 0 {
|
||||
return []jsonutils.JSONObject{}
|
||||
}
|
||||
return list.Data
|
||||
}
|
||||
|
||||
func getLatestActionTimeFromLogs(logActions []jsonutils.JSONObject) (*time.Time, error) {
|
||||
var latestTime *time.Time = nil
|
||||
for _, aLog := range logActions {
|
||||
ops_time, err := aLog.GetTime("ops_time")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return nil, err
|
||||
}
|
||||
if latestTime == nil {
|
||||
|
||||
latestTime = &ops_time
|
||||
}
|
||||
if ops_time.Sub(*latestTime) > 0 {
|
||||
latestTime = &ops_time
|
||||
}
|
||||
}
|
||||
return latestTime, nil
|
||||
}
|
||||
|
||||
func getResourceAmount(alert *models.SSuggestSysAlert, lastUsedTime time.Time) {
|
||||
param := jsonutils.NewDict()
|
||||
param.Add(jsonutils.NewString("system"), "scope")
|
||||
param.Add(jsonutils.NewString("0"), "limit")
|
||||
filter := fmt.Sprintf("resource_id.equals(%s)", alert.ResId)
|
||||
param.Add(jsonutils.NewString(filter), "filter")
|
||||
|
||||
start_day := timeutils.ShortDate(lastUsedTime)
|
||||
end_day := timeutils.ShortDate(time.Now())
|
||||
|
||||
param.Add(jsonutils.NewString(start_day), "start_day")
|
||||
param.Add(jsonutils.NewString(end_day), "end_day")
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
billRtn, err := mod.DailyBills.List(session, param)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return
|
||||
}
|
||||
for _, bill := range billRtn.Data {
|
||||
amount, err := bill.Float("amount")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
break
|
||||
}
|
||||
alert.Amount += amount
|
||||
currency, err := bill.GetString("currency")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
alert.Currency = currency
|
||||
}
|
||||
}
|
||||
|
||||
func ListAllResources(manager modulebase.Manager, params *jsonutils.JSONDict) ([]jsonutils.JSONObject, error) {
|
||||
if params == nil {
|
||||
params = jsonutils.NewDict()
|
||||
}
|
||||
params.Add(jsonutils.NewString("system"), "scope")
|
||||
params.Add(jsonutils.NewInt(0), "limit")
|
||||
var count int
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
objs := make([]jsonutils.JSONObject, 0)
|
||||
for {
|
||||
params.Set("offset", jsonutils.NewInt(int64(count)))
|
||||
result, err := manager.List(session, params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "list %s resources with params %s", manager.KeyString(), params.String())
|
||||
}
|
||||
for _, data := range result.Data {
|
||||
objs = append(objs, data)
|
||||
}
|
||||
total := result.Total
|
||||
count = count + len(result.Data)
|
||||
if count >= total {
|
||||
break
|
||||
}
|
||||
}
|
||||
return objs, nil
|
||||
}
|
||||
|
||||
func GenerateName(name, hint string) string {
|
||||
return fmt.Sprintf("%s-%s", name, hint)
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type DiskUnused struct {
|
||||
*baseDriver
|
||||
}
|
||||
|
||||
func NewDiskUnusedDriver() models.ISuggestSysRuleDriver {
|
||||
return &DiskUnused{
|
||||
baseDriver: newBaseDriver(
|
||||
monitor.DISK_UNUSED,
|
||||
monitor.DISK_MONITOR_RES_TYPE,
|
||||
monitor.DELETE_DRIVER_ACTION,
|
||||
monitor.DISK_MONITOR_SUGGEST,
|
||||
*dbinit.DiskUnusedCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (drv *DiskUnused) DoSuggestSysRule(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
doSuggestSysRule(ctx, userCred, isStart, drv)
|
||||
}
|
||||
|
||||
func (drv *DiskUnused) Run(rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) {
|
||||
Run(drv, rule, setting)
|
||||
}
|
||||
|
||||
func (drv *DiskUnused) GetLatestAlerts(rule *models.SSuggestSysRule, instance *monitor.SSuggestSysAlertSetting) ([]jsonutils.JSONObject, error) {
|
||||
duration, _ := time.ParseDuration(rule.TimeFrom)
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewBool(true), "unused")
|
||||
disks, err := ListAllResources(&modules.Disks, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diskUnusedArr := make([]jsonutils.JSONObject, 0)
|
||||
for _, disk := range disks {
|
||||
id, _ := disk.GetString("id")
|
||||
logInput := logInput{
|
||||
ObjId: id,
|
||||
ObjType: "disk",
|
||||
Limit: "0",
|
||||
Scope: "system",
|
||||
Action: db.ACT_DETACH,
|
||||
}
|
||||
latestTime, err := getResourceObjLatestUsedTime(disk, logInput)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if time.Now().Add(-duration).Sub(latestTime) < 0 {
|
||||
continue
|
||||
}
|
||||
suggestSysAlert, err := getSuggestSysAlertFromJson(disk, drv)
|
||||
if err != nil {
|
||||
return diskUnusedArr, errors.Wrap(err, "getEIPUnused's alertData Unmarshal error")
|
||||
}
|
||||
|
||||
input := &monitor.SSuggestSysAlertSetting{
|
||||
DiskUnused: &monitor.DiskUnused{},
|
||||
}
|
||||
suggestSysAlert.MonitorConfig = jsonutils.Marshal(input)
|
||||
if instance != nil {
|
||||
suggestSysAlert.MonitorConfig = jsonutils.Marshal(instance)
|
||||
}
|
||||
|
||||
problems := []monitor.SuggestAlertProblem{
|
||||
monitor.SuggestAlertProblem{
|
||||
Type: "diskUnused time",
|
||||
Description: fmt.Sprintf("%.1fm", time.Now().Sub(latestTime).Minutes()),
|
||||
},
|
||||
}
|
||||
suggestSysAlert.Problem = jsonutils.Marshal(&problems)
|
||||
diskUnusedArr = append(diskUnusedArr, jsonutils.Marshal(suggestSysAlert))
|
||||
}
|
||||
return diskUnusedArr, nil
|
||||
}
|
||||
|
||||
func (drv *DiskUnused) ValidateSetting(input *monitor.SSuggestSysAlertSetting) error {
|
||||
obj := new(monitor.DiskUnused)
|
||||
input.DiskUnused = obj
|
||||
return nil
|
||||
}
|
||||
|
||||
func (drv *DiskUnused) StartResolveTask(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
suggestSysAlert *models.SSuggestSysAlert, params *jsonutils.JSONDict) error {
|
||||
suggestSysAlert.SetStatus(userCred, monitor.SUGGEST_ALERT_START_DELETE, "")
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "ResolveUnusedTask", suggestSysAlert, userCred, params, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (drv *DiskUnused) Resolve(data *models.SSuggestSysAlert) error {
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
_, err := modules.Disks.Delete(session, data.ResId, jsonutils.NewDict())
|
||||
if err != nil {
|
||||
log.Errorln("delete unused error", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,15 +1 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package suggestsysdrivers // import "yunion.io/x/onecloud/pkg/monitor/suggestsysdrivers"
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/cronman"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
func init() {
|
||||
models.RegisterSuggestSysRuleDrivers(
|
||||
NewEIPUsedDriver(),
|
||||
NewDiskUnusedDriver(),
|
||||
NewLBUnusedDriver(),
|
||||
NewSnapshotUnusedDriver(),
|
||||
NewScaleDownDriver(),
|
||||
NewRdsUnreasonableDriver(),
|
||||
NewOssUnreasonableDriver(),
|
||||
NewRedisUnreasonableDriver(),
|
||||
NewSecGroupRuleInServerDriver(),
|
||||
NewOssSecAclDriver(),
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
func InitSuggestSysRuleCronjob() {
|
||||
rules, err := models.SuggestSysRuleManager.GetRules()
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
log.Errorln("InitSuggestSysRuleCronjob db.FetchModelObjects error")
|
||||
}
|
||||
for _, suggestSysRuleConfig := range rules {
|
||||
cronman.GetCronJobManager().Remove(suggestSysRuleConfig.Type)
|
||||
if suggestSysRuleConfig.Enabled.Bool() {
|
||||
dur, _ := time.ParseDuration(suggestSysRuleConfig.Period)
|
||||
cronman.GetCronJobManager().AddJobAtIntervalsWithStartRun(suggestSysRuleConfig.Type, dur,
|
||||
suggestSysRuleConfig.GetDriver().DoSuggestSysRule, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type EIPUnused struct {
|
||||
*baseDriver
|
||||
}
|
||||
|
||||
func NewEIPUsedDriver() models.ISuggestSysRuleDriver {
|
||||
return &EIPUnused{
|
||||
baseDriver: newBaseDriver(
|
||||
monitor.EIP_UNUSED,
|
||||
monitor.EIP_MONITOR_RES_TYPE,
|
||||
monitor.DELETE_DRIVER_ACTION,
|
||||
monitor.EIP_MONITOR_SUGGEST,
|
||||
*dbinit.EipUnusedCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (drv *EIPUnused) ValidateSetting(input *monitor.SSuggestSysAlertSetting) error {
|
||||
obj := new(monitor.EIPUnused)
|
||||
input.EIPUnused = obj
|
||||
return nil
|
||||
}
|
||||
|
||||
func (drv *EIPUnused) Run(rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) {
|
||||
Run(drv, rule, setting)
|
||||
}
|
||||
|
||||
func (drv *EIPUnused) GetLatestAlerts(rule *models.SSuggestSysRule, instance *monitor.SSuggestSysAlertSetting) ([]jsonutils.JSONObject, error) {
|
||||
duration, _ := time.ParseDuration(rule.TimeFrom)
|
||||
//处理逻辑
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), "limit")
|
||||
query.Add(jsonutils.NewString("system"), "scope")
|
||||
rtn, err := modules.Elasticips.List(session, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
unused := make([]jsonutils.JSONObject, 0)
|
||||
for _, row := range rtn.Data {
|
||||
//Determine whether EIP is used
|
||||
if row.ContainsIgnoreCases("associate_type") || row.ContainsIgnoreCases("associate_id") {
|
||||
continue
|
||||
}
|
||||
id, _ := row.GetString("id")
|
||||
logInput := logInput{
|
||||
ObjId: id,
|
||||
ObjType: "eip",
|
||||
Limit: "0",
|
||||
Scope: "system",
|
||||
Action: db.ACT_DETACH,
|
||||
}
|
||||
|
||||
latestTime, err := getResourceObjLatestUsedTime(row, logInput)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
//Judge that the unused time is beyond the duration time
|
||||
if time.Now().Add(-duration).Sub(latestTime) < 0 {
|
||||
continue
|
||||
}
|
||||
suggestSysAlert, err := getSuggestSysAlertFromJson(row, drv)
|
||||
if err != nil {
|
||||
return unused, errors.Wrap(err, "getEIPUnused's alertData Unmarshal error")
|
||||
}
|
||||
|
||||
input := &monitor.SSuggestSysAlertSetting{
|
||||
EIPUnused: &monitor.EIPUnused{},
|
||||
}
|
||||
suggestSysAlert.MonitorConfig = jsonutils.Marshal(input)
|
||||
if instance != nil {
|
||||
suggestSysAlert.MonitorConfig = jsonutils.Marshal(instance)
|
||||
}
|
||||
|
||||
problems := []monitor.SuggestAlertProblem{
|
||||
monitor.SuggestAlertProblem{
|
||||
Type: "eipUnused time",
|
||||
Description: fmt.Sprintf("%.1fm", time.Now().Sub(latestTime).Minutes()),
|
||||
},
|
||||
}
|
||||
suggestSysAlert.Problem = jsonutils.Marshal(&problems)
|
||||
|
||||
getResourceAmount(suggestSysAlert, latestTime)
|
||||
unused = append(unused, jsonutils.Marshal(suggestSysAlert))
|
||||
}
|
||||
return unused, nil
|
||||
}
|
||||
|
||||
func (drv *EIPUnused) DoSuggestSysRule(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
doSuggestSysRule(ctx, userCred, isStart, drv)
|
||||
}
|
||||
|
||||
func (drv *EIPUnused) Resolve(data *models.SSuggestSysAlert) error {
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
_, err := modules.Elasticips.Delete(session, data.ResId, jsonutils.NewDict())
|
||||
if err != nil {
|
||||
log.Errorln("delete unused eip error", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (drv *EIPUnused) StartResolveTask(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
suggestSysAlert *models.SSuggestSysAlert, params *jsonutils.JSONDict) error {
|
||||
suggestSysAlert.SetStatus(userCred, monitor.SUGGEST_ALERT_START_DELETE, "")
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "ResolveUnusedTask", suggestSysAlert, userCred, params, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type LBUnused struct {
|
||||
*baseDriver
|
||||
}
|
||||
|
||||
func NewLBUnusedDriver() models.ISuggestSysRuleDriver {
|
||||
return &LBUnused{
|
||||
baseDriver: newBaseDriver(
|
||||
monitor.LB_UNUSED,
|
||||
monitor.LB_MONITOR_RES_TYPE,
|
||||
monitor.DELETE_DRIVER_ACTION,
|
||||
monitor.LB_MONITOR_SUGGEST,
|
||||
*dbinit.LbUnusedCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (drv *LBUnused) ValidateSetting(input *monitor.SSuggestSysAlertSetting) error {
|
||||
obj := new(monitor.LBUnused)
|
||||
input.LBUnused = obj
|
||||
return nil
|
||||
}
|
||||
|
||||
func (drv *LBUnused) DoSuggestSysRule(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
doSuggestSysRule(ctx, userCred, isStart, drv)
|
||||
}
|
||||
|
||||
func (drv *LBUnused) Run(rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) {
|
||||
Run(drv, rule, setting)
|
||||
}
|
||||
|
||||
func (drv *LBUnused) GetLatestAlerts(rule *models.SSuggestSysRule, instance *monitor.SSuggestSysAlertSetting) ([]jsonutils.JSONObject, error) {
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), "limit")
|
||||
query.Add(jsonutils.NewString("system"), "scope")
|
||||
lbs, err := modules.Loadbalancers.List(session, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lbArr := make([]jsonutils.JSONObject, 0)
|
||||
for _, lb := range lbs.Data {
|
||||
lbId, _ := lb.GetString("id")
|
||||
|
||||
contains, problems, err := containsLbBackEndGroups(lbId)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if *contains {
|
||||
continue
|
||||
}
|
||||
contains, err = getLbListeners(lbId)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if *contains {
|
||||
continue
|
||||
}
|
||||
problems = append(problems, monitor.SuggestAlertProblem{
|
||||
Type: "listener",
|
||||
Description: monitor.LB_UNUSED_NLISTENER,
|
||||
})
|
||||
suggestSysAlert, err := getSuggestSysAlertFromJson(lb, drv)
|
||||
if err != nil {
|
||||
return lbArr, errors.Wrap(err, "getLatestAlerts's alertData Unmarshal error")
|
||||
}
|
||||
|
||||
input := &monitor.SSuggestSysAlertSetting{
|
||||
LBUnused: &monitor.LBUnused{},
|
||||
}
|
||||
suggestSysAlert.MonitorConfig = jsonutils.Marshal(input)
|
||||
if instance != nil {
|
||||
suggestSysAlert.MonitorConfig = jsonutils.Marshal(instance)
|
||||
}
|
||||
suggestSysAlert.Problem = jsonutils.Marshal(problems)
|
||||
|
||||
lbArr = append(lbArr, jsonutils.Marshal(suggestSysAlert))
|
||||
}
|
||||
return lbArr, nil
|
||||
}
|
||||
|
||||
func getLbListeners(lbId string) (*bool, error) {
|
||||
contains := false
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), "limit")
|
||||
query.Add(jsonutils.NewString("system"), "scope")
|
||||
query.Add(jsonutils.NewString(lbId), "loadbalancer")
|
||||
listeners, err := modules.LoadbalancerListeners.List(session, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if listeners != nil && len(listeners.Data) > 0 {
|
||||
for _, listener := range listeners.Data {
|
||||
status, _ := listener.GetString("status")
|
||||
if status == "enabled" {
|
||||
contains = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return &contains, nil
|
||||
}
|
||||
|
||||
func containsLbBackEndGroups(lbId string) (*bool, []monitor.SuggestAlertProblem, error) {
|
||||
contains := false
|
||||
|
||||
problems := make([]monitor.SuggestAlertProblem, 0)
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), "limit")
|
||||
query.Add(jsonutils.NewString("system"), "scope")
|
||||
query.Add(jsonutils.NewString(lbId), "loadbalancer")
|
||||
groups, err := modules.LoadbalancerBackendGroups.List(session, query)
|
||||
if err != nil {
|
||||
return nil, problems, err
|
||||
}
|
||||
for _, group := range groups.Data {
|
||||
groupId, _ := group.GetString("id")
|
||||
backEnds, err := containsLbBackEnd(groupId)
|
||||
if err != nil {
|
||||
return nil, problems, err
|
||||
}
|
||||
if *backEnds {
|
||||
return backEnds, problems, nil
|
||||
}
|
||||
}
|
||||
if len(groups.Data) == 0 {
|
||||
problems = append(problems, monitor.SuggestAlertProblem{
|
||||
Type: "backendgroup",
|
||||
Description: monitor.LB_UNUSED_NBCGROUP,
|
||||
})
|
||||
}
|
||||
problems = append(problems, monitor.SuggestAlertProblem{
|
||||
Type: "backend",
|
||||
Description: monitor.LB_UNUSED_NBC,
|
||||
})
|
||||
return &contains, problems, nil
|
||||
}
|
||||
|
||||
func containsLbBackEnd(groupId string) (*bool, error) {
|
||||
contains := false
|
||||
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), "limit")
|
||||
query.Add(jsonutils.NewString("system"), "scope")
|
||||
query.Add(jsonutils.NewString(groupId), "backend_group")
|
||||
backEnds, err := modules.LoadbalancerBackends.List(session, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(backEnds.Data) > 0 {
|
||||
contains = true
|
||||
return &contains, nil
|
||||
}
|
||||
return &contains, nil
|
||||
}
|
||||
|
||||
func (rule *LBUnused) StartResolveTask(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
suggestSysAlert *models.SSuggestSysAlert,
|
||||
params *jsonutils.JSONDict) error {
|
||||
suggestSysAlert.SetStatus(userCred, monitor.SUGGEST_ALERT_START_DELETE, "")
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "ResolveUnusedTask", suggestSysAlert, userCred, params, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rule *LBUnused) Resolve(data *models.SSuggestSysAlert) error {
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
_, err := modules.Loadbalancers.Delete(session, data.ResId, jsonutils.NewDict())
|
||||
if err != nil {
|
||||
log.Errorln("delete unused lb error", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type OssSecAcl struct {
|
||||
*baseDriver
|
||||
}
|
||||
|
||||
func NewOssSecAclDriver() models.ISuggestSysRuleDriver {
|
||||
return &OssSecAcl{
|
||||
baseDriver: newBaseDriver(
|
||||
monitor.OSS_SEC_ACL,
|
||||
monitor.OSS_SEC_ACL_MONITOR_RES_TYPE,
|
||||
monitor.OSS_SEC_ACL_DRIVER_ACTION,
|
||||
monitor.OSS_SEC_ACL_MONITOR_SUGGEST,
|
||||
*dbinit.OssSecAclCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
var aclUnSecurity = []string{"public-read", "public-read-write"}
|
||||
var aclSecurity = "private"
|
||||
|
||||
func (drv *OssSecAcl) ValidateSetting(input *monitor.SSuggestSysAlertSetting) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (drv *OssSecAcl) DoSuggestSysRule(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
doSuggestSysRule(ctx, userCred, isStart, drv)
|
||||
}
|
||||
|
||||
func (drv *OssSecAcl) Run(rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) {
|
||||
Run(drv, rule, setting)
|
||||
}
|
||||
|
||||
func (o OssSecAcl) StartResolveTask(ctx context.Context, userCred mcclient.TokenCredential, suggestSysAlert *models.SSuggestSysAlert,
|
||||
params *jsonutils.JSONDict) error {
|
||||
suggestSysAlert.SetStatus(userCred, monitor.SUGGEST_ALERT_START_DELETE, "")
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "ResoleBucketAclTask", suggestSysAlert, userCred, params, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (drv *OssSecAcl) Resolve(data *models.SSuggestSysAlert) error {
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
param := jsonutils.NewDict()
|
||||
keyArr := jsonutils.NewArray()
|
||||
bucket, err := modules.Buckets.GetById(session, data.ResId, jsonutils.NewDict())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("get bucket by %s err", data.ResId))
|
||||
}
|
||||
|
||||
param.Add(jsonutils.NewString(aclSecurity), "acl")
|
||||
|
||||
bucketName, _ := bucket.GetString("name")
|
||||
problems := make([]monitor.SuggestAlertProblem, 0)
|
||||
err = data.Problem.Unmarshal(problems)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unmarshal problem err")
|
||||
}
|
||||
bucketNameContainsBool := false
|
||||
for _, problem := range problems {
|
||||
if problem.Type == bucketName {
|
||||
bucketNameContainsBool = true
|
||||
continue
|
||||
}
|
||||
keyArr.Add(jsonutils.NewString(problem.Type))
|
||||
}
|
||||
if bucketNameContainsBool {
|
||||
//modify bucket acl
|
||||
_, err = modules.Buckets.PerformAction(session, data.ResId, "acl", param)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
//modify object acl in the bucket
|
||||
if keyArr.Length() == 0 {
|
||||
return nil
|
||||
}
|
||||
param.Add(keyArr, "key")
|
||||
_, err = modules.Buckets.PerformAction(session, data.ResId, "acl", param)
|
||||
return err
|
||||
}
|
||||
|
||||
func (drv *OssSecAcl) GetLatestAlerts(rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) ([]jsonutils.JSONObject, error) {
|
||||
allArr := make([]jsonutils.JSONObject, 0)
|
||||
bucketArr, err := drv.getBucketsByAcl()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if bucketArr != nil {
|
||||
allArr = append(allArr, bucketArr...)
|
||||
}
|
||||
bucketObjArr, err := drv.getBucketsByObjAcl()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if bucketObjArr != nil {
|
||||
allArr = append(allArr, bucketObjArr...)
|
||||
}
|
||||
return allArr, nil
|
||||
}
|
||||
|
||||
func (drv *OssSecAcl) getBucketsByAcl() ([]jsonutils.JSONObject, error) {
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("acl.in(public-read,public-read-write)"), "filter")
|
||||
buckets, err := ListAllResources(&modules.Buckets, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bucketArr := make([]jsonutils.JSONObject, 0)
|
||||
for _, bucket := range buckets {
|
||||
acl, _ := bucket.GetString("acl")
|
||||
bucketName, _ := bucket.GetString("name")
|
||||
suggestSysAlert, err := getSuggestSysAlertFromJson(bucket, drv)
|
||||
if err != nil {
|
||||
return bucketArr, errors.Wrap(err, "OssSecAcl getSuggestSysAlertFromJson error")
|
||||
}
|
||||
suggestSysAlert.Amount = 0
|
||||
problems := []monitor.SuggestAlertProblem{
|
||||
monitor.SuggestAlertProblem{
|
||||
Type: bucketName,
|
||||
Description: acl,
|
||||
},
|
||||
}
|
||||
//suggestSysAlert.Name = GenerateName(suggestSysAlert.Name, string(drv.GetType()))
|
||||
suggestSysAlert.Problem = jsonutils.Marshal(&problems)
|
||||
bucketArr = append(bucketArr, jsonutils.Marshal(suggestSysAlert))
|
||||
}
|
||||
return bucketArr, nil
|
||||
}
|
||||
|
||||
func (drv *OssSecAcl) getBucketsByObjAcl() ([]jsonutils.JSONObject, error) {
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString(fmt.Sprintf("acl.equals(%s)", aclSecurity)), "filter")
|
||||
buckets, err := ListAllResources(&modules.Buckets, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bucketArr := make([]jsonutils.JSONObject, 0)
|
||||
for _, bucket := range buckets {
|
||||
id, _ := bucket.GetString("id")
|
||||
unSecBool, problems, err := drv.getObjectsByBucketId(id, "")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if !(*unSecBool) {
|
||||
continue
|
||||
}
|
||||
suggestSysAlert, err := getSuggestSysAlertFromJson(bucket, drv)
|
||||
if err != nil {
|
||||
return bucketArr, errors.Wrap(err, "OssSecAcl getSuggestSysAlertFromJson error")
|
||||
}
|
||||
suggestSysAlert.Amount = 0
|
||||
|
||||
suggestSysAlert.Name = GenerateName(suggestSysAlert.Name, string(drv.GetType()))
|
||||
suggestSysAlert.Problem = jsonutils.Marshal(&problems)
|
||||
bucketArr = append(bucketArr, jsonutils.Marshal(suggestSysAlert))
|
||||
}
|
||||
return bucketArr, nil
|
||||
}
|
||||
|
||||
func (drv *OssSecAcl) getObjectsByBucketId(id, filePath string) (*bool, []monitor.SuggestAlertProblem, error) {
|
||||
aclUnSafeBool := false
|
||||
problems := make([]monitor.SuggestAlertProblem, 0)
|
||||
objects, err := getBucketObjects(id, filePath)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for _, object := range objects {
|
||||
acl, _ := object.GetString("acl")
|
||||
key, _ := object.GetString("key")
|
||||
if acl != aclSecurity {
|
||||
aclUnSafeBool = true
|
||||
problems = append(problems, monitor.SuggestAlertProblem{
|
||||
Type: key,
|
||||
Description: acl,
|
||||
})
|
||||
}
|
||||
if strings.HasSuffix(key, "/") {
|
||||
buffer := new(bytes.Buffer)
|
||||
if len(filePath) != 0 {
|
||||
buffer.WriteString(filePath)
|
||||
}
|
||||
buffer.WriteString(key)
|
||||
unSecBool, prob_, err := drv.getObjectsByBucketId(id, buffer.String())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if *unSecBool {
|
||||
problems = append(problems, prob_...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return &aclUnSafeBool, problems, nil
|
||||
}
|
||||
|
||||
func getBucketObjects(id, filePath string) ([]jsonutils.JSONObject, error) {
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
query := jsonutils.NewDict()
|
||||
if len(filePath) != 0 {
|
||||
query.Add(jsonutils.NewString(filePath), "prefix")
|
||||
}
|
||||
query.Add(jsonutils.NewString("system"), "scope")
|
||||
query.Add(jsonutils.NewInt(0), "limit")
|
||||
var count int
|
||||
objs := make([]jsonutils.JSONObject, 0)
|
||||
for {
|
||||
query.Add(jsonutils.NewInt(int64(count)), "offset")
|
||||
result, err := modules.Buckets.GetSpecific(session, id, "objects", query)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "%s getSpecific %s resources with params %s error",
|
||||
modules.Buckets.KeyString(), "objects", query.String())
|
||||
}
|
||||
listResult := modulebase.ListResult{}
|
||||
err = result.Unmarshal(&listResult)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getObjectsByBucketId unmarshal ListResult error")
|
||||
}
|
||||
for _, data := range listResult.Data {
|
||||
objs = append(objs, data)
|
||||
}
|
||||
total := listResult.Total
|
||||
count = count + len(listResult.Data)
|
||||
if count >= total {
|
||||
break
|
||||
}
|
||||
}
|
||||
return objs, nil
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type OssUnreasonable struct {
|
||||
*InfluxdbBaseDriver
|
||||
}
|
||||
|
||||
func NewOssUnreasonableDriver() models.ISuggestSysRuleDriver {
|
||||
return &OssUnreasonable{
|
||||
InfluxdbBaseDriver: NewInfluxdbBaseDriver(monitor.OSS_UNREASONABLE,
|
||||
monitor.OSS_UNREASONABLE_MONITOR_RES_TYPE,
|
||||
monitor.REDIS_UNREASONABLE_DRIVER_ACTION,
|
||||
monitor.SCALE_DOWN_MONITOR_SUGGEST,
|
||||
*dbinit.OssUnReasonableCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type RdsUnreasonable struct {
|
||||
*InfluxdbBaseDriver
|
||||
}
|
||||
|
||||
func NewRdsUnreasonableDriver() models.ISuggestSysRuleDriver {
|
||||
return &RdsUnreasonable{
|
||||
InfluxdbBaseDriver: NewInfluxdbBaseDriver(monitor.RDS_UNREASONABLE,
|
||||
monitor.RDS_UNREASONABLE_MONITOR_RES_TYPE,
|
||||
monitor.REDIS_UNREASONABLE_DRIVER_ACTION,
|
||||
monitor.SCALE_DOWN_MONITOR_SUGGEST,
|
||||
*dbinit.RdsUnReasonableCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type RedisUnreasonable struct {
|
||||
*InfluxdbBaseDriver
|
||||
}
|
||||
|
||||
func NewRedisUnreasonableDriver() models.ISuggestSysRuleDriver {
|
||||
return &RedisUnreasonable{
|
||||
InfluxdbBaseDriver: NewInfluxdbBaseDriver(monitor.REDIS_UNREASONABLE,
|
||||
monitor.REDIS_UNREASONABLE_MONITOR_RES_TYPE, monitor.REDIS_UNREASONABLE_DRIVER_ACTION,
|
||||
monitor.SCALE_DOWN_MONITOR_SUGGEST,
|
||||
*dbinit.RedisUnReasonableCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type ScaleDown struct {
|
||||
*InfluxdbBaseDriver
|
||||
}
|
||||
|
||||
func NewScaleDownDriver() models.ISuggestSysRuleDriver {
|
||||
return &ScaleDown{
|
||||
InfluxdbBaseDriver: NewInfluxdbBaseDriver(
|
||||
monitor.SCALE_DOWN,
|
||||
monitor.SCALE_MONTITOR_RES_TYPE,
|
||||
monitor.SCALE_DOWN_DRIVER_ACTION,
|
||||
monitor.SCALE_DOWN_MONITOR_SUGGEST,
|
||||
*dbinit.ScaleDownCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
compute_api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type SecGroupRuleInServer struct {
|
||||
*baseDriver
|
||||
}
|
||||
|
||||
func NewSecGroupRuleInServerDriver() models.ISuggestSysRuleDriver {
|
||||
return &SecGroupRuleInServer{
|
||||
baseDriver: newBaseDriver(
|
||||
monitor.SECGROUPRULEINSERVER_ALLIN,
|
||||
monitor.SECGROUPRULEINSERVER_MONITOR_RES_TYPE,
|
||||
monitor.SECGROUPRULEINSERVER_DRIVER_ACTION,
|
||||
monitor.SECGROUPRULEINSERVER_MONITOR_SUGGEST,
|
||||
*dbinit.SecGroupRuleInCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (drv *SecGroupRuleInServer) ValidateSetting(input *monitor.SSuggestSysAlertSetting) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (drv *SecGroupRuleInServer) DoSuggestSysRule(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
doSuggestSysRule(ctx, userCred, isStart, drv)
|
||||
}
|
||||
|
||||
func (drv *SecGroupRuleInServer) Run(rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) {
|
||||
Run(drv, rule, setting)
|
||||
}
|
||||
|
||||
func (drv *SecGroupRuleInServer) GetLatestAlerts(rule *models.SSuggestSysRule,
|
||||
setting *monitor.SSuggestSysAlertSetting) ([]jsonutils.JSONObject, error) {
|
||||
secGroupIdArr, err := drv.getSecGroupIdsInThisRule()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
servers, err := drv.getServersBySecGroupIds(secGroupIdArr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secGroupRuleInServerArr := make([]jsonutils.JSONObject, 0)
|
||||
for _, server := range servers {
|
||||
suggestSysAlert, err := getSuggestSysAlertFromJson(server, drv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//suggestSysAlert.Name = fmt.Sprintf("%s-%s", suggestSysAlert.Name, string(drv.GetType()))
|
||||
suggestSysAlert.Amount = 0
|
||||
secGroupRuleInServerArr = append(secGroupRuleInServerArr, jsonutils.Marshal(suggestSysAlert))
|
||||
}
|
||||
return secGroupRuleInServerArr, nil
|
||||
|
||||
}
|
||||
|
||||
func (drv *SecGroupRuleInServer) getSecGroupIdsInThisRule() ([]string, error) {
|
||||
param := jsonutils.NewDict()
|
||||
param.Add(jsonutils.NewString("in"), "direction")
|
||||
secGroups, err := ListAllResources(&modules.SecGroups, param)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secGroupIdArr := make([]string, 0)
|
||||
for _, secGroup := range secGroups {
|
||||
secGroupDetail := new(compute_api.SecgroupDetails)
|
||||
secGroup.Unmarshal(secGroupDetail)
|
||||
if secGroupDetail.GuestCnt == 0 {
|
||||
continue
|
||||
}
|
||||
for _, inRule := range secGroupDetail.InRules {
|
||||
if inRule.CIDR == monitor.SECGROUPRULEINSERVER_CIDR && len(inRule.Ports) == 0 &&
|
||||
strings.ToLower(inRule.Protocol) != monitor.SECGROUPRULEINSERVER_FILTER_PROTOCOL {
|
||||
secGroupIdArr = append(secGroupIdArr, secGroupDetail.Id)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return secGroupIdArr, nil
|
||||
}
|
||||
|
||||
func (drv *SecGroupRuleInServer) getServersBySecGroupIds(secGroupIdArr []string) ([]jsonutils.JSONObject, error) {
|
||||
param := jsonutils.NewDict()
|
||||
param.Add(jsonutils.NewString("hypervisor.notin(baremetal,container)"), "filter.0")
|
||||
servers := make([]jsonutils.JSONObject, 0)
|
||||
for _, secGroupId := range secGroupIdArr {
|
||||
param.Set("secgroup_id", jsonutils.NewString(secGroupId))
|
||||
serversPart, err := ListAllResources(&modules.Servers, param)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SecGroupRuleInServer getServers error")
|
||||
}
|
||||
servers = append(servers, serversPart...)
|
||||
}
|
||||
return servers, nil
|
||||
}
|
||||
|
||||
func (drv *SecGroupRuleInServer) StartResolveTask(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
suggestSysAlert *models.SSuggestSysAlert, params *jsonutils.JSONDict) error {
|
||||
log.Println("SecGroupRuleInServer StartResolveTask do nothing")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s SecGroupRuleInServer) Resolve(data *models.SSuggestSysAlert) error {
|
||||
log.Println("InfluxdbBaseDriver Resolve do nothing")
|
||||
return nil
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package suggestsysdrivers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/monitor/dbinit"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
)
|
||||
|
||||
type SnapshotUnused struct {
|
||||
*baseDriver
|
||||
}
|
||||
|
||||
func NewSnapshotUnusedDriver() models.ISuggestSysRuleDriver {
|
||||
return &SnapshotUnused{
|
||||
baseDriver: newBaseDriver(
|
||||
monitor.SNAPSHOT_UNUSED,
|
||||
monitor.SNAPSHOT_MONITOR_RES_TYPE,
|
||||
monitor.DELETE_DRIVER_ACTION,
|
||||
monitor.MonitorSuggest("释放未使用的快照"),
|
||||
*dbinit.SnapShotUnusedCreateInput,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (rule *SnapshotUnused) DoSuggestSysRule(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
doSuggestSysRule(ctx, userCred, isStart, rule)
|
||||
}
|
||||
|
||||
func (drv *SnapshotUnused) Run(rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) {
|
||||
Run(drv, rule, setting)
|
||||
}
|
||||
|
||||
func (drv *SnapshotUnused) GetLatestAlerts(rule *models.SSuggestSysRule, setting *monitor.SSuggestSysAlertSetting) ([]jsonutils.JSONObject, error) {
|
||||
duration, _ := time.ParseDuration(rule.TimeFrom)
|
||||
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("snapshot_id.isnotnull()"), "filter.0")
|
||||
query.Add(jsonutils.NewString("snapshot_id.isnotempty()"), "filter.1")
|
||||
unusedSnapshotDisks, err := ListAllResources(&modules.Disks, query)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "list unused snapshot disks")
|
||||
}
|
||||
snapshotQuery := jsonutils.NewDict()
|
||||
snapshotQuery.Add(jsonutils.NewString("ref_count.le(0)"))
|
||||
snapshots, err := ListAllResources(&modules.Snapshots, snapshotQuery)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "list snapshots")
|
||||
}
|
||||
snapshots = drv.filterUnusedSnapshots(snapshots, unusedSnapshotDisks)
|
||||
snapshots = drv.filterSnapshotsByTime(snapshots, duration)
|
||||
|
||||
unusedResult := make([]jsonutils.JSONObject, 0)
|
||||
for _, snapshot := range snapshots {
|
||||
alert, err := getSuggestSysAlertFromJson(snapshot, drv)
|
||||
if err != nil {
|
||||
return unusedResult, errors.Wrap(err, "get unused snapshot")
|
||||
}
|
||||
updateAt, _ := snapshot.GetTime("updated_at")
|
||||
problems := []monitor.SuggestAlertProblem{
|
||||
monitor.SuggestAlertProblem{
|
||||
Type: "snapshotUnused time",
|
||||
Description: fmt.Sprintf("%.1fm", time.Now().Sub(updateAt).Minutes()),
|
||||
},
|
||||
}
|
||||
alert.Problem = jsonutils.Marshal(&problems)
|
||||
unusedResult = append(unusedResult, jsonutils.Marshal(alert))
|
||||
}
|
||||
return unusedResult, nil
|
||||
}
|
||||
|
||||
func (rule *SnapshotUnused) filterUnusedSnapshots(snapshots []jsonutils.JSONObject, disks []jsonutils.JSONObject) []jsonutils.JSONObject {
|
||||
unused := make([]jsonutils.JSONObject, 0)
|
||||
for _, snapshot := range snapshots {
|
||||
if !rule.isSnapshotUsedByDisks(snapshot, disks) {
|
||||
unused = append(unused, snapshot)
|
||||
}
|
||||
}
|
||||
return unused
|
||||
}
|
||||
|
||||
func (rule *SnapshotUnused) filterSnapshotsByTime(snapshots []jsonutils.JSONObject, duration time.Duration) []jsonutils.JSONObject {
|
||||
result := make([]jsonutils.JSONObject, 0)
|
||||
for _, snapshot := range snapshots {
|
||||
updateAt, _ := snapshot.GetTime("updated_at")
|
||||
if time.Now().Add(-duration).Sub(updateAt) < 0 {
|
||||
continue
|
||||
}
|
||||
result = append(result, snapshot)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (rule *SnapshotUnused) isSnapshotUsedByDisks(snapshot jsonutils.JSONObject, disks []jsonutils.JSONObject) bool {
|
||||
for _, disk := range disks {
|
||||
snapshotId, _ := snapshot.GetString("id")
|
||||
diskSnapshotId, _ := disk.GetString("snapshot_id")
|
||||
if diskSnapshotId != "" && snapshotId == diskSnapshotId {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rule *SnapshotUnused) ValidateSetting(input *monitor.SSuggestSysAlertSetting) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rule *SnapshotUnused) StartResolveTask(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
suggestSysAlert *models.SSuggestSysAlert, params *jsonutils.JSONDict) error {
|
||||
suggestSysAlert.SetStatus(userCred, monitor.SUGGEST_ALERT_START_DELETE, "")
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "ResolveUnusedTask", suggestSysAlert, userCred, params, "", "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rule *SnapshotUnused) Resolve(data *models.SSuggestSysAlert) error {
|
||||
session := auth.GetAdminSession(context.Background(), "", "")
|
||||
_, err := modules.Snapshots.Delete(session, data.ResId, jsonutils.NewDict())
|
||||
if err != nil {
|
||||
log.Errorln("delete unused error", err)
|
||||
return errors.Wrapf(err, "delete unused snapshot %s", data.ResId)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type ResoleBucketAclTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(ResoleBucketAclTask{})
|
||||
}
|
||||
|
||||
func (self *ResoleBucketAclTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
suggestSysAlert := obj.(*models.SSuggestSysAlert)
|
||||
err := suggestSysAlert.GetDriver().Resolve(suggestSysAlert)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to change bucket acl: %s", err)
|
||||
self.taskFail(ctx, suggestSysAlert, jsonutils.NewString(msg))
|
||||
return
|
||||
}
|
||||
suggestSysAlert.SetStatus(self.UserCred, api.SUGGEST_ALERT_DELETING, "")
|
||||
err = suggestSysAlert.RealDelete(ctx, self.UserCred)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to delete SSuggestSysAlert %s", err)
|
||||
self.taskFail(ctx, suggestSysAlert, jsonutils.NewString(msg))
|
||||
return
|
||||
}
|
||||
db.OpsLog.LogEvent(suggestSysAlert, db.ACT_DELETE, nil, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, suggestSysAlert, logclient.ACT_DELETE, nil, self.UserCred, true)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *ResoleBucketAclTask) taskFail(ctx context.Context, alert *models.SSuggestSysAlert, msg jsonutils.JSONObject) {
|
||||
alert.SetStatus(self.UserCred, api.SUGGEST_ALERT_DELETE_FAIL, msg.String())
|
||||
db.OpsLog.LogEvent(alert, db.ACT_DELETE, msg, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, alert, logclient.ACT_DELETE, msg, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, msg)
|
||||
return
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/monitor/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type ResolveUnusedTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(ResolveUnusedTask{})
|
||||
}
|
||||
|
||||
func (self *ResolveUnusedTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
suggestSysAlert := obj.(*models.SSuggestSysAlert)
|
||||
err := suggestSysAlert.GetDriver().Resolve(suggestSysAlert)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to delete %s", err)
|
||||
self.taskFail(ctx, suggestSysAlert, jsonutils.NewString(msg))
|
||||
return
|
||||
}
|
||||
suggestSysAlert.SetStatus(self.UserCred, api.SUGGEST_ALERT_DELETING, "")
|
||||
err = suggestSysAlert.RealDelete(ctx, self.UserCred)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("fail to delete SSuggestSysAlert %s", err)
|
||||
self.taskFail(ctx, suggestSysAlert, jsonutils.NewString(msg))
|
||||
return
|
||||
}
|
||||
db.OpsLog.LogEvent(suggestSysAlert, db.ACT_DELETE, nil, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, suggestSysAlert, logclient.ACT_DELETE, nil, self.UserCred, true)
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *ResolveUnusedTask) taskFail(ctx context.Context, alert *models.SSuggestSysAlert, msg jsonutils.JSONObject) {
|
||||
alert.SetStatus(self.UserCred, api.SUGGEST_ALERT_DELETE_FAIL, msg.String())
|
||||
db.OpsLog.LogEvent(alert, db.ACT_DELETE, msg, self.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(self, alert, logclient.ACT_DELETE, msg, self.UserCred, false)
|
||||
self.SetStageFailed(ctx, msg)
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user