From 2d91e1e804f5bdfc5034949a7f9d852e10af67ef Mon Sep 17 00:00:00 2001 From: dvan Date: Mon, 16 Dec 2024 11:50:17 -0500 Subject: [PATCH 1/3] add ability to set ecr tag mutability if repo creation is true --- cmd/drone-ecr/main.go | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/cmd/drone-ecr/main.go b/cmd/drone-ecr/main.go index ae268299..4fdde46b 100644 --- a/cmd/drone-ecr/main.go +++ b/cmd/drone-ecr/main.go @@ -42,6 +42,7 @@ func main() { assumeRole = getenv("PLUGIN_ASSUME_ROLE") externalId = getenv("PLUGIN_EXTERNAL_ID") scanOnPush = parseBoolOrDefault(false, getenv("PLUGIN_SCAN_ON_PUSH")) + tagImmutable = parseBoolOrDefault(false, getenv("PLUGIN_TAG_IMMUTABLE")) idToken = os.Getenv("PLUGIN_OIDC_TOKEN_ID") ) @@ -78,7 +79,7 @@ func main() { } if create { - err = ensureRepoExists(svc, trimHostname(repo, registry), scanOnPush) + err = ensureRepoExists(svc, trimHostname(repo, registry), scanOnPush, getTagImmutableString(tagImmutable)) if err != nil { log.Fatal(fmt.Sprintf("error creating ECR repo: %v", err)) } @@ -86,6 +87,10 @@ func main() { if err != nil { log.Fatal(fmt.Sprintf("error updating scan on push for ECR repo: %v", err)) } + err = updateImageTagMutabilityConfig(svc, trimHostname(repo, registry), getTagImmutableString(tagImmutable)) + if err != nil { + log.Fatal(fmt.Sprintf("error updating tag mutability for ECR repo: %v", err)) + } } if lifecyclePolicy != "" { @@ -129,10 +134,11 @@ func trimHostname(repo, registry string) string { return repo } -func ensureRepoExists(svc *ecr.ECR, name string, scanOnPush bool) (err error) { +func ensureRepoExists(svc *ecr.ECR, name string, scanOnPush bool, tagMutabilityOption string) (err error) { input := &ecr.CreateRepositoryInput{} input.SetRepositoryName(name) input.SetImageScanningConfiguration(&ecr.ImageScanningConfiguration{ScanOnPush: &scanOnPush}) + input.SetImageTagMutability(tagMutabilityOption) _, err = svc.CreateRepository(input) if err != nil { if aerr, ok := err.(awserr.Error); ok && aerr.Code() == ecr.ErrCodeRepositoryAlreadyExistsException { @@ -153,6 +159,15 @@ func updateImageScannningConfig(svc *ecr.ECR, name string, scanOnPush bool) (err return err } +func updateImageTagMutabilityConfig(svc *ecr.ECR, name string, tagMutabilityOption string) (err error) { + input := &ecr.PutImageTagMutabilityInput{} + input.SetRepositoryName(name) + input.SetImageTagMutability(tagMutabilityOption) + _, err = svc.PutImageTagMutability(input) + + return err +} + func uploadLifeCyclePolicy(svc *ecr.ECR, lifecyclePolicy string, name string) (err error) { input := &ecr.PutLifecyclePolicyInput{} input.SetLifecyclePolicyText(lifecyclePolicy) @@ -204,6 +219,14 @@ func parseBoolOrDefault(defaultValue bool, s string) (result bool) { return } +func getTagImmutableString(tagImmutable bool) string { + immutableTagInput := ecr.ImageTagMutabilityMutable + if tagImmutable { + immutableTagInput = ecr.ImageTagMutabilityImmutable + } + return immutableTagInput +} + func getenv(key ...string) (s string) { for _, k := range key { s = os.Getenv(k) From 6ba07f42e4a10dff26cb31b7c73be2ad2dd9e69b Mon Sep 17 00:00:00 2001 From: dvan Date: Mon, 16 Dec 2024 12:08:45 -0500 Subject: [PATCH 2/3] add tests to ensure mutable/immutable strings are correct --- cmd/drone-ecr/main_test.go | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/cmd/drone-ecr/main_test.go b/cmd/drone-ecr/main_test.go index 5c50ba55..9eea1382 100644 --- a/cmd/drone-ecr/main_test.go +++ b/cmd/drone-ecr/main_test.go @@ -1,6 +1,10 @@ package main -import "testing" +import ( + "testing" + + "github.com/aws/aws-sdk-go/service/ecr" +) func TestTrimHostname(t *testing.T) { registry := "000000000000.dkr.ecr.us-east-1.amazonaws.com" @@ -18,3 +22,31 @@ func TestTrimHostname(t *testing.T) { } } } + +func TestGetTagImmutableString(t *testing.T) { + testCases := []struct { + name string + tagImmutable bool + expected string + }{ + { + name: "mutable", + tagImmutable: false, + expected: ecr.ImageTagMutabilityMutable, + }, + { + name: "immutable", + tagImmutable: true, + expected: ecr.ImageTagMutabilityImmutable, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual := getTagImmutableString(tc.tagImmutable) + if actual != tc.expected { + t.Errorf("expected: %s, actual: %s", tc.expected, actual) + } + }) + } +} From 9db244bc3d0bac0978a939effd28ce111e7519cf Mon Sep 17 00:00:00 2001 From: dvan Date: Mon, 16 Dec 2024 12:10:10 -0500 Subject: [PATCH 3/3] Better naming --- cmd/drone-ecr/main.go | 6 +++--- cmd/drone-ecr/main_test.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/drone-ecr/main.go b/cmd/drone-ecr/main.go index 4fdde46b..956f1f55 100644 --- a/cmd/drone-ecr/main.go +++ b/cmd/drone-ecr/main.go @@ -79,7 +79,7 @@ func main() { } if create { - err = ensureRepoExists(svc, trimHostname(repo, registry), scanOnPush, getTagImmutableString(tagImmutable)) + err = ensureRepoExists(svc, trimHostname(repo, registry), scanOnPush, getTagMutabilityString(tagImmutable)) if err != nil { log.Fatal(fmt.Sprintf("error creating ECR repo: %v", err)) } @@ -87,7 +87,7 @@ func main() { if err != nil { log.Fatal(fmt.Sprintf("error updating scan on push for ECR repo: %v", err)) } - err = updateImageTagMutabilityConfig(svc, trimHostname(repo, registry), getTagImmutableString(tagImmutable)) + err = updateImageTagMutabilityConfig(svc, trimHostname(repo, registry), getTagMutabilityString(tagImmutable)) if err != nil { log.Fatal(fmt.Sprintf("error updating tag mutability for ECR repo: %v", err)) } @@ -219,7 +219,7 @@ func parseBoolOrDefault(defaultValue bool, s string) (result bool) { return } -func getTagImmutableString(tagImmutable bool) string { +func getTagMutabilityString(tagImmutable bool) string { immutableTagInput := ecr.ImageTagMutabilityMutable if tagImmutable { immutableTagInput = ecr.ImageTagMutabilityImmutable diff --git a/cmd/drone-ecr/main_test.go b/cmd/drone-ecr/main_test.go index 9eea1382..6cd19af2 100644 --- a/cmd/drone-ecr/main_test.go +++ b/cmd/drone-ecr/main_test.go @@ -23,7 +23,7 @@ func TestTrimHostname(t *testing.T) { } } -func TestGetTagImmutableString(t *testing.T) { +func TestGetTagMutabilityString(t *testing.T) { testCases := []struct { name string tagImmutable bool @@ -43,7 +43,7 @@ func TestGetTagImmutableString(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - actual := getTagImmutableString(tc.tagImmutable) + actual := getTagMutabilityString(tc.tagImmutable) if actual != tc.expected { t.Errorf("expected: %s, actual: %s", tc.expected, actual) }