diff --git a/.changelog/37218.txt b/.changelog/37218.txt new file mode 100644 index 00000000000..b8a92e558b6 --- /dev/null +++ b/.changelog/37218.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_chatbot_slack_workspace +``` diff --git a/internal/service/chatbot/service_package_gen.go b/internal/service/chatbot/service_package_gen.go index 7b8d9756cec..bfed1d17e95 100644 --- a/internal/service/chatbot/service_package_gen.go +++ b/internal/service/chatbot/service_package_gen.go @@ -13,7 +13,12 @@ import ( type servicePackage struct{} func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.ServicePackageFrameworkDataSource { - return []*types.ServicePackageFrameworkDataSource{} + return []*types.ServicePackageFrameworkDataSource{ + { + Factory: newDataSourceSlackWorkspace, + Name: "Slack Workspace", + }, + } } func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { diff --git a/internal/service/chatbot/slack_workspace_data_source.go b/internal/service/chatbot/slack_workspace_data_source.go new file mode 100644 index 00000000000..82ed1118ef5 --- /dev/null +++ b/internal/service/chatbot/slack_workspace_data_source.go @@ -0,0 +1,104 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package chatbot + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/chatbot" + awstypes "github.com/aws/aws-sdk-go-v2/service/chatbot/types" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkDataSource(name="Slack Workspace") +func newDataSourceSlackWorkspace(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceSlackWorkspace{}, nil +} + +const ( + DSNameSlackWorkspace = "Slack Workspace Data Source" +) + +type dataSourceSlackWorkspace struct { + framework.DataSourceWithConfigure +} + +func (d *dataSourceSlackWorkspace) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { // nosemgrep:ci.meta-in-func-name + resp.TypeName = "aws_chatbot_slack_workspace" +} + +func (d *dataSourceSlackWorkspace) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "slack_team_id": schema.StringAttribute{ + Computed: true, + }, + "slack_team_name": schema.StringAttribute{ + Required: true, + }, + }, + } +} + +func (d *dataSourceSlackWorkspace) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().ChatbotClient(ctx) + + var data dataSourceSlackWorkspaceData + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + out, err := findSlackWorkspaceByName(ctx, conn, data.SlackTeamName.ValueString()) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.Chatbot, create.ErrActionReading, DSNameSlackWorkspace, data.SlackTeamName.String(), err), + err.Error(), + ) + return + } + + data.SlackTeamID = flex.StringToFramework(ctx, out.SlackTeamId) + data.SlackTeamName = flex.StringToFramework(ctx, out.SlackTeamName) + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func findSlackWorkspaceByName(ctx context.Context, conn *chatbot.Client, slack_team_name string) (*awstypes.SlackWorkspace, error) { + input := &chatbot.DescribeSlackWorkspacesInput{ + MaxResults: aws.Int32(10), + } + + for { + output, err := conn.DescribeSlackWorkspaces(ctx, input) + if err != nil { + return nil, err + } + + for _, workspace := range output.SlackWorkspaces { + if aws.ToString(workspace.SlackTeamName) == slack_team_name { + return &workspace, nil + } + } + + if output.NextToken == nil { + break + } + input.NextToken = output.NextToken + } + // If we are here, then we need to return an error that the data source was not found. + return nil, create.Error(names.Chatbot, "missing", DSNameSlackWorkspace, slack_team_name, nil) +} + +type dataSourceSlackWorkspaceData struct { + SlackTeamName types.String `tfsdk:"slack_team_name"` + SlackTeamID types.String `tfsdk:"slack_team_id"` +} diff --git a/internal/service/chatbot/slack_workspace_data_source_test.go b/internal/service/chatbot/slack_workspace_data_source_test.go new file mode 100644 index 00000000000..08cb6b9670f --- /dev/null +++ b/internal/service/chatbot/slack_workspace_data_source_test.go @@ -0,0 +1,58 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package chatbot_test + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccChatbotSlackWorkspaceDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + // TIP: This is a long-running test guard for tests that run longer than + // 300s (5 min) generally. + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + // The slack workspace must be created via the AWS Console. It cannot be created via APIs or Terraform. + // Once it is created, export the name of the workspace in the env variable for this test + key := "CHATBOT_SLACK_WORKSPACE_NAME" + workspace_name := os.Getenv(key) + if workspace_name == "" { + t.Skipf("Environment variable %s is not set", key) + } + + dataSourceName := "data.aws_chatbot_slack_workspace.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ChatbotServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccSlackWorkspaceDataSourceConfig_basic(workspace_name), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "slack_team_name", workspace_name), + resource.TestCheckResourceAttrSet(dataSourceName, "slack_team_id"), + ), + }, + }, + }) +} + +func testAccSlackWorkspaceDataSourceConfig_basic(workspace_name string) string { + return fmt.Sprintf(` +data "aws_chatbot_slack_workspace" "test" { + slack_team_name = "%[1]s" +} +`, workspace_name) +} diff --git a/website/docs/d/chatbot_slack_workspace.html.markdown b/website/docs/d/chatbot_slack_workspace.html.markdown new file mode 100644 index 00000000000..39eed7ced8d --- /dev/null +++ b/website/docs/d/chatbot_slack_workspace.html.markdown @@ -0,0 +1,33 @@ +--- +subcategory: "Chatbot" +layout: "aws" +page_title: "AWS: aws_chatbot_slack_workspace" +description: |- + Terraform data source for managing an AWS Chatbot Slack Workspace. +--- + +# Data Source: aws_chatbot_slack_workspace + +Terraform data source for managing an AWS Chatbot Slack Workspace. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_chatbot_slack_workspace" "example" { + team_slack_name = "abc" +} +``` + +## Argument Reference + +The following arguments are required: + +* `slack_team_name` - (Required) Slack workspace name configured with AWS Chabot. + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `slack_team_id` - ID of the Slack Workspace assigned by AWS Chatbot.