From ab55603d51bda2ab741c4e3ddfbee2cfc2e5074c Mon Sep 17 00:00:00 2001 From: Jakub Dyszkiewicz Date: Mon, 23 Aug 2021 10:01:44 +0200 Subject: [PATCH] chore(kuma-cp) open CAProvider and MeshValidator for extensions (#2618) Signed-off-by: Jakub Dyszkiewicz --- pkg/core/bootstrap/bootstrap.go | 9 ++-- .../apis/mesh/mesh_manager_suite_test.go | 2 +- .../managers/apis/mesh/mesh_manager_test.go | 7 +-- pkg/core/managers/apis/mesh/mesh_validator.go | 45 ++++++++++++++----- pkg/core/runtime/builder.go | 30 +++++++++++++ pkg/core/runtime/runtime.go | 14 ++++++ pkg/plugins/runtime/k8s/plugin.go | 7 +-- pkg/test/runtime/runtime.go | 8 ++-- pkg/xds/server/components.go | 2 +- 9 files changed, 92 insertions(+), 32 deletions(-) diff --git a/pkg/core/bootstrap/bootstrap.go b/pkg/core/bootstrap/bootstrap.go index 632d824b1fd0..a5ab64c57f80 100644 --- a/pkg/core/bootstrap/bootstrap.go +++ b/pkg/core/bootstrap/bootstrap.go @@ -39,6 +39,7 @@ import ( "github.com/kumahq/kuma/pkg/metrics" metrics_store "github.com/kumahq/kuma/pkg/metrics/store" xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks" + "github.com/kumahq/kuma/pkg/xds/secrets" ) func buildRuntime(cfg kuma_cp.Config, closeCh <-chan struct{}) (core_runtime.Runtime, error) { @@ -77,6 +78,7 @@ func buildRuntime(cfg kuma_cp.Config, closeCh <-chan struct{}) (core_runtime.Run if err := initializeDNSResolver(cfg, builder); err != nil { return nil, err } + builder.WithMeshValidator(mesh_managers.NewMeshValidator(builder.CaManagers(), builder.ResourceStore())) if err := initializeResourceManager(cfg, builder); err != nil { return nil, err } @@ -94,6 +96,7 @@ func buildRuntime(cfg kuma_cp.Config, closeCh <-chan struct{}) (core_runtime.Run builder.WithEnvoyAdminClient(admin.NewEnvoyAdminClient(builder.ResourceManager(), builder.Config())) builder.WithAPIManager(customization.NewAPIList()) builder.WithXDSHooks(&xds_hooks.Hooks{}) + builder.WithCAProvider(secrets.NewCaProvider(builder.CaManagers())) builder.WithDpServer(server.NewDpServer(*cfg.DpServer, builder.Metrics())) builder.WithKDSContext(kds_context.DefaultContext(builder.ResourceManager(), cfg.Multizone.Zone.Name)) @@ -285,13 +288,9 @@ func initializeResourceManager(cfg kuma_cp.Config, builder *core_runtime.Builder defaultManager := core_manager.NewResourceManager(builder.ResourceStore()) customizableManager := core_manager.NewCustomizableResourceManager(defaultManager, nil) - meshValidator := mesh_managers.MeshValidator{ - CaManagers: builder.CaManagers(), - Store: builder.ResourceStore(), - } customizableManager.Customize( mesh.MeshType, - mesh_managers.NewMeshManager(builder.ResourceStore(), customizableManager, builder.CaManagers(), registry.Global(), meshValidator), + mesh_managers.NewMeshManager(builder.ResourceStore(), customizableManager, builder.CaManagers(), registry.Global(), builder.MeshValidator()), ) customizableManager.Customize( diff --git a/pkg/core/managers/apis/mesh/mesh_manager_suite_test.go b/pkg/core/managers/apis/mesh/mesh_manager_suite_test.go index 489705f2e625..e31db2cbd6aa 100644 --- a/pkg/core/managers/apis/mesh/mesh_manager_suite_test.go +++ b/pkg/core/managers/apis/mesh/mesh_manager_suite_test.go @@ -1,4 +1,4 @@ -package mesh +package mesh_test import ( "testing" diff --git a/pkg/core/managers/apis/mesh/mesh_manager_test.go b/pkg/core/managers/apis/mesh/mesh_manager_test.go index 97de521574fd..4d6f77e07b80 100644 --- a/pkg/core/managers/apis/mesh/mesh_manager_test.go +++ b/pkg/core/managers/apis/mesh/mesh_manager_test.go @@ -1,4 +1,4 @@ -package mesh +package mesh_test import ( "context" @@ -10,6 +10,7 @@ import ( mesh_proto "github.com/kumahq/kuma/api/mesh/v1alpha1" core_ca "github.com/kumahq/kuma/pkg/core/ca" "github.com/kumahq/kuma/pkg/core/datasource" + "github.com/kumahq/kuma/pkg/core/managers/apis/mesh" core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh" "github.com/kumahq/kuma/pkg/core/resources/apis/system" "github.com/kumahq/kuma/pkg/core/resources/manager" @@ -45,8 +46,8 @@ var _ = Describe("Mesh Manager", func() { } manager := manager.NewResourceManager(resStore) - validator := MeshValidator{CaManagers: caManagers, Store: resStore} - resManager = NewMeshManager(resStore, manager, caManagers, test_resources.Global(), validator) + validator := mesh.NewMeshValidator(caManagers, resStore) + resManager = mesh.NewMeshManager(resStore, manager, caManagers, test_resources.Global(), validator) }) Describe("Create()", func() { diff --git a/pkg/core/managers/apis/mesh/mesh_validator.go b/pkg/core/managers/apis/mesh/mesh_validator.go index 38310f4d8c7c..1156cd42f80f 100644 --- a/pkg/core/managers/apis/mesh/mesh_validator.go +++ b/pkg/core/managers/apis/mesh/mesh_validator.go @@ -7,27 +7,41 @@ import ( core_ca "github.com/kumahq/kuma/pkg/core/ca" core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh" - "github.com/kumahq/kuma/pkg/core/resources/store" + core_store "github.com/kumahq/kuma/pkg/core/resources/store" "github.com/kumahq/kuma/pkg/core/validators" ) -type MeshValidator struct { +type MeshValidator interface { + ValidateCreate(ctx context.Context, name string, resource *core_mesh.MeshResource) error + ValidateUpdate(ctx context.Context, previousMesh *core_mesh.MeshResource, newMesh *core_mesh.MeshResource) error + ValidateDelete(ctx context.Context, name string) error +} + +type meshValidator struct { CaManagers core_ca.Managers - Store store.ResourceStore + Store core_store.ResourceStore +} + +func NewMeshValidator(caManagers core_ca.Managers, store core_store.ResourceStore) MeshValidator { + return &meshValidator{ + CaManagers: caManagers, + Store: store, + } } -func (m *MeshValidator) ValidateCreate(ctx context.Context, name string, resource *core_mesh.MeshResource) error { - if err := m.validateMTLSBackends(ctx, name, resource); err != nil { +func (m *meshValidator) ValidateCreate(ctx context.Context, name string, resource *core_mesh.MeshResource) error { + if err := ValidateMTLSBackends(ctx, m.CaManagers, name, resource); err != nil { return err } return nil } -func (m *MeshValidator) validateMTLSBackends(ctx context.Context, name string, resource *core_mesh.MeshResource) error { +func ValidateMTLSBackends(ctx context.Context, caManagers core_ca.Managers, name string, resource *core_mesh.MeshResource) error { verr := validators.ValidationError{} path := validators.RootedAt("mtls").Field("backends") + for idx, backend := range resource.Spec.GetMtls().GetBackends() { - caManager, exist := m.CaManagers[backend.Type] + caManager, exist := caManagers[backend.Type] if !exist { verr.AddViolationAt(path.Index(idx).Field("type"), "could not find installed plugin for this type") return verr.OrNil() @@ -43,20 +57,27 @@ func (m *MeshValidator) validateMTLSBackends(ctx context.Context, name string, r return verr.OrNil() } -func (m *MeshValidator) ValidateUpdate(ctx context.Context, previousMesh *core_mesh.MeshResource, newMesh *core_mesh.MeshResource) error { +func (m *meshValidator) ValidateUpdate(ctx context.Context, previousMesh *core_mesh.MeshResource, newMesh *core_mesh.MeshResource) error { if err := m.validateMTLSBackendChange(previousMesh, newMesh); err != nil { return err } - if err := m.validateMTLSBackends(ctx, newMesh.Meta.GetName(), newMesh); err != nil { + if err := ValidateMTLSBackends(ctx, m.CaManagers, newMesh.Meta.GetName(), newMesh); err != nil { + return err + } + return nil +} + +func (m *meshValidator) ValidateDelete(ctx context.Context, name string) error { + if err := ValidateNoActiveDP(ctx, name, m.Store); err != nil { return err } return nil } -func (m *MeshValidator) ValidateDelete(ctx context.Context, name string) error { +func ValidateNoActiveDP(ctx context.Context, name string, store core_store.ResourceStore) error { dps := core_mesh.DataplaneResourceList{} validationErr := &validators.ValidationError{} - if err := m.Store.List(ctx, &dps, store.ListByMesh(name)); err != nil { + if err := store.List(ctx, &dps, core_store.ListByMesh(name)); err != nil { return errors.Wrap(err, "unable to list Dataplanes") } if len(dps.Items) != 0 { @@ -66,7 +87,7 @@ func (m *MeshValidator) ValidateDelete(ctx context.Context, name string) error { return nil } -func (m *MeshValidator) validateMTLSBackendChange(previousMesh *core_mesh.MeshResource, newMesh *core_mesh.MeshResource) error { +func (m *meshValidator) validateMTLSBackendChange(previousMesh *core_mesh.MeshResource, newMesh *core_mesh.MeshResource) error { verr := validators.ValidationError{} if previousMesh.MTLSEnabled() && newMesh.MTLSEnabled() && previousMesh.Spec.GetMtls().GetEnabledBackend() != newMesh.Spec.GetMtls().GetEnabledBackend() { verr.AddViolation("mtls.enabledBackend", "Changing CA when mTLS is enabled is forbidden. Disable mTLS first and then change the CA") diff --git a/pkg/core/runtime/builder.go b/pkg/core/runtime/builder.go index 0dd403243081..0845b8d98076 100644 --- a/pkg/core/runtime/builder.go +++ b/pkg/core/runtime/builder.go @@ -14,6 +14,7 @@ import ( config_manager "github.com/kumahq/kuma/pkg/core/config/manager" "github.com/kumahq/kuma/pkg/core/datasource" "github.com/kumahq/kuma/pkg/core/dns/lookup" + core_managers "github.com/kumahq/kuma/pkg/core/managers/apis/mesh" core_manager "github.com/kumahq/kuma/pkg/core/resources/manager" core_store "github.com/kumahq/kuma/pkg/core/resources/store" "github.com/kumahq/kuma/pkg/core/runtime/component" @@ -25,6 +26,7 @@ import ( kds_context "github.com/kumahq/kuma/pkg/kds/context" "github.com/kumahq/kuma/pkg/metrics" xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks" + "github.com/kumahq/kuma/pkg/xds/secrets" ) // BuilderContext provides access to Builder's interim state. @@ -44,7 +46,9 @@ type BuilderContext interface { EventReaderFactory() events.ListenerFactory APIManager() api_server.APIManager XDSHooks() *xds_hooks.Hooks + CAProvider() secrets.CaProvider DpServer() *dp_server.DpServer + MeshValidator() core_managers.MeshValidator KDSContext() *kds_context.Context } @@ -71,8 +75,10 @@ type Builder struct { erf events.ListenerFactory apim api_server.APIManager xdsh *xds_hooks.Hooks + cap secrets.CaProvider dps *dp_server.DpServer kdsctx *kds_context.Context + mv core_managers.MeshValidator shutdownCh <-chan struct{} *runtimeInfo } @@ -194,11 +200,21 @@ func (b *Builder) WithXDSHooks(xdsh *xds_hooks.Hooks) *Builder { return b } +func (b *Builder) WithCAProvider(cap secrets.CaProvider) *Builder { + b.cap = cap + return b +} + func (b *Builder) WithDpServer(dps *dp_server.DpServer) *Builder { b.dps = dps return b } +func (b *Builder) WithMeshValidator(mv core_managers.MeshValidator) *Builder { + b.mv = mv + return b +} + func (b *Builder) WithKDSContext(kdsctx *kds_context.Context) *Builder { b.kdsctx = kdsctx return b @@ -247,12 +263,18 @@ func (b *Builder) Build() (Runtime, error) { if b.xdsh == nil { return nil, errors.Errorf("XDSHooks has not been configured") } + if b.cap == nil { + return nil, errors.Errorf("CAProvider has not been configured") + } if b.dps == nil { return nil, errors.Errorf("DpServer has not been configured") } if b.kdsctx == nil { return nil, errors.Errorf("KDSContext has not been configured") } + if b.mv == nil { + return nil, errors.Errorf("MeshValidator has not been configured") + } return &runtime{ RuntimeInfo: b.runtimeInfo, RuntimeContext: &runtimeContext{ @@ -273,8 +295,10 @@ func (b *Builder) Build() (Runtime, error) { erf: b.erf, apim: b.apim, xdsh: b.xdsh, + cap: b.cap, dps: b.dps, kdsctx: b.kdsctx, + mv: b.mv, shutdownCh: b.shutdownCh, }, Manager: b.cm, @@ -335,12 +359,18 @@ func (b *Builder) APIManager() api_server.APIManager { func (b *Builder) XDSHooks() *xds_hooks.Hooks { return b.xdsh } +func (b *Builder) CAProvider() secrets.CaProvider { + return b.cap +} func (b *Builder) DpServer() *dp_server.DpServer { return b.dps } func (b *Builder) KDSContext() *kds_context.Context { return b.kdsctx } +func (b *Builder) MeshValidator() core_managers.MeshValidator { + return b.mv +} func (b *Builder) ShutdownCh() <-chan struct{} { return b.shutdownCh } diff --git a/pkg/core/runtime/runtime.go b/pkg/core/runtime/runtime.go index 9b25d037046d..2589fba7e3a9 100644 --- a/pkg/core/runtime/runtime.go +++ b/pkg/core/runtime/runtime.go @@ -10,6 +10,7 @@ import ( config_manager "github.com/kumahq/kuma/pkg/core/config/manager" "github.com/kumahq/kuma/pkg/core/datasource" "github.com/kumahq/kuma/pkg/core/dns/lookup" + core_managers "github.com/kumahq/kuma/pkg/core/managers/apis/mesh" core_manager "github.com/kumahq/kuma/pkg/core/resources/manager" core_store "github.com/kumahq/kuma/pkg/core/resources/store" "github.com/kumahq/kuma/pkg/core/runtime/component" @@ -21,6 +22,7 @@ import ( kds_context "github.com/kumahq/kuma/pkg/kds/context" "github.com/kumahq/kuma/pkg/metrics" xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks" + "github.com/kumahq/kuma/pkg/xds/secrets" ) // Runtime represents initialized application state. @@ -55,8 +57,10 @@ type RuntimeContext interface { EventReaderFactory() events.ListenerFactory APIInstaller() api_server.APIInstaller XDSHooks() *xds_hooks.Hooks + CAProvider() secrets.CaProvider DpServer() *dp_server.DpServer KDSContext() *kds_context.Context + MeshValidator() core_managers.MeshValidator ShutdownCh() <-chan struct{} } @@ -114,8 +118,10 @@ type runtimeContext struct { erf events.ListenerFactory apim api_server.APIInstaller xdsh *xds_hooks.Hooks + cap secrets.CaProvider dps *dp_server.DpServer kdsctx *kds_context.Context + mv core_managers.MeshValidator shutdownCh <-chan struct{} } @@ -190,6 +196,10 @@ func (rc *runtimeContext) DpServer() *dp_server.DpServer { return rc.dps } +func (rc *runtimeContext) CAProvider() secrets.CaProvider { + return rc.cap +} + func (rc *runtimeContext) XDSHooks() *xds_hooks.Hooks { return rc.xdsh } @@ -198,6 +208,10 @@ func (rc *runtimeContext) KDSContext() *kds_context.Context { return rc.kdsctx } +func (rc *runtimeContext) MeshValidator() core_managers.MeshValidator { + return rc.mv +} + func (rc *runtimeContext) ShutdownCh() <-chan struct{} { return rc.shutdownCh } diff --git a/pkg/plugins/runtime/k8s/plugin.go b/pkg/plugins/runtime/k8s/plugin.go index 7d68d9d24246..1c9795a6af83 100644 --- a/pkg/plugins/runtime/k8s/plugin.go +++ b/pkg/plugins/runtime/k8s/plugin.go @@ -11,7 +11,6 @@ import ( config_core "github.com/kumahq/kuma/pkg/config/core" "github.com/kumahq/kuma/pkg/core" - managers_mesh "github.com/kumahq/kuma/pkg/core/managers/apis/mesh" "github.com/kumahq/kuma/pkg/core/managers/apis/zone" core_plugins "github.com/kumahq/kuma/pkg/core/plugins" core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh" @@ -239,11 +238,7 @@ func addValidators(mgr kube_ctrl.Manager, rt core_runtime.Runtime, converter k8s handler := k8s_webhooks.NewValidatingWebhook(converter, core_registry.Global(), k8s_registry.Global(), rt.Config().Mode, rt.Config().Store.Kubernetes.SystemNamespace) composite.AddValidator(handler) - coreMeshValidator := managers_mesh.MeshValidator{ - CaManagers: rt.CaManagers(), - Store: rt.ResourceStore(), - } - k8sMeshValidator := k8s_webhooks.NewMeshValidatorWebhook(coreMeshValidator, converter, rt.ResourceManager()) + k8sMeshValidator := k8s_webhooks.NewMeshValidatorWebhook(rt.MeshValidator(), converter, rt.ResourceManager()) composite.AddValidator(k8sMeshValidator) coreZoneValidator := zone.Validator{Store: rt.ResourceStore()} diff --git a/pkg/test/runtime/runtime.go b/pkg/test/runtime/runtime.go index 25c372347592..b53cb66ea993 100644 --- a/pkg/test/runtime/runtime.go +++ b/pkg/test/runtime/runtime.go @@ -27,6 +27,7 @@ import ( leader_memory "github.com/kumahq/kuma/pkg/plugins/leader/memory" resources_memory "github.com/kumahq/kuma/pkg/plugins/resources/memory" xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks" + "github.com/kumahq/kuma/pkg/xds/secrets" ) var _ core_runtime.RuntimeInfo = &TestRuntimeInfo{} @@ -63,6 +64,7 @@ func BuilderFor(cfg kuma_cp.Config) (*core_runtime.Builder, error) { builder.WithSecretStore(secret_store.NewSecretStore(builder.ResourceStore())) builder.WithDataSourceLoader(datasource.NewDataSourceLoader(builder.ResourceManager())) + builder.WithMeshValidator(mesh_managers.NewMeshValidator(builder.CaManagers(), builder.ResourceStore())) rm := newResourceManager(builder) builder.WithResourceManager(rm). @@ -77,6 +79,7 @@ func BuilderFor(cfg kuma_cp.Config) (*core_runtime.Builder, error) { builder.WithXDSHooks(&xds_hooks.Hooks{}) builder.WithDpServer(server.NewDpServer(*cfg.DpServer, metrics)) builder.WithKDSContext(kds_context.DefaultContext(builder.ResourceManager(), cfg.Multizone.Zone.Name)) + builder.WithCAProvider(secrets.NewCaProvider(builder.CaManagers())) _ = initializeConfigManager(cfg, builder) _ = initializeDNSResolver(cfg, builder) @@ -99,10 +102,7 @@ func newResourceManager(builder *core_runtime.Builder) core_manager.Customizable defaultManager := core_manager.NewResourceManager(builder.ResourceStore()) customManagers := map[core_model.ResourceType]core_manager.ResourceManager{} customizableManager := core_manager.NewCustomizableResourceManager(defaultManager, customManagers) - validator := mesh_managers.MeshValidator{ - CaManagers: builder.CaManagers(), - } - meshManager := mesh_managers.NewMeshManager(builder.ResourceStore(), customizableManager, builder.CaManagers(), registry.Global(), validator) + meshManager := mesh_managers.NewMeshManager(builder.ResourceStore(), customizableManager, builder.CaManagers(), registry.Global(), builder.MeshValidator()) customManagers[core_mesh.MeshType] = meshManager secretManager := secret_manager.NewSecretManager(builder.SecretStore(), secret_cipher.None(), nil) diff --git a/pkg/xds/server/components.go b/pkg/xds/server/components.go index a9a0d901da7b..5c55f726ec61 100644 --- a/pkg/xds/server/components.go +++ b/pkg/xds/server/components.go @@ -65,7 +65,7 @@ func RegisterXDS(rt core_runtime.Runtime) error { } secrets, err := secrets.NewSecrets( - secrets.NewCaProvider(rt.CaManagers()), + rt.CAProvider(), secrets.NewIdentityProvider(rt.CaManagers()), rt.Metrics(), )