3ac5a841ec
This is a collection of refactors that make upcoming PRs easier to digest. The main change is the introduction of the authmethod.Identity struct. In the one and only current auth method (type=kubernetes) all of the trusted identity attributes are both selectable and projectable, so they were just passed around as a map[string]string. When namespaces were added, this was slightly changed so that the enterprise metadata can also come back from the login operation, so login now returned two fields. Now with some upcoming auth methods it won't be true that all identity attributes will be both selectable and projectable, so rather than update the login function to return 3 pieces of data it seemed worth it to wrap those fields up and give them a proper name.
720 lines
17 KiB
Go
720 lines
17 KiB
Go
package consul
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"regexp"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/consul/agent/metadata"
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
"github.com/hashicorp/go-version"
|
|
"github.com/hashicorp/serf/serf"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestGetPrivateIP(t *testing.T) {
|
|
t.Parallel()
|
|
ip, _, err := net.ParseCIDR("10.1.2.3/32")
|
|
if err != nil {
|
|
t.Fatalf("failed to parse private cidr: %v", err)
|
|
}
|
|
|
|
pubIP, _, err := net.ParseCIDR("8.8.8.8/32")
|
|
if err != nil {
|
|
t.Fatalf("failed to parse public cidr: %v", err)
|
|
}
|
|
|
|
tests := []struct {
|
|
addrs []net.Addr
|
|
expected net.IP
|
|
err error
|
|
}{
|
|
{
|
|
addrs: []net.Addr{
|
|
&net.IPAddr{
|
|
IP: ip,
|
|
},
|
|
&net.IPAddr{
|
|
IP: pubIP,
|
|
},
|
|
},
|
|
expected: ip,
|
|
},
|
|
{
|
|
addrs: []net.Addr{
|
|
&net.IPAddr{
|
|
IP: pubIP,
|
|
},
|
|
},
|
|
err: errors.New("No private IP address found"),
|
|
},
|
|
{
|
|
addrs: []net.Addr{
|
|
&net.IPAddr{
|
|
IP: ip,
|
|
},
|
|
&net.IPAddr{
|
|
IP: ip,
|
|
},
|
|
&net.IPAddr{
|
|
IP: pubIP,
|
|
},
|
|
},
|
|
err: errors.New("Multiple private IPs found. Please configure one."),
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
ip, err := getPrivateIP(test.addrs)
|
|
switch {
|
|
case test.err != nil && err != nil:
|
|
if err.Error() != test.err.Error() {
|
|
t.Fatalf("unexpected error: %v != %v", test.err, err)
|
|
}
|
|
case (test.err == nil && err != nil) || (test.err != nil && err == nil):
|
|
t.Fatalf("unexpected error: %v != %v", test.err, err)
|
|
default:
|
|
if !test.expected.Equal(ip) {
|
|
t.Fatalf("unexpected ip: %v != %v", ip, test.expected)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIsPrivateIP(t *testing.T) {
|
|
t.Parallel()
|
|
if !isPrivateIP("192.168.1.1") {
|
|
t.Fatalf("bad")
|
|
}
|
|
if !isPrivateIP("172.16.45.100") {
|
|
t.Fatalf("bad")
|
|
}
|
|
if !isPrivateIP("10.1.2.3") {
|
|
t.Fatalf("bad")
|
|
}
|
|
if !isPrivateIP("100.115.110.19") {
|
|
t.Fatalf("bad")
|
|
}
|
|
if isPrivateIP("8.8.8.8") {
|
|
t.Fatalf("bad")
|
|
}
|
|
if !isPrivateIP("127.0.0.1") {
|
|
t.Fatalf("bad")
|
|
}
|
|
}
|
|
|
|
func TestUtil_CanServersUnderstandProtocol(t *testing.T) {
|
|
t.Parallel()
|
|
var members []serf.Member
|
|
|
|
// All empty list cases should return false.
|
|
for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if grok {
|
|
t.Fatalf("empty list should always return false")
|
|
}
|
|
}
|
|
|
|
// Add a non-server member.
|
|
members = append(members, serf.Member{
|
|
Tags: map[string]string{
|
|
"vsn_min": fmt.Sprintf("%d", ProtocolVersionMin),
|
|
"vsn_max": fmt.Sprintf("%d", ProtocolVersionMax),
|
|
},
|
|
})
|
|
|
|
// Make sure it doesn't get counted.
|
|
for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if grok {
|
|
t.Fatalf("non-server members should not be counted")
|
|
}
|
|
}
|
|
|
|
// Add a server member.
|
|
members = append(members, serf.Member{
|
|
Tags: map[string]string{
|
|
"role": "consul",
|
|
"vsn_min": fmt.Sprintf("%d", ProtocolVersionMin),
|
|
"vsn_max": fmt.Sprintf("%d", ProtocolVersionMax),
|
|
},
|
|
})
|
|
|
|
// Now it should report that it understands.
|
|
for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if !grok {
|
|
t.Fatalf("server should grok")
|
|
}
|
|
}
|
|
|
|
// Nobody should understand anything from the future.
|
|
for v := uint8(ProtocolVersionMax + 1); v <= uint8(ProtocolVersionMax+10); v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if grok {
|
|
t.Fatalf("server should not grok")
|
|
}
|
|
}
|
|
|
|
// Add an older server.
|
|
members = append(members, serf.Member{
|
|
Tags: map[string]string{
|
|
"role": "consul",
|
|
"vsn_min": fmt.Sprintf("%d", ProtocolVersionMin),
|
|
"vsn_max": fmt.Sprintf("%d", ProtocolVersionMax-1),
|
|
},
|
|
})
|
|
|
|
// The servers should no longer understand the max version.
|
|
for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
expected := v < ProtocolVersionMax
|
|
if grok != expected {
|
|
t.Fatalf("bad: %v != %v", grok, expected)
|
|
}
|
|
}
|
|
|
|
// Try a version that's too low for the minimum.
|
|
{
|
|
grok, err := CanServersUnderstandProtocol(members, 0)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if grok {
|
|
t.Fatalf("server should not grok")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIsConsulNode(t *testing.T) {
|
|
t.Parallel()
|
|
m := serf.Member{
|
|
Tags: map[string]string{
|
|
"role": "node",
|
|
"dc": "east-aws",
|
|
},
|
|
}
|
|
valid, dc := isConsulNode(m)
|
|
if !valid || dc != "east-aws" {
|
|
t.Fatalf("bad: %v %v", valid, dc)
|
|
}
|
|
}
|
|
|
|
func TestByteConversion(t *testing.T) {
|
|
t.Parallel()
|
|
var val uint64 = 2 << 50
|
|
raw := uint64ToBytes(val)
|
|
if bytesToUint64(raw) != val {
|
|
t.Fatalf("no match")
|
|
}
|
|
}
|
|
|
|
func TestGenerateUUID(t *testing.T) {
|
|
t.Parallel()
|
|
prev := generateUUID()
|
|
for i := 0; i < 100; i++ {
|
|
id := generateUUID()
|
|
if prev == id {
|
|
t.Fatalf("Should get a new ID!")
|
|
}
|
|
|
|
matched, err := regexp.MatchString(
|
|
"[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}", id)
|
|
if !matched || err != nil {
|
|
t.Fatalf("expected match %s %v %s", id, matched, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetPublicIPv6(t *testing.T) {
|
|
t.Parallel()
|
|
ip, _, err := net.ParseCIDR("fe80::1/128")
|
|
if err != nil {
|
|
t.Fatalf("failed to parse link-local cidr: %v", err)
|
|
}
|
|
|
|
ip2, _, err := net.ParseCIDR("::1/128")
|
|
if err != nil {
|
|
t.Fatalf("failed to parse loopback cidr: %v", err)
|
|
}
|
|
|
|
ip3, _, err := net.ParseCIDR("fc00::1/128")
|
|
if err != nil {
|
|
t.Fatalf("failed to parse ULA cidr: %v", err)
|
|
}
|
|
|
|
pubIP, _, err := net.ParseCIDR("2001:0db8:85a3::8a2e:0370:7334/128")
|
|
if err != nil {
|
|
t.Fatalf("failed to parse public cidr: %v", err)
|
|
}
|
|
|
|
tests := []struct {
|
|
addrs []net.Addr
|
|
expected net.IP
|
|
err error
|
|
}{
|
|
{
|
|
addrs: []net.Addr{
|
|
&net.IPAddr{
|
|
IP: ip,
|
|
},
|
|
&net.IPAddr{
|
|
IP: ip2,
|
|
},
|
|
&net.IPAddr{
|
|
IP: ip3,
|
|
},
|
|
&net.IPAddr{
|
|
IP: pubIP,
|
|
},
|
|
},
|
|
expected: pubIP,
|
|
},
|
|
{
|
|
addrs: []net.Addr{
|
|
&net.IPAddr{
|
|
IP: ip,
|
|
},
|
|
&net.IPAddr{
|
|
IP: ip2,
|
|
},
|
|
&net.IPAddr{
|
|
IP: ip3,
|
|
},
|
|
},
|
|
err: errors.New("No public IPv6 address found"),
|
|
},
|
|
{
|
|
addrs: []net.Addr{
|
|
&net.IPAddr{
|
|
IP: ip,
|
|
},
|
|
&net.IPAddr{
|
|
IP: ip,
|
|
},
|
|
&net.IPAddr{
|
|
IP: pubIP,
|
|
},
|
|
&net.IPAddr{
|
|
IP: pubIP,
|
|
},
|
|
},
|
|
err: errors.New("Multiple public IPv6 addresses found. Please configure one."),
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
ip, err := getPublicIPv6(test.addrs)
|
|
switch {
|
|
case test.err != nil && err != nil:
|
|
if err.Error() != test.err.Error() {
|
|
t.Fatalf("unexpected error: %v != %v", test.err, err)
|
|
}
|
|
case (test.err == nil && err != nil) || (test.err != nil && err == nil):
|
|
t.Fatalf("unexpected error: %v != %v", test.err, err)
|
|
default:
|
|
if !test.expected.Equal(ip) {
|
|
t.Fatalf("unexpected ip: %v != %v", ip, test.expected)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
type testServersProvider []metadata.Server
|
|
|
|
func (p testServersProvider) CheckServers(datacenter string, fn func(*metadata.Server) bool) {
|
|
for _, srv := range p {
|
|
// filter these out - now I don't have to modify the tests. Originally the dc filtering
|
|
// happened in the ServersInDCMeetMinimumVersion, now we get a list of servers to check
|
|
// through the routing infrastructure or server lookup which will map a datacenter to a
|
|
// list of metadata.Server structs that are all in that datacenter.
|
|
if srv.Datacenter != datacenter {
|
|
continue
|
|
}
|
|
|
|
if !fn(&srv) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestServersInDCMeetMinimumVersion(t *testing.T) {
|
|
t.Parallel()
|
|
makeServer := func(versionStr string, datacenter string) metadata.Server {
|
|
return metadata.Server{
|
|
Name: "foo",
|
|
ShortName: "foo",
|
|
ID: "asdf",
|
|
Port: 10000,
|
|
Expect: 3,
|
|
RaftVersion: 3,
|
|
Status: serf.StatusAlive,
|
|
WanJoinPort: 1234,
|
|
Version: 1,
|
|
Build: *version.Must(version.NewVersion(versionStr)),
|
|
Datacenter: datacenter,
|
|
}
|
|
}
|
|
|
|
cases := []struct {
|
|
servers testServersProvider
|
|
ver *version.Version
|
|
expected bool
|
|
expectedFound bool
|
|
}{
|
|
// One server, meets reqs
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "primary"),
|
|
makeServer("0.7.3", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.7.5")),
|
|
expected: true,
|
|
expectedFound: true,
|
|
},
|
|
// One server, doesn't meet reqs
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "primary"),
|
|
makeServer("0.8.1", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.8.0")),
|
|
expected: false,
|
|
expectedFound: true,
|
|
},
|
|
// Multiple servers, meets req version
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "primary"),
|
|
makeServer("0.8.0", "primary"),
|
|
makeServer("0.7.0", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.7.5")),
|
|
expected: true,
|
|
expectedFound: true,
|
|
},
|
|
// Multiple servers, doesn't meet req version
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "primary"),
|
|
makeServer("0.8.0", "primary"),
|
|
makeServer("0.9.1", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.8.0")),
|
|
expected: false,
|
|
expectedFound: true,
|
|
},
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "secondary"),
|
|
makeServer("0.8.0", "secondary"),
|
|
makeServer("0.9.1", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.7.0")),
|
|
expected: true,
|
|
expectedFound: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
result, found := ServersInDCMeetMinimumVersion(tc.servers, "primary", tc.ver)
|
|
require.Equal(t, tc.expected, result)
|
|
require.Equal(t, tc.expectedFound, found)
|
|
}
|
|
}
|
|
|
|
func TestInterpolateHIL(t *testing.T) {
|
|
for name, test := range map[string]struct {
|
|
in string
|
|
vars map[string]string
|
|
exp string // when lower=false
|
|
expLower string // when lower=true
|
|
ok bool
|
|
}{
|
|
// valid HIL
|
|
"empty": {
|
|
"",
|
|
map[string]string{},
|
|
"",
|
|
"",
|
|
true,
|
|
},
|
|
"no vars": {
|
|
"nothing",
|
|
map[string]string{},
|
|
"nothing",
|
|
"nothing",
|
|
true,
|
|
},
|
|
"just lowercase var": {
|
|
"${item}",
|
|
map[string]string{"item": "value"},
|
|
"value",
|
|
"value",
|
|
true,
|
|
},
|
|
"just uppercase var": {
|
|
"${item}",
|
|
map[string]string{"item": "VaLuE"},
|
|
"VaLuE",
|
|
"value",
|
|
true,
|
|
},
|
|
"lowercase var in middle": {
|
|
"before ${item}after",
|
|
map[string]string{"item": "value"},
|
|
"before valueafter",
|
|
"before valueafter",
|
|
true,
|
|
},
|
|
"uppercase var in middle": {
|
|
"before ${item}after",
|
|
map[string]string{"item": "VaLuE"},
|
|
"before VaLuEafter",
|
|
"before valueafter",
|
|
true,
|
|
},
|
|
"two vars": {
|
|
"before ${item}after ${more}",
|
|
map[string]string{"item": "value", "more": "xyz"},
|
|
"before valueafter xyz",
|
|
"before valueafter xyz",
|
|
true,
|
|
},
|
|
"missing map val": {
|
|
"${item}",
|
|
map[string]string{"item": ""},
|
|
"",
|
|
"",
|
|
true,
|
|
},
|
|
// "weird" HIL, but not technically invalid
|
|
"just end": {
|
|
"}",
|
|
map[string]string{},
|
|
"}",
|
|
"}",
|
|
true,
|
|
},
|
|
"var without start": {
|
|
" item }",
|
|
map[string]string{"item": "value"},
|
|
" item }",
|
|
" item }",
|
|
true,
|
|
},
|
|
"two vars missing second start": {
|
|
"before ${ item }after more }",
|
|
map[string]string{"item": "value", "more": "xyz"},
|
|
"before valueafter more }",
|
|
"before valueafter more }",
|
|
true,
|
|
},
|
|
// invalid HIL
|
|
"just start": {
|
|
"${",
|
|
map[string]string{},
|
|
"",
|
|
"",
|
|
false,
|
|
},
|
|
"backwards": {
|
|
"}${",
|
|
map[string]string{},
|
|
"",
|
|
"",
|
|
false,
|
|
},
|
|
"no varname": {
|
|
"${}",
|
|
map[string]string{},
|
|
"",
|
|
"",
|
|
false,
|
|
},
|
|
"missing map key": {
|
|
"${item}",
|
|
map[string]string{},
|
|
"",
|
|
"",
|
|
false,
|
|
},
|
|
"var without end": {
|
|
"${ item ",
|
|
map[string]string{"item": "value"},
|
|
"",
|
|
"",
|
|
false,
|
|
},
|
|
"two vars missing first end": {
|
|
"before ${ item after ${ more }",
|
|
map[string]string{"item": "value", "more": "xyz"},
|
|
"",
|
|
"",
|
|
false,
|
|
},
|
|
} {
|
|
test := test
|
|
t.Run(name+" lower=false", func(t *testing.T) {
|
|
out, err := InterpolateHIL(test.in, test.vars, false)
|
|
if test.ok {
|
|
require.NoError(t, err)
|
|
require.Equal(t, test.exp, out)
|
|
} else {
|
|
require.NotNil(t, err)
|
|
require.Equal(t, out, "")
|
|
}
|
|
})
|
|
t.Run(name+" lower=true", func(t *testing.T) {
|
|
out, err := InterpolateHIL(test.in, test.vars, true)
|
|
if test.ok {
|
|
require.NoError(t, err)
|
|
require.Equal(t, test.expLower, out)
|
|
} else {
|
|
require.NotNil(t, err)
|
|
require.Equal(t, out, "")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestServersGetACLMode(t *testing.T) {
|
|
t.Parallel()
|
|
makeServer := func(datacenter string, acls structs.ACLMode, status serf.MemberStatus, addr net.IP) metadata.Server {
|
|
return metadata.Server{
|
|
Name: "foo",
|
|
ShortName: "foo",
|
|
ID: "asdf",
|
|
Port: 10000,
|
|
Expect: 3,
|
|
RaftVersion: 3,
|
|
Status: status,
|
|
WanJoinPort: 1234,
|
|
Version: 1,
|
|
Addr: &net.TCPAddr{IP: addr, Port: 10000},
|
|
// shouldn't matter for these tests
|
|
Build: *version.Must(version.NewVersion("1.7.0")),
|
|
Datacenter: datacenter,
|
|
ACLs: acls,
|
|
}
|
|
}
|
|
|
|
type tcase struct {
|
|
servers testServersProvider
|
|
leaderAddr string
|
|
datacenter string
|
|
foundServers bool
|
|
minMode structs.ACLMode
|
|
leaderMode structs.ACLMode
|
|
}
|
|
|
|
cases := map[string]tcase{
|
|
"filter-members": tcase{
|
|
servers: testServersProvider{
|
|
makeServer("primary", structs.ACLModeLegacy, serf.StatusAlive, net.IP([]byte{127, 0, 0, 1})),
|
|
makeServer("primary", structs.ACLModeLegacy, serf.StatusFailed, net.IP([]byte{127, 0, 0, 2})),
|
|
// filtered datacenter
|
|
makeServer("secondary", structs.ACLModeUnknown, serf.StatusAlive, net.IP([]byte{127, 0, 0, 4})),
|
|
// filtered status
|
|
makeServer("primary", structs.ACLModeUnknown, serf.StatusLeaving, net.IP([]byte{127, 0, 0, 5})),
|
|
// filtered status
|
|
makeServer("primary", structs.ACLModeUnknown, serf.StatusLeft, net.IP([]byte{127, 0, 0, 6})),
|
|
// filtered status
|
|
makeServer("primary", structs.ACLModeUnknown, serf.StatusNone, net.IP([]byte{127, 0, 0, 7})),
|
|
},
|
|
foundServers: true,
|
|
leaderAddr: "127.0.0.1:10000",
|
|
datacenter: "primary",
|
|
minMode: structs.ACLModeLegacy,
|
|
leaderMode: structs.ACLModeLegacy,
|
|
},
|
|
"disabled": tcase{
|
|
servers: testServersProvider{
|
|
makeServer("primary", structs.ACLModeLegacy, serf.StatusAlive, net.IP([]byte{127, 0, 0, 1})),
|
|
makeServer("primary", structs.ACLModeUnknown, serf.StatusAlive, net.IP([]byte{127, 0, 0, 2})),
|
|
makeServer("primary", structs.ACLModeDisabled, serf.StatusAlive, net.IP([]byte{127, 0, 0, 3})),
|
|
},
|
|
foundServers: true,
|
|
leaderAddr: "127.0.0.1:10000",
|
|
datacenter: "primary",
|
|
minMode: structs.ACLModeDisabled,
|
|
leaderMode: structs.ACLModeLegacy,
|
|
},
|
|
"unknown": tcase{
|
|
servers: testServersProvider{
|
|
makeServer("primary", structs.ACLModeLegacy, serf.StatusAlive, net.IP([]byte{127, 0, 0, 1})),
|
|
makeServer("primary", structs.ACLModeUnknown, serf.StatusAlive, net.IP([]byte{127, 0, 0, 2})),
|
|
},
|
|
foundServers: true,
|
|
leaderAddr: "127.0.0.1:10000",
|
|
datacenter: "primary",
|
|
minMode: structs.ACLModeUnknown,
|
|
leaderMode: structs.ACLModeLegacy,
|
|
},
|
|
"legacy": tcase{
|
|
servers: testServersProvider{
|
|
makeServer("primary", structs.ACLModeEnabled, serf.StatusAlive, net.IP([]byte{127, 0, 0, 1})),
|
|
makeServer("primary", structs.ACLModeLegacy, serf.StatusAlive, net.IP([]byte{127, 0, 0, 2})),
|
|
},
|
|
foundServers: true,
|
|
leaderAddr: "127.0.0.1:10000",
|
|
datacenter: "primary",
|
|
minMode: structs.ACLModeLegacy,
|
|
leaderMode: structs.ACLModeEnabled,
|
|
},
|
|
"enabled": tcase{
|
|
servers: testServersProvider{
|
|
makeServer("primary", structs.ACLModeEnabled, serf.StatusAlive, net.IP([]byte{127, 0, 0, 1})),
|
|
makeServer("primary", structs.ACLModeEnabled, serf.StatusAlive, net.IP([]byte{127, 0, 0, 2})),
|
|
makeServer("primary", structs.ACLModeEnabled, serf.StatusAlive, net.IP([]byte{127, 0, 0, 3})),
|
|
},
|
|
foundServers: true,
|
|
leaderAddr: "127.0.0.1:10000",
|
|
datacenter: "primary",
|
|
minMode: structs.ACLModeEnabled,
|
|
leaderMode: structs.ACLModeEnabled,
|
|
},
|
|
"failed-members": tcase{
|
|
servers: testServersProvider{
|
|
makeServer("primary", structs.ACLModeLegacy, serf.StatusAlive, net.IP([]byte{127, 0, 0, 1})),
|
|
makeServer("primary", structs.ACLModeUnknown, serf.StatusFailed, net.IP([]byte{127, 0, 0, 2})),
|
|
makeServer("primary", structs.ACLModeLegacy, serf.StatusFailed, net.IP([]byte{127, 0, 0, 3})),
|
|
},
|
|
foundServers: true,
|
|
leaderAddr: "127.0.0.1:10000",
|
|
datacenter: "primary",
|
|
minMode: structs.ACLModeUnknown,
|
|
leaderMode: structs.ACLModeLegacy,
|
|
},
|
|
}
|
|
|
|
for name, tc := range cases {
|
|
name := name
|
|
tc := tc
|
|
t.Run(name, func(t *testing.T) {
|
|
actualServers, actualMinMode, actualLeaderMode := ServersGetACLMode(tc.servers, tc.leaderAddr, tc.datacenter)
|
|
|
|
require.Equal(t, tc.minMode, actualMinMode)
|
|
require.Equal(t, tc.leaderMode, actualLeaderMode)
|
|
require.Equal(t, tc.foundServers, actualServers)
|
|
})
|
|
}
|
|
}
|