-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
fix for dynamodb autoscaling policy import #8397
Changes from 6 commits
6f4e59b
8e280ed
ca98ae3
c4f2e1e
b0e095c
7d86d43
7ecc6c1
a04400e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -407,18 +407,13 @@ func resourceAwsAppautoscalingPolicyDelete(d *schema.ResourceData, meta interfac | |
|
||
func resourceAwsAppautoscalingPolicyImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { | ||
idParts := strings.Split(d.Id(), "/") | ||
var serviceNamespace, resourceId, scalableDimension, policyName string | ||
var err error | ||
|
||
if len(idParts) < 4 { | ||
return nil, fmt.Errorf("unexpected format (%q), expected <service-namespace>/<resource-id>/<scalable-dimension>/<policy-name>", d.Id()) | ||
} | ||
|
||
serviceNamespace := idParts[0] | ||
resourceId := strings.Join(idParts[1:len(idParts)-2], "/") | ||
scalableDimension := idParts[len(idParts)-2] | ||
policyName := idParts[len(idParts)-1] | ||
serviceNamespace, resourceId, scalableDimension, policyName, err = validateAppautoscalingPolicyImportInput(idParts) | ||
|
||
if serviceNamespace == "" || resourceId == "" || scalableDimension == "" || policyName == "" { | ||
return nil, fmt.Errorf("unexpected format (%q), expected <service-namespace>/<resource-id>/<scalable-dimension>/<policy-name>", d.Id()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
d.Set("service_namespace", serviceNamespace) | ||
|
@@ -430,6 +425,33 @@ func resourceAwsAppautoscalingPolicyImport(d *schema.ResourceData, meta interfac | |
return []*schema.ResourceData{d}, nil | ||
} | ||
|
||
func validateAppautoscalingPolicyImportInput(idParts []string) (string, string, string, string, error) { | ||
var serviceNamespace, resourceId, scalableDimension, policyName string | ||
|
||
if len(idParts) < 4 || len(idParts) > 6 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just checked the doc (
It would be almost better to
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @zarnovican Regarding your suggestions... Choose different field delimiterIf you check the Terraform import documentation you will see the format Terraform chose for the input in all 3 cases (ecs, rds and dynamodb). Acording to that format, I also made 2 unit tests in I might be wrong (I'm really new to golang), but as far as I can see the only possible delimiter is Another option I found is to leave the code as it is, truncating the last item in the slice // truncating last redundant element
if idParts[0] == "dynamodb" {
idParts = idParts[:len(idParts) -1]
}
serviceNamespace = idParts[0]
resourceId = strings.Join(idParts[1:len(idParts)-2], "/")
scalableDimension = idParts[len(idParts)-2]
policyName = idParts[len(idParts)-1]
// appending tableName to the policy
if idParts[0] == "dynamodb" {
policyName = policyName + "/" + idParts[2]
} It removes the need for the switch, but adds the truncating and appending. Import by other fields (serviceNamespace/policyName or ARN)I think this involves design changes that are out of scope for this issue. Seems like a nice suggestion, but I feel is up to the Terraform team to do some analysis on this. Maybe @nywilken can shed some light on this. |
||
return serviceNamespace, resourceId, scalableDimension, policyName, fmt.Errorf("unexpected format (%q), expected <service-namespace>/<resource-id>/<scalable-dimension>/<policy-name>", idParts[0]) | ||
} | ||
|
||
switch idParts[0] { | ||
nywilken marked this conversation as resolved.
Show resolved
Hide resolved
|
||
case "ecs", "rds": | ||
serviceNamespace = idParts[0] | ||
resourceId = strings.Join(idParts[1:len(idParts)-2], "/") | ||
scalableDimension = idParts[len(idParts)-2] | ||
policyName = idParts[len(idParts)-1] | ||
case "dynamodb": | ||
serviceNamespace = idParts[0] | ||
resourceId = strings.Join(idParts[1:3], "/") | ||
scalableDimension = idParts[len(idParts)-3] | ||
policyName = strings.Join(idParts[4:], "/") | ||
} | ||
|
||
if serviceNamespace == "" || resourceId == "" || scalableDimension == "" || policyName == "" { | ||
return serviceNamespace, resourceId, scalableDimension, policyName, fmt.Errorf("unexpected format (%q), expected <service-namespace>/<resource-id>/<scalable-dimension>/<policy-name>", idParts[0]) | ||
} | ||
|
||
return serviceNamespace, resourceId, scalableDimension, policyName, nil | ||
} | ||
|
||
// Takes the result of flatmap.Expand for an array of step adjustments and | ||
// returns a []*applicationautoscaling.StepAdjustment. | ||
func expandAppautoscalingStepAdjustments(configured []interface{}) ([]*applicationautoscaling.StepAdjustment, error) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ package aws | |
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
|
@@ -11,6 +12,85 @@ import ( | |
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestValidateAppautoscalingPolicyImportInput_positiveCases(t *testing.T) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's a slightly different version of these tests. This refactor combines the test cases into one function and relies on an func TestValidateAppautoscalingPolicyImportInput(t *testing.T) {
testCases := []struct {
input string
errorExpected bool
expected []string
}{
{
input: "rds/cluster:id/rds:cluster:ReadReplicaCount/cpu-auto-scaling",
expected: []string{"rds", "cluster:id", "rds:cluster:ReadReplicaCount", "cpu-auto-scaling"},
errorExpected: false,
},
{
input: "ecs/service/clusterName/serviceName/ecs:service:DesiredCount/scale-down",
expected: []string{"ecs", "service/clusterName/serviceName", "ecs:service:DesiredCount", "scale-down"},
errorExpected: false,
},
{
input: "dynamodb/table/tableName/dynamodb:table:ReadCapacityUnits/DynamoDBReadCapacityUtilization:table/tableName",
expected: []string{"dynamodb", "table/tableName", "dynamodb:table:ReadCapacityUnits", "DynamoDBReadCapacityUtilization:table/tableName"},
errorExpected: false,
},
{
input: "dynamodb/missing/parts",
errorExpected: true,
},
}
for _, tc := range testCases {
idParts, err := validateAppautoscalingPolicyImportInput(tc.input)
if tc.errorExpected == false && err != nil {
t.Errorf("validateAppautoscalingPolicyImportInput(%q): resulted in an unexpected error: %s", tc.input, err)
}
if tc.errorExpected == true && err == nil {
t.Errorf("validateAppautoscalingPolicyImportInput(%q): expected an error, but returned successfully", tc.input)
}
if !reflect.DeepEqual(tc.expected, idParts) {
t.Errorf("validateAppautoscalingPolicyImportInput(%q): expected %q, but got %q", tc.input, strings.Join(tc.expected, "/"), strings.Join(idParts, "/"))
}
}
} |
||
testCases := []struct { | ||
input string | ||
expectedServiceNamespace string | ||
expectedResourceId string | ||
expectedScalableDimension string | ||
expectedPolicyName string | ||
}{ | ||
{ | ||
"rds/cluster:id/rds:cluster:ReadReplicaCount/cpu-auto-scaling", | ||
"rds", "cluster:id", "rds:cluster:ReadReplicaCount", "cpu-auto-scaling"}, | ||
{ | ||
"ecs/service/clusterName/serviceName/ecs:service:DesiredCount/scale-down", | ||
"ecs", "service/clusterName/serviceName", "ecs:service:DesiredCount", "scale-down"}, | ||
{ | ||
"dynamodb/table/tableName/dynamodb:table:ReadCapacityUnits/DynamoDBReadCapacityUtilization:table/tableName", | ||
"dynamodb", "table/tableName", "dynamodb:table:ReadCapacityUnits", "DynamoDBReadCapacityUtilization:table/tableName"}, | ||
} | ||
|
||
for _, test := range testCases { | ||
idParts := strings.Split(test.input, "/") | ||
serviceNamespace, resourceId, scalableDimension, policyName, err := validateAppautoscalingPolicyImportInput(idParts) | ||
|
||
if err != nil || serviceNamespace != test.expectedServiceNamespace { | ||
t.Errorf("serviceNamespace interpolation error -> %s != %s", test.expectedServiceNamespace, serviceNamespace) | ||
} | ||
if err != nil && resourceId != test.expectedResourceId { | ||
t.Errorf("resourceId interpolation error -> %s != %s", test.expectedResourceId, resourceId) | ||
} | ||
if err != nil || scalableDimension != test.expectedScalableDimension { | ||
t.Errorf("scalableDimension interpolation error -> %s != %s", test.expectedScalableDimension, scalableDimension) | ||
} | ||
if err != nil || policyName != test.expectedPolicyName { | ||
t.Errorf("policyName interpolation error -> %s != %s", test.expectedPolicyName, policyName) | ||
} | ||
} | ||
} | ||
|
||
func TestValidateAppautoscalingPolicyImportInput_negativeCases(t *testing.T) { | ||
testCases := []struct { | ||
input string | ||
expectedServiceNamespace string | ||
expectedResourceId string | ||
expectedScalableDimension string | ||
expectedPolicyName string | ||
}{ | ||
{ | ||
"wrongValue", | ||
"", "", "", ""}, | ||
{ | ||
"", | ||
"", "", "", ""}, | ||
{ | ||
"too/many/arguments/that/are/not/required", | ||
"", "", "", ""}, | ||
} | ||
|
||
for _, test := range testCases { | ||
idParts := strings.Split(test.input, "/") | ||
serviceNamespace, resourceId, scalableDimension, policyName, err := validateAppautoscalingPolicyImportInput(idParts) | ||
|
||
if err == nil || serviceNamespace != test.expectedServiceNamespace { | ||
t.Errorf("serviceNamespace interpolation error -> %s != %s", test.expectedServiceNamespace, serviceNamespace) | ||
} | ||
if err == nil || resourceId != test.expectedResourceId { | ||
t.Errorf("resourceId interpolation error -> %s != %s", test.expectedResourceId, resourceId) | ||
} | ||
if err == nil || scalableDimension != test.expectedScalableDimension { | ||
t.Errorf("scalableDimension interpolation error -> %s != %s", test.expectedScalableDimension, scalableDimension) | ||
} | ||
if err == nil || policyName != test.expectedPolicyName { | ||
t.Errorf("policyName interpolation error -> %s != %s", test.expectedPolicyName, policyName) | ||
} | ||
if err != nil && err.Error() == "" { | ||
t.Errorf("empty error -> error should describe outcome") | ||
} | ||
} | ||
} | ||
|
||
func TestAccAWSAppautoScalingPolicy_basic(t *testing.T) { | ||
var policy applicationautoscaling.ScalingPolicy | ||
appAutoscalingTargetResourceName := "aws_appautoscaling_target.test" | ||
|
@@ -184,7 +264,8 @@ func TestAccAWSAppautoScalingPolicy_dynamoDb(t *testing.T) { | |
Config: testAccAWSAppautoscalingPolicyDynamoDB(randPolicyName), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSAppautoscalingPolicyExists("aws_appautoscaling_policy.dynamo_test", &policy), | ||
resource.TestCheckResourceAttr("aws_appautoscaling_policy.dynamo_test", "name", randPolicyName), | ||
resource.TestCheckResourceAttr("aws_appautoscaling_policy.dynamo_test", "name", fmt.Sprintf("DynamoDBWriteCapacityUtilization:table/%s", randPolicyName)), | ||
resource.TestCheckResourceAttr("aws_appautoscaling_policy.dynamo_test", "policy_type", "TargetTrackingScaling"), | ||
resource.TestCheckResourceAttr("aws_appautoscaling_policy.dynamo_test", "service_namespace", "dynamodb"), | ||
resource.TestCheckResourceAttr("aws_appautoscaling_policy.dynamo_test", "scalable_dimension", "dynamodb:table:WriteCapacityUnits"), | ||
), | ||
|
@@ -527,7 +608,7 @@ resource "aws_appautoscaling_target" "dynamo_test" { | |
} | ||
|
||
resource "aws_appautoscaling_policy" "dynamo_test" { | ||
name = "%s" | ||
name = "DynamoDBWriteCapacityUtilization:${aws_appautoscaling_target.dynamo_test.resource_id}" | ||
policy_type = "TargetTrackingScaling" | ||
service_namespace = "dynamodb" | ||
resource_id = "table/${aws_dynamodb_table.dynamodb_table_test.name}" | ||
|
@@ -545,7 +626,7 @@ resource "aws_appautoscaling_policy" "dynamo_test" { | |
|
||
depends_on = ["aws_appautoscaling_target.dynamo_test"] | ||
} | ||
`, randPolicyName, randPolicyName) | ||
`, randPolicyName) | ||
} | ||
|
||
func testAccAWSAppautoscalingPolicy_multiplePoliciesSameName(tableName1, tableName2, namePrefix string) string { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about moving all this string splitting logic into
validateAppautoscalingPolicyImportInput
to help simplify the Import function?