Skip to content

Commit

Permalink
Merge pull request #4 from martijnvdp/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
martijnvdp authored Feb 28, 2023
2 parents ea1197d + 1e20225 commit 97b02bc
Show file tree
Hide file tree
Showing 14 changed files with 304 additions and 261 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[![goreleaser](https://github.com/martijnvdp/lambda-ecr-image-sync/actions/workflows/go.yml/badge.svg)](https://github.com/martijnvdp/lambda-ecr-image-sync/actions/workflows/go.yml)
# ecr-image-sync
# Lambda-ecr-image-sync

This is a Golang Lambda function that compares images between ECR and public repositories such as DockerHub, Quay.io, and GCR.io. It has the capability to sync the images directly to the target ECR on AWS or output a zipped CSV file with the missing images/tags to an S3 bucket. Another script can then pick up the CSV file to sync the missing images.

Expand Down Expand Up @@ -41,8 +40,9 @@ Lambda event data:

```hcl
{
"ecr_repo_prefix":"base/images" \\optional global_ecr_repo_prefix
"images": [
"ecr_repo_prefix":"base/images" // optional global_ecr_repo_prefix
"repository_arn":"arn:aws:ecr:us-east-1:123456789012:repository/base/infra/datadog/datadog-operator" //optional to sync a single repository
"images": [ // optional images payload to sync
{
"constraint": "~>2.0"
"exclude_rls": ["beta","rc"] \\ excluded pre-releases matches the text after eg: 1.1-beta beta
Expand Down
20 changes: 10 additions & 10 deletions pkg/lambda/check_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,27 @@ func comparePreReleases(v *version.Version, releases *[]string) bool {
return false
}

func (i *InputImage) checkExcConstraints(v *version.Version, c *version.Constraints) bool {
func (i *inputImage) checkExcConstraints(v *version.Version, c *version.Constraints) bool {
return comparePreReleases(v, &i.ExcludeRLS)
}

func (i *InputImage) checkExcTags(t string) bool {
func (i *inputImage) checkExcTags(t string) bool {
return compareIncExclTags(&t, &i.ExcludeTags)
}

func (i *InputImage) checkFilter() bool {
func (i *inputImage) checkFilter() bool {
return len(i.IncludeTags) == 0 && len(i.ExcludeTags) == 0 && !(len(i.IncludeRLS) > 0) && !(len(i.ExcludeRLS) > 0) && i.Constraint == ""
}

func (i *InputImage) checkIncConstraints(v *version.Version, c *version.Constraints) bool {
func (i *inputImage) checkIncConstraints(v *version.Version, c *version.Constraints) bool {
return comparePreReleases(v, &i.IncludeRLS)
}

func (i *InputImage) checkIncTags(t string) bool {
func (i *inputImage) checkIncTags(t string) bool {
return compareIncExclTags(&t, &i.IncludeTags)
}

func (i *InputImage) checkNonVersionTags(tag string) bool {
func (i *inputImage) checkNonVersionTags(tag string) bool {
switch {
case len(i.IncludeTags) > 0 && i.checkIncTags(tag):
return true
Expand All @@ -75,7 +75,7 @@ func (i *InputImage) checkNonVersionTags(tag string) bool {
return false
}

func (i *InputImage) checkVersionTags(v *version.Version, c *version.Constraints) bool {
func (i *inputImage) checkVersionTags(v *version.Version, c *version.Constraints) bool {
switch {
case len(i.IncludeTags) > 0 && i.checkIncTags(v.Original()):
return true
Expand All @@ -92,14 +92,14 @@ func (i *InputImage) checkVersionTags(v *version.Version, c *version.Constraints
return false
}

func (i *InputImage) createConstraint() (constraints version.Constraints, err error) {
func (i *inputImage) createConstraint() (constraints version.Constraints, err error) {
if i.Constraint != "" {
return version.NewConstraint(i.Constraint)
}
return version.NewConstraint(noConstraint)
}

func (i *InputImage) maxResults(globalMaxResults int) (maxResults int) {
func (i *inputImage) maxResults(globalMaxResults int) (maxResults int) {
maxResults = maxInt(globalMaxResults, i.MaxResults)

if !(maxResults > 0) {
Expand Down Expand Up @@ -146,7 +146,7 @@ func sortVersions(rawTags *[]string) (sortedTags []*version.Version, err error)
return sortedTags, err
}

func (i *InputImage) checkTagsFromPublicRepo(inputTags *[]string, maxResults int) (result []string, err error) {
func (i *inputImage) checkTagsFromPublicRepo(inputTags *[]string, maxResults int) (result []string, err error) {
maxResults = i.maxResults(maxResults)
noFilter := i.checkFilter()
versionTags, nonVersionTags := parseVersions(inputTags)
Expand Down
62 changes: 31 additions & 31 deletions pkg/lambda/check_tags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import (
"testing"
)

func Test_InputImage_maxResults(t *testing.T) {
func Test_inputImage_maxResults(t *testing.T) {
type args struct {
globalMaxResults int
}
tests := []struct {
name string
i *InputImage
i *inputImage
args args
wantMaxResults int
}{
Expand All @@ -20,20 +20,20 @@ func Test_InputImage_maxResults(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotMaxResults := tt.i.maxResults(tt.args.globalMaxResults); gotMaxResults != tt.wantMaxResults {
t.Errorf("InputImage.maxResults() = %v, want %v", gotMaxResults, tt.wantMaxResults)
t.Errorf("inputImage.maxResults() = %v, want %v", gotMaxResults, tt.wantMaxResults)
}
})
}
}

func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
func Test_inputImage_checkTagsFromPublicRepo(t *testing.T) {
type args struct {
inputTags []string
maxResults int
}
tests := []struct {
name string
i *InputImage
i *inputImage
args args
wantResult []string
wantErr bool
Expand All @@ -43,7 +43,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"7.32.1-rc.3-jmx", "7.32.1-rc.3-server_core", "7.32.1-servercore-jmx", "7.32.1-servercore", "latest", "latest-jmx", "latest-py2", "latest-py2-jmx", "latest-servercore", "latest-servercore-jmx", "7.3.x-exemplars"},
},
i: &InputImage{
i: &inputImage{
Constraint: ">= 7.30.0",
IncludeRLS: []string{"jmx"},
ExcludeRLS: []string{"rc"},
Expand All @@ -56,7 +56,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"latest-py2", "latest-py2-jmx", "7.3.x-exemplars"},
},
i: &InputImage{},
i: &inputImage{},
wantResult: []string{"latest-py2", "latest-py2-jmx"},
wantErr: false,
},
Expand All @@ -65,7 +65,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"9.3.6", "9.3.4", "7.3.x-exemplars", "7.4.x-exemplars", "7.5.x-exemplars"},
},
i: &InputImage{},
i: &inputImage{},
wantResult: []string{"9.3.6", "9.3.4"},
wantErr: false,
},
Expand All @@ -74,7 +74,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"v0.0.3", "current", "v0.0.6", "latest", "v0.0.7"},
},
i: &InputImage{
i: &inputImage{
ExcludeTags: []string{"v0.0.3", "v0.0.6"},
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
},
Expand All @@ -86,7 +86,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"v0.0.3", "current", "v0.0.6", "latest", "v0.0.7"},
},
i: &InputImage{
i: &inputImage{
IncludeTags: []string{"latest", "current"},
Constraint: ">= v0.0.6",
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
Expand All @@ -99,7 +99,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"v0.0.3", "current", "v0.0.6", "latest", "v0.0.7"},
},
i: &InputImage{
i: &inputImage{
IncludeTags: []string{"latest", "current"},
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
},
Expand All @@ -111,7 +111,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"v0.0.3", "current", "v0.0.6", "latest", "v0.0.7"},
},
i: &InputImage{
i: &inputImage{
IncludeTags: []string{"v0.0.6", "v0.0.7"},
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
},
Expand All @@ -123,7 +123,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"latest", "v0.0.3", "v0.0.4-debian-r20", "v0.0.5-beta", "v0.0.6-win", "v0.0.7", "v0.0.8-debian", "v0.0.9", "v0.1.0", "v0.1.1"},
},
i: &InputImage{
i: &inputImage{
IncludeRLS: []string{"debian", "win"},
Constraint: "< v0.0.8",
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
Expand All @@ -136,7 +136,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"latest", "v0.0.3", "v0.0.4", "v0.0.5-beta", "v0.0.6", "v0.0.7", "v0.0.8-rc", "v0.0.9", "v0.1.0", "v0.1.1"},
},
i: &InputImage{
i: &inputImage{
IncludeTags: []string{"v0.0.4", "v0.1.1"},
Constraint: "< v0.0.9",
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
Expand All @@ -149,7 +149,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"latest", "v0.0.3", "v0.0.4", "v0.0.5-beta", "v0.0.6", "v0.0.7", "v0.0.8", "v0.0.9", "v0.1.0", "v0.1.1", "v0.1.6-rc"},
},
i: &InputImage{
i: &inputImage{
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
IncludeRLS: []string{"rc"},
MaxResults: 6,
Expand All @@ -162,7 +162,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"latest", "v0.0.3", "v0.0.4", "v0.0.5", "v0.0.6", "v0.0.7", "v0.0.8", "v0.0.9", "v0.1.0", "v0.1.1"},
},
i: &InputImage{
i: &inputImage{
IncludeTags: []string{"v0.0.4", "v0.1.1"},
Constraint: "< v0.0.7",
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
Expand All @@ -176,7 +176,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
inputTags: []string{"latest", "v0.0.3", "v0.0.4", "v0.0.5", "v0.0.6", "v0.0.7", "v0.0.8", "v0.0.9", "v0.1.0", "v0.1.1"},
maxResults: 2,
},
i: &InputImage{
i: &inputImage{
Constraint: ">= v0.0.8, <= v0.0.9",
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
},
Expand All @@ -189,7 +189,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
inputTags: []string{"latest", "v0.0.3", "v0.0.4", "v0.0.7", "v0.0.8", "v0.0.9", "v0.1.0", "v0.1.1", "v0.0.5", "v0.0.6"},
maxResults: 7,
},
i: &InputImage{
i: &inputImage{
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
},
wantResult: []string{"latest", "v0.1.1", "v0.1.0", "v0.0.9", "v0.0.8", "v0.0.7", "v0.0.6"},
Expand All @@ -200,7 +200,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"latest", "0.3.0-debian-10-r32", "0.5.0-debian-10-r59", "0.9.0-debian-10-r32", "1.5.0-debian-12"},
},
i: &InputImage{
i: &inputImage{
IncludeRLS: []string{"debian", "test"},
Constraint: ">= v0.6.0",
ImageName: "docker.io/bitnami/metrics-server",
Expand All @@ -214,7 +214,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"latest", "v0.7.0", "0.3.0-debian-10-r32", "0.5.0-debian-10-r59", "0.9.0-debian-10-r32", "1.5.0-debian-12"},
},
i: &InputImage{
i: &inputImage{
IncludeRLS: []string{"debian", "test"},
Constraint: ">= v0.6.0",
ImageName: "docker.io/bitnami/metrics-server",
Expand All @@ -228,7 +228,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"latest", "0.3.0-debian-10-r32", "0.5.0-debian-10-r59", "0.9.0-debian-10-r32", "0.9.0-debian-10-beta", "1.5.0-debian-12", "1.5.0-debian-12-rc"},
},
i: &InputImage{
i: &inputImage{
IncludeRLS: []string{"debian", "test"},
ExcludeRLS: []string{"beta", "rc"},
Constraint: ">= v0.6.0",
Expand All @@ -243,7 +243,7 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
args: args{
inputTags: []string{"latest", "v1.4.1", "v1.4.5", "v1.4.6", "v1.4.7", "v1.4.8", "v1.4.9"},
},
i: &InputImage{
i: &inputImage{
ExcludeTags: []string{"v1.4.8", "v1.4.5"},
ImageName: "quay.io/cilium/cilium",
MaxResults: 6,
Expand All @@ -256,30 +256,30 @@ func Test_InputImage_checkTagsFromPublicRepo(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
gotResult, err := tt.i.checkTagsFromPublicRepo(&tt.args.inputTags, tt.args.maxResults)
if (err != nil) != tt.wantErr {
t.Errorf("InputImage.checkTagsFromPublicRepo() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("inputImage.checkTagsFromPublicRepo() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotResult, tt.wantResult) {
t.Errorf("InputImage.checkTagsFromPublicRepo() = %v, want %v", gotResult, tt.wantResult)
t.Errorf("inputImage.checkTagsFromPublicRepo() = %v, want %v", gotResult, tt.wantResult)
}
})
}
}

func Test_InputImage_checkTagsFromResultsPublicRepo(t *testing.T) {
func Test_inputImage_checkTagsFromResultsPublicRepo(t *testing.T) {
type args struct {
maxResults int
}
tests := []struct {
name string
i *InputImage
i *inputImage
args args
wantResult []string
wantErr bool
}{
{
name: "TestCheckTagLiveDataIncludetags2",
i: &InputImage{
i: &inputImage{
ImageName: "ghcr.io/martijnvdp/ecr-image-sync",
IncludeTags: []string{"v0.1.1", "v0.0.4"},
},
Expand All @@ -288,7 +288,7 @@ func Test_InputImage_checkTagsFromResultsPublicRepo(t *testing.T) {
},
{
name: "TestCheckTagLiveDataIncludetags",
i: &InputImage{
i: &inputImage{
ImageName: "docker.io/openpolicyagent/gatekeeper",
IncludeTags: []string{"v3.4.0", "v3.5.1"},
},
Expand All @@ -297,7 +297,7 @@ func Test_InputImage_checkTagsFromResultsPublicRepo(t *testing.T) {
},
{
name: "TestCheckTagLiveData",
i: &InputImage{
i: &inputImage{
ImageName: "docker.io/openpolicyagent/gatekeeper",
Constraint: ">= 3.5.0, < 3.7.0",
},
Expand All @@ -311,11 +311,11 @@ func Test_InputImage_checkTagsFromResultsPublicRepo(t *testing.T) {
if (err == nil) != tt.wantErr {
gotResult, err := tt.i.checkTagsFromPublicRepo(&inputTags, tt.args.maxResults)
if (err != nil) != tt.wantErr {
t.Errorf("InputImage.checkTagsFromPublicRepo() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("inputImage.checkTagsFromPublicRepo() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotResult, tt.wantResult) {
t.Errorf("InputImage.checkTagsFromPublicRepo() = %v, want %v", gotResult, tt.wantResult)
t.Errorf("inputImage.checkTagsFromPublicRepo() = %v, want %v", gotResult, tt.wantResult)
}
}
})
Expand Down
Loading

0 comments on commit 97b02bc

Please sign in to comment.