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.
316 lines
8.4 KiB
316 lines
8.4 KiB
// Copyright (c) HashiCorp, Inc. |
|
// SPDX-License-Identifier: BUSL-1.1 |
|
|
|
package catalogv2 |
|
|
|
import ( |
|
"fmt" |
|
"testing" |
|
|
|
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" |
|
"github.com/hashicorp/consul/proto-public/pbresource" |
|
libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" |
|
"github.com/hashicorp/consul/test/integration/consul-container/libs/utils" |
|
"github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" |
|
"github.com/hashicorp/consul/testing/deployer/topology" |
|
|
|
"github.com/hashicorp/consul/test-integ/topoutil" |
|
) |
|
|
|
// TestBasicL4ExplicitDestinations sets up the following: |
|
// |
|
// - 1 cluster (no peering / no wanfed) |
|
// - 3 servers in that cluster |
|
// - v2 arch is activated |
|
// - for each tenancy, only using v2 constructs: |
|
// - a client with one explicit destination to a single port service |
|
// - a client with multiple explicit destinations to multiple ports of the |
|
// same multiport service |
|
// |
|
// When this test is executed in CE it will only use the default/default |
|
// tenancy. |
|
// |
|
// When this test is executed in Enterprise it will additionally test the same |
|
// things within these tenancies: |
|
// |
|
// - part1/default |
|
// - default/nsa |
|
// - part1/nsa |
|
func TestBasicL4ExplicitDestinations(t *testing.T) { |
|
|
|
tenancies := []*pbresource.Tenancy{ |
|
{ |
|
Partition: "default", |
|
Namespace: "default", |
|
}, |
|
} |
|
if utils.IsEnterprise() { |
|
tenancies = append(tenancies, &pbresource.Tenancy{ |
|
Partition: "part1", |
|
Namespace: "default", |
|
}) |
|
tenancies = append(tenancies, &pbresource.Tenancy{ |
|
Partition: "part1", |
|
Namespace: "nsa", |
|
}) |
|
tenancies = append(tenancies, &pbresource.Tenancy{ |
|
Partition: "default", |
|
Namespace: "nsa", |
|
}) |
|
} |
|
|
|
cfg := testBasicL4ExplicitDestinationsCreator{ |
|
tenancies: tenancies, |
|
}.NewConfig(t) |
|
|
|
sp := sprawltest.Launch(t, cfg) |
|
|
|
var ( |
|
asserter = topoutil.NewAsserter(sp) |
|
|
|
topo = sp.Topology() |
|
cluster = topo.Clusters["dc1"] |
|
|
|
ships = topo.ComputeRelationships() |
|
) |
|
|
|
clientV2 := sp.ResourceServiceClientForCluster(cluster.Name) |
|
|
|
t.Log(topology.RenderRelationships(ships)) |
|
|
|
// Make sure things are in v2. |
|
for _, ten := range tenancies { |
|
for _, name := range []string{ |
|
"single-server", |
|
"single-client", |
|
"multi-server", |
|
"multi-client", |
|
} { |
|
libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, name, ten, 1) |
|
} |
|
} |
|
|
|
// Check relationships |
|
for _, ship := range ships { |
|
t.Run("relationship: "+ship.String(), func(t *testing.T) { |
|
var ( |
|
wrk = ship.Caller |
|
dest = ship.Destination |
|
) |
|
|
|
clusterPrefix := clusterPrefixForDestination(dest) |
|
|
|
asserter.DestinationEndpointStatus(t, wrk, clusterPrefix+".", "HEALTHY", 1) |
|
asserter.HTTPServiceEchoes(t, wrk, dest.LocalPort, "") |
|
asserter.FortioFetch2FortioName(t, wrk, dest, cluster.Name, dest.ID) |
|
}) |
|
} |
|
} |
|
|
|
type testBasicL4ExplicitDestinationsCreator struct { |
|
tenancies []*pbresource.Tenancy |
|
} |
|
|
|
func (c testBasicL4ExplicitDestinationsCreator) NewConfig(t *testing.T) *topology.Config { |
|
const clusterName = "dc1" |
|
|
|
servers := topoutil.NewTopologyServerSet(clusterName+"-server", 3, []string{clusterName, "wan"}, nil) |
|
|
|
cluster := &topology.Cluster{ |
|
Enterprise: utils.IsEnterprise(), |
|
Name: clusterName, |
|
Nodes: servers, |
|
} |
|
|
|
lastNode := 0 |
|
nodeName := func() string { |
|
lastNode++ |
|
return fmt.Sprintf("%s-box%d", clusterName, lastNode) |
|
} |
|
|
|
for _, ten := range c.tenancies { |
|
c.topologyConfigAddNodes(t, cluster, nodeName, ten) |
|
} |
|
|
|
return &topology.Config{ |
|
Images: utils.TargetImages(), |
|
Networks: []*topology.Network{ |
|
{Name: clusterName}, |
|
{Name: "wan", Type: "wan"}, |
|
}, |
|
Clusters: []*topology.Cluster{ |
|
cluster, |
|
}, |
|
} |
|
} |
|
|
|
func (c testBasicL4ExplicitDestinationsCreator) topologyConfigAddNodes( |
|
t *testing.T, |
|
cluster *topology.Cluster, |
|
nodeName func() string, |
|
tenancy *pbresource.Tenancy, |
|
) { |
|
clusterName := cluster.Name |
|
tenancy.PeerName = "local" |
|
|
|
newID := func(name string, tenancy *pbresource.Tenancy) topology.ID { |
|
return topology.ID{ |
|
Partition: tenancy.Partition, |
|
Namespace: tenancy.Namespace, |
|
Name: name, |
|
} |
|
} |
|
|
|
singleportServerNode := &topology.Node{ |
|
Kind: topology.NodeKindDataplane, |
|
Version: topology.NodeVersionV2, |
|
Partition: tenancy.Partition, |
|
Name: nodeName(), |
|
Workloads: []*topology.Workload{ |
|
topoutil.NewFortioWorkloadWithDefaults( |
|
clusterName, |
|
newID("single-server", tenancy), |
|
topology.NodeVersionV2, |
|
func(wrk *topology.Workload) { |
|
wrk.WorkloadIdentity = "single-server-identity" |
|
}, |
|
), |
|
}, |
|
} |
|
var singleportDestinations []*topology.Destination |
|
for i, ten := range c.tenancies { |
|
singleportDestinations = append(singleportDestinations, &topology.Destination{ |
|
ID: newID("single-server", ten), |
|
PortName: "http", |
|
LocalAddress: "0.0.0.0", // needed for an assertion |
|
LocalPort: 5000 + i, |
|
}) |
|
} |
|
singleportClientNode := &topology.Node{ |
|
Kind: topology.NodeKindDataplane, |
|
Version: topology.NodeVersionV2, |
|
Partition: tenancy.Partition, |
|
Name: nodeName(), |
|
Workloads: []*topology.Workload{ |
|
topoutil.NewFortioWorkloadWithDefaults( |
|
clusterName, |
|
newID("single-client", tenancy), |
|
topology.NodeVersionV2, |
|
func(wrk *topology.Workload) { |
|
delete(wrk.Ports, "grpc") // v2 mode turns this on, so turn it off |
|
delete(wrk.Ports, "http2") // v2 mode turns this on, so turn it off |
|
wrk.WorkloadIdentity = "single-client-identity" |
|
wrk.Destinations = singleportDestinations |
|
}, |
|
), |
|
}, |
|
} |
|
var sources []*pbauth.Source |
|
for _, ten := range c.tenancies { |
|
sources = append(sources, &pbauth.Source{ |
|
IdentityName: "single-client-identity", |
|
Namespace: ten.Namespace, |
|
Partition: ten.Partition, |
|
}) |
|
} |
|
singleportTrafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ |
|
Id: &pbresource.ID{ |
|
Type: pbauth.TrafficPermissionsType, |
|
Name: "single-server-perms", |
|
Tenancy: tenancy, |
|
}, |
|
}, &pbauth.TrafficPermissions{ |
|
Destination: &pbauth.Destination{ |
|
IdentityName: "single-server-identity", |
|
}, |
|
Action: pbauth.Action_ACTION_ALLOW, |
|
Permissions: []*pbauth.Permission{{ |
|
Sources: sources, |
|
}}, |
|
}) |
|
|
|
multiportServerNode := &topology.Node{ |
|
Kind: topology.NodeKindDataplane, |
|
Version: topology.NodeVersionV2, |
|
Partition: tenancy.Partition, |
|
Name: nodeName(), |
|
Workloads: []*topology.Workload{ |
|
topoutil.NewFortioWorkloadWithDefaults( |
|
clusterName, |
|
newID("multi-server", tenancy), |
|
topology.NodeVersionV2, |
|
func(wrk *topology.Workload) { |
|
wrk.WorkloadIdentity = "multi-server-identity" |
|
}, |
|
), |
|
}, |
|
} |
|
var multiportDestinations []*topology.Destination |
|
for i, ten := range c.tenancies { |
|
multiportDestinations = append(multiportDestinations, &topology.Destination{ |
|
ID: newID("multi-server", ten), |
|
PortName: "http", |
|
LocalAddress: "0.0.0.0", // needed for an assertion |
|
LocalPort: 5000 + 2*i, |
|
}) |
|
multiportDestinations = append(multiportDestinations, &topology.Destination{ |
|
ID: newID("multi-server", ten), |
|
PortName: "http2", |
|
LocalAddress: "0.0.0.0", // needed for an assertion |
|
LocalPort: 5000 + 2*i + 1, |
|
}) |
|
} |
|
multiportClientNode := &topology.Node{ |
|
Kind: topology.NodeKindDataplane, |
|
Version: topology.NodeVersionV2, |
|
Partition: tenancy.Partition, |
|
Name: nodeName(), |
|
Workloads: []*topology.Workload{ |
|
topoutil.NewFortioWorkloadWithDefaults( |
|
clusterName, |
|
newID("multi-client", tenancy), |
|
topology.NodeVersionV2, |
|
func(wrk *topology.Workload) { |
|
wrk.WorkloadIdentity = "multi-client-identity" |
|
wrk.Destinations = multiportDestinations |
|
}, |
|
), |
|
}, |
|
} |
|
|
|
var multiportSources []*pbauth.Source |
|
for _, ten := range c.tenancies { |
|
multiportSources = append(multiportSources, &pbauth.Source{ |
|
IdentityName: "multi-client-identity", |
|
Namespace: ten.Namespace, |
|
Partition: ten.Partition, |
|
}) |
|
} |
|
multiportTrafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ |
|
Id: &pbresource.ID{ |
|
Type: pbauth.TrafficPermissionsType, |
|
Name: "multi-server-perms", |
|
Tenancy: tenancy, |
|
}, |
|
}, &pbauth.TrafficPermissions{ |
|
Destination: &pbauth.Destination{ |
|
IdentityName: "multi-server-identity", |
|
}, |
|
Action: pbauth.Action_ACTION_ALLOW, |
|
Permissions: []*pbauth.Permission{{ |
|
Sources: multiportSources, |
|
}}, |
|
}) |
|
|
|
cluster.Nodes = append(cluster.Nodes, |
|
singleportClientNode, |
|
singleportServerNode, |
|
multiportClientNode, |
|
multiportServerNode, |
|
) |
|
|
|
cluster.InitialResources = append(cluster.InitialResources, |
|
singleportTrafficPerms, |
|
multiportTrafficPerms, |
|
) |
|
}
|
|
|