mirror of https://github.com/hashicorp/consul
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2283 lines
60 KiB
2283 lines
60 KiB
9 months ago
|
// Copyright (c) HashiCorp, Inc.
|
||
|
// SPDX-License-Identifier: BUSL-1.1
|
||
|
|
||
|
package topology
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
"github.com/google/go-cmp/cmp"
|
||
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
"google.golang.org/protobuf/testing/protocmp"
|
||
|
|
||
|
"github.com/hashicorp/go-hclog"
|
||
|
|
||
|
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||
|
"github.com/hashicorp/consul/sdk/testutil"
|
||
|
)
|
||
|
|
||
|
func TestCompile_CE(t *testing.T) {
|
||
|
type testcase struct {
|
||
|
in *Config
|
||
|
expect *Topology
|
||
|
expectErr string
|
||
|
}
|
||
|
|
||
|
logger := hclog.NewNullLogger()
|
||
|
|
||
|
const clusterID = "87c82bd03dc89d4d"
|
||
|
|
||
|
run := func(t *testing.T, tc testcase) {
|
||
|
got, err := compile(logger, tc.in, nil, clusterID)
|
||
|
if tc.expectErr == "" {
|
||
|
require.NotNil(t, tc.expect, "field must be set")
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
// Set recursive pointers on expectations.
|
||
|
for _, c := range tc.expect.Clusters {
|
||
|
for _, n := range c.Nodes {
|
||
|
for _, w := range n.Workloads {
|
||
|
w.Node = n
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
assertDeepEqual(t, tc.expect, got)
|
||
|
} else {
|
||
|
require.Nil(t, tc.expect, "field cannot be set")
|
||
|
require.Nil(t, got)
|
||
|
testutil.RequireErrorContains(t, err, tc.expectErr)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cases := map[string]testcase{
|
||
|
"nil": {
|
||
|
in: nil,
|
||
|
expectErr: `config is required`,
|
||
|
},
|
||
|
"consul image cannot be set at the top level": {
|
||
|
in: &Config{
|
||
|
Images: DefaultImages().ChooseConsul(true),
|
||
|
},
|
||
|
expectErr: `topology.images.consul cannot be set at this level`,
|
||
|
},
|
||
|
"no networks": {
|
||
|
in: &Config{},
|
||
|
expectErr: `topology.networks is empty`,
|
||
|
},
|
||
|
"bad network/no name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{{
|
||
|
//
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `network name is not valid`,
|
||
|
},
|
||
|
"bad network/invalid name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{{
|
||
|
Name: "-123",
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `network name is not valid`,
|
||
|
},
|
||
|
"bad network/should not use DockerName": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{{
|
||
|
Name: "foo",
|
||
|
DockerName: "blah",
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `network "foo" should not specify DockerName`,
|
||
|
},
|
||
|
"bad network/duplicate names": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
},
|
||
|
expectErr: `cannot have two networks with the same name "foo"`,
|
||
|
},
|
||
|
"bad network/unknown type": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo", Type: "ext"},
|
||
|
},
|
||
|
},
|
||
|
expectErr: `network "foo" has unknown type "ext"`,
|
||
|
},
|
||
|
"good networks one server node": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo1"},
|
||
|
{Name: "foo2", Type: "lan"},
|
||
|
{Name: "foo3", Type: "wan"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo2",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "node1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo2"},
|
||
|
{Network: "foo3"},
|
||
|
},
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expect: &Topology{
|
||
|
ID: clusterID,
|
||
|
Images: DefaultImages(),
|
||
|
Networks: map[string]*Network{
|
||
|
"foo1": {Name: "foo1", Type: "lan", DockerName: "cslc-foo1-" + clusterID},
|
||
|
"foo2": {Name: "foo2", Type: "lan", DockerName: "cslc-foo2-" + clusterID},
|
||
|
"foo3": {Name: "foo3", Type: "wan", DockerName: "cslc-foo3-" + clusterID},
|
||
|
},
|
||
|
Clusters: map[string]*Cluster{
|
||
|
"foo2": {
|
||
|
Name: "foo2",
|
||
|
NetworkName: "foo2",
|
||
|
Datacenter: "foo2",
|
||
|
Images: DefaultImages().ChooseConsul(false),
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Version: NodeVersionV1,
|
||
|
Partition: "default",
|
||
|
Name: "node1",
|
||
|
Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo2", Type: "lan", DockerNetworkName: "cslc-foo2-" + clusterID},
|
||
|
{Network: "foo3", Type: "wan", DockerNetworkName: "cslc-foo3-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo2",
|
||
|
Datacenter: "foo2",
|
||
|
}},
|
||
|
Services: map[ID]*pbcatalog.Service{},
|
||
|
Partitions: []*Partition{{
|
||
|
Name: "default",
|
||
|
Namespaces: []string{"default"},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"no clusters": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo1"},
|
||
|
},
|
||
|
},
|
||
|
expectErr: `topology.clusters is empty`,
|
||
|
},
|
||
|
"bad cluster/no name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo1"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{}},
|
||
|
},
|
||
|
expectErr: `error building cluster "": cluster has no name`,
|
||
|
},
|
||
|
"bad cluster/invalid name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo1"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "-123",
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "-123": cluster name is not valid: -123`,
|
||
|
},
|
||
|
"bad cluster/invalid dc": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo1"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Datacenter: "-123",
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": datacenter name is not valid: -123`,
|
||
|
},
|
||
|
"bad cluster/missing network": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo1"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
NetworkName: "bar",
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": cluster "foo" uses network name "bar" that does not exist`,
|
||
|
},
|
||
|
"bad cluster/no nodes": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": cluster "foo" has no nodes`,
|
||
|
},
|
||
|
"colliding clusters": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{
|
||
|
{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "node1",
|
||
|
}},
|
||
|
},
|
||
|
{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "node1",
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
expectErr: `cannot have two clusters with the same name "foo"; use unique names and override the Datacenter field if that's what you want`,
|
||
|
},
|
||
|
// TODO: ERR: partitions in CE
|
||
|
// TODO: ERR: namespaces in CE
|
||
|
// TODO: ERR: servers in a non-default partition
|
||
|
"tenancy collection": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Enterprise: true,
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindClient,
|
||
|
Name: "mesh1",
|
||
|
Partition: "ap1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
Workloads: []*Workload{
|
||
|
{
|
||
|
ID: NewID("zim", "ns1", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8888,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
},
|
||
|
{
|
||
|
ID: NewID("gir", "ns2", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8877,
|
||
|
EnvoyAdminPort: 19001,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("gaz", "ns3", "ap3"),
|
||
|
LocalAddress: "127.0.0.1",
|
||
|
LocalPort: 5000,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh2",
|
||
|
Partition: "ap2",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
Workloads: []*Workload{
|
||
|
{
|
||
|
ID: NewID("gir", "ns4", "ap2"),
|
||
|
Image: "busybox",
|
||
|
Port: 8877,
|
||
|
EnvoyAdminPort: 19001,
|
||
|
ImpliedDestinations: []*Destination{{
|
||
|
ID: NewID("gaz", "", "ap4"),
|
||
|
PortName: "www",
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expect: &Topology{
|
||
|
ID: clusterID,
|
||
|
Images: DefaultImages(),
|
||
|
Networks: map[string]*Network{
|
||
|
"foo": {Name: "foo", Type: "lan", DockerName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Clusters: map[string]*Cluster{
|
||
|
"foo": {
|
||
|
Name: "foo",
|
||
|
NetworkName: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Enterprise: true,
|
||
|
EnableV2: true,
|
||
|
Images: DefaultImages().ChooseConsul(true),
|
||
|
Services: map[ID]*pbcatalog.Service{
|
||
|
NewID("gir", "ns4", "ap2"): {
|
||
|
Workloads: &pbcatalog.WorkloadSelector{
|
||
|
Names: []string{"gir-mesh2"},
|
||
|
},
|
||
|
Ports: []*pbcatalog.ServicePort{
|
||
|
{TargetPort: "legacy", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||
|
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||
|
},
|
||
|
VirtualIps: []string{"10.244.0.2"},
|
||
|
},
|
||
|
},
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Version: NodeVersionV1,
|
||
|
Name: "server1",
|
||
|
Partition: "default",
|
||
|
Images: DefaultImages().ChooseConsul(true).ChooseNode(NodeKindServer),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindClient,
|
||
|
Version: NodeVersionV1,
|
||
|
Name: "mesh1",
|
||
|
Partition: "ap1",
|
||
|
Images: DefaultImages().ChooseConsul(true).ChooseNode(NodeKindClient),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Index: 1,
|
||
|
Workloads: []*Workload{
|
||
|
{
|
||
|
ID: NewID("zim", "ns1", "ap1"),
|
||
|
Image: "busybox",
|
||
|
Port: 8888,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
NodeVersion: NodeVersionV1,
|
||
|
},
|
||
|
{
|
||
|
ID: NewID("gir", "ns2", "ap1"),
|
||
|
Image: "busybox",
|
||
|
Port: 8877,
|
||
|
EnvoyAdminPort: 19001,
|
||
|
NodeVersion: NodeVersionV1,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("gaz", "ns3", "ap3"),
|
||
|
Cluster: "foo",
|
||
|
LocalAddress: "127.0.0.1",
|
||
|
LocalPort: 5000,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh2",
|
||
|
Partition: "ap2",
|
||
|
Images: DefaultImages().ChooseConsul(true).ChooseNode(NodeKindDataplane),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Index: 2,
|
||
|
Workloads: []*Workload{
|
||
|
{
|
||
|
ID: NewID("gir", "ns4", "ap2"),
|
||
|
Image: "busybox",
|
||
|
Ports: map[string]*Port{
|
||
|
"legacy": {Number: 8877, Protocol: "tcp", ActualProtocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||
|
"mesh": {Number: 20000, Protocol: "mesh", ActualProtocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||
|
},
|
||
|
EnvoyAdminPort: 19001,
|
||
|
EnvoyPublicListenerPort: 20000,
|
||
|
NodeVersion: NodeVersionV2,
|
||
|
V2Services: []string{"gir"},
|
||
|
WorkloadIdentity: "gir",
|
||
|
Workload: "gir-mesh2",
|
||
|
ImpliedDestinations: []*Destination{{
|
||
|
ID: NewID("gaz", "default", "ap4"),
|
||
|
Cluster: "foo", // TODO: why is this only sometimes populated?
|
||
|
PortName: "www",
|
||
|
Implied: true,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
Partitions: []*Partition{
|
||
|
{
|
||
|
Name: "ap1",
|
||
|
Namespaces: []string{"default", "ns1", "ns2"},
|
||
|
},
|
||
|
{
|
||
|
Name: "ap2",
|
||
|
Namespaces: []string{"default", "ns4"},
|
||
|
},
|
||
|
{
|
||
|
Name: "ap3",
|
||
|
Namespaces: []string{"default", "ns3"},
|
||
|
},
|
||
|
{
|
||
|
Name: "ap4",
|
||
|
Namespaces: []string{"default"},
|
||
|
},
|
||
|
{
|
||
|
Name: "default",
|
||
|
Namespaces: []string{"default"},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"explicit v2 services": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "node1",
|
||
|
}},
|
||
|
Services: map[ID]*pbcatalog.Service{
|
||
|
NewID("zim", "default", "default"): {
|
||
|
Ports: []*pbcatalog.ServicePort{
|
||
|
{TargetPort: "http"},
|
||
|
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expect: &Topology{
|
||
|
ID: clusterID,
|
||
|
Images: DefaultImages(),
|
||
|
Networks: map[string]*Network{
|
||
|
"foo": {Name: "foo", Type: "lan", DockerName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Clusters: map[string]*Cluster{
|
||
|
"foo": {
|
||
|
Name: "foo",
|
||
|
NetworkName: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Images: DefaultImages().ChooseConsul(false),
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Version: NodeVersionV1,
|
||
|
Partition: "default",
|
||
|
Name: "node1",
|
||
|
Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
}},
|
||
|
EnableV2: true,
|
||
|
Services: map[ID]*pbcatalog.Service{
|
||
|
NewID("zim", "default", "default"): {
|
||
|
Ports: []*pbcatalog.ServicePort{
|
||
|
{TargetPort: "http", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||
|
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||
|
},
|
||
|
VirtualIps: []string{"10.244.0.2"},
|
||
|
},
|
||
|
},
|
||
|
Partitions: []*Partition{{
|
||
|
Name: "default",
|
||
|
Namespaces: []string{"default"},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"explicit v2 services/bad workload selector": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "node1",
|
||
|
}},
|
||
|
Services: map[ID]*pbcatalog.Service{
|
||
|
NewID("zim", "default", "default"): {
|
||
|
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"zzz"}},
|
||
|
Ports: []*pbcatalog.ServicePort{
|
||
|
{TargetPort: "http"},
|
||
|
{TargetPort: "mesh"},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": the workloads field for v2 service "default/default/zim" is not user settable`,
|
||
|
},
|
||
|
"tls volume errantly set": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "node1",
|
||
|
}},
|
||
|
TLSVolumeName: "foo",
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": user cannot specify the TLSVolumeName field`,
|
||
|
},
|
||
|
"node/no name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "": cluster "foo" node has no name`,
|
||
|
},
|
||
|
"node/invalid name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "-123",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "-123": node name is not valid: -123`,
|
||
|
},
|
||
|
"node/bad kind": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Name: "zim",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": cluster "foo" node "zim" has invalid kind`,
|
||
|
},
|
||
|
"node/bad version": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Version: "v3",
|
||
|
Name: "zim",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": cluster "foo" node "zim" has invalid version: v3`,
|
||
|
},
|
||
|
"node/bad version for client": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindClient,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "zim",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": v2 does not support client agents at this time`,
|
||
|
},
|
||
|
"node/invalid partition": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "zim",
|
||
|
Partition: "-123",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": node partition is not valid: -123`,
|
||
|
},
|
||
|
"node/invalid usedPorts": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "zim",
|
||
|
usedPorts: map[int]int{5: 6},
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": user cannot specify the usedPorts field`,
|
||
|
},
|
||
|
"node/invalid index": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "zim",
|
||
|
Index: 99,
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": user cannot specify the node index`,
|
||
|
},
|
||
|
"node/missing address network": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "zim",
|
||
|
Addresses: []*Address{{
|
||
|
//
|
||
|
}},
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": cluster "foo" node "zim" has invalid address`,
|
||
|
},
|
||
|
"node/invalid address type": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "zim",
|
||
|
Addresses: []*Address{{
|
||
|
Network: "foo",
|
||
|
Type: "lan",
|
||
|
}},
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": user cannot specify the address type directly`,
|
||
|
},
|
||
|
"node/address network does not exist": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "zim",
|
||
|
Addresses: []*Address{{
|
||
|
Network: "bar",
|
||
|
}},
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": cluster "foo" node "zim" uses network name "bar" that does not exist`,
|
||
|
},
|
||
|
"node/no local addresses": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
{Name: "bar", Type: "wan"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "zim",
|
||
|
Addresses: []*Address{{
|
||
|
Network: "bar",
|
||
|
}},
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": cluster "foo" node "zim" has no local addresses`,
|
||
|
},
|
||
|
"node/too many public addresses": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
{Name: "bar", Type: "wan"},
|
||
|
{Name: "baz", Type: "wan"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "zim",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
{Network: "bar"},
|
||
|
{Network: "baz"},
|
||
|
},
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "zim": cluster "foo" node "zim" has more than one public address`,
|
||
|
},
|
||
|
"node/dataplane with more than one workload": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
Workloads: []*Workload{
|
||
|
{ID: NewID("zim", "default", "default")},
|
||
|
{ID: NewID("gir", "default", "default")},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" uses dataplane, but has more than one service`,
|
||
|
},
|
||
|
"workload/invalid partition": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: ID{
|
||
|
Name: "zim",
|
||
|
Namespace: "default",
|
||
|
Partition: "-123",
|
||
|
},
|
||
|
Image: "busybox",
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": service partition is not valid: -123`,
|
||
|
},
|
||
|
"workload/invalid namespace": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: ID{
|
||
|
Name: "zim",
|
||
|
Namespace: "-123",
|
||
|
Partition: "default",
|
||
|
},
|
||
|
Image: "busybox",
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": service namespace is not valid: -123`,
|
||
|
},
|
||
|
"workload/invalid name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: ID{
|
||
|
Name: "-123",
|
||
|
Namespace: "default",
|
||
|
Partition: "default",
|
||
|
},
|
||
|
Image: "busybox",
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": service name is not valid: -123`,
|
||
|
},
|
||
|
"workload/mismatched partitions": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: ID{
|
||
|
Name: "zim",
|
||
|
Namespace: "default",
|
||
|
Partition: "ap1",
|
||
|
},
|
||
|
Image: "busybox",
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": service zim on node mesh1 has mismatched partitions: ap1 != default`,
|
||
|
},
|
||
|
"workload/node collision": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindClient,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{
|
||
|
{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
},
|
||
|
{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 9090,
|
||
|
EnvoyAdminPort: 19001,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cannot have two services on the same node "default/mesh1" in the same cluster "foo" with the same name "default/default/zim"`,
|
||
|
},
|
||
|
"workload/v1 and implied dest": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindClient,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
ImpliedDestinations: []*Destination{{
|
||
|
ID: NewID("gir", "", ""),
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": v1 does not support implied destinations yet`,
|
||
|
},
|
||
|
"workload/default-destination/impl dest need port names in v2": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
ImpliedDestinations: []*Destination{{
|
||
|
ID: NewID("gir", "", ""),
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": implicit destinations must use port names in v2`,
|
||
|
},
|
||
|
"workload/default-destination/expl dest port name legacy defaulting": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8888,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("gir", "", ""),
|
||
|
LocalAddress: "127.0.0.1",
|
||
|
LocalPort: 5000,
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expect: &Topology{
|
||
|
ID: clusterID,
|
||
|
Images: DefaultImages(),
|
||
|
Networks: map[string]*Network{
|
||
|
"foo": {Name: "foo", Type: "lan", DockerName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Clusters: map[string]*Cluster{
|
||
|
"foo": {
|
||
|
Name: "foo",
|
||
|
NetworkName: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Images: DefaultImages().ChooseConsul(false),
|
||
|
EnableV2: true,
|
||
|
Services: map[ID]*pbcatalog.Service{
|
||
|
NewID("zim", "default", "default"): {
|
||
|
Workloads: &pbcatalog.WorkloadSelector{
|
||
|
Names: []string{"zim-mesh1"},
|
||
|
},
|
||
|
Ports: []*pbcatalog.ServicePort{
|
||
|
{TargetPort: "legacy", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||
|
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||
|
},
|
||
|
VirtualIps: []string{"10.244.0.2"},
|
||
|
},
|
||
|
},
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Version: NodeVersionV1,
|
||
|
Partition: "default",
|
||
|
Name: "server1",
|
||
|
Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Partition: "default",
|
||
|
Name: "mesh1",
|
||
|
Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindDataplane),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Index: 1,
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Ports: map[string]*Port{
|
||
|
"legacy": {Number: 8888, Protocol: "tcp", ActualProtocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||
|
"mesh": {Number: 20000, Protocol: "mesh", ActualProtocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||
|
},
|
||
|
EnvoyAdminPort: 19000,
|
||
|
EnvoyPublicListenerPort: 20000,
|
||
|
NodeVersion: NodeVersionV2,
|
||
|
V2Services: []string{"zim"},
|
||
|
WorkloadIdentity: "zim",
|
||
|
Workload: "zim-mesh1",
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("gir", "", ""),
|
||
|
LocalAddress: "127.0.0.1",
|
||
|
LocalPort: 5000,
|
||
|
Cluster: "foo",
|
||
|
PortName: "legacy", // <--- this
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
Partitions: []*Partition{{
|
||
|
Name: "default",
|
||
|
Namespaces: []string{"default"},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"workload/default-destination/expl dest local address defaulting": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV1,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("gir", "", ""),
|
||
|
LocalPort: 5000,
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expect: &Topology{
|
||
|
ID: clusterID,
|
||
|
Images: DefaultImages(),
|
||
|
Networks: map[string]*Network{
|
||
|
"foo": {Name: "foo", Type: "lan", DockerName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Clusters: map[string]*Cluster{
|
||
|
"foo": {
|
||
|
Name: "foo",
|
||
|
NetworkName: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Images: DefaultImages().ChooseConsul(false),
|
||
|
Services: map[ID]*pbcatalog.Service{
|
||
|
//
|
||
|
},
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Version: NodeVersionV1,
|
||
|
Partition: "default",
|
||
|
Name: "server1",
|
||
|
Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV1,
|
||
|
Partition: "default",
|
||
|
Name: "mesh1",
|
||
|
Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindDataplane),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Index: 1,
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
EnvoyPublicListenerPort: 20000,
|
||
|
NodeVersion: NodeVersionV1,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("gir", "", ""),
|
||
|
LocalAddress: "127.0.0.1", // <--- this
|
||
|
LocalPort: 5000,
|
||
|
Cluster: "foo",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
Partitions: []*Partition{{
|
||
|
Name: "default",
|
||
|
Namespaces: []string{"default"},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"workload/default-destination/expl dest cannot use port names in v1": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV1,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("gir", "", ""),
|
||
|
PortName: "http",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": explicit destinations cannot use port names in v1`,
|
||
|
},
|
||
|
"workload/validate/no name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindClient,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": service name is not valid`,
|
||
|
},
|
||
|
"workload/validate/no image": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindClient,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: service image is required`,
|
||
|
},
|
||
|
"workload/validate/no image mesh gateway": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindClient,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
IsMeshGateway: true,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expect: &Topology{
|
||
|
ID: clusterID,
|
||
|
Images: DefaultImages(),
|
||
|
Networks: map[string]*Network{
|
||
|
"foo": {Name: "foo", Type: "lan", DockerName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Clusters: map[string]*Cluster{
|
||
|
"foo": {
|
||
|
Name: "foo",
|
||
|
NetworkName: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Images: DefaultImages().ChooseConsul(false),
|
||
|
Services: map[ID]*pbcatalog.Service{
|
||
|
//
|
||
|
},
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Version: NodeVersionV1,
|
||
|
Partition: "default",
|
||
|
Name: "server1",
|
||
|
Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindClient,
|
||
|
Version: NodeVersionV1,
|
||
|
Partition: "default",
|
||
|
Name: "mesh1",
|
||
|
Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindClient),
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID},
|
||
|
},
|
||
|
Cluster: "foo",
|
||
|
Datacenter: "foo",
|
||
|
Index: 1,
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
IsMeshGateway: true,
|
||
|
NodeVersion: NodeVersionV1,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
Partitions: []*Partition{{
|
||
|
Name: "default",
|
||
|
Namespaces: []string{"default"},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
"workload/validate/single and multiport v2": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Version: NodeVersionV2,
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8080,
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Ports: map[string]*Port{
|
||
|
"blah": {
|
||
|
Number: 8181,
|
||
|
Protocol: "tcp",
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot specify both singleport and multiport on service in v2`,
|
||
|
},
|
||
|
"workload/validate/multiport nil port": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Version: NodeVersionV2,
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Ports: map[string]*Port{
|
||
|
"blah": nil,
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot be nil`,
|
||
|
},
|
||
|
"workload/validate/multiport negative port": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Version: NodeVersionV2,
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Ports: map[string]*Port{
|
||
|
"blah": {
|
||
|
Number: -5,
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: service has invalid port number`,
|
||
|
},
|
||
|
"workload/validate/multiport set actualprotocol": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Version: NodeVersionV2,
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Ports: map[string]*Port{
|
||
|
"blah": {
|
||
|
Number: 8888,
|
||
|
ActualProtocol: pbcatalog.Protocol_PROTOCOL_GRPC,
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: user cannot specify ActualProtocol field`,
|
||
|
},
|
||
|
"workload/validate/multiport invalid port protocol": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Version: NodeVersionV2,
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Ports: map[string]*Port{
|
||
|
"blah": {
|
||
|
Number: 8888,
|
||
|
Protocol: "zzzz",
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: service has invalid port protocol "zzzz"`,
|
||
|
},
|
||
|
"workload/validate/singleport invalid port": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Port: -999,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: service has invalid port`,
|
||
|
},
|
||
|
"workload/validate/singleport tproxy": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Port: 999,
|
||
|
EnableTransparentProxy: true,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: tproxy does not work with v1 yet`,
|
||
|
},
|
||
|
"workload/validate/mesh with no admin port": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 999,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: envoy admin port is required`,
|
||
|
},
|
||
|
"workload/validate/no mesh with admin port": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
EnvoyAdminPort: 19000,
|
||
|
DisableServiceMesh: true,
|
||
|
Image: "busybox",
|
||
|
Port: 999,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot use envoy admin port without a service mesh`,
|
||
|
},
|
||
|
"workload/validate/expl dest with no name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Image: "busybox",
|
||
|
Port: 999,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("", "", ""),
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: destination service name is required`,
|
||
|
},
|
||
|
"workload/validate/expl dest with no local port": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Image: "busybox",
|
||
|
Port: 999,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("dib", "", ""),
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: destination local port is required`,
|
||
|
},
|
||
|
"workload/validate/expl dest bad local address": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Image: "busybox",
|
||
|
Port: 999,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("dib", "", ""),
|
||
|
LocalPort: 5000,
|
||
|
LocalAddress: "clown@address",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: destination local address is invalid: clown@address`,
|
||
|
},
|
||
|
"workload/validate/expl dest with implied": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Image: "busybox",
|
||
|
Port: 999,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("dib", "", ""),
|
||
|
LocalPort: 5000,
|
||
|
PortName: "http",
|
||
|
Implied: true,
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: implied field cannot be set`,
|
||
|
},
|
||
|
"workload/validate/impl dest with no name": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Image: "busybox",
|
||
|
Port: 999,
|
||
|
ImpliedDestinations: []*Destination{{
|
||
|
ID: NewID("", "", ""),
|
||
|
PortName: "http",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: implied destination service name is required`,
|
||
|
},
|
||
|
"workload/validate/impl dest with local port": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Image: "busybox",
|
||
|
Port: 999,
|
||
|
ImpliedDestinations: []*Destination{{
|
||
|
ID: NewID("dib", "", ""),
|
||
|
PortName: "http",
|
||
|
LocalPort: 5000,
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: implied destination local port cannot be set`,
|
||
|
},
|
||
|
"workload/validate/impl dest with local address": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Image: "busybox",
|
||
|
Port: 999,
|
||
|
ImpliedDestinations: []*Destination{{
|
||
|
ID: NewID("dib", "", ""),
|
||
|
PortName: "http",
|
||
|
LocalAddress: "127.0.0.1",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: implied destination local address cannot be set`,
|
||
|
},
|
||
|
"workload/validate/v1 cannot use multiport": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Ports: map[string]*Port{"web": {Number: 8080}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot specify multiport on service in v1`,
|
||
|
},
|
||
|
"workload/validate/disable-mesh/mgw": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
IsMeshGateway: true,
|
||
|
Port: 8443,
|
||
|
DisableServiceMesh: true,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot disable service mesh and still run a mesh gateway`,
|
||
|
},
|
||
|
"workload/validate/disable-mesh/expl dest": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Port: 8443,
|
||
|
DisableServiceMesh: true,
|
||
|
Destinations: []*Destination{{
|
||
|
ID: NewID("gir", "", ""),
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot disable service mesh and configure destinations`,
|
||
|
},
|
||
|
"workload/validate/disable-mesh/impl dest": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Port: 8443,
|
||
|
DisableServiceMesh: true,
|
||
|
ImpliedDestinations: []*Destination{{
|
||
|
ID: NewID("gir", "", ""),
|
||
|
PortName: "web",
|
||
|
}},
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot disable service mesh and configure implied destinations`,
|
||
|
},
|
||
|
"workload/validate/disable-mesh/tproxy": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Port: 8443,
|
||
|
DisableServiceMesh: true,
|
||
|
EnableTransparentProxy: true,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot disable service mesh and activate tproxy`,
|
||
|
},
|
||
|
"workload/validate/disable-mesh/set admin port": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
EnvoyAdminPort: 19000,
|
||
|
Port: 8443,
|
||
|
DisableServiceMesh: true,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot use envoy admin port without a service mesh`,
|
||
|
},
|
||
|
"workload/validate/enable-mesh/unset admin port": {
|
||
|
in: &Config{
|
||
|
Networks: []*Network{
|
||
|
{Name: "foo"},
|
||
|
},
|
||
|
Clusters: []*Cluster{{
|
||
|
Name: "foo",
|
||
|
Nodes: []*Node{
|
||
|
{
|
||
|
Kind: NodeKindServer,
|
||
|
Name: "server1",
|
||
|
Addresses: []*Address{
|
||
|
{Network: "foo"},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Kind: NodeKindDataplane,
|
||
|
Version: NodeVersionV2,
|
||
|
Name: "mesh1",
|
||
|
Addresses: []*Address{{Network: "foo"}},
|
||
|
Workloads: []*Workload{{
|
||
|
ID: NewID("zim", "", ""),
|
||
|
Image: "busybox",
|
||
|
Port: 8443,
|
||
|
}},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
},
|
||
|
expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: envoy admin port is required`,
|
||
|
},
|
||
|
|
||
|
// TODO: OK: v2 mesh gateway port defaulting
|
||
|
|
||
|
// TODO: collect tenancies from all places (cluster, initialconfigs, initialres, nodes, services, ...)
|
||
|
}
|
||
|
|
||
|
for name, tc := range cases {
|
||
|
t.Run(name, func(t *testing.T) {
|
||
|
run(t, tc)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type testingT interface {
|
||
|
Helper()
|
||
|
Fatalf(format string, args ...interface{})
|
||
|
require.TestingT
|
||
|
}
|
||
|
|
||
|
var ignoreUnexportedTypes = []any{
|
||
|
Cluster{},
|
||
|
Images{},
|
||
|
Node{},
|
||
|
Workload{},
|
||
|
}
|
||
|
|
||
|
func assertDeepEqual[V any](t testingT, exp, got V, msgAndArgs ...any) {
|
||
|
t.Helper()
|
||
|
|
||
|
if diff := cmp.Diff(exp, got, protocmp.Transform(), cmpopts.IgnoreUnexported(ignoreUnexportedTypes...)); diff != "" {
|
||
|
format := "assertion failed: values are not equal\n--- expected\n+++ actual\n%v"
|
||
|
args := []any{diff}
|
||
|
|
||
|
if len(msgAndArgs) > 0 {
|
||
|
suffix, ok := msgAndArgs[0].(string)
|
||
|
require.True(t, ok)
|
||
|
require.NotEmpty(t, suffix)
|
||
|
format += "\n\nMessage: " + suffix
|
||
|
args = append(args, msgAndArgs[1:]...)
|
||
|
}
|
||
|
t.Fatalf(format, args...)
|
||
|
}
|
||
|
}
|