connect: all config entries pick up a meta field (#8596)

Fixes #8595
This commit is contained in:
R.B. Boyer 2020-09-02 14:10:25 -05:00 committed by GitHub
parent df1381f77f
commit b0bde51e70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 478 additions and 20 deletions

3
.changelog/8596.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:feature
connect: all config entries pick up a meta field
```

View File

@ -3436,6 +3436,10 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
{
"kind": "service-defaults",
"name": "web",
"meta" : {
"foo": "bar",
"gir": "zim"
},
"protocol": "http",
"external_sni": "abc-123",
"mesh_gateway": {
@ -3450,6 +3454,10 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
bootstrap {
kind = "service-defaults"
name = "web"
meta {
"foo" = "bar"
"gir" = "zim"
}
protocol = "http"
external_sni = "abc-123"
mesh_gateway {
@ -3461,8 +3469,12 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
rt.DataDir = dataDir
rt.ConfigEntryBootstrap = []structs.ConfigEntry{
&structs.ServiceConfigEntry{
Kind: structs.ServiceDefaults,
Name: "web",
Kind: structs.ServiceDefaults,
Name: "web",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
EnterpriseMeta: *defaultEntMeta,
Protocol: "http",
ExternalSNI: "abc-123",
@ -3482,6 +3494,10 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
{
"Kind": "service-defaults",
"Name": "web",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Protocol": "http",
"ExternalSNI": "abc-123",
"MeshGateway": {
@ -3496,6 +3512,10 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
bootstrap {
Kind = "service-defaults"
Name = "web"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Protocol = "http"
ExternalSNI = "abc-123"
MeshGateway {
@ -3507,8 +3527,12 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
rt.DataDir = dataDir
rt.ConfigEntryBootstrap = []structs.ConfigEntry{
&structs.ServiceConfigEntry{
Kind: structs.ServiceDefaults,
Name: "web",
Kind: structs.ServiceDefaults,
Name: "web",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
EnterpriseMeta: *defaultEntMeta,
Protocol: "http",
ExternalSNI: "abc-123",
@ -3528,6 +3552,10 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
{
"kind": "service-router",
"name": "main",
"meta" : {
"foo": "bar",
"gir": "zim"
},
"routes": [
{
"match": {
@ -3612,6 +3640,10 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
bootstrap {
kind = "service-router"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
routes = [
{
match {
@ -3693,8 +3725,12 @@ func TestBuilder_BuildAndValide_ConfigFlagsAndEdgecases(t *testing.T) {
rt.DataDir = dataDir
rt.ConfigEntryBootstrap = []structs.ConfigEntry{
&structs.ServiceRouterConfigEntry{
Kind: structs.ServiceRouter,
Name: "main",
Kind: structs.ServiceRouter,
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
EnterpriseMeta: *defaultEntMeta,
Routes: []structs.ServiceRoute{
{

View File

@ -10,6 +10,7 @@ import (
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/decode"
"github.com/hashicorp/go-msgpack/codec"
"github.com/hashicorp/go-multierror"
"github.com/mitchellh/hashstructure"
"github.com/mitchellh/mapstructure"
)
@ -43,6 +44,7 @@ type ConfigEntry interface {
CanRead(acl.Authorizer) bool
CanWrite(acl.Authorizer) bool
GetMeta() map[string]string
GetEnterpriseMeta() *EnterpriseMeta
GetRaftIndex() *RaftIndex
}
@ -64,6 +66,7 @@ type ServiceConfigEntry struct {
//
// Connect ConnectConfiguration
Meta map[string]string `json:",omitempty"`
EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
RaftIndex
}
@ -80,6 +83,13 @@ func (e *ServiceConfigEntry) GetName() string {
return e.Name
}
func (e *ServiceConfigEntry) GetMeta() map[string]string {
if e == nil {
return nil
}
return e.Meta
}
func (e *ServiceConfigEntry) Normalize() error {
if e == nil {
return fmt.Errorf("config entry is nil")
@ -94,7 +104,7 @@ func (e *ServiceConfigEntry) Normalize() error {
}
func (e *ServiceConfigEntry) Validate() error {
return nil
return validateConfigEntryMeta(e.Meta)
}
func (e *ServiceConfigEntry) CanRead(authz acl.Authorizer) bool {
@ -137,6 +147,7 @@ type ProxyConfigEntry struct {
MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway"`
Expose ExposeConfig `json:",omitempty"`
Meta map[string]string `json:",omitempty"`
EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
RaftIndex
}
@ -153,6 +164,13 @@ func (e *ProxyConfigEntry) GetName() string {
return e.Name
}
func (e *ProxyConfigEntry) GetMeta() map[string]string {
if e == nil {
return nil
}
return e.Meta
}
func (e *ProxyConfigEntry) Normalize() error {
if e == nil {
return fmt.Errorf("config entry is nil")
@ -175,6 +193,10 @@ func (e *ProxyConfigEntry) Validate() error {
return fmt.Errorf("invalid name (%q), only %q is supported", e.Name, ProxyConfigGlobal)
}
if err := validateConfigEntryMeta(e.Meta); err != nil {
return err
}
return e.validateEnterpriseMeta()
}
@ -682,3 +704,22 @@ func NewConfigEntryKindName(kind, name string, entMeta *EnterpriseMeta) ConfigEn
ret.EnterpriseMeta.Normalize()
return ret
}
func validateConfigEntryMeta(meta map[string]string) error {
var err error
if len(meta) > metaMaxKeyPairs {
err = multierror.Append(err, fmt.Errorf(
"Meta exceeds maximum element count %d", metaMaxKeyPairs))
}
for k, v := range meta {
if len(k) > metaKeyMaxLength {
err = multierror.Append(err, fmt.Errorf(
"Meta key %q exceeds maximum length %d", k, metaKeyMaxLength))
}
if len(v) > metaValueMaxLength {
err = multierror.Append(err, fmt.Errorf(
"Meta value for key %q exceeds maximum length %d", k, metaValueMaxLength))
}
}
return err
}

