connect: enable setting connect upstream destination namespace

This commit is contained in:
Seth Hoenig 2022-05-25 15:05:15 -05:00
parent 9e476c75b8
commit 4631045d83
11 changed files with 116 additions and 71 deletions

3
.changelog/13125.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
connect: Added missing ability of setting Connect upstream destination namespace
```

View File

@ -75,7 +75,6 @@ func (css *ConsulSidecarService) Canonicalize() {
css.Proxy.Canonicalize()
}
// SidecarTask represents a subset of Task fields that can be set to override
// the fields of the Task generated for the sidecar
type SidecarTask struct {
@ -196,11 +195,12 @@ func (c *ConsulMeshGateway) Copy() *ConsulMeshGateway {
// 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"`
LocalBindAddress string `mapstructure:"local_bind_address" hcl:"local_bind_address,optional"`
MeshGateway *ConsulMeshGateway `mapstructure:"mesh_gateway" hcl:"mesh_gateway,block"`
DestinationName string `mapstructure:"destination_name" hcl:"destination_name,optional"`
DestinationNamespace string `mapstructure:"destination_namespace" hcl:"destination_namespace,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"`
MeshGateway *ConsulMeshGateway `mapstructure:"mesh_gateway" hcl:"mesh_gateway,block"`
}
func (cu *ConsulUpstream) Copy() *ConsulUpstream {
@ -208,11 +208,12 @@ func (cu *ConsulUpstream) Copy() *ConsulUpstream {
return nil
}
return &ConsulUpstream{
DestinationName: cu.DestinationName,
LocalBindPort: cu.LocalBindPort,
Datacenter: cu.Datacenter,
LocalBindAddress: cu.LocalBindAddress,
MeshGateway: cu.MeshGateway.Copy(),
DestinationName: cu.DestinationName,
DestinationNamespace: cu.DestinationNamespace,
LocalBindPort: cu.LocalBindPort,
Datacenter: cu.Datacenter,
LocalBindAddress: cu.LocalBindAddress,
MeshGateway: cu.MeshGateway.Copy(),
}
}

View File

@ -163,11 +163,12 @@ func TestConsulUpstream_Copy(t *testing.T) {
t.Run("complete upstream", func(t *testing.T) {
cu := &ConsulUpstream{
DestinationName: "dest1",
Datacenter: "dc2",
LocalBindPort: 2000,
LocalBindAddress: "10.0.0.1",
MeshGateway: &ConsulMeshGateway{Mode: "remote"},
DestinationName: "dest1",
DestinationNamespace: "ns2",
Datacenter: "dc2",
LocalBindPort: 2000,
LocalBindAddress: "10.0.0.1",
MeshGateway: &ConsulMeshGateway{Mode: "remote"},
}
result := cu.Copy()
require.Equal(t, cu, result)
@ -185,19 +186,21 @@ func TestConsulUpstream_Canonicalize(t *testing.T) {
t.Run("complete", func(t *testing.T) {
cu := &ConsulUpstream{
DestinationName: "dest1",
Datacenter: "dc2",
LocalBindPort: 2000,
LocalBindAddress: "10.0.0.1",
MeshGateway: &ConsulMeshGateway{Mode: ""},
DestinationName: "dest1",
DestinationNamespace: "ns2",
Datacenter: "dc2",
LocalBindPort: 2000,
LocalBindAddress: "10.0.0.1",
MeshGateway: &ConsulMeshGateway{Mode: ""},
}
cu.Canonicalize()
require.Equal(t, &ConsulUpstream{
DestinationName: "dest1",
Datacenter: "dc2",
LocalBindPort: 2000,
LocalBindAddress: "10.0.0.1",
MeshGateway: &ConsulMeshGateway{Mode: ""},
DestinationName: "dest1",
DestinationNamespace: "ns2",
Datacenter: "dc2",
LocalBindPort: 2000,
LocalBindAddress: "10.0.0.1",
MeshGateway: &ConsulMeshGateway{Mode: ""},
}, cu)
})
}

View File

@ -195,11 +195,12 @@ 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,
LocalBindAddress: upstream.LocalBindAddress,
MeshGateway: connectMeshGateway(upstream.MeshGateway),
DestinationName: upstream.DestinationName,
DestinationNamespace: upstream.DestinationNamespace,
LocalBindPort: upstream.LocalBindPort,
Datacenter: upstream.Datacenter,
LocalBindAddress: upstream.LocalBindAddress,
MeshGateway: connectMeshGateway(upstream.MeshGateway),
}
}
return upstreams

View File

@ -360,19 +360,21 @@ func TestConnect_connectUpstreams(t *testing.T) {
DestinationName: "foo",
LocalBindPort: 8000,
}, {
DestinationName: "bar",
LocalBindPort: 9000,
Datacenter: "dc2",
LocalBindAddress: "127.0.0.2",
DestinationName: "bar",
DestinationNamespace: "ns2",
LocalBindPort: 9000,
Datacenter: "dc2",
LocalBindAddress: "127.0.0.2",
}},
connectUpstreams([]structs.ConsulUpstream{{
DestinationName: "foo",
LocalBindPort: 8000,
}, {
DestinationName: "bar",
LocalBindPort: 9000,
Datacenter: "dc2",
LocalBindAddress: "127.0.0.2",
DestinationName: "bar",
DestinationNamespace: "ns2",
LocalBindPort: 9000,
Datacenter: "dc2",
LocalBindAddress: "127.0.0.2",
}}),
)
})

