summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjannfis <jann@mistrust.net>2020-08-19 09:41:14 +0200
committerGitHub <noreply@github.com>2020-08-19 09:41:14 +0200
commite848d6f558d87e2150767be87f4cf0cb18a28954 (patch)
tree7d3921b9d7ff6b843057cd0a935189157d7accbd
parent1fb6cbab5e5c3bb8dfee71f3cb48caa2e802d751 (diff)
feat: Allow filtering by application name (#66)
* feat: Allow filtering by application name * include allowed word otherapp
-rw-r--r--.github/actions/spelling/expect.txt1
-rw-r--r--cmd/main.go4
-rw-r--r--pkg/argocd/argocd.go29
-rw-r--r--pkg/argocd/argocd_test.go58
4 files changed, 88 insertions, 4 deletions
diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt
index edee088..3f8c49a 100644
--- a/.github/actions/spelling/expect.txt
+++ b/.github/actions/spelling/expect.txt
@@ -1,3 +1,4 @@
wohoo
myuser
mypass
+otherapp
diff --git a/cmd/main.go b/cmd/main.go
index b0d2ab9..ff951c4 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -41,6 +41,7 @@ type ImageUpdaterConfig struct {
MaxConcurrency int
HealthPort int
RegistriesConf string
+ AppNamePatterns []string
}
// Main loop for argocd-image-controller
@@ -66,7 +67,7 @@ func runImageUpdater(cfg *ImageUpdaterConfig) (argocd.ImageUpdaterResult, error)
// Get the list of applications that are allowed for updates, that is, those
// applications which have correct annotation.
- appList, err := argocd.FilterApplicationsForUpdate(apps)
+ appList, err := argocd.FilterApplicationsForUpdate(apps, cfg.AppNamePatterns)
if err != nil {
return result, err
}
@@ -305,6 +306,7 @@ func newRunCommand() *cobra.Command {
runCmd.Flags().BoolVar(&disableKubernetes, "disable-kubernetes", false, "do not create and use a Kubernetes client")
runCmd.Flags().IntVar(&cfg.MaxConcurrency, "max-concurrency", 10, "maximum number of update threads to run concurrently")
runCmd.Flags().StringVar(&cfg.ArgocdNamespace, "argocd-namespace", "argocd", "namespace where ArgoCD runs in")
+ runCmd.Flags().StringSliceVar(&cfg.AppNamePatterns, "match-application-name", nil, "patterns to match application name against")
return runCmd
}
diff --git a/pkg/argocd/argocd.go b/pkg/argocd/argocd.go
index 159c7ca..1696123 100644
--- a/pkg/argocd/argocd.go
+++ b/pkg/argocd/argocd.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"os"
+ "path/filepath"
"strings"
"github.com/argoproj-labs/argocd-image-updater/pkg/common"
@@ -81,17 +82,43 @@ type ApplicationImages struct {
// update.
type ImageList map[string]ApplicationImages
+// Match a name against a list of patterns
+func nameMatchesPattern(name string, patterns []string) bool {
+ if len(patterns) == 0 {
+ return true
+ }
+ for _, p := range patterns {
+ log.Tracef("Matching application name %s against pattern %s", name, p)
+ if m, err := filepath.Match(p, name); err != nil {
+ log.Warnf("Invalid application name pattern '%s': %v", p, err)
+ } else if m {
+ return true
+ }
+ }
+ return false
+}
+
// Retrieve a list of applications from ArgoCD that qualify for image updates
// Application needs either to be of type Kustomize or Helm and must have the
// correct annotation in order to be considered.
-func FilterApplicationsForUpdate(apps []v1alpha1.Application) (map[string]ApplicationImages, error) {
+func FilterApplicationsForUpdate(apps []v1alpha1.Application, patterns []string) (map[string]ApplicationImages, error) {
var appsForUpdate = make(map[string]ApplicationImages)
for _, app := range apps {
+
+ // Check for valid application type
if !IsValidApplicationType(&app) {
log.Tracef("skipping app '%s' of type '%s' because it's not of supported source type", app.GetName(), app.Status.SourceType)
continue
}
+
+ // Check if application name matches requested patterns
+ if !nameMatchesPattern(app.GetName(), patterns) {
+ log.Tracef("Skipping app '%s' because it does not match requested patterns", app.GetName())
+ continue
+ }
+
+ // Check whether application has our annotation set
annotations := app.GetAnnotations()
if updateImage, ok := annotations[common.ImageUpdaterAnnotation]; !ok {
log.Tracef("skipping app '%s' of type '%s' because required annotation is missing", app.GetName(), app.Status.SourceType)
diff --git a/pkg/argocd/argocd_test.go b/pkg/argocd/argocd_test.go
index 05d3979..fb562c9 100644
--- a/pkg/argocd/argocd_test.go
+++ b/pkg/argocd/argocd_test.go
@@ -113,7 +113,7 @@ func Test_GetApplicationType(t *testing.T) {
}
func Test_FilterApplicationsForUpdate(t *testing.T) {
- t.Run("Filter for applications", func(t *testing.T) {
+ t.Run("Filter for applications without patterns", func(t *testing.T) {
applicationList := []v1alpha1.Application{
// Annotated and correct type
{
@@ -155,12 +155,66 @@ func Test_FilterApplicationsForUpdate(t *testing.T) {
},
},
}
- filtered, err := FilterApplicationsForUpdate(applicationList)
+ filtered, err := FilterApplicationsForUpdate(applicationList, []string{})
require.NoError(t, err)
require.Len(t, filtered, 1)
require.Contains(t, filtered, "app1")
assert.Len(t, filtered["app1"].Images, 2)
})
+
+ t.Run("Filter for applications with patterns", func(t *testing.T) {
+ applicationList := []v1alpha1.Application{
+ // Annotated and correct type
+ {
+ ObjectMeta: v1.ObjectMeta{
+ Name: "app1",
+ Namespace: "argocd",
+ Annotations: map[string]string{
+ common.ImageUpdaterAnnotation: "nginx, quay.io/dexidp/dex:v1.23.0",
+ },
+ },
+ Spec: v1alpha1.ApplicationSpec{},
+ Status: v1alpha1.ApplicationStatus{
+ SourceType: v1alpha1.ApplicationSourceTypeKustomize,
+ },
+ },
+ // Annotated, but invalid type
+ {
+ ObjectMeta: v1.ObjectMeta{
+ Name: "app2",
+ Namespace: "argocd",
+ Annotations: map[string]string{
+ common.ImageUpdaterAnnotation: "nginx, quay.io/dexidp/dex:v1.23.0",
+ },
+ },
+ Spec: v1alpha1.ApplicationSpec{},
+ Status: v1alpha1.ApplicationStatus{
+ SourceType: v1alpha1.ApplicationSourceTypeKustomize,
+ },
+ },
+ // Valid type, but not annotated
+ {
+ ObjectMeta: v1.ObjectMeta{
+ Name: "otherapp3",
+ Namespace: "argocd",
+ Annotations: map[string]string{
+ common.ImageUpdaterAnnotation: "nginx, quay.io/dexidp/dex:v1.23.0",
+ },
+ },
+ Spec: v1alpha1.ApplicationSpec{},
+ Status: v1alpha1.ApplicationStatus{
+ SourceType: v1alpha1.ApplicationSourceTypeHelm,
+ },
+ },
+ }
+ filtered, err := FilterApplicationsForUpdate(applicationList, []string{"app*"})
+ require.NoError(t, err)
+ require.Len(t, filtered, 2)
+ require.Contains(t, filtered, "app1")
+ require.Contains(t, filtered, "app2")
+ assert.Len(t, filtered["app1"].Images, 2)
+ })
+
}
func Test_GetHelmParamAnnotations(t *testing.T) {