diff --git a/.changelog/22768.txt b/.changelog/22768.txt new file mode 100644 index 00000000000..ffe8f320e3d --- /dev/null +++ b/.changelog/22768.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_connect_queue +``` \ No newline at end of file diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 5ee720b6649..a4a2fe394e3 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -482,6 +482,7 @@ func Provider() *schema.Provider { "aws_connect_instance": connect.DataSourceInstance(), "aws_connect_lambda_function_association": connect.DataSourceLambdaFunctionAssociation(), "aws_connect_prompt": connect.DataSourcePrompt(), + "aws_connect_queue": connect.DataSourceQueue(), "aws_connect_quick_connect": connect.DataSourceQuickConnect(), "aws_cur_report_definition": cur.DataSourceReportDefinition(), diff --git a/internal/service/connect/enum.go b/internal/service/connect/enum.go index 7af9fdb0a94..57fb7a0dadb 100644 --- a/internal/service/connect/enum.go +++ b/internal/service/connect/enum.go @@ -24,9 +24,12 @@ const ( // MaxResults Valid Range: Minimum value of 1. Maximum value of 1000 // https://docs.aws.amazon.com/connect/latest/APIReference/API_ListPrompts.html ListPromptsMaxResults = 60 - // ListQueueQuickConnectsMaxResults Valid Range: Minimum value of 1. Maximum value of 100. + // ListQueueQuickConnectsMaxResults Valid Range: Minimum value of 1. Maximum value of 100. // https://docs.aws.amazon.com/connect/latest/APIReference/API_ListQueueQuickConnects.html ListQueueQuickConnectsMaxResults = 60 + // ListQueuesMaxResults Valid Range: Minimum value of 1. Maximum value of 1000. + // https://docs.aws.amazon.com/connect/latest/APIReference/API_ListQueues.html + ListQueuesMaxResults = 60 // ListQuickConnectsMaxResults Valid Range: Minimum value of 1. Maximum value of 1000. // https://docs.aws.amazon.com/connect/latest/APIReference/API_ListQuickConnects.html ListQuickConnectsMaxResults = 60 diff --git a/internal/service/connect/queue_data_source.go b/internal/service/connect/queue_data_source.go new file mode 100644 index 00000000000..596ba1dbca6 --- /dev/null +++ b/internal/service/connect/queue_data_source.go @@ -0,0 +1,174 @@ +package connect + +import ( + "context" + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/connect" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func DataSourceQueue() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceQueueRead, + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "hours_of_operation_id": { + Type: schema.TypeString, + Computed: true, + }, + "instance_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 100), + }, + "max_contacts": { + Type: schema.TypeInt, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ExactlyOneOf: []string{"name", "queue_id"}, + }, + "outbound_caller_config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "outbound_caller_id_name": { + Type: schema.TypeString, + Computed: true, + }, + "outbound_caller_id_number_id": { + Type: schema.TypeString, + Computed: true, + }, + "outbound_flow_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "queue_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ExactlyOneOf: []string{"queue_id", "name"}, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tftags.TagsSchemaComputed(), + }, + } +} + +func dataSourceQueueRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).ConnectConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + + instanceID := d.Get("instance_id").(string) + + input := &connect.DescribeQueueInput{ + InstanceId: aws.String(instanceID), + } + + if v, ok := d.GetOk("queue_id"); ok { + input.QueueId = aws.String(v.(string)) + } else if v, ok := d.GetOk("name"); ok { + name := v.(string) + queueSummary, err := dataSourceGetConnectQueueSummaryByName(ctx, conn, instanceID, name) + + if err != nil { + return diag.FromErr(fmt.Errorf("error finding Connect Queue Summary by name (%s): %w", name, err)) + } + + if queueSummary == nil { + return diag.FromErr(fmt.Errorf("error finding Connect Queue Summary by name (%s): not found", name)) + } + + input.QueueId = queueSummary.Id + } + + resp, err := conn.DescribeQueueWithContext(ctx, input) + + if err != nil { + return diag.FromErr(fmt.Errorf("error getting Connect Queue: %w", err)) + } + + if resp == nil || resp.Queue == nil { + return diag.FromErr(fmt.Errorf("error getting Connect Queue: empty response")) + } + + queue := resp.Queue + + d.Set("arn", queue.QueueArn) + d.Set("description", queue.Description) + d.Set("hours_of_operation_id", queue.HoursOfOperationId) + d.Set("max_contacts", queue.MaxContacts) + d.Set("name", queue.Name) + d.Set("queue_id", queue.QueueId) + d.Set("status", queue.Status) + + if err := d.Set("outbound_caller_config", flattenOutboundCallerConfig(queue.OutboundCallerConfig)); err != nil { + return diag.FromErr(fmt.Errorf("error setting outbound_caller_config: %s", err)) + } + + if err := d.Set("tags", KeyValueTags(queue.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return diag.FromErr(fmt.Errorf("error setting tags: %s", err)) + } + + d.SetId(fmt.Sprintf("%s:%s", instanceID, aws.StringValue(queue.QueueId))) + + return nil +} + +func dataSourceGetConnectQueueSummaryByName(ctx context.Context, conn *connect.Connect, instanceID, name string) (*connect.QueueSummary, error) { + var result *connect.QueueSummary + + input := &connect.ListQueuesInput{ + InstanceId: aws.String(instanceID), + MaxResults: aws.Int64(ListQueuesMaxResults), + } + + err := conn.ListQueuesPagesWithContext(ctx, input, func(page *connect.ListQueuesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, qs := range page.QueueSummaryList { + if qs == nil { + continue + } + + if aws.StringValue(qs.Name) == name { + result = qs + return false + } + } + + return !lastPage + }) + + if err != nil { + return nil, err + } + + return result, nil +} diff --git a/internal/service/connect/queue_data_source_test.go b/internal/service/connect/queue_data_source_test.go new file mode 100644 index 00000000000..632341e9473 --- /dev/null +++ b/internal/service/connect/queue_data_source_test.go @@ -0,0 +1,127 @@ +package connect_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/connect" + 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 TestAccConnectQueueDataSource_queueID(t *testing.T) { + rName := sdkacctest.RandomWithPrefix("resource-test-terraform") + resourceName := "aws_connect_queue.test" + datasourceName := "data.aws_connect_queue.test" + outboundCallerConfigName := "exampleOutboundCallerConfigName" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, connect.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccQueueDataSourceConfig_QueueID(rName, resourceName, outboundCallerConfigName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(datasourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(datasourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(datasourceName, "hours_of_operation_id", resourceName, "hours_of_operation_id"), + resource.TestCheckResourceAttrPair(datasourceName, "instance_id", resourceName, "instance_id"), + resource.TestCheckResourceAttrPair(datasourceName, "max_contacts", resourceName, "max_contacts"), + resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"), + resource.TestCheckResourceAttrPair(datasourceName, "outbound_caller_config.#", resourceName, "outbound_caller_config.#"), + resource.TestCheckResourceAttrPair(datasourceName, "outbound_caller_config.0.outbound_caller_id_name", resourceName, "outbound_caller_config.0.outbound_caller_id_name"), + resource.TestCheckResourceAttrPair(datasourceName, "queue_id", resourceName, "queue_id"), + resource.TestCheckResourceAttrPair(datasourceName, "status", resourceName, "status"), + resource.TestCheckResourceAttrPair(datasourceName, "tags.%", resourceName, "tags.%"), + ), + }, + }, + }) +} + +func TestAccConnectQueueDataSource_name(t *testing.T) { + rName := sdkacctest.RandomWithPrefix("resource-test-terraform") + rName2 := sdkacctest.RandomWithPrefix("resource-test-terraform") + resourceName := "aws_connect_queue.test" + datasourceName := "data.aws_connect_queue.test" + outboundCallerConfigName := "exampleOutboundCallerConfigName" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, connect.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccQueueDataSourceConfig_Name(rName, rName2, outboundCallerConfigName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(datasourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(datasourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(datasourceName, "hours_of_operation_id", resourceName, "hours_of_operation_id"), + resource.TestCheckResourceAttrPair(datasourceName, "instance_id", resourceName, "instance_id"), + resource.TestCheckResourceAttrPair(datasourceName, "max_contacts", resourceName, "max_contacts"), + resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"), + resource.TestCheckResourceAttrPair(datasourceName, "outbound_caller_config.#", resourceName, "outbound_caller_config.#"), + resource.TestCheckResourceAttrPair(datasourceName, "outbound_caller_config.0.outbound_caller_id_name", resourceName, "outbound_caller_config.0.outbound_caller_id_name"), + resource.TestCheckResourceAttrPair(datasourceName, "queue_id", resourceName, "queue_id"), + resource.TestCheckResourceAttrPair(datasourceName, "status", resourceName, "status"), + resource.TestCheckResourceAttrPair(datasourceName, "tags.%", resourceName, "tags.%"), + ), + }, + }, + }) +} + +func testAccQueueBaseDataSourceConfig(rName, rName2, outboundCallerConfigName string) string { + return fmt.Sprintf(` +resource "aws_connect_instance" "test" { + identity_management_type = "CONNECT_MANAGED" + inbound_calls_enabled = true + instance_alias = %[1]q + outbound_calls_enabled = true +} + +data "aws_connect_hours_of_operation" "test" { + instance_id = aws_connect_instance.test.id + name = "Basic Hours" +} + +resource "aws_connect_queue" "test" { + instance_id = aws_connect_instance.test.id + name = %[2]q + description = "Used to test queue data source" + hours_of_operation_id = data.aws_connect_hours_of_operation.test.hours_of_operation_id + + outbound_caller_config { + outbound_caller_id_name = %[3]q + } + + tags = { + "Name" = "Test Queue", + } +} + `, rName, rName2, outboundCallerConfigName) +} + +func testAccQueueDataSourceConfig_QueueID(rName, rName2, outboundCallerConfigName string) string { + return acctest.ConfigCompose( + testAccQueueBaseDataSourceConfig(rName, rName2, outboundCallerConfigName), + ` +data "aws_connect_queue" "test" { + instance_id = aws_connect_instance.test.id + queue_id = aws_connect_queue.test.queue_id +} +`) +} + +func testAccQueueDataSourceConfig_Name(rName, rName2, outboundCallerConfigName string) string { + return acctest.ConfigCompose( + testAccQueueBaseDataSourceConfig(rName, rName2, outboundCallerConfigName), + ` +data "aws_connect_queue" "test" { + instance_id = aws_connect_instance.test.id + name = aws_connect_queue.test.name +} +`) +} diff --git a/website/docs/d/connect_queue.markdown b/website/docs/d/connect_queue.markdown new file mode 100644 index 00000000000..33d6f49e78a --- /dev/null +++ b/website/docs/d/connect_queue.markdown @@ -0,0 +1,61 @@ +--- +subcategory: "Connect" +layout: "aws" +page_title: "AWS: aws_connect_queue" +description: |- + Provides details about a specific Amazon Connect Queue. +--- + +# Data Source: aws_connect_queue + +Provides details about a specific Amazon Connect Queue. + +## Example Usage + +By `name` + +```hcl +data "aws_connect_queue" "example" { + instance_id = "aaaaaaaa-bbbb-cccc-dddd-111111111111" + name = "Example" +} +``` + +By `queue_id` + +```hcl +data "aws_connect_queue" "example" { + instance_id = "aaaaaaaa-bbbb-cccc-dddd-111111111111" + queue_id = "cccccccc-bbbb-cccc-dddd-111111111111" +} +``` + +## Argument Reference + +~> **NOTE:** `instance_id` and one of either `name` or `queue_id` is required. + +The following arguments are supported: + +* `queue_id` - (Optional) Returns information on a specific Queue by Queue id +* `instance_id` - (Required) Reference to the hosting Amazon Connect Instance +* `name` - (Optional) Returns information on a specific Queue by name + +## Attributes Reference + +In addition to all of the arguments above, the following attributes are exported: + +* `arn` - The Amazon Resource Name (ARN) of the Queue. +* `description` - Specifies the description of the Queue. +* `hours_of_operation_id` - Specifies the identifier of the Hours of Operation. +* `id` - The identifier of the hosting Amazon Connect Instance and identifier of the Queue separated by a colon (`:`). +* `max_contacts` - Specifies the maximum number of contacts that can be in the queue before it is considered full. Minimum value of 0. +* `outbound_caller_config` - A block that defines the outbound caller ID name, number, and outbound whisper flow. The Outbound Caller Config block is documented below. +* `queue_id` - The identifier for the Queue. +* `status` - Specifies the description of the Queue. Values are `ENABLED` or `DISABLED`. +* `tags` - A map of tags assigned to the Queue. + +A `outbound_caller_config` block supports the following arguments: + +* `outbound_caller_id_name` - Specifies the caller ID name. +* `outbound_caller_id_number_id` - Specifies the caller ID number. +* `outbound_flow_id` - Specifies the outbound whisper flow to be used during an outbound call. \ No newline at end of file