mirror of https://github.com/hashicorp/terraform
parent
2fda09aab2
commit
454eed63e7
@ -0,0 +1,26 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
)
|
||||
|
||||
// diagnosticComparer is a Comparer function for use with cmp.Diff to compare two tfdiags.Diagnostic values
|
||||
func diagnosticComparer(l, r tfdiags.Diagnostic) bool {
|
||||
if l.Severity() != r.Severity() {
|
||||
return false
|
||||
}
|
||||
if l.Description() != r.Description() {
|
||||
return false
|
||||
}
|
||||
|
||||
lp := tfdiags.GetAttribute(l)
|
||||
rp := tfdiags.GetAttribute(r)
|
||||
if len(lp) != len(rp) {
|
||||
return false
|
||||
}
|
||||
if !lp.Equals(rp) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/arn"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
const (
|
||||
multiRegionKeyIdPattern = `mrk-[a-f0-9]{32}`
|
||||
uuidRegexPattern = `[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[ab89][a-f0-9]{3}-[a-f0-9]{12}`
|
||||
)
|
||||
|
||||
func validateKMSKey(path cty.Path, s string) (diags tfdiags.Diagnostics) {
|
||||
if arn.IsARN(s) {
|
||||
return validateKMSKeyARN(path, s)
|
||||
}
|
||||
return validateKMSKeyID(path, s)
|
||||
}
|
||||
|
||||
func validateKMSKeyID(path cty.Path, s string) (diags tfdiags.Diagnostics) {
|
||||
keyIdRegex := regexp.MustCompile(`^` + uuidRegexPattern + `|` + multiRegionKeyIdPattern + `$`)
|
||||
if !keyIdRegex.MatchString(s) {
|
||||
diags = diags.Append(tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ID",
|
||||
fmt.Sprintf("Value must be a valid KMS Key ID, got %q", s),
|
||||
path,
|
||||
))
|
||||
return diags
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
func validateKMSKeyARN(path cty.Path, s string) (diags tfdiags.Diagnostics) {
|
||||
if _, err := arn.Parse(s); err != nil {
|
||||
diags = diags.Append(tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ARN",
|
||||
fmt.Sprintf("Value must be a valid KMS Key ARN, got %q", s),
|
||||
path,
|
||||
))
|
||||
return diags
|
||||
}
|
||||
|
||||
if !isKeyARN(s) {
|
||||
diags = diags.Append(tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ARN",
|
||||
fmt.Sprintf("Value must be a valid KMS Key ARN, got %q", s),
|
||||
path,
|
||||
))
|
||||
return diags
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
func isKeyARN(s string) bool {
|
||||
parsedARN, err := arn.Parse(s)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return keyIdFromARNResource(parsedARN.Resource) != ""
|
||||
}
|
||||
|
||||
func keyIdFromARNResource(s string) string {
|
||||
keyIdResourceRegex := regexp.MustCompile(`^key/(` + uuidRegexPattern + `|` + multiRegionKeyIdPattern + `)$`)
|
||||
matches := keyIdResourceRegex.FindStringSubmatch(s)
|
||||
if matches == nil || len(matches) != 2 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return matches[1]
|
||||
}
|
||||
@ -0,0 +1,154 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
func TestValidateKMSKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
path := cty.Path{cty.GetAttrStep{Name: "field"}}
|
||||
|
||||
testcases := map[string]struct {
|
||||
in string
|
||||
expected tfdiags.Diagnostics
|
||||
}{
|
||||
"kms key id": {
|
||||
in: "57ff7a43-341d-46b6-aee3-a450c9de6dc8",
|
||||
},
|
||||
"kms key arn": {
|
||||
in: "arn:aws:kms:us-west-2:111122223333:key/57ff7a43-341d-46b6-aee3-a450c9de6dc8",
|
||||
},
|
||||
"kms multi-region key id": {
|
||||
in: "mrk-f827515944fb43f9b902a09d2c8b554f",
|
||||
},
|
||||
"kms multi-region key arn": {
|
||||
in: "arn:aws:kms:us-west-2:111122223333:key/mrk-a835af0b39c94b86a21a8fc9535df681",
|
||||
},
|
||||
"kms key alias": {
|
||||
in: "alias/arbitrary-key",
|
||||
expected: tfdiags.Diagnostics{
|
||||
tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ID",
|
||||
`Value must be a valid KMS Key ID, got "alias/arbitrary-key"`,
|
||||
path,
|
||||
),
|
||||
},
|
||||
},
|
||||
"kms key alias arn": {
|
||||
in: "arn:aws:kms:us-west-2:111122223333:alias/arbitrary-key",
|
||||
expected: tfdiags.Diagnostics{
|
||||
tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ARN",
|
||||
`Value must be a valid KMS Key ARN, got "arn:aws:kms:us-west-2:111122223333:alias/arbitrary-key"`,
|
||||
path,
|
||||
),
|
||||
},
|
||||
},
|
||||
"invalid key": {
|
||||
in: "$%wrongkey",
|
||||
expected: tfdiags.Diagnostics{
|
||||
tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ID",
|
||||
`Value must be a valid KMS Key ID, got "$%wrongkey"`,
|
||||
path,
|
||||
),
|
||||
},
|
||||
},
|
||||
"non-kms arn": {
|
||||
in: "arn:aws:lamda:foo:bar:key/xyz",
|
||||
expected: tfdiags.Diagnostics{
|
||||
tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ARN",
|
||||
`Value must be a valid KMS Key ARN, got "arn:aws:lamda:foo:bar:key/xyz"`,
|
||||
path,
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, testcase := range testcases {
|
||||
testcase := testcase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
diags := validateKMSKey(path, testcase.in)
|
||||
|
||||
if diff := cmp.Diff(diags, testcase.expected, cmp.Comparer(diagnosticComparer)); diff != "" {
|
||||
t.Errorf("unexpected diagnostics difference: %s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateKeyARN(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
path := cty.Path{cty.GetAttrStep{Name: "field"}}
|
||||
|
||||
testcases := map[string]struct {
|
||||
in string
|
||||
expected tfdiags.Diagnostics
|
||||
}{
|
||||
"kms key id": {
|
||||
in: "arn:aws:kms:us-west-2:123456789012:key/57ff7a43-341d-46b6-aee3-a450c9de6dc8",
|
||||
},
|
||||
"kms mrk key id": {
|
||||
in: "arn:aws:kms:us-west-2:111122223333:key/mrk-a835af0b39c94b86a21a8fc9535df681",
|
||||
},
|
||||
"kms non-key id": {
|
||||
in: "arn:aws:kms:us-west-2:123456789012:something/else",
|
||||
expected: tfdiags.Diagnostics{
|
||||
tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ARN",
|
||||
`Value must be a valid KMS Key ARN, got "arn:aws:kms:us-west-2:123456789012:something/else"`,
|
||||
path,
|
||||
),
|
||||
},
|
||||
},
|
||||
"non-kms arn": {
|
||||
in: "arn:aws:iam::123456789012:user/David",
|
||||
expected: tfdiags.Diagnostics{
|
||||
tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ARN",
|
||||
`Value must be a valid KMS Key ARN, got "arn:aws:iam::123456789012:user/David"`,
|
||||
path,
|
||||
),
|
||||
},
|
||||
},
|
||||
"not an arn": {
|
||||
in: "not an arn",
|
||||
expected: tfdiags.Diagnostics{
|
||||
tfdiags.AttributeValue(
|
||||
tfdiags.Error,
|
||||
"Invalid KMS Key ARN",
|
||||
`Value must be a valid KMS Key ARN, got "not an arn"`,
|
||||
path,
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, testcase := range testcases {
|
||||
testcase := testcase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
diags := validateKMSKeyARN(path, testcase.in)
|
||||
|
||||
if diff := cmp.Diff(diags, testcase.expected, cmp.Comparer(diagnosticComparer)); diff != "" {
|
||||
t.Errorf("unexpected diagnostics difference: %s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue