Skip to content

Commit

Permalink
Finishing up ResiliencyPolicy Read/Create and adding a basic acc test
Browse files Browse the repository at this point in the history
  • Loading branch information
YarivLevy81 committed Jun 6, 2022
1 parent 7718e39 commit b72a010
Show file tree
Hide file tree
Showing 5 changed files with 312 additions and 21 deletions.
36 changes: 36 additions & 0 deletions internal/service/resiliencehub/find.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package resiliencehub

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/resiliencehub"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func FindResiliencyPolicyByArn(conn *resiliencehub.ResilienceHub, arn string) (*resiliencehub.ResiliencyPolicy, error) {
input := &resiliencehub.DescribeResiliencyPolicyInput{
PolicyArn: aws.String(arn),
}

output, err := conn.DescribeResiliencyPolicy(input)

if tfawserr.ErrCodeContains(err, resiliencehub.ErrCodeResourceNotFoundException) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

if output == nil || output.Policy == nil {
return nil, &resource.NotFoundError{
Message: "Empty result",
LastRequest: input,
}
}

return output.Policy, nil
}
3 changes: 3 additions & 0 deletions internal/service/resiliencehub/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//go:generate go run ../../generate/tags/main.go -GetTag -ListTags -ServiceTagsMap -UpdateTags

package resiliencehub
163 changes: 142 additions & 21 deletions internal/service/resiliencehub/resiliency_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package resiliencehub

