Skip to content

Commit

Permalink
fixes auto_join for mDNS provider (#25080)
Browse files Browse the repository at this point in the history
* fixes auto_join for mDNS provider

* adds a function to format addresses returned by go-discover

* adds copyright header in raft_rest.go

* Adds changelog file for PR #25080, godoc for TestFormatDiscoveredAddr

---------

Co-authored-by: Violet Hynes <[email protected]>
  • Loading branch information
aubrich and VioletHynes authored Jun 10, 2024
1 parent f7c1679 commit d64856c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
3 changes: 3 additions & 0 deletions changelog/25080.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
storage/raft: Fix auto_join not working with mDNS provider.
```
27 changes: 21 additions & 6 deletions vault/raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/base64"
"errors"
"fmt"
"net"
"net/http"
"net/url"
"strings"
Expand Down Expand Up @@ -1227,17 +1228,15 @@ func (c *Core) raftLeaderInfo(leaderInfo *raft.LeaderJoinInfo, disco *discover.D
// default to 8200 when no port is provided
port = 8200
}
// Addrs returns either IPv4 or IPv6 address, without scheme or port
// Addrs returns either IPv4 or IPv6 address, without scheme and most of them without port
// IPv6 can be explicit such as "[::1]" or implicit "::1"
clusterIPs, err := disco.Addrs(leaderInfo.AutoJoin, c.logger.StandardLogger(nil))
if err != nil {
return nil, fmt.Errorf("failed to parse addresses from auto-join metadata: %w", err)
}
for _, ip := range clusterIPs {
if strings.Count(ip, ":") >= 2 && !strings.HasPrefix(ip, "[") {
// An IPv6 address in implicit form, however we need it in explicit form to use in a URL.
ip = fmt.Sprintf("[%s]", ip)
}
u := fmt.Sprintf("%s://%s:%d", scheme, ip, port)
addr := formatDiscoveredAddr(ip, port)
u := fmt.Sprintf("%s://%s", scheme, addr)
info := *leaderInfo
info.LeaderAPIAddr = u
ret = append(ret, &info)
Expand Down Expand Up @@ -1459,3 +1458,19 @@ func newDiscover() (*discover.Discover, error) {
discover.WithProviders(providers),
)
}

// formatDiscoveredAddr joins ip and port if addr does not already contain a port
func formatDiscoveredAddr(addr string, defaultPort uint) string {
// addr is an implicit IPv6 address
if !strings.HasPrefix(addr, "[") && strings.Count(addr, ":") > 1 {
return fmt.Sprintf("[%s]:%d", addr, defaultPort)
}
ip, port, err := net.SplitHostPort(addr)
if err != nil {
return fmt.Sprintf("%s:%d", addr, defaultPort)
}
if strings.ContainsRune(ip, ':') {
ip = fmt.Sprintf("[%s]", ip)
}
return fmt.Sprintf("%s:%s", ip, port)
}
33 changes: 33 additions & 0 deletions vault/raft_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package vault

import (
"testing"
)

// TestFormatDiscoveredAddr validates that the string returned by formatDiscoveredAddr always respect the format `host:port`.
func TestFormatDiscoveredAddr(t *testing.T) {
type TestCase struct {
addr string
port uint
res string
}
cases := []TestCase{
{addr: "127.0.0.1", port: uint(8200), res: "127.0.0.1:8200"},
{addr: "192.168.137.1:8201", port: uint(8200), res: "192.168.137.1:8201"},
{addr: "fe80::aa5e:45ff:fe54:c6ce", port: uint(8200), res: "[fe80::aa5e:45ff:fe54:c6ce]:8200"},
{addr: "::1", port: uint(8200), res: "[::1]:8200"},
{addr: "[::1]", port: uint(8200), res: "[::1]:8200"},
{addr: "[::1]:8201", port: uint(8200), res: "[::1]:8201"},
{addr: "[fe80::aa5e:45ff:fe54:c6ce]", port: uint(8200), res: "[fe80::aa5e:45ff:fe54:c6ce]:8200"},
{addr: "[fe80::aa5e:45ff:fe54:c6ce]:8201", port: uint(8200), res: "[fe80::aa5e:45ff:fe54:c6ce]:8201"},
}
for i, c := range cases {
res := formatDiscoveredAddr(c.addr, c.port)
if res != c.res {
t.Errorf("case %d result shoud be \"%s\" but is \"%s\"", i, c.res, res)
}
}
}

0 comments on commit d64856c

Please sign in to comment.