Fork of hashicorp/boundary-plugin-aws (MPL-2.0). Module path and Boundary SDK imports now point at repo.anhonesthost.net/CyberCoveLLC. Adds NOTICE and an About this fork section to the README. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
348 lines
19 KiB
Go
348 lines
19 KiB
Go
// Copyright IBM Corp. 2021, 2026
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package testing
|
|
|
|
// This file contains the TestHostPlugin orchestrator. It deploys the Terraform
|
|
// workspace, collects outputs, and calls the per-credential-type helper
|
|
// functions defined in e2e_host_static_test.go and e2e_host_assumerole_test.go.
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"testing"
|
|
|
|
"repo.anhonesthost.net/CyberCoveLLC/threshold-plugin-aws/plugin/service/host"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const (
|
|
envTargetAccessKeyId = "TARGET_AWS_ACCESS_KEY_ID"
|
|
envTargetSecretAccessKey = "TARGET_AWS_SECRET_ACCESS_KEY"
|
|
envTargetSessionToken = "TARGET_AWS_SESSION_TOKEN"
|
|
envTargetRegion = "TARGET_AWS_REGION"
|
|
)
|
|
|
|
const expectedEc2InstanceCount = 5
|
|
|
|
func TestHostPlugin(t *testing.T) {
|
|
region := os.Getenv("AWS_REGION")
|
|
if region == "" {
|
|
t.Skip("set AWS_REGION to use this test")
|
|
}
|
|
if envAccessKeyId := os.Getenv("AWS_ACCESS_KEY_ID"); envAccessKeyId == "" {
|
|
t.Skip("set AWS_ACCESS_KEY_ID to use this test")
|
|
}
|
|
if envSecretAccessKey := os.Getenv("AWS_SECRET_ACCESS_KEY"); envSecretAccessKey == "" {
|
|
t.Skip("set AWS_SECRET_ACCESS_KEY to use this test")
|
|
}
|
|
|
|
require := require.New(t)
|
|
|
|
// Collect cross-account credentials up front so they can be passed as
|
|
// Terraform variables. The cross-account section is skipped (not failed)
|
|
// when these are absent, but we need the values available before Deploy.
|
|
targetAccessKeyId := os.Getenv(envTargetAccessKeyId)
|
|
targetSecretAccessKey := os.Getenv(envTargetSecretAccessKey)
|
|
targetSessionToken := os.Getenv(envTargetSessionToken)
|
|
targetRegion := os.Getenv(envTargetRegion)
|
|
if targetRegion == "" {
|
|
targetRegion = region
|
|
}
|
|
|
|
tfVars := map[string]string{}
|
|
if targetAccessKeyId != "" && targetSecretAccessKey != "" {
|
|
tfVars["target_access_key_id"] = targetAccessKeyId
|
|
tfVars["target_secret_access_key"] = targetSecretAccessKey
|
|
tfVars["target_region"] = targetRegion
|
|
if targetSessionToken != "" {
|
|
tfVars["target_session_token"] = targetSessionToken
|
|
}
|
|
}
|
|
|
|
tf, err := NewTestTerraformer("testdata/host", tfVars)
|
|
require.NoError(err)
|
|
require.NotNil(tf)
|
|
|
|
t.Log("===== deploying test Terraform workspace =====")
|
|
err = tf.Deploy()
|
|
require.NoError(err)
|
|
|
|
defer func() {
|
|
t.Log("===== destroying test Terraform workspace =====")
|
|
if err := tf.Destroy(); err != nil {
|
|
t.Logf("WARNING: could not run Terraform destroy: %s", err)
|
|
}
|
|
}()
|
|
|
|
iamUserNames, err := tf.GetOutputSlice("iam_user_names")
|
|
require.NoError(err)
|
|
require.Len(iamUserNames, expectedIamUserCount)
|
|
|
|
iamUserArns, err := tf.GetOutputSlice("iam_user_arns")
|
|
require.NoError(err)
|
|
require.Len(iamUserArns, expectedIamUserCount)
|
|
|
|
iamAccessKeyIds, err := tf.GetOutputSlice("iam_access_key_ids")
|
|
require.NoError(err)
|
|
require.Len(iamAccessKeyIds, expectedIamUserCount)
|
|
|
|
iamSecretAccessKeys, err := tf.GetOutputSlice("iam_secret_access_keys")
|
|
require.NoError(err)
|
|
require.Len(iamSecretAccessKeys, expectedIamUserCount)
|
|
|
|
ec2InstanceIds, err := tf.GetOutputSlice("instance_ids")
|
|
require.NoError(err)
|
|
require.Len(ec2InstanceIds, expectedEc2InstanceCount)
|
|
|
|
ec2InstanceAddrs, err := tf.GetOutputMap("instance_addrs")
|
|
require.NoError(err)
|
|
require.Len(ec2InstanceAddrs, expectedEc2InstanceCount)
|
|
|
|
ec2InstanceTags, err := tf.GetOutputMap("instance_tags")
|
|
require.NoError(err)
|
|
require.Len(ec2InstanceTags, expectedEc2InstanceCount)
|
|
|
|
rawExpectedTags, err := tf.GetOutputSlice("instance_tag_keys")
|
|
require.NoError(err)
|
|
require.Len(rawExpectedTags, 3)
|
|
expectedTags := make([]string, 0, len(rawExpectedTags))
|
|
for _, rawExpectedTag := range rawExpectedTags {
|
|
expectedTags = append(expectedTags, rawExpectedTag.(string))
|
|
}
|
|
|
|
// Start the workflow now. Set up the host catalog. Note that this
|
|
// will cause the state to go out of drift above in the sense that
|
|
// the access key ID/secret access key will no longer be valid. We
|
|
// will assert this through the returned state.
|
|
p := new(host.HostPlugin)
|
|
ctx := context.Background()
|
|
|
|
// ********************
|
|
// * OnCreateCatalog
|
|
// ********************
|
|
//
|
|
// Test non-rotation (using primary user).
|
|
keyid, secret := testPluginOnCreateCatalog(ctx, t, p, region, iamAccessKeyIds[0].(string), iamSecretAccessKeys[0].(string), false)
|
|
// Test rotation next.
|
|
keyid, secret = testPluginOnCreateCatalog(ctx, t, p, region, keyid, secret, true)
|
|
|
|
// ********************
|
|
// * OnUpdateCatalog
|
|
// ********************
|
|
//
|
|
// Test no-op non-rotation.
|
|
keyid, secret = testPluginOnUpdateCatalog(ctx, t, p, region, keyid, secret, "", "", false, false)
|
|
// Switch to rotation.
|
|
keyid, secret = testPluginOnUpdateCatalog(ctx, t, p, region, keyid, secret, "", "", false, true)
|
|
// Test no-op with rotation.
|
|
keyid, secret = testPluginOnUpdateCatalog(ctx, t, p, region, keyid, secret, "", "", true, true)
|
|
// Switch credentials to next user. Don't rotate.
|
|
keyid, secret = testPluginOnUpdateCatalog(ctx, t, p, region, keyid, secret, iamAccessKeyIds[1].(string), iamSecretAccessKeys[1].(string), true, false)
|
|
// Switch credentials to next user. Add rotation.
|
|
keyid, secret = testPluginOnUpdateCatalog(ctx, t, p, region, keyid, secret, iamAccessKeyIds[2].(string), iamSecretAccessKeys[2].(string), false, true)
|
|
// Switch to next user, with rotation disabled.
|
|
keyid, secret = testPluginOnUpdateCatalog(ctx, t, p, region, keyid, secret, iamAccessKeyIds[3].(string), iamSecretAccessKeys[3].(string), true, false)
|
|
// Last case - switch to another user and keep rotation off.
|
|
keyid, secret = testPluginOnUpdateCatalog(ctx, t, p, region, keyid, secret, iamAccessKeyIds[4].(string), iamSecretAccessKeys[4].(string), false, false)
|
|
|
|
// ********************
|
|
// * OnDeleteCatalog
|
|
// ********************
|
|
//
|
|
// Test non-rotated.
|
|
testPluginOnDeleteCatalog(ctx, t, p, region, keyid, secret, false)
|
|
// Test as if we had rotated these credentials (note that this
|
|
// makes this test set unusable).
|
|
testPluginOnDeleteCatalog(ctx, t, p, region, keyid, secret, true)
|
|
|
|
// ********************
|
|
// * Host set stuff
|
|
// ********************
|
|
// Reassign the keyid and secret first.
|
|
keyid, secret = iamAccessKeyIds[5].(string), iamSecretAccessKeys[5].(string)
|
|
// Process the collection of instances and index by expected tag names.
|
|
expectedTagInstancesMap := buildExpectedTagInstancesMap(ec2InstanceTags, expectedTags)
|
|
|
|
requireTagInstancesMatchProvisioned(t, ec2InstanceIds, expectedTagInstancesMap)
|
|
|
|
cases := [][]string{
|
|
{expectedTags[0]},
|
|
{expectedTags[1]},
|
|
{expectedTags[2]},
|
|
{expectedTags[0], expectedTags[1]},
|
|
{expectedTags[0], expectedTags[2]},
|
|
{expectedTags[1], expectedTags[2]},
|
|
{expectedTags[0], expectedTags[1], expectedTags[2]},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
// Test create/update in one step
|
|
testPluginOnCreateUpdateSet(ctx, t, p, region, keyid, secret, tc)
|
|
// Test ListHosts
|
|
testPluginListHosts(ctx, t, p, region, keyid, secret, tc, expectedTagInstancesMap)
|
|
// TODO: add OnDeleteSet if it needs to be implemented
|
|
}
|
|
|
|
// finally lets test instance_addresses_only catalog attribute correctly syncs only instance addresses
|
|
testInstanceAddressesOnlyListHosts(ctx, t, p, tf, region, keyid, secret)
|
|
|
|
// ********************
|
|
// * AssumeRole - Happy Path & Error Cases
|
|
// ********************
|
|
assumeRoleArn, err := tf.GetOutputString("assume_role_arn")
|
|
require.NoError(err)
|
|
|
|
noTrustRoleArn, err := tf.GetOutputString("assume_role_no_trust_arn")
|
|
require.NoError(err)
|
|
|
|
missingPermRoleArn, err := tf.GetOutputString("assume_role_no_ec2_permission_arn")
|
|
require.NoError(err)
|
|
|
|
testOnCreateCatalogCases(ctx, t, p, []onCreateCatalogCase{
|
|
{name: "assume role happy path", catalogAttrs: roleArnAttrs(region, assumeRoleArn)},
|
|
{name: "assume role no trust", catalogAttrs: roleArnAttrs(region, noTrustRoleArn), wantErr: "AccessDenied"},
|
|
{name: "assume role missing ec2 permission", catalogAttrs: roleArnAttrs(region, missingPermRoleArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testOnUpdateCatalogCases(ctx, t, p, []onUpdateCatalogCase{
|
|
{name: "assume role happy path", catalogAttrs: roleArnAttrs(region, assumeRoleArn)},
|
|
{name: "assume role no trust", catalogAttrs: roleArnAttrs(region, noTrustRoleArn), wantErr: "AccessDenied"},
|
|
{name: "assume role missing ec2 permission", currentAttrs: roleArnAttrs(region, assumeRoleArn), newAttrs: roleArnAttrs(region, missingPermRoleArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testOnCreateSetCases(ctx, t, p, []onSetCase{
|
|
{name: "assume role happy path", catalogAttrs: roleArnAttrs(region, assumeRoleArn), tags: cases[0]},
|
|
{name: "assume role no trust", catalogAttrs: roleArnAttrs(region, noTrustRoleArn), wantErr: "AccessDenied"},
|
|
{name: "assume role missing ec2 permission", catalogAttrs: roleArnAttrs(region, missingPermRoleArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testOnUpdateSetCases(ctx, t, p, []onSetCase{
|
|
{name: "assume role happy path", catalogAttrs: roleArnAttrs(region, assumeRoleArn), tags: cases[0]},
|
|
{name: "assume role no trust", catalogAttrs: roleArnAttrs(region, noTrustRoleArn), wantErr: "AccessDenied"},
|
|
{name: "assume role missing ec2 permission", catalogAttrs: roleArnAttrs(region, missingPermRoleArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testListHostsCases(ctx, t, p, []listHostsCase{
|
|
{name: "assume role happy path", catalogAttrs: roleArnAttrs(region, assumeRoleArn), tags: cases[0], expected: expectedTagInstancesMap},
|
|
{name: "assume role no trust", catalogAttrs: roleArnAttrs(region, noTrustRoleArn), tags: cases[0], wantErr: "AccessDenied"},
|
|
{name: "assume role missing ec2 permission", catalogAttrs: roleArnAttrs(region, missingPermRoleArn), tags: cases[0], wantErr: "UnauthorizedOperation"},
|
|
})
|
|
|
|
// ********************
|
|
// * Cross-Role AssumeRole - Happy Path & Error Cases
|
|
// ********************
|
|
// These tests exercise the two-hop role chain within a single AWS account.
|
|
// The principal role has no ec2:DescribeInstances; the target role
|
|
// (assume_role) does. The plugin must assume the principal first, then use
|
|
// those credentials to assume the target role before calling DescribeInstances.
|
|
// This validates the plugin's chained credential logic without requiring a
|
|
// second AWS account.
|
|
crossRolePrincipalArn, err := tf.GetOutputString("cross_role_principal_arn")
|
|
require.NoError(err)
|
|
|
|
crossRolePrincipalNoTrustArn, err := tf.GetOutputString("cross_role_principal_no_trust_arn")
|
|
require.NoError(err)
|
|
|
|
crossRoleTargetNoTrustArn, err := tf.GetOutputString("cross_role_target_no_trust_arn")
|
|
require.NoError(err)
|
|
|
|
crossRoleTargetNoEc2PermissionArn, err := tf.GetOutputString("cross_role_target_no_ec2_permission_arn")
|
|
require.NoError(err)
|
|
|
|
// assume_role_arn is reused as the cross-role target — it has ec2:DescribeInstances
|
|
// and its trust policy allows the cross-role principal to assume it.
|
|
testOnCreateCatalogCases(ctx, t, p, []onCreateCatalogCase{
|
|
{name: "cross-role happy path", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, assumeRoleArn)},
|
|
{name: "cross-role principal no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalNoTrustArn, assumeRoleArn), wantErr: "AccessDenied"},
|
|
{name: "cross-role target no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoTrustArn), wantErr: "AccessDenied"},
|
|
{name: "cross-role target missing ec2 permission", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoEc2PermissionArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testOnUpdateCatalogCases(ctx, t, p, []onUpdateCatalogCase{
|
|
{name: "cross-role happy path", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, assumeRoleArn)},
|
|
{name: "cross-role principal no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalNoTrustArn, assumeRoleArn), wantErr: "AccessDenied"},
|
|
{name: "cross-role target no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoTrustArn), wantErr: "AccessDenied"},
|
|
{name: "cross-role target missing ec2 permission", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoEc2PermissionArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testOnCreateSetCases(ctx, t, p, []onSetCase{
|
|
{name: "cross-role happy path", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, assumeRoleArn), tags: cases[0]},
|
|
{name: "cross-role principal no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalNoTrustArn, assumeRoleArn), wantErr: "AccessDenied"},
|
|
{name: "cross-role target no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoTrustArn), wantErr: "AccessDenied"},
|
|
{name: "cross-role target missing ec2 permission", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoEc2PermissionArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testOnUpdateSetCases(ctx, t, p, []onSetCase{
|
|
{name: "cross-role happy path", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, assumeRoleArn), tags: cases[0]},
|
|
{name: "cross-role principal no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalNoTrustArn, assumeRoleArn), wantErr: "AccessDenied"},
|
|
{name: "cross-role target no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoTrustArn), wantErr: "AccessDenied"},
|
|
{name: "cross-role target missing ec2 permission", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoEc2PermissionArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testListHostsCases(ctx, t, p, []listHostsCase{
|
|
{name: "cross-role happy path", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, assumeRoleArn), tags: cases[0], expected: expectedTagInstancesMap},
|
|
{name: "cross-role principal no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalNoTrustArn, assumeRoleArn), tags: cases[0], wantErr: "AccessDenied"},
|
|
{name: "cross-role target no trust", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoTrustArn), tags: cases[0], wantErr: "AccessDenied"},
|
|
{name: "cross-role target missing ec2 permission", catalogAttrs: crossRoleAttrs(region, crossRolePrincipalArn, crossRoleTargetNoEc2PermissionArn), tags: cases[0], wantErr: "UnauthorizedOperation"},
|
|
})
|
|
// ********************
|
|
// * Cross-Account AssumeRole - Happy Path & Error Cases
|
|
// ********************
|
|
// These tests require credentials for a second AWS account supplied via
|
|
// TARGET_AWS_ACCESS_KEY_ID, TARGET_AWS_SECRET_ACCESS_KEY, and (for
|
|
// temporary credentials) TARGET_AWS_SESSION_TOKEN. They are skipped
|
|
// (not failed) when the access key ID or secret access key are absent.
|
|
if targetAccessKeyId == "" || targetSecretAccessKey == "" {
|
|
t.Log("skipping cross-account tests: set TARGET_AWS_ACCESS_KEY_ID and TARGET_AWS_SECRET_ACCESS_KEY to enable")
|
|
} else {
|
|
crossAccountPrincipalArn, err := tf.GetOutputString("cross_account_principal_arn")
|
|
require.NoError(err)
|
|
|
|
crossAccountPrincipalNoTrustArn, err := tf.GetOutputString("cross_account_principal_no_trust_arn")
|
|
require.NoError(err)
|
|
|
|
crossAccountTargetArn, err := tf.GetOutputString("cross_account_target_arn")
|
|
require.NoError(err)
|
|
|
|
crossAccountTargetNoTrustArn, err := tf.GetOutputString("cross_account_target_no_trust_arn")
|
|
require.NoError(err)
|
|
|
|
crossAccountTargetNoEc2PermissionArn, err := tf.GetOutputString("cross_account_target_no_ec2_permission_arn")
|
|
require.NoError(err)
|
|
|
|
targetEc2InstanceIds, err := tf.GetOutputSlice("target_instance_ids")
|
|
require.NoError(err)
|
|
require.Len(targetEc2InstanceIds, expectedEc2InstanceCount)
|
|
|
|
targetEc2InstanceTags, err := tf.GetOutputMap("target_instance_tags")
|
|
require.NoError(err)
|
|
expectedTargetTagInstancesMap := buildExpectedTagInstancesMap(targetEc2InstanceTags, expectedTags)
|
|
|
|
requireTagInstancesMatchProvisioned(t, targetEc2InstanceIds, expectedTargetTagInstancesMap)
|
|
|
|
testOnCreateCatalogCases(ctx, t, p, []onCreateCatalogCase{
|
|
{name: "cross-account happy path", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetArn)},
|
|
{name: "cross-account principal no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalNoTrustArn, crossAccountTargetArn), wantErr: "AccessDenied"},
|
|
{name: "cross-account target no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoTrustArn), wantErr: "AccessDenied"},
|
|
{name: "cross-account target missing ec2 permission", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoEc2PermissionArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testOnUpdateCatalogCases(ctx, t, p, []onUpdateCatalogCase{
|
|
{name: "cross-account happy path", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetArn)},
|
|
{name: "cross-account principal no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalNoTrustArn, crossAccountTargetArn), wantErr: "AccessDenied"},
|
|
{name: "cross-account target no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoTrustArn), wantErr: "AccessDenied"},
|
|
{name: "cross-account target missing ec2 permission", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoEc2PermissionArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testOnCreateSetCases(ctx, t, p, []onSetCase{
|
|
{name: "cross-account happy path", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetArn), tags: cases[0]},
|
|
{name: "cross-account principal no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalNoTrustArn, crossAccountTargetArn), wantErr: "AccessDenied"},
|
|
{name: "cross-account target no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoTrustArn), wantErr: "AccessDenied"},
|
|
{name: "cross-account target missing ec2 permission", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoEc2PermissionArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testOnUpdateSetCases(ctx, t, p, []onSetCase{
|
|
{name: "cross-account happy path", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetArn), tags: cases[0]},
|
|
{name: "cross-account principal no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalNoTrustArn, crossAccountTargetArn), wantErr: "AccessDenied"},
|
|
{name: "cross-account target no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoTrustArn), wantErr: "AccessDenied"},
|
|
{name: "cross-account target missing ec2 permission", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoEc2PermissionArn), wantErr: "UnauthorizedOperation"},
|
|
})
|
|
testListHostsCases(ctx, t, p, []listHostsCase{
|
|
{name: "cross-account happy path", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetArn), tags: cases[0], expected: expectedTargetTagInstancesMap},
|
|
{name: "cross-account principal no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalNoTrustArn, crossAccountTargetArn), tags: cases[0], wantErr: "AccessDenied"},
|
|
{name: "cross-account target no trust", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoTrustArn), tags: cases[0], wantErr: "AccessDenied"},
|
|
{name: "cross-account target missing ec2 permission", catalogAttrs: crossRoleAttrs(targetRegion, crossAccountPrincipalArn, crossAccountTargetNoEc2PermissionArn), tags: cases[0], wantErr: "UnauthorizedOperation"},
|
|
})
|
|
}
|
|
}
|