mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
connect: prefix tag with nomad.; merge into envoy_stats_tags; update docs
This PR expands on the work done in #12543 to - prefix the tag, so it is now "nomad.alloc_id" to be more consistent with Consul tags - merge into pre-existing envoy_stats_tags fields - update the upgrade guide docs - update changelog
This commit is contained in:
3
.changelog/12543.txt
Normal file
3
.changelog/12543.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
```release-note:improvement
|
||||||
|
connect: automatically set alloc_id in envoy_stats_tags configuration
|
||||||
|
```
|
||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
"github.com/hashicorp/nomad/helper"
|
"github.com/hashicorp/nomad/helper"
|
||||||
@@ -13,7 +14,7 @@ import (
|
|||||||
// newConnect creates a new Consul AgentServiceConnect struct based on a Nomad
|
// newConnect creates a new Consul AgentServiceConnect struct based on a Nomad
|
||||||
// Connect struct. If the nomad Connect struct is nil, nil will be returned to
|
// Connect struct. If the nomad Connect struct is nil, nil will be returned to
|
||||||
// disable Connect for this service.
|
// disable Connect for this service.
|
||||||
func newConnect(serviceId string, serviceName string, nc *structs.ConsulConnect, networks structs.Networks, ports structs.AllocatedPorts, allocId string) (*api.AgentServiceConnect, error) {
|
func newConnect(serviceID, allocID string, serviceName string, nc *structs.ConsulConnect, networks structs.Networks, ports structs.AllocatedPorts) (*api.AgentServiceConnect, error) {
|
||||||
switch {
|
switch {
|
||||||
case nc == nil:
|
case nc == nil:
|
||||||
// no connect stanza means there is no connect service to register
|
// no connect stanza means there is no connect service to register
|
||||||
@@ -32,7 +33,7 @@ func newConnect(serviceId string, serviceName string, nc *structs.ConsulConnect,
|
|||||||
if nc.SidecarService.Port == "" {
|
if nc.SidecarService.Port == "" {
|
||||||
nc.SidecarService.Port = fmt.Sprintf("%s-%s", structs.ConnectProxyPrefix, serviceName)
|
nc.SidecarService.Port = fmt.Sprintf("%s-%s", structs.ConnectProxyPrefix, serviceName)
|
||||||
}
|
}
|
||||||
sidecarReg, err := connectSidecarRegistration(serviceId, nc.SidecarService, networks, ports, allocId)
|
sidecarReg, err := connectSidecarRegistration(serviceID, allocID, nc.SidecarService, networks, ports)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -47,7 +48,7 @@ func newConnect(serviceId string, serviceName string, nc *structs.ConsulConnect,
|
|||||||
// newConnectGateway creates a new Consul AgentServiceConnectProxyConfig struct based on
|
// newConnectGateway creates a new Consul AgentServiceConnectProxyConfig struct based on
|
||||||
// a Nomad Connect struct. If the Nomad Connect struct does not contain a gateway, nil
|
// a Nomad Connect struct. If the Nomad Connect struct does not contain a gateway, nil
|
||||||
// will be returned as this service is not a gateway.
|
// will be returned as this service is not a gateway.
|
||||||
func newConnectGateway(serviceName string, connect *structs.ConsulConnect) *api.AgentServiceConnectProxyConfig {
|
func newConnectGateway(connect *structs.ConsulConnect) *api.AgentServiceConnectProxyConfig {
|
||||||
if !connect.IsGateway() {
|
if !connect.IsGateway() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -89,7 +90,7 @@ func newConnectGateway(serviceName string, connect *structs.ConsulConnect) *api.
|
|||||||
return &api.AgentServiceConnectProxyConfig{Config: envoyConfig}
|
return &api.AgentServiceConnectProxyConfig{Config: envoyConfig}
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectSidecarRegistration(serviceId string, css *structs.ConsulSidecarService, networks structs.Networks, ports structs.AllocatedPorts, allocId string) (*api.AgentServiceRegistration, error) {
|
func connectSidecarRegistration(serviceID, allocID string, css *structs.ConsulSidecarService, networks structs.Networks, ports structs.AllocatedPorts) (*api.AgentServiceRegistration, error) {
|
||||||
if css == nil {
|
if css == nil {
|
||||||
// no sidecar stanza means there is no sidecar service to register
|
// no sidecar stanza means there is no sidecar service to register
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -100,7 +101,7 @@ func connectSidecarRegistration(serviceId string, css *structs.ConsulSidecarServ
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy, err := connectSidecarProxy(css.Proxy, cMapping.To, networks, allocId)
|
proxy, err := connectSidecarProxy(allocID, css.Proxy, cMapping.To, networks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -109,8 +110,8 @@ func connectSidecarRegistration(serviceId string, css *structs.ConsulSidecarServ
|
|||||||
// ensure service discovery excludes this sidecar from queries
|
// ensure service discovery excludes this sidecar from queries
|
||||||
// (ex. in the case of Connect upstreams)
|
// (ex. in the case of Connect upstreams)
|
||||||
checks := api.AgentServiceChecks{{
|
checks := api.AgentServiceChecks{{
|
||||||
Name: "Connect Sidecar Aliasing " + serviceId,
|
Name: "Connect Sidecar Aliasing " + serviceID,
|
||||||
AliasService: serviceId,
|
AliasService: serviceID,
|
||||||
}}
|
}}
|
||||||
if !css.DisableDefaultTCPCheck {
|
if !css.DisableDefaultTCPCheck {
|
||||||
checks = append(checks, &api.AgentServiceCheck{
|
checks = append(checks, &api.AgentServiceCheck{
|
||||||
@@ -129,7 +130,7 @@ func connectSidecarRegistration(serviceId string, css *structs.ConsulSidecarServ
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectSidecarProxy(proxy *structs.ConsulProxy, cPort int, networks structs.Networks, allocId string) (*api.AgentServiceConnectProxyConfig, error) {
|
func connectSidecarProxy(allocID string, proxy *structs.ConsulProxy, cPort int, networks structs.Networks) (*api.AgentServiceConnectProxyConfig, error) {
|
||||||
if proxy == nil {
|
if proxy == nil {
|
||||||
proxy = new(structs.ConsulProxy)
|
proxy = new(structs.ConsulProxy)
|
||||||
}
|
}
|
||||||
@@ -142,7 +143,7 @@ func connectSidecarProxy(proxy *structs.ConsulProxy, cPort int, networks structs
|
|||||||
return &api.AgentServiceConnectProxyConfig{
|
return &api.AgentServiceConnectProxyConfig{
|
||||||
LocalServiceAddress: proxy.LocalServiceAddress,
|
LocalServiceAddress: proxy.LocalServiceAddress,
|
||||||
LocalServicePort: proxy.LocalServicePort,
|
LocalServicePort: proxy.LocalServicePort,
|
||||||
Config: connectProxyConfig(proxy.Config, cPort, allocId),
|
Config: connectProxyConfig(proxy.Config, cPort, allocID),
|
||||||
Upstreams: connectUpstreams(proxy.Upstreams),
|
Upstreams: connectUpstreams(proxy.Upstreams),
|
||||||
Expose: expose,
|
Expose: expose,
|
||||||
}, nil
|
}, nil
|
||||||
@@ -228,17 +229,40 @@ func connectMeshGateway(in *structs.ConsulMeshGateway) api.MeshGatewayConfig {
|
|||||||
return gw
|
return gw
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectProxyConfig(cfg map[string]interface{}, port int, allocId string) map[string]interface{} {
|
func connectProxyConfig(cfg map[string]interface{}, port int, allocID string) map[string]interface{} {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
cfg = make(map[string]interface{})
|
cfg = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
cfg["bind_address"] = "0.0.0.0"
|
cfg["bind_address"] = "0.0.0.0"
|
||||||
cfg["bind_port"] = port
|
cfg["bind_port"] = port
|
||||||
if allocId != "" {
|
injectAllocID(cfg, allocID)
|
||||||
cfg["envoy_stats_tags"] = []string{"alloc_id=" + allocId}
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
// injectAllocID merges allocID into cfg=>envoy_stats_tags
|
||||||
|
//
|
||||||
|
// cfg must not be nil
|
||||||
|
func injectAllocID(cfg map[string]interface{}, allocID string) {
|
||||||
|
const key = "envoy_stats_tags"
|
||||||
|
const prefix = "nomad.alloc_id="
|
||||||
|
pair := prefix + allocID
|
||||||
|
tags, exists := cfg[key]
|
||||||
|
if !exists {
|
||||||
|
cfg[key] = []string{pair}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg
|
switch v := tags.(type) {
|
||||||
|
case []string:
|
||||||
|
// scan the existing tags to see if alloc_id= is already set
|
||||||
|
for _, s := range v {
|
||||||
|
if strings.HasPrefix(s, prefix) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v = append(v, pair)
|
||||||
|
cfg[key] = v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectNetworkInvariants(networks structs.Networks) error {
|
func connectNetworkInvariants(networks structs.Networks) error {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
"github.com/hashicorp/nomad/ci"
|
"github.com/hashicorp/nomad/ci"
|
||||||
"github.com/hashicorp/nomad/helper"
|
"github.com/hashicorp/nomad/helper"
|
||||||
|
"github.com/hashicorp/nomad/helper/uuid"
|
||||||
"github.com/hashicorp/nomad/nomad/structs"
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@@ -33,29 +34,33 @@ var (
|
|||||||
func TestConnect_newConnect(t *testing.T) {
|
func TestConnect_newConnect(t *testing.T) {
|
||||||
ci.Parallel(t)
|
ci.Parallel(t)
|
||||||
|
|
||||||
|
service := "redis"
|
||||||
|
redisID := uuid.Generate()
|
||||||
|
allocID := uuid.Generate()
|
||||||
|
|
||||||
t.Run("nil", func(t *testing.T) {
|
t.Run("nil", func(t *testing.T) {
|
||||||
asr, err := newConnect("", "", nil, nil, nil, "")
|
asr, err := newConnect("", "", "", nil, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, asr)
|
require.Nil(t, asr)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("native", func(t *testing.T) {
|
t.Run("native", func(t *testing.T) {
|
||||||
asr, err := newConnect("", "", &structs.ConsulConnect{
|
asr, err := newConnect(redisID, allocID, service, &structs.ConsulConnect{
|
||||||
Native: true,
|
Native: true,
|
||||||
}, nil, nil, "")
|
}, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, asr.Native)
|
require.True(t, asr.Native)
|
||||||
require.Nil(t, asr.SidecarService)
|
require.Nil(t, asr.SidecarService)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("with sidecar", func(t *testing.T) {
|
t.Run("with sidecar", func(t *testing.T) {
|
||||||
asr, err := newConnect("redis-service-id", "redis", &structs.ConsulConnect{
|
asr, err := newConnect(redisID, allocID, service, &structs.ConsulConnect{
|
||||||
Native: false,
|
Native: false,
|
||||||
SidecarService: &structs.ConsulSidecarService{
|
SidecarService: &structs.ConsulSidecarService{
|
||||||
Tags: []string{"foo", "bar"},
|
Tags: []string{"foo", "bar"},
|
||||||
Port: "connect-proxy-redis",
|
Port: "connect-proxy-redis",
|
||||||
},
|
},
|
||||||
}, testConnectNetwork, testConnectPorts, "redis-alloc-id")
|
}, testConnectNetwork, testConnectPorts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &api.AgentServiceRegistration{
|
require.Equal(t, &api.AgentServiceRegistration{
|
||||||
Tags: []string{"foo", "bar"},
|
Tags: []string{"foo", "bar"},
|
||||||
@@ -65,13 +70,13 @@ func TestConnect_newConnect(t *testing.T) {
|
|||||||
Config: map[string]interface{}{
|
Config: map[string]interface{}{
|
||||||
"bind_address": "0.0.0.0",
|
"bind_address": "0.0.0.0",
|
||||||
"bind_port": 3000,
|
"bind_port": 3000,
|
||||||
"envoy_stats_tags": []string{"alloc_id=redis-alloc-id"},
|
"envoy_stats_tags": []string{"nomad.alloc_id=" + allocID},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Checks: api.AgentServiceChecks{
|
Checks: api.AgentServiceChecks{
|
||||||
{
|
{
|
||||||
Name: "Connect Sidecar Aliasing redis-service-id",
|
Name: "Connect Sidecar Aliasing " + redisID,
|
||||||
AliasService: "redis-service-id",
|
AliasService: redisID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Connect Sidecar Listening",
|
Name: "Connect Sidecar Listening",
|
||||||
@@ -83,14 +88,14 @@ func TestConnect_newConnect(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("with sidecar without TCP checks", func(t *testing.T) {
|
t.Run("with sidecar without TCP checks", func(t *testing.T) {
|
||||||
asr, err := newConnect("redis-service-id", "redis", &structs.ConsulConnect{
|
asr, err := newConnect(redisID, allocID, service, &structs.ConsulConnect{
|
||||||
Native: false,
|
Native: false,
|
||||||
SidecarService: &structs.ConsulSidecarService{
|
SidecarService: &structs.ConsulSidecarService{
|
||||||
Tags: []string{"foo", "bar"},
|
Tags: []string{"foo", "bar"},
|
||||||
Port: "connect-proxy-redis",
|
Port: "connect-proxy-redis",
|
||||||
DisableDefaultTCPCheck: true,
|
DisableDefaultTCPCheck: true,
|
||||||
},
|
},
|
||||||
}, testConnectNetwork, testConnectPorts, "redis-alloc-id")
|
}, testConnectNetwork, testConnectPorts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &api.AgentServiceRegistration{
|
require.Equal(t, &api.AgentServiceRegistration{
|
||||||
Tags: []string{"foo", "bar"},
|
Tags: []string{"foo", "bar"},
|
||||||
@@ -100,13 +105,13 @@ func TestConnect_newConnect(t *testing.T) {
|
|||||||
Config: map[string]interface{}{
|
Config: map[string]interface{}{
|
||||||
"bind_address": "0.0.0.0",
|
"bind_address": "0.0.0.0",
|
||||||
"bind_port": 3000,
|
"bind_port": 3000,
|
||||||
"envoy_stats_tags": []string{"alloc_id=redis-alloc-id"},
|
"envoy_stats_tags": []string{"nomad.alloc_id=" + allocID},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Checks: api.AgentServiceChecks{
|
Checks: api.AgentServiceChecks{
|
||||||
{
|
{
|
||||||
Name: "Connect Sidecar Aliasing redis-service-id",
|
Name: "Connect Sidecar Aliasing " + redisID,
|
||||||
AliasService: "redis-service-id",
|
AliasService: redisID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, asr.SidecarService)
|
}, asr.SidecarService)
|
||||||
@@ -116,21 +121,24 @@ func TestConnect_newConnect(t *testing.T) {
|
|||||||
func TestConnect_connectSidecarRegistration(t *testing.T) {
|
func TestConnect_connectSidecarRegistration(t *testing.T) {
|
||||||
ci.Parallel(t)
|
ci.Parallel(t)
|
||||||
|
|
||||||
|
redisID := uuid.Generate()
|
||||||
|
allocID := uuid.Generate()
|
||||||
|
|
||||||
t.Run("nil", func(t *testing.T) {
|
t.Run("nil", func(t *testing.T) {
|
||||||
sidecarReg, err := connectSidecarRegistration("", nil, testConnectNetwork, testConnectPorts, "")
|
sidecarReg, err := connectSidecarRegistration(redisID, allocID, nil, testConnectNetwork, testConnectPorts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Nil(t, sidecarReg)
|
require.Nil(t, sidecarReg)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("no service port", func(t *testing.T) {
|
t.Run("no service port", func(t *testing.T) {
|
||||||
_, err := connectSidecarRegistration("unknown-id", &structs.ConsulSidecarService{
|
_, err := connectSidecarRegistration("unknown-id", allocID, &structs.ConsulSidecarService{
|
||||||
Port: "unknown-label",
|
Port: "unknown-label",
|
||||||
}, testConnectNetwork, testConnectPorts, "")
|
}, testConnectNetwork, testConnectPorts)
|
||||||
require.EqualError(t, err, `No port of label "unknown-label" defined`)
|
require.EqualError(t, err, `No port of label "unknown-label" defined`)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("bad proxy", func(t *testing.T) {
|
t.Run("bad proxy", func(t *testing.T) {
|
||||||
_, err := connectSidecarRegistration("redis-service-id", &structs.ConsulSidecarService{
|
_, err := connectSidecarRegistration(redisID, allocID, &structs.ConsulSidecarService{
|
||||||
Port: "connect-proxy-redis",
|
Port: "connect-proxy-redis",
|
||||||
Proxy: &structs.ConsulProxy{
|
Proxy: &structs.ConsulProxy{
|
||||||
Expose: &structs.ConsulExposeConfig{
|
Expose: &structs.ConsulExposeConfig{
|
||||||
@@ -139,15 +147,15 @@ func TestConnect_connectSidecarRegistration(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, testConnectNetwork, testConnectPorts, "")
|
}, testConnectNetwork, testConnectPorts)
|
||||||
require.EqualError(t, err, `No port of label "badPort" defined`)
|
require.EqualError(t, err, `No port of label "badPort" defined`)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("normal", func(t *testing.T) {
|
t.Run("normal", func(t *testing.T) {
|
||||||
proxy, err := connectSidecarRegistration("redis-service-id", &structs.ConsulSidecarService{
|
proxy, err := connectSidecarRegistration(redisID, allocID, &structs.ConsulSidecarService{
|
||||||
Tags: []string{"foo", "bar"},
|
Tags: []string{"foo", "bar"},
|
||||||
Port: "connect-proxy-redis",
|
Port: "connect-proxy-redis",
|
||||||
}, testConnectNetwork, testConnectPorts, "")
|
}, testConnectNetwork, testConnectPorts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &api.AgentServiceRegistration{
|
require.Equal(t, &api.AgentServiceRegistration{
|
||||||
Tags: []string{"foo", "bar"},
|
Tags: []string{"foo", "bar"},
|
||||||
@@ -155,14 +163,15 @@ func TestConnect_connectSidecarRegistration(t *testing.T) {
|
|||||||
Address: "192.168.30.1",
|
Address: "192.168.30.1",
|
||||||
Proxy: &api.AgentServiceConnectProxyConfig{
|
Proxy: &api.AgentServiceConnectProxyConfig{
|
||||||
Config: map[string]interface{}{
|
Config: map[string]interface{}{
|
||||||
"bind_address": "0.0.0.0",
|
"bind_address": "0.0.0.0",
|
||||||
"bind_port": 3000,
|
"bind_port": 3000,
|
||||||
|
"envoy_stats_tags": []string{"nomad.alloc_id=" + allocID},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Checks: api.AgentServiceChecks{
|
Checks: api.AgentServiceChecks{
|
||||||
{
|
{
|
||||||
Name: "Connect Sidecar Aliasing redis-service-id",
|
Name: "Connect Sidecar Aliasing " + redisID,
|
||||||
AliasService: "redis-service-id",
|
AliasService: redisID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Connect Sidecar Listening",
|
Name: "Connect Sidecar Listening",
|
||||||
@@ -177,10 +186,12 @@ func TestConnect_connectSidecarRegistration(t *testing.T) {
|
|||||||
func TestConnect_connectProxy(t *testing.T) {
|
func TestConnect_connectProxy(t *testing.T) {
|
||||||
ci.Parallel(t)
|
ci.Parallel(t)
|
||||||
|
|
||||||
|
allocID := uuid.Generate()
|
||||||
|
|
||||||
// If the input proxy is nil, we expect the output to be a proxy with its
|
// If the input proxy is nil, we expect the output to be a proxy with its
|
||||||
// config set to default values.
|
// config set to default values.
|
||||||
t.Run("nil proxy", func(t *testing.T) {
|
t.Run("nil proxy", func(t *testing.T) {
|
||||||
proxy, err := connectSidecarProxy(nil, 2000, testConnectNetwork, "")
|
proxy, err := connectSidecarProxy(allocID, nil, 2000, testConnectNetwork)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &api.AgentServiceConnectProxyConfig{
|
require.Equal(t, &api.AgentServiceConnectProxyConfig{
|
||||||
LocalServiceAddress: "",
|
LocalServiceAddress: "",
|
||||||
@@ -188,14 +199,15 @@ func TestConnect_connectProxy(t *testing.T) {
|
|||||||
Upstreams: nil,
|
Upstreams: nil,
|
||||||
Expose: api.ExposeConfig{},
|
Expose: api.ExposeConfig{},
|
||||||
Config: map[string]interface{}{
|
Config: map[string]interface{}{
|
||||||
"bind_address": "0.0.0.0",
|
"bind_address": "0.0.0.0",
|
||||||
"bind_port": 2000,
|
"bind_port": 2000,
|
||||||
|
"envoy_stats_tags": []string{"nomad.alloc_id=" + allocID},
|
||||||
},
|
},
|
||||||
}, proxy)
|
}, proxy)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("bad proxy", func(t *testing.T) {
|
t.Run("bad proxy", func(t *testing.T) {
|
||||||
_, err := connectSidecarProxy(&structs.ConsulProxy{
|
_, err := connectSidecarProxy(allocID, &structs.ConsulProxy{
|
||||||
LocalServiceAddress: "0.0.0.0",
|
LocalServiceAddress: "0.0.0.0",
|
||||||
LocalServicePort: 2000,
|
LocalServicePort: 2000,
|
||||||
Upstreams: nil,
|
Upstreams: nil,
|
||||||
@@ -205,12 +217,12 @@ func TestConnect_connectProxy(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
Config: nil,
|
Config: nil,
|
||||||
}, 2000, testConnectNetwork, "")
|
}, 2000, testConnectNetwork)
|
||||||
require.EqualError(t, err, `No port of label "badPort" defined`)
|
require.EqualError(t, err, `No port of label "badPort" defined`)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("normal", func(t *testing.T) {
|
t.Run("normal", func(t *testing.T) {
|
||||||
proxy, err := connectSidecarProxy(&structs.ConsulProxy{
|
proxy, err := connectSidecarProxy(allocID, &structs.ConsulProxy{
|
||||||
LocalServiceAddress: "0.0.0.0",
|
LocalServiceAddress: "0.0.0.0",
|
||||||
LocalServicePort: 2000,
|
LocalServicePort: 2000,
|
||||||
Upstreams: nil,
|
Upstreams: nil,
|
||||||
@@ -223,7 +235,7 @@ func TestConnect_connectProxy(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
Config: nil,
|
Config: nil,
|
||||||
}, 2000, testConnectNetwork, "")
|
}, 2000, testConnectNetwork)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &api.AgentServiceConnectProxyConfig{
|
require.Equal(t, &api.AgentServiceConnectProxyConfig{
|
||||||
LocalServiceAddress: "0.0.0.0",
|
LocalServiceAddress: "0.0.0.0",
|
||||||
@@ -238,8 +250,9 @@ func TestConnect_connectProxy(t *testing.T) {
|
|||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
Config: map[string]interface{}{
|
Config: map[string]interface{}{
|
||||||
"bind_address": "0.0.0.0",
|
"bind_address": "0.0.0.0",
|
||||||
"bind_port": 2000,
|
"bind_port": 2000,
|
||||||
|
"envoy_stats_tags": []string{"nomad.alloc_id=" + allocID},
|
||||||
},
|
},
|
||||||
}, proxy)
|
}, proxy)
|
||||||
})
|
})
|
||||||
@@ -372,7 +385,7 @@ func TestConnect_connectProxyConfig(t *testing.T) {
|
|||||||
require.Equal(t, map[string]interface{}{
|
require.Equal(t, map[string]interface{}{
|
||||||
"bind_address": "0.0.0.0",
|
"bind_address": "0.0.0.0",
|
||||||
"bind_port": 42,
|
"bind_port": 42,
|
||||||
"envoy_stats_tags": []string{"alloc_id=test_alloc1"},
|
"envoy_stats_tags": []string{"nomad.alloc_id=test_alloc1"},
|
||||||
}, connectProxyConfig(nil, 42, "test_alloc1"))
|
}, connectProxyConfig(nil, 42, "test_alloc1"))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -381,18 +394,11 @@ func TestConnect_connectProxyConfig(t *testing.T) {
|
|||||||
"bind_address": "0.0.0.0",
|
"bind_address": "0.0.0.0",
|
||||||
"bind_port": 42,
|
"bind_port": 42,
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
"envoy_stats_tags": []string{"alloc_id=test_alloc2"},
|
"envoy_stats_tags": []string{"nomad.alloc_id=test_alloc2"},
|
||||||
}, connectProxyConfig(map[string]interface{}{
|
}, connectProxyConfig(map[string]interface{}{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
}, 42, "test_alloc2"))
|
}, 42, "test_alloc2"))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("emtpy alloc id", func(t *testing.T) {
|
|
||||||
require.Equal(t, map[string]interface{}{
|
|
||||||
"bind_address": "0.0.0.0",
|
|
||||||
"bind_port": 42,
|
|
||||||
}, connectProxyConfig(nil, 42, ""))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnect_getConnectPort(t *testing.T) {
|
func TestConnect_getConnectPort(t *testing.T) {
|
||||||
@@ -485,12 +491,12 @@ func TestConnect_newConnectGateway(t *testing.T) {
|
|||||||
ci.Parallel(t)
|
ci.Parallel(t)
|
||||||
|
|
||||||
t.Run("not a gateway", func(t *testing.T) {
|
t.Run("not a gateway", func(t *testing.T) {
|
||||||
result := newConnectGateway("s1", &structs.ConsulConnect{Native: true})
|
result := newConnectGateway(&structs.ConsulConnect{Native: true})
|
||||||
require.Nil(t, result)
|
require.Nil(t, result)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("canonical empty", func(t *testing.T) {
|
t.Run("canonical empty", func(t *testing.T) {
|
||||||
result := newConnectGateway("s1", &structs.ConsulConnect{
|
result := newConnectGateway(&structs.ConsulConnect{
|
||||||
Gateway: &structs.ConsulGateway{
|
Gateway: &structs.ConsulGateway{
|
||||||
Proxy: &structs.ConsulGatewayProxy{
|
Proxy: &structs.ConsulGatewayProxy{
|
||||||
ConnectTimeout: helper.TimeToPtr(1 * time.Second),
|
ConnectTimeout: helper.TimeToPtr(1 * time.Second),
|
||||||
@@ -509,7 +515,7 @@ func TestConnect_newConnectGateway(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("proxy undefined", func(t *testing.T) {
|
t.Run("proxy undefined", func(t *testing.T) {
|
||||||
result := newConnectGateway("s1", &structs.ConsulConnect{
|
result := newConnectGateway(&structs.ConsulConnect{
|
||||||
Gateway: &structs.ConsulGateway{
|
Gateway: &structs.ConsulGateway{
|
||||||
Proxy: nil,
|
Proxy: nil,
|
||||||
},
|
},
|
||||||
@@ -520,7 +526,7 @@ func TestConnect_newConnectGateway(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("full", func(t *testing.T) {
|
t.Run("full", func(t *testing.T) {
|
||||||
result := newConnectGateway("s1", &structs.ConsulConnect{
|
result := newConnectGateway(&structs.ConsulConnect{
|
||||||
Gateway: &structs.ConsulGateway{
|
Gateway: &structs.ConsulGateway{
|
||||||
Proxy: &structs.ConsulGatewayProxy{
|
Proxy: &structs.ConsulGatewayProxy{
|
||||||
ConnectTimeout: helper.TimeToPtr(1 * time.Second),
|
ConnectTimeout: helper.TimeToPtr(1 * time.Second),
|
||||||
@@ -585,3 +591,70 @@ func Test_connectMeshGateway(t *testing.T) {
|
|||||||
require.Equal(t, api.MeshGatewayConfig{Mode: api.MeshGatewayModeDefault}, result)
|
require.Equal(t, api.MeshGatewayConfig{Mode: api.MeshGatewayModeDefault}, result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_injectAllocID(t *testing.T) {
|
||||||
|
ci.Parallel(t)
|
||||||
|
|
||||||
|
id := "abc123"
|
||||||
|
|
||||||
|
try := func(allocID string, cfg, exp map[string]interface{}) {
|
||||||
|
injectAllocID(cfg, allocID)
|
||||||
|
require.Equal(t, exp, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty
|
||||||
|
try(
|
||||||
|
id,
|
||||||
|
make(map[string]interface{}),
|
||||||
|
map[string]interface{}{
|
||||||
|
"envoy_stats_tags": []string{"nomad.alloc_id=abc123"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// merge fresh
|
||||||
|
try(
|
||||||
|
id,
|
||||||
|
map[string]interface{}{"foo": "bar"},
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"envoy_stats_tags": []string{"nomad.alloc_id=abc123"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// merge append
|
||||||
|
try(
|
||||||
|
id,
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"envoy_stats_tags": []string{"k1=v1", "k2=v2"},
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"envoy_stats_tags": []string{"k1=v1", "k2=v2", "nomad.alloc_id=abc123"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// merge exists
|
||||||
|
try(
|
||||||
|
id,
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"envoy_stats_tags": []string{"k1=v1", "k2=v2", "nomad.alloc_id=xyz789"},
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"envoy_stats_tags": []string{"k1=v1", "k2=v2", "nomad.alloc_id=xyz789"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// merge wrong type
|
||||||
|
try(
|
||||||
|
id,
|
||||||
|
map[string]interface{}{
|
||||||
|
"envoy_stats_tags": "not a slice of string",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"envoy_stats_tags": "not a slice of string",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,8 +122,9 @@ func TestConsul_Connect(t *testing.T) {
|
|||||||
require.Equal(t, connectService.Proxy.LocalServiceAddress, "127.0.0.1")
|
require.Equal(t, connectService.Proxy.LocalServiceAddress, "127.0.0.1")
|
||||||
require.Equal(t, connectService.Proxy.LocalServicePort, 9000)
|
require.Equal(t, connectService.Proxy.LocalServicePort, 9000)
|
||||||
require.Equal(t, connectService.Proxy.Config, map[string]interface{}{
|
require.Equal(t, connectService.Proxy.Config, map[string]interface{}{
|
||||||
"bind_address": "0.0.0.0",
|
"bind_address": "0.0.0.0",
|
||||||
"bind_port": float64(9998),
|
"bind_port": float64(9998),
|
||||||
|
"envoy_stats_tags": []interface{}{"nomad.alloc_id=" + alloc.ID},
|
||||||
})
|
})
|
||||||
require.Equal(t, alloc.ID, agentService.Meta["alloc_id"])
|
require.Equal(t, alloc.ID, agentService.Meta["alloc_id"])
|
||||||
|
|
||||||
|
|||||||
@@ -964,13 +964,13 @@ func (c *ServiceClient) serviceRegs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// newConnect returns (nil, nil) if there's no Connect-enabled service.
|
// newConnect returns (nil, nil) if there's no Connect-enabled service.
|
||||||
connect, err := newConnect(id, service.Name, service.Connect, workload.Networks, workload.Ports, workload.AllocID)
|
connect, err := newConnect(id, workload.AllocID, service.Name, service.Connect, workload.Networks, workload.Ports)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid Consul Connect configuration for service %q: %v", service.Name, err)
|
return nil, fmt.Errorf("invalid Consul Connect configuration for service %q: %v", service.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newConnectGateway returns nil if there's no Connect gateway.
|
// newConnectGateway returns nil if there's no Connect gateway.
|
||||||
gateway := newConnectGateway(service.Name, service.Connect)
|
gateway := newConnectGateway(service.Connect)
|
||||||
|
|
||||||
// Determine whether to use meta or canary_meta
|
// Determine whether to use meta or canary_meta
|
||||||
var meta map[string]string
|
var meta map[string]string
|
||||||
|
|||||||
@@ -749,7 +749,6 @@ func TestConsul_ShutdownBlocked(t *testing.T) {
|
|||||||
ci.Parallel(t)
|
ci.Parallel(t)
|
||||||
|
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
ci.Parallel(t)
|
|
||||||
ctx := setupFake(t)
|
ctx := setupFake(t)
|
||||||
// can be short because we're intentionally blocking, but needs to
|
// can be short because we're intentionally blocking, but needs to
|
||||||
// be longer than the time we'll block Consul so we can be sure
|
// be longer than the time we'll block Consul so we can be sure
|
||||||
|
|||||||
@@ -107,6 +107,25 @@ However *if you have overridden the default `template.function_denylist` in
|
|||||||
your client configuration, you must add `writeToFile` to your denylist.*
|
your client configuration, you must add `writeToFile` to your denylist.*
|
||||||
Failing to do so allows templates to write to arbitrary paths on the host.
|
Failing to do so allows templates to write to arbitrary paths on the host.
|
||||||
|
|
||||||
|
#### Changes to Envoy metrics labels
|
||||||
|
|
||||||
|
When using Envoy as a sidecar proxy for Connect enabled services, Nomad will now
|
||||||
|
automatically inject the unique allocation ID into Envoy's stats tags configuration.
|
||||||
|
Users who wish to set the tag values themselves may do so using the [`proxy.config`](/docs/job-specification/proxy#config)
|
||||||
|
block.
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
connect {
|
||||||
|
sidecar_service {
|
||||||
|
proxy {
|
||||||
|
config {
|
||||||
|
envoy_stats_tags = ["nomad.alloc_id=<allocID>"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### Linux Control Groups Version 2
|
#### Linux Control Groups Version 2
|
||||||
|
|
||||||
Starting with Nomad 1.3.0, Linux systems configured to use [cgroups v2][cgroups2]
|
Starting with Nomad 1.3.0, Linux systems configured to use [cgroups v2][cgroups2]
|
||||||
|
|||||||
Reference in New Issue
Block a user