Skip to content

Commit 2af9223

Browse files
committed
raft: handle retry_join as blocks
Signed-off-by: Ryan Cragun <[email protected]>
1 parent 180d65d commit 2af9223

File tree

5 files changed

+130
-43
lines changed

5 files changed

+130
-43
lines changed

command/server/config.go

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,19 +1072,33 @@ func normalizeStorageConfigAddresses(storage string, key string, value string) (
10721072
func normalizeRaftRetryJoin(val any) ([]byte, error) {
10731073
res := []map[string]any{}
10741074

1075-
retryJoin, ok := val.([]any)
1076-
if !ok {
1077-
return nil, fmt.Errorf("malformed retry_join stanza: %v+", val)
1078-
}
1079-
1080-
for _, rj := range retryJoin {
1081-
rjMap, ok := rj.(map[string]any)
1075+
// Depending on whether the retry_join stanzas were configured as an attribute,
1076+
// a block, or a mixture of both, we'll get different values from which we
1077+
// need to extract our individual retry joins stanzas.
1078+
stanzas := []map[string]any{}
1079+
if retryJoin, ok := val.([]map[string]any); ok {
1080+
// retry_join stanzas are defined as blocks
1081+
stanzas = retryJoin
1082+
} else {
1083+
// retry_join stanzas are defined as attributes or attributes and blocks
1084+
retryJoin, ok := val.([]any)
10821085
if !ok {
1083-
return nil, fmt.Errorf("malformed retry_join stanza: %v+", rj)
1086+
// retry_join stanzas have not been configured correctly
1087+
return nil, fmt.Errorf("malformed retry_join stanza: %v", val)
10841088
}
10851089

1086-
rjRes := map[string]any{}
1087-
for k, v := range rjMap {
1090+
for _, stanza := range retryJoin {
1091+
stanzaVal, ok := stanza.(map[string]any)
1092+
if !ok {
1093+
return nil, fmt.Errorf("malformed retry_join stanza: %v", stanza)
1094+
}
1095+
stanzas = append(stanzas, stanzaVal)
1096+
}
1097+
}
1098+
1099+
for _, stanza := range stanzas {
1100+
normalizedStanza := map[string]any{}
1101+
for k, v := range stanza {
10881102
switch k {
10891103
case "auto_join":
10901104
pairs := strings.Split(v.(string), " ")
@@ -1100,15 +1114,15 @@ func normalizeRaftRetryJoin(val any) ([]byte, error) {
11001114
pairs[i] = pair
11011115
}
11021116
}
1103-
rjRes[k] = strings.Join(pairs, " ")
1117+
normalizedStanza[k] = strings.Join(pairs, " ")
11041118
case "leader_api_addr":
1105-
rjRes[k] = configutil.NormalizeAddr(v.(string))
1119+
normalizedStanza[k] = configutil.NormalizeAddr(v.(string))
11061120
default:
1107-
rjRes[k] = v
1121+
normalizedStanza[k] = v
11081122
}
11091123
}
11101124

1111-
res = append(res, rjRes)
1125+
res = append(res, normalizedStanza)
11121126
}
11131127

11141128
return json.Marshal(res)

command/server/config_test_helpers.go

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@ func boolPointer(x bool) *bool {
3232

3333
// testConfigRaftRetryJoin decodes and normalizes retry_join stanzas.
3434
func testConfigRaftRetryJoin(t *testing.T) {
35-
t.Helper()
36-
config, err := LoadConfigFile("./test-fixtures/raft_retry_join.hcl")
37-
if err != nil {
38-
t.Fatal(err)
39-
}
35+
t.Parallel()
4036

4137
retryJoinExpected := []map[string]string{
4238
{"leader_api_addr": "http://127.0.0.1:8200"},
@@ -47,32 +43,44 @@ func testConfigRaftRetryJoin(t *testing.T) {
4743
{"auto_join": "provider=packet auth_token=token project=uuid url=https://[2001:db8::2:1] address_type=public_v6"},
4844
{"auto_join": "provider=vsphere category_name=consul-role tag_name=consul-server host=https://[2001:db8::2:1] user=foo password=bar insecure_ssl=false"},
4945
}
50-
retryJoinJSON, err := json.Marshal(retryJoinExpected)
51-
require.NoError(t, err)
46+
for _, cfg := range []string{
47+
"attr",
48+
"block",
49+
"mixed",
50+
} {
51+
t.Run(cfg, func(t *testing.T) {
52+
t.Parallel()
5253

53-
expected := &Config{
54-
SharedConfig: &configutil.SharedConfig{
55-
Listeners: []*configutil.Listener{
56-
{
57-
Type: "tcp",
58-
Address: "127.0.0.1:8200",
59-
CustomResponseHeaders: DefaultCustomHeaders,
54+
config, err := LoadConfigFile(fmt.Sprintf("./test-fixtures/raft_retry_join_%s.hcl", cfg))
55+
require.NoError(t, err)
56+
retryJoinJSON, err := json.Marshal(retryJoinExpected)
57+
require.NoError(t, err)
58+
59+
expected := &Config{
60+
SharedConfig: &configutil.SharedConfig{
61+
Listeners: []*configutil.Listener{
62+
{
63+
Type: "tcp",
64+
Address: "127.0.0.1:8200",
65+
CustomResponseHeaders: DefaultCustomHeaders,
66+
},
67+
},
68+
DisableMlock: true,
6069
},
61-
},
62-
DisableMlock: true,
63-
},
6470

65-
Storage: &Storage{
66-
Type: "raft",
67-
Config: map[string]string{
68-
"path": "/storage/path/raft",
69-
"node_id": "raft1",
70-
"retry_join": string(retryJoinJSON),
71-
},
72-
},
71+
Storage: &Storage{
72+
Type: "raft",
73+
Config: map[string]string{
74+
"path": "/storage/path/raft",
75+
"node_id": "raft1",
76+
"retry_join": string(retryJoinJSON),
77+
},
78+
},
79+
}
80+
config.Prune()
81+
require.EqualValues(t, expected, config)
82+
})
7383
}
74-
config.Prune()
75-
require.EqualValues(t, expected, config)
7684
}
7785

7886
func testLoadConfigFile_topLevel(t *testing.T, entropy *configutil.Entropy) {

command/server/test-fixtures/raft_retry_join.hcl renamed to command/server/test-fixtures/raft_retry_join_attr.hcl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ storage "raft" {
66
node_id = "raft1"
77
retry_join = [
88
{ "leader_api_addr" = "http://127.0.0.1:8200" },
9-
]
10-
retry_join = [
119
{ "leader_api_addr" = "http://[2001:db8:0:0:0:0:2:1]:8200" }
1210
]
1311
retry_join = [
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright (c) HashiCorp, Inc.
2+
# SPDX-License-Identifier: BUSL-1.1
3+
4+
storage "raft" {
5+
path = "/storage/path/raft"
6+
node_id = "raft1"
7+
8+
retry_join {
9+
"leader_api_addr" = "http://127.0.0.1:8200"
10+
}
11+
retry_join {
12+
"leader_api_addr" = "http://[2001:db8:0:0:0:0:2:1]:8200"
13+
}
14+
retry_join {
15+
"auto_join" = "provider=mdns service=consul domain=2001:db8:0:0:0:0:2:1"
16+
}
17+
retry_join {
18+
"auto_join" = "provider=os tag_key=consul tag_value=server username=foo password=bar auth_url=https://[2001:db8:0:0:0:0:2:1]/auth"
19+
}
20+
retry_join {
21+
"auto_join" = "provider=triton account=testaccount url=https://[2001:db8:0:0:0:0:2:1] key_id=1234 tag_key=consul-role tag_value=server"
22+
}
23+
retry_join {
24+
"auto_join" = "provider=packet auth_token=token project=uuid url=https://[2001:db8:0:0:0:0:2:1] address_type=public_v6"
25+
}
26+
retry_join {
27+
"auto_join" = "provider=vsphere category_name=consul-role tag_name=consul-server host=https://[2001:db8:0:0:0:0:2:1] user=foo password=bar insecure_ssl=false"
28+
}
29+
}
30+
31+
listener "tcp" {
32+
address = "127.0.0.1:8200"
33+
}
34+
35+
disable_mlock = true
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Copyright (c) HashiCorp, Inc.
2+
# SPDX-License-Identifier: BUSL-1.1
3+
4+
storage "raft" {
5+
path = "/storage/path/raft"
6+
node_id = "raft1"
7+
retry_join = [
8+
{ "leader_api_addr" = "http://127.0.0.1:8200" },
9+
{ "leader_api_addr" = "http://[2001:db8:0:0:0:0:2:1]:8200" }
10+
]
11+
retry_join {
12+
"auto_join" = "provider=mdns service=consul domain=2001:db8:0:0:0:0:2:1"
13+
}
14+
retry_join = [
15+
{ "auto_join" = "provider=os tag_key=consul tag_value=server username=foo password=bar auth_url=https://[2001:db8:0:0:0:0:2:1]/auth" }
16+
]
17+
retry_join {
18+
"auto_join" = "provider=triton account=testaccount url=https://[2001:db8:0:0:0:0:2:1] key_id=1234 tag_key=consul-role tag_value=server"
19+
}
20+
retry_join = [
21+
{ "auto_join" = "provider=packet auth_token=token project=uuid url=https://[2001:db8:0:0:0:0:2:1] address_type=public_v6" }
22+
]
23+
retry_join {
24+
"auto_join" = "provider=vsphere category_name=consul-role tag_name=consul-server host=https://[2001:db8:0:0:0:0:2:1] user=foo password=bar insecure_ssl=false"
25+
}
26+
}
27+
28+
listener "tcp" {
29+
address = "127.0.0.1:8200"
30+
}
31+
32+
disable_mlock = true

0 commit comments

Comments
 (0)