Skip to content

Commit

Permalink
f/aws_ecr_image - add image_tag_regex option
Browse files Browse the repository at this point in the history
  • Loading branch information
plentydone committed Aug 11, 2024
1 parent 7e5bba0 commit 7198b98
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .changelog/38783.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
datasource/aws_ecr_image: Add `image_tag_regex` option for use with `most_recent`
```
28 changes: 25 additions & 3 deletions internal/service/ecr/image_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ package ecr
import (
"context"
"fmt"
"regexp"
"slices"

"github.com/YakDriver/regexache"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ecr"
"github.com/aws/aws-sdk-go-v2/service/ecr/types"
Expand All @@ -18,6 +20,7 @@ import (
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/errs"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices"
"github.com/hashicorp/terraform-provider-aws/names"
)

Expand Down Expand Up @@ -57,6 +60,12 @@ func dataSourceImage() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"image_tag_regex": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringIsValidRegExp,
ConflictsWith: []string{"image_digest", "image_tag"},
},
names.AttrMostRecent: {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -109,7 +118,11 @@ func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, meta inter
input.RegistryId = aws.String(v.(string))
}

imageDetails, err := findImageDetails(ctx, conn, input)
var imageTagRegexp *regexp.Regexp = nil
if v, ok := d.GetOk("image_tag_regex"); ok {
imageTagRegexp = regexache.MustCompile(v.(string))
}
imageDetails, err := findImageDetails(ctx, conn, input, imageTagRegexp)

if err != nil {
return sdkdiag.AppendErrorf(diags, "reading ECR Images: %s", err)
Expand Down Expand Up @@ -161,7 +174,7 @@ func dataSourceImageRead(ctx context.Context, d *schema.ResourceData, meta inter
return diags
}

func findImageDetails(ctx context.Context, conn *ecr.Client, input *ecr.DescribeImagesInput) ([]types.ImageDetail, error) {
func findImageDetails(ctx context.Context, conn *ecr.Client, input *ecr.DescribeImagesInput, imageTagRegexp *regexp.Regexp) ([]types.ImageDetail, error) {
var output []types.ImageDetail

pages := ecr.NewDescribeImagesPaginator(conn, input)
Expand All @@ -179,7 +192,16 @@ func findImageDetails(ctx context.Context, conn *ecr.Client, input *ecr.Describe
return nil, err
}

output = append(output, page.ImageDetails...)
var imageDetails = page.ImageDetails
if imageTagRegexp != nil {
imageDetails = tfslices.Filter(page.ImageDetails, func(v types.ImageDetail) bool {
return tfslices.Any(v.ImageTags, func(t string) bool {
return imageTagRegexp.MatchString(t)
})
})
}

output = append(output, imageDetails...)
}

return output, nil
Expand Down
11 changes: 11 additions & 0 deletions internal/service/ecr/image_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestAccECRImageDataSource_basic(t *testing.T) {
resourceByTag := "data.aws_ecr_image.by_tag"
resourceByDigest := "data.aws_ecr_image.by_digest"
resourceByMostRecent := "data.aws_ecr_image.by_most_recent"
resourceByMostRecentWithRegex := "data.aws_ecr_image.by_most_recent_with_regex"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
Expand All @@ -38,6 +39,9 @@ func TestAccECRImageDataSource_basic(t *testing.T) {
resource.TestCheckResourceAttrSet(resourceByDigest, "image_uri"),
resource.TestCheckResourceAttrSet(resourceByMostRecent, "image_pushed_at"),
resource.TestCheckResourceAttrSet(resourceByMostRecent, "image_size_in_bytes"),
resource.TestCheckResourceAttrSet(resourceByMostRecentWithRegex, "image_pushed_at"),
resource.TestCheckResourceAttrSet(resourceByMostRecentWithRegex, "image_size_in_bytes"),
resource.TestCheckTypeSetElemAttr(resourceByMostRecentWithRegex, "image_tags.*", "2022"),
),
},
},
Expand All @@ -63,5 +67,12 @@ data "aws_ecr_image" "by_most_recent" {
repository_name = data.aws_ecr_image.by_tag.repository_name
most_recent = true
}
data "aws_ecr_image" "by_most_recent_with_regex" {
registry_id = data.aws_ecr_image.by_tag.registry_id
repository_name = data.aws_ecr_image.by_tag.repository_name
most_recent = true
image_tag_regex = "^2022.*"
}
`, reg, repo, tag)
}
2 changes: 1 addition & 1 deletion internal/service/ecr/repository_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func dataSourceRepositoryRead(ctx context.Context, d *schema.ResourceData, meta
imageDetails, err := findImageDetails(ctx, conn, &ecr.DescribeImagesInput{
RepositoryName: repository.RepositoryName,
RegistryId: repository.RegistryId,
})
}, nil)

if err != nil {
return sdkdiag.AppendErrorf(diags, "reading images for ECR Repository (%s): %s", d.Id(), err)
Expand Down
3 changes: 3 additions & 0 deletions website/docs/d/ecr_image.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ This data source supports the following arguments:
* `image_digest` - (Optional) Sha256 digest of the image manifest. At least one of `image_digest`, `image_tag`, or `most_recent` must be specified.
* `image_tag` - (Optional) Tag associated with this image. At least one of `image_digest`, `image_tag`, or `most_recent` must be specified.
* `most_recent` - (Optional) Return the most recently pushed image. At least one of `image_digest`, `image_tag`, or `most_recent` must be specified.
* `image_tag_regex` - (Optional) Return only images with at least one tag matching the given pattern.
Only applicable when using `most_recent`. This allows more advanced filtering not supported by the AWS API.
This filtering is done locally on what AWS returns, and could have a performance impact if the result is large.

## Attribute Reference

Expand Down

0 comments on commit 7198b98

Please sign in to comment.