Skip to content

Commit

Permalink
Auto-join support for IPv6 discovery (#12366)
Browse files Browse the repository at this point in the history
* Auto-join support for IPv6 discovery

The go-discover library returns IP addresses and not URLs. It just so
happens net.URL parses "127.0.0.1", which isn't a valid URL.

Instead, we construct the URL ourselves. Being careful to check if it's
an ipv6 address and making sure it's in explicit form if so.

Fixes #12323

* feedback: addrs & ipv6 test

Rename addrs to clusterIPs to improve clarity and intent

Tighten up our IPv6 address detection to be more correct and to ensure
it's actually in implicit form
  • Loading branch information
dekimsey committed Sep 7, 2021
1 parent 1fd9fa0 commit e79b352
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 29 deletions.
3 changes: 3 additions & 0 deletions changelog/12366.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
storage/raft: Support `addr_type=public_v6` in auto-join
```
47 changes: 18 additions & 29 deletions vault/raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -947,39 +947,28 @@ func (c *Core) JoinRaftCluster(ctx context.Context, leaderInfos []*raft.LeaderJo
}

case leaderInfo.AutoJoin != "":
addrs, err := disco.Addrs(leaderInfo.AutoJoin, c.logger.StandardLogger(nil))
scheme := leaderInfo.AutoJoinScheme
if scheme == "" {
// default to HTTPS when no scheme is provided
scheme = "https"
}
port := leaderInfo.AutoJoinPort
if port == 0 {
// default to 8200 when no port is provided
port = 8200
}
// Addrs returns either IPv4 or IPv6 address sans scheme or port
clusterIPs, err := disco.Addrs(leaderInfo.AutoJoin, c.logger.StandardLogger(nil))
if err != nil {
c.logger.Error("failed to parse addresses from auto-join metadata", "error", err)
}

for _, addr := range addrs {
u, err := url.Parse(addr)
if err != nil {
c.logger.Error("failed to parse discovered address", "error", err)
continue
}

if u.Scheme == "" {
scheme := leaderInfo.AutoJoinScheme
if scheme == "" {
// default to HTTPS when no scheme is provided
scheme = "https"
}

addr = fmt.Sprintf("%s://%s", scheme, addr)
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)
}

if u.Port() == "" {
port := leaderInfo.AutoJoinPort
if port == 0 {
// default to 8200 when no port is provided
port = 8200
}

addr = fmt.Sprintf("%s:%d", addr, port)
}

if err := joinLeader(leaderInfo, addr); err != nil {
u := fmt.Sprintf("%s://%s:%d", scheme, ip, port)
if err := joinLeader(leaderInfo, u); err != nil {
c.logger.Warn("join attempt failed", "error", err)
} else {
// successfully joined leader
Expand Down

0 comments on commit e79b352

Please sign in to comment.