Skip to content

Commit

Permalink
Merge pull request #217 from linode/dual-stack-support
Browse files Browse the repository at this point in the history
include ipv6 address for node external IPs
  • Loading branch information
AshleyDumaine authored Jun 20, 2024
2 parents 71e7855 + 43db50f commit 4cda99a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 11 deletions.
17 changes: 11 additions & 6 deletions cloud/linode/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"slices"
"strconv"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -36,8 +37,8 @@ type nodeCache struct {
ttl time.Duration
}

// getInstanceIPv4Addresses returns all ipv4 addresses configured on a linode.
func (nc *nodeCache) getInstanceIPv4Addresses(instance linodego.Instance, vpcips []string) []nodeIP {
// getInstanceAddresses returns all addresses configured on a linode.
func (nc *nodeCache) getInstanceAddresses(instance linodego.Instance, vpcips []string) []nodeIP {
ips := []nodeIP{}

// If vpc ips are present, list them first
Expand All @@ -54,6 +55,10 @@ func (nc *nodeCache) getInstanceIPv4Addresses(instance linodego.Instance, vpcips
ips = append(ips, nodeIP{ip: ip.String(), ipType: ipType})
}

if instance.IPv6 != "" {
ips = append(ips, nodeIP{ip: strings.TrimSuffix(instance.IPv6, "/128"), ipType: v1.NodeExternalIP})
}

return ips
}

Expand Down Expand Up @@ -97,7 +102,7 @@ func (nc *nodeCache) refreshInstances(ctx context.Context, client client.Client)
}
node := linodeInstance{
instance: &instances[i],
ips: nc.getInstanceIPv4Addresses(instance, vpcNodes[instance.ID]),
ips: nc.getInstanceAddresses(instance, vpcNodes[instance.ID]),
}
newNodes[instance.ID] = node
}
Expand Down Expand Up @@ -141,7 +146,7 @@ func (i *instances) linodeByIP(kNode *v1.Node) (*linodego.Instance, error) {
defer i.nodeCache.RUnlock()
var kNodeAddresses []string
for _, address := range kNode.Status.Addresses {
if address.Type == "ExternalIP" || address.Type == "InternalIP" {
if address.Type == v1.NodeExternalIP || address.Type == v1.NodeInternalIP {
kNodeAddresses = append(kNodeAddresses, address.Address)
}
}
Expand Down Expand Up @@ -262,7 +267,7 @@ func (i *instances) InstanceMetadata(ctx context.Context, node *v1.Node) (*cloud
return nil, err
}

ips, err := i.getLinodeIPv4Addresses(ctx, node)
ips, err := i.getLinodeAddresses(ctx, node)
if err != nil {
sentry.CaptureError(ctx, err)
return nil, err
Expand Down Expand Up @@ -291,7 +296,7 @@ func (i *instances) InstanceMetadata(ctx context.Context, node *v1.Node) (*cloud
return meta, nil
}

func (i *instances) getLinodeIPv4Addresses(ctx context.Context, node *v1.Node) ([]nodeIP, error) {
func (i *instances) getLinodeAddresses(ctx context.Context, node *v1.Node) ([]nodeIP, error) {
ctx = sentry.SetHubOnContext(ctx)
instance, err := i.lookupLinode(ctx, node)
if err != nil {
Expand Down
23 changes: 18 additions & 5 deletions cloud/linode/instances_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,38 +144,51 @@ func TestMetadataRetrieval(t *testing.T) {

ipTests := []struct {
name string
inputIPs []string
inputIPv4s []string
inputIPv6 string
outputAddresses []v1.NodeAddress
expectedErr error
}{
{"no IPs", nil, nil, instanceNoIPAddressesError{192910}},
{"no IPs", nil, "", nil, instanceNoIPAddressesError{192910}},
{
"one public, one private",
[]string{"32.74.121.25", "192.168.121.42"},
"",
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}, {Type: v1.NodeInternalIP, Address: "192.168.121.42"}},
nil,
},
{
"one public ipv4, one public ipv6",
[]string{"32.74.121.25"},
"2600:3c06::f03c:94ff:fe1e:e072",
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}, {Type: v1.NodeExternalIP, Address: "2600:3c06::f03c:94ff:fe1e:e072"}},
nil,
},
{
"one public, no private",
[]string{"32.74.121.25"},
"",
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}},
nil,
},
{
"one private, no public",
[]string{"192.168.121.42"},
"",
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "192.168.121.42"}},
nil,
},
{
"two public addresses",
[]string{"32.74.121.25", "32.74.121.22"},
"",
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "32.74.121.25"}, {Type: v1.NodeExternalIP, Address: "32.74.121.22"}},
nil,
},
{
"two private addresses",
[]string{"192.168.121.42", "10.0.2.15"},
"",
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "192.168.121.42"}, {Type: v1.NodeInternalIP, Address: "10.0.2.15"}},
nil,
},
Expand All @@ -189,8 +202,8 @@ func TestMetadataRetrieval(t *testing.T) {
providerID := providerIDPrefix + strconv.Itoa(id)
node := nodeWithProviderID(providerID)

ips := make([]*net.IP, 0, len(test.inputIPs))
for _, ip := range test.inputIPs {
ips := make([]*net.IP, 0, len(test.inputIPv4s))
for _, ip := range test.inputIPv4s {
parsed := net.ParseIP(ip)
if parsed == nil {
t.Fatalf("cannot parse %v as an ipv4", ip)
Expand All @@ -201,7 +214,7 @@ func TestMetadataRetrieval(t *testing.T) {
linodeType := "g6-standard-1"
region := "us-east"
client.EXPECT().ListInstances(gomock.Any(), nil).Times(1).Return([]linodego.Instance{
{ID: id, Label: name, Type: linodeType, Region: region, IPv4: ips},
{ID: id, Label: name, Type: linodeType, Region: region, IPv4: ips, IPv6: test.inputIPv6},
}, nil)

meta, err := instances.InstanceMetadata(ctx, node)
Expand Down

0 comments on commit 4cda99a

Please sign in to comment.