Skip to content

Commit

Permalink
r/aws_connect_security_profile (#22369)
Browse files Browse the repository at this point in the history
* feat(connect): add SecurityProfile schema

* feat(connect): add SecurityProfile read

* feat(connect): add SecurityProfile create

* feat(connect): add SecurityProfile update

* feat(connect): add SecurityProfile delete

* feat(connect): add aws_connect_security_profile

* test(connect): config for SecurityProfile

* test(connect): check SecurityProfile exists

* test(connect): check SecurityProfile destroy

* test(connect): SecurityProfile create, update

* test(connect): SecurityProfile disappear

* test(connect): serialize SecurityProfile test

* style(connect): order schema attributes

* docs(connect): add aws_connect_security_profile

* test(connect): temp comment out disappears test

* ci(connect): changelog for SecurityProfile

* test(connect): uncomment disappears test
  • Loading branch information
GlennChia committed Jan 25, 2022
1 parent 865bb33 commit 5a326ca
Show file tree
Hide file tree
Showing 5 changed files with 498 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/22369.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_connect_security_profile
```
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,7 @@ func Provider() *schema.Provider {
"aws_connect_lambda_function_association": connect.ResourceLambdaFunctionAssociation(),
"aws_connect_queue": connect.ResourceQueue(),
"aws_connect_quick_connect": connect.ResourceQuickConnect(),
"aws_connect_security_profile": connect.ResourceSecurityProfile(),

"aws_cur_report_definition": cur.ResourceReportDefinition(),

Expand Down
232 changes: 232 additions & 0 deletions internal/service/connect/security_profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
package connect

import (
"context"
"fmt"
"log"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/connect"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"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"
"github.com/hashicorp/terraform-provider-aws/internal/flex"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
)

func ResourceSecurityProfile() *schema.Resource {
return &schema.Resource{
CreateContext: resourceSecurityProfileCreate,
ReadContext: resourceSecurityProfileRead,
UpdateContext: resourceSecurityProfileUpdate,
DeleteContext: resourceSecurityProfileDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringLenBetween(1, 250),
},
"instance_id": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringLenBetween(1, 100),
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"organization_resource_id": {
Type: schema.TypeString,
Computed: true,
},
"permissions": {
Type: schema.TypeSet,
Optional: true,
MaxItems: 500,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringLenBetween(1, 128),
},
},
"security_profile_id": {
Type: schema.TypeString,
Computed: true,
},
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
},
}
}

func resourceSecurityProfileCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).ConnectConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{})))

instanceID := d.Get("instance_id").(string)
securityProfileName := d.Get("name").(string)

input := &connect.CreateSecurityProfileInput{
InstanceId: aws.String(instanceID),
SecurityProfileName: aws.String(securityProfileName),
}

if v, ok := d.GetOk("description"); ok {
input.Description = aws.String(v.(string))
}

if v, ok := d.GetOk("permissions"); ok && v.(*schema.Set).Len() > 0 {
input.Permissions = flex.ExpandStringSet(v.(*schema.Set))
}

if len(tags) > 0 {
input.Tags = Tags(tags.IgnoreAWS())
}

log.Printf("[DEBUG] Creating Connect Security Profile %s", input)
output, err := conn.CreateSecurityProfileWithContext(ctx, input)

if err != nil {
return diag.FromErr(fmt.Errorf("error creating Connect Security Profile (%s): %w", securityProfileName, err))
}

if output == nil {
return diag.FromErr(fmt.Errorf("error creating Connect Security Profile (%s): empty output", securityProfileName))
}

d.SetId(fmt.Sprintf("%s:%s", instanceID, aws.StringValue(output.SecurityProfileId)))

return resourceSecurityProfileRead(ctx, d, meta)
}

func resourceSecurityProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).ConnectConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

instanceID, securityProfileID, err := SecurityProfileParseID(d.Id())

if err != nil {
return diag.FromErr(err)
}

resp, err := conn.DescribeSecurityProfileWithContext(ctx, &connect.DescribeSecurityProfileInput{
InstanceId: aws.String(instanceID),
SecurityProfileId: aws.String(securityProfileID),
})

if !d.IsNewResource() && tfawserr.ErrMessageContains(err, connect.ErrCodeResourceNotFoundException, "") {
log.Printf("[WARN] Connect Security Profile (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return diag.FromErr(fmt.Errorf("error getting Connect Security Profile (%s): %w", d.Id(), err))
}

if resp == nil || resp.SecurityProfile == nil {
return diag.FromErr(fmt.Errorf("error getting Connect Security Profile (%s): empty response", d.Id()))
}

d.Set("arn", resp.SecurityProfile.Arn)
d.Set("description", resp.SecurityProfile.Description)
d.Set("instance_id", instanceID)
d.Set("organization_resource_id", resp.SecurityProfile.OrganizationResourceId)
d.Set("security_profile_id", resp.SecurityProfile.Id)
d.Set("name", resp.SecurityProfile.SecurityProfileName)
// NOTE: The response does not return information about the permissions

tags := KeyValueTags(resp.SecurityProfile.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig)

//lintignore:AWSR002
if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil {
return diag.FromErr(fmt.Errorf("error setting tags: %w", err))
}

if err := d.Set("tags_all", tags.Map()); err != nil {
return diag.FromErr(fmt.Errorf("error setting tags_all: %w", err))
}

return nil
}

func resourceSecurityProfileUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).ConnectConn

instanceID, securityProfileID, err := SecurityProfileParseID(d.Id())

if err != nil {
return diag.FromErr(err)
}

input := &connect.UpdateSecurityProfileInput{
InstanceId: aws.String(instanceID),
SecurityProfileId: aws.String(securityProfileID),
}

if d.HasChange("description") {
input.Description = aws.String(d.Get("description").(string))
}

if d.HasChange("permissions") {
input.Permissions = flex.ExpandStringSet(d.Get("permissions").(*schema.Set))
}

_, err = conn.UpdateSecurityProfileWithContext(ctx, input)

if err != nil {
return diag.FromErr(fmt.Errorf("[ERROR] Error updating SecurityProfile (%s): %w", d.Id(), err))
}

if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")
if err := UpdateTags(conn, d.Id(), o, n); err != nil {
return diag.FromErr(fmt.Errorf("error updating tags: %w", err))
}
}

return resourceSecurityProfileRead(ctx, d, meta)
}

func resourceSecurityProfileDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).ConnectConn

instanceID, securityProfileID, err := SecurityProfileParseID(d.Id())

if err != nil {
return diag.FromErr(err)
}

_, err = conn.DeleteSecurityProfileWithContext(ctx, &connect.DeleteSecurityProfileInput{
InstanceId: aws.String(instanceID),
SecurityProfileId: aws.String(securityProfileID),
})

if err != nil {
return diag.FromErr(fmt.Errorf("error deleting SecurityProfile (%s): %w", d.Id(), err))
}

return nil
}

func SecurityProfileParseID(id string) (string, string, error) {
parts := strings.SplitN(id, ":", 2)

if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return "", "", fmt.Errorf("unexpected format of ID (%s), expected instanceID:securityProfileID", id)
}

return parts[0], parts[1], nil
}
Loading

0 comments on commit 5a326ca

Please sign in to comment.