|
|
@@ -61,6 +61,7 @@ func (p *CreateUpdatePorterAppEventHandler) ServeHTTP(w http.ResponseWriter, r *
|
|
|
telemetry.AttributeKV{Key: "porter-app-event-status", Value: request.Status},
|
|
|
telemetry.AttributeKV{Key: "porter-app-event-external-source", Value: request.TypeExternalSource},
|
|
|
telemetry.AttributeKV{Key: "porter-app-event-id", Value: request.ID},
|
|
|
+ telemetry.AttributeKV{Key: "deployment-target-id", Value: request.DeploymentTargetID},
|
|
|
)
|
|
|
|
|
|
if request.Type == types.PorterAppEventType_Build {
|
|
|
@@ -68,7 +69,7 @@ func (p *CreateUpdatePorterAppEventHandler) ServeHTTP(w http.ResponseWriter, r *
|
|
|
}
|
|
|
|
|
|
if request.ID == "" {
|
|
|
- event, err := p.createNewAppEvent(ctx, *cluster, appName, request.Status, string(request.Type), request.TypeExternalSource, request.Metadata)
|
|
|
+ event, err := p.createNewAppEvent(ctx, *cluster, appName, request.DeploymentTargetID, request.Status, string(request.Type), request.TypeExternalSource, request.Metadata)
|
|
|
if err != nil {
|
|
|
e := telemetry.Error(ctx, span, err, "error creating new app event")
|
|
|
p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(e, http.StatusBadRequest))
|
|
|
@@ -116,7 +117,7 @@ func reportBuildStatus(ctx context.Context, request *types.CreateOrUpdatePorterA
|
|
|
}
|
|
|
|
|
|
// createNewAppEvent will create a new app event for the given porter app name. If the app event is an agent event, then it will be created only if there is no existing event which has the agent ID. In the case that an existing event is found, that will be returned instead
|
|
|
-func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Context, cluster models.Cluster, porterAppName string, status types.PorterAppEventStatus, eventType string, externalSource string, requestMetadata map[string]any) (types.PorterAppEvent, error) {
|
|
|
+func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Context, cluster models.Cluster, porterAppName string, deploymentTargetID string, status types.PorterAppEventStatus, eventType string, externalSource string, requestMetadata map[string]any) (types.PorterAppEvent, error) {
|
|
|
ctx, span := telemetry.NewSpan(ctx, "create-porter-app-event")
|
|
|
defer span.End()
|
|
|
|
|
|
@@ -138,13 +139,29 @@ func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Contex
|
|
|
// Agent has no way to know what the porter app event id is, so if we must dedup here
|
|
|
// TODO: create a filter to filter by only agent events. Not an issue now as app events are deduped per hour on the agent side
|
|
|
if agentEventID, ok := requestMetadata["agent_event_id"]; ok {
|
|
|
- existingEvents, _, err := p.Repo().PorterAppEvent().ListEventsByPorterAppID(ctx, app.ID)
|
|
|
- if err != nil {
|
|
|
- return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "error listing porter app events for event type")
|
|
|
+ var existingEvents []*models.PorterAppEvent
|
|
|
+ if deploymentTargetID == "" {
|
|
|
+ existingEvents, _, err = p.Repo().PorterAppEvent().ListEventsByPorterAppID(ctx, app.ID)
|
|
|
+ if err != nil {
|
|
|
+ return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "error listing porter app events for event type")
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ deploymentTargetUUID, err := uuid.Parse(deploymentTargetID)
|
|
|
+ if err != nil {
|
|
|
+ return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "error parsing deployment target id")
|
|
|
+ }
|
|
|
+ if deploymentTargetUUID == uuid.Nil {
|
|
|
+ return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "deployment target id cannot be nil")
|
|
|
+ }
|
|
|
+
|
|
|
+ existingEvents, _, err = p.Repo().PorterAppEvent().ListEventsByPorterAppIDAndDeploymentTargetID(ctx, app.ID, deploymentTargetUUID)
|
|
|
+ if err != nil {
|
|
|
+ return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "error listing porter app events for event type with deployment target id")
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
for _, existingEvent := range existingEvents {
|
|
|
- if existingEvent.Type == eventType {
|
|
|
+ if existingEvent != nil && existingEvent.Type == eventType {
|
|
|
existingAgentEventID, ok := existingEvent.Metadata["agent_event_id"]
|
|
|
if !ok {
|
|
|
continue
|
|
|
@@ -163,7 +180,7 @@ func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Contex
|
|
|
if eventType == string(types.PorterAppEventType_Deploy) {
|
|
|
// Agent has no way to know what the porter app event id is, so update the deploy event if it exists
|
|
|
if _, ok := requestMetadata["deploy_status"]; ok {
|
|
|
- return p.updateDeployEvent(ctx, porterAppName, app.ID, requestMetadata), nil
|
|
|
+ return p.updateDeployEvent(ctx, porterAppName, app.ID, deploymentTargetID, requestMetadata), nil
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -176,6 +193,17 @@ func (p *CreateUpdatePorterAppEventHandler) createNewAppEvent(ctx context.Contex
|
|
|
Metadata: make(map[string]any),
|
|
|
}
|
|
|
|
|
|
+ if deploymentTargetID != "" {
|
|
|
+ deploymentTargetUUID, err := uuid.Parse(deploymentTargetID)
|
|
|
+ if err != nil {
|
|
|
+ return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "error parsing deployment target id")
|
|
|
+ }
|
|
|
+ if deploymentTargetUUID == uuid.Nil {
|
|
|
+ return types.PorterAppEvent{}, telemetry.Error(ctx, span, err, "deployment target id cannot be nil")
|
|
|
+ }
|
|
|
+ event.DeploymentTargetID = deploymentTargetUUID
|
|
|
+ }
|
|
|
+
|
|
|
for k, v := range requestMetadata {
|
|
|
event.Metadata[k] = v
|
|
|
}
|
|
|
@@ -246,40 +274,86 @@ func (p *CreateUpdatePorterAppEventHandler) updateExistingAppEvent(ctx context.C
|
|
|
// 4. the services specified in the updatedStatusMetadata match the services in the deploy event metadata
|
|
|
// 5. some of the above services are still in the PROGRESSING state
|
|
|
// if one of these conditions is not met, then an empty event is returned and no update is made; otherwise, the matched event is returned
|
|
|
-func (p *CreateUpdatePorterAppEventHandler) updateDeployEvent(ctx context.Context, appName string, appID uint, updatedStatusMetadata map[string]any) types.PorterAppEvent {
|
|
|
+func (p *CreateUpdatePorterAppEventHandler) updateDeployEvent(ctx context.Context, appName string, appID uint, deploymentTargetID string, updatedStatusMetadata map[string]any) types.PorterAppEvent {
|
|
|
ctx, span := telemetry.NewSpan(ctx, "update-deploy-event")
|
|
|
defer span.End()
|
|
|
|
|
|
- revision, ok := updatedStatusMetadata["revision"]
|
|
|
- if !ok {
|
|
|
- _ = telemetry.Error(ctx, span, nil, "revision not found in request metadata")
|
|
|
- return types.PorterAppEvent{}
|
|
|
- }
|
|
|
- revisionFloat64, ok := revision.(float64)
|
|
|
- if !ok {
|
|
|
- _ = telemetry.Error(ctx, span, nil, "revision not a float64")
|
|
|
- return types.PorterAppEvent{}
|
|
|
- }
|
|
|
- telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "revision", Value: revisionFloat64})
|
|
|
+ var serviceName string
|
|
|
+ var matchEvent models.PorterAppEvent
|
|
|
|
|
|
- podName, ok := updatedStatusMetadata["pod_name"]
|
|
|
- if !ok {
|
|
|
- _ = telemetry.Error(ctx, span, nil, "pod name not found in request metadata")
|
|
|
- return types.PorterAppEvent{}
|
|
|
- }
|
|
|
- podNameStr, ok := podName.(string)
|
|
|
- if !ok {
|
|
|
- _ = telemetry.Error(ctx, span, nil, "pod name not a string")
|
|
|
- return types.PorterAppEvent{}
|
|
|
- }
|
|
|
- telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "pod-name", Value: podNameStr})
|
|
|
+ if deploymentTargetID != "" {
|
|
|
+ appRevisionIDField, ok := updatedStatusMetadata["app_revision_id"]
|
|
|
+ if !ok {
|
|
|
+ _ = telemetry.Error(ctx, span, nil, "app_revision_id not found in request metadata")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ appRevisionID, ok := appRevisionIDField.(string)
|
|
|
+ if !ok {
|
|
|
+ _ = telemetry.Error(ctx, span, nil, "appRevisionID is not a string")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "app-revision-id", Value: appRevisionID})
|
|
|
|
|
|
- serviceName := getServiceNameFromPodName(podNameStr, appName)
|
|
|
- if serviceName == "" {
|
|
|
- _ = telemetry.Error(ctx, span, nil, "service name not found in pod name")
|
|
|
- return types.PorterAppEvent{}
|
|
|
+ serviceNameField, ok := updatedStatusMetadata["service_name"]
|
|
|
+ if !ok {
|
|
|
+ _ = telemetry.Error(ctx, span, nil, "service_name not found in request metadata")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ serviceName, ok = serviceNameField.(string)
|
|
|
+ if !ok {
|
|
|
+ _ = telemetry.Error(ctx, span, nil, "serviceName is not a string")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "service-name", Value: serviceName})
|
|
|
+
|
|
|
+ var err error
|
|
|
+ matchEvent, err = p.Repo().PorterAppEvent().ReadDeployEventByAppRevisionID(ctx, appID, appRevisionID)
|
|
|
+ if err != nil {
|
|
|
+ _ = telemetry.Error(ctx, span, err, "error finding matching deploy event")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "updating-deployment-event", Value: false})
|
|
|
+ } else {
|
|
|
+ revision, ok := updatedStatusMetadata["revision"]
|
|
|
+ if !ok {
|
|
|
+ _ = telemetry.Error(ctx, span, nil, "revision not found in request metadata")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ revisionFloat64, ok := revision.(float64)
|
|
|
+ if !ok {
|
|
|
+ _ = telemetry.Error(ctx, span, nil, "revision not a float64")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "revision", Value: revisionFloat64})
|
|
|
+
|
|
|
+ podName, ok := updatedStatusMetadata["pod_name"]
|
|
|
+ if !ok {
|
|
|
+ _ = telemetry.Error(ctx, span, nil, "pod name not found in request metadata")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ podNameStr, ok := podName.(string)
|
|
|
+ if !ok {
|
|
|
+ _ = telemetry.Error(ctx, span, nil, "pod name not a string")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "pod-name", Value: podNameStr})
|
|
|
+
|
|
|
+ serviceName = getServiceNameFromPodName(podNameStr, appName)
|
|
|
+ if serviceName == "" {
|
|
|
+ _ = telemetry.Error(ctx, span, nil, "service name not found in pod name")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+ telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "service-name", Value: serviceName})
|
|
|
+
|
|
|
+ var err error
|
|
|
+ matchEvent, err = p.Repo().PorterAppEvent().ReadDeployEventByRevision(ctx, appID, revisionFloat64)
|
|
|
+ if err != nil {
|
|
|
+ _ = telemetry.Error(ctx, span, err, "error finding matching deploy event")
|
|
|
+ return types.PorterAppEvent{}
|
|
|
+ }
|
|
|
+
|
|
|
+ telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "updating-deployment-event", Value: false})
|
|
|
}
|
|
|
- telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "service-name", Value: serviceName})
|
|
|
|
|
|
newStatus, ok := updatedStatusMetadata["deploy_status"]
|
|
|
if !ok {
|
|
|
@@ -306,14 +380,6 @@ func (p *CreateUpdatePorterAppEventHandler) updateDeployEvent(ctx context.Contex
|
|
|
|
|
|
telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "new-status", Value: string(porterAppEventStatus)})
|
|
|
|
|
|
- matchEvent, err := p.Repo().PorterAppEvent().ReadDeployEventByRevision(ctx, appID, revisionFloat64)
|
|
|
- if err != nil {
|
|
|
- _ = telemetry.Error(ctx, span, err, "error finding matching deploy event")
|
|
|
- return types.PorterAppEvent{}
|
|
|
- }
|
|
|
-
|
|
|
- telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "updating-deployment-event", Value: false})
|
|
|
-
|
|
|
// first check to see if the event is empty, meaning there was no match found, or not progressing, meaning it has already been updated
|
|
|
if matchEvent.ID == uuid.Nil || matchEvent.Status != string(types.PorterAppEventStatus_Progressing) {
|
|
|
return types.PorterAppEvent{}
|
|
|
@@ -382,7 +448,7 @@ func (p *CreateUpdatePorterAppEventHandler) updateDeployEvent(ctx context.Contex
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- err = p.Repo().PorterAppEvent().UpdateEvent(ctx, &matchEvent)
|
|
|
+ err := p.Repo().PorterAppEvent().UpdateEvent(ctx, &matchEvent)
|
|
|
if err != nil {
|
|
|
_ = telemetry.Error(ctx, span, err, "error updating deploy event")
|
|
|
return matchEvent.ToPorterAppEvent()
|