aws / aws-sdk-go-v2

AWS SDK for the Go programming language.
https://aws.github.io/aws-sdk-go-v2/docs/
Apache License 2.0
2.5k stars 602 forks source link

Get Filtered Repositories from ECR(short issue description) #2604

Closed ayeletdeRoos closed 2 months ago

ayeletdeRoos commented 2 months ago

Describe the feature

Hello,

I've raised a discussion but haven't received a response yet, which leads me to believe that the feature I'm looking for might not exist. The feature I'm interested in is a filter option for the ecr.DescribeRepositories function in the AWS SDK. This filter would allow me to retrieve repositories based on a specified prefix.

In the AWS CLI, I achieve a similar result using the following command: aws ecr describe-repositories --query 'repositories[?starts_with(repositoryName, prd/test)]' --no-cli-pager

Additionally, I'm trying to fetch all images in a repository, including their labels. With the AWS CLI, I use the following command: aws ecr batch-get-image --repository-name prd/test-default --image-ids imageTag=3bf5abb --accepted-media-types "application/vnd.docker.distribution.manifest.v1+json" --output json | jq -r '.images[].imageManifest' | jq -r '.history[0].v1Compatibility' | jq -r '.conf' Is there a way to accomplish this with the aws-sdk-go-v2? Specifically, I'm interested in fetching all images in a repository, retrieving their labels, and possibly limiting the result to the 10 most recent tags. From what I've searched, it seems there's only a way to specify exactly the image tags you wish to retrieve.

Could you provide guidance on achieving these tasks using the AWS SDK for Go version 2?

Thank you.

Use Case

Our Go service interacts with Amazon ECR to fetch images. We store images in the ECR repository following the format prd/{service}-{mode}. In scenarios where a user wants to retrieve all images for a particular service based on the mode, they'll provide us only with the {service} information. In response, we need to fetch images with names matching prd/{service}-*.

Regarding the second requirement, along with fetching the images, we aim to include labels for additional details. Additionally, we want to offer users the flexibility to retrieve the latest versions without explicitly specifying the version number.

Proposed Solution

No response

Other Information

No response

Acknowledgements

AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2 v1.26.1

Go version used

go 1.21

RanVaknin commented 2 months ago

Hi @ayeletdeRoos ,

Thanks for reaching out.

This filter would allow me to retrieve repositories based on a specified prefix.

In the AWS CLI, I achieve a similar result using the following command: aws ecr describe-repositories --query 'repositories[?starts_with(repositoryName, prd/test)]' --no-cli-pager

I just want to clarify that --query that the CLI has is a client side flitering rule and not a service side filter. So it will not "retrieve only repositories based on a specific prefix". This command will retrieve all repositories and the CLI will filter those on the client side.

The SDK's do not have a "Baked-in" client side filter like --query that the CLI has. The CLI has a lot of courtesy functionalities and ease of use customizations, partly because its not as easy to do filtering on JSON from a unix context.

If service side filtering does not exist for a specific operation (ECR DescribeRepositories does not support service side filters) you'll have to write your own Go code to filter based on the specific filtering you need for example:

package main

import (
    "context"
    "fmt"
    "log"
    "strings"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/ecr"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-east-1"))
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    client := ecr.NewFromConfig(cfg)

    result, err := client.DescribeRepositories(context.TODO(), &ecr.DescribeRepositoriesInput{})
    if err != nil {
        panic(err)
    }

    prefix := "prd/test"
    for _, repo := range result.Repositories {
        if strings.HasPrefix(*repo.RepositoryName, prefix) {
            fmt.Println("Repository Name:", *repo.RepositoryName)
        }
    }
}

Regarding

Is there a way to accomplish this with the aws-sdk-go-v2? Specifically, I'm interested in fetching all images in a repository, retrieving their labels, and possibly limiting the result to the 10 most recent tags. From what I've searched, it seems there's only a way to specify exactly the image tags you wish to retrieve.

I'm a bit confused about this question. I'm not sure how the SDK is different than the CLI in this case. In your CLI command you also specify the exact image tag. The answer here is the same, using the CLI, you are using jq to achieve some filtering functionality. When using the SDK, you need to use that SDK's respective programming language to perform whichever filtering logic you need, in this case you'll need to use Golang to iterate over the results from the BatchGetImage response and then parse the raw json found on the response like you do using jq.

package main

import (
    "context"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/ecr"
    "github.com/aws/aws-sdk-go-v2/service/ecr/types"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        panic(err)
    }

    client := ecr.NewFromConfig(cfg)

    input := &ecr.BatchGetImageInput{
        RepositoryName: aws.String("prd/test-default"),
        ImageIds: []types.ImageIdentifier{
            {
                ImageTag: aws.String("3bf5abb"),
            },
        },
        AcceptedMediaTypes: []string{"application/vnd.docker.distribution.manifest.v1+json"},
    }

    result, err := client.BatchGetImage(context.TODO(), input)
    if err != nil {
        panic(err)
    }
}
// iterate over result.Images and apply whichever filtering logic you need.

If you didn't know, all of the SDKs (and CLI) are code generated from the API model of each AWS service in which they interact with. If the ECR operation does not have service side filtering supported, the SDK wont have functionality to do service side filtering and you'll have to do that on the client side using the programming language of that specific SDK. In the CLI that means using Linux's jq to parse json, using the Go SDK, you'll need to use Golang's encoding/json pacakge and unmarshal that json response.

Because of the above reasons, this is not something we can add to the SDK, and therefore wont qualify for a feature. Im going to go ahead and close this issue and also respond to your discussion so we may continue the correspondence there if needed.

Thanks again, Ran~

github-actions[bot] commented 2 months ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.