| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900 |
- // 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"
- "time"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/rbacscope"
- "yunion.io/x/sqlchemy"
- "yunion.io/x/onecloud/pkg/apis"
- "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/mcclient/modulebase"
- modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
- merrors "yunion.io/x/onecloud/pkg/monitor/errors"
- "yunion.io/x/onecloud/pkg/monitor/options"
- "yunion.io/x/onecloud/pkg/util/stringutils2"
- )
- const (
- NodeAlertMetadataType = "type"
- NodeAlertMetadataNodeId = "node_id"
- NodeAlertMetadataNodeName = "node_name"
- )
- var NodeAlertManager *SNodeAlertManager
- func init() {
- NodeAlertManager = NewNodeAlertManager()
- }
- // +onecloud:swagger-gen-ignore
- type SV1AlertManager struct {
- SAlertManager
- }
- // +onecloud:swagger-gen-model-singular=nodealert
- // +onecloud:swagger-gen-model-plural=nodealerts
- type SNodeAlertManager struct {
- SCommonAlertManager
- }
- func NewNodeAlertManager() *SNodeAlertManager {
- man := &SNodeAlertManager{
- SCommonAlertManager: SCommonAlertManager{
- SAlertManager: *NewAlertManager(SNodeAlert{}, "nodealert", "nodealerts"),
- },
- }
- man.SetVirtualObject(man)
- return man
- }
- // +onecloud:swagger-gen-ignore
- type SV1Alert struct {
- SAlert
- }
- type SNodeAlert struct {
- SCommonAlert
- }
- func (v1man *SV1AlertManager) CreateNotification(
- ctx context.Context,
- userCred mcclient.TokenCredential,
- alertName string,
- channel string,
- recipients string) (*SNotification, error) {
- userIds := strings.Split(recipients, ",")
- s := &monitor.NotificationSettingOneCloud{
- Channel: channel,
- UserIds: userIds,
- }
- return NotificationManager.CreateOneCloudNotification(ctx, userCred, alertName, s, "")
- }
- func (man *SNodeAlertManager) ValidateCreateData(
- ctx context.Context, userCred mcclient.TokenCredential,
- ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject,
- data monitor.NodeAlertCreateInput) (*monitor.NodeAlertCreateInput, error) {
- if data.Period == "" {
- data.Period = "5m"
- }
- if _, err := time.ParseDuration(data.Period); err != nil {
- return nil, httperrors.NewInputParameterError("Invalid period format: %s", data.Period)
- }
- if data.Metric == "" {
- return nil, merrors.NewArgIsEmptyErr("metric")
- }
- parts := strings.Split(data.Metric, ".")
- if len(parts) != 2 {
- return nil, httperrors.NewInputParameterError("metric %s is invalid format, usage <measurement>.<field>", data.Metric)
- }
- measurement, field, err := GetMeasurementField(data.Metric)
- if err != nil {
- return nil, err
- }
- if data.Recipients == "" {
- return nil, merrors.NewArgIsEmptyErr("recipients")
- }
- if data.NodeId == "" {
- return nil, merrors.NewArgIsEmptyErr("node_id")
- }
- nodeName, resType, err := man.validateResourceId(ctx, data.Type, data.NodeId)
- if err != nil {
- return nil, err
- }
- data.NodeName = nodeName
- name, err := man.genName(ctx, ownerId, resType, nodeName, data.Metric)
- if err != nil {
- return nil, err
- }
- alertInput := data.ToCommonAlertCreateInput(name, field, measurement, monitor.METRIC_DATABASE_TELE)
- alertInput, err = GetCommonAlertManager().ValidateCreateData(ctx, userCred, ownerId, query, alertInput)
- if err != nil {
- return nil, errors.Wrap(err, "CommonAlertManager.ValidateCreateData")
- }
- data.CommonAlertCreateInput = &alertInput
- data.AlertCreateInput = alertInput.AlertCreateInput
- data.UsedBy = AlertNotificationUsedByNodeAlert
- return &data, nil
- }
- func (man *SNodeAlertManager) genName(ctx context.Context, ownerId mcclient.IIdentityProvider, resType string, nodeName string, metric string) (string, error) {
- nameHint := fmt.Sprintf("%s %s %s", resType, nodeName, metric)
- name, err := db.GenerateName(ctx, man, ownerId, nameHint)
- if err != nil {
- return "", err
- }
- if name != nameHint {
- return "", httperrors.NewDuplicateNameError(man.Keyword(), metric)
- }
- return name, nil
- }
- func (man *SNodeAlertManager) validateResourceId(ctx context.Context, nodeType, nodeId string) (string, string, error) {
- var (
- retType string
- nodeName string
- err error
- )
- switch nodeType {
- case monitor.NodeAlertTypeHost:
- retType = "宿主机"
- nodeName, err = man.validateHostResource(ctx, nodeId)
- case monitor.NodeAlertTypeGuest:
- retType = "虚拟机"
- nodeName, err = man.validateGuestResource(ctx, nodeId)
- default:
- return "", "", httperrors.NewInputParameterError("unsupported resource type %s", nodeType)
- }
- return nodeName, retType, err
- }
- func (man *SNodeAlertManager) validateGuestResource(ctx context.Context, id string) (string, error) {
- return man.validateResourceByMod(ctx, &modules.Servers, id)
- }
- func (man *SNodeAlertManager) validateHostResource(ctx context.Context, id string) (string, error) {
- return man.validateResourceByMod(ctx, &modules.Hosts, id)
- }
- func (man *SNodeAlertManager) validateResourceByMod(ctx context.Context, mod modulebase.Manager, id string) (string, error) {
- s := auth.GetAdminSession(ctx, options.Options.Region)
- ret, err := mod.Get(s, id, nil)
- if err != nil {
- return "", err
- }
- name, err := ret.GetString("name")
- if err != nil {
- return "", err
- }
- return name, nil
- }
- func (man *SNodeAlertManager) ValidateListConditions(ctx context.Context, userCred mcclient.TokenCredential, query *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
- // hack: always use details in query to get more details
- query.Set("details", jsonutils.JSONTrue)
- return query, nil
- }
- func (man *SV1AlertManager) ListItemFilter(
- ctx context.Context,
- q *sqlchemy.SQuery,
- userCred mcclient.TokenCredential,
- query monitor.V1AlertListInput,
- ) (*sqlchemy.SQuery, error) {
- var err error
- q, err = man.SAlertManager.ListItemFilter(ctx, q, userCred, query.AlertListInput)
- if err != nil {
- return nil, errors.Wrap(err, "SAlertManager.ListItemFilter")
- }
- return q, nil
- }
- func (man *SV1AlertManager) OrderByExtraFields(
- ctx context.Context,
- q *sqlchemy.SQuery,
- userCred mcclient.TokenCredential,
- query monitor.V1AlertListInput,
- ) (*sqlchemy.SQuery, error) {
- var err error
- q, err = man.SAlertManager.OrderByExtraFields(ctx, q, userCred, query.AlertListInput)
- if err != nil {
- return nil, errors.Wrap(err, "SAlertManager.OrderByExtraFields")
- }
- return q, nil
- }
- func (man *SV1AlertManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
- var err error
- q, err = man.SAlertManager.QueryDistinctExtraField(q, field)
- if err == nil {
- return q, nil
- }
- return q, httperrors.ErrNotFound
- }
- func (alertV1 *SV1Alert) ValidateUpdateData(
- ctx context.Context,
- userCred mcclient.TokenCredential,
- query jsonutils.JSONObject,
- input monitor.V1AlertUpdateInput,
- ) (monitor.V1AlertUpdateInput, error) {
- var err error
- input.AlertUpdateInput, err = alertV1.SAlert.ValidateUpdateData(ctx, userCred, query, input.AlertUpdateInput)
- if err != nil {
- return input, errors.Wrap(err, "SAlert.ValidateUpdateData")
- }
- return input, nil
- }
- func (man *SNodeAlertManager) ListItemFilter(
- ctx context.Context, q *sqlchemy.SQuery,
- userCred mcclient.TokenCredential,
- query monitor.NodeAlertListInput,
- ) (*sqlchemy.SQuery, error) {
- q, err := man.SCommonAlertManager.ListItemFilter(ctx, q, userCred, query.ToCommonAlertListInput())
- if err != nil {
- return nil, err
- }
- if len(query.Metric) > 0 {
- }
- if len(query.Type) > 0 {
- }
- if len(query.NodeId) > 0 {
- }
- if len(query.NodeName) > 0 {
- }
- q = q.Equals("used_by", AlertNotificationUsedByNodeAlert)
- return q, nil
- }
- func (man *SNodeAlertManager) OrderByExtraFields(
- ctx context.Context,
- q *sqlchemy.SQuery,
- userCred mcclient.TokenCredential,
- query monitor.NodeAlertListInput,
- ) (*sqlchemy.SQuery, error) {
- var err error
- q, err = man.SCommonAlertManager.OrderByExtraFields(ctx, q, userCred, query.AlertListInput)
- if err != nil {
- return nil, errors.Wrap(err, "SV1AlertManager.OrderByExtraFields")
- }
- return q, nil
- }
- func (man *SNodeAlertManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
- var err error
- q, err = man.SCommonAlertManager.QueryDistinctExtraField(q, field)
- if err == nil {
- return q, nil
- }
- return q, httperrors.ErrNotFound
- }
- func (man *SNodeAlertManager) GetAlert(id string) (*SNodeAlert, error) {
- obj, err := man.FetchById(id)
- if err != nil {
- return nil, err
- }
- return obj.(*SNodeAlert), nil
- }
- func (man *SNodeAlertManager) CustomizeFilterList(
- ctx context.Context, q *sqlchemy.SQuery,
- userCred mcclient.TokenCredential, query jsonutils.JSONObject) (
- *db.CustomizeListFilters, error) {
- filters, err := man.SCommonAlertManager.CustomizeFilterList(ctx, q, userCred, query)
- if err != nil {
- return nil, err
- }
- input := new(monitor.NodeAlertListInput)
- if err := query.Unmarshal(input); err != nil {
- return nil, err
- }
- wrapF := func(f func(obj *SNodeAlert) (bool, error)) func(object jsonutils.JSONObject) (bool, error) {
- return func(data jsonutils.JSONObject) (bool, error) {
- id, err := data.GetString("id")
- if err != nil {
- return false, err
- }
- obj, err := man.GetAlert(id)
- if err != nil {
- return false, err
- }
- return f(obj)
- }
- }
- if input.Metric != "" {
- metric := input.Metric
- meaurement, field, err := GetMeasurementField(metric)
- if err != nil {
- return nil, err
- }
- mF := func(obj *SNodeAlert) (bool, error) {
- settings := obj.Settings
- for _, s := range settings.Conditions {
- if s.Query.Model.Measurement == meaurement && len(s.Query.Model.Selects) == 1 {
- if IsQuerySelectHasField(s.Query.Model.Selects[0], field) {
- return true, nil
- }
- }
- }
- return false, nil
- }
- filters.Append(wrapF(mF))
- }
- if input.NodeName != "" {
- nf := func(obj *SNodeAlert) (bool, error) {
- return obj.getNodeName() == input.NodeName, nil
- }
- filters.Append(wrapF(nf))
- }
- if input.NodeId != "" {
- filters.Append(wrapF(func(obj *SNodeAlert) (bool, error) {
- return obj.getNodeId() == input.NodeId, nil
- }))
- }
- if input.Type != "" {
- filters.Append(wrapF(func(obj *SNodeAlert) (bool, error) {
- return obj.getType() == input.Type, nil
- }))
- }
- return filters, nil
- }
- func (alert *SV1Alert) CustomizeCreate(
- ctx context.Context, userCred mcclient.TokenCredential,
- notiName, channel, recipients, usedBy string) error {
- noti, err := MeterAlertManager.CreateNotification(ctx, userCred, notiName, channel, recipients)
- if err != nil {
- return errors.Wrap(err, "create notification")
- }
- if alert.Id == "" {
- alert.Id = db.DefaultUUIDGenerator()
- }
- alert.UsedBy = usedBy
- _, err = alert.AttachNotification(
- ctx, userCred, noti,
- monitor.AlertNotificationStateUnknown,
- usedBy)
- return err
- }
- func (alert *SV1Alert) PostUpdate(
- ctx context.Context, userCred mcclient.TokenCredential,
- query jsonutils.JSONObject, data jsonutils.JSONObject) {
- if data.(*jsonutils.JSONDict).Contains("status") {
- status, _ := data.(*jsonutils.JSONDict).GetString("status")
- alert.UpdateIsEnabledStatus(ctx, userCred, &status)
- }
- }
- func (alert *SNodeAlert) CustomizeCreate(
- ctx context.Context, userCred mcclient.TokenCredential,
- ownerId mcclient.IIdentityProvider,
- query jsonutils.JSONObject,
- data jsonutils.JSONObject,
- ) error {
- input := new(monitor.NodeAlertCreateInput)
- if err := data.Unmarshal(input); err != nil {
- return err
- }
- if alert.Id == "" {
- alert.Id = db.DefaultUUIDGenerator()
- }
- alert.UsedBy = input.UsedBy
- caInput := input.CommonAlertCreateInput
- if err := alert.SCommonAlert.CustomizeCreate(ctx, userCred, ownerId, query, caInput.JSON(caInput)); err != nil {
- return errors.Wrap(err, "CommonAlert.CustomizeCreate")
- }
- return nil
- }
- func (alert *SNodeAlert) getNodeId() string {
- return alert.GetMetadata(context.Background(), NodeAlertMetadataNodeId, nil)
- }
- func (alert *SNodeAlert) setNodeId(ctx context.Context, userCred mcclient.TokenCredential, id string) error {
- return alert.SetMetadata(ctx, NodeAlertMetadataNodeId, id, userCred)
- }
- func (alert *SNodeAlert) getNodeName() string {
- return alert.GetMetadata(context.Background(), NodeAlertMetadataNodeName, nil)
- }
- func (alert *SNodeAlert) setNodeName(ctx context.Context, userCred mcclient.TokenCredential, name string) error {
- return alert.SetMetadata(ctx, NodeAlertMetadataNodeName, name, userCred)
- }
- func (alert *SNodeAlert) getType() string {
- return alert.GetMetadata(context.Background(), NodeAlertMetadataType, nil)
- }
- func (alert *SNodeAlert) setType(ctx context.Context, userCred mcclient.TokenCredential, typ string) error {
- return alert.SetMetadata(ctx, NodeAlertMetadataType, typ, userCred)
- }
- func (alert *SNodeAlert) PostCreate(ctx context.Context,
- userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider,
- query jsonutils.JSONObject, data jsonutils.JSONObject) {
- input := new(monitor.NodeAlertCreateInput)
- if err := data.Unmarshal(input); err != nil {
- log.Errorf("post create unmarshal input: %v", err)
- return
- }
- if err := alert.setNodeId(ctx, userCred, input.NodeId); err != nil {
- log.Errorf("set node id: %v", err)
- return
- }
- if err := alert.setNodeName(ctx, userCred, input.NodeName); err != nil {
- log.Errorf("set node name: %v", err)
- return
- }
- if err := alert.setType(ctx, userCred, input.Type); err != nil {
- log.Errorf("set type: %v", err)
- return
- }
- caInput := input.CommonAlertCreateInput
- alert.SCommonAlert.PostCreate(ctx, userCred, ownerId, query, caInput.JSON(caInput))
- }
- func (man *SV1AlertManager) FetchCustomizeColumns(
- ctx context.Context,
- userCred mcclient.TokenCredential,
- query jsonutils.JSONObject,
- objs []interface{},
- fields stringutils2.SSortedStrings,
- isList bool,
- ) []monitor.AlertV1Details {
- rows := make([]monitor.AlertV1Details, len(objs))
- alertRows := man.SAlertManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
- for i := range rows {
- rows[i] = monitor.AlertV1Details{
- AlertDetails: alertRows[i],
- }
- }
- return rows
- }
- const (
- V1AlertDisabledStatus = "Disabled"
- V1AlertEnabledStatus = "Enabled"
- )
- func (alert *SV1Alert) GetStatus() string {
- if alert.IsEnable() {
- return V1AlertEnabledStatus
- }
- return V1AlertDisabledStatus
- }
- func (alert *SV1Alert) getMoreDetails(out monitor.AlertV1Details, usedBy string) (monitor.AlertV1Details, error) {
- out.Name = alert.GetName()
- if alert.Frequency < 60 {
- out.Window = fmt.Sprintf("%ds", alert.Frequency)
- } else {
- out.Window = fmt.Sprintf("%dm", alert.Frequency/60)
- }
- setting, err := alert.GetSettings()
- if err != nil {
- return out, errors.Wrapf(err, "GetSettings")
- }
- if len(setting.Conditions) == 0 {
- return out, nil
- }
- cond := setting.Conditions[0]
- cmp := ""
- switch cond.Evaluator.Type {
- case "gt":
- cmp = ">="
- case "lt":
- cmp = "<="
- }
- out.Level = alert.Level
- out.Comparator = cmp
- out.Threshold = cond.Evaluator.Params[0]
- out.Period = cond.Query.From
- noti, err := alert.GetNotification(usedBy)
- if err != nil {
- return out, errors.Wrapf(err, "GetNotification for %q", usedBy)
- }
- if noti != nil {
- out.NotifierId = noti.GetId()
- settings := new(monitor.NotificationSettingOneCloud)
- if err := noti.Settings.Unmarshal(settings); err != nil {
- return out, errors.Wrapf(err, "Unmarshal to NotificationSettingOneCloud")
- }
- out.Recipients = strings.Join(settings.UserIds, ",")
- out.Channel = settings.Channel
- }
- q := cond.Query
- measurement := q.Model.Measurement
- field := q.Model.Selects[0][0].Params[0]
- db := q.Model.Database
- out.Measurement = measurement
- out.Field = field
- out.DB = db
- out.Status = alert.GetStatus()
- return out, nil
- }
- func (man *SNodeAlertManager) FetchCustomizeColumns(
- ctx context.Context,
- userCred mcclient.TokenCredential,
- query jsonutils.JSONObject,
- objs []interface{},
- fields stringutils2.SSortedStrings,
- isList bool,
- ) []monitor.NodeAlertDetails {
- rows := make([]monitor.NodeAlertDetails, len(objs))
- cObjs := make([]interface{}, len(objs))
- for i := range objs {
- obj := objs[i].(*SNodeAlert)
- cObjs[i] = &SCommonAlert{obj.SAlert}
- }
- v1Rows := man.SCommonAlertManager.FetchCustomizeColumns(ctx, userCred, query, cObjs, fields, isList)
- for i := range rows {
- rows[i] = monitor.NodeAlertDetails{
- AlertV1Details: monitor.AlertV1Details{
- AlertDetails: v1Rows[i].AlertDetails,
- },
- }
- var err error
- rows[i], err = objs[i].(*SNodeAlert).getMoreDetails(ctx, v1Rows[i], rows[i])
- if err != nil {
- log.Warningf("getMoreDetails for nodealert %s: %v", rows[i].Name, err)
- }
- }
- return rows
- }
- func (alert *SNodeAlert) getMoreDetails(ctx context.Context, input monitor.CommonAlertDetails, out monitor.NodeAlertDetails) (monitor.NodeAlertDetails, error) {
- out.Type = alert.getType()
- out.NodeId = alert.getNodeId()
- out.NodeName = alert.getNodeName()
- out.AlertDetails = input.AlertDetails
- out.Name = alert.GetName()
- out.Period = input.Period
- if alert.Frequency < 60 {
- out.Window = fmt.Sprintf("%ds", alert.Frequency)
- } else {
- out.Window = fmt.Sprintf("%dm", alert.Frequency/60)
- }
- setting, err := alert.GetSettings()
- if err != nil {
- return out, errors.Wrap(err, "GetSettings")
- }
- if len(setting.Conditions) == 0 {
- return out, nil
- }
- cond := setting.Conditions[0]
- cmp := ""
- switch cond.Evaluator.Type {
- case "gt":
- cmp = ">="
- case "lt":
- cmp = "<="
- }
- out.Level = alert.Level
- out.Comparator = cmp
- out.Threshold = cond.Evaluator.Params[0]
- out.Period = cond.Query.From
- q := cond.Query
- measurement := q.Model.Measurement
- field := q.Model.Selects[0][0].Params[0]
- db := q.Model.Database
- out.Measurement = measurement
- out.Field = field
- out.Metric = fmt.Sprintf("%s.%s", out.Measurement, out.Field)
- out.DB = db
- out.Status = alert.GetStatus()
- input, err = alert.SCommonAlert.GetMoreDetails(ctx, input)
- if err != nil {
- return out, errors.Wrap(err, "SCommonAlert.GetMoreDetails")
- }
- if len(input.Channel) > 0 {
- out.Channel = input.Channel[0]
- }
- out.Recipients = strings.Join(input.Recipients, ",")
- return out, nil
- }
- func (alert *SV1Alert) GetNotification(usedby string) (*SNotification, error) {
- alertNotis, err := alert.GetNotifications()
- if err != nil {
- return nil, err
- }
- if len(alertNotis) == 0 {
- return nil, nil
- }
- for _, an := range alertNotis {
- if an.GetUsedBy() == usedby {
- return an.GetNotification()
- }
- }
- return nil, httperrors.NewNotFoundError("not found alert notification used by %s", usedby)
- }
- func (alert *SV1Alert) UpdateNotification(usedBy string, channel, recipients *string) error {
- obj, err := alert.GetNotification(usedBy)
- if err != nil {
- return errors.Wrap(err, "Get notification when update")
- }
- if obj == nil {
- return nil
- }
- setting := new(monitor.NotificationSettingOneCloud)
- if err := obj.Settings.Unmarshal(setting); err != nil {
- return errors.Wrap(err, "unmarshal onecloud notification setting")
- }
- if channel != nil {
- setting.Channel = *channel
- }
- if recipients != nil {
- setting.UserIds = strings.Split(*recipients, ",")
- }
- _, err = db.Update(obj, func() error {
- obj.Settings = jsonutils.Marshal(setting)
- return nil
- })
- return err
- }
- func (alert *SV1Alert) UpdateIsEnabledStatus(ctx context.Context, userCred mcclient.TokenCredential, status *string) error {
- if status == nil {
- return nil
- }
- if status != nil {
- s := *status
- if s == V1AlertDisabledStatus {
- if _, err := alert.PerformDisable(ctx, userCred, nil, apis.PerformDisableInput{}); err != nil {
- return err
- }
- db.Update(&alert.SAlert, func() error {
- alert.SetStatus(ctx, userCred, V1AlertDisabledStatus, "")
- return nil
- })
- } else {
- if _, err := alert.PerformEnable(ctx, userCred, nil, apis.PerformEnableInput{}); err != nil {
- return err
- }
- db.Update(&alert.SAlert, func() error {
- alert.SetStatus(ctx, userCred, V1AlertEnabledStatus, "")
- return nil
- })
- }
- }
- return nil
- }
- func (alert *SV1Alert) CustomizeDelete(
- ctx context.Context, userCred mcclient.TokenCredential,
- query jsonutils.JSONObject, data jsonutils.JSONObject) error {
- notis, err := alert.GetNotifications()
- if err != nil {
- return err
- }
- for _, noti := range notis {
- conf, err := noti.GetNotification()
- if err != nil {
- return err
- }
- if !conf.IsDefault {
- if err := conf.CustomizeDelete(ctx, userCred, query, data); err != nil {
- return err
- }
- if err := conf.Delete(ctx, userCred); err != nil {
- return err
- }
- }
- if err := noti.Detach(ctx, userCred); err != nil {
- return err
- }
- }
- return nil
- }
- func (alert *SNodeAlert) GetCommonAlertUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *monitor.NodeAlertUpdateInput) (jsonutils.JSONObject, error) {
- detailsList := NodeAlertManager.FetchCustomizeColumns(ctx, userCred, nil, []interface{}{alert}, nil, false)
- if len(detailsList) == 0 {
- panic("inconsistent return results of FetchCustomizeColumns")
- }
- details := detailsList[0]
- nameChange := false
- if input.NodeId != nil && *input.NodeId != details.NodeId {
- nameChange = true
- details.NodeId = *input.NodeId
- if err := alert.setNodeId(ctx, userCred, details.NodeId); err != nil {
- return nil, err
- }
- }
- if input.Type != nil && *input.Type != details.Type {
- nameChange = true
- details.Type = *input.Type
- if err := alert.setType(ctx, userCred, details.Type); err != nil {
- return nil, err
- }
- }
- nodeName, resType, err := NodeAlertManager.validateResourceId(ctx, details.Type, details.NodeId)
- if err != nil {
- return nil, err
- }
- if details.NodeName != nodeName {
- nameChange = true
- if err := alert.setNodeName(ctx, userCred, nodeName); err != nil {
- return nil, err
- }
- details.NodeName = nodeName
- }
- if input.Level != nil && *input.Level != details.Level {
- details.Level = *input.Level
- }
- if input.Window != nil && *input.Window != details.Window {
- details.Window = *input.Window
- freq, err := time.ParseDuration(details.Window)
- if err != nil {
- return nil, err
- }
- freqSec := int64(freq / time.Second)
- input.Frequency = &freqSec
- }
- if input.Threshold != nil && *input.Threshold != details.Threshold {
- details.Threshold = *input.Threshold
- }
- if input.Comparator != nil && *input.Comparator != details.Comparator {
- details.Comparator = *input.Comparator
- }
- if input.Period != nil && *input.Period != details.Period {
- details.Period = *input.Period
- }
- if input.Channel != nil {
- details.Channel = *input.Channel
- }
- if input.Recipients != nil {
- details.Recipients = *input.Recipients
- }
- if input.Metric != nil && *input.Metric != details.Metric {
- details.Metric = *input.Metric
- measurement, field, err := GetMeasurementField(*input.Metric)
- if err != nil {
- return nil, err
- }
- details.Measurement = measurement
- details.Field = field
- }
- name := alert.Name
- if nameChange {
- name, err = NodeAlertManager.genName(ctx, userCred, resType, details.NodeName, details.Metric)
- if err != nil {
- return nil, err
- }
- input.Name = name
- }
- tmpS := alert.getUpdateInput(name, details)
- input.Settings = &tmpS.Settings
- uData, err := alert.SCommonAlert.ValidateUpdateData(ctx, userCred, nil, tmpS.JSON(tmpS))
- if err != nil {
- return nil, errors.Wrap(err, "SCommonAlert.ValidateUpdateData")
- }
- return uData, nil
- }
- func (alert *SNodeAlert) ValidateUpdateData(
- ctx context.Context,
- userCred mcclient.TokenCredential,
- query jsonutils.JSONObject,
- input monitor.NodeAlertUpdateInput,
- ) (jsonutils.JSONObject, error) {
- return alert.GetCommonAlertUpdateData(ctx, userCred, query, &input)
- }
- func (alert *SNodeAlert) getUpdateInput(
- name string,
- details monitor.NodeAlertDetails,
- ) monitor.CommonAlertCreateInput {
- data := monitor.NodeAlertCreateInput{
- ResourceAlertV1CreateInput: monitor.ResourceAlertV1CreateInput{
- Period: details.Period,
- Window: details.Window,
- Comparator: details.Comparator,
- Threshold: details.Threshold,
- Channel: details.Channel,
- Recipients: details.Recipients,
- },
- Metric: details.Metric,
- Type: details.Type,
- NodeId: details.NodeId,
- }
- data.Level = details.Level
- out := data.ToCommonAlertCreateInput(name, details.Field, details.Measurement, details.DB)
- out.Settings = *setAlertDefaultSetting(&out.Settings)
- return out
- }
- func (alert *SNodeAlert) PostUpdate(
- ctx context.Context, userCred mcclient.TokenCredential,
- query jsonutils.JSONObject, data jsonutils.JSONObject) {
- input := new(monitor.NodeAlertUpdateInput)
- data.Unmarshal(input)
- uData, err := alert.GetCommonAlertUpdateData(ctx, userCred, query, input)
- if err != nil {
- log.Errorf("GetCommonAlertUpdateData when PostUpdate: %v", err)
- }
- alert.SCommonAlert.PostUpdate(ctx, userCred, query, uData)
- }
- func (alert *SNodeAlert) CustomizeDelete(
- ctx context.Context, userCred mcclient.TokenCredential,
- query jsonutils.JSONObject, data jsonutils.JSONObject) error {
- return alert.SCommonAlert.CustomizeDelete(ctx, userCred, query, data)
- }
- func (m *SNodeAlertManager) FilterByOwner(ctx context.Context, q *sqlchemy.SQuery, man db.FilterByOwnerProvider, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
- return q
- }
|