Merge pull request #1731 from hashicorp/hugoamvieira-gosockaddr-template-support
feature(config): Add go-sockaddr templating support to Controller and Worker Addresses
This commit is contained in:
7 files changed
+664
-14
No files matched your search
@@ -2,6 +2,13 @@
|
||||
|
||||
Canonical reference for changes, improvements, and bugfixes for Boundary.
|
||||
|
||||
## Next
|
||||
|
||||
### New and Improved
|
||||
|
||||
* config: Add support for go-sockaddr templates to Worker and Controller
|
||||
addresses. [(PR)](https://github.com/hashicorp/boundary/pull/1731)
|
||||
|
||||
## 0.7.1 (2021/11/18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -38,9 +38,9 @@ require (
|
||||
github.com/hashicorp/go-secure-stdlib/configutil v0.1.2
|
||||
github.com/hashicorp/go-secure-stdlib/gatedwriter v0.1.1
|
||||
github.com/hashicorp/go-secure-stdlib/kv-builder v0.1.1
|
||||
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.1
|
||||
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.2
|
||||
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.2
|
||||
github.com/hashicorp/go-secure-stdlib/password v0.1.1
|
||||
github.com/hashicorp/go-secure-stdlib/reloadutil v0.1.1
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1
|
||||
@@ -72,7 +72,7 @@ require (
|
||||
github.com/zalando/go-keyring v0.1.1
|
||||
go.uber.org/atomic v1.9.0
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
||||
golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef
|
||||
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1
|
||||
golang.org/x/term v0.0.0-20210916214954-140adaaadfaf
|
||||
golang.org/x/tools v0.1.6
|
||||
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83
|
||||
@@ -100,7 +100,7 @@ require (
|
||||
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||
@@ -135,7 +135,7 @@ require (
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.1.0 // indirect
|
||||
|
||||
@@ -93,8 +93,9 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/ClickHouse/clickhouse-go v1.3.12/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
|
||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
@@ -399,8 +400,9 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
@@ -495,12 +497,14 @@ github.com/hashicorp/go-secure-stdlib/gatedwriter v0.1.1 h1:9um9R8i0+HbRHS9d64kd
|
||||
github.com/hashicorp/go-secure-stdlib/gatedwriter v0.1.1/go.mod h1:6RoRTSMDK2H/rKh3P/JIsk1tK8aatKTt3JyvIopi3GQ=
|
||||
github.com/hashicorp/go-secure-stdlib/kv-builder v0.1.1 h1:IJgULbAXuvWxzKFfu+Au1FUmHIJulS6N4F7Hkn+Kck0=
|
||||
github.com/hashicorp/go-secure-stdlib/kv-builder v0.1.1/go.mod h1:rf5JPE13wi+NwjgsmGkbg4b2CgHq8v7Htn/F0nDe/hg=
|
||||
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.1 h1:HlTofNQN49DTzPCMVDppp+AVxMNVWaHUElpUYC0TRRE=
|
||||
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.1/go.mod h1:irE9ILwhE8VooWdhHhBy0qXzOMRlHKoWoMlr31mAFCE=
|
||||
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.2 h1:vx6ak5Tp3L6oJ66iPYFpp8sINOPQBIWVF0Kjn8NdLVQ=
|
||||
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.2/go.mod h1:irE9ILwhE8VooWdhHhBy0qXzOMRlHKoWoMlr31mAFCE=
|
||||
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc=
|
||||
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.2 h1:Tz6v3Jb2DRnDCfifRSjYKG0m8dLdNq6bcDkB41en7nw=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.2/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
|
||||
github.com/hashicorp/go-secure-stdlib/password v0.1.1 h1:6JzmBqXprakgFEHwBgdchsjaA9x3GyjdI568bXKxa60=
|
||||
github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo=
|
||||
github.com/hashicorp/go-secure-stdlib/reloadutil v0.1.1 h1:SMGUnbpAcat8rIKHkBPjfv81yC46a8eCNZ2hsR2l1EI=
|
||||
@@ -1194,8 +1198,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef h1:fPxZ3Umkct3LZ8gK9nbk+DWDJ9fstZa2grBn+lWVKPs=
|
||||
golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 h1:kwrAHlwJ0DUBZwQ238v+Uod/3eZ8B2K5rYsUHBQvzmI=
|
||||
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210916214954-140adaaadfaf h1:Ihq/mm/suC88gF8WFcVwk+OV6Tq+wyA1O0E5UEvDglI=
|
||||
|
||||
@@ -5,9 +5,12 @@ import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/cmd/config"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/observability/event"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-secure-stdlib/configutil"
|
||||
"github.com/hashicorp/go-secure-stdlib/listenerutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -209,3 +212,623 @@ func TestServer_AddEventerToContext(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetupControllerPublicClusterAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
inputConfig *config.Config
|
||||
inputFlagValue string
|
||||
stateFn func(t *testing.T)
|
||||
expErr bool
|
||||
expErrStr string
|
||||
expPublicClusterAddress string
|
||||
}{
|
||||
{
|
||||
name: "nil controller",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: nil,
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: ":9201",
|
||||
},
|
||||
{
|
||||
name: "setting public cluster address directly with ip",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{
|
||||
PublicClusterAddr: "127.0.0.1",
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:9201",
|
||||
},
|
||||
{
|
||||
name: "setting public cluster address directly with ip:port",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{
|
||||
PublicClusterAddr: "127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "setting public cluster address to env var",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{
|
||||
PublicClusterAddr: "env://TEST_ENV_VAR_FOR_CONTROLLER_ADDR",
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
stateFn: func(t *testing.T) {
|
||||
t.Setenv("TEST_ENV_VAR_FOR_CONTROLLER_ADDR", "127.0.0.1:8080")
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "setting public cluster address to env var that points to template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{
|
||||
PublicClusterAddr: "env://TEST_ENV_VAR_FOR_CONTROLLER_ADDR",
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
stateFn: func(t *testing.T) {
|
||||
t.Setenv("TEST_ENV_VAR_FOR_CONTROLLER_ADDR", `{{ GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" | join "address" " " }}`)
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:9201",
|
||||
},
|
||||
{
|
||||
name: "setting public cluster address to ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{
|
||||
PublicClusterAddr: `{{ GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" | join "address" " " }}`,
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:9201",
|
||||
},
|
||||
{
|
||||
name: "setting public cluster address to multiline ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{
|
||||
PublicClusterAddr: `{{ with $local := GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" -}}
|
||||
{{- $local | join "address" " " -}}
|
||||
{{- end }}`,
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:9201",
|
||||
},
|
||||
{
|
||||
name: "using flag value with ip only",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
inputFlagValue: "127.0.0.1",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:9201",
|
||||
},
|
||||
{
|
||||
name: "using flag value with ip:port",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
inputFlagValue: "127.0.0.1:8080",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "using flag value with ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
inputFlagValue: `{{ GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" | join "address" " " }}`,
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:9201",
|
||||
},
|
||||
{
|
||||
name: "using flag value with multiline ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
inputFlagValue: `{{ with $local := GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" -}}
|
||||
{{- $local | join "address" " " -}}
|
||||
{{- end }}`,
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:9201",
|
||||
},
|
||||
{
|
||||
name: "using flag value to point to env var with ip only",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
inputFlagValue: "env://TEST_ENV_VAR_FOR_CONTROLLER_ADDR",
|
||||
stateFn: func(t *testing.T) {
|
||||
t.Setenv("TEST_ENV_VAR_FOR_CONTROLLER_ADDR", "127.0.0.1")
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:9201",
|
||||
},
|
||||
{
|
||||
name: "using flag value to point to env var with ip:port",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
inputFlagValue: "env://TEST_ENV_VAR_FOR_CONTROLLER_ADDR",
|
||||
stateFn: func(t *testing.T) {
|
||||
t.Setenv("TEST_ENV_VAR_FOR_CONTROLLER_ADDR", "127.0.0.1:8080")
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "read address from listeners ip only",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{
|
||||
{Purpose: []string{"cluster"}, Address: "127.0.0.1"},
|
||||
},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:9201",
|
||||
},
|
||||
{
|
||||
name: "read address from listeners ip:port",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{
|
||||
{Purpose: []string{"cluster"}, Address: "127.0.0.1:8080"},
|
||||
},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "read address from listeners is ignored on different purpose",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{
|
||||
{Purpose: []string{"somethingelse"}, Address: "127.0.0.1:8080"},
|
||||
},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicClusterAddress: ":9201",
|
||||
},
|
||||
{
|
||||
name: "using flag value to point to nonexistent file",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
inputFlagValue: "file://this_doesnt_exist_for_sure",
|
||||
expErr: true,
|
||||
expErrStr: "Error parsing public cluster addr: error reading file at file://this_doesnt_exist_for_sure: open this_doesnt_exist_for_sure: no such file or directory",
|
||||
expPublicClusterAddress: "",
|
||||
},
|
||||
{
|
||||
name: "using flag value to provoke error in SplitHostPort",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
inputFlagValue: "abc::123",
|
||||
expErr: true,
|
||||
expErrStr: "Error splitting public cluster adddress host/port: address abc::123: too many colons in address",
|
||||
expPublicClusterAddress: "",
|
||||
},
|
||||
{
|
||||
name: "bad ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Controller: &config.Controller{},
|
||||
},
|
||||
inputFlagValue: "{{ somethingthatdoesntexist }}",
|
||||
expErr: true,
|
||||
expErrStr: "Error parsing IP template on controller public cluster addr: unable to parse address template \"{{ somethingthatdoesntexist }}\": unable to parse template \"{{ somethingthatdoesntexist }}\": template: sockaddr.Parse:1: function \"somethingthatdoesntexist\" not defined",
|
||||
expPublicClusterAddress: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.stateFn != nil {
|
||||
tt.stateFn(t)
|
||||
}
|
||||
s := Server{}
|
||||
err := s.SetupControllerPublicClusterAddress(tt.inputConfig, tt.inputFlagValue)
|
||||
if tt.expErr {
|
||||
require.EqualError(t, err, tt.expErrStr)
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, tt.inputConfig.Controller)
|
||||
require.Equal(t, tt.expPublicClusterAddress, tt.inputConfig.Controller.PublicClusterAddr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetupWorkerPublicAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
inputConfig *config.Config
|
||||
inputFlagValue string
|
||||
stateFn func(t *testing.T)
|
||||
expErr bool
|
||||
expErrStr string
|
||||
expPublicAddress string
|
||||
}{
|
||||
{
|
||||
name: "nil worker",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: nil,
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: ":9202",
|
||||
},
|
||||
{
|
||||
name: "setting public address directly with ip",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{
|
||||
PublicAddr: "127.0.0.1",
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:9202",
|
||||
},
|
||||
{
|
||||
name: "setting public address directly with ip:port",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{
|
||||
PublicAddr: "127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "setting public address to env var",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{
|
||||
PublicAddr: "env://TEST_ENV_VAR_FOR_WORKER_ADDR",
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
stateFn: func(t *testing.T) {
|
||||
t.Setenv("TEST_ENV_VAR_FOR_WORKER_ADDR", "127.0.0.1:8080")
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "setting public address to env var that points to template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{
|
||||
PublicAddr: "env://TEST_ENV_VAR_FOR_WORKER_ADDR",
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
stateFn: func(t *testing.T) {
|
||||
t.Setenv("TEST_ENV_VAR_FOR_WORKER_ADDR", `{{ GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" | join "address" " " }}`)
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:9202",
|
||||
},
|
||||
{
|
||||
name: "setting public address to ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{
|
||||
PublicAddr: `{{ GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" | join "address" " " }}`,
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:9202",
|
||||
},
|
||||
{
|
||||
name: "setting public address to multiline ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{
|
||||
PublicAddr: `{{ with $local := GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" -}}
|
||||
{{- $local | join "address" " " -}}
|
||||
{{- end }}`,
|
||||
},
|
||||
},
|
||||
inputFlagValue: "",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:9202",
|
||||
},
|
||||
{
|
||||
name: "using flag value with ip only",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
inputFlagValue: "127.0.0.1",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:9202",
|
||||
},
|
||||
{
|
||||
name: "using flag value with ip:port",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
inputFlagValue: "127.0.0.1:8080",
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "using flag value to point to env var with ip only",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
inputFlagValue: "env://TEST_ENV_VAR_FOR_WORKER_ADDR",
|
||||
stateFn: func(t *testing.T) {
|
||||
t.Setenv("TEST_ENV_VAR_FOR_WORKER_ADDR", "127.0.0.1")
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:9202",
|
||||
},
|
||||
{
|
||||
name: "using flag value to point to env var with ip:port",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
inputFlagValue: "env://TEST_ENV_VAR_FOR_WORKER_ADDR",
|
||||
stateFn: func(t *testing.T) {
|
||||
t.Setenv("TEST_ENV_VAR_FOR_WORKER_ADDR", "127.0.0.1:8080")
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "using flag value with ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
inputFlagValue: `{{ GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" | join "address" " " }}`,
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:9202",
|
||||
},
|
||||
{
|
||||
name: "using flag value with multiline ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
inputFlagValue: `{{ with $local := GetAllInterfaces | include "flags" "loopback" | include "type" "IPV4" -}}
|
||||
{{- $local | join "address" " " -}}
|
||||
{{- end }}`,
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:9202",
|
||||
},
|
||||
{
|
||||
name: "read address from listeners ip only",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{
|
||||
{Purpose: []string{"proxy"}, Address: "127.0.0.1"},
|
||||
},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:9202",
|
||||
},
|
||||
{
|
||||
name: "read address from listeners ip:port",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{
|
||||
{Purpose: []string{"proxy"}, Address: "127.0.0.1:8080"},
|
||||
},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: "127.0.0.1:8080",
|
||||
},
|
||||
{
|
||||
name: "read address from listeners is ignored on different purpose",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{
|
||||
{Purpose: []string{"somethingelse"}, Address: "127.0.0.1:8080"},
|
||||
},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
expErr: false,
|
||||
expErrStr: "",
|
||||
expPublicAddress: ":9202",
|
||||
},
|
||||
{
|
||||
name: "using flag value to point to nonexistent file",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
inputFlagValue: "file://this_doesnt_exist_for_sure",
|
||||
expErr: true,
|
||||
expErrStr: "Error parsing public addr: error reading file at file://this_doesnt_exist_for_sure: open this_doesnt_exist_for_sure: no such file or directory",
|
||||
expPublicAddress: "",
|
||||
},
|
||||
{
|
||||
name: "using flag value to provoke error in SplitHostPort",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
inputFlagValue: "abc::123",
|
||||
expErr: true,
|
||||
expErrStr: "Error splitting public adddress host/port: address abc::123: too many colons in address",
|
||||
expPublicAddress: "",
|
||||
},
|
||||
{
|
||||
name: "bad ip template",
|
||||
inputConfig: &config.Config{
|
||||
SharedConfig: &configutil.SharedConfig{
|
||||
Listeners: []*listenerutil.ListenerConfig{},
|
||||
},
|
||||
Worker: &config.Worker{},
|
||||
},
|
||||
inputFlagValue: "{{ somethingthatdoesntexist }}",
|
||||
expErr: true,
|
||||
expErrStr: "Error parsing IP template on worker public addr: unable to parse address template \"{{ somethingthatdoesntexist }}\": unable to parse template \"{{ somethingthatdoesntexist }}\": template: sockaddr.Parse:1: function \"somethingthatdoesntexist\" not defined",
|
||||
expPublicAddress: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.stateFn != nil {
|
||||
tt.stateFn(t)
|
||||
}
|
||||
s := Server{}
|
||||
err := s.SetupWorkerPublicAddress(tt.inputConfig, tt.inputFlagValue)
|
||||
if tt.expErr {
|
||||
require.EqualError(t, err, tt.expErrStr)
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, tt.inputConfig.Worker)
|
||||
require.Equal(t, tt.expPublicAddress, tt.inputConfig.Worker.PublicAddr)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-secure-stdlib/configutil"
|
||||
"github.com/hashicorp/go-secure-stdlib/gatedwriter"
|
||||
"github.com/hashicorp/go-secure-stdlib/listenerutil"
|
||||
"github.com/hashicorp/go-secure-stdlib/mlock"
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
"github.com/hashicorp/go-secure-stdlib/reloadutil"
|
||||
@@ -642,7 +643,13 @@ func (b *Server) SetupControllerPublicClusterAddress(conf *config.Config, flagVa
|
||||
if err != nil && !errors.Is(err, parseutil.ErrNotAUrl) {
|
||||
return fmt.Errorf("Error parsing public cluster addr: %w", err)
|
||||
}
|
||||
|
||||
conf.Controller.PublicClusterAddr, err = listenerutil.ParseSingleIPTemplate(conf.Controller.PublicClusterAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error parsing IP template on controller public cluster addr: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(conf.Controller.PublicClusterAddr)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
@@ -679,7 +686,13 @@ func (b *Server) SetupWorkerPublicAddress(conf *config.Config, flagValue string)
|
||||
if err != nil && !errors.Is(err, parseutil.ErrNotAUrl) {
|
||||
return fmt.Errorf("Error parsing public addr: %w", err)
|
||||
}
|
||||
|
||||
conf.Worker.PublicAddr, err = listenerutil.ParseSingleIPTemplate(conf.Worker.PublicAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error parsing IP template on worker public addr: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(conf.Worker.PublicAddr)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "missing port") {
|
||||
|
||||
@@ -51,8 +51,8 @@ controller {
|
||||
`cluster` purpose. This is especially useful for cloud environments that do not
|
||||
bind a publicly accessible IP to a NIC on the host directly, such as an Amazon
|
||||
EIP. This value can be a direct address string, can refer to a file on disk (file://)
|
||||
from which an address will be read; or an env var (env://) from which the
|
||||
address will be read.
|
||||
from which an address will be read; an env var (env://) from which the
|
||||
address will be read; or a [go-sockaddr template](https://godoc.org/github.com/hashicorp/go-sockaddr/template).
|
||||
|
||||
- `auth_token_time_to_live` - Maximum time to live (TTL) for all auth tokens globally (pertains
|
||||
to all tokens from all auth methods). Valid time units are anything specified by Golang's
|
||||
|
||||
@@ -28,7 +28,10 @@ worker {
|
||||
at which the worker can be reached _by clients for proxying_. This defaults to
|
||||
the address of the listener marked for `proxy` purpose. This is especially
|
||||
useful for cloud environments that do not bind a publicly accessible IP to a NIC
|
||||
on the host directly, such as an Amazon EIP.
|
||||
on the host directly, such as an Amazon EIP. This value can be a direct address string,
|
||||
can refer to a file on disk (file://) from which an address will be read;
|
||||
an env var (env://) from which the address will be read;
|
||||
or a [go-sockaddr template](https://godoc.org/github.com/hashicorp/go-sockaddr/template).
|
||||
|
||||
- `controllers` - A list of hosts/IP addresses and optionally ports for reaching
|
||||
controllers. The port will default to :9201 if not specified.
|
||||
|
||||
Reference in new issue
Block a user