import (
"context"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"log"
"regexp"

"github.com/aws/aws-sdk-go/service/resiliencehub"
Expand All @@ -23,72 +27,127 @@ func ResourceResiliencyPolicy() *schema.Resource {
},

Schema: map[string]*schema.Schema{
"policy_name": {
"arn": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: false,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[A-Za-z\d][A-Za-z\d_\\-]{1,59}$`), "Up to 60 alphanumeric characters, or hyphens, without spaces. The first character must be a letter or a number."),
},
"policy_description": {
Type: schema.TypeString,
Required: false,
ForceNew: false,
ValidateFunc: validation.StringLenBetween(0, 500),
},
"policy": {
Type: schema.TypeSet,
Required: true,
ForceNew: false,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"AZ": FailurePolicy(true),
"Hardware": FailurePolicy(true),
"Software": FailurePolicy(true),
"Region": FailurePolicy(false),
"AZ": failurePolicy(true),
"Hardware": failurePolicy(true),
"Software": failurePolicy(true),
"Region": failurePolicy(false),
},
},
},
"data_location_constraint": {
Type: schema.TypeString,
Required: false,
ForceNew: false,
ValidateFunc: validation.StringInSlice(resiliencehub.DataLocationConstraint_Values(), false),
},
"tier": {
Type: schema.TypeString,
Required: true,
ForceNew: false,
ValidateFunc: validation.StringInSlice(resiliencehub.ResiliencyPolicyTier_Values(), false),
},
"tags": tftags.TagsSchema(),
},
}
}

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

policy := expandPolicy(d.Get("policy").([]interface{}))

input := resiliencehub.CreateResiliencyPolicyInput{
PolicyName: aws.String(d.Get("name").(string)),
Tier: aws.String(d.Get("tier").(string)),
Tags: Tags(tags.IgnoreAWS()),
Policy: policy,
}

input := &resiliencehub.CreateResiliencyPolicyInput{
Policy: data.Get("policy"),
if v, ok := d.GetOk("policy_description"); ok {
input.PolicyDescription = aws.String(v.(string))
}

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

res, err := conn.CreateResiliencyPolicy(&input)
if err != nil {
return diag.Errorf("error creating resiliency policy: %s", err)
}

d.SetId(*res.Policy.PolicyArn)
d.Set("arn", *res.Policy.PolicyArn)
return ResourceResiliencyPolicyRead(ctx, d, meta)
}

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

log.Printf("[DEBUG] Reading ResilienceHub Policy %s", d.Id())
input := resiliencehub.DescribeResiliencyPolicyInput{
PolicyArn: aws.String(d.Get("arn").(string)),
}

resp, err := conn.DescribeResiliencyPolicy(&input)

if err != nil {
if tfawserr.ErrCodeEquals(err, resiliencehub.ErrCodeResourceNotFoundException) {
log.Printf("[WARN] Resilience Hub Resiliency Policy (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

return diag.Errorf("error reading resiliency policy (%s): %s", d.Id(), err)
}

p := *resp.Policy

d.Set("arn", p.PolicyArn)
d.Set("name", p.PolicyName)
d.Set("tier", p.Tier)
d.Set("data_location_constraint", p.DataLocationConstraint)
d.Set("policy_description", p.PolicyDescription)
d.Set("policy", flattenPolicy(p.Policy))

tags := KeyValueTags(p.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))
}

return nil
}

func ResourceResiliencyPolicyUpdate(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).ResilienceHubConn
func ResourceResiliencyPolicyUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
return nil
}

func ResourceResiliencyPolicyDelete(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).ResilienceHubConn
func ResourceResiliencyPolicyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
return nil
}

func FailurePolicy(required bool) *schema.Schema {
func failurePolicy(required bool) *schema.Schema {
return &schema.Schema{
Type: schema.TypeMap,
Required: required,
Expand All @@ -108,3 +167,65 @@ func FailurePolicy(required bool) *schema.Schema {
},
}
}

func expandPolicy(d []interface{}) map[string]*resiliencehub.FailurePolicy {
if len(d) == 0 || d[0] == nil {
return nil
}

policyAsMap := d[0].(map[string]interface{})

failurePolicy := map[string]*resiliencehub.FailurePolicy{
"AZ": expandFailurePolicy(policyAsMap, "AZ"),
"Software": expandFailurePolicy(policyAsMap, "Software"),
"Hardware": expandFailurePolicy(policyAsMap, "Hardware"),
}

if _, ok := policyAsMap["Region"]; ok {
failurePolicy["Region"] = expandFailurePolicy(policyAsMap, "Region")
}

return failurePolicy
}

func expandFailurePolicy(policyMap map[string]interface{}, key string) *resiliencehub.FailurePolicy {
fPolicy := policyMap[key].(map[string]interface{})

rtoInSecs := fPolicy["rtoInSecs"].(int64)
rpoInSecs := fPolicy["rtoInSecs"].(int64)

return &resiliencehub.FailurePolicy{
RpoInSecs: &rpoInSecs,
RtoInSecs: &rtoInSecs,
}
}

func flattenPolicy(policy map[string]*resiliencehub.FailurePolicy) map[string]interface{} {
var tfMap map[string]interface{}

azFailurePolicy := policy["AZ"]
hardwareFailurePolicy := policy["Hardware"]
softwareFailurePolicy := policy["Software"]

tfMap["AZ"] = flattenFailurePolicy(azFailurePolicy)
tfMap["Hardware"] = flattenFailurePolicy(hardwareFailurePolicy)
tfMap["Software"] = flattenFailurePolicy(softwareFailurePolicy)

if regionFailurePolicy, ok := policy["Region"]; ok {
tfMap["Region"] = flattenFailurePolicy(regionFailurePolicy)
}

return tfMap
}

func flattenFailurePolicy(failurePolicy *resiliencehub.FailurePolicy) map[string]interface{} {
var tfMap map[string]interface{}

rtoInSecs := failurePolicy.RtoInSecs
rpoInSecs := failurePolicy.RpoInSecs

tfMap["rtoInSecs"] = rtoInSecs
tfMap["rpoInSecs"] = rpoInSecs

return tfMap
}
36 changes: 36 additions & 0 deletions internal/service/resiliencehub/resiliency_policy_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,37 @@
package resiliencehub

import (
"context"
"github.com/aws/aws-sdk-go/service/account"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
)

func TestAccResiliencyPolicy_basic(t *testing.T) {
resourceName := "aws_resiliency_policy.test"
resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, account.EndpointsID),
ProviderFactories: acctest.ProviderFactories,
CheckDestroy: nil,
Steps: nil,
})
}

func testResiliencyPolicyDestroy(s *terraform.State) {
ctx := context.TODO()
conn := acctest.Provider.Meta().(*conns.AWSClient).ResilienceHubConn

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_resiliency_policy" {
continue
}

}

return nil
}
Loading

0 comments on commit b72a010

Please sign in to comment.