Skip to content

Commit

Permalink
Add ability to find most recently pushed image on ecr_image data source
Browse files Browse the repository at this point in the history
mtt88 committed Sep 19, 2022
1 parent 3c56d2f commit c2235bc
Showing 4 changed files with 43 additions and 18 deletions.
45 changes: 29 additions & 16 deletions internal/service/ecr/image_data_source.go
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ package ecr
import (
"fmt"
"log"
"sort"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ecr"
@@ -47,6 +48,10 @@ func DataSourceImage() *schema.Resource {
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"most_recent": {
Type: schema.TypeBool,
Optional: true,
},
},
}
}
@@ -63,39 +68,47 @@ func dataSourceImageRead(d *schema.ResourceData, meta interface{}) error {
params.RegistryId = aws.String(regId.(string))
}

imgId := ecr.ImageIdentifier{}
digest, ok := d.GetOk("image_digest")
if ok {
imgId.ImageDigest = aws.String(digest.(string))
findMostRecent := false

if _, ok := d.GetOk("most_recent"); ok {
findMostRecent = true
}
tag, ok := d.GetOk("image_tag")
if ok {
imgId.ImageTag = aws.String(tag.(string))

imgId := ecr.ImageIdentifier{}
if v, ok := d.GetOk("image_digest"); ok {
if findMostRecent {
return fmt.Errorf("cannot set image_digest when most_recent is set to true")
}
imgId.ImageDigest = aws.String(v.(string))
}

if imgId.ImageDigest == nil && imgId.ImageTag == nil {
return fmt.Errorf("At least one of either image_digest or image_tag must be defined")
if v, ok := d.GetOk("image_tag"); ok {
if findMostRecent {
return fmt.Errorf("cannot set image_tag when most_recent is set to true")
}
imgId.ImageTag = aws.String(v.(string))
}

params.ImageIds = []*ecr.ImageIdentifier{&imgId}
if !findMostRecent {
params.ImageIds = []*ecr.ImageIdentifier{&imgId}
}

var imageDetails []*ecr.ImageDetail
log.Printf("[DEBUG] Reading ECR Images: %s", params)
err := conn.DescribeImagesPages(params, func(page *ecr.DescribeImagesOutput, lastPage bool) bool {
imageDetails = append(imageDetails, page.ImageDetails...)
return true
})
imageDetails, err := FindImageDetails(conn, params)
if err != nil {
return fmt.Errorf("Error describing ECR images: %w", err)
}

if len(imageDetails) == 0 {
return fmt.Errorf("No matching image found")
}
if len(imageDetails) > 1 {

if len(imageDetails) > 1 && !findMostRecent {
return fmt.Errorf("More than one image found for tag/digest combination")
}

sort.Sort(sort.Reverse(byImagePushedAt(imageDetails)))

image := imageDetails[0]

d.SetId(aws.StringValue(image.ImageDigest))
10 changes: 10 additions & 0 deletions internal/service/ecr/image_data_source_test.go
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ func TestAccECRImageDataSource_ecrImage(t *testing.T) {
registry, repo, tag := "137112412989", "amazonlinux", "latest"
resourceByTag := "data.aws_ecr_image.by_tag"
resourceByDigest := "data.aws_ecr_image.by_digest"
resourceByMostRecent := "data.aws_ecr_image.by_most_recent"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
@@ -31,6 +32,9 @@ func TestAccECRImageDataSource_ecrImage(t *testing.T) {
resource.TestCheckResourceAttrSet(resourceByDigest, "image_pushed_at"),
resource.TestCheckResourceAttrSet(resourceByDigest, "image_size_in_bytes"),
testCheckTagInImageTags(resourceByDigest, tag),
resource.TestCheckResourceAttrSet(resourceByMostRecent, "image_pushed_at"),
resource.TestCheckResourceAttrSet(resourceByMostRecent, "image_size_in_bytes"),
resource.TestCheckResourceAttrSet(resourceByMostRecent, "image_tags.#"),
),
},
},
@@ -50,6 +54,12 @@ data "aws_ecr_image" "by_digest" {
repository_name = data.aws_ecr_image.by_tag.repository_name
image_digest = data.aws_ecr_image.by_tag.image_digest
}
data "aws_ecr_image" "by_most_recent" {
registry_id = data.aws_ecr_image.by_tag.registry_id
repository_name = data.aws_ecr_image.by_tag.repository_name
most_recent = true
}
`, reg, repo, tag)
}

1 change: 1 addition & 0 deletions internal/service/ecr/repository_data_source_test.go
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@ func TestAccECRRepositoryDataSource_basic(t *testing.T) {
resource.TestCheckResourceAttrPair(resourceName, "image_scanning_configuration.#", dataSourceName, "image_scanning_configuration.#"),
resource.TestCheckResourceAttrPair(resourceName, "image_tag_mutability", dataSourceName, "image_tag_mutability"),
resource.TestCheckResourceAttrPair(resourceName, "encryption_configuration.#", dataSourceName, "encryption_configuration.#"),
resource.TestCheckResourceAttrSet(dataSourceName, "most_recent_image_tags.#"),
),
},
},
5 changes: 3 additions & 2 deletions website/docs/d/ecr_image.html.markdown
Original file line number Diff line number Diff line change
@@ -25,8 +25,9 @@ The following arguments are supported:

* `registry_id` - (Optional) ID of the Registry where the repository resides.
* `repository_name` - (Required) Name of the ECR Repository.
* `image_digest` - (Optional) Sha256 digest of the image manifest. At least one of `image_digest` or `image_tag` must be specified.
* `image_tag` - (Optional) Tag associated with this image. At least one of `image_digest` or `image_tag` must be specified.
* `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.

## Attributes Reference

0 comments on commit c2235bc

Please sign in to comment.