Skip to content

Commit

Permalink
feat(updater): add fire and forget mode (#309)
Browse files Browse the repository at this point in the history
  • Loading branch information
shini4i authored Jun 10, 2024
1 parent 71044ba commit 0350ee7
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
8 changes: 8 additions & 0 deletions cmd/argo-watcher/argocd/argo_status_updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ func (updater *ArgoStatusUpdater) WaitForRollout(task models.Task) {

// get application status
status := application.GetRolloutStatus(task.ListImages(), updater.registryProxyUrl, updater.acceptSuspended)
if application.IsFireAndForgetModeActive() {
status = models.ArgoRolloutAppSuccess
}
if status == models.ArgoRolloutAppSuccess {
log.Info().Str("id", task.Id).Msg("App is running on the expected version.")
// deployment success
Expand Down Expand Up @@ -213,6 +216,11 @@ func (updater *ArgoStatusUpdater) waitRollout(task models.Task) (*models.Applica
_ = retry.Do(func() error {
application, err = updater.argo.api.GetApplication(task.App)

if application.IsFireAndForgetModeActive() {
log.Debug().Str("id", task.Id).Msg("Fire and forge mode is active, skipping checks...")
return nil
}

if err != nil {
// check if ArgoCD didn't have the app
if task.IsAppNotFoundError(err) {
Expand Down
10 changes: 10 additions & 0 deletions docs/git-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ sandbox/charts/demo/.argocd-source-demo.yaml

> This is not an ideal solution, but so far it is the only way to reliably determine the correct override file to update.

### Fire and forget mode

In rare cases, we need to force update an application without waiting for image to be detected by ArgoCD as a running. For example for Applications with `CronJob` only.

The following annotation will force argo-watcher to just update the image, and consider application `deployed`:

```bash
argo-watcher/fire-and-forget: "true"
```

### Additional information

- The `app` alias is intended to correspond with an alias specified in the `argo-watcher/ALIAS.helm.image-tag` annotation.
Expand Down
9 changes: 9 additions & 0 deletions internal/models/argo.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const (
managedGitBranch = "argo-watcher/write-back-branch"
managedGitPath = "argo-watcher/write-back-path"
managedGitFile = "argo-watcher/write-back-filename"
fireAndForgetAnnotation = "argo-watcher/fire-and-forget"
)

type ApplicationOperationResource struct {
Expand Down Expand Up @@ -286,6 +287,14 @@ func (app *Application) UpdateGitImageTag(task *Task) error {
return nil
}

// IsFireAndForgetModeActive checks if 'fire-and-forget' mode is enabled in Application's annotations.
func (app *Application) IsFireAndForgetModeActive() bool {
if app.Metadata.Annotations == nil {
return false
}
return app.Metadata.Annotations[fireAndForgetAnnotation] == "true"
}

// extractManagedImages extracts the managed images from the application's annotations.
// It returns a map of the managed images, where the key is the application alias and the value is the image name.
func extractManagedImages(annotations map[string]string) (map[string]string, error) {
Expand Down
46 changes: 46 additions & 0 deletions internal/models/argo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,3 +386,49 @@ func TestExtractManagedImages(t *testing.T) {
})
}
}

func TestIsFireAndForgetModeActive(t *testing.T) {
tt := []struct {
name string
app Application
want bool
}{
{
name: "FireAndForget mode active",
app: Application{
Metadata: ApplicationMetadata{
Annotations: map[string]string{
fireAndForgetAnnotation: "true",
},
},
},
want: true,
},
{
name: "FireAndForget mode inactive",
app: Application{
Metadata: ApplicationMetadata{
Annotations: map[string]string{
fireAndForgetAnnotation: "false",
},
},
},
want: false,
},
{
name: "Annotations are nil",
app: Application{
Metadata: ApplicationMetadata{
Annotations: nil,
},
},
want: false,
},
}

for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.want, tc.app.IsFireAndForgetModeActive())
})
}
}

0 comments on commit 0350ee7

Please sign in to comment.