mirror of https://github.com/hashicorp/consul
Net 6439 (#19517)
* 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 tenanciespull/19589/head
parent
2296bd5c9a
commit
515eed8c7c
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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{
|
||||
|
|
Loading…
Reference in New Issue