View File

@ -38,6 +38,7 @@ type ServiceRouterConfigEntry struct {
// the default service.
Routes []ServiceRoute
Meta map[string]string `json:",omitempty"`
EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
RaftIndex
}
@ -54,6 +55,13 @@ func (e *ServiceRouterConfigEntry) GetName() string {
return e.Name
}
func (e *ServiceRouterConfigEntry) GetMeta() map[string]string {
if e == nil {
return nil
}
return e.Meta
}
func (e *ServiceRouterConfigEntry) Normalize() error {
if e == nil {
return fmt.Errorf("config entry is nil")
@ -89,6 +97,10 @@ func (e *ServiceRouterConfigEntry) Validate() error {
return fmt.Errorf("Name is required")
}
if err := validateConfigEntryMeta(e.Meta); err != nil {
return err
}
// Technically you can have no explicit routes at all where just the
// catch-all is configured for you, but at that point maybe you should just
// delete it so it will default?
@ -407,6 +419,7 @@ type ServiceSplitterConfigEntry struct {
// to the FIRST split.
Splits []ServiceSplit
Meta map[string]string `json:",omitempty"`
EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
RaftIndex
}
@ -423,6 +436,13 @@ func (e *ServiceSplitterConfigEntry) GetName() string {
return e.Name
}
func (e *ServiceSplitterConfigEntry) GetMeta() map[string]string {
if e == nil {
return nil
}
return e.Meta
}
func (e *ServiceSplitterConfigEntry) Normalize() error {
if e == nil {
return fmt.Errorf("config entry is nil")
@ -461,6 +481,10 @@ func (e *ServiceSplitterConfigEntry) Validate() error {
return fmt.Errorf("no splits configured")
}
if err := validateConfigEntryMeta(e.Meta); err != nil {
return err
}
const maxScaledWeight = 100 * 100
copyAsKey := func(s ServiceSplit) ServiceSplit {
@ -639,6 +663,7 @@ type ServiceResolverConfigEntry struct {
// to this service.
ConnectTimeout time.Duration `json:",omitempty" alias:"connect_timeout"`
Meta map[string]string `json:",omitempty"`
EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
RaftIndex
}
@ -710,6 +735,13 @@ func (e *ServiceResolverConfigEntry) GetName() string {
return e.Name
}
func (e *ServiceResolverConfigEntry) GetMeta() map[string]string {
if e == nil {
return nil
}
return e.Meta
}
func (e *ServiceResolverConfigEntry) Normalize() error {
if e == nil {
return fmt.Errorf("config entry is nil")
@ -727,6 +759,10 @@ func (e *ServiceResolverConfigEntry) Validate() error {
return fmt.Errorf("Name is required")
}
if err := validateConfigEntryMeta(e.Meta); err != nil {
return err
}
if len(e.Subsets) > 0 {
for name := range e.Subsets {
if name == "" {

View File

@ -27,6 +27,7 @@ type IngressGatewayConfigEntry struct {
// what services to associated to those ports.
Listeners []IngressListener
Meta map[string]string `json:",omitempty"`
EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
RaftIndex
}
@ -73,6 +74,7 @@ type IngressService struct {
// using a "tcp" listener.
Hosts []string
Meta map[string]string `json:",omitempty"`
EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
}
@ -93,6 +95,13 @@ func (e *IngressGatewayConfigEntry) GetName() string {
return e.Name
}
func (e *IngressGatewayConfigEntry) GetMeta() map[string]string {
if e == nil {
return nil
}
return e.Meta
}
func (e *IngressGatewayConfigEntry) Normalize() error {
if e == nil {
return fmt.Errorf("config entry is nil")
@ -121,6 +130,10 @@ func (e *IngressGatewayConfigEntry) Normalize() error {
}
func (e *IngressGatewayConfigEntry) Validate() error {
if err := validateConfigEntryMeta(e.Meta); err != nil {
return err
}
validProtocols := map[string]bool{
"tcp": true,
"http": true,
@ -283,6 +296,7 @@ type TerminatingGatewayConfigEntry struct {
Name string
Services []LinkedService
Meta map[string]string `json:",omitempty"`
EnterpriseMeta `hcl:",squash" mapstructure:",squash"`
RaftIndex
}
@ -322,6 +336,13 @@ func (e *TerminatingGatewayConfigEntry) GetName() string {
return e.Name
}
func (e *TerminatingGatewayConfigEntry) GetMeta() map[string]string {
if e == nil {
return nil
}
return e.Meta
}
func (e *TerminatingGatewayConfigEntry) Normalize() error {
if e == nil {
return fmt.Errorf("config entry is nil")
@ -339,6 +360,10 @@ func (e *TerminatingGatewayConfigEntry) Normalize() error {
}
func (e *TerminatingGatewayConfigEntry) Validate() error {
if err := validateConfigEntryMeta(e.Meta); err != nil {
return err
}
seen := make(map[ServiceID]bool)
for _, svc := range e.Services {

View File

@ -46,6 +46,10 @@ func TestDecodeConfigEntry(t *testing.T) {
snake: `
kind = "proxy-defaults"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
config {
"foo" = 19
"bar" = "abc"
@ -60,6 +64,10 @@ func TestDecodeConfigEntry(t *testing.T) {
camel: `
Kind = "proxy-defaults"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Config {
"foo" = 19
"bar" = "abc"
@ -74,6 +82,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &ProxyConfigEntry{
Kind: "proxy-defaults",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Config: map[string]interface{}{
"foo": 19,
"bar": "abc",
@ -91,6 +103,10 @@ func TestDecodeConfigEntry(t *testing.T) {
snake: `
kind = "service-defaults"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
protocol = "http"
external_sni = "abc-123"
mesh_gateway {
@ -100,6 +116,10 @@ func TestDecodeConfigEntry(t *testing.T) {
camel: `
Kind = "service-defaults"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Protocol = "http"
ExternalSNI = "abc-123"
MeshGateway {
@ -107,8 +127,12 @@ func TestDecodeConfigEntry(t *testing.T) {
}
`,
expect: &ServiceConfigEntry{
Kind: "service-defaults",
Name: "main",
Kind: "service-defaults",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Protocol: "http",
ExternalSNI: "abc-123",
MeshGateway: MeshGatewayConfig{
@ -121,6 +145,10 @@ func TestDecodeConfigEntry(t *testing.T) {
snake: `
kind = "service-router"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
routes = [
{
match {
@ -200,6 +228,10 @@ func TestDecodeConfigEntry(t *testing.T) {
camel: `
Kind = "service-router"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Routes = [
{
Match {
@ -279,6 +311,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &ServiceRouterConfigEntry{
Kind: "service-router",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Routes: []ServiceRoute{
{
Match: &ServiceRouteMatch{
@ -361,6 +397,10 @@ func TestDecodeConfigEntry(t *testing.T) {
snake: `
kind = "service-splitter"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
splits = [
{
weight = 99.1
@ -376,6 +416,10 @@ func TestDecodeConfigEntry(t *testing.T) {
camel: `
Kind = "service-splitter"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Splits = [
{
Weight = 99.1
@ -391,6 +435,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &ServiceSplitterConfigEntry{
Kind: ServiceSplitter,
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Splits: []ServiceSplit{
{
Weight: 99.1,
@ -409,6 +457,10 @@ func TestDecodeConfigEntry(t *testing.T) {
snake: `
kind = "service-resolver"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
default_subset = "v1"
connect_timeout = "15s"
subsets = {
@ -434,6 +486,10 @@ func TestDecodeConfigEntry(t *testing.T) {
camel: `
Kind = "service-resolver"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
DefaultSubset = "v1"
ConnectTimeout = "15s"
Subsets = {
@ -457,8 +513,12 @@ func TestDecodeConfigEntry(t *testing.T) {
}
}`,
expect: &ServiceResolverConfigEntry{
Kind: "service-resolver",
Name: "main",
Kind: "service-resolver",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
DefaultSubset: "v1",
ConnectTimeout: 15 * time.Second,
Subsets: map[string]ServiceResolverSubset{
@ -536,6 +596,10 @@ func TestDecodeConfigEntry(t *testing.T) {
snake: `
kind = "ingress-gateway"
name = "ingress-web"
meta {
"foo" = "bar"
"gir" = "zim"
}
tls {
enabled = true
@ -578,6 +642,10 @@ func TestDecodeConfigEntry(t *testing.T) {
camel: `
Kind = "ingress-gateway"
Name = "ingress-web"
Meta {
"foo" = "bar"
"gir" = "zim"
}
TLS {
Enabled = true
}
@ -618,6 +686,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &IngressGatewayConfigEntry{
Kind: "ingress-gateway",
Name: "ingress-web",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
TLS: GatewayTLSConfig{
Enabled: true,
},
@ -661,6 +733,10 @@ func TestDecodeConfigEntry(t *testing.T) {
snake: `
kind = "terminating-gateway"
name = "terminating-gw-west"
meta {
"foo" = "bar"
"gir" = "zim"
}
services = [
{
name = "payments",
@ -681,6 +757,10 @@ func TestDecodeConfigEntry(t *testing.T) {
camel: `
Kind = "terminating-gateway"
Name = "terminating-gw-west"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Services = [
{
Name = "payments",
@ -701,6 +781,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &TerminatingGatewayConfigEntry{
Kind: "terminating-gateway",
Name: "terminating-gw-west",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Services: []LinkedService{
{
Name: "payments",

View File

@ -95,6 +95,7 @@ type ServiceConfigEntry struct {
MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway"`
Expose ExposeConfig `json:",omitempty"`
ExternalSNI string `json:",omitempty" alias:"external_sni"`
Meta map[string]string `json:",omitempty"`
CreateIndex uint64
ModifyIndex uint64
}
@ -122,6 +123,7 @@ type ProxyConfigEntry struct {
Config map[string]interface{} `json:",omitempty"`
MeshGateway MeshGatewayConfig `json:",omitempty" alias:"mesh_gateway"`
Expose ExposeConfig `json:",omitempty"`
Meta map[string]string `json:",omitempty"`
CreateIndex uint64
ModifyIndex uint64
}

View File

@ -12,6 +12,7 @@ type ServiceRouterConfigEntry struct {
Routes []ServiceRoute `json:",omitempty"`
Meta map[string]string `json:",omitempty"`
CreateIndex uint64
ModifyIndex uint64
}
@ -111,6 +112,7 @@ type ServiceSplitterConfigEntry struct {
Splits []ServiceSplit `json:",omitempty"`
Meta map[string]string `json:",omitempty"`
CreateIndex uint64
ModifyIndex uint64
}
@ -138,6 +140,7 @@ type ServiceResolverConfigEntry struct {
Failover map[string]ServiceResolverFailover `json:",omitempty"`
ConnectTimeout time.Duration `json:",omitempty" alias:"connect_timeout"`
Meta map[string]string `json:",omitempty"`
CreateIndex uint64
ModifyIndex uint64
}

View File

@ -21,6 +21,8 @@ type IngressGatewayConfigEntry struct {
// what services to associated to those ports.
Listeners []IngressListener
Meta map[string]string `json:",omitempty"`
// CreateIndex is the Raft index this entry was created at. This is a
// read-only field.
CreateIndex uint64
@ -115,6 +117,8 @@ type TerminatingGatewayConfigEntry struct {
// Services is a list of service names represented by the terminating gateway.
Services []LinkedService `json:",omitempty"`
Meta map[string]string `json:",omitempty"`
// CreateIndex is the Raft index this entry was created at. This is a
// read-only field.
CreateIndex uint64

View File

@ -271,6 +271,10 @@ func TestDecodeConfigEntry(t *testing.T) {
{
"Kind": "proxy-defaults",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Config": {
"foo": 19,
"bar": "abc",
@ -286,6 +290,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &ProxyConfigEntry{
Kind: "proxy-defaults",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Config: map[string]interface{}{
"foo": float64(19),
"bar": "abc",
@ -304,6 +312,10 @@ func TestDecodeConfigEntry(t *testing.T) {
{
"Kind": "service-defaults",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Protocol": "http",
"ExternalSNI": "abc-123",
"MeshGateway": {
@ -312,8 +324,12 @@ func TestDecodeConfigEntry(t *testing.T) {
}
`,
expect: &ServiceConfigEntry{
Kind: "service-defaults",
Name: "main",
Kind: "service-defaults",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Protocol: "http",
ExternalSNI: "abc-123",
MeshGateway: MeshGatewayConfig{
@ -327,6 +343,10 @@ func TestDecodeConfigEntry(t *testing.T) {
{
"Kind": "service-router",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Routes": [
{
"Match": {
@ -407,6 +427,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &ServiceRouterConfigEntry{
Kind: "service-router",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Routes: []ServiceRoute{
{
Match: &ServiceRouteMatch{
@ -490,6 +514,10 @@ func TestDecodeConfigEntry(t *testing.T) {
{
"Kind": "service-splitter",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Splits": [
{
"Weight": 99.1,
@ -506,6 +534,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &ServiceSplitterConfigEntry{
Kind: ServiceSplitter,
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Splits: []ServiceSplit{
{
Weight: 99.1,
@ -525,6 +557,10 @@ func TestDecodeConfigEntry(t *testing.T) {
{
"Kind": "service-resolver",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"DefaultSubset": "v1",
"ConnectTimeout": "15s",
"Subsets": {
@ -549,8 +585,12 @@ func TestDecodeConfigEntry(t *testing.T) {
}
}`,
expect: &ServiceResolverConfigEntry{
Kind: "service-resolver",
Name: "main",
Kind: "service-resolver",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
DefaultSubset: "v1",
ConnectTimeout: 15 * time.Second,
Subsets: map[string]ServiceResolverSubset{
@ -619,6 +659,10 @@ func TestDecodeConfigEntry(t *testing.T) {
{
"Kind": "ingress-gateway",
"Name": "ingress-web",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Tls": {
"Enabled": true
},
@ -651,6 +695,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &IngressGatewayConfigEntry{
Kind: "ingress-gateway",
Name: "ingress-web",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
TLS: GatewayTLSConfig{
Enabled: true,
},
@ -686,6 +734,10 @@ func TestDecodeConfigEntry(t *testing.T) {
{
"Kind": "terminating-gateway",
"Name": "terminating-west",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Services": [
{
"Namespace": "foo",
@ -707,6 +759,10 @@ func TestDecodeConfigEntry(t *testing.T) {
expect: &TerminatingGatewayConfigEntry{
Kind: "terminating-gateway",
Name: "terminating-west",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Services: []LinkedService{
{
Namespace: "foo",

View File

@ -161,6 +161,10 @@ func TestParseConfigEntry(t *testing.T) {
snake: `
kind = "proxy-defaults"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
config {
"foo" = 19
"bar" = "abc"
@ -175,6 +179,10 @@ func TestParseConfigEntry(t *testing.T) {
camel: `
Kind = "proxy-defaults"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Config {
"foo" = 19
"bar" = "abc"
@ -190,6 +198,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"kind": "proxy-defaults",
"name": "main",
"meta" : {
"foo": "bar",
"gir": "zim"
},
"config": {
"foo": 19,
"bar": "abc",
@ -206,6 +218,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"Kind": "proxy-defaults",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Config": {
"foo": 19,
"bar": "abc",
@ -221,6 +237,10 @@ func TestParseConfigEntry(t *testing.T) {
expect: &api.ProxyConfigEntry{
Kind: "proxy-defaults",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Config: map[string]interface{}{
"foo": 19,
"bar": "abc",
@ -235,6 +255,10 @@ func TestParseConfigEntry(t *testing.T) {
expectJSON: &api.ProxyConfigEntry{
Kind: "proxy-defaults",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Config: map[string]interface{}{
"foo": float64(19), // json decoding gives float64 instead of int here
"bar": "abc",
@ -253,6 +277,10 @@ func TestParseConfigEntry(t *testing.T) {
kind = "terminating-gateway"
name = "terminating-gw-west"
namespace = "default"
meta {
"foo" = "bar"
"gir" = "zim"
}
services = [
{
name = "billing"
@ -272,6 +300,10 @@ func TestParseConfigEntry(t *testing.T) {
Kind = "terminating-gateway"
Name = "terminating-gw-west"
Namespace = "default"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Services = [
{
Name = "billing"
@ -292,6 +324,10 @@ func TestParseConfigEntry(t *testing.T) {
"kind": "terminating-gateway",
"name": "terminating-gw-west",
"namespace": "default",
"meta" : {
"foo": "bar",
"gir": "zim"
},
"services": [
{
"name": "billing",
@ -313,6 +349,10 @@ func TestParseConfigEntry(t *testing.T) {
"Kind": "terminating-gateway",
"Name": "terminating-gw-west",
"Namespace": "default",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Services": [
{
"Name": "billing",
@ -333,6 +373,10 @@ func TestParseConfigEntry(t *testing.T) {
Kind: "terminating-gateway",
Name: "terminating-gw-west",
Namespace: "default",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Services: []api.LinkedService{
{
Name: "billing",
@ -352,6 +396,10 @@ func TestParseConfigEntry(t *testing.T) {
Kind: "terminating-gateway",
Name: "terminating-gw-west",
Namespace: "default",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Services: []api.LinkedService{
{
Name: "billing",
@ -373,6 +421,10 @@ func TestParseConfigEntry(t *testing.T) {
snake: `
kind = "service-defaults"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
protocol = "http"
external_sni = "abc-123"
mesh_gateway {
@ -382,6 +434,10 @@ func TestParseConfigEntry(t *testing.T) {
camel: `
Kind = "service-defaults"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Protocol = "http"
ExternalSNI = "abc-123"
MeshGateway {
@ -392,6 +448,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"kind": "service-defaults",
"name": "main",
"meta" : {
"foo": "bar",
"gir": "zim"
},
"protocol": "http",
"external_sni": "abc-123",
"mesh_gateway": {
@ -403,6 +463,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"Kind": "service-defaults",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Protocol": "http",
"ExternalSNI": "abc-123",
"MeshGateway": {
@ -411,8 +475,12 @@ func TestParseConfigEntry(t *testing.T) {
}
`,
expect: &api.ServiceConfigEntry{
Kind: "service-defaults",
Name: "main",
Kind: "service-defaults",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Protocol: "http",
ExternalSNI: "abc-123",
MeshGateway: api.MeshGatewayConfig{
@ -425,6 +493,10 @@ func TestParseConfigEntry(t *testing.T) {
snake: `
kind = "service-router"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
routes = [
{
match {
@ -504,6 +576,10 @@ func TestParseConfigEntry(t *testing.T) {
camel: `
Kind = "service-router"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Routes = [
{
Match {
@ -584,6 +660,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"kind": "service-router",
"name": "main",
"meta" : {
"foo": "bar",
"gir": "zim"
},
"routes": [
{
"match": {
@ -671,6 +751,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"Kind": "service-router",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Routes": [
{
"Match": {
@ -757,6 +841,10 @@ func TestParseConfigEntry(t *testing.T) {
expect: &api.ServiceRouterConfigEntry{
Kind: "service-router",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Routes: []api.ServiceRoute{
{
Match: &api.ServiceRouteMatch{
@ -839,6 +927,10 @@ func TestParseConfigEntry(t *testing.T) {
snake: `
kind = "service-splitter"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
splits = [
{
weight = 97.1
@ -858,6 +950,10 @@ func TestParseConfigEntry(t *testing.T) {
camel: `
Kind = "service-splitter"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Splits = [
{
Weight = 97.1
@ -878,6 +974,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"kind": "service-splitter",
"name": "main",
"meta" : {
"foo": "bar",
"gir": "zim"
},
"splits": [
{
"weight": 97.1,
@ -899,6 +999,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"Kind": "service-splitter",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Splits": [
{
"Weight": 97.1,
@ -919,6 +1023,10 @@ func TestParseConfigEntry(t *testing.T) {
expect: &api.ServiceSplitterConfigEntry{
Kind: api.ServiceSplitter,
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
Splits: []api.ServiceSplit{
{
Weight: 97.1,
@ -941,6 +1049,10 @@ func TestParseConfigEntry(t *testing.T) {
snake: `
kind = "service-resolver"
name = "main"
meta {
"foo" = "bar"
"gir" = "zim"
}
default_subset = "v1"
connect_timeout = "15s"
subsets = {
@ -966,6 +1078,10 @@ func TestParseConfigEntry(t *testing.T) {
camel: `
Kind = "service-resolver"
Name = "main"
Meta {
"foo" = "bar"
"gir" = "zim"
}
DefaultSubset = "v1"
ConnectTimeout = "15s"
Subsets = {
@ -992,6 +1108,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"kind": "service-resolver",
"name": "main",
"meta" : {
"foo": "bar",
"gir": "zim"
},
"default_subset": "v1",
"connect_timeout": "15s",
"subsets": {
@ -1025,6 +1145,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"Kind": "service-resolver",
"Name": "main",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"DefaultSubset": "v1",
"ConnectTimeout": "15s",
"Subsets": {
@ -1055,8 +1179,12 @@ func TestParseConfigEntry(t *testing.T) {
}
`,
expect: &api.ServiceResolverConfigEntry{
Kind: "service-resolver",
Name: "main",
Kind: "service-resolver",
Name: "main",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
DefaultSubset: "v1",
ConnectTimeout: 15 * time.Second,
Subsets: map[string]api.ServiceResolverSubset{
@ -1390,6 +1518,10 @@ func TestParseConfigEntry(t *testing.T) {
snake: `
kind = "ingress-gateway"
name = "ingress-web"
meta {
"foo" = "bar"
"gir" = "zim"
}
tls {
enabled = true
}
@ -1413,6 +1545,10 @@ func TestParseConfigEntry(t *testing.T) {
camel: `
Kind = "ingress-gateway"
Name = "ingress-web"
Meta {
"foo" = "bar"
"gir" = "zim"
}
Tls {
Enabled = true
}
@ -1437,6 +1573,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"kind": "ingress-gateway",
"name": "ingress-web",
"meta" : {
"foo": "bar",
"gir": "zim"
},
"tls": {
"enabled": true
},
@ -1462,6 +1602,10 @@ func TestParseConfigEntry(t *testing.T) {
{
"Kind": "ingress-gateway",
"Name": "ingress-web",
"Meta" : {
"foo": "bar",
"gir": "zim"
},
"Tls": {
"Enabled": true
},
@ -1486,6 +1630,10 @@ func TestParseConfigEntry(t *testing.T) {
expect: &api.IngressGatewayConfigEntry{
Kind: "ingress-gateway",
Name: "ingress-web",
Meta: map[string]string{
"foo": "bar",
"gir": "zim",
},
TLS: api.GatewayTLSConfig{
Enabled: true,
},

View File

@ -329,6 +329,8 @@ Also make two services in the frontend namespace available over a custom port wi
the gateway is registered in. If omitted, the namespace will be inherited
from [the request](/api/config#ns) or will default to the `default` namespace.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.9.0.
- `TLS` `(TLSConfig: <optional>)` - TLS configuration for this gateway.
- `Enabled` `(bool: false)` - Set this configuration to enable TLS for

View File

@ -46,6 +46,8 @@ Config {
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.9.0.
- `Config` `(map[string]arbitrary)` - An arbitrary map of configuration values used by Connect proxies.
The available configurations depend on the Connect proxy you use. Any values
that your proxy allows can be configured globally here. To

View File

@ -31,6 +31,8 @@ Protocol = "http"
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.9.0.
- `Protocol` `(string: "tcp")` - Sets the protocol of the service. This is used
by Connect proxies for things like observability features and to unlock usage
of the [`service-splitter`](/docs/agent/config-entries/service-splitter) and

View File

@ -78,6 +78,10 @@ Name = "web"
- `Name` `(string: <required>)` - Set to the name of the service being configured.
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.9.0.
- `ConnectTimeout` `(duration: 0s)` - The timeout for establishing new network
connections to this service.

View File

@ -129,6 +129,10 @@ Routes = [
- `Name` `(string: <required>)` - Set to the name of the service being configured.
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.9.0.
- `Routes` `(array<ServiceRoute>)` - The list of routes to consider when
processing L7 requests. The first route to match in the list is terminal and
stops further evaluation. Traffic that fails to match any of the provided

View File

@ -81,6 +81,10 @@ Splits = [
- `Name` `(string: <required>)` - Set to the name of the service being configured.
- `Namespace` `(string: "default")` <EnterpriseAlert inline /> - Specifies the namespace the config entry will apply to.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.9.0.
- `Splits` `(array<ServiceSplit>)` - Defines how much traffic to send to which
set of service instances during a traffic split. The sum of weights across
all splits must add up to 100.

View File

@ -407,6 +407,8 @@ and configure default certificates for mutual TLS. Also override the SNI and CA
If omitted, the namespace will be inherited from [the request](/api/config#ns)
or will default to the `default` namespace.
- `Meta` `(map<string|string>: nil)` - Specifies arbitrary KV metadata pairs. Added in Consul 1.9.0.
- `Services` `(array<LinkedService>: <optional>)` - A list of services to link
with the gateway. The gateway will proxy traffic to these services. These linked services
must be registered with Consul for the gateway to discover their addresses. They must also