diff options
| author | jannfis <jann@mistrust.net> | 2020-09-27 14:24:30 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-27 14:24:30 +0200 |
| commit | 330fa57fd51331b911901d5a31b6956cb080ba0e (patch) | |
| tree | 4251a3459449b8f1444147c7ed91344297089719 | |
| parent | 02d580fc6805963e89632fbad3782cf5bfa1e80e (diff) | |
feat: Allow ignoring set of tags (#101)
* feat: Allow ignoring set of tags
* Fix a typo in symbol name
* Rename symbol
* err must be nil; also print trace message
* Update documentation
* Update documentation
* String is already trimmed
| -rw-r--r-- | docs/configuration/images.md | 25 | ||||
| -rw-r--r-- | pkg/argocd/update.go | 1 | ||||
| -rw-r--r-- | pkg/common/constants.go | 5 | ||||
| -rw-r--r-- | pkg/image/options.go | 21 | ||||
| -rw-r--r-- | pkg/image/options_test.go | 15 | ||||
| -rw-r--r-- | pkg/image/version.go | 14 | ||||
| -rw-r--r-- | pkg/registry/registry.go | 4 |
7 files changed, 81 insertions, 4 deletions
diff --git a/docs/configuration/images.md b/docs/configuration/images.md index 6284d53..52212a7 100644 --- a/docs/configuration/images.md +++ b/docs/configuration/images.md @@ -144,6 +144,30 @@ to prevent considering (and possibly update to) the wrong tags by accident. If the annotation is not specified, a match function `any` will be used to match the tag names, effectively performing no filtering at all. +## Ignoring certain tags + +If you want to ignore certain tags from the registry for any given image, you +can define a comma separated list of glob-like patterns using the following +annotation: + +```yaml +argocd-image-updater.argoproj.io/<image_name>.ignore-tags: <pattern1>[, <pattern2>, ...] +``` + +You can use glob patterns as described in this +[documentation](https://golang.org/pkg/path/filepath/#Match) + +If you want to disable updating an image temporarily, without removing all of +the configuration, you can do so by just ignoring all tags, effectively +preventing the image updater to consider any of the tags returned from the +registry: + +```yaml +argocd-image-updater.argoproj.io/<image_name>.ignore-tags: "*" +``` + +Please note that regular expressions are not supported to be used for patterns. + ## Specifying pull secrets There are generally two ways on how to specify pull secrets for Argo CD Image @@ -318,6 +342,7 @@ must be prefixed with `argocd-image-updater.argoproj.io`. |`image-list`|*none*|Comma separated list of images to consider for update| |`<image_alias>.update-strategy`|`semver`|The update strategy to be used for the image| |`<image_alias>.tag-match`|*any*|A function to match tag names from registry against to be considered for update| +|`<image_alias>.ignore-tags`|*none*|A comma-separated list of glob patterns that when match ignore a certain tag from the registry| |`<image_alias>.pull-secret`|*none*|A reference to a secret to be used as registry credentials for this image| |`<image_alias>.helm.image-spec`|*none*|Name of the Helm parameter to specify the canonical name of the image, i.e. holds `image/name:1.0`. If this is set, other Helm parameter related options will be ignored.| |`<image_alias>.helm.image-name`|`image.name`|Name of the Helm parameter used for specifying the image name, i.e. holds `image/name`| diff --git a/pkg/argocd/update.go b/pkg/argocd/update.go index c52aa09..cf68011 100644 --- a/pkg/argocd/update.go +++ b/pkg/argocd/update.go @@ -75,6 +75,7 @@ func UpdateApplication(newRegFn registry.NewRegistryClient, argoClient ArgoCD, k vc.SortMode = applicationImage.GetParameterUpdateStrategy(curApplication.Application.Annotations) vc.MatchFunc, vc.MatchArgs = applicationImage.GetParameterMatch(curApplication.Application.Annotations) + vc.IgnoreList = applicationImage.GetParameterIgnoreTags(curApplication.Application.Annotations) // The endpoint can provide default credentials for pulling images err = rep.SetEndpointCredentials(kubeClient) diff --git a/pkg/common/constants.go b/pkg/common/constants.go index 76bf2bb..847fe39 100644 --- a/pkg/common/constants.go +++ b/pkg/common/constants.go @@ -28,8 +28,9 @@ const ( // Upgrade strategy related annotations const ( - MatchOptionAnnotation = ImageUpdaterAnnotationPrefix + "/%s.tag-match" - UpdateStrategyAnnotation = ImageUpdaterAnnotationPrefix + "/%s.update-strategy" + MatchOptionAnnotation = ImageUpdaterAnnotationPrefix + "/%s.tag-match" + IgnoreTagsOptionAnnotation = ImageUpdaterAnnotationPrefix + "/%s.ignore-tags" + UpdateStrategyAnnotation = ImageUpdaterAnnotationPrefix + "/%s.update-strategy" ) // Image pull secret related annotations diff --git a/pkg/image/options.go b/pkg/image/options.go index ea0515e..f777cf0 100644 --- a/pkg/image/options.go +++ b/pkg/image/options.go @@ -114,6 +114,7 @@ func (img *ContainerImage) GetParameterMatch(annotations map[string]string) (Mat } } +// GetParameterPullSecret retrieves an image's pull secret credentials func (img *ContainerImage) GetParameterPullSecret(annotations map[string]string) *CredentialSource { key := fmt.Sprintf(common.SecretListAnnotation, img.normalizedSymbolicName()) val, ok := annotations[key] @@ -129,6 +130,26 @@ func (img *ContainerImage) GetParameterPullSecret(annotations map[string]string) return credSrc } +// GetParameterIgnoreTags retrieves a list of tags to ignore from a comma-separated string +func (img *ContainerImage) GetParameterIgnoreTags(annotations map[string]string) []string { + key := fmt.Sprintf(common.IgnoreTagsOptionAnnotation, img.normalizedSymbolicName()) + val, ok := annotations[key] + if !ok { + log.Tracef("No ignore-tags annotation %s found", key) + return nil + } + ignoreList := make([]string, 0) + tags := strings.Split(strings.TrimSpace(val), ",") + for _, tag := range tags { + // We ignore empty tags + trimmed := strings.TrimSpace(tag) + if trimmed != "" { + ignoreList = append(ignoreList, trimmed) + } + } + return ignoreList +} + func (img *ContainerImage) normalizedSymbolicName() string { return strings.ReplaceAll(img.ImageAlias, "/", "_") } diff --git a/pkg/image/options_test.go b/pkg/image/options_test.go index 493c59c..182fc02 100644 --- a/pkg/image/options_test.go +++ b/pkg/image/options_test.go @@ -178,3 +178,18 @@ func Test_GetSecretOption(t *testing.T) { require.Nil(t, credSrc) }) } + +func Test_GetIgnoreTags(t *testing.T) { + t.Run("Get list of tags to ignore from annotation", func(t *testing.T) { + annotations := map[string]string{ + fmt.Sprintf(common.IgnoreTagsOptionAnnotation, "dummy"): "tag1, ,tag2, tag3 , tag4", + } + img := NewFromIdentifier("dummy=foo/bar:1.12") + tags := img.GetParameterIgnoreTags(annotations) + require.Len(t, tags, 4) + assert.Equal(t, "tag1", tags[0]) + assert.Equal(t, "tag2", tags[1]) + assert.Equal(t, "tag3", tags[2]) + assert.Equal(t, "tag4", tags[3]) + }) +} diff --git a/pkg/image/version.go b/pkg/image/version.go index 392d127..3abdc7d 100644 --- a/pkg/image/version.go +++ b/pkg/image/version.go @@ -1,6 +1,8 @@ package image import ( + "path/filepath" + "github.com/argoproj-labs/argocd-image-updater/pkg/log" "github.com/argoproj-labs/argocd-image-updater/pkg/tag" @@ -36,6 +38,7 @@ type VersionConstraint struct { Constraint string MatchFunc MatchFuncFn MatchArgs interface{} + IgnoreList []string SortMode VersionSortMode } @@ -123,3 +126,14 @@ func (img *ContainerImage) GetNewestVersionFromTags(vc *VersionConstraint, tagLi return img.ImageTag, nil } } + +// IsTagIgnored matches tag against the patterns in IgnoreList and returns true if one of them matches +func (vc *VersionConstraint) IsTagIgnored(tag string) bool { + for _, t := range vc.IgnoreList { + if match, err := filepath.Match(t, tag); err == nil && match { + log.Tracef("tag %s is ignored by pattern %s", tag, t) + return true + } + } + return false +} diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go index ffe895d..496e301 100644 --- a/pkg/registry/registry.go +++ b/pkg/registry/registry.go @@ -42,8 +42,8 @@ func (endpoint *RegistryEndpoint) GetTags(img *image.ContainerImage, regClient R // Loop through tags, removing those we do not want if vc.MatchFunc != nil { for _, t := range tTags { - if !vc.MatchFunc(t, vc.MatchArgs) { - log.Tracef("Removing tag %s because of tag match options", t) + if !vc.MatchFunc(t, vc.MatchArgs) || vc.IsTagIgnored(t) { + log.Tracef("Removing tag %s because it either didn't match defined pattern or is ignored", t) } else { tags = append(tags, t) } |
