Skip to content

Commit

Permalink
Merge pull request #34475 from Baachi/feature/ecr-pull-through-creden…
Browse files Browse the repository at this point in the history
…tials

Implement credential_arn for ecr pull cache through rules
  • Loading branch information
ewbankkit authored Feb 14, 2024
2 parents 46a7e24 + 5e16562 commit aa44dc4
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 77 deletions.
7 changes: 7 additions & 0 deletions .changelog/34475.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_ecr_pull_through_cache_rule: Add `credential_arn` argument
```

```release-note:enhancement
data-source/aws_ecr_pull_through_cache_rule: Add `credential_arn` attribute
```
11 changes: 11 additions & 0 deletions internal/service/ecr/exports_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package ecr

// Exports for use in tests only.
var (
ResourcePullThroughCacheRule = resourcePullThroughCacheRule

FindPullThroughCacheRuleByRepositoryPrefix = findPullThroughCacheRuleByRepositoryPrefix
)
43 changes: 0 additions & 43 deletions internal/service/ecr/find.go

This file was deleted.

71 changes: 63 additions & 8 deletions internal/service/ecr/pull_through_cache_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,33 @@ import (
"github.com/aws/aws-sdk-go/service/ecr"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)

// @SDKResource("aws_ecr_pull_through_cache_rule")
func ResourcePullThroughCacheRule() *schema.Resource {
// @SDKResource("aws_ecr_pull_through_cache_rule", name="Pull Through Cache Rule")
func resourcePullThroughCacheRule() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourcePullThroughCacheRuleCreate,
ReadWithoutTimeout: resourcePullThroughCacheRuleRead,
DeleteWithoutTimeout: resourcePullThroughCacheRuleDelete,
UpdateWithoutTimeout: resourcePullThroughCacheRuleUpdate,

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

Schema: map[string]*schema.Schema{
"credential_arn": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: verify.ValidARN,
},
"ecr_repository_prefix": {
Type: schema.TypeString,
Required: true,
Expand All @@ -57,7 +65,6 @@ func ResourcePullThroughCacheRule() *schema.Resource {

func resourcePullThroughCacheRuleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { // nosemgrep:ci.ecr-in-func-name
var diags diag.Diagnostics

conn := meta.(*conns.AWSClient).ECRConn(ctx)

repositoryPrefix := d.Get("ecr_repository_prefix").(string)
Expand All @@ -66,7 +73,10 @@ func resourcePullThroughCacheRuleCreate(ctx context.Context, d *schema.ResourceD
UpstreamRegistryUrl: aws.String(d.Get("upstream_registry_url").(string)),
}

log.Printf("[DEBUG] Creating ECR Pull Through Cache Rule: %s", input)
if v, ok := d.GetOk("credential_arn"); ok {
input.CredentialArn = aws.String(v.(string))
}

_, err := conn.CreatePullThroughCacheRuleWithContext(ctx, input)

if err != nil {
Expand All @@ -80,10 +90,9 @@ func resourcePullThroughCacheRuleCreate(ctx context.Context, d *schema.ResourceD

func resourcePullThroughCacheRuleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics

conn := meta.(*conns.AWSClient).ECRConn(ctx)

rule, err := FindPullThroughCacheRuleByRepositoryPrefix(ctx, conn, d.Id())
rule, err := findPullThroughCacheRuleByRepositoryPrefix(ctx, conn, d.Id())

if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] ECR Pull Through Cache Rule (%s) not found, removing from state", d.Id())
Expand All @@ -95,19 +104,40 @@ func resourcePullThroughCacheRuleRead(ctx context.Context, d *schema.ResourceDat
return sdkdiag.AppendErrorf(diags, "reading ECR Pull Through Cache Rule (%s): %s", d.Id(), err)
}

d.Set("credential_arn", rule.CredentialArn)
d.Set("ecr_repository_prefix", rule.EcrRepositoryPrefix)
d.Set("registry_id", rule.RegistryId)
d.Set("upstream_registry_url", rule.UpstreamRegistryUrl)

return diags
}

func resourcePullThroughCacheRuleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
func resourcePullThroughCacheRuleUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).ECRConn(ctx)

repositoryPrefix := d.Get("ecr_repository_prefix").(string)
input := &ecr.UpdatePullThroughCacheRuleInput{
CredentialArn: aws.String(d.Get("credential_arn").(string)),
EcrRepositoryPrefix: aws.String(repositoryPrefix),
}

_, err := conn.UpdatePullThroughCacheRuleWithContext(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating ECR Pull Through Cache Rule (%s): %s", repositoryPrefix, err)
}

d.SetId(repositoryPrefix)

return append(diags, resourcePullThroughCacheRuleRead(ctx, d, meta)...)
}

func resourcePullThroughCacheRuleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).ECRConn(ctx)

log.Printf("[DEBUG] Deleting ECR Pull Through Cache Rule: (%s)", d.Id())
log.Printf("[DEBUG] Deleting ECR Pull Through Cache Rule: %s", d.Id())
_, err := conn.DeletePullThroughCacheRuleWithContext(ctx, &ecr.DeletePullThroughCacheRuleInput{
EcrRepositoryPrefix: aws.String(d.Id()),
RegistryId: aws.String(d.Get("registry_id").(string)),
Expand All @@ -123,3 +153,28 @@ func resourcePullThroughCacheRuleDelete(ctx context.Context, d *schema.ResourceD

return diags
}

func findPullThroughCacheRuleByRepositoryPrefix(ctx context.Context, conn *ecr.ECR, repositoryPrefix string) (*ecr.PullThroughCacheRule, error) {
input := &ecr.DescribePullThroughCacheRulesInput{
EcrRepositoryPrefixes: aws.StringSlice([]string{repositoryPrefix}),
}

output, err := conn.DescribePullThroughCacheRulesWithContext(ctx, input)

if tfawserr.ErrCodeEquals(err, ecr.ErrCodePullThroughCacheRuleNotFoundException) {
return nil, &retry.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

if output == nil {
return nil, tfresource.NewEmptyResultError(input)
}

return tfresource.AssertSinglePtrResult(output.PullThroughCacheRules)
}
14 changes: 9 additions & 5 deletions internal/service/ecr/pull_through_cache_rule_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ import (
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
)

// @SDKDataSource("aws_ecr_pull_through_cache_rule")
func DataSourcePullThroughCacheRule() *schema.Resource {
// @SDKDataSource("aws_ecr_pull_through_cache_rule", name="Pull Through Cache Rule")
func dataSourcePullThroughCacheRule() *schema.Resource {
return &schema.Resource{
ReadWithoutTimeout: dataSourcePullThroughCacheRuleRead,

Schema: map[string]*schema.Schema{
"credential_arn": {
Type: schema.TypeString,
Computed: true,
},
"ecr_repository_prefix": {
Type: schema.TypeString,
Required: true,
Expand All @@ -45,18 +50,17 @@ func DataSourcePullThroughCacheRule() *schema.Resource {

func dataSourcePullThroughCacheRuleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics

conn := meta.(*conns.AWSClient).ECRConn(ctx)

repositoryPrefix := d.Get("ecr_repository_prefix").(string)

rule, err := FindPullThroughCacheRuleByRepositoryPrefix(ctx, conn, repositoryPrefix)
rule, err := findPullThroughCacheRuleByRepositoryPrefix(ctx, conn, repositoryPrefix)

if err != nil {
return sdkdiag.AppendErrorf(diags, "reading ECR Pull Through Cache Rule (%s): %s", repositoryPrefix, err)
}

d.SetId(aws.StringValue(rule.EcrRepositoryPrefix))
d.Set("credential_arn", rule.CredentialArn)
d.Set("ecr_repository_prefix", rule.EcrRepositoryPrefix)
d.Set("registry_id", rule.RegistryId)
d.Set("upstream_registry_url", rule.UpstreamRegistryUrl)
Expand Down
52 changes: 49 additions & 3 deletions internal/service/ecr/pull_through_cache_rule_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ func TestAccECRPullThroughCacheRuleDataSource_basic(t *testing.T) {
Steps: []resource.TestStep{
{
Config: testAccPullThroughCacheRuleDataSourceConfig_basic(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSource, "upstream_registry_url", "public.ecr.aws"),
Check: resource.ComposeAggregateTestCheckFunc(
acctest.CheckResourceAttrAccountID(dataSource, "registry_id"),
resource.TestCheckResourceAttr(dataSource, "upstream_registry_url", "public.ecr.aws"),
),
},
},
Expand All @@ -46,9 +46,31 @@ func TestAccECRPullThroughCacheRuleDataSource_repositoryPrefixWithSlash(t *testi
Steps: []resource.TestStep{
{
Config: testAccPullThroughCacheRuleDataSourceConfig_repositoryPrefixWithSlash(repositoryPrefix),
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
acctest.CheckResourceAttrAccountID(dataSource, "registry_id"),
resource.TestCheckResourceAttr(dataSource, "upstream_registry_url", "public.ecr.aws"),
),
},
},
})
}

func TestAccECRPullThroughCacheRuleDataSource_credential(t *testing.T) {
ctx := acctest.Context(t)
repositoryPrefix := "tf-test-" + sdkacctest.RandString(8)
dataSource := "data.aws_ecr_pull_through_cache_rule.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, ecr.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccPullThroughCacheRuleDataSourceConfig_credentialARN(repositoryPrefix),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(dataSource, "credential_arn"),
acctest.CheckResourceAttrAccountID(dataSource, "registry_id"),
resource.TestCheckResourceAttr(dataSource, "upstream_registry_url", "registry-1.docker.io"),
),
},
},
Expand Down Expand Up @@ -80,3 +102,27 @@ data "aws_ecr_pull_through_cache_rule" "test" {
}
`, repositoryPrefix)
}

func testAccPullThroughCacheRuleDataSourceConfig_credentialARN(repositoryPrefix string) string {
return fmt.Sprintf(`
resource "aws_secretsmanager_secret" "test" {
name = "ecr-pullthroughcache/%[1]s"
recovery_window_in_days = 0
}
resource "aws_secretsmanager_secret_version" "test" {
secret_id = aws_secretsmanager_secret.test.id
secret_string = "test"
}
resource "aws_ecr_pull_through_cache_rule" "test" {
ecr_repository_prefix = %[1]q
upstream_registry_url = "registry-1.docker.io"
credential_arn = aws_secretsmanager_secret.test.arn
}
data "aws_ecr_pull_through_cache_rule" "test" {
ecr_repository_prefix = aws_ecr_pull_through_cache_rule.test.ecr_repository_prefix
}
`, repositoryPrefix)
}
Loading

0 comments on commit aa44dc4

Please sign in to comment.