Selaa lähdekoodia

add latest events to latest revision

Feroze Mohideen 2 vuotta sitten
vanhempi
sitoutus
acecfd9039

+ 33 - 3
api/server/handlers/porter_app/current_app_revision.go

@@ -13,6 +13,7 @@ import (
 	"github.com/google/uuid"
 
 	"github.com/porter-dev/porter/internal/porter_app"
+	"github.com/porter-dev/porter/internal/porter_app/notifications"
 	"github.com/porter-dev/porter/internal/telemetry"
 
 	"github.com/porter-dev/porter/api/server/handlers"
@@ -50,6 +51,8 @@ type LatestAppRevisionRequest struct {
 type LatestAppRevisionResponse struct {
 	// AppRevision is the latest revision for the app
 	AppRevision porter_app.Revision `json:"app_revision"`
+	// Notifications are the notifications associated with the app revision
+	Notifications []notifications.Notification `json:"notifications"`
 }
 
 // ServeHTTP translates the request into a CurrentAppRevision grpc request, forwards to the cluster control plane, and returns the response.
@@ -107,7 +110,10 @@ func (c *LatestAppRevisionHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ
 		return
 	}
 
-	if porterApps[0].ID == 0 {
+	appId := porterApps[0].ID
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "app-id", Value: appId})
+
+	if appId == 0 {
 		err := telemetry.Error(ctx, span, err, "porter app id is missing")
 		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
@@ -115,7 +121,7 @@ func (c *LatestAppRevisionHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ
 
 	currentAppRevisionReq := connect.NewRequest(&porterv1.CurrentAppRevisionRequest{
 		ProjectId:          int64(project.ID),
-		AppId:              int64(porterApps[0].ID),
+		AppId:              int64(appId),
 		DeploymentTargetId: request.DeploymentTargetID,
 	})
 
@@ -140,8 +146,32 @@ func (c *LatestAppRevisionHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ
 		return
 	}
 
+	appRevisionId := encodedRevision.ID
+	notificationEvents, err := c.Repo().PorterAppEvent().ReadNotificationsByAppRevisionID(ctx, appId, appRevisionId)
+	if err != nil {
+		err := telemetry.Error(ctx, span, err, "error getting notifications from repo")
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+		return
+	}
+	latestNotifications := make([]notifications.Notification, 0)
+	for _, event := range notificationEvents {
+		notification, err := notifications.NotificationFromPorterAppEvent(event)
+		if err != nil {
+			err := telemetry.Error(ctx, span, err, "error converting porter app event to notification")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+			return
+		}
+		if notification == nil {
+			err := telemetry.Error(ctx, span, err, "notification is nil")
+			c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
+			return
+		}
+		latestNotifications = append(latestNotifications, *notification)
+	}
+
 	response := LatestAppRevisionResponse{
-		AppRevision: encodedRevision,
+		AppRevision:   encodedRevision,
+		Notifications: latestNotifications,
 	}
 
 	c.WriteResult(w, r, response)

+ 15 - 6
internal/porter_app/notifications/app_event.go

@@ -107,15 +107,10 @@ func isNotificationDuplicate(
 
 	for _, existingEvent := range existingEvents {
 		if existingEvent != nil && existingEvent.Type == PorterAppEventType_Notification {
-			existingNotification := &Notification{}
-			bytes, err := json.Marshal(existingEvent.Metadata)
+			existingNotification, err := NotificationFromPorterAppEvent(existingEvent)
 			if err != nil {
 				continue
 			}
-			err = json.Unmarshal(bytes, existingNotification)
-			if err != nil || existingNotification == nil {
-				continue
-			}
 			if existingNotification.AgentEventID == 0 {
 				continue
 			}
@@ -271,3 +266,17 @@ func saveNotification(ctx context.Context, notification Notification, eventRepo
 
 	return nil
 }
+
+func NotificationFromPorterAppEvent(appEvent *models.PorterAppEvent) (*Notification, error) {
+	notification := &Notification{}
+	bytes, err := json.Marshal(appEvent.Metadata)
+	if err != nil {
+		return nil, err
+	}
+	err = json.Unmarshal(bytes, notification)
+	if err != nil {
+		return nil, err
+	}
+
+	return notification, nil
+}

+ 2 - 2
internal/porter_app/notifications/deployment.go

@@ -103,7 +103,7 @@ func deploymentStatus(depl v1.Deployment) DeploymentStatus {
 
 	for _, condition := range depl.Status.Conditions {
 		if condition.Type == "Progressing" {
-			if condition.Status == "True" && condition.Reason == "NewReplicaSetAvailable" {
+			if condition.Status == "True" && condition.Reason == "NewReplicaSetAvailable" && depl.Status.ReadyReplicas == depl.Status.Replicas {
 				deploymentStatus = DeploymentStatus_Success
 				break
 			} else if condition.Status == "False" && condition.Reason == "ProgressDeadlineExceeded" {
@@ -134,7 +134,7 @@ func detailIndicatesDeploymentFailure(detail string) bool {
 
 func translateAgentSummary(notification Notification, status DeploymentStatus) string {
 	humanReadableSummary := notification.AgentSummary
-	pattern := `application \w+ in namespace \w+`
+	pattern := `application (\S+) in namespace (\S+)`
 	regex := regexp.MustCompile(pattern)
 	if regex.MatchString(humanReadableSummary) {
 		fmt.Printf("matched regex\n")

+ 0 - 1
internal/porter_app/notifications/notification.go

@@ -89,7 +89,6 @@ type Notification struct {
 	AppRevisionID        string     `json:"app_revision_id"`
 	AgentEventID         int        `json:"agent_event_id"`
 	AgentDetail          string     `json:"agent_detail"`
-	AgentShortSummary    string     `json:"agent_short_summary"`
 	AgentSummary         string     `json:"agent_summary"`
 	HumanReadableDetail  string     `json:"human_readable_detail"`
 	HumanReadableSummary string     `json:"human_readable_summary"`

+ 20 - 0
internal/repository/gorm/porter_app_event.go

@@ -136,6 +136,26 @@ func (repo *PorterAppEventRepository) ReadEvent(ctx context.Context, id uuid.UUI
 	return appEvent, nil
 }
 
+func (repo *PorterAppEventRepository) ReadNotificationsByAppRevisionID(ctx context.Context, porterAppID uint, appRevisionId string) ([]*models.PorterAppEvent, error) {
+	notifications := []*models.PorterAppEvent{}
+
+	if appRevisionId == "" {
+		return notifications, errors.New("invalid app revision ID supplied")
+	}
+
+	if porterAppID == 0 {
+		return notifications, errors.New("invalid porter app ID supplied")
+	}
+
+	strAppID := strconv.Itoa(int(porterAppID))
+
+	if err := repo.db.Where("porter_app_id = ? AND type = 'NOTIFICATION' AND metadata->>'app_revision_id' = ?", strAppID, appRevisionId).Find(&notifications).Error; err != nil {
+		return notifications, err
+	}
+
+	return notifications, nil
+}
+
 func (repo *PorterAppEventRepository) ReadDeployEventByRevision(ctx context.Context, porterAppID uint, revision float64) (models.PorterAppEvent, error) {
 	appEvent := models.PorterAppEvent{}
 

+ 1 - 0
internal/repository/porter_app_event.go

@@ -19,4 +19,5 @@ type PorterAppEventRepository interface {
 	ReadDeployEventByRevision(ctx context.Context, porterAppID uint, revision float64) (models.PorterAppEvent, error)
 	// ReadDeployEventByAppRevisionID returns a deploy event for a given porter app id and app revision ID
 	ReadDeployEventByAppRevisionID(ctx context.Context, porterAppID uint, appRevisionID string) (models.PorterAppEvent, error)
+	ReadNotificationsByAppRevisionID(ctx context.Context, porterAppID uint, appRevisionID string) ([]*models.PorterAppEvent, error)
 }