diff --git a/.changelog/34446.txt b/.changelog/34446.txt new file mode 100644 index 00000000000..ff39c693a98 --- /dev/null +++ b/.changelog/34446.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_ecr_repositories +`` diff --git a/go.mod b/go.mod index 5f1e293efb4..06cb516035e 100644 --- a/go.mod +++ b/go.mod @@ -38,6 +38,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/directoryservice v1.22.2 github.com/aws/aws-sdk-go-v2/service/docdbelastic v1.6.2 github.com/aws/aws-sdk-go-v2/service/ec2 v1.138.2 + github.com/aws/aws-sdk-go-v2/service/ecr v1.24.2 github.com/aws/aws-sdk-go-v2/service/eks v1.35.2 github.com/aws/aws-sdk-go-v2/service/emr v1.35.2 github.com/aws/aws-sdk-go-v2/service/emrserverless v1.14.2 diff --git a/go.sum b/go.sum index 1a52bb87dca..7a12f417a7d 100644 --- a/go.sum +++ b/go.sum @@ -102,6 +102,8 @@ github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.2 h1:IPMh5Selz3UKr1rY8FaNTv4 github.com/aws/aws-sdk-go-v2/service/dynamodb v1.26.2/go.mod h1:Mj372IvfZ9ftME7Kdo74stz3KAjMA+WC7Fzzry9uCDI= github.com/aws/aws-sdk-go-v2/service/ec2 v1.138.2 h1:e3Imv1oXz+W3Tfclflkh72t5TUPUwWdkHP7ctQGk8Dc= github.com/aws/aws-sdk-go-v2/service/ec2 v1.138.2/go.mod h1:d1hAqgLDOPaSO1Piy/0bBmj6oAplFwv6p0cquHntNHM= +github.com/aws/aws-sdk-go-v2/service/ecr v1.24.2 h1:ETo/9bTM+fp1Gf6l04jhoA8emIjZNDRu1qoNRBd419g= +github.com/aws/aws-sdk-go-v2/service/ecr v1.24.2/go.mod h1:/m9MiYl5Ds0cZqy/bbeSUWxKLwTarGugjXxSgiXNQFc= github.com/aws/aws-sdk-go-v2/service/eks v1.35.2 h1:G1gPnbhGBEKedQLoSI71u3+IMJ+uIPxCNB0ZPmv6dpk= github.com/aws/aws-sdk-go-v2/service/eks v1.35.2/go.mod h1:HZ5xGhvvZEs7iBPbwhLWZWvAxWezzOFn/HrepDivCgQ= github.com/aws/aws-sdk-go-v2/service/emr v1.35.2 h1:Q4nxzsfd61L/d83LDDD/UhDk1Tktd4+8QPhRLyRUVIs= diff --git a/internal/conns/awsclient_gen.go b/internal/conns/awsclient_gen.go index 9d9b23d4ba0..89887d35653 100644 --- a/internal/conns/awsclient_gen.go +++ b/internal/conns/awsclient_gen.go @@ -32,6 +32,7 @@ import ( directoryservice_sdkv2 "github.com/aws/aws-sdk-go-v2/service/directoryservice" docdbelastic_sdkv2 "github.com/aws/aws-sdk-go-v2/service/docdbelastic" ec2_sdkv2 "github.com/aws/aws-sdk-go-v2/service/ec2" + ecr_sdkv2 "github.com/aws/aws-sdk-go-v2/service/ecr" eks_sdkv2 "github.com/aws/aws-sdk-go-v2/service/eks" emr_sdkv2 "github.com/aws/aws-sdk-go-v2/service/emr" emrserverless_sdkv2 "github.com/aws/aws-sdk-go-v2/service/emrserverless" @@ -537,6 +538,10 @@ func (c *AWSClient) ECRConn(ctx context.Context) *ecr_sdkv1.ECR { return errs.Must(conn[*ecr_sdkv1.ECR](ctx, c, names.ECR)) } +func (c *AWSClient) ECRClient(ctx context.Context) *ecr_sdkv2.Client { + return errs.Must(client[*ecr_sdkv2.Client](ctx, c, names.ECR)) +} + func (c *AWSClient) ECRPublicConn(ctx context.Context) *ecrpublic_sdkv1.ECRPublic { return errs.Must(conn[*ecrpublic_sdkv1.ECRPublic](ctx, c, names.ECRPublic)) } diff --git a/internal/service/ecr/repositories_data_source.go b/internal/service/ecr/repositories_data_source.go new file mode 100644 index 00000000000..f449a93a806 --- /dev/null +++ b/internal/service/ecr/repositories_data_source.go @@ -0,0 +1,76 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package ecr + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ecr" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + fwtypes "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" +) + +// @FrameworkDataSource(name="Repositories") +func newRepositoriesDataSource(context.Context) (datasource.DataSourceWithConfigure, error) { + return &repositoriesDataSource{}, nil +} + +type repositoriesDataSource struct { + framework.DataSourceWithConfigure +} + +func (d *repositoriesDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { // nosemgrep:ci.meta-in-func-name + resp.TypeName = "aws_ecr_repositories" +} + +func (d *repositoriesDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": framework.IDAttribute(), + "names": schema.SetAttribute{ + ElementType: fwtypes.StringType, + Computed: true, + }, + }, + } +} +func (d *repositoriesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().ECRClient(ctx) + + var data repositoriesDataSourceModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + var names []string + + pages := ecr.NewDescribeRepositoriesPaginator(conn, &ecr.DescribeRepositoriesInput{}) + for pages.HasMorePages() { + output, err := pages.NextPage(ctx) + + if err != nil { + resp.Diagnostics.AddError("reading ECR Repositories", err.Error()) + return + } + + for _, v := range output.Repositories { + names = append(names, aws.ToString(v.RepositoryName)) + } + } + + data.ID = flex.StringValueToFramework(ctx, d.Meta().Region) + data.Names = flex.FlattenFrameworkStringValueSet(ctx, names) + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +type repositoriesDataSourceModel struct { + ID fwtypes.String `tfsdk:"id"` + Names fwtypes.Set `tfsdk:"names"` +} diff --git a/internal/service/ecr/repositories_data_source_test.go b/internal/service/ecr/repositories_data_source_test.go new file mode 100644 index 00000000000..963e0a28e46 --- /dev/null +++ b/internal/service/ecr/repositories_data_source_test.go @@ -0,0 +1,67 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package ecr_test + +import ( + "encoding/json" + "fmt" + "strings" + "testing" + + "github.com/aws/aws-sdk-go/service/ecr" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccECRRepositoriesDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + var rNames []string + for i := 1; i < 6; i++ { + rNames = append(rNames, sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)) + } + dataSourceName := "data.aws_ecr_repositories.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.ECREndpointID) + }, + ErrorCheck: acctest.ErrorCheck(t, strings.ToLower(ecr.ServiceID)), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccRepositoriesDataSourceConfig_basic(rNames), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "names.#", "5"), + resource.TestCheckTypeSetElemAttr(dataSourceName, "names.*", rNames[0]), + resource.TestCheckTypeSetElemAttr(dataSourceName, "names.*", rNames[1]), + resource.TestCheckTypeSetElemAttr(dataSourceName, "names.*", rNames[2]), + resource.TestCheckTypeSetElemAttr(dataSourceName, "names.*", rNames[3]), + resource.TestCheckTypeSetElemAttr(dataSourceName, "names.*", rNames[4]), + ), + }, + }, + }) +} + +func testAccRepositoriesDataSourceConfig_basic(rNames []string) string { + rNameJson, _ := json.Marshal(rNames) + rNameString := string(rNameJson) + return fmt.Sprintf(` +locals { + repo_list = %[1]s +} + +resource "aws_ecr_repository" "test" { + count = length(local.repo_list) + name = local.repo_list[count.index] +} + +data "aws_ecr_repositories" "test" { + depends_on = [aws_ecr_repository.test] +} +`, rNameString) +} diff --git a/internal/service/ecr/service_package_gen.go b/internal/service/ecr/service_package_gen.go index 21c06cb21fe..d86217289e0 100644 --- a/internal/service/ecr/service_package_gen.go +++ b/internal/service/ecr/service_package_gen.go @@ -5,6 +5,8 @@ package ecr import ( "context" + aws_sdkv2 "github.com/aws/aws-sdk-go-v2/aws" + ecr_sdkv2 "github.com/aws/aws-sdk-go-v2/service/ecr" aws_sdkv1 "github.com/aws/aws-sdk-go/aws" session_sdkv1 "github.com/aws/aws-sdk-go/aws/session" ecr_sdkv1 "github.com/aws/aws-sdk-go/service/ecr" @@ -16,7 +18,12 @@ import ( type servicePackage struct{} func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.ServicePackageFrameworkDataSource { - return []*types.ServicePackageFrameworkDataSource{} + return []*types.ServicePackageFrameworkDataSource{ + { + Factory: newRepositoriesDataSource, + Name: "Repositories", + }, + } } func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { @@ -92,6 +99,17 @@ func (p *servicePackage) NewConn(ctx context.Context, config map[string]any) (*e return ecr_sdkv1.New(sess.Copy(&aws_sdkv1.Config{Endpoint: aws_sdkv1.String(config["endpoint"].(string))})), nil } +// NewClient returns a new AWS SDK for Go v2 client for this service package's AWS API. +func (p *servicePackage) NewClient(ctx context.Context, config map[string]any) (*ecr_sdkv2.Client, error) { + cfg := *(config["aws_sdkv2_config"].(*aws_sdkv2.Config)) + + return ecr_sdkv2.NewFromConfig(cfg, func(o *ecr_sdkv2.Options) { + if endpoint := config["endpoint"].(string); endpoint != "" { + o.BaseEndpoint = aws_sdkv2.String(endpoint) + } + }), nil +} + func ServicePackage(ctx context.Context) conns.ServicePackage { return &servicePackage{} } diff --git a/names/names.go b/names/names.go index fdfbbb9e8df..f3d1fcab1fe 100644 --- a/names/names.go +++ b/names/names.go @@ -48,6 +48,7 @@ const ( DocDBElasticEndpointID = "docdb-elastic" ControlTowerEndpointID = "controltower" DSEndpointID = "ds" + ECREndpointID = "api.ecr" EKSEndpointID = "eks" EMREndpointID = "elasticmapreduce" EMRServerlessEndpointID = "emrserverless" diff --git a/names/names_data.csv b/names/names_data.csv index 3a779fa544f..c66263276fb 100644 --- a/names/names_data.csv +++ b/names/names_data.csv @@ -129,7 +129,7 @@ ebs,ebs,ebs,ebs,,ebs,,,EBS,EBS,,1,,,aws_ebs_,,changewhenimplemented,EBS (Elastic ec2,ec2,ec2,ec2,,ec2,ec2,,EC2,EC2,,1,2,aws_(ami|availability_zone|ec2_(availability|capacity|fleet|host|instance|public_ipv4_pool|serial|spot|tag)|eip|instance|key_pair|launch_template|placement_group|spot),aws_ec2_,ec2_,ami;availability_zone;ec2_availability_;ec2_capacity_;ec2_fleet;ec2_host;ec2_image_;ec2_instance_;ec2_public_ipv4_pool;ec2_serial_;ec2_spot_;ec2_tag;eip;instance;key_pair;launch_template;placement_group;spot_,EC2 (Elastic Compute Cloud),Amazon,,,,,,, imagebuilder,imagebuilder,imagebuilder,imagebuilder,,imagebuilder,,,ImageBuilder,Imagebuilder,,1,,,aws_imagebuilder_,,imagebuilder_,EC2 Image Builder,Amazon,,,,,,, ec2-instance-connect,ec2instanceconnect,ec2instanceconnect,ec2instanceconnect,,ec2instanceconnect,,,EC2InstanceConnect,EC2InstanceConnect,,1,,,aws_ec2instanceconnect_,,ec2instanceconnect_,EC2 Instance Connect,AWS,,x,,,,, -ecr,ecr,ecr,ecr,,ecr,,,ECR,ECR,,1,,,aws_ecr_,,ecr_,ECR (Elastic Container Registry),Amazon,,,,,,, +ecr,ecr,ecr,ecr,,ecr,,,ECR,ECR,,1,2,,aws_ecr_,,ecr_,ECR (Elastic Container Registry),Amazon,,,,,,, ecr-public,ecrpublic,ecrpublic,ecrpublic,,ecrpublic,,,ECRPublic,ECRPublic,,1,,,aws_ecrpublic_,,ecrpublic_,ECR Public,Amazon,,,,,,, ecs,ecs,ecs,ecs,,ecs,,,ECS,ECS,,1,,,aws_ecs_,,ecs_,ECS (Elastic Container),Amazon,,,,,,, efs,efs,efs,efs,,efs,,,EFS,EFS,,1,,,aws_efs_,,efs_,EFS (Elastic File System),Amazon,,,,,,, diff --git a/website/docs/d/ecr_repositories.html.markdown b/website/docs/d/ecr_repositories.html.markdown new file mode 100644 index 00000000000..ed3489342f9 --- /dev/null +++ b/website/docs/d/ecr_repositories.html.markdown @@ -0,0 +1,30 @@ +--- +subcategory: "ECR (Elastic Container Registry)" +layout: "aws" +page_title: "AWS: aws_ecr_repositories" +description: |- + Terraform data source for providing information on AWS ECR (Elastic Container Registry) Repositories. +--- + +# Data Source: aws_ecr_repositories + +Terraform data source for providing information on AWS ECR (Elastic Container Registry) Repositories. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_ecr_repositories" "example" {} +``` + +## Argument Reference + +There are no arguments available for this data source. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - AWS Region. +* `names` - A list if AWS Elastic Container Registries for the region.