Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding GlobalSettings resource for Amazon Chime SDK voice connector #31365

Merged
3 changes: 3 additions & 0 deletions .changelog/31365.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_chimesdkvoice_global_settings
```
145 changes: 145 additions & 0 deletions internal/service/chimesdkvoice/global_settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package chimesdkvoice

import (
"context"
"errors"
"log"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/chimesdkvoice"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/create"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/names"
)

const (
ResNameGlobalSettings = "Global Settings"
globalSettingsPropagationTimeout = time.Second * 10
)

// @SDKResource("aws_chimesdkvoice_global_settings")
func ResourceGlobalSettings() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceGlobalSettingsUpdate,
ReadWithoutTimeout: resourceGlobalSettingsRead,
UpdateWithoutTimeout: resourceGlobalSettingsUpdate,
DeleteWithoutTimeout: resourceGlobalSettingsDelete,

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

Schema: map[string]*schema.Schema{
"voice_connector": {
Type: schema.TypeList,
MaxItems: 1,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cdr_bucket": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
},
}
}

func resourceGlobalSettingsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).ChimeSDKVoiceConn()

// Include retry handling to allow for propagation of the Global Settings
// logging bucket configuration
var out *chimesdkvoice.GetGlobalSettingsOutput
err := tfresource.Retry(ctx, globalSettingsPropagationTimeout, func() *retry.RetryError {
var getErr error
out, getErr = conn.GetGlobalSettingsWithContext(ctx, &chimesdkvoice.GetGlobalSettingsInput{})
if getErr != nil {
return retry.NonRetryableError(getErr)
}
if out.VoiceConnector == nil {
return retry.RetryableError(tfresource.NewEmptyResultError(&chimesdkvoice.GetGlobalSettingsInput{}))
}

return nil
})

var ere *tfresource.EmptyResultError
if !d.IsNewResource() && errors.As(err, &ere) {
log.Printf("[WARN] ChimeSDKVoice GlobalSettings (%s) not found, removing from state", d.Id())
d.SetId("")
return diags
}

if err != nil {
return append(diags, create.DiagError(names.ChimeSDKVoice, create.ErrActionReading, ResNameGlobalSettings, d.Id(), err)...)
}

d.SetId(meta.(*conns.AWSClient).AccountID)
d.Set("voice_connector", flattenVoiceConnectorSettings(out.VoiceConnector))

return diags
}

func resourceGlobalSettingsUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).ChimeSDKVoiceConn()

if d.HasChange("voice_connector") {
input := &chimesdkvoice.UpdateGlobalSettingsInput{
VoiceConnector: expandVoiceConnectorSettings(d.Get("voice_connector").([]interface{})),
}

_, err := conn.UpdateGlobalSettingsWithContext(ctx, input)
if err != nil {
return append(diags, create.DiagError(names.ChimeSDKVoice, create.ErrActionUpdating, ResNameGlobalSettings, d.Id(), err)...)
}
}
d.SetId(meta.(*conns.AWSClient).AccountID)

return append(diags, resourceGlobalSettingsRead(ctx, d, meta)...)
}

func resourceGlobalSettingsDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).ChimeSDKVoiceConn()

_, err := conn.UpdateGlobalSettingsWithContext(ctx, &chimesdkvoice.UpdateGlobalSettingsInput{
VoiceConnector: &chimesdkvoice.VoiceConnectorSettings{},
})
if err != nil {
return append(diags, create.DiagError(names.ChimeSDKVoice, create.ErrActionDeleting, ResNameGlobalSettings, d.Id(), err)...)
}

return diags
}

func expandVoiceConnectorSettings(tfList []interface{}) *chimesdkvoice.VoiceConnectorSettings {
if len(tfList) == 0 {
return nil
}

tfMap, ok := tfList[0].(map[string]interface{})
if !ok {
return nil
}

return &chimesdkvoice.VoiceConnectorSettings{
CdrBucket: aws.String(tfMap["cdr_bucket"].(string)),
}
}

func flattenVoiceConnectorSettings(apiObject *chimesdkvoice.VoiceConnectorSettings) []interface{} {
m := map[string]interface{}{
"cdr_bucket": aws.StringValue(apiObject.CdrBucket),
}
return []interface{}{m}
}
156 changes: 156 additions & 0 deletions internal/service/chimesdkvoice/global_settings_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package chimesdkvoice_test

import (
"context"
"errors"
"fmt"
"testing"
"time"

"github.com/aws/aws-sdk-go/service/chimesdkvoice"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tfchimesdkvoice "github.com/hashicorp/terraform-provider-aws/internal/service/chimesdkvoice"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
)

func TestAccChimeSDKVoiceGlobalSettings_serial(t *testing.T) {
t.Parallel()

testCases := map[string]func(t *testing.T){
"basic": testAccGlobalSettings_basic,
"disappears": testAccGlobalSettings_disappears,
"update": testAccGlobalSettings_update,
}

acctest.RunSerialTests1Level(t, testCases, 0)
}

func testAccGlobalSettings_basic(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_chimesdkvoice_global_settings.test"
bucketResourceName := "aws_s3_bucket.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, chimesdkvoice.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckGlobalSettingsDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccGlobalSettingsConfig_basic(rName),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrPair(resourceName, "voice_connector.0.cdr_bucket", bucketResourceName, "id"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccGlobalSettings_disappears(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_chimesdkvoice_global_settings.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, chimesdkvoice.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckGlobalSettingsDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccGlobalSettingsConfig_basic(rName),
Check: resource.ComposeAggregateTestCheckFunc(
acctest.CheckResourceDisappears(ctx, acctest.Provider, tfchimesdkvoice.ResourceGlobalSettings(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccGlobalSettings_update(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
rNameUpdated := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_chimesdkvoice_global_settings.test"
bucketResourceName := "aws_s3_bucket.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, chimesdkvoice.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckGlobalSettingsDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccGlobalSettingsConfig_basic(rName),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrPair(resourceName, "voice_connector.0.cdr_bucket", bucketResourceName, "id"),
),
},
// Note: due to eventual consistency, the read after update can occasionally
// return the previous cdr_bucket name, causing this test to fail. Running
// in us-east-1 produces the most consistent results.
{
Config: testAccGlobalSettingsConfig_basic(rNameUpdated),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrPair(resourceName, "voice_connector.0.cdr_bucket", bucketResourceName, "id"),
),
},
},
})
}

func testAccCheckGlobalSettingsDestroy(ctx context.Context) resource.TestCheckFunc {
return func(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_chimesdkvoice_global_settings" {
continue
}

conn := acctest.Provider.Meta().(*conns.AWSClient).ChimeSDKVoiceConn()
input := &chimesdkvoice.GetGlobalSettingsInput{}

const retryTimeout = 10 * time.Second
response := &chimesdkvoice.GetGlobalSettingsOutput{}

err := tfresource.Retry(ctx, retryTimeout, func() *retry.RetryError {
var err error
response, err = conn.GetGlobalSettingsWithContext(ctx, input)
if err == nil && response.VoiceConnector.CdrBucket != nil {
return retry.RetryableError(errors.New("error Chime Voice Connector Global settings still exists"))
}
return nil
})

if err != nil {
return fmt.Errorf("error Chime Voice Connector Global settings still exists")
}
}
return nil
}
}

func testAccGlobalSettingsConfig_basic(rName string) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "test" {
bucket = %[1]q
}

resource "aws_chimesdkvoice_global_settings" "test" {
voice_connector {
cdr_bucket = aws_s3_bucket.test.id
}
}
`, rName)
}
4 changes: 4 additions & 0 deletions internal/service/chimesdkvoice/service_package_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 49 additions & 0 deletions website/docs/r/chimesdkvoice_global_settings.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
subcategory: "Chime SDK Voice"
layout: "aws"
page_title: "AWS: aws_chimesdkvoice_global_settings"
description: |-
Terraform resource for managing Amazon Chime SDK Voice Global Settings.
---

# Resource: aws_chimesdkvoice_global_settings

Terraform resource for managing Amazon Chime SDK Voice Global Settings.

## Example Usage

### Basic Usage

```terraform
resource "aws_chimesdkvoice_global_settings" "example" {
voice_connector {
cdr_bucket = "example-bucket-name"
}
}
```

## Argument Reference

The following arguments are supported:

* `voice_connector` - (Required) The Voice Connector settings. See [voice_connector](#voice_connector).

### `voice_connector`

The Amazon Chime SDK Voice Connector settings. Includes any Amazon S3 buckets designated for storing call detail records.

* `cdr_bucket` - (Optional) The S3 bucket that stores the Voice Connector's call detail records.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:

* `id` - AWS account ID for which the settings are applied.

## Import

AWS Chime SDK Voice Global Settings can be imported using the `id` (AWS account ID), e.g.,

```
$ terraform import aws_chimesdkvoice_global_settings.example 123456789012
```