|
|
|
@ -5,6 +5,7 @@ package proxyconfiguration
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"context" |
|
|
|
|
"fmt" |
|
|
|
|
"testing" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
@ -46,10 +47,13 @@ type controllerTestSuite struct {
|
|
|
|
|
proxyCfg3 *pbmesh.ProxyConfiguration |
|
|
|
|
|
|
|
|
|
expComputedProxyCfg *pbmesh.ComputedProxyConfiguration |
|
|
|
|
|
|
|
|
|
tenancies []*pbresource.Tenancy |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) SetupTest() { |
|
|
|
|
resourceClient := svctest.RunResourceService(suite.T(), types.Register, catalog.RegisterTypes) |
|
|
|
|
suite.tenancies = resourcetest.TestTenancies() |
|
|
|
|
resourceClient := svctest.RunResourceServiceWithTenancies(suite.T(), types.Register, catalog.RegisterTypes) |
|
|
|
|
suite.client = resourcetest.NewClient(resourceClient) |
|
|
|
|
suite.runtime = controller.Runtime{Client: resourceClient, Logger: testutil.Logger(suite.T())} |
|
|
|
|
suite.ctx = testutil.TestContext(suite.T()) |
|
|
|
@ -57,78 +61,26 @@ func (suite *controllerTestSuite) SetupTest() {
|
|
|
|
|
suite.ctl = &reconciler{ |
|
|
|
|
proxyConfigMapper: workloadselectionmapper.New[*pbmesh.ProxyConfiguration](pbmesh.ComputedProxyConfigurationType), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
suite.workload = &pbcatalog.Workload{ |
|
|
|
|
Addresses: []*pbcatalog.WorkloadAddress{{Host: "1.1.1.1"}}, |
|
|
|
|
Ports: map[string]*pbcatalog.WorkloadPort{ |
|
|
|
|
"tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, |
|
|
|
|
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, |
|
|
|
|
}, |
|
|
|
|
Identity: "test", |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
suite.workloadRes = resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). |
|
|
|
|
WithData(suite.T(), suite.workload). |
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
|
|
|
|
|
suite.proxyCfg1 = &pbmesh.ProxyConfiguration{ |
|
|
|
|
Workloads: &pbcatalog.WorkloadSelector{ |
|
|
|
|
Names: []string{suite.workloadRes.Id.Name}, |
|
|
|
|
}, |
|
|
|
|
DynamicConfig: &pbmesh.DynamicConfig{ |
|
|
|
|
Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
suite.proxyCfg2 = &pbmesh.ProxyConfiguration{ |
|
|
|
|
Workloads: &pbcatalog.WorkloadSelector{ |
|
|
|
|
Prefixes: []string{"test-"}, |
|
|
|
|
}, |
|
|
|
|
DynamicConfig: &pbmesh.DynamicConfig{ |
|
|
|
|
Mode: pbmesh.ProxyMode_PROXY_MODE_DIRECT, // this setting should be overridden by proxycfg1
|
|
|
|
|
LocalConnection: map[string]*pbmesh.ConnectionConfig{ |
|
|
|
|
"tcp": {ConnectTimeout: durationpb.New(2 * time.Second)}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
suite.proxyCfg3 = &pbmesh.ProxyConfiguration{ |
|
|
|
|
Workloads: &pbcatalog.WorkloadSelector{ |
|
|
|
|
Prefixes: []string{"test-wor"}, |
|
|
|
|
}, |
|
|
|
|
BootstrapConfig: &pbmesh.BootstrapConfig{ |
|
|
|
|
PrometheusBindAddr: "0.0.0.0:9000", |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
suite.expComputedProxyCfg = &pbmesh.ComputedProxyConfiguration{ |
|
|
|
|
DynamicConfig: &pbmesh.DynamicConfig{ |
|
|
|
|
Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, |
|
|
|
|
TransparentProxy: &pbmesh.TransparentProxy{OutboundListenerPort: iptables.DefaultTProxyOutboundPort}, |
|
|
|
|
LocalConnection: map[string]*pbmesh.ConnectionConfig{ |
|
|
|
|
"tcp": {ConnectTimeout: durationpb.New(2 * time.Second)}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
BootstrapConfig: &pbmesh.BootstrapConfig{ |
|
|
|
|
PrometheusBindAddr: "0.0.0.0:9000", |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) TestReconcile_NoWorkload() { |
|
|
|
|
// This test ensures that removed workloads are ignored and don't result
|
|
|
|
|
// in the creation of the proxy state template.
|
|
|
|
|
id := resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, "not-found").ID() |
|
|
|
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { |
|
|
|
|
id := resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, "not-found").WithTenancy(tenancy).ID() |
|
|
|
|
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ |
|
|
|
|
ID: id, |
|
|
|
|
}) |
|
|
|
|
require.NoError(suite.T(), err) |
|
|
|
|
|
|
|
|
|
suite.client.RequireResourceNotFound(suite.T(), id) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) TestReconcile_NonMeshWorkload() { |
|
|
|
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { |
|
|
|
|
resourcetest.Resource(pbcatalog.WorkloadType, "non-mesh"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(suite.T(), &pbcatalog.Workload{ |
|
|
|
|
Addresses: []*pbcatalog.WorkloadAddress{{Host: "1.1.1.1"}}, |
|
|
|
|
Ports: map[string]*pbcatalog.WorkloadPort{ |
|
|
|
@ -138,6 +90,7 @@ func (suite *controllerTestSuite) TestReconcile_NonMeshWorkload() {
|
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
|
|
|
|
|
cpcID := resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, "non-mesh"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
Write(suite.T(), suite.client).Id |
|
|
|
|
|
|
|
|
|
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ |
|
|
|
@ -146,23 +99,28 @@ func (suite *controllerTestSuite) TestReconcile_NonMeshWorkload() {
|
|
|
|
|
require.NoError(suite.T(), err) |
|
|
|
|
|
|
|
|
|
suite.client.RequireResourceNotFound(suite.T(), cpcID) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) TestReconcile_HappyPath() { |
|
|
|
|
// Write all three proxy cfgs.
|
|
|
|
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { |
|
|
|
|
pCfg1 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg1"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(suite.T(), suite.proxyCfg1). |
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
_, err := suite.ctl.proxyConfigMapper.MapToComputedType(suite.ctx, suite.runtime, pCfg1) |
|
|
|
|
require.NoError(suite.T(), err) |
|
|
|
|
|
|
|
|
|
pCfg2 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg2"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(suite.T(), suite.proxyCfg2). |
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
_, err = suite.ctl.proxyConfigMapper.MapToComputedType(suite.ctx, suite.runtime, pCfg2) |
|
|
|
|
require.NoError(suite.T(), err) |
|
|
|
|
|
|
|
|
|
pCfg3 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg3"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(suite.T(), suite.proxyCfg3). |
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
_, err = suite.ctl.proxyConfigMapper.MapToComputedType(suite.ctx, suite.runtime, pCfg3) |
|
|
|
@ -176,17 +134,21 @@ func (suite *controllerTestSuite) TestReconcile_HappyPath() {
|
|
|
|
|
require.NoError(suite.T(), err) |
|
|
|
|
|
|
|
|
|
suite.requireComputedProxyConfiguration(suite.T(), cpcID) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) TestReconcile_NoProxyConfigs() { |
|
|
|
|
// Create a proxy cfg and map it so that it gets saved to cache.
|
|
|
|
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { |
|
|
|
|
pCfg1 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg1"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(suite.T(), suite.proxyCfg1). |
|
|
|
|
Build() |
|
|
|
|
_, err := suite.ctl.proxyConfigMapper.MapToComputedType(suite.ctx, suite.runtime, pCfg1) |
|
|
|
|
require.NoError(suite.T(), err) |
|
|
|
|
|
|
|
|
|
cpcID := resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, suite.workloadRes.Id.Name). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
Write(suite.T(), suite.client).Id |
|
|
|
|
err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ |
|
|
|
|
ID: cpcID, |
|
|
|
@ -195,6 +157,7 @@ func (suite *controllerTestSuite) TestReconcile_NoProxyConfigs() {
|
|
|
|
|
require.NoError(suite.T(), err) |
|
|
|
|
|
|
|
|
|
suite.client.RequireResourceNotFound(suite.T(), cpcID) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) TestController() { |
|
|
|
@ -206,16 +169,20 @@ func (suite *controllerTestSuite) TestController() {
|
|
|
|
|
mgr.SetRaftLeader(true) |
|
|
|
|
go mgr.Run(suite.ctx) |
|
|
|
|
|
|
|
|
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { |
|
|
|
|
// Write proxy configs.
|
|
|
|
|
pCfg1 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg1"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(suite.T(), suite.proxyCfg1). |
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
|
|
|
|
|
pCfg2 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg2"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(suite.T(), suite.proxyCfg2). |
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
|
|
|
|
|
pCfg3 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg3"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(suite.T(), suite.proxyCfg3). |
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
|
|
|
|
@ -229,7 +196,7 @@ func (suite *controllerTestSuite) TestController() {
|
|
|
|
|
|
|
|
|
|
testutil.RunStep(suite.T(), "add another workload", func(t *testing.T) { |
|
|
|
|
// Create another workload that will match only proxyCfg2.
|
|
|
|
|
matchingWorkload := resourcetest.Resource(pbcatalog.WorkloadType, "test-extra-workload"). |
|
|
|
|
matchingWorkload := resourcetest.Resource(pbcatalog.WorkloadType, "test-extra-workload").WithTenancy(tenancy). |
|
|
|
|
WithData(t, suite.workload). |
|
|
|
|
Write(t, suite.client) |
|
|
|
|
matchingWorkloadCPCID := resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, matchingWorkload.Id) |
|
|
|
@ -253,10 +220,12 @@ func (suite *controllerTestSuite) TestController() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
matchingWorkload := resourcetest.Resource(pbcatalog.WorkloadType, "test-extra-workload"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(t, suite.workload). |
|
|
|
|
Write(t, suite.client) |
|
|
|
|
matchingWorkloadCPCID := resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, matchingWorkload.Id) |
|
|
|
|
resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg2"). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
WithData(suite.T(), updatedProxyCfg). |
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
|
|
|
|
@ -294,6 +263,7 @@ func (suite *controllerTestSuite) TestController() {
|
|
|
|
|
suite.client.RequireResourceNotFound(r, cpcID) |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestControllerSuite(t *testing.T) { |
|
|
|
@ -306,3 +276,80 @@ func (suite *controllerTestSuite) requireComputedProxyConfiguration(t resourcete
|
|
|
|
|
prototest.AssertDeepEqual(t, suite.expComputedProxyCfg, decCPC.Data) |
|
|
|
|
resourcetest.RequireOwner(t, cpcRes, resource.ReplaceType(pbcatalog.WorkloadType, id), true) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) setupResourcesWithTenancy(tenancy *pbresource.Tenancy) { |
|
|
|
|
suite.workload = &pbcatalog.Workload{ |
|
|
|
|
Addresses: []*pbcatalog.WorkloadAddress{{Host: "1.1.1.1"}}, |
|
|
|
|
Ports: map[string]*pbcatalog.WorkloadPort{ |
|
|
|
|
"tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, |
|
|
|
|
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, |
|
|
|
|
}, |
|
|
|
|
Identity: "test", |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
suite.workloadRes = resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). |
|
|
|
|
WithData(suite.T(), suite.workload). |
|
|
|
|
WithTenancy(tenancy). |
|
|
|
|
Write(suite.T(), suite.client) |
|
|
|
|
|
|
|
|
|
suite.proxyCfg1 = &pbmesh.ProxyConfiguration{ |
|
|
|
|
Workloads: &pbcatalog.WorkloadSelector{ |
|
|
|
|
Names: []string{suite.workloadRes.Id.Name}, |
|
|
|
|
}, |
|
|
|
|
DynamicConfig: &pbmesh.DynamicConfig{ |
|
|
|
|
Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
suite.proxyCfg2 = &pbmesh.ProxyConfiguration{ |
|
|
|
|
Workloads: &pbcatalog.WorkloadSelector{ |
|
|
|
|
Prefixes: []string{"test-"}, |
|
|
|
|
}, |
|
|
|
|
DynamicConfig: &pbmesh.DynamicConfig{ |
|
|
|
|
Mode: pbmesh.ProxyMode_PROXY_MODE_DIRECT, // this setting should be overridden by proxycfg1
|
|
|
|
|
LocalConnection: map[string]*pbmesh.ConnectionConfig{ |
|
|
|
|
"tcp": {ConnectTimeout: durationpb.New(2 * time.Second)}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
suite.proxyCfg3 = &pbmesh.ProxyConfiguration{ |
|
|
|
|
Workloads: &pbcatalog.WorkloadSelector{ |
|
|
|
|
Prefixes: []string{"test-wor"}, |
|
|
|
|
}, |
|
|
|
|
BootstrapConfig: &pbmesh.BootstrapConfig{ |
|
|
|
|
PrometheusBindAddr: "0.0.0.0:9000", |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
suite.expComputedProxyCfg = &pbmesh.ComputedProxyConfiguration{ |
|
|
|
|
DynamicConfig: &pbmesh.DynamicConfig{ |
|
|
|
|
Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, |
|
|
|
|
TransparentProxy: &pbmesh.TransparentProxy{OutboundListenerPort: iptables.DefaultTProxyOutboundPort}, |
|
|
|
|
LocalConnection: map[string]*pbmesh.ConnectionConfig{ |
|
|
|
|
"tcp": {ConnectTimeout: durationpb.New(2 * time.Second)}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
BootstrapConfig: &pbmesh.BootstrapConfig{ |
|
|
|
|
PrometheusBindAddr: "0.0.0.0:9000", |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) cleanupResources() { |
|
|
|
|
suite.client.MustDelete(suite.T(), suite.workloadRes.Id) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) runTestCaseWithTenancies(testFunc func(*pbresource.Tenancy)) { |
|
|
|
|
for _, tenancy := range suite.tenancies { |
|
|
|
|
suite.Run(suite.appendTenancyInfo(tenancy), func() { |
|
|
|
|
suite.setupResourcesWithTenancy(tenancy) |
|
|
|
|
testFunc(tenancy) |
|
|
|
|
suite.T().Cleanup(suite.cleanupResources) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (suite *controllerTestSuite) appendTenancyInfo(tenancy *pbresource.Tenancy) string { |
|
|
|
|
return fmt.Sprintf("%s_Namespace_%s_Partition", tenancy.Namespace, tenancy.Partition) |
|
|
|
|
} |
|
|
|
|