Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,9 @@ start-local: mod-vendor-local dep-ui-local cli-local
run:
bash ./hack/goreman-start.sh

.PHONY: cf-release
cf-release:
go run ./hack/release

# Runs pre-commit validation with the virtualized toolchain
.PHONY: pre-commit
Expand Down
6 changes: 2 additions & 4 deletions acr_controller/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ type ACRController interface {
type applicationChangeRevisionController struct {
appBroadcaster Broadcaster
acrService service.ACRService
useAnnotations bool
}

func NewApplicationChangeRevisionController(appInformer cache.SharedIndexInformer, applicationServiceClient appclient.ApplicationClient, applicationClientset appclientset.Interface, useAnnotations bool) ACRController {
func NewApplicationChangeRevisionController(appInformer cache.SharedIndexInformer, applicationServiceClient appclient.ApplicationClient, applicationClientset appclientset.Interface) ACRController {
appBroadcaster := NewBroadcaster()
_, err := appInformer.AddEventHandler(appBroadcaster)
if err != nil {
Expand All @@ -36,7 +35,6 @@ func NewApplicationChangeRevisionController(appInformer cache.SharedIndexInforme
return &applicationChangeRevisionController{
appBroadcaster: appBroadcaster,
acrService: service.NewACRService(applicationClientset, applicationServiceClient),
useAnnotations: useAnnotations,
}
}

Expand All @@ -48,7 +46,7 @@ func (c *applicationChangeRevisionController) Run(ctx context.Context) {
return nil // ignore this event
}

return c.acrService.ChangeRevision(ctx, &a, c.useAnnotations)
return c.acrService.ChangeRevision(ctx, &a)
}

// TODO: move to abstraction
Expand Down
2 changes: 1 addition & 1 deletion acr_controller/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (a *ACRServer) Init(ctx context.Context) {
}

func (a *ACRServer) RunController(ctx context.Context) {
controller := acr_controller.NewApplicationChangeRevisionController(a.appInformer, a.ApplicationServiceClient, a.applicationClientset, !a.DisableAnnotations)
controller := acr_controller.NewApplicationChangeRevisionController(a.appInformer, a.ApplicationServiceClient, a.applicationClientset)
go controller.Run(ctx)
}

Expand Down
131 changes: 34 additions & 97 deletions acr_controller/service/acr_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package service
import (
"context"
"encoding/json"
"fmt"
"sync"

log "github.com/sirupsen/logrus"
Expand All @@ -25,7 +24,7 @@ const (
)

type ACRService interface {
ChangeRevision(ctx context.Context, application *application.Application, useAnnotations bool) error
ChangeRevision(ctx context.Context, application *application.Application) error
}

type acrService struct {
Expand Down Expand Up @@ -63,7 +62,7 @@ func getChangeRevision(app *application.Application) string {
return ""
}

func (c *acrService) ChangeRevision(ctx context.Context, a *application.Application, useAnnotations bool) error {
func (c *acrService) ChangeRevision(ctx context.Context, a *application.Application) error {
c.lock.Lock()
defer c.lock.Unlock()

Expand All @@ -81,108 +80,36 @@ func (c *acrService) ChangeRevision(ctx context.Context, a *application.Applicat
return nil
}

currentRevision, previousRevision := c.getRevisions(ctx, a)
if currentRevision == "" {
c.logger.Infof("Got empty current revision for application %s, is it an unsupported multisource or helm repo based application?", app.Name)
return nil
}
revision, err := c.calculateRevision(ctx, app, currentRevision, previousRevision)
revision, err := c.calculateRevision(ctx, app)
if err != nil {
return err
}

var revisions []string
if revision == nil || *revision == "" {
c.logger.Infof("Revision for application %s is empty", app.Name)
} else {
c.logger.Infof("Change revision for application %s is %s", app.Name, *revision)
revisions = []string{*revision}
return nil
}

c.logger.Infof("Change revision for application %s is %s", app.Name, *revision)

app, err = c.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(ctx, app.Name, metav1.GetOptions{})
if err != nil {
return err
}

patchMap := make(map[string]any, 2)

if len(revisions) > 0 {
if app.Status.OperationState != nil && app.Status.OperationState.Operation.Sync != nil {
c.logger.Infof("Patch operation status for application %s", app.Name)
patchMap = c.patchOperationSyncResultWithChangeRevision(revisions)
} else {
c.logger.Infof("Patch operation for application %s", app.Name)
patchMap = c.patchOperationWithChangeRevision(revisions)
}
}
if useAnnotations {
err = c.addAnnotationPatch(patchMap, app, *revision, revisions, currentRevision, []string{currentRevision})
if err != nil {
return err
}
}
if len(patchMap) > 0 {
c.logger.Infof("Patching resource: %v", patchMap)
patch, err := json.Marshal(patchMap)
if err != nil {
return err
}
_, err = c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Patch(ctx, a.Name, types.MergePatchType, patch, metav1.PatchOptions{})
return err
}
c.logger.Infof("No patch needed")
return nil
}

func addPatchIfNeeded(annotations map[string]string, currentAnnotations map[string]string, key string, val string) {
currentVal, ok := currentAnnotations[key]
if !ok || currentVal != val {
annotations[key] = val
}
}

func (c *acrService) addAnnotationPatch(m map[string]any,
a *application.Application,
changeRevision string,
changeRevisions []string,
gitRevision string,
gitRevisions []string,
) error {
c.logger.Infof("annotating application '%s', changeRevision=%s, changeRevisions=%v, gitRevision=%s, gitRevisions=%v", a.Name, changeRevision, changeRevisions, gitRevision, gitRevisions)
annotations := map[string]string{}
currentAnnotations := a.Annotations
revisions := []string{*revision}

if changeRevision != "" {
addPatchIfNeeded(annotations, currentAnnotations, CHANGE_REVISION_ANN, changeRevision)
}
if len(changeRevisions) > 0 {
changeRevisionsJSON, err := json.Marshal(changeRevisions)
if err != nil {
return fmt.Errorf("failed to marshall changeRevisions %v: %w", changeRevisions, err)
}
addPatchIfNeeded(annotations, currentAnnotations, CHANGE_REVISIONS_ANN, string(changeRevisionsJSON))
}
if gitRevision != "" {
addPatchIfNeeded(annotations, currentAnnotations, GIT_REVISION_ANN, gitRevision)
}
if len(gitRevisions) > 0 {
gitRevisionsJSON, err := json.Marshal(gitRevisions)
if err != nil {
return fmt.Errorf("failed to marshall gitRevisions %v: %w", gitRevisions, err)
}
addPatchIfNeeded(annotations, currentAnnotations, GIT_REVISIONS_ANN, string(gitRevisionsJSON))
if app.Status.OperationState != nil && app.Status.OperationState.Operation.Sync != nil {
c.logger.Infof("Patch operation status for application %s", app.Name)
return c.patchOperationSyncResultWithChangeRevision(ctx, app, revisions)
}

if len(annotations) == 0 {
c.logger.Info("no need to add annotations")
} else {
c.logger.Infof("added annotations to application %s patch: %v", a.Name, annotations)
m["metadata"] = map[string]any{"annotations": annotations}
}
return nil
c.logger.Infof("Patch operation for application %s", app.Name)
return c.patchOperationWithChangeRevision(ctx, app, revisions)
}

func (c *acrService) calculateRevision(ctx context.Context, a *application.Application, currentRevision string, previousRevision string) (*string, error) {
func (c *acrService) calculateRevision(ctx context.Context, a *application.Application) (*string, error) {
currentRevision, previousRevision := c.getRevisions(ctx, a)
c.logger.Infof("Calculate revision for application '%s', current revision '%s', previous revision '%s'", a.Name, currentRevision, previousRevision)
changeRevisionResult, err := c.applicationServiceClient.GetChangeRevision(ctx, &appclient.ChangeRevisionRequest{
AppName: ptr.To(a.GetName()),
Expand All @@ -196,28 +123,33 @@ func (c *acrService) calculateRevision(ctx context.Context, a *application.Appli
return changeRevisionResult.Revision, nil
}

func (c *acrService) patchOperationWithChangeRevision(revisions []string) map[string]any {
func (c *acrService) patchOperationWithChangeRevision(ctx context.Context, a *application.Application, revisions []string) error {
if len(revisions) == 1 {
return map[string]any{
patch, _ := json.Marshal(map[string]any{
"operation": map[string]any{
"sync": map[string]any{
"changeRevision": revisions[0],
},
},
}
})
_, err := c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Patch(ctx, a.Name, types.MergePatchType, patch, metav1.PatchOptions{})
return err
}
return map[string]any{

patch, _ := json.Marshal(map[string]any{
"operation": map[string]any{
"sync": map[string]any{
"changeRevisions": revisions,
},
},
}
})
_, err := c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Patch(ctx, a.Name, types.MergePatchType, patch, metav1.PatchOptions{})
return err
}

func (c *acrService) patchOperationSyncResultWithChangeRevision(revisions []string) map[string]any {
func (c *acrService) patchOperationSyncResultWithChangeRevision(ctx context.Context, a *application.Application, revisions []string) error {
if len(revisions) == 1 {
return map[string]any{
patch, _ := json.Marshal(map[string]any{
"status": map[string]any{
"operationState": map[string]any{
"operation": map[string]any{
Expand All @@ -227,9 +159,12 @@ func (c *acrService) patchOperationSyncResultWithChangeRevision(revisions []stri
},
},
},
}
})
_, err := c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Patch(ctx, a.Name, types.MergePatchType, patch, metav1.PatchOptions{})
return err
}
return map[string]any{

patch, _ := json.Marshal(map[string]any{
"status": map[string]any{
"operationState": map[string]any{
"operation": map[string]any{
Expand All @@ -239,7 +174,9 @@ func (c *acrService) patchOperationSyncResultWithChangeRevision(revisions []stri
},
},
},
}
})
_, err := c.applicationClientset.ArgoprojV1alpha1().Applications(a.Namespace).Patch(ctx, a.Name, types.MergePatchType, patch, metav1.PatchOptions{})
return err
}

func getCurrentRevisionFromOperation(a *application.Application) string {
Expand Down
Loading