* node health controller tenancy

* some prog

* some fixes

* revert

* pr comment resolved

* removed name

* Add namespace and tenancy in sidecar proxy controller test

* revert node health controller

* clean up data

* fix local

* copy from ENT

* removed dup code

* removed tenancy

* add test tenancies
pull/19589/head
Ashesh Vidyut 2023-11-09 11:47:19 +05:30 committed by GitHub
parent 2296bd5c9a
commit 515eed8c7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 634 additions and 526 deletions

View File

@ -5,6 +5,9 @@ package sidecarproxy
import (
"context"
"fmt"
mockres "github.com/hashicorp/consul/agent/grpc-external/services/resource"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest"
"strings"
"testing"
@ -16,7 +19,6 @@ import (
"github.com/hashicorp/consul/internal/auth"
"github.com/hashicorp/consul/internal/catalog"
"github.com/hashicorp/consul/internal/controller"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/builder"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/fetcher"
@ -59,10 +61,22 @@ type controllerTestSuite struct {
dbEndpointsData *pbcatalog.ServiceEndpoints
proxyStateTemplate *pbmesh.ProxyStateTemplate
tenancies []*pbresource.Tenancy
}
func (suite *controllerTestSuite) SetupTest() {
resourceClient := svctest.RunResourceService(suite.T(), types.Register, catalog.RegisterTypes, auth.RegisterTypes)
suite.tenancies = resourcetest.TestTenancies()
mockTenancyBridge := &mockres.MockTenancyBridge{}
for _, tenancy := range suite.tenancies {
mockTenancyBridge.On("PartitionExists", tenancy.Partition).Return(true, nil)
mockTenancyBridge.On("NamespaceExists", tenancy.Partition, tenancy.Namespace).Return(true, nil)
mockTenancyBridge.On("IsPartitionMarkedForDeletion", tenancy.Partition).Return(false, nil)
mockTenancyBridge.On("IsNamespaceMarkedForDeletion", tenancy.Partition, tenancy.Namespace).Return(false, nil)
}
cfg := mockres.Config{
TenancyBridge: mockTenancyBridge,
}
resourceClient := svctest.RunResourceServiceWithConfig(suite.T(), cfg, types.Register, catalog.RegisterTypes, auth.RegisterTypes)
suite.client = resourcetest.NewClient(resourceClient)
suite.runtime = controller.Runtime{Client: resourceClient, Logger: testutil.Logger(suite.T())}
suite.ctx = testutil.TestContext(suite.T())
@ -74,10 +88,6 @@ func (suite *controllerTestSuite) SetupTest() {
},
}
{
// DB will be a service with a single workload, IN the mesh that will
// be a destination of web.
suite.dbWorkload = &pbcatalog.Workload{
Identity: "db-identity",
Addresses: []*pbcatalog.WorkloadAddress{
@ -88,52 +98,6 @@ func (suite *controllerTestSuite) SetupTest() {
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
},
}
suite.dbWorkloadID = resourcetest.Resource(pbcatalog.WorkloadType, "db-abc").
WithData(suite.T(), suite.dbWorkload).
Write(suite.T(), resourceClient).Id
suite.dbService = resourcetest.Resource(pbcatalog.ServiceType, "db-service").
WithData(suite.T(), &pbcatalog.Service{
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"db-abc"}},
VirtualIps: []string{"1.1.1.1"},
Ports: []*pbcatalog.ServicePort{
{TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP},
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
}}).
Write(suite.T(), suite.client)
suite.dbEndpointsData = &pbcatalog.ServiceEndpoints{
Endpoints: []*pbcatalog.Endpoint{
{
TargetRef: suite.dbWorkloadID,
Addresses: suite.dbWorkload.Addresses,
Ports: suite.dbWorkload.Ports,
Identity: "db-identity",
},
},
}
suite.dbEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "db-service").
WithData(suite.T(), suite.dbEndpointsData).
Write(suite.T(), suite.client)
}
suite.apiWorkload = &pbcatalog.Workload{
Identity: "api-identity",
Addresses: []*pbcatalog.WorkloadAddress{
{
Host: "10.0.0.1",
},
},
Ports: map[string]*pbcatalog.WorkloadPort{
"tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
},
}
suite.apiWorkloadID = resourcetest.Resource(pbcatalog.WorkloadType, "api-abc").
WithData(suite.T(), suite.apiWorkload).
Write(suite.T(), resourceClient).Id
suite.apiServiceData = &pbcatalog.Service{
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"api-abc"}},
@ -159,28 +123,22 @@ func (suite *controllerTestSuite) SetupTest() {
},
},
}
}
suite.apiComputedTrafficPermissions = resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, suite.apiWorkload.Identity).
WithData(suite.T(), suite.apiComputedTrafficPermissionsData).
Write(suite.T(), resourceClient)
func (suite *controllerTestSuite) setupSuiteWithTenancy(tenancy *pbresource.Tenancy) {
suite.apiService = resourcetest.Resource(pbcatalog.ServiceType, "api-service").
WithData(suite.T(), suite.apiServiceData).
Write(suite.T(), suite.client.ResourceServiceClient)
suite.apiEndpointsData = &pbcatalog.ServiceEndpoints{
Endpoints: []*pbcatalog.Endpoint{
{
TargetRef: suite.apiWorkloadID,
Addresses: suite.apiWorkload.Addresses,
Ports: suite.apiWorkload.Ports,
suite.apiWorkload = &pbcatalog.Workload{
Identity: "api-identity",
Addresses: []*pbcatalog.WorkloadAddress{
{
Host: "10.0.0.1",
},
},
Ports: map[string]*pbcatalog.WorkloadPort{
"tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
},
}
suite.apiEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service").
WithData(suite.T(), suite.apiEndpointsData).
Write(suite.T(), suite.client.ResourceServiceClient)
webWorkloadData := &pbcatalog.Workload{
Identity: "web-identity",
@ -194,15 +152,84 @@ func (suite *controllerTestSuite) SetupTest() {
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
},
}
// DB will be a service with a single workload, IN the mesh that will
// be a destination of web.
suite.dbWorkloadID = resourcetest.Resource(pbcatalog.WorkloadType, "db-abc").
WithData(suite.T(), suite.dbWorkload).
WithTenancy(tenancy).
Write(suite.T(), suite.client.ResourceServiceClient).Id
suite.dbService = resourcetest.Resource(pbcatalog.ServiceType, "db-service").
WithData(suite.T(), &pbcatalog.Service{
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"db-abc"}},
VirtualIps: []string{"1.1.1.1"},
Ports: []*pbcatalog.ServicePort{
{TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP},
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
}}).
WithTenancy(tenancy).
Write(suite.T(), suite.client)
suite.dbEndpointsData = &pbcatalog.ServiceEndpoints{
Endpoints: []*pbcatalog.Endpoint{
{
TargetRef: suite.dbWorkloadID,
Addresses: suite.dbWorkload.Addresses,
Ports: suite.dbWorkload.Ports,
Identity: "db-identity",
},
},
}
suite.dbEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "db-service").
WithData(suite.T(), suite.dbEndpointsData).
WithTenancy(tenancy).
Write(suite.T(), suite.client)
suite.apiWorkloadID = resourcetest.Resource(pbcatalog.WorkloadType, "api-abc").
WithTenancy(tenancy).
WithData(suite.T(), suite.apiWorkload).
Write(suite.T(), suite.client.ResourceServiceClient).Id
suite.apiComputedTrafficPermissions = resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, suite.apiWorkload.Identity).
WithData(suite.T(), suite.apiComputedTrafficPermissionsData).
WithTenancy(tenancy).
Write(suite.T(), suite.client.ResourceServiceClient)
suite.apiService = resourcetest.Resource(pbcatalog.ServiceType, "api-service").
WithData(suite.T(), suite.apiServiceData).
WithTenancy(tenancy).
Write(suite.T(), suite.client.ResourceServiceClient)
suite.apiEndpointsData = &pbcatalog.ServiceEndpoints{
Endpoints: []*pbcatalog.Endpoint{
{
TargetRef: suite.apiWorkloadID,
Addresses: suite.apiWorkload.Addresses,
Ports: suite.apiWorkload.Ports,
Identity: "api-identity",
},
},
}
suite.apiEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service").
WithData(suite.T(), suite.apiEndpointsData).
WithTenancy(tenancy).
Write(suite.T(), suite.client.ResourceServiceClient)
suite.webWorkload = resourcetest.Resource(pbcatalog.WorkloadType, "web-def").
WithData(suite.T(), webWorkloadData).
WithTenancy(tenancy).
Write(suite.T(), suite.client)
resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, webWorkloadData.Identity).
WithData(suite.T(), &pbauth.ComputedTrafficPermissions{IsDefault: true}).
Write(suite.T(), resourceClient)
WithTenancy(tenancy).
Write(suite.T(), suite.client.ResourceServiceClient)
resourcetest.Resource(pbcatalog.ServiceType, "web").
WithTenancy(tenancy).
WithData(suite.T(), &pbcatalog.Service{
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"web-def"}},
Ports: []*pbcatalog.ServicePort{
@ -212,6 +239,7 @@ func (suite *controllerTestSuite) SetupTest() {
Write(suite.T(), suite.client)
resourcetest.Resource(pbcatalog.ServiceEndpointsType, "web").
WithTenancy(tenancy).
WithData(suite.T(), &pbcatalog.ServiceEndpoints{
Endpoints: []*pbcatalog.Endpoint{
{
@ -236,9 +264,11 @@ func (suite *controllerTestSuite) SetupTest() {
}
func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_NoServicesInCache() {
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
dataFetcher := fetcher.New(suite.client, suite.ctl.cache)
workload := resourcetest.Resource(pbcatalog.WorkloadType, "api-workload").
WithTenancy(tenancy).
WithData(suite.T(), &pbcatalog.Workload{
Ports: map[string]*pbcatalog.WorkloadPort{
"tcp": {Port: 8080},
@ -250,9 +280,11 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_NoService
workloadPorts, err := suite.ctl.workloadPortProtocolsFromService(suite.ctx, dataFetcher, decWorkload, suite.runtime.Logger)
require.NoError(suite.T(), err)
prototest.AssertDeepEqual(suite.T(), pbcatalog.Protocol_PROTOCOL_TCP, workloadPorts["tcp"].GetProtocol())
})
}
func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_ServiceNotFound() {
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
c := cache.New()
dataFetcher := fetcher.New(suite.client, c)
ctrl := &reconciler{
@ -267,6 +299,7 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_ServiceNo
Names: []string{"api-workload"},
},
}).
WithTenancy(tenancy).
Build()
decSvc := resourcetest.MustDecode[*pbcatalog.Service](suite.T(), svc)
@ -278,6 +311,7 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_ServiceNo
"tcp": {Port: 8080},
},
}).
WithTenancy(tenancy).
Build()
decWorkload := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), workload)
@ -287,9 +321,11 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_ServiceNo
prototest.AssertDeepEqual(suite.T(), pbcatalog.Protocol_PROTOCOL_TCP, workloadPorts["tcp"].GetProtocol())
// Check that the service is no longer in cache.
require.Nil(suite.T(), c.ServicesForWorkload(workload.Id))
})
}
func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService() {
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
c := cache.New()
dataFetcher := fetcher.New(suite.client, c)
ctrl := &reconciler{
@ -314,12 +350,14 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService() {
},
},
}).
WithTenancy(tenancy).
Write(suite.T(), suite.client)
decSvc := resourcetest.MustDecode[*pbcatalog.Service](suite.T(), svc1)
c.TrackService(decSvc)
svc2 := resourcetest.Resource(pbcatalog.ServiceType, "api-2").
WithTenancy(tenancy).
WithData(suite.T(), &pbcatalog.Service{
Workloads: &pbcatalog.WorkloadSelector{
Names: []string{"api-workload"},
@ -341,6 +379,7 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService() {
c.TrackService(decSvc)
workload := resourcetest.Resource(pbcatalog.WorkloadType, "api-workload").
WithTenancy(tenancy).
WithData(suite.T(), &pbcatalog.Workload{
Ports: map[string]*pbcatalog.WorkloadPort{
"http1": {Port: 8080},
@ -351,7 +390,7 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService() {
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
},
}).
WithTenancy(resource.DefaultNamespacedTenancy()).
WithTenancy(tenancy).
Build()
decWorkload := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), workload)
@ -378,20 +417,24 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService() {
require.NoError(suite.T(), err)
prototest.AssertDeepEqual(suite.T(), expWorkloadPorts, workloadPorts)
})
}
func (suite *controllerTestSuite) TestReconcile_NoWorkload() {
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
// This test ensures that removed workloads are ignored and don't result
// in the creation of the proxy state template.
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
ID: resourceID(pbmesh.ProxyStateTemplateType, "not-found"),
ID: resourceID(pbmesh.ProxyStateTemplateType, "not-found", tenancy),
})
require.NoError(suite.T(), err)
suite.client.RequireResourceNotFound(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, "not-found"))
suite.client.RequireResourceNotFound(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, "not-found", tenancy))
})
}
func (suite *controllerTestSuite) TestReconcile_NonMeshWorkload() {
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
// This test ensures that non-mesh workloads are ignored by the controller.
nonMeshWorkload := &pbcatalog.Workload{
@ -407,50 +450,58 @@ func (suite *controllerTestSuite) TestReconcile_NonMeshWorkload() {
resourcetest.Resource(pbcatalog.WorkloadType, "test-non-mesh-api-workload").
WithData(suite.T(), nonMeshWorkload).
WithTenancy(tenancy).
Write(suite.T(), suite.client.ResourceServiceClient)
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
ID: resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload"),
ID: resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload", tenancy),
})
require.NoError(suite.T(), err)
suite.client.RequireResourceNotFound(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload"))
suite.client.RequireResourceNotFound(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload", tenancy))
})
}
func (suite *controllerTestSuite) TestReconcile_NoExistingProxyStateTemplate() {
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
ID: resourceID(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID.Name),
ID: resourceID(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID.Name, tenancy),
})
require.NoError(suite.T(), err)
res := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID.Name))
res := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID.Name, tenancy))
require.NoError(suite.T(), err)
require.NotNil(suite.T(), res.Data)
prototest.AssertDeepEqual(suite.T(), suite.apiWorkloadID, res.Owner)
})
}
func (suite *controllerTestSuite) TestReconcile_ExistingProxyStateTemplate_WithUpdates() {
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
// This test ensures that we write a new proxy state template when there are changes.
// Write the original.
resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc").
WithData(suite.T(), suite.proxyStateTemplate).
WithOwner(suite.apiWorkloadID).
WithTenancy(tenancy).
Write(suite.T(), suite.client.ResourceServiceClient)
// Update the apiWorkload and check that we default the port to tcp if it's unspecified.
suite.apiWorkload.Ports["tcp"].Protocol = pbcatalog.Protocol_PROTOCOL_UNSPECIFIED
updatedWorkloadID := resourcetest.Resource(pbcatalog.WorkloadType, "api-abc").
WithTenancy(tenancy).
WithData(suite.T(), suite.apiWorkload).
Write(suite.T(), suite.client.ResourceServiceClient).Id
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
ID: resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name),
ID: resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name, tenancy),
})
require.NoError(suite.T(), err)
res := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name))
res := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name, tenancy))
require.NoError(suite.T(), err)
require.NotNil(suite.T(), res.Data)
prototest.AssertDeepEqual(suite.T(), updatedWorkloadID, res.Owner)
@ -466,15 +517,18 @@ func (suite *controllerTestSuite) TestReconcile_ExistingProxyStateTemplate_WithU
l4InboundRouter := updatedProxyStateTemplate.ProxyState.Listeners[0].
Routers[0].GetL4()
require.NotNil(suite.T(), l4InboundRouter)
})
}
func (suite *controllerTestSuite) TestReconcile_ExistingProxyStateTemplate_NoUpdates() {
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
// This test ensures that we skip writing of the proxy state template when there are no changes to it.
// Write the original.
originalProxyState := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc").
WithData(suite.T(), suite.proxyStateTemplate).
WithOwner(suite.apiWorkloadID).
WithTenancy(tenancy).
Write(suite.T(), suite.client.ResourceServiceClient)
// Update the metadata on the apiWorkload which should result in no changes.
@ -484,20 +538,16 @@ func (suite *controllerTestSuite) TestReconcile_ExistingProxyStateTemplate_NoUpd
Write(suite.T(), suite.client.ResourceServiceClient).Id
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
ID: resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name),
ID: resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name, tenancy),
})
require.NoError(suite.T(), err)
updatedProxyState := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID.Name))
updatedProxyState := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID.Name, tenancy))
resourcetest.RequireVersionUnchanged(suite.T(), updatedProxyState, originalProxyState.Version)
})
}
func (suite *controllerTestSuite) TestController() {
// This is a comprehensive test that checks the overall controller behavior as various resources change state.
// This should test interactions between the reconciler, the mappers, and the destinationsCache to ensure they work
// together and produce expected result.
// Run the controller manager
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
// Initialize controller dependencies.
@ -508,10 +558,16 @@ func (suite *controllerTestSuite) TestController() {
mgr.SetRaftLeader(true)
go mgr.Run(suite.ctx)
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
// This is a comprehensive test that checks the overall controller behavior as various resources change state.
// This should test interactions between the reconciler, the mappers, and the destinationsCache to ensure they work
// together and produce expected result.
// Run the controller manager
var (
// Create proxy state template IDs to check against in this test.
apiProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc").ID()
webProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "web-def").ID()
apiProxyStateTemplateID = resourcetest.ResourceWithTenancy(pbmesh.ProxyStateTemplateType, "api-abc", tenancy).ID()
webProxyStateTemplateID = resourcetest.ResourceWithTenancy(pbmesh.ProxyStateTemplateType, "web-def", tenancy).ID()
apiComputedRoutesID = resource.ReplaceType(pbmesh.ComputedRoutesType, suite.apiService.Id)
dbComputedRoutesID = resource.ReplaceType(pbmesh.ComputedRoutesType, suite.dbService.Id)
@ -537,6 +593,7 @@ func (suite *controllerTestSuite) TestController() {
// Add a source service and check that a new proxy state is generated.
webComputedDestinations = resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webWorkload.Id.Name).
WithTenancy(tenancy).
WithData(suite.T(), &pbmesh.ComputedExplicitDestinations{
Destinations: []*pbmesh.Destination{
{
@ -572,6 +629,7 @@ func (suite *controllerTestSuite) TestController() {
// be reconciled after the workload has been updated, and so we need to write the
// workload and service before we write service endpoints.
resourcetest.Resource(pbcatalog.WorkloadType, "api-abc").
WithTenancy(tenancy).
WithData(suite.T(), &pbcatalog.Workload{
Identity: "api-identity",
Addresses: suite.apiWorkload.Addresses,
@ -579,6 +637,7 @@ func (suite *controllerTestSuite) TestController() {
Write(suite.T(), suite.client)
suite.apiService = resourcetest.ResourceID(suite.apiService.Id).
WithTenancy(tenancy).
WithData(t, &pbcatalog.Service{
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"api-abc"}},
VirtualIps: []string{"1.1.1.1"},
@ -590,6 +649,7 @@ func (suite *controllerTestSuite) TestController() {
Write(suite.T(), suite.client)
resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service").
WithTenancy(tenancy).
WithData(suite.T(), &pbcatalog.ServiceEndpoints{
Endpoints: []*pbcatalog.Endpoint{
{
@ -624,14 +684,17 @@ func (suite *controllerTestSuite) TestController() {
suite.runtime.Logger.Trace("updating ports to mesh")
resourcetest.Resource(pbcatalog.WorkloadType, "api-abc").
WithTenancy(tenancy).
WithData(suite.T(), suite.apiWorkload).
Write(suite.T(), suite.client)
suite.apiService = resourcetest.Resource(pbcatalog.ServiceType, "api-service").
WithData(suite.T(), suite.apiServiceData).
WithTenancy(tenancy).
Write(suite.T(), suite.client.ResourceServiceClient)
resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service").
WithTenancy(tenancy).
WithData(suite.T(), suite.apiEndpointsData).
Write(suite.T(), suite.client.ResourceServiceClient)
@ -672,6 +735,7 @@ func (suite *controllerTestSuite) TestController() {
// Enable transparent proxy for the web proxy.
resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, suite.webWorkload.Id.Name).
WithTenancy(tenancy).
WithData(t, &pbmesh.ComputedProxyConfiguration{
DynamicConfig: &pbmesh.DynamicConfig{
Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT,
@ -702,6 +766,7 @@ func (suite *controllerTestSuite) TestController() {
suite.runtime.Logger.Trace("creating computed traffic permissions")
resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, suite.apiWorkload.Identity).
WithTenancy(tenancy).
WithData(t, suite.apiComputedTrafficPermissionsData).
Write(t, suite.client)
@ -739,7 +804,7 @@ func (suite *controllerTestSuite) TestController() {
}},
}
route := resourcetest.Resource(pbmesh.HTTPRouteType, "db-http-route").
WithTenancy(resource.DefaultNamespacedTenancy()).
WithTenancy(tenancy).
WithData(t, routeData).
Build()
require.NoError(t, types.MutateHTTPRoute(route))
@ -759,9 +824,11 @@ func (suite *controllerTestSuite) TestController() {
requireImplicitDestinationsFound(t, "api", webProxyStateTemplate)
requireImplicitDestinationsFound(t, "db", webProxyStateTemplate)
})
})
}
func (suite *controllerTestSuite) TestControllerDefaultAllow() {
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
// Run the controller manager
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
@ -775,8 +842,8 @@ func (suite *controllerTestSuite) TestControllerDefaultAllow() {
var (
// Create proxy state template IDs to check against in this test.
apiProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc").ID()
webProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "web-def").ID()
apiProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc").WithTenancy(tenancy).ID()
webProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "web-def").WithTenancy(tenancy).ID()
)
retry.Run(suite.T(), func(r *retry.R) {
@ -787,6 +854,7 @@ func (suite *controllerTestSuite) TestControllerDefaultAllow() {
assertTrafficPermissionDefaultPolicy(r, false, apiProxyStateTemplate)
assertTrafficPermissionDefaultPolicy(r, true, webProxyStateTemplate)
})
})
}
func TestMeshController(t *testing.T) {
@ -893,14 +961,10 @@ func requireClustersAndEndpoints(t *testing.T, name string, tmpl *pbmesh.ProxySt
require.Equal(t, found, foundEndpoints)
}
func resourceID(rtype *pbresource.Type, name string) *pbresource.ID {
func resourceID(rtype *pbresource.Type, name string, tenancy *pbresource.Tenancy) *pbresource.ID {
return &pbresource.ID{
Type: rtype,
Tenancy: &pbresource.Tenancy{
Partition: "default",
Namespace: "default",
PeerName: "local",
},
Tenancy: tenancy,
Name: name,
}
}
@ -919,3 +983,31 @@ func assertTrafficPermissionDefaultPolicy(t resourcetest.T, defaultAllow bool, r
require.NotNil(t, l4)
require.Equal(t, defaultAllow, l4.TrafficPermissions.DefaultAllow)
}
func (suite *controllerTestSuite) appendTenancyInfo(tenancy *pbresource.Tenancy) string {
return fmt.Sprintf("%s_Namespace_%s_Partition", tenancy.Namespace, tenancy.Partition)
}
func (suite *controllerTestSuite) cleanupResources() {
suite.client.MustDelete(suite.T(), suite.apiWorkloadID)
suite.client.MustDelete(suite.T(), suite.apiComputedTrafficPermissions.Id)
suite.client.MustDelete(suite.T(), suite.apiService.Id)
suite.client.MustDelete(suite.T(), suite.apiEndpoints.Id)
suite.client.MustDelete(suite.T(), suite.webWorkload.Id)
suite.client.MustDelete(suite.T(), suite.dbWorkloadID)
suite.client.MustDelete(suite.T(), suite.dbService.Id)
suite.client.MustDelete(suite.T(), suite.dbEndpoints.Id)
}
func (suite *controllerTestSuite) runTestCaseWithTenancies(t func(*pbresource.Tenancy)) {
for _, tenancy := range suite.tenancies {
suite.Run(suite.appendTenancyInfo(tenancy), func() {
suite.setupSuiteWithTenancy(tenancy)
suite.T().Cleanup(func() {
suite.cleanupResources()
})
t(tenancy)
})
}
}

View File

@ -43,6 +43,22 @@ func Resource(rtype *pbresource.Type, name string) *resourceBuilder {
}
}
func ResourceWithTenancy(rtype *pbresource.Type, name string, tenancy *pbresource.Tenancy) *resourceBuilder {
return &resourceBuilder{
resource: &pbresource.Resource{
Id: &pbresource.ID{
Type: &pbresource.Type{
Group: rtype.Group,
GroupVersion: rtype.GroupVersion,
Kind: rtype.Kind,
},
Name: name,
Tenancy: tenancy,
},
},
}
}
func ResourceID(id *pbresource.ID) *resourceBuilder {
return &resourceBuilder{
resource: &pbresource.Resource{