From a41590eb77dcc15adafd833c21cd1bb42c72bab4 Mon Sep 17 00:00:00 2001 From: justinsb Date: Sat, 24 Feb 2024 13:08:03 -0500 Subject: [PATCH] gce: match IP addresses including subnet where relevant We can have the same internal IP address on different subnets, so when trying to find the cloud resource by IP address, we need to match considering the subnet when matching internal IP addresses. --- upup/pkg/fi/cloudup/gcetasks/address.go | 34 ++++++++++++++----- .../pkg/fi/cloudup/gcetasks/forwardingrule.go | 4 +-- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/upup/pkg/fi/cloudup/gcetasks/address.go b/upup/pkg/fi/cloudup/gcetasks/address.go index 4730680041..4e0020daaa 100644 --- a/upup/pkg/fi/cloudup/gcetasks/address.go +++ b/upup/pkg/fi/cloudup/gcetasks/address.go @@ -64,25 +64,43 @@ func (e *Address) Find(c *fi.CloudupContext) (*Address, error) { return actual, err } -func findAddressByIP(cloud gce.GCECloud, ip string) (*Address, error) { - // Technically this is a regex, but it doesn't matter... +func findAddressByIP(cloud gce.GCECloud, ip string, subnet string) (*Address, error) { + // Technically this is a regex, but it doesn't matter, it's a prefilter addrs, err := cloud.Compute().Addresses().ListWithFilter(cloud.Project(), cloud.Region(), "address eq "+ip) if err != nil { return nil, fmt.Errorf("error listing IP Addresses: %v", err) } - if len(addrs) == 0 { + var matches []*compute.Address + for _, addr := range addrs { + if subnet != "" && addr.Subnetwork != subnet { + continue + } + if addr.Address == ip { + matches = append(matches, addr) + } + } + + if len(matches) == 0 { return nil, nil } - if len(addrs) > 1 { + + if len(matches) > 1 { return nil, fmt.Errorf("found multiple Addresses matching %q", ip) } + addr := matches[0] + actual := &Address{} - actual.IPAddress = &addrs[0].Address - actual.IPAddressType = &addrs[0].AddressType - actual.Purpose = &addrs[0].Purpose - actual.Name = &addrs[0].Name + actual.IPAddress = &addr.Address + actual.IPAddressType = &addr.AddressType + actual.Purpose = &addr.Purpose + actual.Name = &addr.Name + if addr.Subnetwork != "" { + actual.Subnetwork = &Subnet{ + Name: fi.PtrTo(lastComponent(addr.Subnetwork)), + } + } return actual, nil } diff --git a/upup/pkg/fi/cloudup/gcetasks/forwardingrule.go b/upup/pkg/fi/cloudup/gcetasks/forwardingrule.go index dbc79b44c2..55b162bc37 100644 --- a/upup/pkg/fi/cloudup/gcetasks/forwardingrule.go +++ b/upup/pkg/fi/cloudup/gcetasks/forwardingrule.go @@ -95,9 +95,9 @@ func (e *ForwardingRule) Find(c *fi.CloudupContext) (*ForwardingRule, error) { } } if r.IPAddress != "" { - address, err := findAddressByIP(cloud, r.IPAddress) + address, err := findAddressByIP(cloud, r.IPAddress, r.Subnetwork) if err != nil { - return nil, fmt.Errorf("error finding Address with IP=%q: %v", r.IPAddress, err) + return nil, fmt.Errorf("error finding Address with IP=%q: %w", r.IPAddress, err) } actual.IPAddress = address }