From 6f0df81d2ba5b18b2648c293733bd7aeaa35e9c5 Mon Sep 17 00:00:00 2001 From: Matt Romanelli Date: Wed, 23 Sep 2026 15:47:34 -0500 Subject: [PATCH] Testing gaps --- testing/e2e_host_assumerole_test.go | 16 ++++++ testing/e2e_host_test.go | 17 ++---- testing/testdata/host/iam_cross_account.tf | 65 ++++++++++++++++++++++ 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/testing/e2e_host_assumerole_test.go b/testing/e2e_host_assumerole_test.go index 6708976..f589540 100644 --- a/testing/e2e_host_assumerole_test.go +++ b/testing/e2e_host_assumerole_test.go @@ -54,6 +54,21 @@ func tagFilterSetAttrs(tags []string) map[string]any { } } +// buildExpectedTagInstancesMap builds a map of tag key to instance IDs from a Terraform instance_tags output map. +func buildExpectedTagInstancesMap(rawTags map[string]any, expectedTags []string) map[string][]string { + tagMap := make(map[string][]string) + for instanceId, instanceTags := range rawTags { + for tagKey := range instanceTags.(map[string]any) { + for _, expectedTag := range expectedTags { + if tagKey == expectedTag { + tagMap[tagKey] = append(tagMap[tagKey], instanceId) + } + } + } + } + return tagMap +} + // --------------------------------------------------------------------------- // Table-driven runners // --------------------------------------------------------------------------- @@ -271,3 +286,4 @@ func testListHostsCases(ctx context.Context, t *testing.T, p *host.HostPlugin, c }) } } + diff --git a/testing/e2e_host_test.go b/testing/e2e_host_test.go index 5eee736..6f052d8 100644 --- a/testing/e2e_host_test.go +++ b/testing/e2e_host_test.go @@ -162,16 +162,7 @@ func TestHostPlugin(t *testing.T) { // 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 := make(map[string][]string) - for instanceId, instanceTags := range ec2InstanceTags { - for tagKey := range instanceTags.(map[string]any) { - for _, expectedTag := range expectedTags { - if tagKey == expectedTag { - expectedTagInstancesMap[tagKey] = append(expectedTagInstancesMap[tagKey], instanceId) - } - } - } - } + expectedTagInstancesMap := buildExpectedTagInstancesMap(ec2InstanceTags, expectedTags) cases := [][]string{ {expectedTags[0]}, @@ -310,6 +301,10 @@ func TestHostPlugin(t *testing.T) { crossAccountTargetNoEc2PermissionArn, err := tf.GetOutputString("cross_account_target_no_ec2_permission_arn") require.NoError(err) + targetEc2InstanceTags, err := tf.GetOutputMap("target_instance_tags") + require.NoError(err) + expectedTargetTagInstancesMap := buildExpectedTagInstancesMap(targetEc2InstanceTags, expectedTags) + 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"}, @@ -335,7 +330,7 @@ func TestHostPlugin(t *testing.T) { {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: expectedTagInstancesMap}, + {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"}, diff --git a/testing/testdata/host/iam_cross_account.tf b/testing/testdata/host/iam_cross_account.tf index 30af38a..fa74717 100644 --- a/testing/testdata/host/iam_cross_account.tf +++ b/testing/testdata/host/iam_cross_account.tf @@ -255,3 +255,68 @@ resource "aws_iam_role" "cross_account_target_no_trust" { output "cross_account_target_no_trust_arn" { value = aws_iam_role.cross_account_target_no_trust.arn } + +# --------------------------------------------------------------------------- +# Account B: EC2 instance for cross-account host discovery validation +# --------------------------------------------------------------------------- + +data "aws_availability_zones" "target_azs" { + count = var.target_access_key_id != "" ? 1 : 0 + provider = aws.target +} + +data "aws_ami" "target_ubuntu" { + count = var.target_access_key_id != "" ? 1 : 0 + provider = aws.target + most_recent = true + + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + owners = ["099720109477"] # Canonical +} + +resource "aws_vpc" "target_vpc" { + count = var.target_access_key_id != "" ? 1 : 0 + provider = aws.target + cidr_block = "10.1.0.0/16" + assign_generated_ipv6_cidr_block = true +} + +resource "aws_subnet" "target_subnet" { + count = var.target_access_key_id != "" ? 1 : 0 + provider = aws.target + vpc_id = aws_vpc.target_vpc[0].id + cidr_block = aws_vpc.target_vpc[0].cidr_block + ipv6_cidr_block = cidrsubnet(aws_vpc.target_vpc[0].ipv6_cidr_block, 8, 0) + availability_zone = data.aws_availability_zones.target_azs[0].names[0] + map_public_ip_on_launch = true + assign_ipv6_address_on_creation = true +} + +resource "aws_instance" "target_instances" { + count = var.target_access_key_id != "" ? length(local.instance_tags) : 0 + provider = aws.target + ami = data.aws_ami.target_ubuntu[0].id + instance_type = "t3.nano" + subnet_id = aws_subnet.target_subnet[0].id + + tags = local.instance_tags[count.index] +} + +output "target_instance_ids" { + value = aws_instance.target_instances.*.id +} + +output "target_instance_tags" { + value = { + for _, r in aws_instance.target_instances : r.id => r.tags + } +}