View File

@ -1628,11 +1628,12 @@ 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,
LocalBindAddress: upstream.LocalBindAddress,
MeshGateway: apiMeshGatewayToStructs(upstream.MeshGateway),
DestinationName: upstream.DestinationName,
DestinationNamespace: upstream.DestinationNamespace,
LocalBindPort: upstream.LocalBindPort,
Datacenter: upstream.Datacenter,
LocalBindAddress: upstream.LocalBindAddress,
MeshGateway: apiMeshGatewayToStructs(upstream.MeshGateway),
}
}
return upstreams

View File

@ -3679,17 +3679,19 @@ 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",
LocalBindAddress: "127.0.0.2",
MeshGateway: &structs.ConsulMeshGateway{Mode: "local"},
DestinationName: "upstream",
DestinationNamespace: "ns2",
LocalBindPort: 8000,
Datacenter: "dc2",
LocalBindAddress: "127.0.0.2",
MeshGateway: &structs.ConsulMeshGateway{Mode: "local"},
}}, apiUpstreamsToStructs([]*api.ConsulUpstream{{
DestinationName: "upstream",
LocalBindPort: 8000,
Datacenter: "dc2",
LocalBindAddress: "127.0.0.2",
MeshGateway: &api.ConsulMeshGateway{Mode: "local"},
DestinationName: "upstream",
DestinationNamespace: "ns2",
LocalBindPort: 8000,
Datacenter: "dc2",
LocalBindAddress: "127.0.0.2",
MeshGateway: &api.ConsulMeshGateway{Mode: "local"},
}}))
}

View File

