Skip to content

Commit

Permalink
event-reporter: report all revisions metadata instead single to suppo…
Browse files Browse the repository at this point in the history
…rt multisourced apps
  • Loading branch information
oleksandr-codefresh committed Sep 11, 2024
1 parent 9ecb8eb commit 1113941
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 55 deletions.
30 changes: 18 additions & 12 deletions event_reporter/reporter/app_revision.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,27 @@ func (s *applicationEventReporter) getCommitRevisionsDetails(ctx context.Context
func (s *applicationEventReporter) getApplicationRevisionsMetadata(ctx context.Context, logCtx *log.Entry, a *appv1.Application) (*utils.AppSyncRevisionsMetadata, error) {
result := &utils.AppSyncRevisionsMetadata{}

// can be the latest revision of repository
operationSyncRevisionsMetadata, err := s.getCommitRevisionsDetails(ctx, a, utils.GetOperationSyncRevisions(a))
if source, _ := a.Spec.GetNonRefSource(); !source.IsHelm() && (a.Status.Sync.Revision != "" || a.Status.Sync.Revisions != nil || (a.Status.History != nil && len(a.Status.History) > 0)) {
// can be the latest revision of repository
operationSyncRevisionsMetadata, err := s.getCommitRevisionsDetails(ctx, a, utils.GetOperationSyncRevisions(a))

if err != nil {
logCtx.WithError(err).Warnf("failed to get application(%s) revisions metadata, resuming", a.GetName())
}
if err != nil {
logCtx.WithError(err).Warnf("failed to get application(%s) sync revisions metadata, resuming", a.GetName())
}

if operationSyncRevisionsMetadata != nil {
result.SyncRevisions = operationSyncRevisionsMetadata
}
// latest revision of repository where changes to app resource were actually made; empty if no changeRevisionі present
operationChangeRevisionsMetadata, err := s.getCommitRevisionsDetails(ctx, a, utils.GetOperationChangeRevisions(a))
if err == nil && operationSyncRevisionsMetadata != nil {
result.SyncRevisions = operationSyncRevisionsMetadata
}
// latest revision of repository where changes to app resource were actually made; empty if no changeRevisionі present
operationChangeRevisionsMetadata, err := s.getCommitRevisionsDetails(ctx, a, utils.GetOperationChangeRevisions(a))

if err == nil && operationChangeRevisionsMetadata != nil {
result.ChangeRevisions = operationChangeRevisionsMetadata
if err != nil {
logCtx.WithError(err).Warnf("failed to get application(%s) change revisions metadata, resuming", a.GetName())
}

if err == nil && operationChangeRevisionsMetadata != nil {
result.ChangeRevisions = operationChangeRevisionsMetadata
}
}

return result, nil
Expand Down
32 changes: 16 additions & 16 deletions event_reporter/reporter/application_event_reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,13 @@ func (s *applicationEventReporter) StreamApplicationEvents(

// helm app hasnt revision
// TODO: add check if it helm application
parentOperationRevision := utils.GetOperationRevision(parentApplicationEntity)
parentRevisionMetadata, err := s.getApplicationRevisionDetails(ctx, parentApplicationEntity, parentOperationRevision)
parentAppSyncRevisionsMetadata, err := s.getApplicationRevisionsMetadata(ctx, logCtx, parentApplicationEntity)
if err != nil {
logCtx.WithError(err).Warn("failed to get parent application's revision metadata, resuming")
}

utils.SetHealthStatusIfMissing(rs)
err = s.processResource(ctx, *rs, parentApplicationEntity, logCtx, ts, parentDesiredManifests, appTree, manifestGenErr, a, parentRevisionMetadata, appInstanceLabelKey, trackingMethod, desiredManifests.ApplicationVersions)
err = s.processResource(ctx, *rs, parentApplicationEntity, logCtx, ts, parentDesiredManifests, appTree, manifestGenErr, a, parentAppSyncRevisionsMetadata, appInstanceLabelKey, trackingMethod, desiredManifests.ApplicationVersions)
if err != nil {
s.metricsServer.IncErroredEventsCounter(metrics.MetricChildAppEventType, metrics.MetricEventUnknownErrorType, a.Name)
return err
Expand Down Expand Up @@ -203,7 +202,7 @@ func (s *applicationEventReporter) StreamApplicationEvents(
s.metricsServer.ObserveEventProcessingDurationHistogramDuration(a.Name, metrics.MetricParentAppEventType, reconcileDuration)
}

revisionMetadata, _ := s.getApplicationRevisionDetails(ctx, a, utils.GetOperationRevision(a))
revisionsMetadata, _ := s.getApplicationRevisionsMetadata(ctx, logCtx, a)
// for each resource in the application get desired and actual state,
// then stream the event
for _, rs := range a.Status.Resources {
Expand All @@ -215,7 +214,7 @@ func (s *applicationEventReporter) StreamApplicationEvents(
s.metricsServer.IncCachedIgnoredEventsCounter(metrics.MetricResourceEventType, a.Name)
continue
}
err := s.processResource(ctx, rs, a, logCtx, ts, desiredManifests, appTree, manifestGenErr, nil, revisionMetadata, appInstanceLabelKey, trackingMethod, nil)
err := s.processResource(ctx, rs, a, logCtx, ts, desiredManifests, appTree, manifestGenErr, nil, revisionsMetadata, appInstanceLabelKey, trackingMethod, nil)
if err != nil {
s.metricsServer.IncErroredEventsCounter(metrics.MetricResourceEventType, metrics.MetricEventUnknownErrorType, a.Name)
return err
Expand All @@ -227,21 +226,22 @@ func (s *applicationEventReporter) StreamApplicationEvents(
func (s *applicationEventReporter) getAppForResourceReporting(
rs appv1.ResourceStatus,
ctx context.Context,
logCtx *log.Entry,
a *appv1.Application,
revisionMetadata *appv1.RevisionMetadata,
) (*appv1.Application, *appv1.RevisionMetadata) {
syncRevisionsMetadata *utils.AppSyncRevisionsMetadata,
) (*appv1.Application, *utils.AppSyncRevisionsMetadata) {
if rs.Kind != "Rollout" { // for rollout it's crucial to report always correct operationSyncRevision
return a, revisionMetadata
return a, syncRevisionsMetadata
}

latestAppStatus, err := s.appLister.Applications(a.Namespace).Get(a.Name)
if err != nil {
return a, revisionMetadata
return a, syncRevisionsMetadata
}

revisionMetadataToReport, err := s.getApplicationRevisionDetails(ctx, latestAppStatus, utils.GetOperationRevision(latestAppStatus))
revisionMetadataToReport, err := s.getApplicationRevisionsMetadata(ctx, logCtx, latestAppStatus)
if err != nil {
return a, revisionMetadata
return a, syncRevisionsMetadata
}

return latestAppStatus, revisionMetadataToReport
Expand All @@ -257,7 +257,7 @@ func (s *applicationEventReporter) processResource(
appTree *appv1.ApplicationTree,
manifestGenErr bool,
originalApplication *appv1.Application,
revisionMetadata *appv1.RevisionMetadata,
revisionsMetadata *utils.AppSyncRevisionsMetadata,
appInstanceLabelKey string,
trackingMethod appv1.TrackingMethod,
applicationVersions *apiclient.ApplicationVersions,
Expand All @@ -283,12 +283,12 @@ func (s *applicationEventReporter) processResource(
return nil
}

parentApplicationToReport, revisionMetadataToReport := s.getAppForResourceReporting(rs, ctx, parentApplication, revisionMetadata)
parentApplicationToReport, revisionMetadataToReport := s.getAppForResourceReporting(rs, ctx, logCtx, parentApplication, revisionsMetadata)

var originalAppRevisionMetadata *appv1.RevisionMetadata = nil
var originalAppRevisionMetadata *utils.AppSyncRevisionsMetadata = nil

if originalApplication != nil {
originalAppRevisionMetadata, _ = s.getApplicationRevisionDetails(ctx, originalApplication, utils.GetOperationRevision(originalApplication))
originalAppRevisionMetadata, _ = s.getApplicationRevisionsMetadata(ctx, logCtx, originalApplication)
}

ev, err := getResourceEventPayload(parentApplicationToReport, &rs, actualState, desiredState, appTree, manifestGenErr, ts, originalApplication, revisionMetadataToReport, originalAppRevisionMetadata, appInstanceLabelKey, trackingMethod, applicationVersions)
Expand All @@ -305,7 +305,7 @@ func (s *applicationEventReporter) processResource(
appName = appRes.Name
} else {
utils.LogWithResourceStatus(logCtx, rs).Info("streaming resource event")
appName = rs.Name
appName = parentApplication.Name
}

if err := s.codefreshClient.SendEvent(ctx, appName, ev); err != nil {
Expand Down
50 changes: 24 additions & 26 deletions event_reporter/reporter/event_payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ func getResourceEventPayload(
manifestGenErr bool,
ts string,
originalApplication *appv1.Application, // passed when rs is application
revisionMetadata *appv1.RevisionMetadata,
originalAppRevisionMetadata *appv1.RevisionMetadata, // passed when rs is application
revisionsMetadata *utils.AppSyncRevisionsMetadata,
originalAppRevisionMetadata *utils.AppSyncRevisionsMetadata, // passed when rs is application
appInstanceLabelKey string,
trackingMethod appv1.TrackingMethod,
applicationVersions *apiclient.ApplicationVersions,
Expand All @@ -54,7 +54,7 @@ func getResourceEventPayload(
actualObject, err := appv1.UnmarshalToUnstructured(*actualState.Manifest)

if err == nil {
actualObject = utils.AddCommitDetailsToLabels(actualObject, originalAppRevisionMetadata)
actualObject = utils.AddCommitsDetailsToAnnotations(actualObject, originalAppRevisionMetadata)
object, err = actualObject.MarshalJSON()
if err != nil {
return nil, fmt.Errorf("failed to marshal unstructured object: %w", err)
Expand All @@ -75,7 +75,7 @@ func getResourceEventPayload(
u.SetName(rs.Name)
u.SetNamespace(rs.Namespace)
if originalAppRevisionMetadata != nil {
u = utils.AddCommitDetailsToLabels(u, originalAppRevisionMetadata)
u = utils.AddCommitsDetailsToAnnotations(u, originalAppRevisionMetadata)
}

object, err = u.MarshalJSON()
Expand All @@ -89,7 +89,7 @@ func getResourceEventPayload(
return nil, fmt.Errorf("failed to add destination namespace to manifest: %w", err)
}
if originalAppRevisionMetadata != nil {
unstructuredWithNamespace = utils.AddCommitDetailsToLabels(unstructuredWithNamespace, originalAppRevisionMetadata)
unstructuredWithNamespace = utils.AddCommitsDetailsToAnnotations(unstructuredWithNamespace, originalAppRevisionMetadata)
}

object, _ = unstructuredWithNamespace.MarshalJSON()
Expand Down Expand Up @@ -166,10 +166,17 @@ func getResourceEventPayload(
TrackingMethod: string(trackingMethod),
}

if revisionMetadata != nil {
source.CommitMessage = revisionMetadata.Message
source.CommitAuthor = revisionMetadata.Author
source.CommitDate = &revisionMetadata.Date
if revisionsMetadata != nil && revisionsMetadata.SyncRevisions != nil {
_, sourceIdx := parentApplication.Spec.GetNonRefSource()
if sourceIdx == -1 { // single source app
sourceIdx = 0
}
revisionMetadata := revisionsMetadata.SyncRevisions[sourceIdx]
if revisionMetadata != nil {
source.CommitMessage = revisionMetadata.Message
source.CommitAuthor = revisionMetadata.Author
source.CommitDate = &revisionMetadata.Date
}
}

if rs.Health != nil {
Expand Down Expand Up @@ -225,27 +232,18 @@ func (s *applicationEventReporter) getApplicationEventPayload(
syncFinished = a.Status.OperationState.FinishedAt
}

applicationSource := a.Spec.GetSource()
if !applicationSource.IsHelm() && (a.Status.Sync.Revision != "" || (a.Status.History != nil && len(a.Status.History) > 0)) {
revisionMetadata, err := s.getApplicationRevisionDetails(ctx, a, utils.GetOperationRevision(a))

if err != nil {
if !strings.Contains(err.Error(), "not found") {
return nil, fmt.Errorf("failed to get revision metadata: %w", err)
}

logCtx.Warnf("failed to get revision metadata: %s, reporting application deletion event", err.Error())
} else {
if obj.ObjectMeta.Labels == nil {
obj.ObjectMeta.Labels = map[string]string{}
}
revisionsMetadata, err := s.getApplicationRevisionsMetadata(ctx, logCtx, a)

obj.ObjectMeta.Labels["app.meta.commit-date"] = revisionMetadata.Date.Format("2006-01-02T15:04:05.000Z")
obj.ObjectMeta.Labels["app.meta.commit-author"] = revisionMetadata.Author
obj.ObjectMeta.Labels["app.meta.commit-message"] = revisionMetadata.Message
if err != nil {
if !strings.Contains(err.Error(), "not found") {
return nil, fmt.Errorf("failed to get revision metadata: %w", err)
}

logCtx.Warnf("failed to get revision metadata: %s, reporting application deletion event", err.Error())
}

utils.AddCommitsDetailsToAppAnnotations(obj, revisionsMetadata)

object, err := json.Marshal(&obj)
if err != nil {
return nil, fmt.Errorf("failed to marshal application event")
Expand Down
24 changes: 23 additions & 1 deletion event_reporter/utils/app_revision.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ func AddCommitDetailsToLabels(u *unstructured.Unstructured, revisionMetadata *ap
return u
}

var annotationRevisionKey = "app.meta.revisions-metadata"

func AddCommitsDetailsToAnnotations(unstrApp *unstructured.Unstructured, revisionsMetadata *AppSyncRevisionsMetadata) *unstructured.Unstructured {
if revisionsMetadata == nil || unstrApp == nil {
return unstrApp
Expand All @@ -142,7 +144,27 @@ func AddCommitsDetailsToAnnotations(unstrApp *unstructured.Unstructured, revisio
return unstrApp
}

_ = unstructured.SetNestedField(unstrApp.Object, jsonRevisionsMetadata, "metadata", "annotations", "app.meta.revisions-metadata")
_ = unstructured.SetNestedField(unstrApp.Object, string(jsonRevisionsMetadata), "metadata", "annotations", annotationRevisionKey)

return unstrApp
}

func AddCommitsDetailsToAppAnnotations(app appv1.Application, revisionsMetadata *AppSyncRevisionsMetadata) appv1.Application {
if revisionsMetadata == nil {
return app
}

if app.ObjectMeta.Annotations == nil {
app.ObjectMeta.Labels = map[string]string{}
}

jsonRevisionsMetadata, err := json.Marshal(revisionsMetadata)

if err != nil {
return app
}

app.ObjectMeta.Annotations[annotationRevisionKey] = string(jsonRevisionsMetadata)

return app
}
16 changes: 16 additions & 0 deletions pkg/apis/application/v1alpha1/types_codefresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,19 @@ func (a *Application) SetDefaultTypeMeta() {
APIVersion: SchemeGroupVersion.String(),
}
}

func (a *ApplicationSpec) GetNonRefSource() (*ApplicationSource, int) {
if a.HasMultipleSources() {
for idx, source := range a.Sources {
if !source.IsRef() {
return &source, idx
}
}
}

if a.Source != nil { // single source app
return a.Source, -1
}

return nil, -2
}

0 comments on commit 1113941

Please sign in to comment.