fix(igw): write attachment State="attached" for AWS parity

Reconciler intent loader (network/reconcile/intent.go::loadIGWs) filters
IGW records with `State == "attached"`, but AttachInternetGateway was
writing `State = "available"`. The reconciler therefore never picked up
any attached IGW — `intent_igws=0` on every pass — so the OVN external
switch + gateway LRP + WAN bridge wiring built by IGWManager.AttachIGW
never ran for default-VPC IGWs (whose live `vpc.igw-attach` publish at
daemon bootstrap is lost — vpcd subscriber not yet wired).

Net effect on single-node e2e: every SSH probe to 192.168.x public IPs
timed out (TestSSHProbe, TestModifyInstanceAttribute, TestRebootInstance,
TestNATGateway, TestSGToSGDatapath) because SNAT/DNAT rules on the VPC
router had no path to the external network.

Match AWS InternetGatewayAttachment.State semantics:
 - Attach: State="attached"
 - Detach: State="detached"

Detach value is internal — recordToEC2 gates Attachments on VpcId != "",
so the detached State is never surfaced to API consumers.

Bead: mulga-siv-131
This commit is contained in:
joshsiv-mulga
2026-05-24 20:10:49 +10:00
parent b2390fb398
commit b7505f8b5f
2 changed files with 4 additions and 4 deletions
+2 -2
View File
@@ -291,7 +291,7 @@ func (s *IGWServiceImpl) AttachInternetGateway(input *ec2.AttachInternetGatewayI
}
record.VpcId = vpcID
record.State = "available"
record.State = "attached"
data, err := json.Marshal(record)
if err != nil {
@@ -349,7 +349,7 @@ func (s *IGWServiceImpl) DetachInternetGateway(input *ec2.DetachInternetGatewayI
}
record.VpcId = ""
record.State = "available"
record.State = "detached"
data, err := json.Marshal(record)
if err != nil {
@@ -191,7 +191,7 @@ func TestAttachInternetGateway(t *testing.T) {
require.Len(t, desc.InternetGateways, 1)
require.Len(t, desc.InternetGateways[0].Attachments, 1)
assert.Equal(t, "vpc-test123", *desc.InternetGateways[0].Attachments[0].VpcId)
assert.Equal(t, "available", *desc.InternetGateways[0].Attachments[0].State)
assert.Equal(t, "attached", *desc.InternetGateways[0].Attachments[0].State)
}
func TestAttachInternetGateway_NotFound(t *testing.T) {
@@ -527,7 +527,7 @@ func TestDescribeInternetGateways_FilterByAttachmentState(t *testing.T) {
desc, err := svc.DescribeInternetGateways(&ec2.DescribeInternetGatewaysInput{
Filters: []*ec2.Filter{
{Name: aws.String("attachment.state"), Values: []*string{aws.String("available")}},
{Name: aws.String("attachment.state"), Values: []*string{aws.String("attached")}},
},
}, testAccountID)
require.NoError(t, err)