summaryrefslogtreecommitdiff
path: root/registry-scanner/pkg/cache
diff options
context:
space:
mode:
authorIshita Sequeira <46771830+ishitasequeira@users.noreply.github.com>2024-11-13 08:57:55 -0500
committerGitHub <noreply@github.com>2024-11-13 08:57:55 -0500
commitcde58c56ff0981df884433eeea76d747f4b809de (patch)
tree6fb745e6995e3bc3fe87be90524a4d39ebe3531a /registry-scanner/pkg/cache
parent1d04e9aa3e237530336bc0693eaaa7f6de7b66e1 (diff)
refactor: Add registry pkg registry scanner (#933)
Signed-off-by: Ishita Sequeira <ishiseq29@gmail.com>
Diffstat (limited to 'registry-scanner/pkg/cache')
-rw-r--r--registry-scanner/pkg/cache/cache.go20
-rw-r--r--registry-scanner/pkg/cache/memcache.go74
-rw-r--r--registry-scanner/pkg/cache/memcache_test.go70
3 files changed, 164 insertions, 0 deletions
diff --git a/registry-scanner/pkg/cache/cache.go b/registry-scanner/pkg/cache/cache.go
new file mode 100644
index 0000000..1ceef66
--- /dev/null
+++ b/registry-scanner/pkg/cache/cache.go
@@ -0,0 +1,20 @@
+package cache
+
+import (
+ "github.com/argoproj-labs/argocd-image-updater/registry-scanner/pkg/tag"
+)
+
+type ImageTagCache interface {
+ HasTag(imageName string, imageTag string) bool
+ GetTag(imageName string, imageTag string) (*tag.ImageTag, error)
+ SetTag(imageName string, imgTag *tag.ImageTag)
+ ClearCache()
+ NumEntries() int
+}
+
+// KnownImage represents a known image and the applications using it, without
+// any version/tag information.
+type KnownImage struct {
+ ImageName string
+ // Applications []string
+}
diff --git a/registry-scanner/pkg/cache/memcache.go b/registry-scanner/pkg/cache/memcache.go
new file mode 100644
index 0000000..03b4080
--- /dev/null
+++ b/registry-scanner/pkg/cache/memcache.go
@@ -0,0 +1,74 @@
+package cache
+
+import (
+ "fmt"
+
+ "github.com/argoproj-labs/argocd-image-updater/registry-scanner/pkg/tag"
+
+ memcache "github.com/patrickmn/go-cache"
+)
+
+type MemCache struct {
+ cache *memcache.Cache
+}
+
+// NewMemCache returns a new instance of MemCache
+func NewMemCache() ImageTagCache {
+ mc := MemCache{}
+ c := memcache.New(0, 0)
+ mc.cache = c
+ return &mc
+}
+
+// HasTag returns true if cache has entry for given tag, false if not
+func (mc *MemCache) HasTag(imageName string, tagName string) bool {
+ tag, err := mc.GetTag(imageName, tagName)
+ if err != nil || tag == nil {
+ return false
+ } else {
+ return true
+ }
+}
+
+// SetTag sets a tag entry into the cache
+func (mc *MemCache) SetTag(imageName string, imgTag *tag.ImageTag) {
+ mc.cache.Set(tagCacheKey(imageName, imgTag.TagName), *imgTag, -1)
+}
+
+// GetTag gets a tag entry from the cache
+func (mc *MemCache) GetTag(imageName string, tagName string) (*tag.ImageTag, error) {
+ var imgTag tag.ImageTag
+ e, ok := mc.cache.Get(tagCacheKey(imageName, tagName))
+ if !ok {
+ return nil, nil
+ }
+ imgTag, ok = e.(tag.ImageTag)
+ if !ok {
+ return nil, fmt.Errorf("")
+ }
+ return &imgTag, nil
+}
+
+func (mc *MemCache) SetImage(imageName, application string) {
+ mc.cache.Set(imageCacheKey(imageName), application, -1)
+}
+
+// ClearCache clears the cache
+func (mc *MemCache) ClearCache() {
+ for k := range mc.cache.Items() {
+ mc.cache.Delete(k)
+ }
+}
+
+// NumEntries returns the number of entries in the cache
+func (mc *MemCache) NumEntries() int {
+ return mc.cache.ItemCount()
+}
+
+func tagCacheKey(imageName, imageTag string) string {
+ return fmt.Sprintf("tags:%s:%s", imageName, imageTag)
+}
+
+func imageCacheKey(imageName string) string {
+ return fmt.Sprintf("image:%s", imageName)
+}
diff --git a/registry-scanner/pkg/cache/memcache_test.go b/registry-scanner/pkg/cache/memcache_test.go
new file mode 100644
index 0000000..8fcb47b
--- /dev/null
+++ b/registry-scanner/pkg/cache/memcache_test.go
@@ -0,0 +1,70 @@
+package cache
+
+import (
+ "testing"
+ "time"
+
+ memcache "github.com/patrickmn/go-cache"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/argoproj-labs/argocd-image-updater/pkg/tag"
+)
+
+func Test_MemCache(t *testing.T) {
+ imageName := "foo/bar"
+ imageTag := "v1.0.0"
+ t.Run("Cache hit", func(t *testing.T) {
+ mc := NewMemCache()
+ newTag := tag.NewImageTag(imageTag, time.Unix(0, 0), "")
+ mc.SetTag(imageName, newTag)
+ cachedTag, err := mc.GetTag(imageName, imageTag)
+ require.NoError(t, err)
+ require.NotNil(t, cachedTag)
+ assert.Equal(t, imageTag, cachedTag.TagName)
+ assert.True(t, mc.HasTag(imageName, imageTag))
+ assert.Equal(t, 1, mc.NumEntries())
+ })
+
+ t.Run("Cache miss", func(t *testing.T) {
+ mc := NewMemCache()
+ newTag := tag.NewImageTag(imageTag, time.Unix(0, 0), "")
+ mc.SetTag(imageName, newTag)
+ assert.Equal(t, 1, mc.NumEntries())
+ cachedTag, err := mc.GetTag(imageName, "v1.0.1")
+ require.NoError(t, err)
+ require.Nil(t, cachedTag)
+ assert.False(t, mc.HasTag(imageName, "v1.0.1"))
+ })
+
+ t.Run("Cache clear", func(t *testing.T) {
+ mc := NewMemCache()
+ newTag := tag.NewImageTag(imageTag, time.Unix(0, 0), "")
+ mc.SetTag(imageName, newTag)
+ cachedTag, err := mc.GetTag(imageName, imageTag)
+ require.NoError(t, err)
+ require.NotNil(t, cachedTag)
+ assert.Equal(t, imageTag, cachedTag.TagName)
+ assert.True(t, mc.HasTag(imageName, imageTag))
+ assert.Equal(t, 1, mc.NumEntries())
+ mc.ClearCache()
+ assert.Equal(t, 0, mc.NumEntries())
+ cachedTag, err = mc.GetTag(imageName, imageTag)
+ require.NoError(t, err)
+ require.Nil(t, cachedTag)
+ })
+ t.Run("Image Cache Key", func(t *testing.T) {
+ mc := MemCache{
+ cache: memcache.New(0, 0),
+ }
+ application := "application1"
+ key := imageCacheKey(imageName)
+ mc.SetImage(imageName, application)
+ app, b := mc.cache.Get(key)
+ assert.True(t, b)
+ assert.Equal(t, application, app)
+ assert.Equal(t, 1, mc.NumEntries())
+ mc.ClearCache()
+ assert.Equal(t, 0, mc.NumEntries())
+ })
+}