[fix] allow IPv6 controllers, workers, and targets (#5221)
Co-authored-by: Damian Debkowski <damian.debkowski@hashicorp.com>
This commit is contained in:
1 parent
680bb02af9
commit
62c41191ff
42 files changed
+1996
-546
No files matched your search
+18
-14
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
"github.com/hashicorp/boundary/internal/util"
|
||||
"github.com/hashicorp/boundary/testing/dbtest"
|
||||
capoidc "github.com/hashicorp/cap/oidc"
|
||||
"github.com/jimlambrt/gldap"
|
||||
@@ -242,13 +243,9 @@ func (b *Server) CreateDevLdapAuthMethod(ctx context.Context) error {
|
||||
if purpose != "api" {
|
||||
continue
|
||||
}
|
||||
host, _, err = net.SplitHostPort(ln.Config.Address)
|
||||
host, _, err = util.SplitHostPort(ln.Config.Address)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
host = ln.Config.Address
|
||||
} else {
|
||||
return fmt.Errorf("error splitting host/port: %w", err)
|
||||
}
|
||||
return fmt.Errorf("error splitting host/port: %w", err)
|
||||
}
|
||||
}
|
||||
if host == "" {
|
||||
@@ -259,6 +256,16 @@ func (b *Server) CreateDevLdapAuthMethod(ctx context.Context) error {
|
||||
tb := &oidcLogger{}
|
||||
|
||||
port = testdirectory.FreePort(tb)
|
||||
|
||||
// The util.SplitHostPort() method removes the square brackets that enclose the
|
||||
// host address when the address type is ipv6. The square brackets must be
|
||||
// added back, otherwise the gldap server will fail to start due to a parsing
|
||||
// error.
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
if ip.To16() != nil {
|
||||
host = fmt.Sprintf("[%s]", host)
|
||||
}
|
||||
}
|
||||
b.DevLdapSetup.testDirectory = testdirectory.Start(tb,
|
||||
testdirectory.WithNoTLS(tb),
|
||||
testdirectory.WithHost(tb, host),
|
||||
@@ -455,15 +462,12 @@ func (b *Server) CreateDevOidcAuthMethod(ctx context.Context) error {
|
||||
if purpose != "api" {
|
||||
continue
|
||||
}
|
||||
b.DevOidcSetup.hostAddr, b.DevOidcSetup.callbackPort, err = net.SplitHostPort(ln.Config.Address)
|
||||
b.DevOidcSetup.hostAddr, b.DevOidcSetup.callbackPort, err = util.SplitHostPort(ln.Config.Address)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
b.DevOidcSetup.hostAddr = ln.Config.Address
|
||||
// Use the default API port in the callback
|
||||
b.DevOidcSetup.callbackPort = "9200"
|
||||
} else {
|
||||
return fmt.Errorf("error splitting host/port: %w", err)
|
||||
}
|
||||
return fmt.Errorf("error splitting host/port: %w", err)
|
||||
}
|
||||
if b.DevOidcSetup.callbackPort == "" {
|
||||
b.DevOidcSetup.callbackPort = "9200"
|
||||
}
|
||||
}
|
||||
if b.DevOidcSetup.hostAddr == "" {
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
_ "crypto/sha512"
|
||||
"crypto/tls"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/util"
|
||||
"github.com/hashicorp/go-secure-stdlib/listenerutil"
|
||||
"github.com/hashicorp/go-secure-stdlib/reloadutil"
|
||||
"github.com/mitchellh/cli"
|
||||
@@ -137,24 +138,22 @@ func tcpListenerFactory(purpose string, l *listenerutil.ListenerConfig, ui cli.U
|
||||
}
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(l.Address)
|
||||
host, port, err := util.SplitHostPort(l.Address)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
switch purpose {
|
||||
case "api":
|
||||
port = "9200"
|
||||
case "cluster":
|
||||
port = "9201"
|
||||
case "proxy":
|
||||
port = "9202"
|
||||
case "ops":
|
||||
port = "9203"
|
||||
default:
|
||||
return "", nil, errors.New("no purpose provided for listener and no port discoverable")
|
||||
}
|
||||
host = l.Address
|
||||
} else {
|
||||
return "", nil, fmt.Errorf("error splitting host/port: %w", err)
|
||||
return "", nil, fmt.Errorf("error splitting host/port: %w", err)
|
||||
}
|
||||
if port == "" {
|
||||
switch purpose {
|
||||
case "api":
|
||||
port = "9200"
|
||||
case "cluster":
|
||||
port = "9201"
|
||||
case "proxy":
|
||||
port = "9202"
|
||||
case "ops":
|
||||
port = "9203"
|
||||
default:
|
||||
return "", nil, errors.New("no purpose provided for listener and no port discoverable")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -58,10 +56,6 @@ const (
|
||||
WorkerAuthReqFile = "auth_request_token"
|
||||
)
|
||||
|
||||
// This regular expression is used to find all instances of square brackets within a string.
|
||||
// This regular expression is used to remove the square brackets from an IPv6 address.
|
||||
var squareBrackets = regexp.MustCompile("\\[|\\]")
|
||||
|
||||
func init() {
|
||||
metric.InitializeBuildInfo(prometheus.DefaultRegisterer)
|
||||
}
|
||||
@@ -841,20 +835,14 @@ func (b *Server) SetupWorkerPublicAddress(conf *config.Config, flagValue string)
|
||||
}
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(conf.Worker.PublicAddr)
|
||||
host, port, err := util.SplitHostPort(conf.Worker.PublicAddr)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
port = "9202"
|
||||
host = conf.Worker.PublicAddr
|
||||
} else {
|
||||
return fmt.Errorf("Error splitting public adddress host/port: %w", err)
|
||||
}
|
||||
return fmt.Errorf("Error splitting public adddress host/port: %w", err)
|
||||
}
|
||||
|
||||
// remove the square brackets from the ipv6 address because the method
|
||||
// net.JoinHostPort() will add a second pair of square brackets.
|
||||
host = squareBrackets.ReplaceAllString(host, "")
|
||||
conf.Worker.PublicAddr = net.JoinHostPort(host, port)
|
||||
if port == "" {
|
||||
port = "9202"
|
||||
}
|
||||
conf.Worker.PublicAddr = util.JoinHostPort(host, port)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -22,6 +21,7 @@ import (
|
||||
apiproxy "github.com/hashicorp/boundary/api/proxy"
|
||||
"github.com/hashicorp/boundary/api/targets"
|
||||
"github.com/hashicorp/boundary/internal/cmd/base"
|
||||
"github.com/hashicorp/boundary/internal/util"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
"go.uber.org/atomic"
|
||||
@@ -476,14 +476,10 @@ func (c *Command) Run(args []string) (retCode int) {
|
||||
|
||||
proxyAddr := clientProxy.ListenerAddress(context.Background())
|
||||
var clientProxyHost, clientProxyPort string
|
||||
clientProxyHost, clientProxyPort, err = net.SplitHostPort(proxyAddr)
|
||||
clientProxyHost, clientProxyPort, err = util.SplitHostPort(proxyAddr)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
clientProxyHost = proxyAddr
|
||||
} else {
|
||||
c.PrintCliError(fmt.Errorf("error splitting listener addr: %w", err))
|
||||
return base.CommandCliError
|
||||
}
|
||||
c.PrintCliError(fmt.Errorf("error splitting listener addr: %w", err))
|
||||
return base.CommandCliError
|
||||
}
|
||||
c.sessInfo.Address = clientProxyHost
|
||||
|
||||
@@ -605,15 +601,11 @@ func (c *Command) handleExec(clientProxy *apiproxy.ClientProxy, passthroughArgs
|
||||
addr := clientProxy.ListenerAddress(context.Background())
|
||||
var host, port string
|
||||
var err error
|
||||
host, port, err = net.SplitHostPort(addr)
|
||||
host, port, err = util.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
host = addr
|
||||
} else {
|
||||
c.PrintCliError(fmt.Errorf("Error splitting listener addr: %w", err))
|
||||
c.execCmdReturnValue.Store(int32(3))
|
||||
return
|
||||
}
|
||||
c.PrintCliError(fmt.Errorf("Error splitting listener addr: %w", err))
|
||||
c.execCmdReturnValue.Store(int32(3))
|
||||
return
|
||||
}
|
||||
|
||||
var args []string
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -27,6 +26,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/server"
|
||||
"github.com/hashicorp/boundary/internal/server/store"
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
"github.com/hashicorp/boundary/internal/util"
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
"github.com/hashicorp/go-secure-stdlib/strutil"
|
||||
"github.com/hashicorp/nodeenrollment"
|
||||
@@ -592,13 +592,10 @@ func (c *Command) Run(args []string) int {
|
||||
return base.CommandUserError
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(c.flagHostAddress)
|
||||
host, port, err := util.SplitHostPort(c.flagHostAddress)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "missing port") {
|
||||
c.UI.Error(fmt.Errorf("Invalid host address specified: %w", err).Error())
|
||||
return base.CommandUserError
|
||||
}
|
||||
host = c.flagHostAddress
|
||||
c.UI.Error(fmt.Errorf("Invalid host address specified: %w", err).Error())
|
||||
return base.CommandUserError
|
||||
}
|
||||
if port != "" {
|
||||
c.UI.Error(`Port must not be specified as part of the dev host address`)
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/event"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/hashicorp/boundary/internal/util"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-secure-stdlib/mlock"
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
@@ -355,14 +356,10 @@ func (c *Command) Run(args []string) int {
|
||||
}
|
||||
}
|
||||
for _, upstream := range c.Config.Worker.InitialUpstreams {
|
||||
host, _, err := net.SplitHostPort(upstream)
|
||||
host, _, err := util.SplitHostPort(upstream)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), globals.MissingPortErrStr) {
|
||||
host = upstream
|
||||
} else {
|
||||
c.UI.Error(fmt.Errorf("Invalid worker upstream address %q: %w", upstream, err).Error())
|
||||
return base.CommandUserError
|
||||
}
|
||||
c.UI.Error(fmt.Errorf("Invalid worker upstream address %q: %w", upstream, err).Error())
|
||||
return base.CommandUserError
|
||||
}
|
||||
ip := net.ParseIP(host)
|
||||
if ip != nil {
|
||||
@@ -413,14 +410,10 @@ func (c *Command) Run(args []string) int {
|
||||
if purpose != "cluster" {
|
||||
continue
|
||||
}
|
||||
host, _, err := net.SplitHostPort(ln.Address)
|
||||
host, _, err := util.SplitHostPort(ln.Address)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), globals.MissingPortErrStr) {
|
||||
host = ln.Address
|
||||
} else {
|
||||
c.UI.Error(fmt.Errorf("Invalid cluster listener address %q: %w", ln.Address, err).Error())
|
||||
return base.CommandUserError
|
||||
}
|
||||
c.UI.Error(fmt.Errorf("Invalid cluster listener address %q: %w", ln.Address, err).Error())
|
||||
return base.CommandUserError
|
||||
}
|
||||
ip := net.ParseIP(host)
|
||||
if ip != nil {
|
||||
|
||||
+111
-32
@@ -15,7 +15,6 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -103,6 +102,84 @@ listener "tcp" {
|
||||
purpose = "ops"
|
||||
tls_disable = true
|
||||
}
|
||||
`
|
||||
|
||||
devIpv6ControllerExtraConfig = `
|
||||
controller {
|
||||
name = "dev-controller"
|
||||
description = "A default controller created in dev mode"
|
||||
}
|
||||
|
||||
kms "aead" {
|
||||
purpose = "root"
|
||||
aead_type = "aes-gcm"
|
||||
key = "%s"
|
||||
key_id = "global_root"
|
||||
}
|
||||
|
||||
kms "aead" {
|
||||
purpose = "worker-auth"
|
||||
aead_type = "aes-gcm"
|
||||
key = "%s"
|
||||
key_id = "global_worker-auth"
|
||||
}
|
||||
|
||||
kms "aead" {
|
||||
purpose = "bsr"
|
||||
aead_type = "aes-gcm"
|
||||
key = "%s"
|
||||
key_id = "global_bsr"
|
||||
}
|
||||
|
||||
kms "aead" {
|
||||
purpose = "recovery"
|
||||
aead_type = "aes-gcm"
|
||||
key = "%s"
|
||||
key_id = "global_recovery"
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "[::1]"
|
||||
purpose = "api"
|
||||
tls_disable = true
|
||||
cors_enabled = true
|
||||
cors_allowed_origins = ["*"]
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "[::1]"
|
||||
purpose = "cluster"
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "[::1]"
|
||||
purpose = "ops"
|
||||
tls_disable = true
|
||||
}
|
||||
`
|
||||
|
||||
devIpv6WorkerExtraConfig = `
|
||||
listener "tcp" {
|
||||
address = "[::1]"
|
||||
purpose = "proxy"
|
||||
}
|
||||
|
||||
worker {
|
||||
name = "w_1234567890"
|
||||
description = "A default worker created in dev mode"
|
||||
public_addr = "[::1]"
|
||||
initial_upstreams = ["[::1]"]
|
||||
tags {
|
||||
type = ["dev", "local"]
|
||||
}
|
||||
}
|
||||
|
||||
kms "aead" {
|
||||
purpose = "worker-auth-storage"
|
||||
aead_type = "aes-gcm"
|
||||
key = "%s"
|
||||
key_id = "worker-auth-storage"
|
||||
}
|
||||
`
|
||||
|
||||
devWorkerExtraConfig = `
|
||||
@@ -133,10 +210,6 @@ kms "aead" {
|
||||
defaultCsp = "default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; frame-src 'self'; font-src 'self'; connect-src 'self'; img-src 'self' data:; style-src 'self'; media-src 'self'; manifest-src 'self'; style-src-attr 'self'; frame-ancestors 'self'"
|
||||
)
|
||||
|
||||
// This regular expression is used to find all instances of square brackets within a string.
|
||||
// This regular expression is used to remove the square brackets from an IPv6 address.
|
||||
var squareBrackets = regexp.MustCompile("\\[|\\]")
|
||||
|
||||
// Config is the configuration for the boundary controller
|
||||
type Config struct {
|
||||
*configutil.SharedConfig `hcl:"-"`
|
||||
@@ -378,15 +451,18 @@ type License struct {
|
||||
// WithAuditEventsEnabled, TestWithErrorEventsEnabled
|
||||
func DevWorker(opt ...Option) (*Config, error) {
|
||||
workerAuthStorageKey := DevKeyGeneration()
|
||||
hclStr := fmt.Sprintf(devConfig+devWorkerExtraConfig, workerAuthStorageKey)
|
||||
parsed, err := Parse(hclStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing dev config: %w", err)
|
||||
}
|
||||
opts, err := getOpts(opt...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing options: %w", err)
|
||||
}
|
||||
hclStr := fmt.Sprintf(devConfig+devWorkerExtraConfig, workerAuthStorageKey)
|
||||
if opts.withIPv6Enabled {
|
||||
hclStr = fmt.Sprintf(devConfig+devIpv6WorkerExtraConfig, workerAuthStorageKey)
|
||||
}
|
||||
parsed, err := Parse(hclStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing dev config: %w", err)
|
||||
}
|
||||
parsed.Eventing.AuditEnabled = opts.withAuditEventsEnabled
|
||||
parsed.Eventing.ObservationsEnabled = opts.withObservationsEnabled
|
||||
parsed.Eventing.SysEventsEnabled = opts.withSysEventsEnabled
|
||||
@@ -414,12 +490,20 @@ func DevKeyGeneration() string {
|
||||
// DevController is a Config that is used for dev mode of Boundary
|
||||
// controllers
|
||||
func DevController(opt ...Option) (*Config, error) {
|
||||
opts, err := getOpts(opt...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing options: %w", err)
|
||||
}
|
||||
|
||||
controllerKey := DevKeyGeneration()
|
||||
workerAuthKey := DevKeyGeneration()
|
||||
bsrKey := DevKeyGeneration()
|
||||
recoveryKey := DevKeyGeneration()
|
||||
|
||||
hclStr := fmt.Sprintf(devConfig+devControllerExtraConfig, controllerKey, workerAuthKey, bsrKey, recoveryKey)
|
||||
if opts.withIPv6Enabled {
|
||||
hclStr = fmt.Sprintf(devConfig+devIpv6ControllerExtraConfig, controllerKey, workerAuthKey, bsrKey, recoveryKey)
|
||||
}
|
||||
parsed, err := Parse(hclStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing dev config: %w", err)
|
||||
@@ -429,10 +513,6 @@ func DevController(opt ...Option) (*Config, error) {
|
||||
parsed.DevWorkerAuthKey = workerAuthKey
|
||||
parsed.DevBsrKey = bsrKey
|
||||
parsed.DevRecoveryKey = recoveryKey
|
||||
opts, err := getOpts(opt...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing options: %w", err)
|
||||
}
|
||||
parsed.Eventing.AuditEnabled = opts.withAuditEventsEnabled
|
||||
parsed.Eventing.ObservationsEnabled = opts.withObservationsEnabled
|
||||
parsed.Eventing.SysEventsEnabled = opts.withSysEventsEnabled
|
||||
@@ -440,13 +520,22 @@ func DevController(opt ...Option) (*Config, error) {
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
func DevCombined() (*Config, error) {
|
||||
func DevCombined(opt ...Option) (*Config, error) {
|
||||
opts, err := getOpts(opt...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing options: %w", err)
|
||||
}
|
||||
|
||||
controllerKey := DevKeyGeneration()
|
||||
workerAuthKey := DevKeyGeneration()
|
||||
workerAuthStorageKey := DevKeyGeneration()
|
||||
bsrKey := DevKeyGeneration()
|
||||
recoveryKey := DevKeyGeneration()
|
||||
|
||||
hclStr := fmt.Sprintf(devConfig+devControllerExtraConfig+devWorkerExtraConfig, controllerKey, workerAuthKey, bsrKey, recoveryKey, workerAuthStorageKey)
|
||||
if opts.withIPv6Enabled {
|
||||
hclStr = fmt.Sprintf(devConfig+devIpv6ControllerExtraConfig+devIpv6WorkerExtraConfig, controllerKey, workerAuthKey, bsrKey, recoveryKey, workerAuthStorageKey)
|
||||
}
|
||||
parsed, err := Parse(hclStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing dev config: %w", err)
|
||||
@@ -1255,20 +1344,14 @@ func (c *Config) SetupControllerPublicClusterAddress(flagValue string) error {
|
||||
}
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(c.Controller.PublicClusterAddr)
|
||||
host, port, err := util.SplitHostPort(c.Controller.PublicClusterAddr)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
port = "9201"
|
||||
host = c.Controller.PublicClusterAddr
|
||||
} else {
|
||||
return fmt.Errorf("Error splitting public cluster adddress host/port: %w", err)
|
||||
}
|
||||
return fmt.Errorf("Error splitting public cluster adddress host/port: %w", err)
|
||||
}
|
||||
|
||||
// remove the square brackets from the ipv6 address because the method
|
||||
// net.JoinHostPort() will add a second pair of square brackets.
|
||||
host = squareBrackets.ReplaceAllString(host, "")
|
||||
c.Controller.PublicClusterAddr = net.JoinHostPort(host, port)
|
||||
if port == "" {
|
||||
port = "9201"
|
||||
}
|
||||
c.Controller.PublicClusterAddr = util.JoinHostPort(host, port)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1322,11 +1405,7 @@ func (c *Config) SetupWorkerInitialUpstreams() error {
|
||||
break
|
||||
}
|
||||
// Best effort see if it's a domain name and if not assume it must match
|
||||
host, _, err := net.SplitHostPort(c.Worker.InitialUpstreams[0])
|
||||
if err != nil && strings.Contains(err.Error(), globals.MissingPortErrStr) {
|
||||
err = nil
|
||||
host = c.Worker.InitialUpstreams[0]
|
||||
}
|
||||
host, _, err := util.SplitHostPort(c.Worker.InitialUpstreams[0])
|
||||
if err == nil {
|
||||
ip := net.ParseIP(host)
|
||||
if ip == nil {
|
||||
|
||||
@@ -6,6 +6,7 @@ package config
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
|
||||
"github.com/hashicorp/boundary/internal/event"
|
||||
"github.com/hashicorp/boundary/internal/ratelimit"
|
||||
"github.com/hashicorp/boundary/internal/util"
|
||||
configutil "github.com/hashicorp/go-secure-stdlib/configutil/v2"
|
||||
"github.com/hashicorp/go-secure-stdlib/listenerutil"
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
@@ -779,6 +781,101 @@ func TestDevWorkerRecordingStoragePath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDevControllerIpv6(t *testing.T) {
|
||||
require, assert := require.New(t), assert.New(t)
|
||||
// This test only validates that all listeners are utilizing an IPv6 address.
|
||||
// Other dev controller configurations are validates in TestDevController.
|
||||
actual, err := DevController(WithIPv6Enabled(true))
|
||||
require.NoError(err)
|
||||
|
||||
// expected an error here because we purposely did not provide a port number
|
||||
// to allow randomly assigned port values
|
||||
_, _, err = net.SplitHostPort(actual.Controller.PublicClusterAddr)
|
||||
require.Error(err)
|
||||
|
||||
// assert the square brackets are removed from the host ipv6 address and that the port value is empty
|
||||
publicAddr, port, err := util.SplitHostPort(actual.Controller.PublicClusterAddr)
|
||||
require.NoError(err)
|
||||
assert.Empty(port)
|
||||
assert.Empty(publicAddr)
|
||||
|
||||
require.NotEmpty(actual.Listeners)
|
||||
for _, l := range actual.Listeners {
|
||||
addr, _, err := util.SplitHostPort(l.Address)
|
||||
require.NoError(err)
|
||||
ip := net.ParseIP(addr)
|
||||
assert.NotNil(ip, "failed to parse listener address for %v", l.Purpose)
|
||||
assert.NotNil(ip.To16(), "failed to convert address to IPv6 for %v, found %v", l.Purpose, addr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDevWorkerIpv6(t *testing.T) {
|
||||
require, assert := require.New(t), assert.New(t)
|
||||
// This test only validates that all listeners are utilizing an IPv6 address.
|
||||
// Other dev worker configurations are validates in TestDevWorker.
|
||||
actual, err := DevWorker(WithIPv6Enabled(true))
|
||||
require.NoError(err)
|
||||
|
||||
// expected an error here because we purposely did not provide a port number
|
||||
// to allow randomly assigned port values
|
||||
_, _, err = net.SplitHostPort(actual.Worker.PublicAddr)
|
||||
require.Error(err)
|
||||
|
||||
// assert the square brackets are removed from the worker ipv6 address and that the port value is empty
|
||||
publicAddr, port, err := util.SplitHostPort(actual.Worker.PublicAddr)
|
||||
require.NoError(err)
|
||||
assert.Empty(port)
|
||||
ip := net.ParseIP(publicAddr)
|
||||
assert.NotNil(ip, "failed to parse worker public address")
|
||||
assert.NotNil(ip.To16(), "worker public address is not IPv6 %s", actual.Worker.PublicAddr)
|
||||
|
||||
require.NotEmpty(actual.Listeners)
|
||||
for _, l := range actual.Listeners {
|
||||
addr, _, err := util.SplitHostPort(l.Address)
|
||||
require.NoError(err)
|
||||
ip := net.ParseIP(addr)
|
||||
assert.NotNil(ip, "failed to parse listener address for %v", l.Purpose)
|
||||
assert.NotNil(ip.To16(), "failed to convert address to IPv6 for %v, found %v", l.Purpose, addr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDevCombinedIpv6(t *testing.T) {
|
||||
require, assert := require.New(t), assert.New(t)
|
||||
// This test only validates that all listeners are utilizing an IPv6 address.
|
||||
actual, err := DevCombined(WithIPv6Enabled(true))
|
||||
require.NoError(err)
|
||||
|
||||
// expected an error here because we purposely did not provide a port number
|
||||
// to allow randomly assigned port values for the worker and controller
|
||||
_, _, err = net.SplitHostPort(actual.Worker.PublicAddr)
|
||||
require.Error(err)
|
||||
_, _, err = net.SplitHostPort(actual.Controller.PublicClusterAddr)
|
||||
require.Error(err)
|
||||
|
||||
// assert the square brackets are removed from the host ipv6 address and that the port value is empty
|
||||
publicAddr, port, err := util.SplitHostPort(actual.Worker.PublicAddr)
|
||||
require.NoError(err)
|
||||
assert.Empty(port)
|
||||
ip := net.ParseIP(publicAddr)
|
||||
assert.NotNil(ip, "failed to parse worker public address")
|
||||
assert.NotNil(ip.To16(), "worker public address is not IPv6 %s", actual.Worker.PublicAddr)
|
||||
|
||||
// assert the square brackets are removed from the controller ipv6 address and that the port value is empty
|
||||
publicAddr, port, err = util.SplitHostPort(actual.Controller.PublicClusterAddr)
|
||||
require.NoError(err)
|
||||
assert.Empty(port)
|
||||
assert.Empty(publicAddr)
|
||||
|
||||
require.NotEmpty(actual.Listeners)
|
||||
for _, l := range actual.Listeners {
|
||||
addr, _, err := util.SplitHostPort(l.Address)
|
||||
require.NoError(err)
|
||||
ip := net.ParseIP(addr)
|
||||
assert.NotNil(ip, "failed to parse listener address for %v", l.Purpose)
|
||||
assert.NotNil(ip.To16(), "failed to convert address to IPv6 for %v, found %v", l.Purpose, addr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDevKeyGeneration(t *testing.T) {
|
||||
t.Parallel()
|
||||
dk := DevKeyGeneration()
|
||||
|
||||
@@ -35,6 +35,7 @@ type options struct {
|
||||
withSysEventsEnabled bool
|
||||
withAuditEventsEnabled bool
|
||||
withObservationsEnabled bool
|
||||
withIPv6Enabled bool
|
||||
testWithErrorEventsEnabled bool
|
||||
}
|
||||
|
||||
@@ -59,6 +60,12 @@ func getDefaultOptions() (options, error) {
|
||||
}
|
||||
opts.withObservationsEnabled = obs
|
||||
|
||||
ipv6, err := parseutil.ParseBool(os.Getenv("BOUNDARY_ENABLE_TEST_IPV6"))
|
||||
if err != nil {
|
||||
return opts, err
|
||||
}
|
||||
opts.withIPv6Enabled = ipv6
|
||||
|
||||
errEvents, err := parseutil.ParseBool(os.Getenv("BOUNDARY_ENABLE_TEST_ERROR_EVENTS"))
|
||||
if err != nil {
|
||||
return opts, err
|
||||
@@ -92,6 +99,14 @@ func WithObservationsEnabled(enable bool) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithIPv6Enabled provides an option for enabling network ipv6 addresses
|
||||
func WithIPv6Enabled(enable bool) Option {
|
||||
return func(o *options) error {
|
||||
o.withIPv6Enabled = enable
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// TestWithErrorEventsEnabled provides an option for enabling error events
|
||||
// during tests.
|
||||
func TestWithErrorEventsEnabled(_ testing.TB, enable bool) Option {
|
||||
|
||||
Reference in new issue
Block a user