From b06dd71693ad07c98e650ed672691610d23a653c Mon Sep 17 00:00:00 2001
From: Jack Henschel <jack.henschel@cern.ch>
Date: Tue, 17 Jan 2023 18:49:44 +0100
Subject: [PATCH 1/5] Standardize project blocking label

---
 controllers/reconciler_common.go | 35 ++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/controllers/reconciler_common.go b/controllers/reconciler_common.go
index eac4c371..a152e432 100644
--- a/controllers/reconciler_common.go
+++ b/controllers/reconciler_common.go
@@ -59,6 +59,8 @@ type DeploymentConfig struct {
 	drupalLogsResources  corev1.ResourceRequirements
 }
 
+const projectBlockedLabel = "okd.cern.ch/project-blocked"
+
 func setReady(drp *webservicesv1a1.DrupalSite) (update bool) {
 	return drp.Status.Conditions.SetCondition(status.Condition{
 		Type:   "Ready",
@@ -455,21 +457,28 @@ func backupListUpdateNeeded(veleroBackupsList []velerov1.Backup, statusBackupsLi
 
 // expectedDeploymentReplicas calculates expected replicas of deployment
 func expectedDeploymentReplicas(currentnamespace *corev1.Namespace, qosClass webservicesv1a1.QoSClass) (int32, error) {
-	_, isBlockedTimestampAnnotationSet := currentnamespace.Annotations["blocked.webservices.cern.ch/blocked-timestamp"]
-	_, isBlockedReasonAnnotationSet := currentnamespace.Annotations["blocked.webservices.cern.ch/reason"]
-	blocked := isBlockedTimestampAnnotationSet && isBlockedReasonAnnotationSet
-	notBlocked := !isBlockedTimestampAnnotationSet && !isBlockedReasonAnnotationSet
-	switch {
-	case !blocked && !notBlocked:
-		return 0, fmt.Errorf("both annotations blocked.webservices.cern.ch/blocked-timestamp and blocked.webservices.cern.ch/reason should be added/removed to block/unblock")
-	case blocked:
+	// websites in blocked projects should be scaled to zero replicas
+	// this causes HAProxy routers to return "503 Application not available"
+	if projectBlocked(currentnamespace) {
 		return 0, nil
-	default:
-		if qosClass == webservicesv1a1.QoSCritical {
-			return 3, nil
-		}
-		return 1, nil
 	}
+
+	// websites with "critical" QoS should be scaled to three replicas,
+	// so they have one pod per availability zone
+	if qosClass == webservicesv1a1.QoSCritical {
+		return 3, nil
+	}
+
+	// regular websites should have a single replica
+	return 1, nil
+}
+
+func projectBlocked(namespace v1.Namespace) bool {
+	value, found := namespace.ObjectMeta.Labels[projectBlockedLabel]
+	if found && value == "true" {
+		return true
+	}
+	return false
 }
 
 // containerExists checks if a container exists on the deployment
-- 
GitLab


From 6697fc5580da00152a297b0c9359747769a918e6 Mon Sep 17 00:00:00 2001
From: Jack Henschel <jack.henschel@cern.ch>
Date: Tue, 17 Jan 2023 18:57:44 +0100
Subject: [PATCH 2/5] fix

---
 controllers/reconciler_common.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/controllers/reconciler_common.go b/controllers/reconciler_common.go
index a152e432..771d116b 100644
--- a/controllers/reconciler_common.go
+++ b/controllers/reconciler_common.go
@@ -473,7 +473,7 @@ func expectedDeploymentReplicas(currentnamespace *corev1.Namespace, qosClass web
 	return 1, nil
 }
 
-func projectBlocked(namespace v1.Namespace) bool {
+func projectBlocked(namespace corev1.Namespace) bool {
 	value, found := namespace.ObjectMeta.Labels[projectBlockedLabel]
 	if found && value == "true" {
 		return true
-- 
GitLab


From 8750f004e81e69ae660b8d3d294ebe97e91ff4d8 Mon Sep 17 00:00:00 2001
From: Jack Henschel <jack.henschel@cern.ch>
Date: Tue, 17 Jan 2023 21:57:00 +0100
Subject: [PATCH 3/5] fix

---
 controllers/reconciler_common.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/controllers/reconciler_common.go b/controllers/reconciler_common.go
index 771d116b..b37a2721 100644
--- a/controllers/reconciler_common.go
+++ b/controllers/reconciler_common.go
@@ -459,7 +459,7 @@ func backupListUpdateNeeded(veleroBackupsList []velerov1.Backup, statusBackupsLi
 func expectedDeploymentReplicas(currentnamespace *corev1.Namespace, qosClass webservicesv1a1.QoSClass) (int32, error) {
 	// websites in blocked projects should be scaled to zero replicas
 	// this causes HAProxy routers to return "503 Application not available"
-	if projectBlocked(currentnamespace) {
+	if projectBlocked(*currentnamespace) {
 		return 0, nil
 	}
 
-- 
GitLab


From 1379593abd7ce0d43586ad76b5444b99e82c8717 Mon Sep 17 00:00:00 2001
From: Jack Henschel <jack.henschel@cern.ch>
Date: Wed, 18 Jan 2023 09:06:37 +0100
Subject: [PATCH 4/5] adjust tests

---
 controllers/drupalsite_controller_test.go | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/controllers/drupalsite_controller_test.go b/controllers/drupalsite_controller_test.go
index 98258e1d..5bc80362 100644
--- a/controllers/drupalsite_controller_test.go
+++ b/controllers/drupalsite_controller_test.go
@@ -495,17 +495,17 @@ var _ = Describe("DrupalSite controller", func() {
 					return k8sClient.Get(ctx, key, &cr)
 				}, timeout, interval).Should(Succeed())
 
-				By("Adding label to namespace")
+				By("Adding user-project label to namespace")
 				Eventually(func() error {
 					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace}, &namespace)
 					namespace.Labels = map[string]string{"okd.cern.ch/user-project": "true"}
 					return k8sClient.Update(ctx, &namespace)
 				}, timeout, interval).Should(Succeed())
 
-				By("Adding annotations to namespace")
+				By("Adding blocked label to namespace")
 				Eventually(func() error {
 					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace}, &namespace)
-					namespace.Annotations = map[string]string{"blocked.webservices.cern.ch/blocked-timestamp": "2021-08-11T10:20:00+00:00", "blocked.webservices.cern.ch/reason": "Blocked due to security reason"}
+					namespace.Labels["okd.cern.ch/blocked-project"] = "true"
 					return k8sClient.Update(ctx, &namespace)
 				}, timeout, interval).Should(Succeed())
 
@@ -516,11 +516,10 @@ var _ = Describe("DrupalSite controller", func() {
 					return *deploy.Spec.Replicas == 0
 				}, timeout, interval).Should(BeTrue())
 
-				By("Removing annotations to namespace")
+				By("Removing blocked label from namespace")
 				Eventually(func() error {
 					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace}, &namespace)
-					delete(namespace.Annotations, "blocked.webservices.cern.ch/blocked-timestamp")
-					delete(namespace.Annotations, "blocked.webservices.cern.ch/reason")
+					delete(namespace.Labels, "okd.cern.ch/blocked-project")
 					return k8sClient.Update(ctx, &namespace)
 				}, timeout, interval).Should(Succeed())
 
-- 
GitLab


From 5d3cd4f19f2b4435fa662dbf8d5273b89de95d78 Mon Sep 17 00:00:00 2001
From: Jack Henschel <jack.henschel@cern.ch>
Date: Wed, 18 Jan 2023 09:10:49 +0100
Subject: [PATCH 5/5] fix tests

---
 controllers/drupalsite_controller_test.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/controllers/drupalsite_controller_test.go b/controllers/drupalsite_controller_test.go
index 5bc80362..85b2eefa 100644
--- a/controllers/drupalsite_controller_test.go
+++ b/controllers/drupalsite_controller_test.go
@@ -505,7 +505,7 @@ var _ = Describe("DrupalSite controller", func() {
 				By("Adding blocked label to namespace")
 				Eventually(func() error {
 					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace}, &namespace)
-					namespace.Labels["okd.cern.ch/blocked-project"] = "true"
+					namespace.Labels["okd.cern.ch/project-blocked"] = "true"
 					return k8sClient.Update(ctx, &namespace)
 				}, timeout, interval).Should(Succeed())
 
@@ -519,7 +519,7 @@ var _ = Describe("DrupalSite controller", func() {
 				By("Removing blocked label from namespace")
 				Eventually(func() error {
 					k8sClient.Get(ctx, types.NamespacedName{Name: key.Namespace}, &namespace)
-					delete(namespace.Labels, "okd.cern.ch/blocked-project")
+					delete(namespace.Labels, "okd.cern.ch/project-blocked")
 					return k8sClient.Update(ctx, &namespace)
 				}, timeout, interval).Should(Succeed())
 
-- 
GitLab