From 682325de89895751d531e6fa66f6124eb33a80d8 Mon Sep 17 00:00:00 2001 From: chinhtranvan Date: Tue, 19 Dec 2023 04:20:28 -0500 Subject: [PATCH] WIP --- PROJECT | 11 +- api/v1/groupversion_info.go | 6 +- api/v1/verticarestorepointsquery_types.go | 104 +++++++++++++++++ api/v1/zz_generated.deepcopy.go | 89 +++++++++++++++ cmd/operator/main.go | 9 ++ config/crd/kustomization.yaml | 2 + ...ection_in_verticarestorepointsqueries.yaml | 7 ++ ...ebhook_in_verticarestorepointsqueries.yaml | 8 ++ ...verticarestorepointsquery_editor_role.yaml | 31 +++++ ...verticarestorepointsquery_viewer_role.yaml | 27 +++++ config/samples/kustomization.yaml | 1 + .../samples/v1_verticarestorepointsquery.yaml | 12 ++ pkg/controllers/vrqb/suite_test.go | 95 ++++++++++++++++ .../verticarestorepointsquery_controller.go | 107 ++++++++++++++++++ ...rticarestorepointsquery_controller_test.go | 41 +++++++ pkg/opcfg/config.go | 34 +++--- scripts/config-transformer.sh | 1 + 17 files changed, 565 insertions(+), 20 deletions(-) create mode 100644 api/v1/verticarestorepointsquery_types.go create mode 100644 config/crd/patches/cainjection_in_verticarestorepointsqueries.yaml create mode 100644 config/crd/patches/webhook_in_verticarestorepointsqueries.yaml create mode 100644 config/rbac/verticarestorepointsquery_editor_role.yaml create mode 100644 config/rbac/verticarestorepointsquery_viewer_role.yaml create mode 100644 config/samples/v1_verticarestorepointsquery.yaml create mode 100644 pkg/controllers/vrqb/suite_test.go create mode 100644 pkg/controllers/vrqb/verticarestorepointsquery_controller.go create mode 100644 pkg/controllers/vrqb/verticarestorepointsquery_controller_test.go diff --git a/PROJECT b/PROJECT index 9a88bd70d..f1101d093 100644 --- a/PROJECT +++ b/PROJECT @@ -13,7 +13,6 @@ repo: github.com/vertica/vertica-kubernetes resources: - api: crdVersion: v1 - namespaced: false controller: true domain: vertica.com kind: VerticaDB @@ -25,7 +24,6 @@ resources: webhookVersion: v1 - api: crdVersion: v1 - namespaced: false controller: true domain: vertica.com kind: VerticaAutoscaler @@ -37,7 +35,6 @@ resources: webhookVersion: v1 - api: crdVersion: v1 - namespaced: false controller: true domain: vertica.com kind: EventTrigger @@ -54,4 +51,12 @@ resources: kind: VerticaDB path: github.com/vertica/vertica-kubernetes/api/v1 version: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: vertica.com + kind: VerticaRestorePointsQuery + path: github.com/vertica/vertica-kubernetes/api/v1 + version: v1 version: "3" diff --git a/api/v1/groupversion_info.go b/api/v1/groupversion_info.go index 360585861..207266a8a 100644 --- a/api/v1/groupversion_info.go +++ b/api/v1/groupversion_info.go @@ -28,8 +28,9 @@ const ( Group = "vertica.com" Version = "v1" - VerticaDBKind = "VerticaDB" - VerticaDBKindPlural = "verticadbs" + VerticaDBKind = "VerticaDB" + VerticaDBKindPlural = "verticadbs" + RestorePointsQueryKind = "VerticaRestorePointsQuery" ) var ( @@ -41,4 +42,5 @@ var ( // AddToScheme adds the types in this group-version to the given scheme. AddToScheme = SchemeBuilder.AddToScheme + GkVRPQ = schema.GroupKind{Group: Group, Kind: RestorePointsQueryKind} ) diff --git a/api/v1/verticarestorepointsquery_types.go b/api/v1/verticarestorepointsquery_types.go new file mode 100644 index 000000000..3edd05fe2 --- /dev/null +++ b/api/v1/verticarestorepointsquery_types.go @@ -0,0 +1,104 @@ +/* +Copyright [2021-2023] Open Text. +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 v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// VerticaRestorePointsQuerySpec defines the desired state of VerticaRestorePointsQuery +type VerticaRestorePointsQuerySpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // +kubebuilder:validation:Required + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors="urn:alm:descriptor:com.tectonic.ui:text" + // The name of the VerticaDB CR that this VerticaRestorePointsQuery is defined for. The + // VerticaDB object must exist in the same namespace as this object. + VerticaDBName string `json:"verticaDBName"` + + // +operator-sdk:csv:customresourcedefinitions:type=spec + // Optional parameter that will limit the query to only restore points + // from this archvie + ArchiveName string `json:"archiveName"` +} + +const ( + ArchiveNm = "backup" +) + +// VerticaRestorePointsQueryStatus defines the observed state of VerticaRestorePointsQuery +type VerticaRestorePointsQueryStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// VerticaRestorePointsQuery is the Schema for the verticarestorepointsqueries API +type VerticaRestorePointsQuery struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec VerticaRestorePointsQuerySpec `json:"spec,omitempty"` + Status VerticaRestorePointsQueryStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// VerticaRestorePointsQueryList contains a list of VerticaRestorePointsQuery +type VerticaRestorePointsQueryList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []VerticaRestorePointsQuery `json:"items"` +} + +func init() { + SchemeBuilder.Register(&VerticaRestorePointsQuery{}, &VerticaRestorePointsQueryList{}) +} + +func (vrqb *VerticaRestorePointsQuery) ExtractNamespacedName() types.NamespacedName { + return types.NamespacedName{ + Name: vrqb.ObjectMeta.Name, + Namespace: vrqb.ObjectMeta.Namespace, + } +} + +func MakeSampleVrqbName() types.NamespacedName { + return types.NamespacedName{Name: "vrqb-sample", Namespace: "default"} +} + +// MakeVrqb will make an VerticaRestorePointsQuery for test purposes +func MakeVrqb() *VerticaRestorePointsQuery { + VDBNm := MakeVDBName() + nm := MakeSampleVrqbName() + return &VerticaRestorePointsQuery{ + TypeMeta: metav1.TypeMeta{ + APIVersion: GroupVersion.String(), + Kind: RestorePointsQueryKind, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: nm.Name, + Namespace: nm.Namespace, + UID: "zxcvbn-ghi-lkm", + }, + Spec: VerticaRestorePointsQuerySpec{ + VerticaDBName: VDBNm.Name, + ArchiveName: ArchiveNm, + }, + } +} diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 81e9baffe..963cbaec9 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -415,3 +415,92 @@ func (in *VerticaDBStatus) DeepCopy() *VerticaDBStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticaRestorePointsQuery) DeepCopyInto(out *VerticaRestorePointsQuery) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticaRestorePointsQuery. +func (in *VerticaRestorePointsQuery) DeepCopy() *VerticaRestorePointsQuery { + if in == nil { + return nil + } + out := new(VerticaRestorePointsQuery) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VerticaRestorePointsQuery) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticaRestorePointsQueryList) DeepCopyInto(out *VerticaRestorePointsQueryList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VerticaRestorePointsQuery, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticaRestorePointsQueryList. +func (in *VerticaRestorePointsQueryList) DeepCopy() *VerticaRestorePointsQueryList { + if in == nil { + return nil + } + out := new(VerticaRestorePointsQueryList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VerticaRestorePointsQueryList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticaRestorePointsQuerySpec) DeepCopyInto(out *VerticaRestorePointsQuerySpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticaRestorePointsQuerySpec. +func (in *VerticaRestorePointsQuerySpec) DeepCopy() *VerticaRestorePointsQuerySpec { + if in == nil { + return nil + } + out := new(VerticaRestorePointsQuerySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VerticaRestorePointsQueryStatus) DeepCopyInto(out *VerticaRestorePointsQueryStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VerticaRestorePointsQueryStatus. +func (in *VerticaRestorePointsQueryStatus) DeepCopy() *VerticaRestorePointsQueryStatus { + if in == nil { + return nil + } + out := new(VerticaRestorePointsQueryStatus) + in.DeepCopyInto(out) + return out +} diff --git a/cmd/operator/main.go b/cmd/operator/main.go index f694ecd1f..889c912c9 100644 --- a/cmd/operator/main.go +++ b/cmd/operator/main.go @@ -47,6 +47,7 @@ import ( "github.com/vertica/vertica-kubernetes/pkg/controllers/et" "github.com/vertica/vertica-kubernetes/pkg/controllers/vas" "github.com/vertica/vertica-kubernetes/pkg/controllers/vdb" + "github.com/vertica/vertica-kubernetes/pkg/controllers/vrqb" vmeta "github.com/vertica/vertica-kubernetes/pkg/meta" "github.com/vertica/vertica-kubernetes/pkg/opcfg" "github.com/vertica/vertica-kubernetes/pkg/security" @@ -77,6 +78,7 @@ func init() { utilruntime.Must(vapiB1.AddToScheme(scheme)) utilruntime.Must(vapiV1.AddToScheme(scheme)) + utilruntime.Must(vapiV1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } @@ -129,6 +131,13 @@ func addReconcilersToManager(mgr manager.Manager, restCfg *rest.Config, oc *opcf setupLog.Error(err, "unable to create controller", "controller", "EventTrigger") os.Exit(1) } + if err := (&vrqb.VerticaRestorePointsQueryReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "VerticaRestorePointsQuery") + os.Exit(1) + } //+kubebuilder:scaffold:builder } diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 5b21bb6e2..8ce9a661d 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -5,6 +5,7 @@ resources: - bases/vertica.com_verticadbs.yaml - bases/vertica.com_verticaautoscalers.yaml - bases/vertica.com_eventtriggers.yaml + - bases/vertica.com_verticarestorepointsqueries.yaml #+kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: @@ -12,6 +13,7 @@ patchesStrategicMerge: - patches/webhook_in_verticadbs.yaml - patches/webhook_in_verticaautoscalers.yaml - patches/webhook_in_eventtriggers.yaml + - patches/webhook_in_verticarestorepointsqueries.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] there was an optional patch to include an annotation that diff --git a/config/crd/patches/cainjection_in_verticarestorepointsqueries.yaml b/config/crd/patches/cainjection_in_verticarestorepointsqueries.yaml new file mode 100644 index 000000000..4a206626c --- /dev/null +++ b/config/crd/patches/cainjection_in_verticarestorepointsqueries.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: verticarestorepointsqueries.vertica.com diff --git a/config/crd/patches/webhook_in_verticarestorepointsqueries.yaml b/config/crd/patches/webhook_in_verticarestorepointsqueries.yaml new file mode 100644 index 000000000..b7835b0d7 --- /dev/null +++ b/config/crd/patches/webhook_in_verticarestorepointsqueries.yaml @@ -0,0 +1,8 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: verticarestorepointsqueries.vertica.com +spec: + conversion: + strategy: None diff --git a/config/rbac/verticarestorepointsquery_editor_role.yaml b/config/rbac/verticarestorepointsquery_editor_role.yaml new file mode 100644 index 000000000..86f7d32e7 --- /dev/null +++ b/config/rbac/verticarestorepointsquery_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit verticarestorepointsqueries. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: verticarestorepointsquery-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: verticadb-operator + app.kubernetes.io/part-of: verticadb-operator + app.kubernetes.io/managed-by: kustomize + name: verticarestorepointsquery-editor-role +rules: +- apiGroups: + - vertica.com + resources: + - verticarestorepointsqueries + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - vertica.com + resources: + - verticarestorepointsqueries/status + verbs: + - get diff --git a/config/rbac/verticarestorepointsquery_viewer_role.yaml b/config/rbac/verticarestorepointsquery_viewer_role.yaml new file mode 100644 index 000000000..0fc8bd218 --- /dev/null +++ b/config/rbac/verticarestorepointsquery_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view verticarestorepointsqueries. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: verticarestorepointsquery-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: verticadb-operator + app.kubernetes.io/part-of: verticadb-operator + app.kubernetes.io/managed-by: kustomize + name: verticarestorepointsquery-viewer-role +rules: +- apiGroups: + - vertica.com + resources: + - verticarestorepointsqueries + verbs: + - get + - list + - watch +- apiGroups: + - vertica.com + resources: + - verticarestorepointsqueries/status + verbs: + - get diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index a3338b853..837440c7d 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -4,4 +4,5 @@ resources: - v1beta1_verticaautoscaler.yaml - v1beta1_eventtrigger.yaml - v1_verticadb.yaml +- v1_verticarestorepointsquery.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/v1_verticarestorepointsquery.yaml b/config/samples/v1_verticarestorepointsquery.yaml new file mode 100644 index 000000000..e280d61e5 --- /dev/null +++ b/config/samples/v1_verticarestorepointsquery.yaml @@ -0,0 +1,12 @@ +apiVersion: vertica.com/v1 +kind: VerticaRestorePointsQuery +metadata: + labels: + app.kubernetes.io/name: verticarestorepointsquery + app.kubernetes.io/instance: verticarestorepointsquery-sample + app.kubernetes.io/part-of: verticadb-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: verticadb-operator + name: verticarestorepointsquery-sample +spec: + # TODO(user): Add fields here diff --git a/pkg/controllers/vrqb/suite_test.go b/pkg/controllers/vrqb/suite_test.go new file mode 100644 index 000000000..b7ad44e3d --- /dev/null +++ b/pkg/controllers/vrqb/suite_test.go @@ -0,0 +1,95 @@ +/* +Copyright [2021-2023] Open Text. +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 vrqb + +import ( + "path/filepath" + "testing" + + "github.com/go-logr/logr" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + vmeta "github.com/vertica/vertica-kubernetes/pkg/meta" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + v1vapi "github.com/vertica/vertica-kubernetes/api/v1" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var vrqbRec *VerticaRestorePointsQueryReconciler +var logger logr.Logger + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "VerticaRestorePointQuery Suite") +} + +var _ = BeforeSuite(func() { + logger = zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)) + logf.SetLogger(logger) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = v1vapi.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme.Scheme, + MetricsBindAddress: "0", // Disable metrics for the test + }) + + vrqbRec = &VerticaRestorePointsQueryReconciler{ + Client: k8sClient, + Scheme: scheme.Scheme, + Log: logger, + EVRec: mgr.GetEventRecorderFor(vmeta.OperatorName), + } + Expect(err).NotTo(HaveOccurred()) +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/pkg/controllers/vrqb/verticarestorepointsquery_controller.go b/pkg/controllers/vrqb/verticarestorepointsquery_controller.go new file mode 100644 index 000000000..b63e45ab5 --- /dev/null +++ b/pkg/controllers/vrqb/verticarestorepointsquery_controller.go @@ -0,0 +1,107 @@ +/* +Copyright [2021-2023] Open Text. +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 vrqb + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/record" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/go-logr/logr" + vapi "github.com/vertica/vertica-kubernetes/api/v1" + "github.com/vertica/vertica-kubernetes/pkg/controllers" + verrors "github.com/vertica/vertica-kubernetes/pkg/errors" + "github.com/vertica/vertica-kubernetes/pkg/meta" +) + +// VerticaRestorePointsQueryReconciler reconciles a VerticaRestorePointsQuery object +type VerticaRestorePointsQueryReconciler struct { + client.Client + Scheme *runtime.Scheme + Log logr.Logger + EVRec record.EventRecorder +} + +//+kubebuilder:rbac:groups=vertica.com,resources=verticarestorepointsqueries,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=vertica.com,resources=verticarestorepointsqueries/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=vertica.com,resources=verticarestorepointsqueries/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the VerticaRestorePointsQuery object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.14.1/pkg/reconcile +func (r *VerticaRestorePointsQueryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + log := r.Log.WithValues("vrqb", req.NamespacedName) + log.Info("starting reconcile of vertica restore point query") + + vrqb := &vapi.VerticaRestorePointsQuery{} + err := r.Get(ctx, req.NamespacedName, vrqb) + if err != nil { + if errors.IsNotFound(err) { + // Request object not found, cound have been deleted after reconcile request. + log.Info("VerticaRestorePointsQuery resource not found. Ignoring since object must be deleted") + return ctrl.Result{}, nil + } + log.Error(err, "failed to get VerticaRestorePointsQuery") + return ctrl.Result{}, err + } + + if meta.IsPauseAnnotationSet(vrqb.Annotations) { + log.Info(fmt.Sprintf("The pause annotation %s is set. Suspending the iteration", meta.PauseOperatorAnnotation), + "result", ctrl.Result{}, "err", nil) + return ctrl.Result{}, nil + } + + // Iterate over each actor + actors := r.constructActors(vrqb, log) + var res ctrl.Result + for _, act := range actors { + log.Info("starting actor", "name", fmt.Sprintf("%T", act)) + res, err = act.Reconcile(ctx, &req) + // Error or a request to requeue will stop the reconciliation. + if verrors.IsReconcileAborted(res, err) { + log.Info("aborting reconcile of EventTrigger", "result", res, "err", err) + return res, err + } + } + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *VerticaRestorePointsQueryReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&vapi.VerticaRestorePointsQuery{}). + Complete(r) +} + +// constructActors will a list of actors that should be run for the reconcile. +// Order matters in that some actors depend on the successeful execution of +// earlier ones. +func (r *VerticaRestorePointsQueryReconciler) constructActors(_ *vapi.VerticaRestorePointsQuery, + _ logr.Logger) []controllers.ReconcileActor { + // The actors that will be applied, in sequence, to reconcile an et. + // Temporarily, we set nil value for constructActors + return nil +} diff --git a/pkg/controllers/vrqb/verticarestorepointsquery_controller_test.go b/pkg/controllers/vrqb/verticarestorepointsquery_controller_test.go new file mode 100644 index 000000000..cdd874c7e --- /dev/null +++ b/pkg/controllers/vrqb/verticarestorepointsquery_controller_test.go @@ -0,0 +1,41 @@ +/* +Copyright [2021-2023] Open Text. +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 vrqb + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + vapi "github.com/vertica/vertica-kubernetes/api/v1" + "github.com/vertica/vertica-kubernetes/pkg/meta" + ctrl "sigs.k8s.io/controller-runtime" +) + +var _ = Describe("verticarestorepointsquery_controller", func() { + ctx := context.Background() + + It("should reconcile an Vertica Restore Points Query with no errors if vrqb doesn't exist", func() { + vrqb := vapi.MakeVrqb() + Expect(vrqbRec.Reconcile(ctx, ctrl.Request{NamespacedName: vrqb.ExtractNamespacedName()})).Should(Equal(ctrl.Result{})) + }) + + It("should suspend the reconcile if pause annotation is set", func() { + vrqb := vapi.MakeVrqb() + vrqb.Annotations = map[string]string{meta.PauseOperatorAnnotation: "1"} + Expect(k8sClient.Create(ctx, vrqb)).Should(Succeed()) + defer func() { Expect(k8sClient.Delete(ctx, vrqb)).Should(Succeed()) }() + Expect(vrqbRec.Reconcile(ctx, ctrl.Request{NamespacedName: vrqb.ExtractNamespacedName()})).Should(Equal(ctrl.Result{})) + }) +}) diff --git a/pkg/opcfg/config.go b/pkg/opcfg/config.go index e2c099908..e55682b92 100644 --- a/pkg/opcfg/config.go +++ b/pkg/opcfg/config.go @@ -29,17 +29,18 @@ import ( ) const ( - DefaultZapcoreLevel = zapcore.InfoLevel - First = 100 - ThereAfter = 100 - DefaultMaxFileSize = 500 - DefaultMaxFileAge = 7 - DefaultMaxFileRotation = 3 - DefaultLevel = "info" - DefaultDevMode = true - DefaultVerticaDBConcurrency = 5 - DefaultVerticaAutoscalerDBConcurrency = 1 - DefaultEventTriggerDBConcurrency = 1 + DefaultZapcoreLevel = zapcore.InfoLevel + First = 100 + ThereAfter = 100 + DefaultMaxFileSize = 500 + DefaultMaxFileAge = 7 + DefaultMaxFileRotation = 3 + DefaultLevel = "info" + DefaultDevMode = true + DefaultVerticaDBConcurrency = 5 + DefaultVerticaAutoscalerDBConcurrency = 1 + DefaultEventTriggerDBConcurrency = 1 + DefaultVerticaRestorePointQueryConcurrency = 1 ) type OperatorConfig struct { @@ -57,9 +58,10 @@ type OperatorConfig struct { // The *Currency parms control the concurrency of go routines handling each // CR. For instance, VerticaDBConcurrency is the number of go routines to // handle reconciliation of VerticaDB CRs. - VerticaDBConcurrency int - VerticaAutoscalerConcurrency int - EventTriggerConcurrency int + VerticaDBConcurrency int + VerticaAutoscalerConcurrency int + EventTriggerConcurrency int + VerticaRestorePointQueryConcurrency int Logging } @@ -107,8 +109,10 @@ func (o *OperatorConfig) SetFlagArgs() { flag.IntVar(&o.VerticaAutoscalerConcurrency, "verticaautoscaler-concurrency", DefaultVerticaAutoscalerDBConcurrency, "The amount of concurrency to reconcile VerticaAutoscaler CRs") - flag.IntVar(&o.EventTriggerConcurrency, "eventtrigger-concurrency", DefaultVerticaDBConcurrency, + flag.IntVar(&o.EventTriggerConcurrency, "eventtrigger-concurrency", DefaultEventTriggerDBConcurrency, "The amount of concurrency to reconcile EventTrigger CRs") + flag.IntVar(&o.VerticaRestorePointQueryConcurrency, "verticarestorepoint-concurrency", DefaultVerticaRestorePointQueryConcurrency, + "The amount of concurrency to reconcile VerticaRestorePointQuery CRs") } // getEncoderConfig returns a concrete encoders configuration diff --git a/scripts/config-transformer.sh b/scripts/config-transformer.sh index 6d5bde7a3..995ba6626 100755 --- a/scripts/config-transformer.sh +++ b/scripts/config-transformer.sh @@ -32,6 +32,7 @@ $KUSTOMIZE build $REPO_DIR/config/default | $KUBERNETES_SPLIT_YAML --outdir $TEM mv $TEMPLATE_DIR/verticadbs.vertica.com-crd.yaml $CRD_DIR mv $TEMPLATE_DIR/verticaautoscalers.vertica.com-crd.yaml $CRD_DIR mv $TEMPLATE_DIR/eventtriggers.vertica.com-crd.yaml $CRD_DIR +mv $TEMPLATE_DIR/verticarestorepointsqueries.vertica.com-crd.yaml $CRD_DIR # Delete openshift clusterRole and clusterRoleBinding files rm $TEMPLATE_DIR/verticadb-operator-openshift-cluster-role-cr.yaml