2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
2023-08-11 13:12:13 +00:00
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-03-28 18:39:22 +00:00
|
|
|
|
2018-09-27 13:33:12 +00:00
|
|
|
package agent
|
|
|
|
|
|
|
|
import (
|
2018-09-27 14:00:51 +00:00
|
|
|
"fmt"
|
2018-09-27 13:33:12 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2022-08-03 01:50:40 +00:00
|
|
|
"github.com/hashicorp/consul/acl"
|
|
|
|
|
2018-09-27 13:33:12 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2020-11-30 17:53:46 +00:00
|
|
|
|
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
2018-09-27 13:33:12 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestAgent_sidecarServiceFromNodeService(t *testing.T) {
|
2020-12-07 18:42:55 +00:00
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("too slow for testing.Short")
|
|
|
|
}
|
|
|
|
|
2018-09-27 13:33:12 +00:00
|
|
|
tests := []struct {
|
2022-07-27 18:19:17 +00:00
|
|
|
name string
|
|
|
|
sd *structs.ServiceDefinition
|
|
|
|
token string
|
|
|
|
wantNS *structs.NodeService
|
|
|
|
wantChecks []*structs.CheckType
|
|
|
|
wantToken string
|
|
|
|
wantErr string
|
2018-09-27 13:33:12 +00:00
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "no sidecar",
|
|
|
|
sd: &structs.ServiceDefinition{
|
|
|
|
Name: "web",
|
|
|
|
Port: 1111,
|
|
|
|
},
|
|
|
|
token: "foo",
|
|
|
|
wantNS: nil,
|
|
|
|
wantChecks: nil,
|
|
|
|
wantToken: "",
|
|
|
|
wantErr: "", // Should NOT error
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "all the defaults",
|
|
|
|
sd: &structs.ServiceDefinition{
|
|
|
|
ID: "web1",
|
|
|
|
Name: "web",
|
|
|
|
Port: 1111,
|
|
|
|
Connect: &structs.ServiceConnect{
|
|
|
|
SidecarService: &structs.ServiceDefinition{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
token: "foo",
|
|
|
|
wantNS: &structs.NodeService{
|
2021-07-22 18:20:45 +00:00
|
|
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
2018-09-27 13:33:12 +00:00
|
|
|
Kind: structs.ServiceKindConnectProxy,
|
|
|
|
ID: "web1-sidecar-proxy",
|
|
|
|
Service: "web-sidecar-proxy",
|
2022-09-07 00:35:31 +00:00
|
|
|
Port: 0,
|
2018-09-27 13:33:12 +00:00
|
|
|
LocallyRegisteredAsSidecar: true,
|
|
|
|
Proxy: structs.ConnectProxyConfig{
|
|
|
|
DestinationServiceName: "web",
|
|
|
|
DestinationServiceID: "web1",
|
|
|
|
LocalServiceAddress: "127.0.0.1",
|
|
|
|
LocalServicePort: 1111,
|
|
|
|
},
|
|
|
|
},
|
2022-09-07 00:35:31 +00:00
|
|
|
wantChecks: nil,
|
|
|
|
wantToken: "foo",
|
2018-09-27 13:33:12 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "all the allowed overrides",
|
|
|
|
sd: &structs.ServiceDefinition{
|
|
|
|
ID: "web1",
|
|
|
|
Name: "web",
|
|
|
|
Port: 1111,
|
Improve Connect with Prepared Queries (#5291)
Given a query like:
```
{
"Name": "tagged-connect-query",
"Service": {
"Service": "foo",
"Tags": ["tag"],
"Connect": true
}
}
```
And a Consul configuration like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {} },
"tags": ["tag"]
]
}
```
If you executed the query it would always turn up with 0 results. This was because the sidecar service was being created without any tags. You could instead make your config look like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {
"tags": ["tag"]
} },
"tags": ["tag"]
]
}
```
However that is a bit redundant for most cases. This PR ensures that the tags and service meta of the parent service get copied to the sidecar service. If there are any tags or service meta set in the sidecar service definition then this copying does not take place. After the changes, the query will now return the expected results.
A second change was made to prepared queries in this PR which is to allow filtering on ServiceMeta just like we allow for filtering on NodeMeta.
2019-02-04 14:36:51 +00:00
|
|
|
Tags: []string{"baz"},
|
|
|
|
Meta: map[string]string{"foo": "baz"},
|
2018-09-27 13:33:12 +00:00
|
|
|
Connect: &structs.ServiceConnect{
|
|
|
|
SidecarService: &structs.ServiceDefinition{
|
|
|
|
Name: "motorbike1",
|
|
|
|
Port: 3333,
|
|
|
|
Tags: []string{"foo", "bar"},
|
|
|
|
Address: "127.127.127.127",
|
|
|
|
Meta: map[string]string{"foo": "bar"},
|
|
|
|
Check: structs.CheckType{
|
|
|
|
ScriptArgs: []string{"sleep", "1"},
|
|
|
|
Interval: 999 * time.Second,
|
|
|
|
},
|
|
|
|
Token: "custom-token",
|
|
|
|
EnableTagOverride: true,
|
|
|
|
Proxy: &structs.ConnectProxyConfig{
|
|
|
|
DestinationServiceName: "web",
|
|
|
|
DestinationServiceID: "web1",
|
|
|
|
LocalServiceAddress: "127.0.127.0",
|
|
|
|
LocalServicePort: 9999,
|
|
|
|
Config: map[string]interface{}{"baz": "qux"},
|
2023-03-22 18:56:18 +00:00
|
|
|
Upstreams: structs.TestUpstreams(t, false),
|
2018-09-27 13:33:12 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
token: "foo",
|
|
|
|
wantNS: &structs.NodeService{
|
2021-07-22 18:20:45 +00:00
|
|
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
2020-02-06 15:52:25 +00:00
|
|
|
Kind: structs.ServiceKindConnectProxy,
|
|
|
|
ID: "web1-sidecar-proxy",
|
|
|
|
Service: "motorbike1",
|
|
|
|
Port: 3333,
|
|
|
|
Tags: []string{"foo", "bar"},
|
|
|
|
Address: "127.127.127.127",
|
2018-09-27 13:33:12 +00:00
|
|
|
Meta: map[string]string{
|
|
|
|
"foo": "bar",
|
|
|
|
},
|
|
|
|
LocallyRegisteredAsSidecar: true,
|
|
|
|
EnableTagOverride: true,
|
|
|
|
Proxy: structs.ConnectProxyConfig{
|
|
|
|
DestinationServiceName: "web",
|
|
|
|
DestinationServiceID: "web1",
|
|
|
|
LocalServiceAddress: "127.0.127.0",
|
|
|
|
LocalServicePort: 9999,
|
|
|
|
Config: map[string]interface{}{"baz": "qux"},
|
2023-03-22 18:56:18 +00:00
|
|
|
Upstreams: structs.TestAddDefaultsToUpstreams(t, structs.TestUpstreams(t, false),
|
2021-07-26 21:12:29 +00:00
|
|
|
*structs.DefaultEnterpriseMetaInDefaultPartition()),
|
2018-09-27 13:33:12 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
wantChecks: []*structs.CheckType{
|
2020-06-16 17:19:31 +00:00
|
|
|
{
|
2018-09-27 13:33:12 +00:00
|
|
|
ScriptArgs: []string{"sleep", "1"},
|
|
|
|
Interval: 999 * time.Second,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wantToken: "custom-token",
|
|
|
|
},
|
Improve Connect with Prepared Queries (#5291)
Given a query like:
```
{
"Name": "tagged-connect-query",
"Service": {
"Service": "foo",
"Tags": ["tag"],
"Connect": true
}
}
```
And a Consul configuration like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {} },
"tags": ["tag"]
]
}
```
If you executed the query it would always turn up with 0 results. This was because the sidecar service was being created without any tags. You could instead make your config look like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {
"tags": ["tag"]
} },
"tags": ["tag"]
]
}
```
However that is a bit redundant for most cases. This PR ensures that the tags and service meta of the parent service get copied to the sidecar service. If there are any tags or service meta set in the sidecar service definition then this copying does not take place. After the changes, the query will now return the expected results.
A second change was made to prepared queries in this PR which is to allow filtering on ServiceMeta just like we allow for filtering on NodeMeta.
2019-02-04 14:36:51 +00:00
|
|
|
{
|
2023-08-10 18:00:44 +00:00
|
|
|
name: "inherit locality, tags and meta",
|
Improve Connect with Prepared Queries (#5291)
Given a query like:
```
{
"Name": "tagged-connect-query",
"Service": {
"Service": "foo",
"Tags": ["tag"],
"Connect": true
}
}
```
And a Consul configuration like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {} },
"tags": ["tag"]
]
}
```
If you executed the query it would always turn up with 0 results. This was because the sidecar service was being created without any tags. You could instead make your config look like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {
"tags": ["tag"]
} },
"tags": ["tag"]
]
}
```
However that is a bit redundant for most cases. This PR ensures that the tags and service meta of the parent service get copied to the sidecar service. If there are any tags or service meta set in the sidecar service definition then this copying does not take place. After the changes, the query will now return the expected results.
A second change was made to prepared queries in this PR which is to allow filtering on ServiceMeta just like we allow for filtering on NodeMeta.
2019-02-04 14:36:51 +00:00
|
|
|
sd: &structs.ServiceDefinition{
|
|
|
|
ID: "web1",
|
|
|
|
Name: "web",
|
|
|
|
Port: 1111,
|
|
|
|
Tags: []string{"foo"},
|
|
|
|
Meta: map[string]string{"foo": "bar"},
|
2023-08-10 18:00:44 +00:00
|
|
|
Locality: &structs.Locality{
|
|
|
|
Region: "us-east-1",
|
|
|
|
Zone: "us-east-1a",
|
|
|
|
},
|
Improve Connect with Prepared Queries (#5291)
Given a query like:
```
{
"Name": "tagged-connect-query",
"Service": {
"Service": "foo",
"Tags": ["tag"],
"Connect": true
}
}
```
And a Consul configuration like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {} },
"tags": ["tag"]
]
}
```
If you executed the query it would always turn up with 0 results. This was because the sidecar service was being created without any tags. You could instead make your config look like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {
"tags": ["tag"]
} },
"tags": ["tag"]
]
}
```
However that is a bit redundant for most cases. This PR ensures that the tags and service meta of the parent service get copied to the sidecar service. If there are any tags or service meta set in the sidecar service definition then this copying does not take place. After the changes, the query will now return the expected results.
A second change was made to prepared queries in this PR which is to allow filtering on ServiceMeta just like we allow for filtering on NodeMeta.
2019-02-04 14:36:51 +00:00
|
|
|
Connect: &structs.ServiceConnect{
|
|
|
|
SidecarService: &structs.ServiceDefinition{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wantNS: &structs.NodeService{
|
2023-08-10 18:00:44 +00:00
|
|
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
|
|
|
Kind: structs.ServiceKindConnectProxy,
|
|
|
|
ID: "web1-sidecar-proxy",
|
|
|
|
Service: "web-sidecar-proxy",
|
|
|
|
Port: 0,
|
|
|
|
Tags: []string{"foo"},
|
|
|
|
Meta: map[string]string{"foo": "bar"},
|
|
|
|
Locality: &structs.Locality{
|
|
|
|
Region: "us-east-1",
|
|
|
|
Zone: "us-east-1a",
|
|
|
|
},
|
|
|
|
LocallyRegisteredAsSidecar: true,
|
|
|
|
Proxy: structs.ConnectProxyConfig{
|
|
|
|
DestinationServiceName: "web",
|
|
|
|
DestinationServiceID: "web1",
|
|
|
|
LocalServiceAddress: "127.0.0.1",
|
|
|
|
LocalServicePort: 1111,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wantChecks: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "retain locality, tags and meta if explicitly configured",
|
|
|
|
sd: &structs.ServiceDefinition{
|
|
|
|
ID: "web1",
|
|
|
|
Name: "web",
|
|
|
|
Port: 1111,
|
|
|
|
Tags: []string{"foo"},
|
|
|
|
Meta: map[string]string{"foo": "bar"},
|
|
|
|
Locality: &structs.Locality{
|
|
|
|
Region: "us-east-1",
|
|
|
|
Zone: "us-east-1a",
|
|
|
|
},
|
|
|
|
Connect: &structs.ServiceConnect{
|
|
|
|
SidecarService: &structs.ServiceDefinition{
|
|
|
|
Tags: []string{"bar"},
|
|
|
|
Meta: map[string]string{"baz": "qux"},
|
|
|
|
Locality: &structs.Locality{
|
|
|
|
Region: "us-east-2",
|
|
|
|
Zone: "us-east-2a",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
wantNS: &structs.NodeService{
|
|
|
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
|
|
|
Kind: structs.ServiceKindConnectProxy,
|
|
|
|
ID: "web1-sidecar-proxy",
|
|
|
|
Service: "web-sidecar-proxy",
|
|
|
|
Port: 0,
|
|
|
|
Tags: []string{"bar"},
|
|
|
|
Meta: map[string]string{"baz": "qux"},
|
|
|
|
Locality: &structs.Locality{
|
|
|
|
Region: "us-east-2",
|
|
|
|
Zone: "us-east-2a",
|
|
|
|
},
|
Improve Connect with Prepared Queries (#5291)
Given a query like:
```
{
"Name": "tagged-connect-query",
"Service": {
"Service": "foo",
"Tags": ["tag"],
"Connect": true
}
}
```
And a Consul configuration like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {} },
"tags": ["tag"]
]
}
```
If you executed the query it would always turn up with 0 results. This was because the sidecar service was being created without any tags. You could instead make your config look like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {
"tags": ["tag"]
} },
"tags": ["tag"]
]
}
```
However that is a bit redundant for most cases. This PR ensures that the tags and service meta of the parent service get copied to the sidecar service. If there are any tags or service meta set in the sidecar service definition then this copying does not take place. After the changes, the query will now return the expected results.
A second change was made to prepared queries in this PR which is to allow filtering on ServiceMeta just like we allow for filtering on NodeMeta.
2019-02-04 14:36:51 +00:00
|
|
|
LocallyRegisteredAsSidecar: true,
|
|
|
|
Proxy: structs.ConnectProxyConfig{
|
|
|
|
DestinationServiceName: "web",
|
|
|
|
DestinationServiceID: "web1",
|
|
|
|
LocalServiceAddress: "127.0.0.1",
|
|
|
|
LocalServicePort: 1111,
|
|
|
|
},
|
|
|
|
},
|
2022-09-07 00:35:31 +00:00
|
|
|
wantChecks: nil,
|
Improve Connect with Prepared Queries (#5291)
Given a query like:
```
{
"Name": "tagged-connect-query",
"Service": {
"Service": "foo",
"Tags": ["tag"],
"Connect": true
}
}
```
And a Consul configuration like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {} },
"tags": ["tag"]
]
}
```
If you executed the query it would always turn up with 0 results. This was because the sidecar service was being created without any tags. You could instead make your config look like:
```
{
"services": [
"name": "foo",
"port": 8080,
"connect": { "sidecar_service": {
"tags": ["tag"]
} },
"tags": ["tag"]
]
}
```
However that is a bit redundant for most cases. This PR ensures that the tags and service meta of the parent service get copied to the sidecar service. If there are any tags or service meta set in the sidecar service definition then this copying does not take place. After the changes, the query will now return the expected results.
A second change was made to prepared queries in this PR which is to allow filtering on ServiceMeta just like we allow for filtering on NodeMeta.
2019-02-04 14:36:51 +00:00
|
|
|
},
|
2018-09-27 13:33:12 +00:00
|
|
|
{
|
|
|
|
name: "invalid check type",
|
|
|
|
sd: &structs.ServiceDefinition{
|
|
|
|
ID: "web1",
|
|
|
|
Name: "web",
|
|
|
|
Port: 1111,
|
|
|
|
Connect: &structs.ServiceConnect{
|
|
|
|
SidecarService: &structs.ServiceDefinition{
|
|
|
|
Check: structs.CheckType{
|
|
|
|
TCP: "foo",
|
|
|
|
// Invalid since no interval specified
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
token: "foo",
|
|
|
|
wantErr: "Interval must be > 0",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "invalid meta",
|
|
|
|
sd: &structs.ServiceDefinition{
|
|
|
|
ID: "web1",
|
|
|
|
Name: "web",
|
|
|
|
Port: 1111,
|
|
|
|
Connect: &structs.ServiceConnect{
|
|
|
|
SidecarService: &structs.ServiceDefinition{
|
|
|
|
Meta: map[string]string{
|
|
|
|
"consul-reserved-key-should-be-rejected": "true",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
token: "foo",
|
|
|
|
wantErr: "reserved for internal use",
|
|
|
|
},
|
2022-07-27 18:19:17 +00:00
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
ns := tt.sd.NodeService()
|
|
|
|
err := ns.Validate()
|
|
|
|
require.NoError(t, err, "Invalid test case - NodeService must validate")
|
|
|
|
|
2022-09-07 00:35:31 +00:00
|
|
|
gotNS, gotChecks, gotToken, err := sidecarServiceFromNodeService(ns, tt.token)
|
2022-07-27 18:19:17 +00:00
|
|
|
if tt.wantErr != "" {
|
|
|
|
require.Error(t, err)
|
|
|
|
require.Contains(t, err.Error(), tt.wantErr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, tt.wantNS, gotNS)
|
|
|
|
require.Equal(t, tt.wantChecks, gotChecks)
|
|
|
|
require.Equal(t, tt.wantToken, gotToken)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-03 01:50:40 +00:00
|
|
|
func TestAgent_SidecarPortFromServiceID(t *testing.T) {
|
2022-07-27 18:19:17 +00:00
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("too slow for testing.Short")
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
autoPortsDisabled bool
|
|
|
|
enterpriseMeta acl.EnterpriseMeta
|
|
|
|
maxPort int
|
|
|
|
port int
|
2022-11-04 14:29:16 +00:00
|
|
|
preRegister []*structs.ServiceDefinition
|
2022-07-27 18:19:17 +00:00
|
|
|
serviceID string
|
|
|
|
wantPort int
|
|
|
|
wantErr string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "use auto ports",
|
|
|
|
serviceID: "web1",
|
2022-08-03 01:50:40 +00:00
|
|
|
wantPort: 2222,
|
2022-07-27 18:19:17 +00:00
|
|
|
},
|
2018-09-27 14:00:51 +00:00
|
|
|
{
|
|
|
|
name: "re-registering same sidecar with no port should pick same one",
|
|
|
|
// Allow multiple ports to be sure we get the right one
|
|
|
|
maxPort: 2500,
|
2022-11-04 14:29:16 +00:00
|
|
|
// Pre register the main service and sidecar we want
|
|
|
|
preRegister: []*structs.ServiceDefinition{{
|
|
|
|
Kind: structs.ServiceKindConnectProxy,
|
|
|
|
ID: "web1",
|
|
|
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
|
|
|
Name: "web",
|
|
|
|
Port: 2221,
|
|
|
|
Proxy: &structs.ConnectProxyConfig{
|
|
|
|
DestinationServiceName: "web",
|
|
|
|
DestinationServiceID: "web1",
|
|
|
|
LocalServiceAddress: "127.0.0.1",
|
|
|
|
LocalServicePort: 1110,
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
Kind: structs.ServiceKindConnectProxy,
|
|
|
|
ID: "web1-sidecar-proxy",
|
|
|
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
|
|
|
Name: "web-sidecar-proxy",
|
|
|
|
Port: 2222,
|
2018-09-27 14:00:51 +00:00
|
|
|
Proxy: &structs.ConnectProxyConfig{
|
|
|
|
DestinationServiceName: "web",
|
|
|
|
DestinationServiceID: "web1",
|
|
|
|
LocalServiceAddress: "127.0.0.1",
|
|
|
|
LocalServicePort: 1111,
|
|
|
|
},
|
2022-11-04 14:29:16 +00:00
|
|
|
}},
|
|
|
|
// Register same sidecar again
|
|
|
|
serviceID: "web1-sidecar-proxy",
|
|
|
|
enterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
|
|
|
wantPort: 2222, // Should claim the same port as before
|
2022-07-27 18:19:17 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "all auto ports already taken",
|
2022-11-04 14:29:16 +00:00
|
|
|
// register another service with sidecar consuming our 1 and only allocated auto port.
|
|
|
|
preRegister: []*structs.ServiceDefinition{{
|
|
|
|
Kind: structs.ServiceKindConnectProxy,
|
|
|
|
ID: "api1",
|
|
|
|
EnterpriseMeta: *structs.DefaultEnterpriseMetaInDefaultPartition(),
|
|
|
|
Name: "api",
|
|
|
|
Port: 2221,
|
|
|
|
Proxy: &structs.ConnectProxyConfig{
|
|
|
|
DestinationServiceName: "api",
|
|
|
|
DestinationServiceID: "api1",
|
|
|
|
LocalServiceAddress: "127.0.0.1",
|
|
|
|
LocalServicePort: 1110,
|
|
|
|
},
|
|
|
|
}, {
|
2022-07-27 18:19:17 +00:00
|
|
|
Kind: structs.ServiceKindConnectProxy,
|
|
|
|
Name: "api-proxy-sidecar",
|
|
|
|
Port: 2222, // Consume the one available auto-port
|
|
|
|
Proxy: &structs.ConnectProxyConfig{
|
2022-11-04 14:29:16 +00:00
|
|
|
DestinationServiceID: "api1",
|
2022-07-27 18:19:17 +00:00
|
|
|
DestinationServiceName: "api",
|
2018-09-27 14:00:51 +00:00
|
|
|
},
|
2022-11-04 14:29:16 +00:00
|
|
|
}},
|
2022-07-27 18:19:17 +00:00
|
|
|
wantErr: "none left in the configured range [2222, 2222]",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "auto ports disabled",
|
|
|
|
autoPortsDisabled: true,
|
|
|
|
wantErr: "auto-assignment disabled in config",
|
2018-09-27 14:00:51 +00:00
|
|
|
},
|
2018-09-27 13:33:12 +00:00
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2021-07-26 21:12:29 +00:00
|
|
|
// Set port range to be tiny (one available) to test consuming all of it.
|
2018-09-27 14:00:51 +00:00
|
|
|
// This allows a single assigned port at 2222 thanks to being inclusive at
|
|
|
|
// both ends.
|
|
|
|
if tt.maxPort == 0 {
|
|
|
|
tt.maxPort = 2222
|
|
|
|
}
|
|
|
|
hcl := fmt.Sprintf(`
|
2018-09-27 13:33:12 +00:00
|
|
|
ports {
|
|
|
|
sidecar_min_port = 2222
|
2018-09-27 14:00:51 +00:00
|
|
|
sidecar_max_port = %d
|
2018-09-27 13:33:12 +00:00
|
|
|
}
|
2018-09-27 14:00:51 +00:00
|
|
|
`, tt.maxPort)
|
2018-09-27 13:33:12 +00:00
|
|
|
if tt.autoPortsDisabled {
|
|
|
|
hcl = `
|
|
|
|
ports {
|
|
|
|
sidecar_min_port = 0
|
|
|
|
sidecar_max_port = 0
|
|
|
|
}
|
|
|
|
`
|
|
|
|
}
|
2022-09-07 00:35:31 +00:00
|
|
|
a := NewTestAgent(t, hcl)
|
2019-08-26 20:19:59 +00:00
|
|
|
defer a.Shutdown()
|
2018-09-27 13:33:12 +00:00
|
|
|
|
2022-11-04 14:29:16 +00:00
|
|
|
if len(tt.preRegister) > 0 {
|
|
|
|
for _, s := range tt.preRegister {
|
|
|
|
err := a.addServiceFromSource(s.NodeService(), nil, false, "", ConfigSourceLocal)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
2018-09-27 13:33:12 +00:00
|
|
|
}
|
|
|
|
|
2022-09-07 00:35:31 +00:00
|
|
|
gotPort, err := a.sidecarPortFromServiceIDLocked(structs.ServiceID{ID: tt.serviceID, EnterpriseMeta: tt.enterpriseMeta})
|
2018-09-27 13:33:12 +00:00
|
|
|
|
|
|
|
if tt.wantErr != "" {
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
require.Contains(t, err.Error(), tt.wantErr)
|
2018-09-27 13:33:12 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, err)
|
2022-07-27 18:19:17 +00:00
|
|
|
require.Equal(t, tt.wantPort, gotPort)
|
2018-09-27 13:33:12 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2022-09-07 00:35:31 +00:00
|
|
|
|
|
|
|
func TestAgent_SidecarDefaultChecks(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
2022-09-09 14:47:10 +00:00
|
|
|
serviceID string
|
2022-09-07 00:35:31 +00:00
|
|
|
svcAddress string
|
|
|
|
proxyLocalSvcAddress string
|
|
|
|
port int
|
|
|
|
wantChecks []*structs.CheckType
|
|
|
|
}{{
|
|
|
|
name: "uses proxy address for check",
|
2022-09-09 14:47:10 +00:00
|
|
|
serviceID: "web1-1-sidecar-proxy",
|
2022-09-07 00:35:31 +00:00
|
|
|
svcAddress: "123.123.123.123",
|
|
|
|
proxyLocalSvcAddress: "255.255.255.255",
|
|
|
|
port: 2222,
|
|
|
|
wantChecks: []*structs.CheckType{
|
|
|
|
{
|
|
|
|
Name: "Connect Sidecar Listening",
|
|
|
|
TCP: "123.123.123.123:2222",
|
|
|
|
Interval: 10 * time.Second,
|
|
|
|
},
|
|
|
|
{
|
2022-09-09 14:47:10 +00:00
|
|
|
Name: "Connect Sidecar Aliasing web1-1",
|
|
|
|
AliasService: "web1-1",
|
2022-09-07 00:35:31 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "uses proxy.local_service_address for check if proxy address is empty",
|
2022-09-09 14:47:10 +00:00
|
|
|
serviceID: "web1-1-sidecar-proxy",
|
2022-09-07 00:35:31 +00:00
|
|
|
proxyLocalSvcAddress: "1.2.3.4",
|
|
|
|
port: 2222,
|
|
|
|
wantChecks: []*structs.CheckType{
|
|
|
|
{
|
|
|
|
Name: "Connect Sidecar Listening",
|
|
|
|
TCP: "1.2.3.4:2222",
|
|
|
|
Interval: 10 * time.Second,
|
|
|
|
},
|
|
|
|
{
|
2022-09-09 14:47:10 +00:00
|
|
|
Name: "Connect Sidecar Aliasing web1-1",
|
|
|
|
AliasService: "web1-1",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "redundant name",
|
|
|
|
serviceID: "1-sidecar-proxy-web1-sidecar-proxy",
|
|
|
|
svcAddress: "123.123.123.123",
|
|
|
|
proxyLocalSvcAddress: "255.255.255.255",
|
|
|
|
port: 2222,
|
|
|
|
wantChecks: []*structs.CheckType{
|
|
|
|
{
|
|
|
|
Name: "Connect Sidecar Listening",
|
|
|
|
TCP: "123.123.123.123:2222",
|
|
|
|
Interval: 10 * time.Second,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Connect Sidecar Aliasing 1-sidecar-proxy-web1",
|
|
|
|
AliasService: "1-sidecar-proxy-web1",
|
2022-09-07 00:35:31 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2022-09-09 14:47:10 +00:00
|
|
|
gotChecks := sidecarDefaultChecks(tt.serviceID, tt.svcAddress, tt.proxyLocalSvcAddress, tt.port)
|
2022-09-07 00:35:31 +00:00
|
|
|
require.Equal(t, tt.wantChecks, gotChecks)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|