From 256ee37b804cb188c102b42ded7cb5c8d0e19cbc Mon Sep 17 00:00:00 2001 From: Jakub Dyszkiewicz Date: Wed, 2 Oct 2019 10:01:46 -0700 Subject: [PATCH] feat(kumacp) Delete related mesh resources --- Makefile | 2 +- pkg/core/managers/apis/mesh/mesh_manager.go | 6 ++ .../apis/mesh/mesh_manager_suite_test.go | 13 +++ .../managers/apis/mesh/mesh_manager_test.go | 87 +++++++++++++++++++ pkg/core/resources/store/options.go | 20 +++++ pkg/core/resources/store/store.go | 4 + .../resources/store/store_test_template.go | 64 ++++++++++++++ pkg/plugins/resources/k8s/k8s_suite_test.go | 13 ++- .../k8s/native/pkg/registry/interfaces.go | 2 + .../k8s/native/pkg/registry/registry.go | 16 ++++ pkg/plugins/resources/k8s/store.go | 28 ++++-- .../resources/k8s/store_template_test.go | 5 ++ pkg/plugins/resources/memory/store.go | 15 ++++ pkg/plugins/resources/postgres/store.go | 14 +++ pkg/plugins/resources/remote/store.go | 3 + .../k8s/controllers/mesh_controller.go | 6 ++ pkg/plugins/runtime/k8s/plugin.go | 1 + 17 files changed, 290 insertions(+), 9 deletions(-) create mode 100644 pkg/core/managers/apis/mesh/mesh_manager_suite_test.go create mode 100644 pkg/core/managers/apis/mesh/mesh_manager_test.go diff --git a/Makefile b/Makefile index 1793e5752ab8..5f9c637ada83 100644 --- a/Makefile +++ b/Makefile @@ -365,7 +365,7 @@ test/kuma-injector: test ## Dev: Run 'kuma injector' tests only integration: ## Dev: Run integration tests mkdir -p "$(shell dirname "$(COVERAGE_INTEGRATION_PROFILE)")" - tools/test/run-integration-tests.sh '$(GO_TEST) -race -covermode=atomic -tags=integration -count=1 -coverpkg=./... -coverprofile=$(COVERAGE_INTEGRATION_PROFILE) $(PKG_LIST)' + tools/test/run-integration-tests.sh '$(GO_TEST) $(GO_TEST_OPTS) -race -covermode=atomic -tags=integration -count=1 -coverpkg=./... -coverprofile=$(COVERAGE_INTEGRATION_PROFILE) $(PKG_LIST)' go tool cover -html="$(COVERAGE_INTEGRATION_PROFILE)" -o "$(COVERAGE_INTEGRATION_REPORT_HTML)" build: build/kuma-cp build/kuma-dp build/kumactl build/kuma-injector build/kuma-tcp-echo ## Dev: Build all binaries diff --git a/pkg/core/managers/apis/mesh/mesh_manager.go b/pkg/core/managers/apis/mesh/mesh_manager.go index d019849bd1f9..5a4ef5393be9 100644 --- a/pkg/core/managers/apis/mesh/mesh_manager.go +++ b/pkg/core/managers/apis/mesh/mesh_manager.go @@ -75,6 +75,8 @@ func (m *meshManager) Create(ctx context.Context, resource core_model.Resource, } func (m *meshManager) Delete(ctx context.Context, resource core_model.Resource, fs ...core_store.DeleteOptionsFunc) error { + opts := core_store.NewDeleteOptions(fs...) + mesh, err := m.mesh(resource) if err != nil { return err @@ -89,6 +91,10 @@ func (m *meshManager) Delete(ctx context.Context, resource core_model.Resource, if err := m.builtinCaManager.Delete(ctx, name); err != nil { return errors.Wrapf(err, "failed to delete Builtin CA for a given mesh") } + // delete associated resources + if err := m.store.DeleteMany(ctx, core_store.DeleteManyByMesh(opts.Name)); err != nil { + return errors.Wrapf(err, "failed to delete associated resources") + } return nil } diff --git a/pkg/core/managers/apis/mesh/mesh_manager_suite_test.go b/pkg/core/managers/apis/mesh/mesh_manager_suite_test.go new file mode 100644 index 000000000000..362af0d48fbd --- /dev/null +++ b/pkg/core/managers/apis/mesh/mesh_manager_suite_test.go @@ -0,0 +1,13 @@ +package mesh + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestMeshManager(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Mesh Manager Suite") +} diff --git a/pkg/core/managers/apis/mesh/mesh_manager_test.go b/pkg/core/managers/apis/mesh/mesh_manager_test.go new file mode 100644 index 000000000000..46c4da32a148 --- /dev/null +++ b/pkg/core/managers/apis/mesh/mesh_manager_test.go @@ -0,0 +1,87 @@ +package mesh + +import ( + "context" + "github.com/Kong/kuma/pkg/core/ca/builtin" + core_mesh "github.com/Kong/kuma/pkg/core/resources/apis/mesh" + "github.com/Kong/kuma/pkg/core/resources/manager" + "github.com/Kong/kuma/pkg/core/resources/model" + "github.com/Kong/kuma/pkg/core/resources/store" + "github.com/Kong/kuma/pkg/core/secrets/cipher" + secrets_manager "github.com/Kong/kuma/pkg/core/secrets/manager" + secrets_store "github.com/Kong/kuma/pkg/core/secrets/store" + "github.com/Kong/kuma/pkg/plugins/resources/memory" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Mesh Manager", func() { + + const namespace = "default" + + var resManager manager.ResourceManager + var resStore store.ResourceStore + var caManager builtin.BuiltinCaManager + + BeforeEach(func() { + resStore = memory.NewStore() + caManager = builtin.NewBuiltinCaManager(secrets_manager.NewSecretManager(secrets_store.NewSecretStore(resStore), cipher.None())) + resManager = NewMeshManager(resStore, caManager) + }) + + It("Create() should also create a built-in CA", func() { + // given + meshName := "mesh-1" + resKey := model.ResourceKey{ + Mesh: meshName, + Namespace: namespace, + Name: meshName, + } + + // when + mesh := core_mesh.MeshResource{} + err := resManager.Create(context.Background(), &mesh, store.CreateBy(resKey)) + + // then + Expect(err).ToNot(HaveOccurred()) + + // and built-in CA is created + certs, err := caManager.GetRootCerts(context.Background(), meshName) + Expect(err).ToNot(HaveOccurred()) + Expect(certs).To(HaveLen(1)) + }) + + It("Delete() should delete all associated resources", func() { + // given mesh + meshName := "mesh-1" + + mesh := core_mesh.MeshResource{} + resKey := model.ResourceKey{ + Mesh: meshName, + Namespace: namespace, + Name: meshName, + } + err := resManager.Create(context.Background(), &mesh, store.CreateBy(resKey)) + Expect(err).ToNot(HaveOccurred()) + + // and resource associated with it + dp := core_mesh.DataplaneResource{} + err = resStore.Create(context.Background(), &dp, store.CreateByKey(namespace, "dp-1", meshName)) + Expect(err).ToNot(HaveOccurred()) + + // when mesh is deleted + err = resManager.Delete(context.Background(), &mesh, store.DeleteBy(resKey)) + + // then + Expect(err).ToNot(HaveOccurred()) + + // and resource is deleted + err = resStore.Get(context.Background(), &core_mesh.DataplaneResource{}, store.GetByKey(namespace, "dp-1", meshName)) + Expect(store.IsResourceNotFound(err)).To(BeTrue()) + + // and built-in mesh CA is deleted + _, err = caManager.GetRootCerts(context.Background(), meshName) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(Equal("failed to load CA key pair for Mesh \"mesh-1\": Resource not found: type=\"Secret\" namespace=\"default\" name=\"builtinca.mesh-1\" mesh=\"mesh-1\"")) + }) +}) diff --git a/pkg/core/resources/store/options.go b/pkg/core/resources/store/options.go index 388d9847d688..4be7d21647ed 100644 --- a/pkg/core/resources/store/options.go +++ b/pkg/core/resources/store/options.go @@ -73,6 +73,26 @@ func DeleteByKey(ns, name, mesh string) DeleteOptionsFunc { } } +type DeleteManyOptions struct { + Mesh string +} + +type DeleteManyOptionsFunc func(*DeleteManyOptions) + +func NewDeleteManyOptions(fs ...DeleteManyOptionsFunc) *DeleteManyOptions { + opts := &DeleteManyOptions{} + for _, f := range fs { + f(opts) + } + return opts +} + +func DeleteManyByMesh(mesh string) DeleteManyOptionsFunc { + return func(opts *DeleteManyOptions) { + opts.Mesh = mesh + } +} + type GetOptions struct { Namespace string Name string diff --git a/pkg/core/resources/store/store.go b/pkg/core/resources/store/store.go index 4830f91420b8..669e9903844b 100644 --- a/pkg/core/resources/store/store.go +++ b/pkg/core/resources/store/store.go @@ -13,6 +13,7 @@ type ResourceStore interface { Create(context.Context, model.Resource, ...CreateOptionsFunc) error Update(context.Context, model.Resource, ...UpdateOptionsFunc) error Delete(context.Context, model.Resource, ...DeleteOptionsFunc) error + DeleteMany(context.Context, ...DeleteManyOptionsFunc) error Get(context.Context, model.Resource, ...GetOptionsFunc) error List(context.Context, model.ResourceList, ...ListOptionsFunc) error } @@ -88,6 +89,9 @@ func (s *strictResourceStore) Delete(ctx context.Context, r model.Resource, fs . } return s.delegate.Delete(ctx, r, fs...) } +func (s *strictResourceStore) DeleteMany(ctx context.Context, fs ...DeleteManyOptionsFunc) error { + return s.delegate.DeleteMany(ctx, fs...) +} func (s *strictResourceStore) Get(ctx context.Context, r model.Resource, fs ...GetOptionsFunc) error { if r == nil { return fmt.Errorf("ResourceStore.Get() requires a non-nil resource") diff --git a/pkg/core/resources/store/store_test_template.go b/pkg/core/resources/store/store_test_template.go index 45abd181f5df..bc9dd12b7120 100644 --- a/pkg/core/resources/store/store_test_template.go +++ b/pkg/core/resources/store/store_test_template.go @@ -2,6 +2,8 @@ package store import ( "context" + mesh_proto "github.com/Kong/kuma/api/mesh/v1alpha1" + core_mesh "github.com/Kong/kuma/pkg/core/resources/apis/mesh" sample_proto "github.com/Kong/kuma/pkg/test/apis/sample/v1alpha1" sample_model "github.com/Kong/kuma/pkg/test/resources/apis/sample" . "github.com/onsi/ginkgo" @@ -176,6 +178,68 @@ func ExecuteStoreTests( }) }) + Describe("DeleteMany()", func() { + BeforeEach(func() { + trRes := sample_model.TrafficRouteResource{ + Spec: sample_proto.TrafficRoute{ + Path: "demo", + }, + } + err := s.Create(context.Background(), &trRes, CreateByKey(namespace, "tr-1", "mesh-1")) + Expect(err).ToNot(HaveOccurred()) + + dpRes := core_mesh.DataplaneResource{ + Spec: mesh_proto.Dataplane{}, + } + err = s.Create(context.Background(), &dpRes, CreateByKey(namespace, "dp-1", "mesh-2")) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should delete all resources", func() { + // when + err := s.DeleteMany(context.Background()) + + // then + Expect(err).ToNot(HaveOccurred()) + + // when query for deleted resource + resource := sample_model.TrafficRouteResource{} + err = s.Get(context.Background(), &resource, GetByKey(namespace, "tr-1", "mesh-1")) + + // then resource cannot be found + Expect(err).To(Equal(ErrorResourceNotFound(resource.GetType(), namespace, "tr-1", "mesh-1"))) + + // when query for deleted resource + dpResource := core_mesh.DataplaneResource{} + err = s.Get(context.Background(), &dpResource, GetByKey(namespace, "dp-1", "mesh-2")) + + // then resource cannot be found + Expect(err).To(Equal(ErrorResourceNotFound(dpResource.GetType(), namespace, "dp-1", "mesh-2"))) + }) + + It("should delete resources by mesh", func() { + // when + err := s.DeleteMany(context.Background(), DeleteManyByMesh("mesh-1")) + + // then + Expect(err).ToNot(HaveOccurred()) + + // when query for deleted resource in given mesh + resource := sample_model.TrafficRouteResource{} + err = s.Get(context.Background(), &resource, GetByKey(namespace, "tr-1", "mesh-1")) + + // then resource cannot be found + Expect(err).To(Equal(ErrorResourceNotFound(resource.GetType(), namespace, "tr-1", "mesh-1"))) + + // when query for resource in another mesh + dpResource := core_mesh.DataplaneResource{} + err = s.Get(context.Background(), &dpResource, GetByKey(namespace, "dp-1", "mesh-2")) + + // then resource is not deleted + Expect(err).ToNot(HaveOccurred()) + }) + }) + Describe("Get()", func() { It("should return an error if resource is not found", func() { // given diff --git a/pkg/plugins/resources/k8s/k8s_suite_test.go b/pkg/plugins/resources/k8s/k8s_suite_test.go index 6130202114bb..fad92b872cb0 100644 --- a/pkg/plugins/resources/k8s/k8s_suite_test.go +++ b/pkg/plugins/resources/k8s/k8s_suite_test.go @@ -30,7 +30,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" // +kubebuilder:scaffold:imports - sample_v1alpha1 "github.com/Kong/kuma/pkg/plugins/resources/k8s/native/test/api/sample/v1alpha1" + mesh_proto "github.com/Kong/kuma/pkg/plugins/resources/k8s/native/api/v1alpha1" + sample_proto "github.com/Kong/kuma/pkg/plugins/resources/k8s/native/test/api/sample/v1alpha1" ) var k8sClient client.Client @@ -50,14 +51,20 @@ var _ = BeforeSuite(func(done Done) { By("bootstrapping test environment") testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("native", "test", "config", "crd", "bases")}, + CRDDirectoryPaths: []string{ + filepath.Join("native", "test", "config", "crd", "bases"), + filepath.Join("native", "config", "crd", "bases"), + }, } cfg, err := testEnv.Start() Expect(err).ToNot(HaveOccurred()) Expect(cfg).ToNot(BeNil()) - err = sample_v1alpha1.AddToScheme(k8sClientScheme) + err = sample_proto.AddToScheme(k8sClientScheme) + Expect(err).NotTo(HaveOccurred()) + + err = mesh_proto.AddToScheme(k8sClientScheme) Expect(err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme diff --git a/pkg/plugins/resources/k8s/native/pkg/registry/interfaces.go b/pkg/plugins/resources/k8s/native/pkg/registry/interfaces.go index 846b9ff4ec8f..afee56e0354f 100644 --- a/pkg/plugins/resources/k8s/native/pkg/registry/interfaces.go +++ b/pkg/plugins/resources/k8s/native/pkg/registry/interfaces.go @@ -10,6 +10,8 @@ type ResourceType = proto.Message type TypeRegistry interface { RegisterObjectType(ResourceType, model.KubernetesObject) error RegisterListType(ResourceType, model.KubernetesList) error + RegisteredObjects() []model.KubernetesObject + RegisteredLists() []model.KubernetesList NewObject(ResourceType) (model.KubernetesObject, error) NewList(ResourceType) (model.KubernetesList, error) diff --git a/pkg/plugins/resources/k8s/native/pkg/registry/registry.go b/pkg/plugins/resources/k8s/native/pkg/registry/registry.go index 0c5a3d00fa51..f048c273d799 100644 --- a/pkg/plugins/resources/k8s/native/pkg/registry/registry.go +++ b/pkg/plugins/resources/k8s/native/pkg/registry/registry.go @@ -20,6 +20,22 @@ type typeRegistry struct { objectListTypes map[string]model.KubernetesList } +func (r *typeRegistry) RegisteredObjects() []model.KubernetesObject { + var objs []model.KubernetesObject + for _, obj := range r.objectTypes { + objs = append(objs, obj.DeepCopyObject().(model.KubernetesObject)) + } + return objs +} + +func (r *typeRegistry) RegisteredLists() []model.KubernetesList { + var lists []model.KubernetesList + for _, list := range r.objectListTypes { + lists = append(lists, list.DeepCopyObject().(model.KubernetesList)) + } + return lists +} + func (r *typeRegistry) RegisterObjectType(typ ResourceType, obj model.KubernetesObject) error { name := proto.MessageName(typ) if previous, ok := r.objectTypes[name]; ok { diff --git a/pkg/plugins/resources/k8s/store.go b/pkg/plugins/resources/k8s/store.go index fb2ba3057268..721303301832 100644 --- a/pkg/plugins/resources/k8s/store.go +++ b/pkg/plugins/resources/k8s/store.go @@ -3,7 +3,6 @@ package k8s import ( "context" "fmt" - core_model "github.com/Kong/kuma/pkg/core/resources/model" "github.com/Kong/kuma/pkg/core/resources/store" k8s_model "github.com/Kong/kuma/pkg/plugins/resources/k8s/native/pkg/model" @@ -18,14 +17,16 @@ import ( var _ store.ResourceStore = &KubernetesStore{} type KubernetesStore struct { - Client kube_client.Client - Converter Converter + Client kube_client.Client + Converter Converter + TypeRegistry k8s_registry.TypeRegistry } func NewStore(client kube_client.Client) (store.ResourceStore, error) { return &KubernetesStore{ - Client: client, - Converter: DefaultConverter(), + Client: client, + Converter: DefaultConverter(), + TypeRegistry: k8s_registry.Global(), }, nil } @@ -93,6 +94,23 @@ func (s *KubernetesStore) Delete(ctx context.Context, r core_model.Resource, fs } return nil } +func (s *KubernetesStore) DeleteMany(ctx context.Context, fs ...store.DeleteManyOptionsFunc) error { + opts := store.NewDeleteManyOptions(fs...) + + for _, list := range s.TypeRegistry.RegisteredLists() { + if err := s.Client.List(ctx, list); err != nil { + return errors.Wrapf(err, "failed to list resources of type %s", list.GetObjectKind().GroupVersionKind().String()) + } + for _, obj := range list.GetItems() { + if opts.Mesh == "" || opts.Mesh == obj.GetMesh() { + if err := s.Client.Delete(ctx, obj); err != nil { + return errors.Wrap(err, "failed to delete k8s resource") + } + } + } + } + return nil +} func (s *KubernetesStore) Get(ctx context.Context, r core_model.Resource, fs ...store.GetOptionsFunc) error { opts := store.NewGetOptions(fs...) obj, err := s.Converter.ToKubernetesObject(r) diff --git a/pkg/plugins/resources/k8s/store_template_test.go b/pkg/plugins/resources/k8s/store_template_test.go index 72e02a448b9c..2248464cb9c5 100644 --- a/pkg/plugins/resources/k8s/store_template_test.go +++ b/pkg/plugins/resources/k8s/store_template_test.go @@ -4,8 +4,10 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + mesh_proto "github.com/Kong/kuma/api/mesh/v1alpha1" "github.com/Kong/kuma/pkg/core/resources/store" "github.com/Kong/kuma/pkg/plugins/resources/k8s" + mesh_k8s "github.com/Kong/kuma/pkg/plugins/resources/k8s/native/api/v1alpha1" k8s_registry "github.com/Kong/kuma/pkg/plugins/resources/k8s/native/pkg/registry" sample_k8s "github.com/Kong/kuma/pkg/plugins/resources/k8s/native/test/api/sample/v1alpha1" sample_proto "github.com/Kong/kuma/pkg/test/apis/sample/v1alpha1" @@ -15,7 +17,9 @@ var _ = Describe("KubernetesStore template", func() { store.ExecuteStoreTests(func() store.ResourceStore { kubeTypes := k8s_registry.NewTypeRegistry() + Expect(kubeTypes.RegisterObjectType(&mesh_proto.Dataplane{}, &mesh_k8s.Dataplane{})).To(Succeed()) Expect(kubeTypes.RegisterObjectType(&sample_proto.TrafficRoute{}, &sample_k8s.TrafficRoute{})).To(Succeed()) + Expect(kubeTypes.RegisterListType(&mesh_proto.Dataplane{}, &mesh_k8s.DataplaneList{})).To(Succeed()) Expect(kubeTypes.RegisterListType(&sample_proto.TrafficRoute{}, &sample_k8s.TrafficRouteList{})).To(Succeed()) ks := &k8s.KubernetesStore{ @@ -25,6 +29,7 @@ var _ = Describe("KubernetesStore template", func() { KubeTypes: kubeTypes, }, }, + TypeRegistry: kubeTypes, } s := store.NewStrictResourceStore(ks) return s diff --git a/pkg/plugins/resources/memory/store.go b/pkg/plugins/resources/memory/store.go index db5ca270bf50..3cf2d58d1b32 100644 --- a/pkg/plugins/resources/memory/store.go +++ b/pkg/plugins/resources/memory/store.go @@ -151,6 +151,21 @@ func (c *memoryStore) Delete(_ context.Context, r model.Resource, fs ...store.De } return nil } +func (c *memoryStore) DeleteMany(_ context.Context, fs ...store.DeleteManyOptionsFunc) error { + c.mu.Lock() + defer c.mu.Unlock() + + opts := store.NewDeleteManyOptions(fs...) + + retained := memoryStoreRecords{} + for _, record := range c.records { + if opts.Mesh != "" && opts.Mesh != record.Mesh { + retained = append(retained, record) + } + } + c.records = retained + return nil +} func (c *memoryStore) Get(_ context.Context, r model.Resource, fs ...store.GetOptionsFunc) error { c.mu.RLock() diff --git a/pkg/plugins/resources/postgres/store.go b/pkg/plugins/resources/postgres/store.go index 944aedfadbd0..416554ddac33 100644 --- a/pkg/plugins/resources/postgres/store.go +++ b/pkg/plugins/resources/postgres/store.go @@ -127,6 +127,20 @@ func (r *postgresResourceStore) Delete(_ context.Context, resource model.Resourc return nil } +func (r *postgresResourceStore) DeleteMany(ctx context.Context, fs ...store.DeleteManyOptionsFunc) error { + opts := store.NewDeleteManyOptions(fs...) + statement := `DELETE FROM resources` + var statementArgs []interface{} + if opts.Mesh != "" { + statement += ` WHERE mesh=$1` + statementArgs = append(statementArgs, opts.Mesh) + } + if _, err := r.db.Exec(statement, statementArgs...); err != nil { + return errors.Wrapf(err, "failed to execute query: %s", statement) + } + return nil +} + func (r *postgresResourceStore) Get(_ context.Context, resource model.Resource, fs ...store.GetOptionsFunc) error { opts := store.NewGetOptions(fs...) diff --git a/pkg/plugins/resources/remote/store.go b/pkg/plugins/resources/remote/store.go index 7c3bbff64604..782a95bb918a 100644 --- a/pkg/plugins/resources/remote/store.go +++ b/pkg/plugins/resources/remote/store.go @@ -89,6 +89,9 @@ func (s *remoteStore) upsert(ctx context.Context, res model.Resource, meta rest. func (s *remoteStore) Delete(context.Context, model.Resource, ...store.DeleteOptionsFunc) error { return errors.Errorf("not implemented yet") } +func (s *remoteStore) DeleteMany(context.Context, ...store.DeleteManyOptionsFunc) error { + return errors.Errorf("not implemented yet") +} func (s *remoteStore) Get(ctx context.Context, res model.Resource, fs ...store.GetOptionsFunc) error { resourceApi, err := s.api.GetResourceApi(res.GetType()) if err != nil { diff --git a/pkg/plugins/runtime/k8s/controllers/mesh_controller.go b/pkg/plugins/runtime/k8s/controllers/mesh_controller.go index 8bdec7388af6..b04de59c0cf2 100644 --- a/pkg/plugins/runtime/k8s/controllers/mesh_controller.go +++ b/pkg/plugins/runtime/k8s/controllers/mesh_controller.go @@ -8,6 +8,8 @@ import ( builtin_ca "github.com/Kong/kuma/pkg/core/ca/builtin" mesh_core "github.com/Kong/kuma/pkg/core/resources/apis/mesh" + "github.com/Kong/kuma/pkg/core/resources/manager" + "github.com/Kong/kuma/pkg/core/resources/store" k8s_resources "github.com/Kong/kuma/pkg/plugins/resources/k8s" mesh_k8s "github.com/Kong/kuma/pkg/plugins/resources/k8s/native/api/v1alpha1" @@ -30,6 +32,7 @@ type MeshReconciler struct { Converter k8s_resources.Converter BuiltinCaManager builtin_ca.BuiltinCaManager SystemNamespace string + ResourceManager manager.ResourceManager } func (r *MeshReconciler) Reconcile(req kube_ctrl.Request) (kube_ctrl.Result, error) { @@ -40,6 +43,9 @@ func (r *MeshReconciler) Reconcile(req kube_ctrl.Request) (kube_ctrl.Result, err mesh := &mesh_k8s.Mesh{} if err := r.Get(ctx, req.NamespacedName, mesh); err != nil { if kube_apierrs.IsNotFound(err) { + if err := r.ResourceManager.Delete(ctx, &mesh_core.MeshResource{}, store.DeleteByKey(req.NamespacedName.Namespace, req.Name, req.Name)); err != nil { + return kube_ctrl.Result{}, err + } return kube_ctrl.Result{}, nil } log.Error(err, "unable to fetch Mesh") diff --git a/pkg/plugins/runtime/k8s/plugin.go b/pkg/plugins/runtime/k8s/plugin.go index 3961b74debcf..4238244a2a97 100644 --- a/pkg/plugins/runtime/k8s/plugin.go +++ b/pkg/plugins/runtime/k8s/plugin.go @@ -73,6 +73,7 @@ func addMeshReconciler(mgr kube_ctrl.Manager, rt core_runtime.Runtime) error { Converter: k8s_resources.DefaultConverter(), BuiltinCaManager: rt.BuiltinCaManager(), SystemNamespace: rt.Config().Store.Kubernetes.SystemNamespace, + ResourceManager: rt.ResourceManager(), } return reconciler.SetupWithManager(mgr) }