chore(monitor): delete suggestion files

1. 移除优化建议相关内容
2. mcclient中新增baseManager:SuggestionManager,修改优化建议相关的manager
This commit is contained in:
zhaoxiangchun
2020-12-04 19:28:23 +08:00
parent b2255754c9
commit ad0c063fb9
28 changed files with 20 additions and 3673 deletions
-102
View File
@@ -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
}
+6
View File
@@ -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")
}
-591
View File
@@ -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"`
//监控规则typeRule 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
}
-701
View File
@@ -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)
}
-543
View File
@@ -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
}
-3
View File
@@ -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,
-2
View File
@@ -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()
-63
View File
@@ -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
}
-278
View File
@@ -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(&param))
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)
}
-136
View File
@@ -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
}
-14
View File
@@ -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)
}
}
}
-146
View File
@@ -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
}
-213
View File
@@ -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
}
-253
View File
@@ -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
}
-64
View File
@@ -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
}