diff --git a/.changelog/28148.txt b/.changelog/28148.txt new file mode 100644 index 00000000000..b0d615199d4 --- /dev/null +++ b/.changelog/28148.txt @@ -0,0 +1,7 @@ +```release-note:new-data-source +aws_api_gateway_authorizers +``` + +```release-note:new-data-source +aws_api_gateway_authorizer +``` \ No newline at end of file diff --git a/internal/service/apigateway/authorizer.go b/internal/service/apigateway/authorizer.go index 4f0aa689659..7a007c5c724 100644 --- a/internal/service/apigateway/authorizer.go +++ b/internal/service/apigateway/authorizer.go @@ -190,13 +190,7 @@ func resourceAuthorizerRead(ctx context.Context, d *schema.ResourceData, meta in return sdkdiag.AppendErrorf(diags, "reading API Gateway Authorizer (%s): %s", d.Id(), err) } - arn := arn.ARN{ - Partition: meta.(*conns.AWSClient).Partition, - Service: "apigateway", - Region: meta.(*conns.AWSClient).Region, - Resource: fmt.Sprintf("/restapis/%s/authorizers/%s", apiID, d.Id()), - }.String() - d.Set("arn", arn) + d.Set("arn", authorizerARN(meta.(*conns.AWSClient), apiID, d.Id())) d.Set("authorizer_credentials", authorizer.AuthorizerCredentials) if authorizer.AuthorizerResultTtlInSeconds != nil { // nosemgrep:ci.helper-schema-ResourceData-Set-extraneous-nil-check d.Set("authorizer_result_ttl_in_seconds", authorizer.AuthorizerResultTtlInSeconds) @@ -207,8 +201,8 @@ func resourceAuthorizerRead(ctx context.Context, d *schema.ResourceData, meta in d.Set("identity_source", authorizer.IdentitySource) d.Set("identity_validation_expression", authorizer.IdentityValidationExpression) d.Set("name", authorizer.Name) + d.Set("provider_arns", aws.StringValueSlice(authorizer.ProviderARNs)) d.Set("type", authorizer.Type) - d.Set("provider_arns", flex.FlattenStringSet(authorizer.ProviderARNs)) return diags } @@ -384,3 +378,12 @@ func FindAuthorizerByTwoPartKey(ctx context.Context, conn *apigateway.APIGateway return output, nil } + +func authorizerARN(c *conns.AWSClient, apiID, authorizerID string) string { + return arn.ARN{ + Partition: c.Partition, + Service: "apigateway", + Region: c.Region, + Resource: fmt.Sprintf("/restapis/%s/authorizers/%s", apiID, authorizerID), + }.String() +} diff --git a/internal/service/apigateway/authorizer_data_source.go b/internal/service/apigateway/authorizer_data_source.go new file mode 100644 index 00000000000..073109251cb --- /dev/null +++ b/internal/service/apigateway/authorizer_data_source.go @@ -0,0 +1,96 @@ +package apigateway + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "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" +) + +// @SDKDataSource("aws_api_gateway_authorizer") +func DataSourceAuthorizer() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceAuthorizerRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "authorizer_credentials": { + Type: schema.TypeString, + Computed: true, + }, + "authorizer_id": { + Type: schema.TypeString, + Required: true, + }, + "authorizer_result_ttl_in_seconds": { + Type: schema.TypeInt, + Computed: true, + }, + "authorizer_uri": { + Type: schema.TypeString, + Computed: true, + }, + "identity_source": { + Type: schema.TypeString, + Computed: true, + }, + "identity_validation_expression": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "provider_arns": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "rest_api_id": { + Type: schema.TypeString, + Required: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceAuthorizerRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).APIGatewayConn() + + authorizerID := d.Get("authorizer_id").(string) + apiID := d.Get("rest_api_id").(string) + authorizer, err := FindAuthorizerByTwoPartKey(ctx, conn, authorizerID, apiID) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "reading API Gateway Authorizer (%s): %s", authorizerID, err) + } + + d.SetId(authorizerID) + d.Set("arn", authorizerARN(meta.(*conns.AWSClient), apiID, d.Id())) + d.Set("authorizer_credentials", authorizer.AuthorizerCredentials) + if authorizer.AuthorizerResultTtlInSeconds != nil { // nosemgrep:ci.helper-schema-ResourceData-Set-extraneous-nil-check + d.Set("authorizer_result_ttl_in_seconds", authorizer.AuthorizerResultTtlInSeconds) + } else { + d.Set("authorizer_result_ttl_in_seconds", DefaultAuthorizerTTL) + } + d.Set("authorizer_uri", authorizer.AuthorizerUri) + d.Set("identity_source", authorizer.IdentitySource) + d.Set("identity_validation_expression", authorizer.IdentityValidationExpression) + d.Set("name", authorizer.Name) + d.Set("provider_arns", aws.StringValueSlice(authorizer.ProviderARNs)) + d.Set("type", authorizer.Type) + + return diags +} diff --git a/internal/service/apigateway/authorizer_data_source_test.go b/internal/service/apigateway/authorizer_data_source_test.go new file mode 100644 index 00000000000..f709583a291 --- /dev/null +++ b/internal/service/apigateway/authorizer_data_source_test.go @@ -0,0 +1,48 @@ +package apigateway_test + +import ( + "testing" + + "github.com/aws/aws-sdk-go/service/apigateway" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccAPIGatewayAuthorizerDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_api_gateway_authorizer.test" + dataSourceName := "data.aws_api_gateway_authorizer.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, apigateway.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccAuthorizerDataSourceConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(resourceName, "arn", dataSourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "authorizer_credentials", dataSourceName, "authorizer_credentials"), + resource.TestCheckResourceAttrPair(resourceName, "authorizer_result_ttl_in_seconds", dataSourceName, "authorizer_result_ttl_in_seconds"), + resource.TestCheckResourceAttrPair(resourceName, "authorizer_uri", dataSourceName, "authorizer_uri"), + resource.TestCheckResourceAttrPair(resourceName, "identity_source", dataSourceName, "identity_source"), + resource.TestCheckResourceAttrPair(resourceName, "identity_validation_expression", dataSourceName, "identity_validation_expression"), + resource.TestCheckResourceAttrPair(resourceName, "name", dataSourceName, "name"), + resource.TestCheckResourceAttrPair(resourceName, "provider_arns.#", dataSourceName, "provider_arns.#"), + resource.TestCheckResourceAttrPair(resourceName, "type", dataSourceName, "type"), + ), + }, + }, + }) +} + +func testAccAuthorizerDataSourceConfig_basic(rName string) string { + return acctest.ConfigCompose(testAccAuthorizerConfig_lambda(rName), ` +data "aws_api_gateway_authorizer" "test" { + rest_api_id = aws_api_gateway_rest_api.test.id + authorizer_id = aws_api_gateway_authorizer.test.id +} +`) +} diff --git a/internal/service/apigateway/authorizers_data_source.go b/internal/service/apigateway/authorizers_data_source.go new file mode 100644 index 00000000000..ff8cf55f8a0 --- /dev/null +++ b/internal/service/apigateway/authorizers_data_source.go @@ -0,0 +1,67 @@ +package apigateway + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/apigateway" + "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" +) + +// @SDKDataSource("aws_api_gateway_authorizers") +func DataSourceAuthorizers() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceAuthorizersRead, + + Schema: map[string]*schema.Schema{ + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "rest_api_id": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func dataSourceAuthorizersRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).APIGatewayConn() + + apiID := d.Get("rest_api_id").(string) + input := &apigateway.GetAuthorizersInput{ + RestApiId: aws.String(apiID), + } + var ids []*string + + err := getAuthorizersPages(ctx, conn, input, func(page *apigateway.GetAuthorizersOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Items { + if v == nil { + continue + } + + ids = append(ids, v.Id) + } + + return !lastPage + }) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "reading API Gateway Authorizers (%s): %s", apiID, err) + } + + d.SetId(apiID) + d.Set("ids", aws.StringValueSlice(ids)) + + return diags +} diff --git a/internal/service/apigateway/authorizers_data_source_test.go b/internal/service/apigateway/authorizers_data_source_test.go new file mode 100644 index 00000000000..af689f16678 --- /dev/null +++ b/internal/service/apigateway/authorizers_data_source_test.go @@ -0,0 +1,50 @@ +package apigateway_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/apigateway" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccAPIGatewayAuthorizersDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_api_gateway_authorizers.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, apigateway.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccAuthorizersDataSourceConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "ids.#", "2"), + ), + }, + }, + }) +} + +func testAccAuthorizersDataSourceConfig_basic(rName string) string { + return acctest.ConfigCompose(testAccAuthorizerConfig_base(rName), fmt.Sprintf(` +resource "aws_api_gateway_authorizer" "test" { + count = 2 + + name = "%[1]s-${count.index}" + rest_api_id = aws_api_gateway_rest_api.test.id + authorizer_uri = aws_lambda_function.test.invoke_arn + authorizer_credentials = aws_iam_role.test.arn +} + +data "aws_api_gateway_authorizers" "test" { + rest_api_id = aws_api_gateway_rest_api.test.id + + depends_on = [aws_api_gateway_authorizer.test[0], aws_api_gateway_authorizer.test[1]] +} +`, rName)) +} diff --git a/internal/service/apigateway/generate.go b/internal/service/apigateway/generate.go index feaca4d6a84..69c14e7cdd2 100644 --- a/internal/service/apigateway/generate.go +++ b/internal/service/apigateway/generate.go @@ -1,3 +1,4 @@ +//go:generate go run ../../generate/listpages/main.go -ListOps=GetAuthorizers -Paginator=Position //go:generate go run ../../generate/tags/main.go -ServiceTagsMap -UpdateTags // ONLY generate directives and package declaration! Do not add anything else to this file. diff --git a/internal/service/apigateway/list_pages_gen.go b/internal/service/apigateway/list_pages_gen.go new file mode 100644 index 00000000000..82d9d6086a7 --- /dev/null +++ b/internal/service/apigateway/list_pages_gen.go @@ -0,0 +1,28 @@ +// Code generated by "internal/generate/listpages/main.go -ListOps=GetAuthorizers -Paginator=Position"; DO NOT EDIT. + +package apigateway + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/apigateway" + "github.com/aws/aws-sdk-go/service/apigateway/apigatewayiface" +) + +func getAuthorizersPages(ctx context.Context, conn apigatewayiface.APIGatewayAPI, input *apigateway.GetAuthorizersInput, fn func(*apigateway.GetAuthorizersOutput, bool) bool) error { + for { + output, err := conn.GetAuthorizersWithContext(ctx, input) + if err != nil { + return err + } + + lastPage := aws.StringValue(output.Position) == "" + if !fn(output, lastPage) || lastPage { + break + } + + input.Position = output.Position + } + return nil +} diff --git a/internal/service/apigateway/service_package_gen.go b/internal/service/apigateway/service_package_gen.go index b65a27ec10c..38d9b3da07f 100644 --- a/internal/service/apigateway/service_package_gen.go +++ b/internal/service/apigateway/service_package_gen.go @@ -25,6 +25,14 @@ func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePac Factory: DataSourceAPIKey, TypeName: "aws_api_gateway_api_key", }, + { + Factory: DataSourceAuthorizer, + TypeName: "aws_api_gateway_authorizer", + }, + { + Factory: DataSourceAuthorizers, + TypeName: "aws_api_gateway_authorizers", + }, { Factory: DataSourceDomainName, TypeName: "aws_api_gateway_domain_name", diff --git a/website/docs/d/api_gateway_authorizer.html.markdown b/website/docs/d/api_gateway_authorizer.html.markdown new file mode 100644 index 00000000000..d7189176479 --- /dev/null +++ b/website/docs/d/api_gateway_authorizer.html.markdown @@ -0,0 +1,41 @@ +--- +subcategory: "API Gateway" +layout: "aws" +page_title: "AWS: aws_api_gateway_authorizer" +description: |- + Provides details about a specific API Gateway Authorizer. +--- + +# Data Source: aws_api_gateway_authorizer + +Provides details about a specific API Gateway Authorizer. + +## Example Usage + +```terraform +data "aws_api_gateway_authorizer" "example" { + rest_api_id = aws_api_gateway_rest_api.example.id + authorizer_id = data.aws_api_gateway_authorizers.example.ids[0] +} +``` + +## Argument Reference + +The following arguments are required: + +* `authorizer_id` - (Required) Authorizer identifier. +* `rest_api_id` - (Required) ID of the associated REST API. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - ARN of the API Gateway Authorizer. +* `authorizer_credentials` - Credentials required for the authorizer. +* `authorizer_result_ttl_in_seconds` - TTL of cached authorizer results in seconds. +* `authorizer_uri` - Authorizer's Uniform Resource Identifier (URI). +* `identity_source` - Source of the identity in an incoming request. +* `identity_validation_expression` - Validation expression for the incoming identity. +* `name` - Name of the authorizer. +* `provider_arns` - List of the Amazon Cognito user pool ARNs. +* `type` - Type of the authorizer. diff --git a/website/docs/d/api_gateway_authorizers.html.markdown b/website/docs/d/api_gateway_authorizers.html.markdown new file mode 100644 index 00000000000..88a25085254 --- /dev/null +++ b/website/docs/d/api_gateway_authorizers.html.markdown @@ -0,0 +1,31 @@ +--- +subcategory: "API Gateway" +layout: "aws" +page_title: "AWS: aws_api_gateway_authorizers" +description: |- + Provides details about multiple API Gateway Authorizers. +--- + +# Data Source: aws_api_gateway_authorizers + +Provides details about multiple API Gateway Authorizers. + +## Example Usage + +```terraform +data "aws_api_gateway_authorizers" "example" { + rest_api_id = aws_api_gateway_rest_api.example.id +} +``` + +## Argument Reference + +The following arguments are required: + +* `rest_api_id` - (Required) ID of the associated REST API. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `ids` - List of Authorizer identifiers.