mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 11:38:02 +00:00
Make AWS credential types more explicit (#4360)
* Make AWS credential types more explicit The AWS secret engine had a lot of confusing overloading with role paramemters and how they mapped to each of the three credential types supported. This now adds parameters to remove the overloading while maintaining backwards compatibility. With the change, it also becomes easier to add other feature requests. Attaching multiple managed policies to IAM users and adding a policy document to STS AssumedRole credentials is now also supported. Fixes #4229 Fixes #3751 Fixes #2817 * Add missing write action to STS endpoint * Allow unsetting policy_document with empty string This allows unsetting the policy_document by passing in an empty string. Previously, it would fail because the empty string isn't a valid JSON document. * Respond to some PR feedback * Refactor and simplify role reading/upgrading This gets rid of the duplicated role upgrade code between both role reading and role writing by handling the upgrade all in the role reading. * Eliminate duplicated AWS secret test code The testAccStepReadUser and testAccStepReadSTS were virtually identical, so they are consolidated into a single method with the path passed in. * Switch to use AWS ARN parser
This commit is contained in:
committed by
Jeff Mitchell
parent
d2f3abf02e
commit
8275802ac9
@@ -1,18 +1,19 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
@@ -34,8 +35,8 @@ func TestBackend_basic(t *testing.T) {
|
||||
Backend: getBackend(t),
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepConfig(t),
|
||||
testAccStepWritePolicy(t, "test", testPolicy),
|
||||
testAccStepReadUser(t, "test"),
|
||||
testAccStepWritePolicy(t, "test", testDynamoPolicy),
|
||||
testAccStepRead(t, "creds", "test", []credentialTestFunc{listDynamoTablesTest}),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -56,12 +57,12 @@ func TestBackend_basicSTS(t *testing.T) {
|
||||
Backend: getBackend(t),
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepConfigWithCreds(t, accessKey),
|
||||
testAccStepWritePolicy(t, "test", testPolicy),
|
||||
testAccStepReadSTS(t, "test"),
|
||||
testAccStepWriteArnPolicyRef(t, "test", testPolicyArn),
|
||||
testAccStepWritePolicy(t, "test", testDynamoPolicy),
|
||||
testAccStepRead(t, "sts", "test", []credentialTestFunc{listDynamoTablesTest}),
|
||||
testAccStepWriteArnPolicyRef(t, "test", ec2PolicyArn),
|
||||
testAccStepReadSTSWithArnPolicy(t, "test"),
|
||||
testAccStepWriteArnRoleRef(t, testRoleName),
|
||||
testAccStepReadSTS(t, testRoleName),
|
||||
testAccStepRead(t, "sts", testRoleName, []credentialTestFunc{describeInstancesTest}),
|
||||
},
|
||||
Teardown: func() error {
|
||||
return teardown(accessKey)
|
||||
@@ -70,8 +71,8 @@ func TestBackend_basicSTS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBackend_policyCrud(t *testing.T) {
|
||||
var compacted bytes.Buffer
|
||||
if err := json.Compact(&compacted, []byte(testPolicy)); err != nil {
|
||||
compacted, err := compactJSON(testDynamoPolicy)
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
|
||||
@@ -80,8 +81,8 @@ func TestBackend_policyCrud(t *testing.T) {
|
||||
Backend: getBackend(t),
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepConfig(t),
|
||||
testAccStepWritePolicy(t, "test", testPolicy),
|
||||
testAccStepReadPolicy(t, "test", compacted.String()),
|
||||
testAccStepWritePolicy(t, "test", testDynamoPolicy),
|
||||
testAccStepReadPolicy(t, "test", compacted),
|
||||
testAccStepDeletePolicy(t, "test"),
|
||||
testAccStepReadPolicy(t, "test", ""),
|
||||
},
|
||||
@@ -162,7 +163,7 @@ func createRole(t *testing.T) {
|
||||
}
|
||||
|
||||
attachment := &iam.AttachRolePolicyInput{
|
||||
PolicyArn: aws.String(testPolicyArn),
|
||||
PolicyArn: aws.String(ec2PolicyArn),
|
||||
RoleName: aws.String(testRoleName), // Required
|
||||
}
|
||||
_, err = svc.AttachRolePolicy(attachment)
|
||||
@@ -254,7 +255,7 @@ func createUser(t *testing.T, accessKey *awsAccessKey) {
|
||||
accessKey.SecretAccessKey = *genAccessKey.SecretAccessKey
|
||||
}
|
||||
|
||||
func teardown(accessKey *awsAccessKey) error {
|
||||
func deleteTestRole() error {
|
||||
awsConfig := &aws.Config{
|
||||
Region: aws.String("us-east-1"),
|
||||
HTTPClient: cleanhttp.DefaultClient(),
|
||||
@@ -262,7 +263,7 @@ func teardown(accessKey *awsAccessKey) error {
|
||||
svc := iam.New(session.New(awsConfig))
|
||||
|
||||
attachment := &iam.DetachRolePolicyInput{
|
||||
PolicyArn: aws.String(testPolicyArn),
|
||||
PolicyArn: aws.String(ec2PolicyArn),
|
||||
RoleName: aws.String(testRoleName), // Required
|
||||
}
|
||||
_, err := svc.DetachRolePolicy(attachment)
|
||||
@@ -282,12 +283,25 @@ func teardown(accessKey *awsAccessKey) error {
|
||||
log.Printf("[WARN] AWS DeleteRole failed: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func teardown(accessKey *awsAccessKey) error {
|
||||
|
||||
if err := deleteTestRole(); err != nil {
|
||||
return err
|
||||
}
|
||||
awsConfig := &aws.Config{
|
||||
Region: aws.String("us-east-1"),
|
||||
HTTPClient: cleanhttp.DefaultClient(),
|
||||
}
|
||||
svc := iam.New(session.New(awsConfig))
|
||||
|
||||
userDetachment := &iam.DetachUserPolicyInput{
|
||||
PolicyArn: aws.String("arn:aws:iam::aws:policy/AdministratorAccess"),
|
||||
UserName: aws.String(testUserName),
|
||||
}
|
||||
_, err = svc.DetachUserPolicy(userDetachment)
|
||||
_, err := svc.DetachUserPolicy(userDetachment)
|
||||
if err != nil {
|
||||
log.Printf("[WARN] AWS DetachUserPolicy failed: %v", err)
|
||||
return err
|
||||
@@ -354,51 +368,10 @@ func testAccStepConfigWithCreds(t *testing.T, accessKey *awsAccessKey) logicalte
|
||||
}
|
||||
}
|
||||
|
||||
func testAccStepReadUser(t *testing.T, name string) logicaltest.TestStep {
|
||||
func testAccStepRead(t *testing.T, path, name string, credentialTests []credentialTestFunc) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.ReadOperation,
|
||||
Path: "creds/" + name,
|
||||
Check: func(resp *logical.Response) error {
|
||||
var d struct {
|
||||
AccessKey string `mapstructure:"access_key"`
|
||||
SecretKey string `mapstructure:"secret_key"`
|
||||
}
|
||||
if err := mapstructure.Decode(resp.Data, &d); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("[WARN] Generated credentials: %v", d)
|
||||
|
||||
// Build a client and verify that the credentials work
|
||||
creds := credentials.NewStaticCredentials(d.AccessKey, d.SecretKey, "")
|
||||
awsConfig := &aws.Config{
|
||||
Credentials: creds,
|
||||
Region: aws.String("us-east-1"),
|
||||
HTTPClient: cleanhttp.DefaultClient(),
|
||||
}
|
||||
client := ec2.New(session.New(awsConfig))
|
||||
|
||||
log.Printf("[WARN] Verifying that the generated credentials work...")
|
||||
retryCount := 0
|
||||
success := false
|
||||
var err error
|
||||
for !success && retryCount < 10 {
|
||||
_, err = client.DescribeInstances(&ec2.DescribeInstancesInput{})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
retryCount++
|
||||
}
|
||||
|
||||
return err
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func testAccStepReadSTS(t *testing.T, name string) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.ReadOperation,
|
||||
Path: "sts/" + name,
|
||||
Path: path + "/" + name,
|
||||
Check: func(resp *logical.Response) error {
|
||||
var d struct {
|
||||
AccessKey string `mapstructure:"access_key"`
|
||||
@@ -409,27 +382,101 @@ func testAccStepReadSTS(t *testing.T, name string) logicaltest.TestStep {
|
||||
return err
|
||||
}
|
||||
log.Printf("[WARN] Generated credentials: %v", d)
|
||||
|
||||
// Build a client and verify that the credentials work
|
||||
creds := credentials.NewStaticCredentials(d.AccessKey, d.SecretKey, d.STSToken)
|
||||
awsConfig := &aws.Config{
|
||||
Credentials: creds,
|
||||
Region: aws.String("us-east-1"),
|
||||
HTTPClient: cleanhttp.DefaultClient(),
|
||||
for _, test := range credentialTests {
|
||||
err := test(d.AccessKey, d.SecretKey, d.STSToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
client := ec2.New(session.New(awsConfig))
|
||||
|
||||
log.Printf("[WARN] Verifying that the generated credentials work...")
|
||||
_, err := client.DescribeInstances(&ec2.DescribeInstancesInput{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func describeInstancesTest(accessKey, secretKey, token string) error {
|
||||
creds := credentials.NewStaticCredentials(accessKey, secretKey, token)
|
||||
awsConfig := &aws.Config{
|
||||
Credentials: creds,
|
||||
Region: aws.String("us-east-1"),
|
||||
HTTPClient: cleanhttp.DefaultClient(),
|
||||
}
|
||||
client := ec2.New(session.New(awsConfig))
|
||||
log.Printf("[WARN] Verifying that the generated credentials work with ec2:DescribeInstances...")
|
||||
return retryUntilSuccess(func() error {
|
||||
_, err := client.DescribeInstances(&ec2.DescribeInstancesInput{})
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func describeAzsTestUnauthorized(accessKey, secretKey, token string) error {
|
||||
creds := credentials.NewStaticCredentials(accessKey, secretKey, token)
|
||||
awsConfig := &aws.Config{
|
||||
Credentials: creds,
|
||||
Region: aws.String("us-east-1"),
|
||||
HTTPClient: cleanhttp.DefaultClient(),
|
||||
}
|
||||
client := ec2.New(session.New(awsConfig))
|
||||
log.Printf("[WARN] Verifying that the generated credentials don't work with ec2:DescribeAvailabilityZones...")
|
||||
return retryUntilSuccess(func() error {
|
||||
_, err := client.DescribeAvailabilityZones(&ec2.DescribeAvailabilityZonesInput{})
|
||||
// Need to make sure AWS authenticates the generated credentials but does not authorize the operation
|
||||
if err == nil {
|
||||
return fmt.Errorf("operation succeeded when expected failure")
|
||||
}
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
if aerr.Code() == "UnauthorizedOperation" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func listIamUsersTest(accessKey, secretKey, token string) error {
|
||||
creds := credentials.NewStaticCredentials(accessKey, secretKey, token)
|
||||
awsConfig := &aws.Config{
|
||||
Credentials: creds,
|
||||
Region: aws.String("us-east-1"),
|
||||
HTTPClient: cleanhttp.DefaultClient(),
|
||||
}
|
||||
client := iam.New(session.New(awsConfig))
|
||||
log.Printf("[WARN] Verifying that the generated credentials work with iam:ListUsers...")
|
||||
return retryUntilSuccess(func() error {
|
||||
_, err := client.ListUsers(&iam.ListUsersInput{})
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func listDynamoTablesTest(accessKey, secretKey, token string) error {
|
||||
creds := credentials.NewStaticCredentials(accessKey, secretKey, token)
|
||||
awsConfig := &aws.Config{
|
||||
Credentials: creds,
|
||||
Region: aws.String("us-east-1"),
|
||||
HTTPClient: cleanhttp.DefaultClient(),
|
||||
}
|
||||
client := dynamodb.New(session.New(awsConfig))
|
||||
log.Printf("[WARN] Verifying that the generated credentials work with dynamodb:ListTables...")
|
||||
return retryUntilSuccess(func() error {
|
||||
_, err := client.ListTables(&dynamodb.ListTablesInput{})
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func retryUntilSuccess(op func() error) error {
|
||||
retryCount := 0
|
||||
success := false
|
||||
var err error
|
||||
for !success && retryCount < 10 {
|
||||
err = op()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
retryCount++
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func testAccStepReadSTSWithArnPolicy(t *testing.T, name string) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.ReadOperation,
|
||||
@@ -437,7 +484,7 @@ func testAccStepReadSTSWithArnPolicy(t *testing.T, name string) logicaltest.Test
|
||||
ErrorOk: true,
|
||||
Check: func(resp *logical.Response) error {
|
||||
if resp.Data["error"] !=
|
||||
"Can't generate STS credentials for a managed policy; use a role to assume or an inline policy instead" {
|
||||
"attempted to retrieve iam_user credentials through the sts path; this is not allowed for legacy roles" {
|
||||
t.Fatalf("bad: %v", resp)
|
||||
}
|
||||
return nil
|
||||
@@ -450,7 +497,7 @@ func testAccStepWritePolicy(t *testing.T, name string, policy string) logicaltes
|
||||
Operation: logical.UpdateOperation,
|
||||
Path: "roles/" + name,
|
||||
Data: map[string]interface{}{
|
||||
"policy": testPolicy,
|
||||
"policy": policy,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -475,31 +522,28 @@ func testAccStepReadPolicy(t *testing.T, name string, value string) logicaltest.
|
||||
return fmt.Errorf("bad: %#v", resp)
|
||||
}
|
||||
|
||||
var d struct {
|
||||
Policy string `mapstructure:"policy"`
|
||||
expected := map[string]interface{}{
|
||||
"policy_arns": []string(nil),
|
||||
"role_arns": []string(nil),
|
||||
"policy_document": value,
|
||||
"credential_types": []string{iamUserCred, federationTokenCred},
|
||||
}
|
||||
if err := mapstructure.Decode(resp.Data, &d); err != nil {
|
||||
return err
|
||||
if !reflect.DeepEqual(resp.Data, expected) {
|
||||
return fmt.Errorf("bad: got: %#v\nexpected: %#v", resp.Data, expected)
|
||||
}
|
||||
|
||||
if d.Policy != value {
|
||||
return fmt.Errorf("bad: %#v", resp)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const testPolicy = `
|
||||
{
|
||||
const testDynamoPolicy = `{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "Stmt1426528957000",
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"ec2:*"
|
||||
"dynamodb:List*"
|
||||
],
|
||||
"Resource": [
|
||||
"*"
|
||||
@@ -509,14 +553,42 @@ const testPolicy = `
|
||||
}
|
||||
`
|
||||
|
||||
const testPolicyArn = "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"
|
||||
const ec2PolicyArn = "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"
|
||||
const iamPolicyArn = "arn:aws:iam::aws:policy/IAMReadOnlyAccess"
|
||||
|
||||
func testAccStepWriteRole(t *testing.T, name string, data map[string]interface{}) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.UpdateOperation,
|
||||
Path: "roles/" + name,
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
func testAccStepReadRole(t *testing.T, name string, expected map[string]interface{}) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.ReadOperation,
|
||||
Path: "roles/" + name,
|
||||
Check: func(resp *logical.Response) error {
|
||||
if resp == nil {
|
||||
if expected == nil {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("bad: nil response")
|
||||
}
|
||||
if !reflect.DeepEqual(resp.Data, expected) {
|
||||
return fmt.Errorf("bad: got %#v\nexpected: %#v", resp.Data, expected)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func testAccStepWriteArnPolicyRef(t *testing.T, name string, arn string) logicaltest.TestStep {
|
||||
return logicaltest.TestStep{
|
||||
Operation: logical.UpdateOperation,
|
||||
Path: "roles/" + name,
|
||||
Data: map[string]interface{}{
|
||||
"arn": testPolicyArn,
|
||||
"arn": ec2PolicyArn,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -528,20 +600,92 @@ func TestBackend_basicPolicyArnRef(t *testing.T) {
|
||||
Backend: getBackend(t),
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepConfig(t),
|
||||
testAccStepWriteArnPolicyRef(t, "test", testPolicyArn),
|
||||
testAccStepReadUser(t, "test"),
|
||||
testAccStepWriteArnPolicyRef(t, "test", ec2PolicyArn),
|
||||
testAccStepRead(t, "creds", "test", []credentialTestFunc{describeInstancesTest}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_iamUserManagedInlinePolicies(t *testing.T) {
|
||||
compacted, err := compactJSON(testDynamoPolicy)
|
||||
if err != nil {
|
||||
t.Fatalf("bad: %#v", err)
|
||||
}
|
||||
roleData := map[string]interface{}{
|
||||
"policy_document": testDynamoPolicy,
|
||||
"policy_arns": []string{ec2PolicyArn, iamPolicyArn},
|
||||
"credential_type": iamUserCred,
|
||||
}
|
||||
expectedRoleData := map[string]interface{}{
|
||||
"policy_document": compacted,
|
||||
"policy_arns": []string{ec2PolicyArn, iamPolicyArn},
|
||||
"credential_types": []string{iamUserCred},
|
||||
"role_arns": []string(nil),
|
||||
}
|
||||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
AcceptanceTest: true,
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Backend: getBackend(t),
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepConfig(t),
|
||||
testAccStepWriteRole(t, "test", roleData),
|
||||
testAccStepReadRole(t, "test", expectedRoleData),
|
||||
testAccStepRead(t, "creds", "test", []credentialTestFunc{describeInstancesTest, listIamUsersTest, listDynamoTablesTest}),
|
||||
testAccStepRead(t, "sts", "test", []credentialTestFunc{describeInstancesTest, listIamUsersTest, listDynamoTablesTest}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_AssumedRoleWithPolicyDoc(t *testing.T) {
|
||||
// This looks a bit curious. The policy document and the role document act
|
||||
// as a logical intersection of policies. The role allows ec2:Describe*
|
||||
// (among other permissions). This policy allows everything BUT
|
||||
// ec2:DescribeAvailabilityZones. Thus, the logical intersection of the two
|
||||
// is all ec2:Describe* EXCEPT ec2:DescribeAvailabilityZones, and so the
|
||||
// describeAZs call should fail
|
||||
allowAllButDescribeAzs := `
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{
|
||||
"Effect": "Allow",
|
||||
"NotAction": "ec2:DescribeAvailabilityZones",
|
||||
"Resource": "*"
|
||||
}]
|
||||
}
|
||||
`
|
||||
roleData := map[string]interface{}{
|
||||
"policy_document": allowAllButDescribeAzs,
|
||||
"role_arns": []string{fmt.Sprintf("arn:aws:iam::%s:role/%s", os.Getenv("AWS_ACCOUNT_ID"), testRoleName)},
|
||||
"credential_type": assumedRoleCred,
|
||||
}
|
||||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
AcceptanceTest: true,
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
createRole(t)
|
||||
// Sleep sometime because AWS is eventually consistent
|
||||
log.Println("[WARN] Sleeping for 10 seconds waiting for AWS...")
|
||||
time.Sleep(10 * time.Second)
|
||||
},
|
||||
Backend: getBackend(t),
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepConfig(t),
|
||||
testAccStepWriteRole(t, "test", roleData),
|
||||
testAccStepRead(t, "sts", "test", []credentialTestFunc{describeInstancesTest, describeAzsTestUnauthorized}),
|
||||
testAccStepRead(t, "creds", "test", []credentialTestFunc{describeInstancesTest, describeAzsTestUnauthorized}),
|
||||
},
|
||||
Teardown: deleteTestRole,
|
||||
})
|
||||
}
|
||||
|
||||
func TestBackend_policyArnCrud(t *testing.T) {
|
||||
logicaltest.Test(t, logicaltest.TestCase{
|
||||
AcceptanceTest: true,
|
||||
Backend: getBackend(t),
|
||||
Steps: []logicaltest.TestStep{
|
||||
testAccStepConfig(t),
|
||||
testAccStepWriteArnPolicyRef(t, "test", testPolicyArn),
|
||||
testAccStepReadArnPolicy(t, "test", testPolicyArn),
|
||||
testAccStepWriteArnPolicyRef(t, "test", ec2PolicyArn),
|
||||
testAccStepReadArnPolicy(t, "test", ec2PolicyArn),
|
||||
testAccStepDeletePolicy(t, "test"),
|
||||
testAccStepReadArnPolicy(t, "test", ""),
|
||||
},
|
||||
@@ -561,15 +705,14 @@ func testAccStepReadArnPolicy(t *testing.T, name string, value string) logicalte
|
||||
return fmt.Errorf("bad: %#v", resp)
|
||||
}
|
||||
|
||||
var d struct {
|
||||
Policy string `mapstructure:"arn"`
|
||||
expected := map[string]interface{}{
|
||||
"policy_arns": []string{value},
|
||||
"role_arns": []string(nil),
|
||||
"policy_document": "",
|
||||
"credential_types": []string{iamUserCred},
|
||||
}
|
||||
if err := mapstructure.Decode(resp.Data, &d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.Policy != value {
|
||||
return fmt.Errorf("bad: %#v", resp)
|
||||
if !reflect.DeepEqual(resp.Data, expected) {
|
||||
return fmt.Errorf("bad: got: %#v\nexpected: %#v", resp.Data, expected)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -591,3 +734,5 @@ type awsAccessKey struct {
|
||||
AccessKeyId string
|
||||
SecretAccessKey string
|
||||
}
|
||||
|
||||
type credentialTestFunc func(string, string, string) error
|
||||
|
||||
Reference in New Issue
Block a user