| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- package service
- import (
- "context"
- "database/sql"
- "errors"
- "strings"
- "time"
- infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
- )
- func (s *OpsService) ListAlertRules(ctx context.Context) ([]*OpsAlertRule, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return []*OpsAlertRule{}, nil
- }
- return s.opsRepo.ListAlertRules(ctx)
- }
- func (s *OpsService) CreateAlertRule(ctx context.Context, rule *OpsAlertRule) (*OpsAlertRule, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return nil, infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if rule == nil {
- return nil, infraerrors.BadRequest("INVALID_RULE", "invalid rule")
- }
- created, err := s.opsRepo.CreateAlertRule(ctx, rule)
- if err != nil {
- return nil, err
- }
- return created, nil
- }
- func (s *OpsService) UpdateAlertRule(ctx context.Context, rule *OpsAlertRule) (*OpsAlertRule, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return nil, infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if rule == nil || rule.ID <= 0 {
- return nil, infraerrors.BadRequest("INVALID_RULE", "invalid rule")
- }
- updated, err := s.opsRepo.UpdateAlertRule(ctx, rule)
- if err != nil {
- if errors.Is(err, sql.ErrNoRows) {
- return nil, infraerrors.NotFound("OPS_ALERT_RULE_NOT_FOUND", "alert rule not found")
- }
- return nil, err
- }
- return updated, nil
- }
- func (s *OpsService) DeleteAlertRule(ctx context.Context, id int64) error {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return err
- }
- if s.opsRepo == nil {
- return infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if id <= 0 {
- return infraerrors.BadRequest("INVALID_RULE_ID", "invalid rule id")
- }
- if err := s.opsRepo.DeleteAlertRule(ctx, id); err != nil {
- if errors.Is(err, sql.ErrNoRows) {
- return infraerrors.NotFound("OPS_ALERT_RULE_NOT_FOUND", "alert rule not found")
- }
- return err
- }
- return nil
- }
- func (s *OpsService) ListAlertEvents(ctx context.Context, filter *OpsAlertEventFilter) ([]*OpsAlertEvent, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return []*OpsAlertEvent{}, nil
- }
- return s.opsRepo.ListAlertEvents(ctx, filter)
- }
- func (s *OpsService) GetAlertEventByID(ctx context.Context, eventID int64) (*OpsAlertEvent, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return nil, infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if eventID <= 0 {
- return nil, infraerrors.BadRequest("INVALID_EVENT_ID", "invalid event id")
- }
- ev, err := s.opsRepo.GetAlertEventByID(ctx, eventID)
- if err != nil {
- if errors.Is(err, sql.ErrNoRows) {
- return nil, infraerrors.NotFound("OPS_ALERT_EVENT_NOT_FOUND", "alert event not found")
- }
- return nil, err
- }
- if ev == nil {
- return nil, infraerrors.NotFound("OPS_ALERT_EVENT_NOT_FOUND", "alert event not found")
- }
- return ev, nil
- }
- func (s *OpsService) GetActiveAlertEvent(ctx context.Context, ruleID int64) (*OpsAlertEvent, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return nil, infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if ruleID <= 0 {
- return nil, infraerrors.BadRequest("INVALID_RULE_ID", "invalid rule id")
- }
- return s.opsRepo.GetActiveAlertEvent(ctx, ruleID)
- }
- func (s *OpsService) CreateAlertSilence(ctx context.Context, input *OpsAlertSilence) (*OpsAlertSilence, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return nil, infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if input == nil {
- return nil, infraerrors.BadRequest("INVALID_SILENCE", "invalid silence")
- }
- if input.RuleID <= 0 {
- return nil, infraerrors.BadRequest("INVALID_RULE_ID", "invalid rule id")
- }
- if strings.TrimSpace(input.Platform) == "" {
- return nil, infraerrors.BadRequest("INVALID_PLATFORM", "invalid platform")
- }
- if input.Until.IsZero() {
- return nil, infraerrors.BadRequest("INVALID_UNTIL", "invalid until")
- }
- created, err := s.opsRepo.CreateAlertSilence(ctx, input)
- if err != nil {
- return nil, err
- }
- return created, nil
- }
- func (s *OpsService) IsAlertSilenced(ctx context.Context, ruleID int64, platform string, groupID *int64, region *string, now time.Time) (bool, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return false, err
- }
- if s.opsRepo == nil {
- return false, infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if ruleID <= 0 {
- return false, infraerrors.BadRequest("INVALID_RULE_ID", "invalid rule id")
- }
- if strings.TrimSpace(platform) == "" {
- return false, nil
- }
- return s.opsRepo.IsAlertSilenced(ctx, ruleID, platform, groupID, region, now)
- }
- func (s *OpsService) GetLatestAlertEvent(ctx context.Context, ruleID int64) (*OpsAlertEvent, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return nil, infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if ruleID <= 0 {
- return nil, infraerrors.BadRequest("INVALID_RULE_ID", "invalid rule id")
- }
- return s.opsRepo.GetLatestAlertEvent(ctx, ruleID)
- }
- func (s *OpsService) CreateAlertEvent(ctx context.Context, event *OpsAlertEvent) (*OpsAlertEvent, error) {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return nil, err
- }
- if s.opsRepo == nil {
- return nil, infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if event == nil {
- return nil, infraerrors.BadRequest("INVALID_EVENT", "invalid event")
- }
- created, err := s.opsRepo.CreateAlertEvent(ctx, event)
- if err != nil {
- return nil, err
- }
- return created, nil
- }
- func (s *OpsService) UpdateAlertEventStatus(ctx context.Context, eventID int64, status string, resolvedAt *time.Time) error {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return err
- }
- if s.opsRepo == nil {
- return infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if eventID <= 0 {
- return infraerrors.BadRequest("INVALID_EVENT_ID", "invalid event id")
- }
- status = strings.TrimSpace(status)
- if status == "" {
- return infraerrors.BadRequest("INVALID_STATUS", "invalid status")
- }
- if status != OpsAlertStatusResolved && status != OpsAlertStatusManualResolved {
- return infraerrors.BadRequest("INVALID_STATUS", "invalid status")
- }
- return s.opsRepo.UpdateAlertEventStatus(ctx, eventID, status, resolvedAt)
- }
- func (s *OpsService) UpdateAlertEventEmailSent(ctx context.Context, eventID int64, emailSent bool) error {
- if err := s.RequireMonitoringEnabled(ctx); err != nil {
- return err
- }
- if s.opsRepo == nil {
- return infraerrors.ServiceUnavailable("OPS_REPO_UNAVAILABLE", "Ops repository not available")
- }
- if eventID <= 0 {
- return infraerrors.BadRequest("INVALID_EVENT_ID", "invalid event id")
- }
- return s.opsRepo.UpdateAlertEventEmailSent(ctx, eventID, emailSent)
- }
|