diff --git a/.changelog/24815.txt b/.changelog/24815.txt new file mode 100644 index 00000000000..ef59eec5c35 --- /dev/null +++ b/.changelog/24815.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_athena_named_query +``` diff --git a/internal/service/athena/named_query_data_source.go b/internal/service/athena/named_query_data_source.go new file mode 100644 index 00000000000..176e3083d94 --- /dev/null +++ b/internal/service/athena/named_query_data_source.go @@ -0,0 +1,107 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package athena + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/athena" + "github.com/aws/aws-sdk-go-v2/service/athena/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" + tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +// @SDKDataSource("aws_athena_named_query") +func dataSourceNamedQuery() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceNamedQueryRead, + + Schema: map[string]*schema.Schema{ + "database": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "querystring": { + Type: schema.TypeString, + Computed: true, + }, + "workgroup": { + Type: schema.TypeString, + Optional: true, + Default: "primary", + }, + }, + } +} + +func dataSourceNamedQueryRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).AthenaClient(ctx) + + input := &athena.ListNamedQueriesInput{ + WorkGroup: aws.String(d.Get("workgroup").(string)), + } + var queryIDs []string + pages := athena.NewListNamedQueriesPaginator(conn, input) + for pages.HasMorePages() { + page, err := pages.NextPage(ctx) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "listing Athena Named Queries: %s", err) + } + + queryIDs = append(queryIDs, page.NamedQueryIds...) + } + + name := d.Get("name").(string) + query, err := findNamedQueryByName(ctx, conn, queryIDs, name) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "reading Athena Named Query (%s): %s", name, err) + } + + d.SetId(aws.ToString(query.NamedQueryId)) + d.Set("database", query.Database) + d.Set("description", query.Description) + d.Set("name", query.Name) + d.Set("querystring", query.QueryString) + d.Set("workgroup", query.WorkGroup) + + return nil +} + +func findNamedQueryByName(ctx context.Context, conn *athena.Client, queryIDs []string, name string) (*types.NamedQuery, error) { + input := &athena.BatchGetNamedQueryInput{ + NamedQueryIds: queryIDs, + } + + output, err := conn.BatchGetNamedQuery(ctx, input) + + if err != nil { + return nil, err + } + + if output == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + queries := tfslices.Filter(output.NamedQueries, func(v types.NamedQuery) bool { + return aws.ToString(v.Name) == name + }) + + return tfresource.AssertSingleValueResult(queries) +} diff --git a/internal/service/athena/named_query_data_source_test.go b/internal/service/athena/named_query_data_source_test.go new file mode 100644 index 00000000000..e86f9448f0f --- /dev/null +++ b/internal/service/athena/named_query_data_source_test.go @@ -0,0 +1,46 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package athena_test + +import ( + "testing" + + 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 TestAccAthenaNamedQueryDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + resourceName := "aws_athena_named_query.test" + dataSourceName := "data.aws_athena_named_query.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.AthenaEndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccNamedQueryDataSourceConfig_basic(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "database", resourceName, "database"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "name", resourceName, "name"), + resource.TestCheckResourceAttrPair(dataSourceName, "query", resourceName, "querystring"), + resource.TestCheckResourceAttrPair(dataSourceName, "workgroup", resourceName, "workgroup"), + ), + }, + }, + }) +} + +func testAccNamedQueryDataSourceConfig_basic() string { + return acctest.ConfigCompose(testAccNamedQueryConfig_basic(sdkacctest.RandInt(), sdkacctest.RandString(5)), ` +data "aws_athena_named_query" "test" { + name = aws_athena_named_query.test.name +} +`) +} diff --git a/internal/service/athena/named_query_test.go b/internal/service/athena/named_query_test.go index 89cf4d0d5ab..17a835dabf0 100644 --- a/internal/service/athena/named_query_test.go +++ b/internal/service/athena/named_query_test.go @@ -107,49 +107,43 @@ func testAccCheckNamedQueryExists(ctx context.Context, n string) resource.TestCh } } -func testAccNamedQueryConfig_basic(rInt int, rName string) string { +func testAccNamedQueryConfig_base(rInt int, rName string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { - bucket = "tf-test-athena-db-%s-%d" + bucket = "%[3]s-%[1]s-%[2]d" force_destroy = true } resource "aws_athena_database" "test" { - name = "%s" + name = %[1]q bucket = aws_s3_bucket.test.bucket } +`, rName, rInt, acctest.ResourcePrefix) +} +func testAccNamedQueryConfig_basic(rInt int, rName string) string { + return acctest.ConfigCompose(testAccNamedQueryConfig_base(rInt, rName), fmt.Sprintf(` resource "aws_athena_named_query" "test" { - name = "tf-athena-named-query-%s" + name = "%[2]s-%[1]s" database = aws_athena_database.test.name query = "SELECT * FROM ${aws_athena_database.test.name} limit 10;" description = "tf test" } -`, rName, rInt, rName, rName) +`, rName, acctest.ResourcePrefix)) } func testAccNamedQueryConfig_workGroup(rInt int, rName string) string { - return fmt.Sprintf(` -resource "aws_s3_bucket" "test" { - bucket = "tf-test-athena-db-%s-%d" - force_destroy = true -} - + return acctest.ConfigCompose(testAccNamedQueryConfig_base(rInt, rName), fmt.Sprintf(` resource "aws_athena_workgroup" "test" { - name = "tf-athena-workgroup-%s-%d" -} - -resource "aws_athena_database" "test" { - name = "%s" - bucket = aws_s3_bucket.test.bucket + name = "%[3]s-%[1]s-%[2]d" } resource "aws_athena_named_query" "test" { - name = "tf-athena-named-query-%s" + name = "%[3]s-%[1]s" workgroup = aws_athena_workgroup.test.id database = aws_athena_database.test.name query = "SELECT * FROM ${aws_athena_database.test.name} limit 10;" description = "tf test" } -`, rName, rInt, rName, rInt, rName, rName) +`, rName, rInt, acctest.ResourcePrefix)) } diff --git a/internal/service/athena/service_package_gen.go b/internal/service/athena/service_package_gen.go index 4ee48c31c5a..cc637c5d578 100644 --- a/internal/service/athena/service_package_gen.go +++ b/internal/service/athena/service_package_gen.go @@ -23,7 +23,12 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.Servic } func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePackageSDKDataSource { - return []*types.ServicePackageSDKDataSource{} + return []*types.ServicePackageSDKDataSource{ + { + Factory: dataSourceNamedQuery, + TypeName: "aws_athena_named_query", + }, + } } func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePackageSDKResource { diff --git a/website/docs/d/athena_named_query.html.markdown b/website/docs/d/athena_named_query.html.markdown new file mode 100644 index 00000000000..f280455b8c3 --- /dev/null +++ b/website/docs/d/athena_named_query.html.markdown @@ -0,0 +1,35 @@ +--- +subcategory: "Athena" +layout: "aws" +page_title: "AWS: aws_athena_named_query" +description: |- + Provides an Athena Named Query data source. +--- + +# Data Source: aws_athena_named_query + +Provides an Athena Named Query data source. + +## Example Usage + +```hcl +data "aws_athena_named_query" "example" { + name = "athenaQueryName" +} +``` + +## Argument Reference + +This data source supports the following arguments: + +* `name` - (Required) The plain language name for the query. Maximum length of 128. +* `workgroup` - (Optional) The workgroup to which the query belongs. Defaults to `primary`. + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `database` - Database to which the query belongs. +* `description` - Brief explanation of the query. +* `id` - The unique ID of the query. +* `query` - Text of the query itself.