From 47ae3a90b2bd2a8be94de096f28f6057305a29df Mon Sep 17 00:00:00 2001 From: Ekaterina Kazakova Date: Thu, 12 Sep 2024 13:15:20 +0400 Subject: [PATCH] Add base code for the TemplateManagement reconciler --- cmd/main.go | 9 +++ .../templatemanagement_controller.go | 59 ++++++++++++++ .../templatemanagement_controller_test.go | 80 +++++++++++++++++++ .../provider/hmc/templates/rbac/roles.yaml | 19 ++++- 4 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 internal/controller/templatemanagement_controller.go create mode 100644 internal/controller/templatemanagement_controller_test.go diff --git a/cmd/main.go b/cmd/main.go index 81504348d..1a9914ef9 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -220,6 +220,15 @@ func main() { setupLog.Error(err, "unable to create controller", "controller", "Management") os.Exit(1) } + if err = (&controller.TemplateManagementReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Config: mgr.GetConfig(), + SystemNamespace: currentNamespace, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "TemplateManagement") + os.Exit(1) + } if err = mgr.Add(&controller.Poller{ Client: mgr.GetClient(), Config: mgr.GetConfig(), diff --git a/internal/controller/templatemanagement_controller.go b/internal/controller/templatemanagement_controller.go new file mode 100644 index 000000000..092b34f44 --- /dev/null +++ b/internal/controller/templatemanagement_controller.go @@ -0,0 +1,59 @@ +// Copyright 2024 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controller + +import ( + "context" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + hmc "github.com/Mirantis/hmc/api/v1alpha1" +) + +// TemplateManagementReconciler reconciles a TemplateManagement object +type TemplateManagementReconciler struct { + client.Client + Scheme *runtime.Scheme + Config *rest.Config + SystemNamespace string +} + +func (r *TemplateManagementReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + l := log.FromContext(ctx).WithValues("TemplateManagementController", req.NamespacedName) + log.IntoContext(ctx, l) + l.Info("Reconciling TemplateManagement") + templateMgmt := &hmc.TemplateManagement{} + if err := r.Get(ctx, req.NamespacedName, templateMgmt); err != nil { + if apierrors.IsNotFound(err) { + l.Info("TemplateManagement not found, ignoring since object must be deleted") + return ctrl.Result{}, nil + } + l.Error(err, "Failed to get TemplateManagement") + return ctrl.Result{}, err + } + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *TemplateManagementReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&hmc.TemplateManagement{}). + Complete(r) +} diff --git a/internal/controller/templatemanagement_controller_test.go b/internal/controller/templatemanagement_controller_test.go new file mode 100644 index 000000000..73a5968de --- /dev/null +++ b/internal/controller/templatemanagement_controller_test.go @@ -0,0 +1,80 @@ +// Copyright 2024 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controller + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + hmcmirantiscomv1alpha1 "github.com/Mirantis/hmc/api/v1alpha1" +) + +var _ = Describe("Template Management Controller", func() { + Context("When reconciling a resource", func() { + const resourceName = "test-resource" + + ctx := context.Background() + + typeNamespacedName := types.NamespacedName{ + Name: resourceName, + } + templateMgmt := &hmcmirantiscomv1alpha1.TemplateManagement{} + + BeforeEach(func() { + By("creating the custom resource for the Kind TemplateManagement") + err := k8sClient.Get(ctx, typeNamespacedName, templateMgmt) + if err != nil && errors.IsNotFound(err) { + resource := &hmcmirantiscomv1alpha1.TemplateManagement{ + ObjectMeta: metav1.ObjectMeta{ + Name: resourceName, + }, + // TODO(user): Specify other spec details if needed. + } + Expect(k8sClient.Create(ctx, resource)).To(Succeed()) + } + }) + + AfterEach(func() { + // TODO(user): Cleanup logic after each test, like removing the resource instance. + resource := &hmcmirantiscomv1alpha1.TemplateManagement{} + err := k8sClient.Get(ctx, typeNamespacedName, resource) + Expect(err).NotTo(HaveOccurred()) + + By("Cleanup the specific resource instance TemplateManagement") + Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) + }) + It("should successfully reconcile the resource", func() { + By("Reconciling the created resource") + controllerReconciler := &TemplateManagementReconciler{ + Client: k8sClient, + Scheme: k8sClient.Scheme(), + } + + _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ + NamespacedName: typeNamespacedName, + }) + Expect(err).NotTo(HaveOccurred()) + // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. + // Example: If you expect a certain status condition after reconciliation, verify it here. + }) + }) +}) diff --git a/templates/provider/hmc/templates/rbac/roles.yaml b/templates/provider/hmc/templates/rbac/roles.yaml index 4a72d9312..96c613214 100644 --- a/templates/provider/hmc/templates/rbac/roles.yaml +++ b/templates/provider/hmc/templates/rbac/roles.yaml @@ -6,12 +6,12 @@ metadata: {{- include "hmc.labels" . | nindent 4 }} rules: - apiGroups: - - cluster.x-k8s.io + - cluster.x-k8s.io resources: - - clusters + - clusters verbs: - - get - - list + - get + - list - apiGroups: - helm.toolkit.fluxcd.io resources: @@ -62,6 +62,16 @@ rules: - patch - update - watch +- apiGroups: + - hmc.mirantis.com + resources: + - templatemanagements + verbs: + - get + - list + - patch + - update + - watch - apiGroups: - hmc.mirantis.com resources: @@ -72,6 +82,7 @@ rules: - hmc.mirantis.com resources: - managements/status + - templatemanagements/status verbs: - get - patch