From 79eadd1afd947673fc70570a75f8646784f6b23b Mon Sep 17 00:00:00 2001 From: John Murret Date: Fri, 13 Oct 2023 10:51:58 -0600 Subject: [PATCH] WIP --- .../controllers/xds/controller_test.go | 79 ++++++++- ...le-destination-ip-port-bind-address.golden | 162 ++++++++++++++++++ 2 files changed, 232 insertions(+), 9 deletions(-) create mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden diff --git a/internal/mesh/internal/controllers/xds/controller_test.go b/internal/mesh/internal/controllers/xds/controller_test.go index 4987995c57e2..cde26bdd0d86 100644 --- a/internal/mesh/internal/controllers/xds/controller_test.go +++ b/internal/mesh/internal/controllers/xds/controller_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "google.golang.org/protobuf/encoding/protojson" + "strings" "testing" svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" @@ -1005,9 +1006,9 @@ func (suite *xdsControllerTestSuite) TestBuildExplicitDestinations() { path := "../sidecarproxy/builder/testdata" cases := []string{ "destination/l4-single-destination-ip-port-bind-address", - "destination/l4-single-destination-unix-socket-bind-address", - "destination/l4-multi-destination", - "destination/mixed-multi-destination", + //"destination/l4-single-destination-unix-socket-bind-address", + //"destination/l4-multi-destination", + //"destination/mixed-multi-destination", } for _, name := range cases { @@ -1016,17 +1017,73 @@ func (suite *xdsControllerTestSuite) TestBuildExplicitDestinations() { pst := JSONToProxyTemplate(suite.T(), golden.GetBytesAtFilePath(suite.T(), fmt.Sprintf("%s/%s.golden", path, name))) + //get service data + serviceData := &pbcatalog.Service{} + var vp uint32 = 7000 + svcNames := map[string]map[string]string + + // get service name and ports + for name := range pst.RequiredEndpoints { + vp++ + nameSplit := strings.Split(name, ".") + port := nameSplit[0] + svcNames[nameSplit[1]] = name + serviceData.Ports = append(serviceData.Ports, &pbcatalog.ServicePort{ + TargetPort: port, + VirtualPort: vp, + Protocol: pbcatalog.Protocol_PROTOCOL_TCP, + }) + } + + svc := resourcetest.Resource(pbcatalog.ServiceType, svcName). + WithData(suite.T(), &pbcatalog.Service{}). + Write(suite.T(), suite.client) + + eps := resourcetest.Resource(pbcatalog.ServiceEndpointsType, svcName). + WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{ + { + Ports: map[string]*pbcatalog.WorkloadPort{ + "mesh": { + Port: 20000, + Protocol: pbcatalog.Protocol_PROTOCOL_MESH, + }, + }, + Addresses: []*pbcatalog.WorkloadAddress{ + { + Host: "10.1.1.1", + Ports: []string{"mesh"}, + }, + }, + }, + }}). + WithOwner(svc.Id). + Write(suite.T(), suite.client) + // + requiredEps := make(map[string]*pbproxystate.EndpointRef) + for epName := range pst.RequiredEndpoints { + requiredEps[epName] = &pbproxystate.EndpointRef{ + Id: eps.Id, + Port: "mesh", + } + } + + wiLeafs := make(map[string]*pbproxystate.LeafCertificateRef) + wiLeafs["wi-workload-identity"] = &pbproxystate.LeafCertificateRef{ + Name: "wi-workload-identity", + } + + pst.RequiredEndpoints = requiredEps + // Store the initial ProxyStateTemplate and track it in the mapper. proxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test"). WithData(suite.T(), pst). Write(suite.T(), suite.client) + retry.Run(suite.T(), func(r *retry.R) { + suite.client.RequireResourceExists(r, proxyStateTemplate.Id) + }) + suite.mapper.TrackItem(proxyStateTemplate.Id, []resource.ReferenceOrID{}) - for idx, ep := range pst.ProxyState.Endpoints { - resourcetest.Resource(pbcatalog.ServiceEndpointsType, fmt.Sprintf("test-%d", idx)). - WithData(suite.T(), ep). - Write(suite.T(), suite.client) - } // Run the reconcile, and since no ProxyStateTemplate is stored, this simulates a deletion. err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ @@ -1035,7 +1092,11 @@ func (suite *xdsControllerTestSuite) TestBuildExplicitDestinations() { require.NoError(suite.T(), err) require.NotNil(suite.T(), proxyStateTemplate) - //require.JSONEq(suite.T(), expected, actual) + + actual := prototest.ProtoToJSON(suite.T(), proxyStateTemplate.Data) + expected := golden.Get(suite.T(), actual, name+".golden") + + require.JSONEq(suite.T(), expected, actual) }) } } diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden new file mode 100644 index 000000000000..7ba711123559 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden @@ -0,0 +1,162 @@ +{ + "proxyState": { + "clusters": { + "null_route_cluster": { + "endpointGroup": { + "static": { + "config": { + "connectTimeout": "10s" + } + } + }, + "name": "null_route_cluster" + }, + "tcp.api-1.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-1.default.dc1.internal.foo.consul" + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-2.default.dc1.internal.foo.consul" + } + }, + "identity": { + "name": "test-identity", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "auth", + "groupVersion": "v2beta1", + "kind": "WorkloadIdentity" + } + }, + "listeners": [ + { + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "1.1.1.1", + "port": 1234 + }, + "name": "default/local/default/api-1:tcp:1.1.1.1:1234", + "routers": [ + { + "l4": { + "statPrefix": "upstream.tcp.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + } + ] + }, + "requiredEndpoints": { + "tcp.api-1.default.dc1.internal.foo.consul": { + "id": { + "name": "api-1", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "catalog", + "groupVersion": "v2beta1", + "kind": "ServiceEndpoints" + } + }, + "port": "mesh" + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "id": { + "name": "api-2", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "catalog", + "groupVersion": "v2beta1", + "kind": "ServiceEndpoints" + } + }, + "port": "mesh" + } + }, + "requiredLeafCertificates": { + "test-identity": { + "name": "test-identity", + "namespace": "default", + "partition": "default" + } + }, + "requiredTrustBundles": { + "local": { + "peer": "local" + } + } +} \ No newline at end of file