From 8b13249f5a85ac6c0c3276c1de5ca4e2dfdcbd57 Mon Sep 17 00:00:00 2001 From: Cyril MARIN Date: Fri, 8 Dec 2023 13:14:58 +0100 Subject: [PATCH 1/2] fix: filter images by image-list annotation Signed-off-by: Cyril MARIN --- Dockerfile | 8 +-- pkg/argocd/argocd.go | 21 ++++++-- pkg/argocd/argocd_test.go | 3 ++ pkg/argocd/update_test.go | 104 ++++++++++++++++++++++++++------------ 4 files changed, 93 insertions(+), 43 deletions(-) diff --git a/Dockerfile b/Dockerfile index c374bae7..a11d76df 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,13 +14,9 @@ FROM alpine:latest RUN apk update && \ apk upgrade && \ - apk add ca-certificates git openssh-client python3 py3-pip tini && \ - pip3 install --upgrade pip && \ - pip3 install awscli && \ - rm -rf /var/cache/apk/* + apk add --no-cache aws-cli ca-certificates git openssh-client tini -RUN mkdir -p /usr/local/bin -RUN mkdir -p /app/config +RUN mkdir -p /usr/local/bin /app/config RUN adduser --home "/app" --disabled-password --uid 1000 argocd COPY --from=builder /src/argocd-image-updater/dist/argocd-image-updater /usr/local/bin/ diff --git a/pkg/argocd/argocd.go b/pkg/argocd/argocd.go index 4584dbe0..e43398b2 100644 --- a/pkg/argocd/argocd.go +++ b/pkg/argocd/argocd.go @@ -481,19 +481,32 @@ func SetKustomizeImage(app *v1alpha1.Application, newImage *image.ContainerImage return nil } +// ImageIsAllowed checks whether img is declared in image-list annotation +func ImageIsAllowed(img *image.ContainerImage, list *image.ContainerImageList) bool { + for _, i := range *list { + if i.ImageName == img.ImageName { + return true + } + } + return false +} + // GetImagesFromApplication returns the list of known images for the given application func GetImagesFromApplication(app *v1alpha1.Application) image.ContainerImageList { images := make(image.ContainerImageList, 0) + annotations := app.Annotations + imagesFromAnnotations := parseImageList(annotations) for _, imageStr := range app.Status.Summary.Images { - image := image.NewFromIdentifier(imageStr) - images = append(images, image) + img := image.NewFromIdentifier(imageStr) + if ImageIsAllowed(img, imagesFromAnnotations) { + images = append(images, img) + } } // The Application may wish to update images that don't create a container we can detect. // Check the image list for images with a force-update annotation, and add them if they are not already present. - annotations := app.Annotations - for _, img := range *parseImageList(annotations) { + for _, img := range *imagesFromAnnotations { if img.HasForceUpdateOptionAnnotation(annotations) { img.ImageTag = nil // the tag from the image list will be a version constraint, which isn't a valid tag images = append(images, img) diff --git a/pkg/argocd/argocd_test.go b/pkg/argocd/argocd_test.go index 95553570..bfedb126 100644 --- a/pkg/argocd/argocd_test.go +++ b/pkg/argocd/argocd_test.go @@ -27,6 +27,9 @@ func Test_GetImagesFromApplication(t *testing.T) { ObjectMeta: v1.ObjectMeta{ Name: "test-app", Namespace: "argocd", + Annotations: map[string]string{ + common.ImageUpdaterAnnotation: "nginx:1.12.2,that/image,quay.io/dexidp/dex:v1.23.0", + }, }, Spec: v1alpha1.ApplicationSpec{}, Status: v1alpha1.ApplicationStatus{ diff --git a/pkg/argocd/update_test.go b/pkg/argocd/update_test.go index 1d1246fa..0197aa23 100644 --- a/pkg/argocd/update_test.go +++ b/pkg/argocd/update_test.go @@ -109,11 +109,15 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "jannfis/foobar:1.0.0", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -167,11 +171,15 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "jannfis/foobar:1.0.0,jannfis/barbar:1.0.0", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -354,11 +362,15 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "jannfis/foobar:1.0.x", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -412,14 +424,16 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeClientsetWithResources(fixture.NewSecret("foo", "bar", map[string][]byte{"creds": []byte("myuser:mypass")})), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "jannfis/foobar:1.0.0", + fmt.Sprintf(common.PullSecretAnnotation, "dummy"): "secret:foo/bar#creds", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", - Annotations: map[string]string{ - fmt.Sprintf(common.PullSecretAnnotation, "dummy"): "secret:foo/bar#creds", - }, + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -526,11 +540,15 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "jannfis/foobar:1.0.1", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -716,15 +734,17 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "dummy=jannfis/foobar", + fmt.Sprintf(common.AllowTagsOptionAnnotation, "dummy"): "regexp:^foobar$", + fmt.Sprintf(common.UpdateStrategyAnnotation, "dummy"): "name", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", - Annotations: map[string]string{ - fmt.Sprintf(common.AllowTagsOptionAnnotation, "dummy"): "regexp:^foobar$", - fmt.Sprintf(common.UpdateStrategyAnnotation, "dummy"): "name", - }, + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -792,15 +812,17 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "dummy=jannfis/foobar", + fmt.Sprintf(common.IgnoreTagsOptionAnnotation, "dummy"): "*", + fmt.Sprintf(common.UpdateStrategyAnnotation, "dummy"): "name", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", - Annotations: map[string]string{ - fmt.Sprintf(common.IgnoreTagsOptionAnnotation, "dummy"): "*", - fmt.Sprintf(common.UpdateStrategyAnnotation, "dummy"): "name", - }, + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -852,11 +874,15 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "example.io/jannfis/example:1.0.x", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -905,11 +931,15 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "jannfis/foobar:1.0.0", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -961,11 +991,15 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "jannfis/foobar:1.0.0", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ @@ -1017,11 +1051,15 @@ func Test_UpdateApplication(t *testing.T) { kubeClient := kube.KubernetesClient{ Clientset: fake.NewFakeKubeClient(), } + annotations := map[string]string{ + common.ImageUpdaterAnnotation: "jannfis/foobar:stable", + } appImages := &ApplicationImages{ Application: v1alpha1.Application{ ObjectMeta: v1.ObjectMeta{ - Name: "guestbook", - Namespace: "guestbook", + Name: "guestbook", + Namespace: "guestbook", + Annotations: annotations, }, Spec: v1alpha1.ApplicationSpec{ Source: &v1alpha1.ApplicationSource{ From 77a5fc876360c86c5208a145226b4ea3d839afb0 Mon Sep 17 00:00:00 2001 From: pasha-codefresh Date: Sat, 25 May 2024 11:39:45 +0300 Subject: [PATCH 2/2] Update Dockerfile --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5a1f63eb..df43be20 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,8 @@ RUN apk update && \ apk add ca-certificates git openssh-client aws-cli tini && \ rm -rf /var/cache/apk/* -RUN mkdir -p /usr/local/bin /app/config +RUN mkdir -p /usr/local/bin +RUN mkdir -p /app/config RUN adduser --home "/app" --disabled-password --uid 1000 argocd COPY --from=builder /src/argocd-image-updater/dist/argocd-image-updater /usr/local/bin/