Rather than pick addresses totally at random, this changes the preference to be private IP4 > public IP4 > DNS. (Ordering is not guaranteed, but in many cases there will only be one of each type of IP anyways.) All three of these are preferred over IP6, which also goes public > private. This seems likely to match the common case where you're getting into a machine on the private side from the public side. It's harder to know if DNS is private or not, so IPs are preferred in this case.
153 lines
4.0 KiB
Go
153 lines
4.0 KiB
Go
package endpoint
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestPreferencer(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ctx := context.Background()
|
|
|
|
t.Run("badOption", func(t *testing.T) {
|
|
_, err := NewPreferencer(ctx, WithPreferenceOrder([]string{"bad:1.2.3.4"}))
|
|
assert.Error(t, err)
|
|
})
|
|
t.Run("goodOption", func(t *testing.T) {
|
|
_, err := NewPreferencer(ctx, WithPreferenceOrder([]string{"cidr:1.2.3.4"}))
|
|
assert.NoError(t, err)
|
|
})
|
|
t.Run("chooseBadOption", func(t *testing.T) {
|
|
p, err := NewPreferencer(ctx)
|
|
require.NoError(t, err)
|
|
_, err = p.Choose(ctx, WithIpAddrs([]string{"266.1.2.3"}))
|
|
assert.Error(t, err)
|
|
})
|
|
t.Run("noAddresses", func(t *testing.T) {
|
|
p, err := NewPreferencer(ctx)
|
|
require.NoError(t, err)
|
|
_, err = p.Choose(ctx)
|
|
assert.Error(t, err)
|
|
})
|
|
t.Run("preferenceOrder", func(t *testing.T) {
|
|
p, err := NewPreferencer(ctx,
|
|
WithPreferenceOrder([]string{
|
|
"cidr:1.2.3.4/24",
|
|
"dns:*.example.com",
|
|
"cidr:5.6.7.8/8",
|
|
"dns:*.company.com",
|
|
}))
|
|
require.NoError(t, err)
|
|
|
|
cases := []struct {
|
|
name string
|
|
withIpAddrs []string
|
|
withDnsNames []string
|
|
expectedEndpoint string
|
|
expectedErrorContains string
|
|
}{
|
|
{
|
|
name: "first cidr",
|
|
withIpAddrs: []string{"5.6.7.8", "1.2.3.56"},
|
|
withDnsNames: []string{"foo.bar", "bar.baz"},
|
|
expectedEndpoint: "1.2.3.56",
|
|
},
|
|
{
|
|
name: "first dns",
|
|
withIpAddrs: []string{"48.134.5.1", "1.2.7.56"},
|
|
withDnsNames: []string{"bar.baz", "foo.example.com"},
|
|
expectedEndpoint: "foo.example.com",
|
|
},
|
|
{
|
|
name: "second cidr",
|
|
withIpAddrs: []string{"5.6.7.8", "1.2.7.56"},
|
|
withDnsNames: []string{"foo.bar", "bar.baz"},
|
|
expectedEndpoint: "5.6.7.8",
|
|
},
|
|
{
|
|
name: "second dns",
|
|
withIpAddrs: []string{"48.134.5.1", "1.2.7.56"},
|
|
withDnsNames: []string{"foo.bar.com", "bar.company.com"},
|
|
expectedEndpoint: "bar.company.com",
|
|
},
|
|
{
|
|
name: "no match",
|
|
withIpAddrs: []string{"48.134.5.1", "1.2.7.56"},
|
|
withDnsNames: []string{"foo.bar.com", "bar.baz.com"},
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
out, err := p.Choose(ctx, WithIpAddrs(tc.withIpAddrs), WithDnsNames(tc.withDnsNames))
|
|
if tc.expectedErrorContains != "" {
|
|
require.Error(t, err)
|
|
assert.Contains(t, tc.expectedErrorContains, err.Error())
|
|
}
|
|
assert.Equal(t, tc.expectedEndpoint, out)
|
|
})
|
|
}
|
|
})
|
|
t.Run("noPrefReturnsPrivate", func(t *testing.T) {
|
|
const privAddr = "192.168.4.3"
|
|
p, err := NewPreferencer(ctx)
|
|
require.NoError(t, err)
|
|
out, err := p.Choose(
|
|
ctx,
|
|
WithIpAddrs([]string{"48.134.5.1", "2001::1", privAddr}),
|
|
WithDnsNames([]string{"foo.bar.com", "bar.baz.com"}),
|
|
)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, privAddr, out)
|
|
})
|
|
t.Run("noPrefNoPrivateReturnsIp4", func(t *testing.T) {
|
|
const exp = "48.134.5.1"
|
|
p, err := NewPreferencer(ctx)
|
|
require.NoError(t, err)
|
|
out, err := p.Choose(
|
|
ctx,
|
|
WithIpAddrs([]string{"2001::1", exp}),
|
|
WithDnsNames([]string{"foo.bar.com", "bar.baz.com"}),
|
|
)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, exp, out)
|
|
})
|
|
t.Run("noPrefNoIp4ReturnsDns", func(t *testing.T) {
|
|
const exp = "foo.bar.com"
|
|
p, err := NewPreferencer(ctx)
|
|
require.NoError(t, err)
|
|
out, err := p.Choose(
|
|
ctx,
|
|
WithIpAddrs([]string{"2001::1"}),
|
|
WithDnsNames([]string{exp}),
|
|
)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, exp, out)
|
|
})
|
|
t.Run("ip6OnlyReturnsPrivate", func(t *testing.T) {
|
|
const exp = "fc00::1"
|
|
p, err := NewPreferencer(ctx)
|
|
require.NoError(t, err)
|
|
out, err := p.Choose(
|
|
ctx,
|
|
WithIpAddrs([]string{"2001::1", exp}),
|
|
)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, exp, out)
|
|
})
|
|
t.Run("ip6OnlyPublic", func(t *testing.T) {
|
|
const exp = "2001::1"
|
|
p, err := NewPreferencer(ctx)
|
|
require.NoError(t, err)
|
|
out, err := p.Choose(
|
|
ctx,
|
|
WithIpAddrs([]string{exp}),
|
|
)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, exp, out)
|
|
})
|
|
}
|