-
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
fix for dynamodb autoscaling policy import #8397
Conversation
@jdecarli thanks for contributing a fix for issue #8306. Quickly looking at the PR, the change looks reasonable but I’ve not officially verified or tested. With that said, the issue states a failure that does not seem to be represented in the tests. Would you please add the accompanying tests to showcase that the following issue has been fixed.
See our contributing guide for help with writing tests for the provider. Cheers! |
Thanks for your quick response! Sure @nywilken I'll work on that |
@nywilken I did some refactor and added a unit test specifically for the fix. Acceptance tests: make testacc TEST=./aws/ TESTARGS='-run=TestValidateAppautoscalingPolicyImportInput'
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./aws/ -v -parallel 20 -run=TestValidateAppautoscalingPolicyImportInput -timeout 120m
=== RUN TestValidateAppautoscalingPolicyImportInput
--- PASS: TestValidateAppautoscalingPolicyImportInput (0.00s)
PASS
ok github.com/terraform-providers/terraform-provider-aws/aws 0.137s Please, let me know if anything else is required. Thanks! |
Hi @nywilken does this pr requires anything else in order for merge? I can add any missing piece |
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.
Hi @jdecarli apologies for the long delay on feedback. The team and I have been focused on TF 0.12 related items the past few weeks. Thank you for sticking with us and for your work on this issue.
I've had a chance to pull down your changes and test. Are you able to run the acceptance tests?
In running the acceptance tests make testacc TESTARGS="-run=TestAccAWSAppautoScalingPolicy_dynamoDb"
I get an index out of bounds error on line #441
I've left some suggested changes, and a couple of questions for you. Please let me know if you have any questions or need help implementing the suggested changes.
@nywilken I think I've addressed all suggested changes. Changes:
Please let me know if there's anything else needed? |
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 comment
The reason will be displayed to describe this comment to others. Learn more.
just checked the doc (aws application-autoscaling describe-scaling-policies help
).
resourceId
may contain from 0 to 3 "/" charactersscalableDimension
seems to be without "/"policyName
can also contain variable number of "/": 0-3
It would be almost better to
- choose different field delimiter
- or, import by
serviceNamespace/policyName
(if it is unique in namespace) - or, import by ARN
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.
Hi @zarnovican
Regarding your suggestions...
Choose different field delimiter
If 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 TestValidateAppautoscalingPolicyImportInput_positiveCases
and TestValidateAppautoscalingPolicyImportInput_negativeCases
.
I might be wrong (I'm really new to golang), but as far as I can see the only possible delimiter is /
(this is the input coming from the import command) and the problem is, as you mention, that it varies depending on the serviceNamespace
. This is basically the root of the issue this pr tries to resolve.
Another option I found is to leave the code as it is, truncating the last item in the slice idParts
which is the tableName
(which also happens to be redundant, because its coming as the third element in the slice). But this will also force us to append this tableName
element to the policy, and this will look pretty ugly in the code with something like this:
// 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.
@jdecarli I’m catching up with pending reviews - thanks for continuing to push this forward and for sticking with me. Give me a day to review and think about the latest comments. |
Hi @nywilken Sorry for pinging again, I just don't want this pr to drift away too much from the codebase Do you think we need to add anything else? |
@@ -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 comment
The 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 expectedError
field to assert that the input validation should fail when expected.
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, "/"))
}
}
}
@@ -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 |
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?
func resourceAwsAppautoscalingPolicyImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
idParts, err := validateAppautoscalingPolicyImportInput(d.Id())
if err != nil {
return nil, fmt.Errorf("unexpected format (%q), expected <service-namespace>/<resource-id>/<scalable-dimension>/<policy-name>", d.Id())
}
serviceNamespace := idParts[0]
resourceId := idParts[1]
scalableDimension := idParts[2]
policyName := idParts[3]
d.Set("service_namespace", serviceNamespace)
d.Set("resource_id", resourceId)
d.Set("scalable_dimension", scalableDimension)
d.Set("name", policyName)
d.SetId(policyName)
return []*schema.ResourceData{d}, nil
}
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.
Hi @jdecarli apologies for the long review cycle. I've been away for a couple of weeks. The changes work as expected, thanks for the update. I made a few suggestions around the code itself in an effort simplify things a bit and follow some idiomatic Go constructs for testings. Take a look and let me know if you have any questions.
We should also rebase on to the latest master. |
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.
LGTM! Those IDs are wild, but nice work on the handling and testing!
The fix to the For further feature requests or bug reports with this resource, please create a new GitHub issue following the template for triage. Thanks! |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks! |
Community Note
Fixes #8306
Changes proposed in this pull request: