Просмотр исходного кода

add threshold to notifications to avoid too many notifs

Alexander Belanger 4 лет назад
Родитель
Сommit
25621b2379
4 измененных файлов с 68 добавлено и 7 удалено
  1. 3 0
      .gitignore
  2. 44 4
      api/server/handlers/kube_events/create.go
  3. 2 0
      api/types/release.go
  4. 19 3
      internal/models/notification.go

+ 3 - 0
.gitignore

@@ -15,6 +15,9 @@ staging.sh
 *.key
 bin
 
+# Local docs directories
+/docs/.obsidian
+
 # Local .terraform directories
 **/.terraform/*
 

+ 44 - 4
api/server/handlers/kube_events/create.go

@@ -99,13 +99,30 @@ func notifyPodCrashing(
 	cluster *models.Cluster,
 	event *types.CreateKubeEventRequest,
 ) error {
-	slackInts, _ := config.Repo.SlackIntegration().ListSlackIntegrationsByProjectID(project.ID)
-
-	notifier := slack.NewSlackNotifier(&types.NotificationConfig{
+	notifConfig := &types.NotificationConfig{
 		Enabled: true,
 		Success: true,
 		Failure: true,
-	}, slackInts...)
+	}
+
+	// attempt to get a matching Porter release to get the notification configuration
+	matchedRel := getMatchedPorterRelease(config, cluster.ID, event.OwnerName, event.Namespace)
+
+	if matchedRel != nil {
+		conf, err := config.Repo.NotificationConfig().ReadNotificationConfig(matchedRel.NotificationConfig)
+
+		if !conf.ShouldNotify() {
+			return nil
+		}
+
+		if err == nil && conf != nil {
+			notifConfig = conf.ToNotificationConfigType()
+		}
+	}
+
+	slackInts, _ := config.Repo.SlackIntegration().ListSlackIntegrationsByProjectID(project.ID)
+
+	notifier := slack.NewSlackNotifier(notifConfig, slackInts...)
 
 	notifyOpts := &slack.NotifyOpts{
 		ProjectID:   cluster.ProjectID,
@@ -120,3 +137,26 @@ func notifyPodCrashing(
 
 	return notifier.Notify(notifyOpts)
 }
+
+// getMatchedPorterRelease attempts to find a matching Porter release from the name of a controller.
+// For example, if the controller has a suffix "-web", it is likely a Porter web application, and
+// so we query for a Porter release with a matching name. Returns nil if no match is found
+func getMatchedPorterRelease(config *config.Config, clusterID uint, ownerName, namespace string) *models.Release {
+	matchingName := ""
+
+	if strings.Contains(ownerName, "-web") {
+		matchingName = strings.Split(ownerName, "-web")[0]
+	} else if strings.Contains(ownerName, "-worker") {
+		matchingName = strings.Split(ownerName, "-worker")[0]
+	} else if strings.Contains(ownerName, "-job") {
+		matchingName = strings.Split(ownerName, "-job")[0]
+	}
+
+	rel, err := config.Repo.Release().ReadRelease(clusterID, matchingName, namespace)
+
+	if err != nil {
+		return nil
+	}
+
+	return rel
+}

+ 2 - 0
api/types/release.go

@@ -114,6 +114,8 @@ type NotificationConfig struct {
 	Enabled bool `json:"enabled"`
 	Success bool `json:"success"`
 	Failure bool `json:"failure"`
+
+	NotifLimit string `json:"notif_limit"`
 }
 
 type GetNotificationConfigResponse struct {

+ 19 - 3
internal/models/notification.go

@@ -1,6 +1,8 @@
 package models
 
 import (
+	"time"
+
 	"github.com/porter-dev/porter/api/types"
 	"gorm.io/gorm"
 )
@@ -12,12 +14,26 @@ type NotificationConfig struct {
 
 	Success bool
 	Failure bool
+
+	LastNotifiedTime time.Time
+	NotifLimit       string
 }
 
 func (conf *NotificationConfig) ToNotificationConfigType() *types.NotificationConfig {
 	return &types.NotificationConfig{
-		Enabled: conf.Enabled,
-		Success: conf.Success,
-		Failure: conf.Failure,
+		Enabled:    conf.Enabled,
+		Success:    conf.Success,
+		Failure:    conf.Failure,
+		NotifLimit: conf.NotifLimit,
 	}
 }
+
+func (conf *NotificationConfig) ShouldNotify() bool {
+	// check the last notified time against the notification limit
+	return conf.LastNotifiedTime.Before(notifLimitToTime(conf.NotifLimit))
+}
+
+func notifLimitToTime(notifTime string) time.Time {
+	// TODO: compute a time that's not just 5 min
+	return time.Now().Add(-5 * time.Minute)
+}