@ -2773,10 +2773,11 @@ func TestTaskGroupDiff(t *testing.T) {
LocalServicePort: 8080,
Upstreams: []ConsulUpstream{
{
DestinationName: "foo",
LocalBindPort: 8000,
Datacenter: "dc2",
LocalBindAddress: "127.0.0.2",
DestinationName: "foo",
DestinationNamespace: "ns2",
LocalBindPort: 8000,
Datacenter: "dc2",
LocalBindAddress: "127.0.0.2",
MeshGateway: &ConsulMeshGateway{
Mode: "remote",
},
@ -3101,6 +3102,12 @@ func TestTaskGroupDiff(t *testing.T) {
Old: "",
New: "foo",
},
{
Type: DiffTypeAdded,
Name: "DestinationNamespace",
Old: "",
New: "ns2",
},
{
Type: DiffTypeAdded,
Name: "LocalBindAddress",

View File

@ -725,6 +725,7 @@ func hashConnect(h hash.Hash, connect *ConsulConnect) {
hashConfig(h, p.Config)
for _, upstream := range p.Upstreams {
hashString(h, upstream.DestinationName)
hashString(h, upstream.DestinationNamespace)
hashString(h, strconv.Itoa(upstream.LocalBindPort))
hashStringIfNonEmpty(h, upstream.Datacenter)
hashStringIfNonEmpty(h, upstream.LocalBindAddress)
@ -1363,6 +1364,9 @@ type ConsulUpstream struct {
// DestinationName is the name of the upstream service.
DestinationName string
// DestinationNamespace is the namespace of the upstream service.
DestinationNamespace string
// LocalBindPort is the port the proxy will receive connections for the
// upstream on.
LocalBindPort int
@ -1403,11 +1407,12 @@ func (u *ConsulUpstream) Copy() *ConsulUpstream {
}
return &ConsulUpstream{
DestinationName: u.DestinationName,
LocalBindPort: u.LocalBindPort,
Datacenter: u.Datacenter,
LocalBindAddress: u.LocalBindAddress,
MeshGateway: u.MeshGateway.Copy(),
DestinationName: u.DestinationName,
DestinationNamespace: u.DestinationNamespace,
LocalBindPort: u.LocalBindPort,
Datacenter: u.Datacenter,
LocalBindAddress: u.LocalBindAddress,
MeshGateway: u.MeshGateway.Copy(),
}
}
@ -1420,6 +1425,8 @@ func (u *ConsulUpstream) Equals(o *ConsulUpstream) bool {
switch {
case u.DestinationName != o.DestinationName:
return false
case u.DestinationNamespace != o.DestinationNamespace:
return false
case u.LocalBindPort != o.LocalBindPort:
return false
case u.Datacenter != o.Datacenter:

View File

@ -209,8 +209,9 @@ func TestService_Hash(t *testing.T) {
LocalServicePort: 24000,
Config: map[string]interface{}{"foo": "bar"},
Upstreams: []ConsulUpstream{{
DestinationName: "upstream1",
LocalBindPort: 29000,
DestinationName: "upstream1",
DestinationNamespace: "ns2",
LocalBindPort: 29000,
}},
},
},
@ -291,11 +292,15 @@ func TestService_Hash(t *testing.T) {
try(t, func(s *svc) { s.Connect.SidecarService.Proxy.Config = map[string]interface{}{"foo": "baz"} })
})
t.Run("mod connect sidecar proxy upstream dest name", func(t *testing.T) {
t.Run("mod connect sidecar proxy upstream destination name", func(t *testing.T) {
try(t, func(s *svc) { s.Connect.SidecarService.Proxy.Upstreams[0].DestinationName = "dest2" })
})
t.Run("mod connect sidecar proxy upstream dest local bind port", func(t *testing.T) {
t.Run("mod connect sidecar proxy upstream destination namespace", func(t *testing.T) {
try(t, func(s *svc) { s.Connect.SidecarService.Proxy.Upstreams[0].DestinationNamespace = "ns3" })
})
t.Run("mod connect sidecar proxy upstream destination local bind port", func(t *testing.T) {
try(t, func(s *svc) { s.Connect.SidecarService.Proxy.Upstreams[0].LocalBindPort = 29999 })
})
}
@ -331,12 +336,14 @@ func TestConsulConnect_CopyEquals(t *testing.T) {
LocalServicePort: 8080,
Upstreams: []ConsulUpstream{
{
DestinationName: "up1",
LocalBindPort: 9002,
DestinationName: "up1",
DestinationNamespace: "ns2",
LocalBindPort: 9002,
},
{
DestinationName: "up2",
LocalBindPort: 9003,
DestinationName: "up2",
DestinationNamespace: "ns2",
LocalBindPort: 9003,
},
},
Config: map[string]interface{}{
@ -530,6 +537,16 @@ func TestConsulUpstream_upstreamEquals(t *testing.T) {
require.False(t, upstreamsEquals(a, b))
})
t.Run("different namespace", func(t *testing.T) {
a := []ConsulUpstream{up("foo", 8000)}
a[0].DestinationNamespace = "ns1"
b := []ConsulUpstream{up("foo", 8000)}
b[0].DestinationNamespace = "ns2"
require.False(t, upstreamsEquals(a, b))
})
t.Run("different mesh_gateway", func(t *testing.T) {
a := []ConsulUpstream{{DestinationName: "foo", MeshGateway: &ConsulMeshGateway{Mode: "local"}}}
b := []ConsulUpstream{{DestinationName: "foo", MeshGateway: &ConsulMeshGateway{Mode: "remote"}}}

View File

@ -82,6 +82,7 @@ job "countdash" {
## `upstreams` Parameters
- `destination_name` `(string: <required>)` - Name of the upstream service.
- `destination_namespace` `(string: <required>)` - Name of the upstream Consul namespace.
- `local_bind_port` - `(int: <required>)` - The port the proxy will receive
connections for the upstream on.
- `datacenter` `(string: "")` - The Consul datacenter in which to issue the