From 566b840db27f7438fa5e426a77587d18e53b070a Mon Sep 17 00:00:00 2001 From: Konstantinos Samaras-Tsakiris <konstantinos.samaras-tsakiris@cern.ch> Date: Tue, 16 Mar 2021 16:34:13 +0000 Subject: [PATCH] Revert "Merge branch 'dbod-integration' into 'master'" This reverts merge request !33 --- Makefile | 2 +- .../templates/manager-rbac.yaml | 14 - config/rbac/role.yaml | 14 - ...rupal.webservices_v1alpha1_drupalsite.yaml | 1 - controllers/drupalsite_controller.go | 30 +- controllers/drupalsite_controller_test.go | 272 +++++++------- controllers/drupalsite_resources.go | 347 ++++++++++++++---- controllers/error_types.go | 1 - controllers/suite_test.go | 12 +- go.mod | 1 - go.sum | 13 - main.go | 7 +- .../mock_crd/dbod.cern_dbodclasses.yaml | 49 --- .../mock_crd/dbod.cern_dbodregistrations.yaml | 67 ---- .../drupal/paas/dbod-operator/LICENSE | 21 -- .../go/api/v1alpha1/dbodclass_types.go | 64 ---- .../go/api/v1alpha1/dbodregistration_types.go | 64 ---- .../go/api/v1alpha1/groupversion_info.go | 36 -- .../go/api/v1alpha1/zz_generated.deepcopy.go | 210 ----------- vendor/modules.txt | 3 - 20 files changed, 434 insertions(+), 794 deletions(-) delete mode 100644 testResources/mock_crd/dbod.cern_dbodclasses.yaml delete mode 100644 testResources/mock_crd/dbod.cern_dbodregistrations.yaml delete mode 100644 vendor/gitlab.cern.ch/drupal/paas/dbod-operator/LICENSE delete mode 100644 vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/dbodclass_types.go delete mode 100644 vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/dbodregistration_types.go delete mode 100644 vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/groupversion_info.go delete mode 100644 vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/zz_generated.deepcopy.go diff --git a/Makefile b/Makefile index 57737985..0814910e 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ manager: generate fmt vet # Run against the configured Kubernetes cluster in ~/.kube/config run: generate fmt vet manifests - go run ./main.go + go run ./main.go --assignable-router-shard=apps-shard-1 # Install CRDs into a cluster install: manifests kustomize diff --git a/chart/drupalsite-operator/templates/manager-rbac.yaml b/chart/drupalsite-operator/templates/manager-rbac.yaml index 394a78a2..bb048203 100644 --- a/chart/drupalsite-operator/templates/manager-rbac.yaml +++ b/chart/drupalsite-operator/templates/manager-rbac.yaml @@ -71,20 +71,6 @@ rules: - routes/finalizers verbs: - '*' -- apiGroups: - - dbod.cern - resources: - - dbodregistrations - verbs: - - '*' -- apiGroups: - - dbod.cern - resources: - - dbodclasses - verbs: - - get - - list - - watch --- apiVersion: v1 kind: ServiceAccount diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index fb7a05be..4d565113 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -38,20 +38,6 @@ rules: verbs: - get - list -- apiGroups: - - dbod.cern - resources: - - dbodclasses - verbs: - - get - - list - - watch -- apiGroups: - - dbod.cern - resources: - - dbodregistrations - verbs: - - '*' - apiGroups: - drupal.webservices.cern.ch resources: diff --git a/config/samples/drupal.webservices_v1alpha1_drupalsite.yaml b/config/samples/drupal.webservices_v1alpha1_drupalsite.yaml index d4945e47..242d0462 100644 --- a/config/samples/drupal.webservices_v1alpha1_drupalsite.yaml +++ b/config/samples/drupal.webservices_v1alpha1_drupalsite.yaml @@ -8,4 +8,3 @@ spec: environment: name: "dev" qosClass: "standard" - dbodClass: "test-dbodclass" diff --git a/controllers/drupalsite_controller.go b/controllers/drupalsite_controller.go index f16366c4..4aa9b2ec 100644 --- a/controllers/drupalsite_controller.go +++ b/controllers/drupalsite_controller.go @@ -25,14 +25,12 @@ import ( "os" "path/filepath" "strings" - "time" "github.com/go-logr/logr" buildv1 "github.com/openshift/api/build/v1" imagev1 "github.com/openshift/api/image/v1" routev1 "github.com/openshift/api/route/v1" "github.com/operator-framework/operator-lib/status" - dbodv1a1 "gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1" webservicesv1a1 "gitlab.cern.ch/drupal/paas/drupalsite-operator/api/v1alpha1" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" @@ -45,11 +43,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -const ( - // REQUEUE_INTERVAL is the standard waiting period when the controller decides to requeue itself after a transient condition has occurred - REQUEUE_INTERVAL = time.Duration(20 * time.Second) -) - // DrupalSiteReconciler reconciles a DrupalSite object type DrupalSiteReconciler struct { client.Client @@ -67,8 +60,6 @@ type DrupalSiteReconciler struct { // +kubebuilder:rbac:groups=core,resources=persistentvolumeclaims;services,verbs=* // +kubebuilder:rbac:groups=batch,resources=jobs,verbs=* // +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list; -// +kubebuilder:rbac:groups=dbod.cern,resources=dbodregistrations,verbs=* -// +kubebuilder:rbac:groups=dbod.cern,resources=dbodclasses,verbs=get;list;watch; func (r *DrupalSiteReconciler) initEnv() { log := r.Log @@ -106,7 +97,6 @@ func (r *DrupalSiteReconciler) SetupWithManager(mgr ctrl.Manager) error { Owns(&corev1.PersistentVolumeClaim{}). Owns(&corev1.Service{}). Owns(&batchv1.Job{}). - Owns(&dbodv1a1.DBODRegistration{}). Complete(r) } @@ -165,19 +155,11 @@ func (r *DrupalSiteReconciler) Reconcile(ctx context.Context, req ctrl.Request) // Ensure installed - Installed status // Create route - // Ensure all resources + // Ensure all primary resources if transientErrs := r.ensureResources(drupalSite, log); transientErrs != nil { transientErr := concat(transientErrs) setNotReady(drupalSite, transientErr) - return handleTransientErr(transientErr, "%v while ensuring the resources") - } - - // Check if DBOD has been provisioned - if dbodReady := r.isDBODProvisioned(ctx, drupalSite); !dbodReady { - if update := setNotReady(drupalSite, newApplicationError(nil, ErrDBOD)); update { - r.updateCRStatusorFailReconcile(ctx, log, drupalSite) - } - return reconcile.Result{Requeue: true, RequeueAfter: REQUEUE_INTERVAL}, nil + return handleTransientErr(transientErr, "%v while creating the resources") } // Check if the drupal site is ready to serve requests @@ -198,6 +180,14 @@ func (r *DrupalSiteReconciler) Reconcile(ctx context.Context, req ctrl.Request) } } + // If the installed status and ready status is true, create the route + if drupalSite.ConditionTrue("Installed") && drupalSite.ConditionTrue("Ready") { + if transientErr := r.ensureIngressResources(drupalSite, log); transientErr != nil { + return handleTransientErr(transientErr, "%v while creating route") + } + return r.updateCRorFailReconcile(ctx, log, drupalSite) + } + return ctrl.Result{}, nil } diff --git a/controllers/drupalsite_controller_test.go b/controllers/drupalsite_controller_test.go index c94aa557..a4b1c044 100644 --- a/controllers/drupalsite_controller_test.go +++ b/controllers/drupalsite_controller_test.go @@ -18,20 +18,21 @@ package controllers import ( "context" + "fmt" "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" buildv1 "github.com/openshift/api/build/v1" imagev1 "github.com/openshift/api/image/v1" - dbodv1a1 "gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1" - drupalwebservicesv1alpha1 "gitlab.cern.ch/drupal/paas/drupalsite-operator/api/v1alpha1" appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + + drupalwebservicesv1alpha1 "gitlab.cern.ch/drupal/paas/drupalsite-operator/api/v1alpha1" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" ) // Ginkgo makes it easy to write expressive specs that describe the behavior of your code in an organized manner. @@ -110,114 +111,102 @@ var _ = Describe("DrupalSite controller", func() { deploy := appsv1.Deployment{} is := imagev1.ImageStream{} bc := buildv1.BuildConfig{} - dbod := dbodv1a1.DBODRegistration{} - - // Check DBOD resource creation - By("Expecting DBOD resource created") - Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "dbod-" + key.Name, Namespace: key.Namespace}, &dbod) - return dbod.ObjectMeta.OwnerReferences - }, timeout, interval).Should(ContainElement(expectedOwnerReference)) - - // Update DBOD resource status field - By("Updating secret name in DBOD resource status") - Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "dbod-" + key.Name, Namespace: key.Namespace}, &dbod) - dbod.Status.DbCredentialsSecret = "test" - return k8sClient.Status().Update(ctx, &dbod) - }, timeout, interval).Should(Succeed()) - - By("Expecting the drupal deployment to have the EnvFrom secret field set correctly") - Eventually(func() bool { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &deploy) - if len(deploy.Spec.Template.Spec.Containers) < 2 || len(deploy.Spec.Template.Spec.Containers[0].EnvFrom) == 0 || len(deploy.Spec.Template.Spec.Containers[1].EnvFrom) == 0 { - return false - } - if deploy.Spec.Template.Spec.Containers[0].EnvFrom[0].SecretRef.Name == "test" && deploy.Spec.Template.Spec.Containers[1].EnvFrom[0].SecretRef.Name == "test" { - return true - } - return false - }, timeout, interval).Should(BeTrue()) - - By("Expecting the drush job to have the EnvFrom secret field set correctly") - Eventually(func() bool { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-drush-" + key.Name, Namespace: key.Namespace}, &job) - if len(job.Spec.Template.Spec.Containers) == 0 || len(job.Spec.Template.Spec.Containers[0].EnvFrom) == 0 { - return false - } - if job.Spec.Template.Spec.Containers[0].EnvFrom[0].SecretRef.Name == "test" { - return true - } - return false - }, timeout, interval).Should(BeTrue()) // Check PHP-FPM configMap creation By("Expecting PHP_FPM configmaps created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "php-fpm-cm-" + key.Name, Namespace: key.Namespace}, &configmap) + k8sClient.Get(ctx, types.NamespacedName{Name: "php-fpm-cm-" + Name, Namespace: Namespace}, &configmap) return configmap.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Nginx configMap creation By("Expecting Nginx configmaps created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "nginx-cm-" + key.Name, Namespace: key.Namespace}, &configmap) + k8sClient.Get(ctx, types.NamespacedName{Name: "nginx-cm-" + Name, Namespace: Namespace}, &configmap) + return configmap.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + + // Check MySQL configMap creation + By("Expecting MySQL configmaps created") + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "mysql-cm-" + Name, Namespace: Namespace}, &configmap) return configmap.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Drupal service By("Expecting Drupal service created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &svc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &svc) + return svc.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + + // Check MySQL service + By("Expecting MySQL service created") + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-mysql", Namespace: Namespace}, &svc) return svc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check drupal persistentVolumeClaim By("Expecting drupal persistentVolumeClaim created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-pv-claim-" + key.Name, Namespace: key.Namespace}, &pvc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-pv-claim-" + Name, Namespace: Namespace}, &pvc) return pvc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) - // Check Drupal deployments - By("Expecting Drupal deployments created") + // Check MySQL persistentVolumeClaim + By("Expecting MySQL persistentVolumeClaim created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &deploy) + k8sClient.Get(ctx, types.NamespacedName{Name: "mysql-pv-claim-" + Name, Namespace: Namespace}, &pvc) + return pvc.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + + // Check Drupal deploymentConfigs + By("Expecting Drupal deploymentConfigs created") + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &deploy) + return deploy.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + + // Check MySQL deploymentConfigs + By("Expecting MySQL deploymentConfigs created") + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-mysql-" + Name, Namespace: Namespace}, &deploy) return deploy.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check PHP imageStream By("Expecting PHP imageStream created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + key.Name, Namespace: key.Namespace}, &is) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + Name, Namespace: Namespace}, &is) return is.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Nginx imageStream By("Expecting Nginx imageStream created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + key.Name, Namespace: key.Namespace}, &is) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + Name, Namespace: Namespace}, &is) return is.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Drush job By("Expecting Drush job created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-drush-" + key.Name, Namespace: key.Namespace}, &job) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-drush-" + Name, Namespace: Namespace}, &job) return job.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check PHP buildConfig By("Expecting PHP buildConfig created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + key.Name, Namespace: key.Namespace}, &bc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + Name, Namespace: Namespace}, &bc) return bc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Nginx buildConfig By("Expecting Nginx buildConfigs created") Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + key.Name, Namespace: key.Namespace}, &bc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + Name, Namespace: Namespace}, &bc) return bc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) }) @@ -236,7 +225,7 @@ var _ = Describe("DrupalSite controller", func() { expectedOwnerReference := v1.OwnerReference{ APIVersion: "drupal.webservices.cern.ch/v1alpha1", Kind: "DrupalSite", - Name: key.Name, + Name: Name, UID: cr.UID, Controller: &trueVar, } @@ -251,110 +240,154 @@ var _ = Describe("DrupalSite controller", func() { // Check PHP-FPM configMap recreation By("Expecting PHP_FPM configmaps recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "php-fpm-cm-" + key.Name, Namespace: key.Namespace}, &configmap) + k8sClient.Get(ctx, types.NamespacedName{Name: "php-fpm-cm-" + Name, Namespace: Namespace}, &configmap) return k8sClient.Delete(ctx, &configmap) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "php-fpm-cm-" + key.Name, Namespace: key.Namespace}, &configmap) + k8sClient.Get(ctx, types.NamespacedName{Name: "php-fpm-cm-" + Name, Namespace: Namespace}, &configmap) return configmap.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Nginx configMap creation By("Expecting Nginx configmaps recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "nginx-cm-" + key.Name, Namespace: key.Namespace}, &configmap) + k8sClient.Get(ctx, types.NamespacedName{Name: "nginx-cm-" + Name, Namespace: Namespace}, &configmap) return k8sClient.Delete(ctx, &configmap) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "nginx-cm-" + key.Name, Namespace: key.Namespace}, &configmap) + k8sClient.Get(ctx, types.NamespacedName{Name: "nginx-cm-" + Name, Namespace: Namespace}, &configmap) + return configmap.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + + // Check MySQL configMap creation + By("Expecting MySQL configmaps recreated") + Eventually(func() error { + k8sClient.Get(ctx, types.NamespacedName{Name: "mysql-cm-" + Name, Namespace: Namespace}, &configmap) + return k8sClient.Delete(ctx, &configmap) + }, timeout, interval).Should(Succeed()) + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "mysql-cm-" + Name, Namespace: Namespace}, &configmap) return configmap.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Drupal service By("Expecting Drupal service recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &svc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &svc) return k8sClient.Delete(ctx, &svc) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &svc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &svc) + return svc.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + + // Check MySQL service + By("Expecting MySQL service recreated") + Eventually(func() error { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-mysql", Namespace: Namespace}, &svc) + return k8sClient.Delete(ctx, &svc) + }, timeout, interval).Should(Succeed()) + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-mysql", Namespace: Namespace}, &svc) return svc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check drupal persistentVolumeClaim By("Expecting drupal persistentVolumeClaim recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-pv-claim-" + key.Name, Namespace: key.Namespace}, &pvc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-pv-claim-" + Name, Namespace: Namespace}, &pvc) return k8sClient.Delete(ctx, &pvc) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-pv-claim-" + key.Name, Namespace: key.Namespace}, &pvc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-pv-claim-" + Name, Namespace: Namespace}, &pvc) return pvc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) - // Check Drupal deployments - By("Expecting Drupal deployments recreated") + // Check MySQL persistentVolumeClaim + By("Expecting MySQL persistentVolumeClaim recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &deploy) + k8sClient.Get(ctx, types.NamespacedName{Name: "mysql-pv-claim-" + Name, Namespace: Namespace}, &pvc) + return k8sClient.Delete(ctx, &pvc) + }, timeout, interval).Should(Succeed()) + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "mysql-pv-claim-" + Name, Namespace: Namespace}, &pvc) + return pvc.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + + // Check Drupal deploymentConfigs + By("Expecting Drupal deploymentConfigs recreated") + Eventually(func() error { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &deploy) return k8sClient.Delete(ctx, &deploy) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &deploy) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &deploy) + return deploy.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + + // Check MySQL deploymentConfigs + By("Expecting MySQL deploymentConfigs recreated") + Eventually(func() error { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-mysql-" + Name, Namespace: Namespace}, &deploy) + return k8sClient.Delete(ctx, &deploy) + }, timeout, interval).Should(Succeed()) + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-mysql-" + Name, Namespace: Namespace}, &deploy) return deploy.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check PHP imageStream By("Expecting PHP imageStream recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + key.Name, Namespace: key.Namespace}, &is) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + Name, Namespace: Namespace}, &is) return k8sClient.Delete(ctx, &is) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + key.Name, Namespace: key.Namespace}, &is) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + Name, Namespace: Namespace}, &is) return is.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Nginx imageStream By("Expecting Nginx imageStream recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + key.Name, Namespace: key.Namespace}, &is) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + Name, Namespace: Namespace}, &is) return k8sClient.Delete(ctx, &is) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + key.Name, Namespace: key.Namespace}, &is) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + Name, Namespace: Namespace}, &is) return is.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Drush job By("Expecting Drush job recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-drush-" + key.Name, Namespace: key.Namespace}, &job) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-drush-" + Name, Namespace: Namespace}, &job) return k8sClient.Delete(ctx, &job) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-drush-" + key.Name, Namespace: key.Namespace}, &job) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-drush-" + Name, Namespace: Namespace}, &job) return job.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check PHP buildConfig By("Expecting PHP buildConfig recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + key.Name, Namespace: key.Namespace}, &bc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + Name, Namespace: Namespace}, &bc) return k8sClient.Delete(ctx, &bc) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + key.Name, Namespace: key.Namespace}, &bc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-php-" + Name, Namespace: Namespace}, &bc) return bc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) // Check Nginx buildConfig By("Expecting Nginx buildConfigs recreated") Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + key.Name, Namespace: key.Namespace}, &bc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + Name, Namespace: Namespace}, &bc) return k8sClient.Delete(ctx, &bc) }, timeout, interval).Should(Succeed()) Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + key.Name, Namespace: key.Namespace}, &bc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-nginx-" + Name, Namespace: Namespace}, &bc) return bc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) }) @@ -366,7 +399,7 @@ var _ = Describe("DrupalSite controller", func() { It("Should not be updated successfully", func() { By("By updating service object") svc := corev1.Service{} - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &svc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &svc) svc.Labels["app"] = "testUpdateLabel" Eventually(func() error { return k8sClient.Update(ctx, &svc) @@ -375,9 +408,10 @@ var _ = Describe("DrupalSite controller", func() { time.Sleep(1 * time.Second) Eventually(func() map[string]string { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &svc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &svc) return svc.GetLabels() }, timeout, interval).ShouldNot(HaveKeyWithValue("app", "testUpdateLabel")) + fmt.Println(svc.Annotations) }) }) }) @@ -388,7 +422,7 @@ var _ = Describe("DrupalSite controller", func() { const adminAnnotation = "drupal.cern.ch/admin-custom-edit" By("By updating service object with admin annotation") svc := corev1.Service{} - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &svc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &svc) if len(svc.GetAnnotations()) == 0 { svc.Annotations = map[string]string{} } @@ -403,7 +437,7 @@ var _ = Describe("DrupalSite controller", func() { }, timeout, interval).Should(Succeed()) Eventually(func() map[string]string { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &svc) + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + Name, Namespace: Namespace}, &svc) return svc.GetLabels() }, timeout, interval).Should(HaveKeyWithValue("app", "testUpdateLabel")) }) @@ -486,46 +520,6 @@ var _ = Describe("DrupalSite controller", func() { deploy := appsv1.Deployment{} is := imagev1.ImageStream{} bc := buildv1.BuildConfig{} - dbod := dbodv1a1.DBODRegistration{} - - // Check DBOD resource creation - By("Expecting DBOD resource created") - Eventually(func() []v1.OwnerReference { - k8sClient.Get(ctx, types.NamespacedName{Name: "dbod-" + key.Name, Namespace: key.Namespace}, &dbod) - return dbod.ObjectMeta.OwnerReferences - }, timeout, interval).Should(ContainElement(expectedOwnerReference)) - - // Update DBOD resource status field - By("Updating secret name in DBOD resource status") - Eventually(func() error { - k8sClient.Get(ctx, types.NamespacedName{Name: "dbod-" + key.Name, Namespace: key.Namespace}, &dbod) - dbod.Status.DbCredentialsSecret = "test" - return k8sClient.Status().Update(ctx, &dbod) - }, timeout, interval).Should(Succeed()) - - By("Expecting the drupal deployment to have the EnvFrom secret field set correctly") - Eventually(func() bool { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &deploy) - if len(deploy.Spec.Template.Spec.Containers) < 2 || len(deploy.Spec.Template.Spec.Containers[0].EnvFrom) == 0 || len(deploy.Spec.Template.Spec.Containers[1].EnvFrom) == 0 { - return false - } - if deploy.Spec.Template.Spec.Containers[0].EnvFrom[0].SecretRef.Name == "test" && deploy.Spec.Template.Spec.Containers[1].EnvFrom[0].SecretRef.Name == "test" { - return true - } - return false - }, timeout, interval).Should(BeTrue()) - - By("Expecting the drush job to have the EnvFrom secret field set correctly") - Eventually(func() bool { - k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-drush-" + key.Name, Namespace: key.Namespace}, &job) - if len(job.Spec.Template.Spec.Containers) == 0 || len(job.Spec.Template.Spec.Containers[0].EnvFrom) == 0 { - return false - } - if job.Spec.Template.Spec.Containers[0].EnvFrom[0].SecretRef.Name == "test" { - return true - } - return false - }, timeout, interval).Should(BeTrue()) // Check PHP-FPM configMap creation By("Expecting PHP_FPM configmaps created") @@ -541,6 +535,13 @@ var _ = Describe("DrupalSite controller", func() { return configmap.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + // Check MySQL configMap creation + By("Expecting MySQL configmaps created") + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "mysql-cm-" + key.Name, Namespace: key.Namespace}, &configmap) + return configmap.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + // Check Drupal service By("Expecting Drupal service created") Eventually(func() []v1.OwnerReference { @@ -548,6 +549,13 @@ var _ = Describe("DrupalSite controller", func() { return svc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + // Check MySQL service + By("Expecting MySQL service created") + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-mysql", Namespace: key.Namespace}, &svc) + return svc.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + // Check drupal persistentVolumeClaim By("Expecting drupal persistentVolumeClaim created") Eventually(func() []v1.OwnerReference { @@ -555,13 +563,27 @@ var _ = Describe("DrupalSite controller", func() { return pvc.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) - // Check Drupal deployments - By("Expecting Drupal deployments created") + // Check MySQL persistentVolumeClaim + By("Expecting MySQL persistentVolumeClaim created") + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "mysql-pv-claim-" + key.Name, Namespace: key.Namespace}, &pvc) + return pvc.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + + // Check Drupal deploymentConfigs + By("Expecting Drupal deploymentConfigs created") Eventually(func() []v1.OwnerReference { k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-" + key.Name, Namespace: key.Namespace}, &deploy) return deploy.ObjectMeta.OwnerReferences }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + // Check MySQL deploymentConfigs + By("Expecting MySQL deploymentConfigs created") + Eventually(func() []v1.OwnerReference { + k8sClient.Get(ctx, types.NamespacedName{Name: "drupal-mysql-" + key.Name, Namespace: key.Namespace}, &deploy) + return deploy.ObjectMeta.OwnerReferences + }, timeout, interval).Should(ContainElement(expectedOwnerReference)) + // Check PHP imageStream By("Expecting PHP imageStream created") Eventually(func() []v1.OwnerReference { diff --git a/controllers/drupalsite_resources.go b/controllers/drupalsite_resources.go index 2049939b..348239db 100644 --- a/controllers/drupalsite_resources.go +++ b/controllers/drupalsite_resources.go @@ -28,8 +28,6 @@ import ( buildv1 "github.com/openshift/api/build/v1" imagev1 "github.com/openshift/api/image/v1" routev1 "github.com/openshift/api/route/v1" - - dbodv1a1 "gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1" webservicesv1a1 "gitlab.cern.ch/drupal/paas/drupalsite-operator/api/v1alpha1" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" @@ -105,8 +103,8 @@ func ensureSpecFinalizer(drp *webservicesv1a1.DrupalSite, log logr.Logger) (upda } /* -ensureResources ensures the presence of all the resources that the DrupalSite needs to serve content. -This includes BuildConfigs/ImageStreams, DB, PVC, PHP/Nginx deployment + service, site install job, Routes. +ensureResources ensures the presence of all the resources that the DrupalSite needs to serve content, apart from the ingress Route. +This includes BuildConfigs/ImageStreams, DB, PVC, PHP/Nginx deployment + service, site install job. */ func (r *DrupalSiteReconciler) ensureResources(drp *webservicesv1a1.DrupalSite, log logr.Logger) (transientErrs []reconcileError) { ctx := context.TODO() @@ -139,8 +137,17 @@ func (r *DrupalSiteReconciler) ensureResources(drp *webservicesv1a1.DrupalSite, if transientErr := r.ensureResourceX(ctx, drp, "pvc_drupal", log); transientErr != nil { transientErrs = append(transientErrs, transientErr.Wrap("%v: for Drupal PVC")) } - if transientErr := r.ensureResourceX(ctx, drp, "dbod_cr", log); transientErr != nil { - transientErrs = append(transientErrs, transientErr.Wrap("%v: for DBOD resource")) + if transientErr := r.ensureResourceX(ctx, drp, "pvc_mysql", log); transientErr != nil { + transientErrs = append(transientErrs, transientErr.Wrap("%v: for MySQL PVC")) + } + if transientErr := r.ensureResourceX(ctx, drp, "deploy_mysql", log); transientErr != nil { + transientErrs = append(transientErrs, transientErr.Wrap("%v: for Mysql DC")) + } + if transientErr := r.ensureResourceX(ctx, drp, "svc_mysql", log); transientErr != nil { + transientErrs = append(transientErrs, transientErr.Wrap("%v: for Mysql SVC")) + } + if transientErr := r.ensureResourceX(ctx, drp, "cm_mysql", log); transientErr != nil { + transientErrs = append(transientErrs, transientErr.Wrap("%v: for MySQL CM")) } // 3. Serving layer @@ -151,30 +158,30 @@ func (r *DrupalSiteReconciler) ensureResources(drp *webservicesv1a1.DrupalSite, if transientErr := r.ensureResourceX(ctx, drp, "cm_nginx", log); transientErr != nil { transientErrs = append(transientErrs, transientErr.Wrap("%v: for Nginx CM")) } - if r.isDBODProvisioned(ctx, drp) { - if transientErr := r.ensureResourceX(ctx, drp, "deploy_drupal", log); transientErr != nil { - transientErrs = append(transientErrs, transientErr.Wrap("%v: for Drupal DC")) - } + if transientErr := r.ensureResourceX(ctx, drp, "deploy_drupal", log); transientErr != nil { + transientErrs = append(transientErrs, transientErr.Wrap("%v: for Drupal DC")) } if transientErr := r.ensureResourceX(ctx, drp, "svc_nginx", log); transientErr != nil { transientErrs = append(transientErrs, transientErr.Wrap("%v: for Nginx SVC")) } - if r.isDBODProvisioned(ctx, drp) { - if transientErr := r.ensureResourceX(ctx, drp, "site_install_job", log); transientErr != nil { - transientErrs = append(transientErrs, transientErr.Wrap("%v: for site install Job")) - } - } // 4. Ingress - if drp.ConditionTrue("Installed") && drp.ConditionTrue("Ready") { - if transientErr := r.ensureResourceX(ctx, drp, "route", log); transientErr != nil { - transientErrs = append(transientErrs, transientErr.Wrap("%v: for Route")) - } + if transientErr := r.ensureResourceX(ctx, drp, "site_install_job", log); transientErr != nil { + transientErrs = append(transientErrs, transientErr.Wrap("%v: for site install Job")) } return transientErrs } +// ensureIngressResources ensures the presence of the Route to access the website from the outside world +func (r *DrupalSiteReconciler) ensureIngressResources(drp *webservicesv1a1.DrupalSite, log logr.Logger) (transientErr reconcileError) { + ctx := context.TODO() + if transientErr := r.ensureResourceX(ctx, drp, "route", log); transientErr != nil { + return transientErr.Wrap("%v: for Route") + } + return nil +} + // labelsForDrupalSite returns the labels for selecting the resources // belonging to the given drupalSite CR name. func labelsForDrupalSite(name string) map[string]string { @@ -470,10 +477,13 @@ func buildConfigForDrupalSiteNginx(currentobject *buildv1.BuildConfig, d *webser return nil } -// dbodForDrupalSite returns a DBOD resource for the the Drupal Site -func dbodForDrupalSite(currentobject *dbodv1a1.DBODRegistration, d *webservicesv1a1.DrupalSite) error { +// deploymentForDrupalSiteMySQL returns a Deployment object for MySQL +func deploymentForDrupalSiteMySQL(currentobject *appsv1.Deployment, d *webservicesv1a1.DrupalSite) error { if currentobject.CreationTimestamp.IsZero() { addOwnerRefToObject(currentobject, asOwner(d)) + currentobject.Spec.Template.ObjectMeta.Annotations = map[string]string{ + "mysql-configmap-version": "1", + } } if currentobject.Labels == nil { currentobject.Labels = map[string]string{} @@ -483,23 +493,80 @@ func dbodForDrupalSite(currentobject *dbodv1a1.DBODRegistration, d *webservicesv return nil } ls := labelsForDrupalSite(d.Name) - ls["app"] = "dbod" + ls["app"] = "mysql" for k, v := range ls { currentobject.Labels[k] = v } - currentobject.Spec = dbodv1a1.DBODRegistrationSpec{ - DbodClass: string(d.Spec.Environment.DBODClass), - DbName: string(d.Namespace + "-" + d.Name), - DbUser: string(d.Namespace + "-" + d.Name), - RegistrationLabels: map[string]string{ - "drupalSite": d.Name, + currentobject.Spec.Replicas = pointer.Int32Ptr(1) + currentobject.Spec.Selector = &metav1.LabelSelector{ + MatchLabels: ls, + } + currentobject.Spec.Template.ObjectMeta.Labels = ls + + currentobject.Spec.Template.Spec = corev1.PodSpec{ + Containers: []corev1.Container{{ + Image: "mysql:5.7", + Name: "mysql", + ImagePullPolicy: "IfNotPresent", + Ports: []corev1.ContainerPort{{ + ContainerPort: 3306, + Name: "mysql", + Protocol: "TCP", + }}, + Env: []corev1.EnvVar{ + { + Name: "MYSQL_DATABASE", + Value: "drupal", + }, + { + Name: "MYSQL_ROOT_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + Key: "DB_PASSWORD", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "drupal-mysql-secret", + }, + }, + }, + }, + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "mysql-persistent-storage", + MountPath: "/var/lib/mysql", + }, + { + Name: "config-volume", + MountPath: "/etc/mysql/conf.d/mysql-config.cnf", + SubPath: "mysql-config.cnf", + }}, + }}, + Volumes: []corev1.Volume{ + { + Name: "mysql-persistent-storage", + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: "mysql-pv-claim-" + d.Name, + }, + }, + }, + { + Name: "config-volume", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "mysql-cm-" + d.Name, + }, + }, + }, + }, }, } return nil } // deploymentForDrupalSite defines the server runtime deployment of a DrupalSite -func deploymentForDrupalSite(currentobject *appsv1.Deployment, dbodSecret string, d *webservicesv1a1.DrupalSite) error { +func deploymentForDrupalSite(currentobject *appsv1.Deployment, d *webservicesv1a1.DrupalSite) error { if currentobject.CreationTimestamp.IsZero() { addOwnerRefToObject(currentobject, asOwner(d)) currentobject.Annotations = map[string]string{ @@ -548,7 +615,7 @@ func deploymentForDrupalSite(currentobject *appsv1.Deployment, dbodSecret string { SecretRef: &corev1.SecretEnvSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: dbodSecret, + Name: "drupal-mysql-secret", }, }, }, @@ -588,7 +655,7 @@ func deploymentForDrupalSite(currentobject *appsv1.Deployment, dbodSecret string { SecretRef: &corev1.SecretEnvSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: dbodSecret, + Name: "drupal-mysql-secret", }, }, }, @@ -646,6 +713,38 @@ func deploymentForDrupalSite(currentobject *appsv1.Deployment, dbodSecret string return nil } +// persistentVolumeClaimForMySQL returns a PVC object +func persistentVolumeClaimForMySQL(currentobject *corev1.PersistentVolumeClaim, d *webservicesv1a1.DrupalSite) error { + if currentobject.CreationTimestamp.IsZero() { + addOwnerRefToObject(currentobject, asOwner(d)) + currentobject.Spec = corev1.PersistentVolumeClaimSpec{ + // Selector: &metav1.LabelSelector{ + // MatchLabels: ls, + // }, + StorageClassName: pointer.StringPtr("cephfs-no-backup"), + AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceName(corev1.ResourceStorage): resource.MustParse("5Gi"), + }, + }, + } + } + if currentobject.Labels == nil { + currentobject.Labels = map[string]string{} + } + if len(currentobject.GetAnnotations()[adminAnnotation]) > 0 { + // Do nothing + return nil + } + ls := labelsForDrupalSite(d.Name) + ls["app"] = "mysql" + for k, v := range ls { + currentobject.Labels[k] = v + } + return nil +} + // persistentVolumeClaimForDrupalSite returns a PVC object func persistentVolumeClaimForDrupalSite(currentobject *corev1.PersistentVolumeClaim, d *webservicesv1a1.DrupalSite) error { if currentobject.CreationTimestamp.IsZero() { @@ -705,6 +804,33 @@ func serviceForDrupalSite(currentobject *corev1.Service, d *webservicesv1a1.Drup return nil } +// serviceForDrupalSiteMySQL returns a service object for MySQL +func serviceForDrupalSiteMySQL(currentobject *corev1.Service, d *webservicesv1a1.DrupalSite) error { + if currentobject.CreationTimestamp.IsZero() { + addOwnerRefToObject(currentobject, asOwner(d)) + } + if currentobject.Labels == nil { + currentobject.Labels = map[string]string{} + } + if len(currentobject.GetAnnotations()[adminAnnotation]) > 0 { + // Do nothing + return nil + } + ls := labelsForDrupalSite(d.Name) + ls["app"] = "mysql" + for k, v := range ls { + currentobject.Labels[k] = v + } + currentobject.Spec.Selector = ls + currentobject.Spec.Ports = []corev1.ServicePort{{ + TargetPort: intstr.FromInt(3306), + Name: "mysql", + Port: 3306, + Protocol: "TCP", + }} + return nil +} + // routeForDrupalSite returns a route object func routeForDrupalSite(currentobject *routev1.Route, d *webservicesv1a1.DrupalSite) error { if currentobject.CreationTimestamp.IsZero() { @@ -743,7 +869,7 @@ func routeForDrupalSite(currentobject *routev1.Route, d *webservicesv1a1.DrupalS } // jobForDrupalSiteDrush returns a job object thats runs drush -func jobForDrupalSiteDrush(currentobject *batchv1.Job, dbodSecret string, d *webservicesv1a1.DrupalSite) error { +func jobForDrupalSiteDrush(currentobject *batchv1.Job, d *webservicesv1a1.DrupalSite) error { ls := labelsForDrupalSite(d.Name) if currentobject.CreationTimestamp.IsZero() { addOwnerRefToObject(currentobject, asOwner(d)) @@ -784,7 +910,7 @@ func jobForDrupalSiteDrush(currentobject *batchv1.Job, dbodSecret string, d *web { SecretRef: &corev1.SecretEnvSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: dbodSecret, + Name: "drupal-mysql-secret", }, }, }, @@ -912,8 +1038,60 @@ func updateConfigMapForNginx(ctx context.Context, currentobject *corev1.ConfigMa return nil } +// updateConfigMapForMySQL ensures a configmap object to configure MySQL if not present. Else configmap object is updated and a new rollout is triggered +func updateConfigMapForMySQL(ctx context.Context, currentobject *corev1.ConfigMap, d *webservicesv1a1.DrupalSite, c client.Client) error { + if currentobject.CreationTimestamp.IsZero() { + addOwnerRefToObject(currentobject, asOwner(d)) + } + if currentobject.Labels == nil { + currentobject.Labels = map[string]string{} + } + if len(currentobject.GetAnnotations()[adminAnnotation]) > 0 { + // Do nothing + return nil + } + ls := labelsForDrupalSite(d.Name) + ls["app"] = "mysql" + for k, v := range ls { + currentobject.Labels[k] = v + } + + configPath := "/tmp/qos-" + string(d.Spec.Environment.QoSClass) + "/mysql-config.cnf" + + content, err := ioutil.ReadFile(configPath) + if err != nil { + return newApplicationError(fmt.Errorf("reading MySQL configuration failed: %w", err), ErrFilesystemIO) + } + + currentConfig := currentobject.Data["mysql-config.cnf"] + currentobject.Data = map[string]string{ + "mysql-config.cnf": string(content), + } + + if !currentobject.CreationTimestamp.IsZero() { + if currentConfig != string(content) { + // Roll out a new deployment + deploy := &appsv1.Deployment{} + err = c.Get(ctx, types.NamespacedName{Name: "drupal-" + d.Name, Namespace: d.Namespace}, deploy) + if err != nil { + return newApplicationError(fmt.Errorf("Failed to roll out new deployment while updating the MySQL configMap (deployment not found): %w", err), ErrClientK8s) + } + currentVersion, _ := strconv.Atoi(deploy.Spec.Template.ObjectMeta.Annotations["mysql-configmap-version"]) + deploy.Spec.Template.ObjectMeta.Annotations["mysql-configmap-version"] = strconv.Itoa(currentVersion + 1) + if err := c.Update(ctx, deploy); err != nil { + return newApplicationError(fmt.Errorf("Failed to roll out new deployment while updating the MySQL configMap: %w", err), ErrClientK8s) + } + } + } + return nil +} + /* ensureResourceX ensure the requested resource is created, with the following valid values + - deploy_mysql: Deployment for MySQL + - svc_mysql: Service for MySQL + - cm_mysql: Configmap for MySQL + - pvc_mysql: PersistentVolume for the MySQL - pvc_drupal: PersistentVolume for the drupalsite - site_install_job: Kubernetes Job for the drush site-install - is_base: ImageStream for sitebuilder-base @@ -928,7 +1106,6 @@ ensureResourceX ensure the requested resource is created, with the following val - cm_php: ConfigMap for PHP-FPM - cm_nginx: ConfigMap for Nginx - route: Route for the drupalsite - - dbod_cr: DBOD custom resource to establish database & respective connection for the drupalsite */ func (r *DrupalSiteReconciler) ensureResourceX(ctx context.Context, d *webservicesv1a1.DrupalSite, resType string, log logr.Logger) (transientErr reconcileError) { switch resType { @@ -998,17 +1175,37 @@ func (r *DrupalSiteReconciler) ensureResourceX(ctx context.Context, d *webservic return newApplicationError(err, ErrClientK8s) } return nil + case "deploy_mysql": + deploy := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "drupal-mysql-" + d.Name, Namespace: d.Namespace}} + _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, deploy, func() error { + log.Info("Ensuring Resource", "Kind", deploy.TypeMeta.Kind, "Resource.Namespace", deploy.Namespace, "Resource.Name", deploy.Name) + return deploymentForDrupalSiteMySQL(deploy, d) + }) + if err != nil { + log.Error(err, "Failed to ensure Resource", "Kind", deploy.TypeMeta.Kind, "Resource.Namespace", deploy.Namespace, "Resource.Name", deploy.Name) + return newApplicationError(err, ErrClientK8s) + } + return nil case "deploy_drupal": - if dbodSecret := r.getDBODProvisionedSecret(ctx, d); len(dbodSecret) != 0 { - deploy := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "drupal-" + d.Name, Namespace: d.Namespace}} - _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, deploy, func() error { - log.Info("Ensuring Resource", "Kind", deploy.TypeMeta.Kind, "Resource.Namespace", deploy.Namespace, "Resource.Name", deploy.Name) - return deploymentForDrupalSite(deploy, dbodSecret, d) - }) - if err != nil { - log.Error(err, "Failed to ensure Resource", "Kind", deploy.TypeMeta.Kind, "Resource.Namespace", deploy.Namespace, "Resource.Name", deploy.Name) - return newApplicationError(err, ErrClientK8s) - } + deploy := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "drupal-" + d.Name, Namespace: d.Namespace}} + _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, deploy, func() error { + log.Info("Ensuring Resource", "Kind", deploy.TypeMeta.Kind, "Resource.Namespace", deploy.Namespace, "Resource.Name", deploy.Name) + return deploymentForDrupalSite(deploy, d) + }) + if err != nil { + log.Error(err, "Failed to ensure Resource", "Kind", deploy.TypeMeta.Kind, "Resource.Namespace", deploy.Namespace, "Resource.Name", deploy.Name) + return newApplicationError(err, ErrClientK8s) + } + return nil + case "svc_mysql": + svc := &corev1.Service{ObjectMeta: metav1.ObjectMeta{Name: "drupal-mysql", Namespace: d.Namespace}} + _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, svc, func() error { + log.Info("Ensuring Resource", "Kind", svc.TypeMeta.Kind, "Resource.Namespace", svc.Namespace, "Resource.Name", svc.Name) + return serviceForDrupalSiteMySQL(svc, d) + }) + if err != nil { + log.Error(err, "Failed to ensure Resource", "Kind", svc.TypeMeta.Kind, "Resource.Namespace", svc.Namespace, "Resource.Name", svc.Name) + return newApplicationError(err, ErrClientK8s) } return nil case "svc_nginx": @@ -1022,6 +1219,17 @@ func (r *DrupalSiteReconciler) ensureResourceX(ctx context.Context, d *webservic return newApplicationError(err, ErrClientK8s) } return nil + case "pvc_mysql": + pvc := &corev1.PersistentVolumeClaim{ObjectMeta: metav1.ObjectMeta{Name: "mysql-pv-claim-" + d.Name, Namespace: d.Namespace}} + _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, pvc, func() error { + log.Info("Ensuring Resource", "Kind", pvc.TypeMeta.Kind, "Resource.Namespace", pvc.Namespace, "Resource.Name", pvc.Name) + return persistentVolumeClaimForMySQL(pvc, d) + }) + if err != nil { + log.Error(err, "Failed to ensure Resource", "Kind", pvc.TypeMeta.Kind, "Resource.Namespace", pvc.Namespace, "Resource.Name", pvc.Name) + return newApplicationError(err, ErrClientK8s) + } + return nil case "pvc_drupal": pvc := &corev1.PersistentVolumeClaim{ObjectMeta: metav1.ObjectMeta{Name: "drupal-pv-claim-" + d.Name, Namespace: d.Namespace}} _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, pvc, func() error { @@ -1045,16 +1253,14 @@ func (r *DrupalSiteReconciler) ensureResourceX(ctx context.Context, d *webservic } return nil case "site_install_job": - if dbodSecret := r.getDBODProvisionedSecret(ctx, d); len(dbodSecret) != 0 { - job := &batchv1.Job{ObjectMeta: metav1.ObjectMeta{Name: "drupal-drush-" + d.Name, Namespace: d.Namespace}} - _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, job, func() error { - log.Info("Ensuring Resource", "Kind", job.TypeMeta.Kind, "Resource.Namespace", job.Namespace, "Resource.Name", job.Name) - return jobForDrupalSiteDrush(job, dbodSecret, d) - }) - if err != nil { - log.Error(err, "Failed to ensure Resource", "Kind", job.TypeMeta.Kind, "Resource.Namespace", job.Namespace, "Resource.Name", job.Name) - return newApplicationError(err, ErrClientK8s) - } + job := &batchv1.Job{ObjectMeta: metav1.ObjectMeta{Name: "drupal-drush-" + d.Name, Namespace: d.Namespace}} + _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, job, func() error { + log.Info("Ensuring Resource", "Kind", job.TypeMeta.Kind, "Resource.Namespace", job.Namespace, "Resource.Name", job.Name) + return jobForDrupalSiteDrush(job, d) + }) + if err != nil { + log.Error(err, "Failed to ensure Resource", "Kind", job.TypeMeta.Kind, "Resource.Namespace", job.Namespace, "Resource.Name", job.Name) + return newApplicationError(err, ErrClientK8s) } return nil case "cm_php": @@ -1068,25 +1274,25 @@ func (r *DrupalSiteReconciler) ensureResourceX(ctx context.Context, d *webservic return newApplicationError(err, ErrClientK8s) } return nil - case "cm_nginx": - cm := &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "nginx-cm-" + d.Name, Namespace: d.Namespace}} + case "cm_mysql": + cm := &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "mysql-cm-" + d.Name, Namespace: d.Namespace}} _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, cm, func() error { log.Info("Ensuring Resource", "Kind", cm.TypeMeta.Kind, "Resource.Namespace", cm.Namespace, "Resource.Name", cm.Name) - return updateConfigMapForNginx(ctx, cm, d, r.Client) + return updateConfigMapForMySQL(ctx, cm, d, r.Client) }) if err != nil { log.Error(err, "Failed to ensure Resource", "Kind", cm.TypeMeta.Kind, "Resource.Namespace", cm.Namespace, "Resource.Name", cm.Name) return newApplicationError(err, ErrClientK8s) } return nil - case "dbod_cr": - dbod := &dbodv1a1.DBODRegistration{ObjectMeta: metav1.ObjectMeta{Name: "dbod-" + d.Name, Namespace: d.Namespace}} - _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, dbod, func() error { - log.Info("Ensuring Resource", "Kind", dbod.TypeMeta.Kind, "Resource.Namespace", dbod.Namespace, "Resource.Name", dbod.Name) - return dbodForDrupalSite(dbod, d) + case "cm_nginx": + cm := &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "nginx-cm-" + d.Name, Namespace: d.Namespace}} + _, err := controllerruntime.CreateOrUpdate(ctx, r.Client, cm, func() error { + log.Info("Ensuring Resource", "Kind", cm.TypeMeta.Kind, "Resource.Namespace", cm.Namespace, "Resource.Name", cm.Name) + return updateConfigMapForNginx(ctx, cm, d, r.Client) }) if err != nil { - log.Error(err, "Failed to ensure Resource", "Kind", dbod.TypeMeta.Kind, "Resource.Namespace", dbod.Namespace, "Resource.Name", dbod.Name) + log.Error(err, "Failed to ensure Resource", "Kind", cm.TypeMeta.Kind, "Resource.Namespace", cm.Namespace, "Resource.Name", cm.Name) return newApplicationError(err, ErrClientK8s) } return nil @@ -1158,21 +1364,6 @@ func (r *DrupalSiteReconciler) isDrupalSiteReady(ctx context.Context, d *webserv return false } -// isDBODProvisioned checks if the DBOD has been provisioned by checking the status of DBOD custom resource -func (r *DrupalSiteReconciler) isDBODProvisioned(ctx context.Context, d *webservicesv1a1.DrupalSite) bool { - return len(r.getDBODProvisionedSecret(ctx, d)) > 0 -} - -// getDBODProvisionedSecret fetches the secret name of the DBOD provisioned secret by checking the status of DBOD custom resource -func (r *DrupalSiteReconciler) getDBODProvisionedSecret(ctx context.Context, d *webservicesv1a1.DrupalSite) string { - dbodCR := &dbodv1a1.DBODRegistration{ObjectMeta: metav1.ObjectMeta{Name: "dbod-" + d.Name, Namespace: d.Namespace}} - err1 := r.Get(ctx, types.NamespacedName{Name: dbodCR.Name, Namespace: dbodCR.Namespace}, dbodCR) - if err1 == nil { - return dbodCR.Status.DbCredentialsSecret - } - return "" -} - // siteInstallJobForDrupalSite outputs the command needed for jobForDrupalSiteDrush func siteInstallJobForDrupalSite() []string { // return []string{"sh", "-c", "echo"} diff --git a/controllers/error_types.go b/controllers/error_types.go index 840ba4df..db9029cd 100644 --- a/controllers/error_types.go +++ b/controllers/error_types.go @@ -15,7 +15,6 @@ var ( ErrFunctionDomain = errors.New("FunctionDomainError") ErrClientK8s = errors.New("k8sAPIClientError") ErrFilesystemIO = errors.New("FilesystemIOError") - ErrDBOD = errors.New("DBODError") ) type reconcileError interface { diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 16e21057..0910da86 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -22,7 +22,6 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - dbodv1a1 "gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1" drupalwebservicesv1alpha1 "gitlab.cern.ch/drupal/paas/drupalsite-operator/api/v1alpha1" "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -74,10 +73,10 @@ var _ = BeforeSuite(func(done Done) { filepath.Join("..", "config", "crd", "bases"), filepath.Join("..", "testResources", "mock_crd"), }, - BinaryAssetsDirectory: filepath.Join("..", "testbin", "bin"), - ErrorIfCRDPathMissing: true, - KubeAPIServerFlags: apiServerFlags, - // AttachControlPlaneOutput: true, + BinaryAssetsDirectory: filepath.Join("..", "testbin", "bin"), + ErrorIfCRDPathMissing: true, + KubeAPIServerFlags: apiServerFlags, + AttachControlPlaneOutput: true, } err := drupalwebservicesv1alpha1.AddToScheme(scheme) Expect(err).NotTo(HaveOccurred()) @@ -86,9 +85,6 @@ var _ = BeforeSuite(func(done Done) { err = clientgoscheme.AddToScheme(scheme) Expect(err).NotTo(HaveOccurred()) - err = dbodv1a1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - err = buildv1.AddToScheme(scheme) Expect(err).NotTo(HaveOccurred()) diff --git a/go.mod b/go.mod index 4fa1dede..ffc1ddfc 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/onsi/gomega v1.10.2 github.com/openshift/api v0.0.0-20201126092428-04abbec6c099 github.com/operator-framework/operator-lib v0.1.0 - gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312144809-29eb48685cf7 k8s.io/api v0.19.2 k8s.io/apimachinery v0.19.2 k8s.io/client-go v0.19.2 diff --git a/go.sum b/go.sum index 514a2b94..5f0d28db 100644 --- a/go.sum +++ b/go.sum @@ -437,19 +437,6 @@ github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210119225708-900ca5bbbfe7 h1:9kZ9H4jqVg5heUP5IY4gRewpy1l+qWOdeyBOSd2NizQ= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312110617-37b8b6dcb513 h1:2cEJR4KQr17rXkN/UD/BbWNDSnrXvkCFvoXJLYkTeb4= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312110617-37b8b6dcb513/go.mod h1:puUnn3MDKHTUdDbVitOG+nYgrnm8R9VdzJNrQafEhFU= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312133521-97c04a204e9a h1:V6UjpaqglRGsGjo+EfBgAVM+ypHj3ZklwoLJYCHHIh0= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312133521-97c04a204e9a/go.mod h1:puUnn3MDKHTUdDbVitOG+nYgrnm8R9VdzJNrQafEhFU= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312133849-37479298a0dd h1:jke80+7wpmYWhEM+/TlOOocmsYAVyqNl5uS0E5T0VFI= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312133849-37479298a0dd/go.mod h1:puUnn3MDKHTUdDbVitOG+nYgrnm8R9VdzJNrQafEhFU= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312134124-05e1ae37ce11 h1:T7pi0K54Vc0kscQKPYPsV5R4E5tTp0P7k21ihea4oVk= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312134124-05e1ae37ce11/go.mod h1:puUnn3MDKHTUdDbVitOG+nYgrnm8R9VdzJNrQafEhFU= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312134323-fbc6a3e88886 h1:fVaVkmUn0jHbOcagf8suyOebY6yRNkOxIdvjXP38jj4= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312134323-fbc6a3e88886/go.mod h1:puUnn3MDKHTUdDbVitOG+nYgrnm8R9VdzJNrQafEhFU= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312144809-29eb48685cf7 h1:uNsaE6zOE11C6U+Q8QgUragUhp19cEfxm++E026sTg0= -gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312144809-29eb48685cf7/go.mod h1:puUnn3MDKHTUdDbVitOG+nYgrnm8R9VdzJNrQafEhFU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= diff --git a/main.go b/main.go index 0c15a614..6681d6f6 100644 --- a/main.go +++ b/main.go @@ -24,9 +24,6 @@ import ( // to ensure that exec-entrypoint and run can make use of them. _ "k8s.io/client-go/plugin/pkg/client/auth" - dbodv1a1 "gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1" - drupalwebservicesv1alpha1 "gitlab.cern.ch/drupal/paas/drupalsite-operator/api/v1alpha1" - "gitlab.cern.ch/drupal/paas/drupalsite-operator/controllers" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -34,6 +31,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" + drupalwebservicesv1alpha1 "gitlab.cern.ch/drupal/paas/drupalsite-operator/api/v1alpha1" + "gitlab.cern.ch/drupal/paas/drupalsite-operator/controllers" + // +kubebuilder:scaffold:imports buildv1 "github.com/openshift/api/build/v1" imagev1 "github.com/openshift/api/image/v1" @@ -50,7 +50,6 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(drupalwebservicesv1alpha1.AddToScheme(scheme)) - utilruntime.Must(dbodv1a1.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme utilruntime.Must(appsv1.AddToScheme(scheme)) utilruntime.Must(routev1.AddToScheme(scheme)) diff --git a/testResources/mock_crd/dbod.cern_dbodclasses.yaml b/testResources/mock_crd/dbod.cern_dbodclasses.yaml deleted file mode 100644 index 328b41cf..00000000 --- a/testResources/mock_crd/dbod.cern_dbodclasses.yaml +++ /dev/null @@ -1,49 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: dbodclasses.dbod.cern -spec: - group: dbod.cern - names: - kind: DBODClass - listKind: DBODClassList - plural: dbodclasses - singular: dbodclass - scope: Cluster - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: DBODClass is the Schema for the dbodclasses API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of DBODClass - type: object - x-kubernetes-preserve-unknown-fields: true - properties: - instances: - items: - type: string - type: array - status: - description: Status defines the observed state of DBODClass - type: object - x-kubernetes-preserve-unknown-fields: true - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testResources/mock_crd/dbod.cern_dbodregistrations.yaml b/testResources/mock_crd/dbod.cern_dbodregistrations.yaml deleted file mode 100644 index 971b02aa..00000000 --- a/testResources/mock_crd/dbod.cern_dbodregistrations.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: dbodregistrations.dbod.cern -spec: - group: dbod.cern - names: - kind: DBODRegistration - listKind: DBODRegistrationList - plural: dbodregistrations - singular: dbodregistration - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: DBODRegistration is the Schema for the dbodregistrations API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of DBODRegistration - type: object - properties: - dbodClass: - description: 'Name of the required DB Quality of Service level (consult the `DBODClass`es supported by the cluster)' - type: string - dbodInstanceName: - description: '[exceptional] Request to create the new DB on a specific DBOD instance' - type: string - dbName: - type: string - dbUser: - type: string - registrationLabels: - description: 'Labels to be assigned to the secret that will be created the operator (useful with "label selector")' - type: object - x-kubernetes-preserve-unknown-fields: true - required: - - dbName - - dbUser - - registrationLabels - status: - description: Status defines the observed state of DBODRegistration - type: object - x-kubernetes-preserve-unknown-fields: true - properties: - dbodInstance: - type: string - dbCredentialsSecret: - type: string - type: object - served: true - storage: true - subresources: - status: {} diff --git a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/LICENSE b/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/LICENSE deleted file mode 100644 index 59a27fe3..00000000 --- a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 drupal / paas - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/dbodclass_types.go b/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/dbodclass_types.go deleted file mode 100644 index 229b81e1..00000000 --- a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/dbodclass_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2021. - -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 v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// DBODClassSpec defines the desired state of DBODClass -type DBODClassSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Foo is an example field of DBODClass. Edit DBODClass_types.go to remove/update - Foo string `json:"foo,omitempty"` -} - -// DBODClassStatus defines the observed state of DBODClass -type DBODClassStatus 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 - -// DBODClass is the Schema for the dbodclasses API -type DBODClass struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec DBODClassSpec `json:"spec,omitempty"` - Status DBODClassStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// DBODClassList contains a list of DBODClass -type DBODClassList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []DBODClass `json:"items"` -} - -func init() { - SchemeBuilder.Register(&DBODClass{}, &DBODClassList{}) -} diff --git a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/dbodregistration_types.go b/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/dbodregistration_types.go deleted file mode 100644 index 910d62ba..00000000 --- a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/dbodregistration_types.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2021. - -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 v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// DBODRegistrationSpec defines the desired state of DBODRegistration -type DBODRegistrationSpec struct { - DbodClass string `json:"dbodClass,omitempty"` - DbodInstanceName string `json:"dbodInstanceName,omitempty"` - DbName string `json:"dbName"` - DbUser string `json:"dbUser"` - RegistrationLabels map[string]string `json:"registrationLabels,omitempty"` -} - -// DBODRegistrationStatus defines the observed state of DBODRegistration -type DBODRegistrationStatus struct { - DbodInstance string `json:"dbodInstance,omitempty"` - DbCredentialsSecret string `json:"dbCredentialsSecret,omitempty"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status - -// DBODRegistration is the Schema for the dbodregistrations API -type DBODRegistration struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec DBODRegistrationSpec `json:"spec,omitempty"` - Status DBODRegistrationStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// DBODRegistrationList contains a list of DBODRegistration -type DBODRegistrationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []DBODRegistration `json:"items"` -} - -func init() { - SchemeBuilder.Register(&DBODRegistration{}, &DBODRegistrationList{}) -} diff --git a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/groupversion_info.go b/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/groupversion_info.go deleted file mode 100644 index 75579cab..00000000 --- a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2021. - -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 v1alpha1 contains API Schema definitions for the dbod.cern v1alpha1 API group -// +kubebuilder:object:generate=true -// +groupName=dbod.cern -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -var ( - // GroupVersion is group version used to register these objects - GroupVersion = schema.GroupVersion{Group: "dbod.cern", Version: "v1alpha1"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} - - // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme -) diff --git a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/zz_generated.deepcopy.go b/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index 12633e16..00000000 --- a/vendor/gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,210 +0,0 @@ -// +build !ignore_autogenerated - -/* -Copyright 2021. - -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. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DBODClass) DeepCopyInto(out *DBODClass) { - *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 DBODClass. -func (in *DBODClass) DeepCopy() *DBODClass { - if in == nil { - return nil - } - out := new(DBODClass) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DBODClass) 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 *DBODClassList) DeepCopyInto(out *DBODClassList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]DBODClass, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DBODClassList. -func (in *DBODClassList) DeepCopy() *DBODClassList { - if in == nil { - return nil - } - out := new(DBODClassList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DBODClassList) 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 *DBODClassSpec) DeepCopyInto(out *DBODClassSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DBODClassSpec. -func (in *DBODClassSpec) DeepCopy() *DBODClassSpec { - if in == nil { - return nil - } - out := new(DBODClassSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DBODClassStatus) DeepCopyInto(out *DBODClassStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DBODClassStatus. -func (in *DBODClassStatus) DeepCopy() *DBODClassStatus { - if in == nil { - return nil - } - out := new(DBODClassStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DBODRegistration) DeepCopyInto(out *DBODRegistration) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DBODRegistration. -func (in *DBODRegistration) DeepCopy() *DBODRegistration { - if in == nil { - return nil - } - out := new(DBODRegistration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DBODRegistration) 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 *DBODRegistrationList) DeepCopyInto(out *DBODRegistrationList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]DBODRegistration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DBODRegistrationList. -func (in *DBODRegistrationList) DeepCopy() *DBODRegistrationList { - if in == nil { - return nil - } - out := new(DBODRegistrationList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DBODRegistrationList) 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 *DBODRegistrationSpec) DeepCopyInto(out *DBODRegistrationSpec) { - *out = *in - if in.RegistrationLabels != nil { - in, out := &in.RegistrationLabels, &out.RegistrationLabels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DBODRegistrationSpec. -func (in *DBODRegistrationSpec) DeepCopy() *DBODRegistrationSpec { - if in == nil { - return nil - } - out := new(DBODRegistrationSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DBODRegistrationStatus) DeepCopyInto(out *DBODRegistrationStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DBODRegistrationStatus. -func (in *DBODRegistrationStatus) DeepCopy() *DBODRegistrationStatus { - if in == nil { - return nil - } - out := new(DBODRegistrationStatus) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 341e2063..0d819948 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -141,9 +141,6 @@ github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util # github.com/spf13/pflag v1.0.5 github.com/spf13/pflag -# gitlab.cern.ch/drupal/paas/dbod-operator v0.0.0-20210312144809-29eb48685cf7 -## explicit -gitlab.cern.ch/drupal/paas/dbod-operator/go/api/v1alpha1 # go.uber.org/atomic v1.6.0 go.uber.org/atomic # go.uber.org/multierr v1.5.0 -- GitLab