mirror of https://github.com/status-im/consul.git
[NET-6438] Add tenancy to xDS Tests (#19551)
* [NET-6438] Add tenancy to xDS Tests * [NET-6438] Add tenancy to xDS Tests - Fixing imports * [NET-6438] Add tenancy to xDS Tests - Added cleanup post test run * [NET-6356] Add tenancy to xDS Tests - Added cleanup post test run * [NET-6438] Add tenancy to xDS Tests - using t.Cleanup instead of defer delete * [NET-6438] Add tenancy to xDS Tests - rebased * [NET-6438] Add tenancy to xDS Tests - rebased
This commit is contained in:
parent
005e1b9926
commit
68e7f27fd2
|
@ -5,7 +5,6 @@ package testing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
|
@ -21,6 +20,7 @@ import (
|
||||||
internal "github.com/hashicorp/consul/agent/grpc-internal"
|
internal "github.com/hashicorp/consul/agent/grpc-internal"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/internal/resource"
|
"github.com/hashicorp/consul/internal/resource"
|
||||||
|
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||||
"github.com/hashicorp/consul/internal/storage/inmem"
|
"github.com/hashicorp/consul/internal/storage/inmem"
|
||||||
"github.com/hashicorp/consul/internal/tenancy"
|
"github.com/hashicorp/consul/internal/tenancy"
|
||||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/internal/testing/golden"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"google.golang.org/protobuf/encoding/protojson"
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
@ -26,6 +25,7 @@ import (
|
||||||
"github.com/hashicorp/consul/internal/resource"
|
"github.com/hashicorp/consul/internal/resource"
|
||||||
"github.com/hashicorp/consul/internal/resource/mappers/bimapper"
|
"github.com/hashicorp/consul/internal/resource/mappers/bimapper"
|
||||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||||
|
"github.com/hashicorp/consul/internal/testing/golden"
|
||||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||||
"github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate"
|
"github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate"
|
||||||
|
@ -51,6 +51,7 @@ type xdsControllerTestSuite struct {
|
||||||
leafCancels *LeafCancels
|
leafCancels *LeafCancels
|
||||||
leafCertEvents chan controller.Event
|
leafCertEvents chan controller.Event
|
||||||
signer *leafcert.TestSigner
|
signer *leafcert.TestSigner
|
||||||
|
tenancies []*pbresource.Tenancy
|
||||||
|
|
||||||
fooProxyStateTemplate *pbresource.Resource
|
fooProxyStateTemplate *pbresource.Resource
|
||||||
barProxyStateTemplate *pbresource.Resource
|
barProxyStateTemplate *pbresource.Resource
|
||||||
|
@ -69,7 +70,7 @@ type xdsControllerTestSuite struct {
|
||||||
|
|
||||||
func (suite *xdsControllerTestSuite) SetupTest() {
|
func (suite *xdsControllerTestSuite) SetupTest() {
|
||||||
suite.ctx = testutil.TestContext(suite.T())
|
suite.ctx = testutil.TestContext(suite.T())
|
||||||
resourceClient := svctest.RunResourceService(suite.T(), types.Register, catalog.RegisterTypes)
|
resourceClient := svctest.RunResourceServiceWithTenancies(suite.T(), types.Register, catalog.RegisterTypes)
|
||||||
suite.runtime = controller.Runtime{Client: resourceClient, Logger: testutil.Logger(suite.T())}
|
suite.runtime = controller.Runtime{Client: resourceClient, Logger: testutil.Logger(suite.T())}
|
||||||
suite.client = resourcetest.NewClient(resourceClient)
|
suite.client = resourcetest.NewClient(resourceClient)
|
||||||
suite.fetcher = mockFetcher
|
suite.fetcher = mockFetcher
|
||||||
|
@ -99,6 +100,8 @@ func (suite *xdsControllerTestSuite) SetupTest() {
|
||||||
leafCertEvents: suite.leafCertEvents,
|
leafCertEvents: suite.leafCertEvents,
|
||||||
datacenter: "dc1",
|
datacenter: "dc1",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suite.tenancies = resourcetest.TestTenancies()
|
||||||
}
|
}
|
||||||
|
|
||||||
func mockFetcher() (*pbproxystate.TrustBundle, error) {
|
func mockFetcher() (*pbproxystate.TrustBundle, error) {
|
||||||
|
@ -112,8 +115,12 @@ func mockFetcher() (*pbproxystate.TrustBundle, error) {
|
||||||
|
|
||||||
// This test ensures when a ProxyState is deleted, it is no longer tracked in the mappers.
|
// This test ensures when a ProxyState is deleted, it is no longer tracked in the mappers.
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_NoProxyStateTemplate() {
|
func (suite *xdsControllerTestSuite) TestReconcile_NoProxyStateTemplate() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Track the id of a non-existent ProxyStateTemplate.
|
// Track the id of a non-existent ProxyStateTemplate.
|
||||||
proxyStateTemplateId := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "not-found").ID()
|
proxyStateTemplateId := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "not-found").WithTenancy(tenancy).ID()
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(proxyStateTemplateId))
|
||||||
|
|
||||||
suite.mapper.TrackItem(proxyStateTemplateId, []resource.ReferenceOrID{})
|
suite.mapper.TrackItem(proxyStateTemplateId, []resource.ReferenceOrID{})
|
||||||
suite.leafMapper.TrackItem(proxyStateTemplateId, []resource.ReferenceOrID{})
|
suite.leafMapper.TrackItem(proxyStateTemplateId, []resource.ReferenceOrID{})
|
||||||
require.False(suite.T(), suite.mapper.IsEmpty())
|
require.False(suite.T(), suite.mapper.IsEmpty())
|
||||||
|
@ -128,16 +135,21 @@ func (suite *xdsControllerTestSuite) TestReconcile_NoProxyStateTemplate() {
|
||||||
// Assert that nothing is tracked in the endpoints mapper.
|
// Assert that nothing is tracked in the endpoints mapper.
|
||||||
require.True(suite.T(), suite.mapper.IsEmpty())
|
require.True(suite.T(), suite.mapper.IsEmpty())
|
||||||
require.True(suite.T(), suite.leafMapper.IsEmpty())
|
require.True(suite.T(), suite.leafMapper.IsEmpty())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test ensures if the controller was previously tracking a ProxyStateTemplate, and now that proxy has
|
// This test ensures if the controller was previously tracking a ProxyStateTemplate, and now that proxy has
|
||||||
// disconnected from this server, it's ignored and removed from the mapper.
|
// disconnected from this server, it's ignored and removed from the mapper.
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_RemoveTrackingProxiesNotConnectedToServer() {
|
func (suite *xdsControllerTestSuite) TestReconcile_RemoveTrackingProxiesNotConnectedToServer() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Store the initial ProxyStateTemplate and track it in the mapper.
|
// Store the initial ProxyStateTemplate and track it in the mapper.
|
||||||
proxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").
|
proxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").
|
||||||
WithData(suite.T(), &pbmesh.ProxyStateTemplate{}).
|
WithData(suite.T(), &pbmesh.ProxyStateTemplate{}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(proxyStateTemplate.Id))
|
||||||
|
|
||||||
suite.mapper.TrackItem(proxyStateTemplate.Id, []resource.ReferenceOrID{})
|
suite.mapper.TrackItem(proxyStateTemplate.Id, []resource.ReferenceOrID{})
|
||||||
|
|
||||||
// Simulate the proxy disconnecting from this server. The resource still exists, but this proxy might be connected
|
// Simulate the proxy disconnecting from this server. The resource still exists, but this proxy might be connected
|
||||||
|
@ -152,16 +164,18 @@ func (suite *xdsControllerTestSuite) TestReconcile_RemoveTrackingProxiesNotConne
|
||||||
|
|
||||||
// Assert that nothing is tracked in the mapper.
|
// Assert that nothing is tracked in the mapper.
|
||||||
require.True(suite.T(), suite.mapper.IsEmpty())
|
require.True(suite.T(), suite.mapper.IsEmpty())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test sets up the updater to return an error when calling PushChange, and ensures the status is set
|
// This test sets up the updater to return an error when calling PushChange, and ensures the status is set
|
||||||
// correctly.
|
// correctly.
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_PushChangeError() {
|
func (suite *xdsControllerTestSuite) TestReconcile_PushChangeError() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Have the mock simulate an error from the PushChange call.
|
// Have the mock simulate an error from the PushChange call.
|
||||||
suite.updater.pushChangeError = true
|
suite.updater.pushChangeError = true
|
||||||
|
|
||||||
// Setup a happy path scenario.
|
// Setup a happy path scenario.
|
||||||
suite.setupFooProxyStateTemplateWithReferences()
|
suite.setupFooProxyStateTemplateWithReferences(tenancy)
|
||||||
|
|
||||||
// Run the reconcile.
|
// Run the reconcile.
|
||||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||||
|
@ -171,14 +185,16 @@ func (suite *xdsControllerTestSuite) TestReconcile_PushChangeError() {
|
||||||
|
|
||||||
// Assert on the status reflecting endpoint not found.
|
// Assert on the status reflecting endpoint not found.
|
||||||
suite.client.RequireStatusCondition(suite.T(), suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionRejectedPushChangeFailed(status.KeyFromID(suite.fooProxyStateTemplate.Id)))
|
suite.client.RequireStatusCondition(suite.T(), suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionRejectedPushChangeFailed(status.KeyFromID(suite.fooProxyStateTemplate.Id)))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test sets up a ProxyStateTemplate that references a ServiceEndpoints that doesn't exist, and ensures the
|
// This test sets up a ProxyStateTemplate that references a ServiceEndpoints that doesn't exist, and ensures the
|
||||||
// status is correct.
|
// status is correct.
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_MissingEndpoint() {
|
func (suite *xdsControllerTestSuite) TestReconcile_MissingEndpoint() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Set fooProxyStateTemplate with a reference to fooEndpoints, without storing fooEndpoints so the controller should
|
// Set fooProxyStateTemplate with a reference to fooEndpoints, without storing fooEndpoints so the controller should
|
||||||
// notice it's missing.
|
// notice it's missing.
|
||||||
fooEndpointsId := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service").WithTenancy(resource.DefaultNamespacedTenancy()).ID()
|
fooEndpointsId := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service").WithTenancy(tenancy).ID()
|
||||||
fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef)
|
fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef)
|
||||||
fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{
|
fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{
|
||||||
Id: fooEndpointsId,
|
Id: fooEndpointsId,
|
||||||
|
@ -190,8 +206,11 @@ func (suite *xdsControllerTestSuite) TestReconcile_MissingEndpoint() {
|
||||||
RequiredEndpoints: fooRequiredEndpoints,
|
RequiredEndpoints: fooRequiredEndpoints,
|
||||||
ProxyState: &pbmesh.ProxyState{},
|
ProxyState: &pbmesh.ProxyState{},
|
||||||
}).
|
}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooProxyStateTemplate.Id))
|
||||||
|
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id)
|
suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id)
|
||||||
})
|
})
|
||||||
|
@ -204,18 +223,20 @@ func (suite *xdsControllerTestSuite) TestReconcile_MissingEndpoint() {
|
||||||
|
|
||||||
// Assert on the status reflecting endpoint not found.
|
// Assert on the status reflecting endpoint not found.
|
||||||
suite.client.RequireStatusCondition(suite.T(), fooProxyStateTemplate.Id, ControllerName, status.ConditionRejectedErrorReadingEndpoints(status.KeyFromID(fooEndpointsId), "rpc error: code = NotFound desc = resource not found"))
|
suite.client.RequireStatusCondition(suite.T(), fooProxyStateTemplate.Id, ControllerName, status.ConditionRejectedErrorReadingEndpoints(status.KeyFromID(fooEndpointsId), "rpc error: code = NotFound desc = resource not found"))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test sets up a ProxyStateTemplate that references a ServiceEndpoints that can't be read correctly, and
|
// This test sets up a ProxyStateTemplate that references a ServiceEndpoints that can't be read correctly, and
|
||||||
// checks the status is correct.
|
// checks the status is correct.
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_ReadEndpointError() {
|
func (suite *xdsControllerTestSuite) TestReconcile_ReadEndpointError() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
badID := &pbresource.ID{
|
badID := &pbresource.ID{
|
||||||
Type: &pbresource.Type{
|
Type: &pbresource.Type{
|
||||||
Group: "not",
|
Group: "not",
|
||||||
Kind: "found",
|
Kind: "found",
|
||||||
GroupVersion: "vfake",
|
GroupVersion: "vfake",
|
||||||
},
|
},
|
||||||
Tenancy: &pbresource.Tenancy{Namespace: "default", Partition: "default", PeerName: "local"},
|
Tenancy: tenancy,
|
||||||
}
|
}
|
||||||
fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef)
|
fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef)
|
||||||
fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{
|
fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{
|
||||||
|
@ -228,8 +249,11 @@ func (suite *xdsControllerTestSuite) TestReconcile_ReadEndpointError() {
|
||||||
RequiredEndpoints: fooRequiredEndpoints,
|
RequiredEndpoints: fooRequiredEndpoints,
|
||||||
ProxyState: &pbmesh.ProxyState{},
|
ProxyState: &pbmesh.ProxyState{},
|
||||||
}).
|
}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooProxyStateTemplate.Id))
|
||||||
|
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id)
|
suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id)
|
||||||
})
|
})
|
||||||
|
@ -245,15 +269,17 @@ func (suite *xdsControllerTestSuite) TestReconcile_ReadEndpointError() {
|
||||||
status.KeyFromID(badID),
|
status.KeyFromID(badID),
|
||||||
"rpc error: code = InvalidArgument desc = id.name invalid: a resource name must consist of lower case alphanumeric characters or '-', must start and end with an alphanumeric character and be less than 64 characters, got: \"\"",
|
"rpc error: code = InvalidArgument desc = id.name invalid: a resource name must consist of lower case alphanumeric characters or '-', must start and end with an alphanumeric character and be less than 64 characters, got: \"\"",
|
||||||
))
|
))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test is a happy path creation test to make sure pbproxystate.Endpoints are created in the computed
|
// This test is a happy path creation test to make sure pbproxystate.Endpoints are created in the computed
|
||||||
// pbmesh.ProxyState from the RequiredEndpoints references. More specific translations between endpoint references
|
// pbmesh.ProxyState from the RequiredEndpoints references. More specific translations between endpoint references
|
||||||
// and pbproxystate.Endpoints are unit tested in endpoint_builder.go.
|
// and pbproxystate.Endpoints are unit tested in endpoint_builder.go.
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateComputesEndpoints() {
|
func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateComputesEndpoints() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Set up fooEndpoints and fooProxyStateTemplate with a reference to fooEndpoints and store them in the state store.
|
// Set up fooEndpoints and fooProxyStateTemplate with a reference to fooEndpoints and store them in the state store.
|
||||||
// This setup saves expected values in the suite so it can be asserted against later.
|
// This setup saves expected values in the suite so it can be asserted against later.
|
||||||
suite.setupFooProxyStateTemplateWithReferences()
|
suite.setupFooProxyStateTemplateWithReferences(tenancy)
|
||||||
|
|
||||||
// Run the reconcile.
|
// Run the reconcile.
|
||||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||||
|
@ -267,12 +293,14 @@ func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateComputesEnd
|
||||||
// Assert that the endpoints computed in the controller matches the expected endpoints.
|
// Assert that the endpoints computed in the controller matches the expected endpoints.
|
||||||
actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name)
|
actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name)
|
||||||
prototest.AssertDeepEqual(suite.T(), suite.expectedFooProxyStateEndpoints, actualEndpoints)
|
prototest.AssertDeepEqual(suite.T(), suite.expectedFooProxyStateEndpoints, actualEndpoints)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateComputesLeafCerts() {
|
func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateComputesLeafCerts() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Set up fooEndpoints and fooProxyStateTemplate with a reference to fooEndpoints and store them in the state store.
|
// Set up fooEndpoints and fooProxyStateTemplate with a reference to fooEndpoints and store them in the state store.
|
||||||
// This setup saves expected values in the suite so it can be asserted against later.
|
// This setup saves expected values in the suite so it can be asserted against later.
|
||||||
suite.setupFooProxyStateTemplateWithReferences()
|
suite.setupFooProxyStateTemplateWithReferences(tenancy)
|
||||||
|
|
||||||
// Run the reconcile.
|
// Run the reconcile.
|
||||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||||
|
@ -287,17 +315,19 @@ func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateComputesLea
|
||||||
actualLeafs := suite.updater.GetLeafs(suite.fooProxyStateTemplate.Id.Name)
|
actualLeafs := suite.updater.GetLeafs(suite.fooProxyStateTemplate.Id.Name)
|
||||||
|
|
||||||
for k, l := range actualLeafs {
|
for k, l := range actualLeafs {
|
||||||
pem, _ := pem.Decode([]byte(l.Cert))
|
pemDecode, _ := pem.Decode([]byte(l.Cert))
|
||||||
cert, err := x509.ParseCertificate(pem.Bytes)
|
cert, err := x509.ParseCertificate(pemDecode.Bytes)
|
||||||
require.NoError(suite.T(), err)
|
require.NoError(suite.T(), err)
|
||||||
require.Equal(suite.T(), cert.URIs[0].String(), suite.expectedFooProxyStateSpiffes[k])
|
require.Equal(suite.T(), cert.URIs[0].String(), suite.expectedFooProxyStateSpiffes[k])
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test is a happy path creation test to make sure pbproxystate.Template.TrustBundles are created in the computed
|
// This test is a happy path creation test to make sure pbproxystate.Template.TrustBundles are created in the computed
|
||||||
// pbmesh.ProxyState from the TrustBundleFetcher.
|
// pbmesh.ProxyState from the TrustBundleFetcher.
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateSetsTrustBundles() {
|
func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateSetsTrustBundles() {
|
||||||
suite.setupFooProxyStateTemplateWithReferences()
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
|
suite.setupFooProxyStateTemplateWithReferences(tenancy)
|
||||||
|
|
||||||
// Run the reconcile.
|
// Run the reconcile.
|
||||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||||
|
@ -311,6 +341,7 @@ func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateSetsTrustBu
|
||||||
// Assert that the endpoints computed in the controller matches the expected endpoints.
|
// Assert that the endpoints computed in the controller matches the expected endpoints.
|
||||||
actualTrustBundle := suite.updater.GetTrustBundle(suite.fooProxyStateTemplate.Id.Name)
|
actualTrustBundle := suite.updater.GetTrustBundle(suite.fooProxyStateTemplate.Id.Name)
|
||||||
prototest.AssertDeepEqual(suite.T(), suite.expectedTrustBundle, actualTrustBundle)
|
prototest.AssertDeepEqual(suite.T(), suite.expectedTrustBundle, actualTrustBundle)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test is a happy path creation test that calls reconcile multiple times with a more complex setup. This
|
// This test is a happy path creation test that calls reconcile multiple times with a more complex setup. This
|
||||||
|
@ -318,9 +349,10 @@ func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateSetsTrustBu
|
||||||
// stored in the state store. So this test ensures that between multiple reconciles the correct ProxyStates are
|
// stored in the state store. So this test ensures that between multiple reconciles the correct ProxyStates are
|
||||||
// computed for each ProxyStateTemplate.
|
// computed for each ProxyStateTemplate.
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_MultipleProxyStateTemplatesComputesMultipleEndpoints() {
|
func (suite *xdsControllerTestSuite) TestReconcile_MultipleProxyStateTemplatesComputesMultipleEndpoints() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Set up fooProxyStateTemplate and barProxyStateTemplate and their associated resources and store them. Resources
|
// Set up fooProxyStateTemplate and barProxyStateTemplate and their associated resources and store them. Resources
|
||||||
// and expected results are stored in the suite to assert against.
|
// and expected results are stored in the suite to assert against.
|
||||||
suite.setupFooBarProxyStateTemplateAndEndpoints()
|
suite.setupFooBarProxyStateTemplateAndEndpoints(tenancy)
|
||||||
|
|
||||||
// Reconcile the fooProxyStateTemplate.
|
// Reconcile the fooProxyStateTemplate.
|
||||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||||
|
@ -347,17 +379,19 @@ func (suite *xdsControllerTestSuite) TestReconcile_MultipleProxyStateTemplatesCo
|
||||||
// Assert that the endpoints computed in the controller matches the expected endpoints.
|
// Assert that the endpoints computed in the controller matches the expected endpoints.
|
||||||
actualBarEndpoints := suite.updater.GetEndpoints(suite.barProxyStateTemplate.Id.Name)
|
actualBarEndpoints := suite.updater.GetEndpoints(suite.barProxyStateTemplate.Id.Name)
|
||||||
prototest.AssertDeepEqual(suite.T(), suite.expectedBarProxyStateEndpoints, actualBarEndpoints)
|
prototest.AssertDeepEqual(suite.T(), suite.expectedBarProxyStateEndpoints, actualBarEndpoints)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up a full controller, and tests that reconciles are getting triggered for the events it should.
|
// Sets up a full controller, and tests that reconciles are getting triggered for the events it should.
|
||||||
func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateEndpointReferences() {
|
func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateEndpointReferences() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Run the controller manager.
|
// Run the controller manager.
|
||||||
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
||||||
mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1"))
|
mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1"))
|
||||||
mgr.SetRaftLeader(true)
|
mgr.SetRaftLeader(true)
|
||||||
go mgr.Run(suite.ctx)
|
go mgr.Run(suite.ctx)
|
||||||
|
|
||||||
suite.setupFooProxyStateTemplateWithReferences()
|
suite.setupFooProxyStateTemplateWithReferences(tenancy)
|
||||||
|
|
||||||
// Assert that the expected ProxyState matches the actual ProxyState that PushChange was called with. This needs to
|
// Assert that the expected ProxyState matches the actual ProxyState that PushChange was called with. This needs to
|
||||||
// be in a retry block unlike the Reconcile tests because the controller triggers asynchronously.
|
// be in a retry block unlike the Reconcile tests because the controller triggers asynchronously.
|
||||||
|
@ -371,7 +405,7 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateEndpointRefe
|
||||||
|
|
||||||
// Now, update the endpoint to be unhealthy. This will ensure the controller is getting triggered on changes to this
|
// Now, update the endpoint to be unhealthy. This will ensure the controller is getting triggered on changes to this
|
||||||
// endpoint that it should be tracking, even when the ProxyStateTemplate does not change.
|
// endpoint that it should be tracking, even when the ProxyStateTemplate does not change.
|
||||||
resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service").
|
svc := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service").
|
||||||
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
||||||
{
|
{
|
||||||
Ports: map[string]*pbcatalog.WorkloadPort{
|
Ports: map[string]*pbcatalog.WorkloadPort{
|
||||||
|
@ -394,8 +428,11 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateEndpointRefe
|
||||||
},
|
},
|
||||||
}}).
|
}}).
|
||||||
WithOwner(suite.fooService.Id).
|
WithOwner(suite.fooService.Id).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(svc.Id))
|
||||||
|
|
||||||
// Wait for the endpoint to be written.
|
// Wait for the endpoint to be written.
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
suite.client.RequireVersionChanged(suite.T(), suite.fooEndpoints.Id, suite.fooEndpoints.Version)
|
suite.client.RequireVersionChanged(suite.T(), suite.fooEndpoints.Id, suite.fooEndpoints.Version)
|
||||||
|
@ -417,8 +454,11 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateEndpointRefe
|
||||||
// now tracks the newly added endpoint.
|
// now tracks the newly added endpoint.
|
||||||
secondService := resourcetest.Resource(pbcatalog.ServiceType, "second-service").
|
secondService := resourcetest.Resource(pbcatalog.ServiceType, "second-service").
|
||||||
WithData(suite.T(), &pbcatalog.Service{}).
|
WithData(suite.T(), &pbcatalog.Service{}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(secondService.Id))
|
||||||
|
|
||||||
secondEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "second-service").
|
secondEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "second-service").
|
||||||
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
||||||
{
|
{
|
||||||
|
@ -441,8 +481,11 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateEndpointRefe
|
||||||
},
|
},
|
||||||
}}).
|
}}).
|
||||||
WithOwner(secondService.Id).
|
WithOwner(secondService.Id).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(secondEndpoints.Id))
|
||||||
|
|
||||||
// Update the endpoint references on the fooProxyStateTemplate.
|
// Update the endpoint references on the fooProxyStateTemplate.
|
||||||
suite.fooEndpointRefs["test-cluster-2"] = &pbproxystate.EndpointRef{
|
suite.fooEndpointRefs["test-cluster-2"] = &pbproxystate.EndpointRef{
|
||||||
Id: secondEndpoints.Id,
|
Id: secondEndpoints.Id,
|
||||||
|
@ -456,8 +499,11 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateEndpointRefe
|
||||||
ProxyState: &pbmesh.ProxyState{},
|
ProxyState: &pbmesh.ProxyState{},
|
||||||
RequiredLeafCertificates: suite.fooLeafRefs,
|
RequiredLeafCertificates: suite.fooLeafRefs,
|
||||||
}).
|
}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooProxyStateTemplate.Id))
|
||||||
|
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
suite.client.RequireVersionChanged(r, fooProxyStateTemplate.Id, oldVersion)
|
suite.client.RequireVersionChanged(r, fooProxyStateTemplate.Id, oldVersion)
|
||||||
})
|
})
|
||||||
|
@ -494,18 +540,20 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateEndpointRefe
|
||||||
prototest.AssertDeepEqual(r, suite.expectedFooProxyStateEndpoints, actualEndpoints)
|
prototest.AssertDeepEqual(r, suite.expectedFooProxyStateEndpoints, actualEndpoints)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up a full controller, and tests that reconciles are getting triggered for the leaf cert events it should.
|
// Sets up a full controller, and tests that reconciles are getting triggered for the leaf cert events it should.
|
||||||
// This test ensures when a CA is updated, the controller is triggered to update the leaf cert when it changes.
|
// This test ensures when a CA is updated, the controller is triggered to update the leaf cert when it changes.
|
||||||
func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateDeleteLeafReferences() {
|
func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateDeleteLeafReferences() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Run the controller manager.
|
// Run the controller manager.
|
||||||
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
||||||
mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1"))
|
mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1"))
|
||||||
mgr.SetRaftLeader(true)
|
mgr.SetRaftLeader(true)
|
||||||
go mgr.Run(suite.ctx)
|
go mgr.Run(suite.ctx)
|
||||||
|
|
||||||
suite.setupFooProxyStateTemplateWithReferences()
|
suite.setupFooProxyStateTemplateWithReferences(tenancy)
|
||||||
leafCertRef := suite.fooLeafRefs["foo-workload-identity"]
|
leafCertRef := suite.fooLeafRefs["foo-workload-identity"]
|
||||||
fooLeafResRef := leafResourceRef(leafCertRef.Name, leafCertRef.Namespace, leafCertRef.Partition)
|
fooLeafResRef := leafResourceRef(leafCertRef.Name, leafCertRef.Namespace, leafCertRef.Partition)
|
||||||
|
|
||||||
|
@ -524,8 +572,8 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateDeleteLeafRe
|
||||||
// Assert that the leafs computed in the controller matches the expected leafs.
|
// Assert that the leafs computed in the controller matches the expected leafs.
|
||||||
require.Len(r, actualLeafs, 1)
|
require.Len(r, actualLeafs, 1)
|
||||||
for k, l := range actualLeafs {
|
for k, l := range actualLeafs {
|
||||||
pem, _ := pem.Decode([]byte(l.Cert))
|
pemDecode, _ := pem.Decode([]byte(l.Cert))
|
||||||
cert, err := x509.ParseCertificate(pem.Bytes)
|
cert, err := x509.ParseCertificate(pemDecode.Bytes)
|
||||||
oldLeaf = cert
|
oldLeaf = cert
|
||||||
require.NoError(r, err)
|
require.NoError(r, err)
|
||||||
require.Equal(r, cert.URIs[0].String(), suite.expectedFooProxyStateSpiffes[k])
|
require.Equal(r, cert.URIs[0].String(), suite.expectedFooProxyStateSpiffes[k])
|
||||||
|
@ -541,8 +589,8 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateDeleteLeafRe
|
||||||
actualLeafs := suite.updater.GetLeafs(suite.fooProxyStateTemplate.Id.Name)
|
actualLeafs := suite.updater.GetLeafs(suite.fooProxyStateTemplate.Id.Name)
|
||||||
require.Len(r, actualLeafs, 1)
|
require.Len(r, actualLeafs, 1)
|
||||||
for k, l := range actualLeafs {
|
for k, l := range actualLeafs {
|
||||||
pem, _ := pem.Decode([]byte(l.Cert))
|
pemDecode, _ := pem.Decode([]byte(l.Cert))
|
||||||
cert, err := x509.ParseCertificate(pem.Bytes)
|
cert, err := x509.ParseCertificate(pemDecode.Bytes)
|
||||||
// Ensure the leaf was actually updated by checking that the leaf we just got is different from the old leaf.
|
// Ensure the leaf was actually updated by checking that the leaf we just got is different from the old leaf.
|
||||||
require.NotEqual(r, oldLeaf.Raw, cert.Raw)
|
require.NotEqual(r, oldLeaf.Raw, cert.Raw)
|
||||||
require.NoError(r, err)
|
require.NoError(r, err)
|
||||||
|
@ -563,8 +611,11 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateDeleteLeafRe
|
||||||
ProxyState: &pbmesh.ProxyState{},
|
ProxyState: &pbmesh.ProxyState{},
|
||||||
RequiredLeafCertificates: suite.fooLeafRefs,
|
RequiredLeafCertificates: suite.fooLeafRefs,
|
||||||
}).
|
}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooProxyStateTemplate.Id))
|
||||||
|
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
suite.client.RequireVersionChanged(r, fooProxyStateTemplate.Id, oldVersion)
|
suite.client.RequireVersionChanged(r, fooProxyStateTemplate.Id, oldVersion)
|
||||||
})
|
})
|
||||||
|
@ -574,18 +625,20 @@ func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateDeleteLeafRe
|
||||||
_, ok := suite.leafCancels.Get(keyFromReference(fooLeafResRef))
|
_, ok := suite.leafCancels.Get(keyFromReference(fooLeafResRef))
|
||||||
require.False(r, ok)
|
require.False(r, ok)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up a full controller, and tests that reconciles are getting triggered for the leaf cert events it should.
|
// Sets up a full controller, and tests that reconciles are getting triggered for the leaf cert events it should.
|
||||||
// This test ensures that when a ProxyStateTemplate is deleted, the leaf watches are cancelled.
|
// This test ensures that when a ProxyStateTemplate is deleted, the leaf watches are cancelled.
|
||||||
func (suite *xdsControllerTestSuite) TestController_ComputeLeafReferencesDeletePST() {
|
func (suite *xdsControllerTestSuite) TestController_ComputeLeafReferencesDeletePST() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Run the controller manager.
|
// Run the controller manager.
|
||||||
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
||||||
mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1"))
|
mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1"))
|
||||||
mgr.SetRaftLeader(true)
|
mgr.SetRaftLeader(true)
|
||||||
go mgr.Run(suite.ctx)
|
go mgr.Run(suite.ctx)
|
||||||
|
|
||||||
suite.setupFooProxyStateTemplateWithReferences()
|
suite.setupFooProxyStateTemplateWithReferences(tenancy)
|
||||||
leafCertRef := suite.fooLeafRefs["foo-workload-identity"]
|
leafCertRef := suite.fooLeafRefs["foo-workload-identity"]
|
||||||
fooLeafResRef := leafResourceRef(leafCertRef.Name, leafCertRef.Namespace, leafCertRef.Partition)
|
fooLeafResRef := leafResourceRef(leafCertRef.Name, leafCertRef.Namespace, leafCertRef.Partition)
|
||||||
|
|
||||||
|
@ -601,8 +654,8 @@ func (suite *xdsControllerTestSuite) TestController_ComputeLeafReferencesDeleteP
|
||||||
// Assert that the leafs computed in the controller matches the expected leafs.
|
// Assert that the leafs computed in the controller matches the expected leafs.
|
||||||
require.Len(r, actualLeafs, 1)
|
require.Len(r, actualLeafs, 1)
|
||||||
for k, l := range actualLeafs {
|
for k, l := range actualLeafs {
|
||||||
pem, _ := pem.Decode([]byte(l.Cert))
|
pemDecode, _ := pem.Decode([]byte(l.Cert))
|
||||||
cert, err := x509.ParseCertificate(pem.Bytes)
|
cert, err := x509.ParseCertificate(pemDecode.Bytes)
|
||||||
require.NoError(r, err)
|
require.NoError(r, err)
|
||||||
require.Equal(r, cert.URIs[0].String(), suite.expectedFooProxyStateSpiffes[k])
|
require.Equal(r, cert.URIs[0].String(), suite.expectedFooProxyStateSpiffes[k])
|
||||||
// Check the state of the cancel functions map.
|
// Check the state of the cancel functions map.
|
||||||
|
@ -616,17 +669,20 @@ func (suite *xdsControllerTestSuite) TestController_ComputeLeafReferencesDeleteP
|
||||||
req := &pbresource.DeleteRequest{
|
req := &pbresource.DeleteRequest{
|
||||||
Id: suite.fooProxyStateTemplate.Id,
|
Id: suite.fooProxyStateTemplate.Id,
|
||||||
}
|
}
|
||||||
suite.client.Delete(suite.ctx, req)
|
_, err := suite.client.Delete(suite.ctx, req)
|
||||||
|
require.NoError(suite.T(), err)
|
||||||
|
|
||||||
// Ensure the leaf certificate watches were cancelled since we deleted the leaf reference.
|
// Ensure the leaf certificate watches were cancelled since we deleted the leaf reference.
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
_, ok := suite.leafCancels.Get(keyFromReference(fooLeafResRef))
|
_, ok := suite.leafCancels.Get(keyFromReference(fooLeafResRef))
|
||||||
require.False(r, ok)
|
require.False(r, ok)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets up a full controller, and tests that reconciles are getting triggered for the events it should.
|
// Sets up a full controller, and tests that reconciles are getting triggered for the events it should.
|
||||||
func (suite *xdsControllerTestSuite) TestController_ComputeEndpointForProxyConnections() {
|
func (suite *xdsControllerTestSuite) TestController_ComputeEndpointForProxyConnections() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
// Run the controller manager.
|
// Run the controller manager.
|
||||||
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
||||||
|
|
||||||
|
@ -636,7 +692,7 @@ func (suite *xdsControllerTestSuite) TestController_ComputeEndpointForProxyConne
|
||||||
|
|
||||||
// Set up fooEndpoints and fooProxyStateTemplate with a reference to fooEndpoints. These need to be stored
|
// Set up fooEndpoints and fooProxyStateTemplate with a reference to fooEndpoints. These need to be stored
|
||||||
// because the controller reconcile looks them up.
|
// because the controller reconcile looks them up.
|
||||||
suite.setupFooProxyStateTemplateWithReferences()
|
suite.setupFooProxyStateTemplateWithReferences(tenancy)
|
||||||
|
|
||||||
// Assert that the expected ProxyState matches the actual ProxyState that PushChange was called with. This needs to
|
// Assert that the expected ProxyState matches the actual ProxyState that PushChange was called with. This needs to
|
||||||
// be in a retry block unlike the Reconcile tests because the controller triggers asynchronously.
|
// be in a retry block unlike the Reconcile tests because the controller triggers asynchronously.
|
||||||
|
@ -654,6 +710,7 @@ func (suite *xdsControllerTestSuite) TestController_ComputeEndpointForProxyConne
|
||||||
// Wait for the proxy state template to be re-evaluated.
|
// Wait for the proxy state template to be re-evaluated.
|
||||||
proxyStateTemp := suite.client.WaitForNewVersion(suite.T(), suite.fooProxyStateTemplate.Id, suite.fooProxyStateTemplate.Version)
|
proxyStateTemp := suite.client.WaitForNewVersion(suite.T(), suite.fooProxyStateTemplate.Id, suite.fooProxyStateTemplate.Version)
|
||||||
require.NotNil(suite.T(), proxyStateTemp)
|
require.NotNil(suite.T(), proxyStateTemp)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup: fooProxyStateTemplate with:
|
// Setup: fooProxyStateTemplate with:
|
||||||
|
@ -661,11 +718,14 @@ func (suite *xdsControllerTestSuite) TestController_ComputeEndpointForProxyConne
|
||||||
// - a LeafCertificateRef to "foo-workload-identity"
|
// - a LeafCertificateRef to "foo-workload-identity"
|
||||||
//
|
//
|
||||||
// Saves all related resources to the suite so they can be looked up by the controller or modified if needed.
|
// Saves all related resources to the suite so they can be looked up by the controller or modified if needed.
|
||||||
func (suite *xdsControllerTestSuite) setupFooProxyStateTemplateWithReferences() {
|
func (suite *xdsControllerTestSuite) setupFooProxyStateTemplateWithReferences(tenancy *pbresource.Tenancy) {
|
||||||
fooService := resourcetest.Resource(pbcatalog.ServiceType, "foo-service").
|
fooService := resourcetest.Resource(pbcatalog.ServiceType, "foo-service").
|
||||||
WithData(suite.T(), &pbcatalog.Service{}).
|
WithData(suite.T(), &pbcatalog.Service{}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooService.Id))
|
||||||
|
|
||||||
fooEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service").
|
fooEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service").
|
||||||
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
||||||
{
|
{
|
||||||
|
@ -687,9 +747,12 @@ func (suite *xdsControllerTestSuite) setupFooProxyStateTemplateWithReferences()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}}).
|
}}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
WithOwner(fooService.Id).
|
WithOwner(fooService.Id).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooEndpoints.Id))
|
||||||
|
|
||||||
fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef)
|
fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef)
|
||||||
fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{
|
fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{
|
||||||
Id: fooEndpoints.Id,
|
Id: fooEndpoints.Id,
|
||||||
|
@ -707,8 +770,11 @@ func (suite *xdsControllerTestSuite) setupFooProxyStateTemplateWithReferences()
|
||||||
RequiredLeafCertificates: fooRequiredLeafs,
|
RequiredLeafCertificates: fooRequiredLeafs,
|
||||||
ProxyState: &pbmesh.ProxyState{},
|
ProxyState: &pbmesh.ProxyState{},
|
||||||
}).
|
}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooProxyStateTemplate.Id))
|
||||||
|
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id)
|
suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id)
|
||||||
})
|
})
|
||||||
|
@ -754,6 +820,14 @@ func (suite *xdsControllerTestSuite) setupFooProxyStateTemplateWithReferences()
|
||||||
suite.expectedFooProxyStateEndpoints = expectedFooProxyStateEndpoints
|
suite.expectedFooProxyStateEndpoints = expectedFooProxyStateEndpoints
|
||||||
suite.expectedTrustBundle = expectedTrustBundle
|
suite.expectedTrustBundle = expectedTrustBundle
|
||||||
suite.expectedFooProxyStateSpiffes = expectedFooLeafSpiffes
|
suite.expectedFooProxyStateSpiffes = expectedFooLeafSpiffes
|
||||||
|
|
||||||
|
suite.T().Cleanup(func() {
|
||||||
|
suite.fooEndpointRefs = make(map[string]*pbproxystate.EndpointRef)
|
||||||
|
suite.fooLeafRefs = make(map[string]*pbproxystate.LeafCertificateRef)
|
||||||
|
suite.expectedFooProxyStateEndpoints = make(map[string]*pbproxystate.Endpoints)
|
||||||
|
suite.expectedTrustBundle = make(map[string]*pbproxystate.TrustBundle)
|
||||||
|
suite.expectedFooProxyStateSpiffes = make(map[string]string)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup:
|
// Setup:
|
||||||
|
@ -761,11 +835,14 @@ func (suite *xdsControllerTestSuite) setupFooProxyStateTemplateWithReferences()
|
||||||
// - barProxyStateTemplate with an EndpointsRef to fooBarEndpoints.
|
// - barProxyStateTemplate with an EndpointsRef to fooBarEndpoints.
|
||||||
//
|
//
|
||||||
// Saves all related resources to the suite so they can be modified if needed.
|
// Saves all related resources to the suite so they can be modified if needed.
|
||||||
func (suite *xdsControllerTestSuite) setupFooBarProxyStateTemplateAndEndpoints() {
|
func (suite *xdsControllerTestSuite) setupFooBarProxyStateTemplateAndEndpoints(tenancy *pbresource.Tenancy) {
|
||||||
fooService := resourcetest.Resource(pbcatalog.ServiceType, "foo-service").
|
fooService := resourcetest.Resource(pbcatalog.ServiceType, "foo-service").
|
||||||
WithData(suite.T(), &pbcatalog.Service{}).
|
WithData(suite.T(), &pbcatalog.Service{}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooService.Id))
|
||||||
|
|
||||||
fooEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service").
|
fooEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service").
|
||||||
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
||||||
{
|
{
|
||||||
|
@ -788,12 +865,18 @@ func (suite *xdsControllerTestSuite) setupFooBarProxyStateTemplateAndEndpoints()
|
||||||
},
|
},
|
||||||
}}).
|
}}).
|
||||||
WithOwner(fooService.Id).
|
WithOwner(fooService.Id).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooEndpoints.Id))
|
||||||
|
|
||||||
fooBarService := resourcetest.Resource(pbcatalog.ServiceType, "foo-bar-service").
|
fooBarService := resourcetest.Resource(pbcatalog.ServiceType, "foo-bar-service").
|
||||||
WithData(suite.T(), &pbcatalog.Service{}).
|
WithData(suite.T(), &pbcatalog.Service{}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooBarService.Id))
|
||||||
|
|
||||||
fooBarEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-bar-service").
|
fooBarEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-bar-service").
|
||||||
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
||||||
{
|
{
|
||||||
|
@ -816,8 +899,11 @@ func (suite *xdsControllerTestSuite) setupFooBarProxyStateTemplateAndEndpoints()
|
||||||
},
|
},
|
||||||
}}).
|
}}).
|
||||||
WithOwner(fooBarService.Id).
|
WithOwner(fooBarService.Id).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooBarEndpoints.Id))
|
||||||
|
|
||||||
fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef)
|
fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef)
|
||||||
fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{
|
fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{
|
||||||
Id: fooEndpoints.Id,
|
Id: fooEndpoints.Id,
|
||||||
|
@ -841,8 +927,11 @@ func (suite *xdsControllerTestSuite) setupFooBarProxyStateTemplateAndEndpoints()
|
||||||
RequiredEndpoints: fooRequiredEndpoints,
|
RequiredEndpoints: fooRequiredEndpoints,
|
||||||
ProxyState: &pbmesh.ProxyState{},
|
ProxyState: &pbmesh.ProxyState{},
|
||||||
}).
|
}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(fooProxyStateTemplate.Id))
|
||||||
|
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id)
|
suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id)
|
||||||
})
|
})
|
||||||
|
@ -853,8 +942,11 @@ func (suite *xdsControllerTestSuite) setupFooBarProxyStateTemplateAndEndpoints()
|
||||||
RequiredEndpoints: barRequiredEndpoints,
|
RequiredEndpoints: barRequiredEndpoints,
|
||||||
ProxyState: &pbmesh.ProxyState{},
|
ProxyState: &pbmesh.ProxyState{},
|
||||||
}).
|
}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(barProxyStateTemplate.Id))
|
||||||
|
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
suite.client.RequireResourceExists(r, barProxyStateTemplate.Id)
|
suite.client.RequireResourceExists(r, barProxyStateTemplate.Id)
|
||||||
})
|
})
|
||||||
|
@ -935,9 +1027,17 @@ func (suite *xdsControllerTestSuite) setupFooBarProxyStateTemplateAndEndpoints()
|
||||||
suite.fooBarService = fooBarService
|
suite.fooBarService = fooBarService
|
||||||
suite.expectedFooProxyStateEndpoints = expectedFooProxyStateEndpoints
|
suite.expectedFooProxyStateEndpoints = expectedFooProxyStateEndpoints
|
||||||
suite.expectedBarProxyStateEndpoints = expectedBarProxyStateEndpoints
|
suite.expectedBarProxyStateEndpoints = expectedBarProxyStateEndpoints
|
||||||
|
|
||||||
|
suite.T().Cleanup(func() {
|
||||||
|
suite.barEndpointRefs = make(map[string]*pbproxystate.EndpointRef)
|
||||||
|
suite.fooEndpointRefs = make(map[string]*pbproxystate.EndpointRef)
|
||||||
|
suite.expectedFooProxyStateEndpoints = make(map[string]*pbproxystate.Endpoints)
|
||||||
|
suite.expectedBarProxyStateEndpoints = make(map[string]*pbproxystate.Endpoints)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_prevWatchesToCancel() {
|
func (suite *xdsControllerTestSuite) TestReconcile_prevWatchesToCancel() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
makeRef := func(names ...string) []*pbresource.Reference {
|
makeRef := func(names ...string) []*pbresource.Reference {
|
||||||
out := make([]*pbresource.Reference, len(names))
|
out := make([]*pbresource.Reference, len(names))
|
||||||
for i, name := range names {
|
for i, name := range names {
|
||||||
|
@ -948,7 +1048,7 @@ func (suite *xdsControllerTestSuite) TestReconcile_prevWatchesToCancel() {
|
||||||
GroupVersion: "v",
|
GroupVersion: "v",
|
||||||
Kind: "k",
|
Kind: "k",
|
||||||
},
|
},
|
||||||
Tenancy: &pbresource.Tenancy{},
|
Tenancy: tenancy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
|
@ -997,6 +1097,7 @@ func (suite *xdsControllerTestSuite) TestReconcile_prevWatchesToCancel() {
|
||||||
toCancel := prevWatchesToCancel(tc.old, convert(tc.new))
|
toCancel := prevWatchesToCancel(tc.old, convert(tc.new))
|
||||||
require.ElementsMatch(suite.T(), toCancel, tc.expect)
|
require.ElementsMatch(suite.T(), toCancel, tc.expect)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestXdsController(t *testing.T) {
|
func TestXdsController(t *testing.T) {
|
||||||
|
@ -1017,6 +1118,7 @@ func TestXdsController(t *testing.T) {
|
||||||
// rather than just endpoints, leaf certs, and trust bundles, the test also ensures
|
// rather than just endpoints, leaf certs, and trust bundles, the test also ensures
|
||||||
// side effects or change in scope to XDS controller are not introduce mistakenly.
|
// side effects or change in scope to XDS controller are not introduce mistakenly.
|
||||||
func (suite *xdsControllerTestSuite) TestReconcile_SidecarProxyGoldenFileInputs() {
|
func (suite *xdsControllerTestSuite) TestReconcile_SidecarProxyGoldenFileInputs() {
|
||||||
|
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||||
path := "../sidecarproxy/builder/testdata"
|
path := "../sidecarproxy/builder/testdata"
|
||||||
cases := []string{
|
cases := []string{
|
||||||
// destinations - please add in alphabetical order
|
// destinations - please add in alphabetical order
|
||||||
|
@ -1053,14 +1155,17 @@ func (suite *xdsControllerTestSuite) TestReconcile_SidecarProxyGoldenFileInputs(
|
||||||
|
|
||||||
// Destinations will need endpoint refs set up.
|
// Destinations will need endpoint refs set up.
|
||||||
if strings.Split(name, "/")[0] == "destination" && len(pst.ProxyState.Endpoints) == 0 {
|
if strings.Split(name, "/")[0] == "destination" && len(pst.ProxyState.Endpoints) == 0 {
|
||||||
suite.addRequiredEndpointsAndRefs(pst)
|
suite.addRequiredEndpointsAndRefs(pst, tenancy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the initial ProxyStateTemplate.
|
// Store the initial ProxyStateTemplate.
|
||||||
proxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").
|
proxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").
|
||||||
WithData(suite.T(), pst).
|
WithData(suite.T(), pst).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(proxyStateTemplate.Id))
|
||||||
|
|
||||||
// Check with resource service that it exists.
|
// Check with resource service that it exists.
|
||||||
retry.Run(suite.T(), func(r *retry.R) {
|
retry.Run(suite.T(), func(r *retry.R) {
|
||||||
suite.client.RequireResourceExists(r, proxyStateTemplate.Id)
|
suite.client.RequireResourceExists(r, proxyStateTemplate.Id)
|
||||||
|
@ -1095,9 +1200,10 @@ func (suite *xdsControllerTestSuite) TestReconcile_SidecarProxyGoldenFileInputs(
|
||||||
require.JSONEq(suite.T(), expected, actual)
|
require.JSONEq(suite.T(), expected, actual)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *xdsControllerTestSuite) addRequiredEndpointsAndRefs(pst *pbmesh.ProxyStateTemplate) {
|
func (suite *xdsControllerTestSuite) addRequiredEndpointsAndRefs(pst *pbmesh.ProxyStateTemplate, tenancy *pbresource.Tenancy) {
|
||||||
//get service data
|
//get service data
|
||||||
serviceData := &pbcatalog.Service{}
|
serviceData := &pbcatalog.Service{}
|
||||||
var vp uint32 = 7000
|
var vp uint32 = 7000
|
||||||
|
@ -1125,8 +1231,11 @@ func (suite *xdsControllerTestSuite) addRequiredEndpointsAndRefs(pst *pbmesh.Pro
|
||||||
// create service.
|
// create service.
|
||||||
svc := resourcetest.Resource(pbcatalog.ServiceType, svcName).
|
svc := resourcetest.Resource(pbcatalog.ServiceType, svcName).
|
||||||
WithData(suite.T(), &pbcatalog.Service{}).
|
WithData(suite.T(), &pbcatalog.Service{}).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(svc.Id))
|
||||||
|
|
||||||
// create endpoints with svc as owner.
|
// create endpoints with svc as owner.
|
||||||
eps := resourcetest.Resource(pbcatalog.ServiceEndpointsType, svcName).
|
eps := resourcetest.Resource(pbcatalog.ServiceEndpointsType, svcName).
|
||||||
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{
|
||||||
|
@ -1146,8 +1255,11 @@ func (suite *xdsControllerTestSuite) addRequiredEndpointsAndRefs(pst *pbmesh.Pro
|
||||||
},
|
},
|
||||||
}}).
|
}}).
|
||||||
WithOwner(svc.Id).
|
WithOwner(svc.Id).
|
||||||
|
WithTenancy(tenancy).
|
||||||
Write(suite.T(), suite.client)
|
Write(suite.T(), suite.client)
|
||||||
|
|
||||||
|
suite.T().Cleanup(suite.deleteResourceFunc(eps.Id))
|
||||||
|
|
||||||
// add to working list of required endpoints.
|
// add to working list of required endpoints.
|
||||||
requiredEps[clusterName] = &pbproxystate.EndpointRef{
|
requiredEps[clusterName] = &pbproxystate.EndpointRef{
|
||||||
Id: eps.Id,
|
Id: eps.Id,
|
||||||
|
@ -1167,3 +1279,21 @@ func JSONToProxyTemplate(t *testing.T, json []byte) *pbmesh.ProxyStateTemplate {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return proxyTemplate
|
return proxyTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *xdsControllerTestSuite) runTestCaseWithTenancies(testCase func(tenancy *pbresource.Tenancy)) {
|
||||||
|
for _, tenancy := range suite.tenancies {
|
||||||
|
suite.Run(suite.appendTenancyInfo(tenancy), func() {
|
||||||
|
testCase(tenancy)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *xdsControllerTestSuite) appendTenancyInfo(tenancy *pbresource.Tenancy) string {
|
||||||
|
return fmt.Sprintf("%s_Namespace_%s_Partition", tenancy.Namespace, tenancy.Partition)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *xdsControllerTestSuite) deleteResourceFunc(id *pbresource.ID) func() {
|
||||||
|
return func() {
|
||||||
|
suite.client.MustDelete(suite.T(), id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
package resourcetest
|
package resourcetest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/internal/resource"
|
"github.com/hashicorp/consul/internal/resource"
|
||||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue