* feat(tests) Add Terraform testing to support Cross-account discovery **Problem** * To support cross-account DHC discovery, we need to add terraform configurations and tests to test against live AWS data. * However, there was nothing in place to support any AssumeRole testing, irrespective of cross-account. **Solution** * Added a new terraform file, iam_assume_role.tf, to contain the new terraform configurations for single-account AssumeRole and cross-role * Added a second terraform file, iam_cross_account.tf, to contain the new terraform configurations for cross-account * Refactored how the tests are organized. The previous static test cases used a system where a separate function was created for each test. This was moved to a dedicated file, e2e_host_static_test.go. * For AssumeRole tests (single account, cross role, and cross account), this system wasn't ideal since there are so many test cases and they are all extremely similar. A table driven system was better that passed in a set of variables to shared test helpers. A dedicated file, e2e_host_assumerole_test.go, was created to contain the testing infrastructure for AssumeRole tests. * e2e_host_test.go remains the main test runner that then calls e2e_host_assumerole_test.go and e2e_host_static_test.go * The terraform tests work by setting environment variables for the AWS account that you want to configure the terraform for. The existing setup worked for single-account and cross-role. However, to support cross-account, support had to be added for a second set of credentials. The second set of environment variables can now be set with the TARGET_ prefix. Some configuration in testing.go had to be added to support creating/destroying multiple terraform setups. **Testing** * The single account tests pass as expected. However, a bug was discovered during this process that will be addressed later. * The cross-role and cross-account tests failed as expected because this featured has not yet been delivered. * It was noticed that some of the existing static tests were flaky. The problem and fix were identified and will be addressed later.
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"
|
|
|
|
"github.com/hashicorp/boundary-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"},
|
|
})
|
|
}
|
|
}
|