diff --git a/api/services.go b/api/services.go index e40d703a8..d7cb87e57 100644 --- a/api/services.go +++ b/api/services.go @@ -286,9 +286,10 @@ func (cp *ConsulProxy) Canonicalize() { // ConsulUpstream represents a Consul Connect upstream jobspec stanza. type ConsulUpstream struct { - DestinationName string `mapstructure:"destination_name" hcl:"destination_name,optional"` - LocalBindPort int `mapstructure:"local_bind_port" hcl:"local_bind_port,optional"` - Datacenter string `mapstructure:"datacenter" hcl:"datacenter,optional"` + DestinationName string `mapstructure:"destination_name" hcl:"destination_name,optional"` + LocalBindPort int `mapstructure:"local_bind_port" hcl:"local_bind_port,optional"` + Datacenter string `mapstructure:"datacenter" hcl:"datacenter,optional"` + LocalBindAddress string `mapstructure:"local_bind_address" hcl:"local_bind_address,optional"` } type ConsulExposeConfig struct { diff --git a/api/services_test.go b/api/services_test.go index 9a7338164..705787ef2 100644 --- a/api/services_test.go +++ b/api/services_test.go @@ -228,9 +228,10 @@ func TestService_Connect_proxy_settings(t *testing.T) { Proxy: &ConsulProxy{ Upstreams: []*ConsulUpstream{ { - DestinationName: "upstream", - LocalBindPort: 80, - Datacenter: "dc2", + DestinationName: "upstream", + LocalBindPort: 80, + Datacenter: "dc2", + LocalBindAddress: "127.0.0.2", }, }, LocalServicePort: 8000, @@ -244,6 +245,7 @@ func TestService_Connect_proxy_settings(t *testing.T) { require.Equal(t, proxy.Upstreams[0].DestinationName, "upstream") require.Equal(t, proxy.Upstreams[0].LocalBindPort, 80) require.Equal(t, proxy.Upstreams[0].Datacenter, "dc2") + require.Equal(t, proxy.Upstreams[0].LocalBindAddress, "127.0.0.2") require.Equal(t, proxy.LocalServicePort, 8000) } diff --git a/command/agent/consul/connect.go b/command/agent/consul/connect.go index 3825c0da9..4a52d05bb 100644 --- a/command/agent/consul/connect.go +++ b/command/agent/consul/connect.go @@ -189,9 +189,10 @@ func connectUpstreams(in []structs.ConsulUpstream) []api.Upstream { upstreams := make([]api.Upstream, len(in)) for i, upstream := range in { upstreams[i] = api.Upstream{ - DestinationName: upstream.DestinationName, - LocalBindPort: upstream.LocalBindPort, - Datacenter: upstream.Datacenter, + DestinationName: upstream.DestinationName, + LocalBindPort: upstream.LocalBindPort, + Datacenter: upstream.Datacenter, + LocalBindAddress: upstream.LocalBindAddress, } } return upstreams diff --git a/command/agent/consul/connect_test.go b/command/agent/consul/connect_test.go index 7d89c55ec..68eb908e6 100644 --- a/command/agent/consul/connect_test.go +++ b/command/agent/consul/connect_test.go @@ -315,17 +315,19 @@ func TestConnect_connectUpstreams(t *testing.T) { DestinationName: "foo", LocalBindPort: 8000, }, { - DestinationName: "bar", - LocalBindPort: 9000, - Datacenter: "dc2", + DestinationName: "bar", + LocalBindPort: 9000, + Datacenter: "dc2", + LocalBindAddress: "127.0.0.2", }}, connectUpstreams([]structs.ConsulUpstream{{ DestinationName: "foo", LocalBindPort: 8000, }, { - DestinationName: "bar", - LocalBindPort: 9000, - Datacenter: "dc2", + DestinationName: "bar", + LocalBindPort: 9000, + Datacenter: "dc2", + LocalBindAddress: "127.0.0.2", }}), ) }) diff --git a/command/agent/job_endpoint.go b/command/agent/job_endpoint.go index bc7f26f11..ec21072f9 100644 --- a/command/agent/job_endpoint.go +++ b/command/agent/job_endpoint.go @@ -1513,9 +1513,10 @@ func apiUpstreamsToStructs(in []*api.ConsulUpstream) []structs.ConsulUpstream { upstreams := make([]structs.ConsulUpstream, len(in)) for i, upstream := range in { upstreams[i] = structs.ConsulUpstream{ - DestinationName: upstream.DestinationName, - LocalBindPort: upstream.LocalBindPort, - Datacenter: upstream.Datacenter, + DestinationName: upstream.DestinationName, + LocalBindPort: upstream.LocalBindPort, + Datacenter: upstream.Datacenter, + LocalBindAddress: upstream.LocalBindAddress, } } return upstreams diff --git a/command/agent/job_endpoint_test.go b/command/agent/job_endpoint_test.go index b6eeb94b3..9a4870e81 100644 --- a/command/agent/job_endpoint_test.go +++ b/command/agent/job_endpoint_test.go @@ -3009,13 +3009,15 @@ func TestConversion_apiUpstreamsToStructs(t *testing.T) { require.Nil(t, apiUpstreamsToStructs(nil)) require.Nil(t, apiUpstreamsToStructs(make([]*api.ConsulUpstream, 0))) require.Equal(t, []structs.ConsulUpstream{{ - DestinationName: "upstream", - LocalBindPort: 8000, - Datacenter: "dc2", + DestinationName: "upstream", + LocalBindPort: 8000, + Datacenter: "dc2", + LocalBindAddress: "127.0.0.2", }}, apiUpstreamsToStructs([]*api.ConsulUpstream{{ - DestinationName: "upstream", - LocalBindPort: 8000, - Datacenter: "dc2", + DestinationName: "upstream", + LocalBindPort: 8000, + Datacenter: "dc2", + LocalBindAddress: "127.0.0.2", }})) } diff --git a/nomad/structs/diff_test.go b/nomad/structs/diff_test.go index 0b087abd5..2d1637c19 100644 --- a/nomad/structs/diff_test.go +++ b/nomad/structs/diff_test.go @@ -2695,9 +2695,10 @@ func TestTaskGroupDiff(t *testing.T) { LocalServicePort: 8080, Upstreams: []ConsulUpstream{ { - DestinationName: "foo", - LocalBindPort: 8000, - Datacenter: "dc2", + DestinationName: "foo", + LocalBindPort: 8000, + Datacenter: "dc2", + LocalBindAddress: "127.0.0.2", }, }, Config: map[string]interface{}{ @@ -2986,6 +2987,12 @@ func TestTaskGroupDiff(t *testing.T) { Old: "", New: "foo", }, + { + Type: DiffTypeAdded, + Name: "LocalBindAddress", + Old: "", + New: "127.0.0.2", + }, { Type: DiffTypeAdded, Name: "LocalBindPort", diff --git a/nomad/structs/services.go b/nomad/structs/services.go index 769a8cda5..03a777f88 100644 --- a/nomad/structs/services.go +++ b/nomad/structs/services.go @@ -630,6 +630,7 @@ func hashConnect(h hash.Hash, connect *ConsulConnect) { hashString(h, upstream.DestinationName) hashString(h, strconv.Itoa(upstream.LocalBindPort)) hashStringIfNonEmpty(h, upstream.Datacenter) + hashStringIfNonEmpty(h, upstream.LocalBindAddress) } } } @@ -1198,6 +1199,10 @@ type ConsulUpstream struct { // Datacenter is the datacenter in which to issue the discovery query to. Datacenter string + + // LocalBindAddress is the address the proxy will receive connections for the + // upstream on. + LocalBindAddress string } func upstreamsEquals(a, b []ConsulUpstream) bool { @@ -1224,9 +1229,10 @@ func (u *ConsulUpstream) Copy() *ConsulUpstream { } return &ConsulUpstream{ - DestinationName: u.DestinationName, - LocalBindPort: u.LocalBindPort, - Datacenter: u.Datacenter, + DestinationName: u.DestinationName, + LocalBindPort: u.LocalBindPort, + Datacenter: u.Datacenter, + LocalBindAddress: u.LocalBindAddress, } } diff --git a/vendor/github.com/hashicorp/nomad/api/services.go b/vendor/github.com/hashicorp/nomad/api/services.go index e40d703a8..d7cb87e57 100644 --- a/vendor/github.com/hashicorp/nomad/api/services.go +++ b/vendor/github.com/hashicorp/nomad/api/services.go @@ -286,9 +286,10 @@ func (cp *ConsulProxy) Canonicalize() { // ConsulUpstream represents a Consul Connect upstream jobspec stanza. type ConsulUpstream struct { - DestinationName string `mapstructure:"destination_name" hcl:"destination_name,optional"` - LocalBindPort int `mapstructure:"local_bind_port" hcl:"local_bind_port,optional"` - Datacenter string `mapstructure:"datacenter" hcl:"datacenter,optional"` + DestinationName string `mapstructure:"destination_name" hcl:"destination_name,optional"` + LocalBindPort int `mapstructure:"local_bind_port" hcl:"local_bind_port,optional"` + Datacenter string `mapstructure:"datacenter" hcl:"datacenter,optional"` + LocalBindAddress string `mapstructure:"local_bind_address" hcl:"local_bind_address,optional"` } type ConsulExposeConfig struct { diff --git a/website/content/docs/job-specification/upstreams.mdx b/website/content/docs/job-specification/upstreams.mdx index 53dc624d7..883629472 100644 --- a/website/content/docs/job-specification/upstreams.mdx +++ b/website/content/docs/job-specification/upstreams.mdx @@ -54,6 +54,7 @@ job "countdash" { destination_name = "count-api" local_bind_port = 8080 datacenter = "dc1" + local_bind_address = "127.0.0.1" } } } @@ -84,6 +85,8 @@ job "countdash" { - `datacenter` `(string: "")` - The Consul datacenter in which to issue the discovery query. Defaults to the empty string, which Consul interprets as the local Consul datacenter. +- `local_bind_address` - `(string: "")` - The address the proxy will receive + connections for the upstream on. The `NOMAD_UPSTREAM_ADDR_` environment variables may be used to interpolate the upstream's `host:port` address.