Repository: argoproj-labs/argocd-operator
Pull request #675 (2022-06-06 00:26:32)

chore: enable pod security admission
**What type of PR is this?**

/kind chore

**What does this PR do / why we need it**:

Updates the code to work with Pod Security Admission, which is enabled by default in k8s 1.24

**Have you updated the necessary documentation?**

* [ ] Documentation update is required by this PR.
* [ ] Documentation has been updated.

**How to test changes / Special notes to the reviewer**:

- Install the operator on a k8s 1.24 system.
- Install an Argo CD instance
```yaml
apiVersion: argoproj.io/v1alpha1
kind: ArgoCD
metadata:
  name: argocd
spec:
  applicationSet: {}
  notifications:
    enabled: true
  ha:
    enabled: false
  grafana:
    enabled: true
  redis:
    disableTLSVerification: false
  dex:
    config: |
      connectors:
      - type: mockCallback
        id: mock
        name: Example
```
- Ensure all workloads are running
```bash
% kubectl get po
NAME                                                READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                     1/1     Running   0          34s
argocd-applicationset-controller-6d99f5bc48-cpbdm   1/1     Running   0          34s
argocd-dex-server-6f4bd74657-jl7zk                  1/1     Running   0          34s
argocd-grafana-7588bd47b5-8xrqt                     1/1     Running   0          34s
argocd-notifications-controller-86ddb6ff44-kqxjk    1/1     Running   0          33s
argocd-redis-7c79b9c5b6-7wmcf                       1/1     Running   0          34s
argocd-repo-server-857cf5d777-j6vnd                 1/1     Running   0          34s
argocd-server-579b655b48-c49rc                      1/1     Running   0          34s
```
- Install the operator on a k8s 1.23 system
- Install an ArgoCD instance
- Ensure all workloads are running




Patch:
diff --git a/bundle/manifests/argocd-operator.clusterserviceversion.yaml b/bundle/manifests/argocd-operator.clusterserviceversion.yaml
index c31e9d9c..e8652b5b 100644
--- a/bundle/manifests/argocd-operator.clusterserviceversion.yaml
+++ b/bundle/manifests/argocd-operator.clusterserviceversion.yaml
@@ -904,6 +904,14 @@ spec:
           - jobs
           verbs:
           - '*'
+        - apiGroups:
+          - config.openshift.io
+          resources:
+          - clusterversions
+          verbs:
+          - get
+          - list
+          - watch
         - apiGroups:
           - monitoring.coreos.com
           resources:
diff --git a/common/defaults.go b/common/defaults.go
index 16e0e7e5..46a6f730 100644
--- a/common/defaults.go
+++ b/common/defaults.go
@@ -30,7 +30,10 @@ const (
 	// ArgoCDServerComponent is the name of the Dex server control plane component
 	ArgoCDServerComponent = "argocd-server"
 
-	// ArgoCDRedisHAComponent is the name of the Redis control plane component
+	// ArgoCDRedisComponent is the name of the Redis control plane component
+	ArgoCDRedisComponent = "argocd-redis"
+
+	// ArgoCDRedisHAComponent is the name of the Redis HA control plane component
 	ArgoCDRedisHAComponent = "argocd-redis-ha"
 
 	// ArgoCDDexServerComponent is the name of the Dex server control plane component
@@ -39,6 +42,9 @@ const (
 	// ArgoCDNotificationsControllerComponent is the name of the Notifications controller control plane component
 	ArgoCDNotificationsControllerComponent = "argocd-notifications-controller"
 
+	// ArgoCDOperatorGrafanaComponent is the name of the Grafana control plane component
+	ArgoCDOperatorGrafanaComponent = "argocd-grafana"
+
 	// ArgoCDDefaultAdminPasswordLength is the length of the generated default admin password.
 	ArgoCDDefaultAdminPasswordLength = 32
 
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index c2dd4fc4..3dab5fd1 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -87,6 +87,14 @@ rules:
   - jobs
   verbs:
   - '*'
+- apiGroups:
+  - config.openshift.io
+  resources:
+  - clusterversions
+  verbs:
+  - get
+  - list
+  - watch
 - apiGroups:
   - monitoring.coreos.com
   resources:
diff --git a/controllers/argocd/applicationset.go b/controllers/argocd/applicationset.go
index f9ebb304..f1daa4fe 100644
--- a/controllers/argocd/applicationset.go
+++ b/controllers/argocd/applicationset.go
@@ -133,6 +133,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoprojv1a1.Arg
 	podSpec.Containers = []corev1.Container{
 		applicationSetContainer(cr),
 	}
+	AddSeccompProfileForOpenShift(r.Client, podSpec)
 
 	if existing := newDeploymentWithSuffix("applicationset-controller", "controller", cr); argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) {
 
diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go
index 490d0141..5f282d87 100644
--- a/controllers/argocd/argocd_controller.go
+++ b/controllers/argocd/argocd_controller.go
@@ -53,6 +53,7 @@ var log = logr.Log.WithName("controller_argocd")
 //+kubebuilder:rbac:groups=argoproj.io,resources=argocds;argocds/finalizers;argocds/status,verbs=*
 //+kubebuilder:rbac:groups=autoscaling,resources=horizontalpodautoscalers,verbs=*
 //+kubebuilder:rbac:groups=batch,resources=cronjobs;jobs,verbs=*
+//+kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions,verbs=get;list;watch
 //+kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=*
 //+kubebuilder:rbac:groups=monitoring.coreos.com,resources=prometheuses;servicemonitors,verbs=*
 //+kubebuilder:rbac:groups=route.openshift.io,resources=routes;routes/custom-host,verbs=*
diff --git a/controllers/argocd/deployment.go b/controllers/argocd/deployment.go
index 7ccb6c16..86f2e4b1 100644
--- a/controllers/argocd/deployment.go
+++ b/controllers/argocd/deployment.go
@@ -425,6 +425,9 @@ func (r *ReconcileArgoCD) reconcileDeployments(cr *argoprojv1a1.ArgoCD, useTLSFo
 // reconcileDexDeployment will ensure the Deployment resource is present for the ArgoCD Dex component.
 func (r *ReconcileArgoCD) reconcileDexDeployment(cr *argoprojv1a1.ArgoCD) error {
 	deploy := newDeploymentWithSuffix("dex-server", "dex-server", cr)
+
+	AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec)
+
 	deploy.Spec.Template.Spec.Containers = []corev1.Container{{
 		Command: []string{
 			"/shared/argocd-dex",
@@ -457,6 +460,15 @@ func (r *ReconcileArgoCD) reconcileDexDeployment(cr *argoprojv1a1.ArgoCD) error
 			},
 		},
 		Resources: getDexResources(cr),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+		},
 		VolumeMounts: []corev1.VolumeMount{{
 			Name:      "static-files",
 			MountPath: "/shared",
@@ -475,6 +487,15 @@ func (r *ReconcileArgoCD) reconcileDexDeployment(cr *argoprojv1a1.ArgoCD) error
 		ImagePullPolicy: corev1.PullAlways,
 		Name:            "copyutil",
 		Resources:       getDexResources(cr),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+		},
 		VolumeMounts: []corev1.VolumeMount{{
 			Name:      "static-files",
 			MountPath: "/shared",
@@ -555,6 +576,7 @@ func (r *ReconcileArgoCD) reconcileDexDeployment(cr *argoprojv1a1.ArgoCD) error
 func (r *ReconcileArgoCD) reconcileGrafanaDeployment(cr *argoprojv1a1.ArgoCD) error {
 	deploy := newDeploymentWithSuffix("grafana", "grafana", cr)
 	deploy.Spec.Replicas = getGrafanaReplicas(cr)
+	AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec)
 	deploy.Spec.Template.Spec.Containers = []corev1.Container{{
 		Image:           getGrafanaContainerImage(cr),
 		ImagePullPolicy: corev1.PullAlways,
@@ -566,6 +588,16 @@ func (r *ReconcileArgoCD) reconcileGrafanaDeployment(cr *argoprojv1a1.ArgoCD) er
 		},
 		Env:       proxyEnvVars(),
 		Resources: getGrafanaResources(cr),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+			RunAsUser:    int64Ptr(472),
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				Name:      "grafana-config",
@@ -583,6 +615,7 @@ func (r *ReconcileArgoCD) reconcileGrafanaDeployment(cr *argoprojv1a1.ArgoCD) er
 		},
 	}}
 
+	deploy.Spec.Template.Spec.ServiceAccountName = fmt.Sprintf("%s-%s", cr.Name, "argocd-grafana")
 	deploy.Spec.Template.Spec.Volumes = []corev1.Volume{
 		{
 			Name: "grafana-config",
@@ -674,6 +707,9 @@ func (r *ReconcileArgoCD) reconcileGrafanaDeployment(cr *argoprojv1a1.ArgoCD) er
 // reconcileRedisDeployment will ensure the Deployment resource is present for the ArgoCD Redis component.
 func (r *ReconcileArgoCD) reconcileRedisDeployment(cr *argoprojv1a1.ArgoCD, useTLS bool) error {
 	deploy := newDeploymentWithSuffix("redis", "redis", cr)
+
+	AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec)
+
 	deploy.Spec.Template.Spec.Containers = []corev1.Container{{
 		Args:            getArgoRedisArgs(useTLS),
 		Image:           getRedisContainerImage(cr),
@@ -686,6 +722,16 @@ func (r *ReconcileArgoCD) reconcileRedisDeployment(cr *argoprojv1a1.ArgoCD, useT
 		},
 		Resources: getRedisResources(cr),
 		Env:       proxyEnvVars(),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+			RunAsUser:    int64Ptr(999),
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				Name:      common.ArgoCDRedisServerTLSSecretName,
@@ -694,6 +740,7 @@ func (r *ReconcileArgoCD) reconcileRedisDeployment(cr *argoprojv1a1.ArgoCD, useT
 		},
 	}}
 
+	deploy.Spec.Template.Spec.ServiceAccountName = fmt.Sprintf("%s-%s", cr.Name, "argocd-redis")
 	deploy.Spec.Template.Spec.Volumes = []corev1.Volume{
 		{
 			Name: common.ArgoCDRedisServerTLSSecretName,
@@ -837,6 +884,15 @@ func (r *ReconcileArgoCD) reconcileRedisHAProxyDeployment(cr *argoprojv1a1.ArgoC
 			},
 		},
 		Resources: getRedisHAProxyResources(cr),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				Name:      "data",
@@ -865,6 +921,14 @@ func (r *ReconcileArgoCD) reconcileRedisHAProxyDeployment(cr *argoprojv1a1.ArgoC
 		Name:            "config-init",
 		Env:             proxyEnvVars(),
 		Resources:       getRedisHAProxyResources(cr),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				Name:      "config-volume",
@@ -912,6 +976,13 @@ func (r *ReconcileArgoCD) reconcileRedisHAProxyDeployment(cr *argoprojv1a1.ArgoC
 		},
 	}
 
+	deploy.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{
+		RunAsNonRoot: boolPtr(true),
+		RunAsUser:    int64Ptr(1000),
+		FSGroup:      int64Ptr(1000),
+	}
+	AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec)
+
 	deploy.Spec.Template.Spec.ServiceAccountName = fmt.Sprintf("%s-%s", cr.Name, "argocd-redis-ha")
 
 	if err := applyReconcilerHook(cr, deploy, ""); err != nil {
@@ -946,6 +1017,8 @@ func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoprojv1a1.ArgoCD, useTL
 		repoEnv = argoutil.EnvMerge(repoEnv, []corev1.EnvVar{{Name: "ARGOCD_EXEC_TIMEOUT", Value: fmt.Sprintf("%d", *cr.Spec.Repo.ExecTimeout)}}, true)
 	}
 
+	AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec)
+
 	deploy.Spec.Template.Spec.InitContainers = []corev1.Container{{
 		Name:            "copyutil",
 		Image:           getArgoContainerImage(cr),
@@ -953,6 +1026,15 @@ func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoprojv1a1.ArgoCD, useTL
 		ImagePullPolicy: corev1.PullAlways,
 		Resources:       getArgoRepoResources(cr),
 		Env:             proxyEnvVars(),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				Name:      "var-files",
@@ -1037,7 +1119,16 @@ func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoprojv1a1.ArgoCD, useTL
 			InitialDelaySeconds: 5,
 			PeriodSeconds:       10,
 		},
-		Resources:    getArgoRepoResources(cr),
+		Resources: getArgoRepoResources(cr),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+		},
 		VolumeMounts: repoServerVolumeMounts,
 	}}
 
@@ -1199,6 +1290,7 @@ func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoprojv1a1.ArgoCD, use
 	deploy := newDeploymentWithSuffix("server", "server", cr)
 	serverEnv := cr.Spec.Server.Env
 	serverEnv = argoutil.EnvMerge(serverEnv, proxyEnvVars(), false)
+	AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec)
 	deploy.Spec.Template.Spec.Containers = []corev1.Container{{
 		Command:         getArgoServerCommand(cr, useTLSForRedis),
 		Image:           getArgoContainerImage(cr),
@@ -1233,6 +1325,15 @@ func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoprojv1a1.ArgoCD, use
 			PeriodSeconds:       30,
 		},
 		Resources: getArgoServerResources(cr),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				Name:      "ssh-known-hosts",
diff --git a/controllers/argocd/notifications.go b/controllers/argocd/notifications.go
index 08cfbdb1..902dfa7d 100644
--- a/controllers/argocd/notifications.go
+++ b/controllers/argocd/notifications.go
@@ -257,7 +257,6 @@ func (r *ReconcileArgoCD) reconcileNotificationsRoleBinding(cr *argoprojv1a1.Arg
 
 func (r *ReconcileArgoCD) reconcileNotificationsDeployment(cr *argoprojv1a1.ArgoCD, sa *corev1.ServiceAccount) error {
 
-	var runAsNonRoot bool = true
 	desiredDeployment := newDeploymentWithSuffix("notifications-controller", "controller", cr)
 
 	desiredDeployment.Spec.Strategy = appsv1.DeploymentStrategy{
@@ -270,8 +269,9 @@ func (r *ReconcileArgoCD) reconcileNotificationsDeployment(cr *argoprojv1a1.Argo
 
 	podSpec := &desiredDeployment.Spec.Template.Spec
 	podSpec.SecurityContext = &corev1.PodSecurityContext{
-		RunAsNonRoot: &runAsNonRoot,
+		RunAsNonRoot: boolPtr(true),
 	}
+	AddSeccompProfileForOpenShift(r.Client, podSpec)
 	podSpec.ServiceAccountName = sa.ObjectMeta.Name
 	podSpec.Volumes = []corev1.Volume{
 		{
@@ -310,6 +310,14 @@ func (r *ReconcileArgoCD) reconcileNotificationsDeployment(cr *argoprojv1a1.Argo
 				},
 			},
 		},
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				Name:      "tls-certs",
diff --git a/controllers/argocd/policyrule.go b/controllers/argocd/policyrule.go
index daa4428d..f8d8e399 100644
--- a/controllers/argocd/policyrule.go
+++ b/controllers/argocd/policyrule.go
@@ -1,9 +1,14 @@
 package argocd
 
 import (
-	v1 "k8s.io/api/rbac/v1"
+	"fmt"
+
+	"golang.org/x/mod/semver"
 
 	"github.com/argoproj-labs/argocd-operator/common"
+
+	v1 "k8s.io/api/rbac/v1"
+	"sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 func policyRuleForApplicationController() []v1.PolicyRule {
@@ -23,7 +28,17 @@ func policyRuleForApplicationController() []v1.PolicyRule {
 	}
 }
 
-func policyRuleForRedisHa() []v1.PolicyRule {
+func policyRuleForRedis(client client.Client) []v1.PolicyRule {
+	rules := []v1.PolicyRule{}
+
+	// Need additional policy rules if we are running on openshift, else the stateful set won't have the right
+	// permissions to start
+	rules = appendOpenShiftNonRootSCC(rules, client)
+
+	return rules
+}
+
+func policyRuleForRedisHa(client client.Client) []v1.PolicyRule {
 
 	rules := []v1.PolicyRule{
 		{
@@ -41,23 +56,7 @@ func policyRuleForRedisHa() []v1.PolicyRule {
 
 	// Need additional policy rules if we are running on openshift, else the stateful set won't have the right
 	// permissions to start
-	if IsRouteAPIAvailable() {
-		orules := v1.PolicyRule{
-			APIGroups: []string{
-				"security.openshift.io",
-			},
-			ResourceNames: []string{
-				"nonroot",
-			},
-			Resources: []string{
-				"securitycontextconstraints",
-			},
-			Verbs: []string{
-				"use",
-			},
-		}
-		rules = append(rules, orules)
-	}
+	rules = appendOpenShiftNonRootSCC(rules, client)
 
 	return rules
 }
@@ -239,7 +238,17 @@ func policyRuleForServerClusterRole() []v1.PolicyRule {
 	}
 }
 
-func getPolicyRuleList() []struct {
+func policyRuleForGrafana(client client.Client) []v1.PolicyRule {
+	rules := []v1.PolicyRule{}
+
+	// Need additional policy rules if we are running on openshift, else the stateful set won't have the right
+	// permissions to start
+	rules = appendOpenShiftNonRootSCC(rules, client)
+
+	return rules
+}
+
+func getPolicyRuleList(client client.Client) []struct {
 	name       string
 	policyRule []v1.PolicyRule
 } {
@@ -258,7 +267,13 @@ func getPolicyRuleList() []struct {
 			policyRule: policyRuleForServer(),
 		}, {
 			name:       common.ArgoCDRedisHAComponent,
-			policyRule: policyRuleForRedisHa(),
+			policyRule: policyRuleForRedisHa(client),
+		}, {
+			name:       common.ArgoCDRedisComponent,
+			policyRule: policyRuleForRedis(client),
+		}, {
+			name:       common.ArgoCDOperatorGrafanaComponent,
+			policyRule: policyRuleForGrafana(client),
 		},
 	}
 }
@@ -280,3 +295,33 @@ func getPolicyRuleClusterRoleList() []struct {
 		},
 	}
 }
+
+func appendOpenShiftNonRootSCC(rules []v1.PolicyRule, client client.Client) []v1.PolicyRule {
+	if IsVersionAPIAvailable() {
+		// Starting with OpenShift 4.11, we need to use the resource name "nonroot-v2" instead of "nonroot"
+		resourceName := "nonroot"
+		version, err := getClusterVersion(client)
+		if err != nil {
+			log.Error(err, "couldn't get OpenShift version")
+		}
+		if version == "" || semver.Compare(fmt.Sprintf("v%s", version), "v4.10.999") > 0 {
+			resourceName = "nonroot-v2"
+		}
+		orules := v1.PolicyRule{
+			APIGroups: []string{
+				"security.openshift.io",
+			},
+			ResourceNames: []string{
+				resourceName,
+			},
+			Resources: []string{
+				"securitycontextconstraints",
+			},
+			Verbs: []string{
+				"use",
+			},
+		}
+		rules = append(rules, orules)
+	}
+	return rules
+}
diff --git a/controllers/argocd/role.go b/controllers/argocd/role.go
index 470c6f1b..32945433 100644
--- a/controllers/argocd/role.go
+++ b/controllers/argocd/role.go
@@ -52,7 +52,7 @@ func newClusterRole(name string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD)
 
 // reconcileRoles will ensure that all ArgoCD Service Accounts are configured.
 func (r *ReconcileArgoCD) reconcileRoles(cr *argoprojv1a1.ArgoCD) error {
-	params := getPolicyRuleList()
+	params := getPolicyRuleList(r.Client)
 
 	for _, param := range params {
 		if _, err := r.reconcileRole(param.name, param.policyRule, cr); err != nil {
diff --git a/controllers/argocd/rolebinding.go b/controllers/argocd/rolebinding.go
index 34e6933a..d2e5030e 100644
--- a/controllers/argocd/rolebinding.go
+++ b/controllers/argocd/rolebinding.go
@@ -69,7 +69,7 @@ func newRoleBindingWithname(name string, cr *argoprojv1a1.ArgoCD) *v1.RoleBindin
 // reconcileRoleBindings will ensure that all ArgoCD RoleBindings are configured.
 func (r *ReconcileArgoCD) reconcileRoleBindings(cr *argoprojv1a1.ArgoCD) error {
 
-	params := getPolicyRuleList()
+	params := getPolicyRuleList(r.Client)
 
 	for _, param := range params {
 		if err := r.reconcileRoleBinding(param.name, param.policyRule, cr); err != nil {
diff --git a/controllers/argocd/service_account.go b/controllers/argocd/service_account.go
index dec6143c..885f10bb 100644
--- a/controllers/argocd/service_account.go
+++ b/controllers/argocd/service_account.go
@@ -60,7 +60,7 @@ func newServiceAccountWithName(name string, cr *argoprojv1a1.ArgoCD) *corev1.Ser
 
 // reconcileServiceAccounts will ensure that all ArgoCD Service Accounts are configured.
 func (r *ReconcileArgoCD) reconcileServiceAccounts(cr *argoprojv1a1.ArgoCD) error {
-	params := getPolicyRuleList()
+	params := getPolicyRuleList(r.Client)
 
 	for _, param := range params {
 		if err := r.reconcileServiceAccountPermissions(param.name, param.policyRule, cr); err != nil {
diff --git a/controllers/argocd/statefulset.go b/controllers/argocd/statefulset.go
index ca7b43b5..ce236bf6 100644
--- a/controllers/argocd/statefulset.go
+++ b/controllers/argocd/statefulset.go
@@ -202,6 +202,15 @@ func (r *ReconcileArgoCD) reconcileRedisStatefulSet(cr *argoprojv1a1.ArgoCD) err
 				TimeoutSeconds:      int32(15),
 			},
 			Resources: getRedisResources(cr),
+			SecurityContext: &corev1.SecurityContext{
+				AllowPrivilegeEscalation: boolPtr(false),
+				Capabilities: &corev1.Capabilities{
+					Drop: []corev1.Capability{
+						"ALL",
+					},
+				},
+				RunAsNonRoot: boolPtr(true),
+			},
 			VolumeMounts: []corev1.VolumeMount{
 				{
 					MountPath: "/data",
@@ -264,6 +273,15 @@ func (r *ReconcileArgoCD) reconcileRedisStatefulSet(cr *argoprojv1a1.ArgoCD) err
 				TimeoutSeconds:      int32(15),
 			},
 			Resources: getRedisResources(cr),
+			SecurityContext: &corev1.SecurityContext{
+				AllowPrivilegeEscalation: boolPtr(false),
+				Capabilities: &corev1.Capabilities{
+					Drop: []corev1.Capability{
+						"ALL",
+					},
+				},
+				RunAsNonRoot: boolPtr(true),
+			},
 			VolumeMounts: []corev1.VolumeMount{
 				{
 					MountPath: "/data",
@@ -306,6 +324,15 @@ func (r *ReconcileArgoCD) reconcileRedisStatefulSet(cr *argoprojv1a1.ArgoCD) err
 		ImagePullPolicy: corev1.PullIfNotPresent,
 		Name:            "config-init",
 		Resources:       getRedisResources(cr),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				MountPath: "/readonly-config",
@@ -332,6 +359,7 @@ func (r *ReconcileArgoCD) reconcileRedisStatefulSet(cr *argoprojv1a1.ArgoCD) err
 		RunAsNonRoot: &runAsNonRoot,
 		RunAsUser:    &runAsUser,
 	}
+	AddSeccompProfileForOpenShift(r.Client, &ss.Spec.Template.Spec)
 
 	ss.Spec.Template.Spec.ServiceAccountName = nameWithSuffix("argocd-redis-ha", cr)
 
@@ -452,6 +480,15 @@ func (r *ReconcileArgoCD) reconcileApplicationControllerStatefulSet(cr *argoproj
 			PeriodSeconds:       10,
 		},
 		Resources: getArgoApplicationControllerResources(cr),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				Name:      "argocd-repo-server-tls",
@@ -463,6 +500,7 @@ func (r *ReconcileArgoCD) reconcileApplicationControllerStatefulSet(cr *argoproj
 			},
 		},
 	}}
+	AddSeccompProfileForOpenShift(r.Client, podSpec)
 	podSpec.ServiceAccountName = nameWithSuffix("argocd-application-controller", cr)
 	podSpec.Volumes = []corev1.Volume{
 		{
@@ -524,7 +562,16 @@ func (r *ReconcileArgoCD) reconcileApplicationControllerStatefulSet(cr *argoproj
 			Image:           getArgoImportContainerImage(export),
 			ImagePullPolicy: corev1.PullAlways,
 			Name:            "argocd-import",
-			VolumeMounts:    getArgoImportVolumeMounts(),
+			SecurityContext: &corev1.SecurityContext{
+				AllowPrivilegeEscalation: boolPtr(false),
+				Capabilities: &corev1.Capabilities{
+					Drop: []corev1.Capability{
+						"ALL",
+					},
+				},
+				RunAsNonRoot: boolPtr(true),
+			},
+			VolumeMounts: getArgoImportVolumeMounts(),
 		}}
 
 		podSpec.Volumes = getArgoImportVolumes(export)
diff --git a/controllers/argocd/util.go b/controllers/argocd/util.go
index 8c7459ad..ce2dd094 100644
--- a/controllers/argocd/util.go
+++ b/controllers/argocd/util.go
@@ -39,9 +39,11 @@ import (
 
 	monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1"
 	oappsv1 "github.com/openshift/api/apps/v1"
+	configv1 "github.com/openshift/api/config/v1"
 	routev1 "github.com/openshift/api/route/v1"
 	configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
 	"github.com/sethvargo/go-password/password"
+	"golang.org/x/mod/semver"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	networkingv1 "k8s.io/api/networking/v1"
@@ -61,6 +63,25 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/source"
 )
 
+var (
+	versionAPIFound = false
+)
+
+// IsVersionAPIAvailable returns true if the version api is present
+func IsVersionAPIAvailable() bool {
+	return versionAPIFound
+}
+
+// verifyVersionAPI will verify that the template API is present.
+func verifyVersionAPI() error {
+	found, err := argoutil.VerifyAPI(configv1.GroupName, configv1.GroupVersion.Version)
+	if err != nil {
+		return err
+	}
+	versionAPIFound = found
+	return nil
+}
+
 // DexConnector represents an authentication connector for Dex.
 type DexConnector struct {
 	Config map[string]interface{} `yaml:"config,omitempty"`
@@ -727,6 +748,10 @@ func InspectCluster() error {
 	if err := verifyTemplateAPI(); err != nil {
 		return err
 	}
+
+	if err := verifyVersionAPI(); err != nil {
+		return err
+	}
 	return nil
 }
 
@@ -1168,6 +1193,10 @@ func boolPtr(val bool) *bool {
 	return &val
 }
 
+func int64Ptr(val int64) *int64 {
+	return &val
+}
+
 // triggerRollout will trigger a rollout of a Kubernetes resource specified as
 // obj. It currently supports Deployment and StatefulSet resources.
 func (r *ReconcileArgoCD) triggerRollout(obj interface{}, key string) error {
@@ -1477,6 +1506,43 @@ func getOpenShiftAPIURL() string {
 	return out
 }
 
+func AddSeccompProfileForOpenShift(client client.Client, podspec *corev1.PodSpec) {
+	if !IsVersionAPIAvailable() {
+		return
+	}
+	version, err := getClusterVersion(client)
+	if err != nil {
+		log.Error(err, "couldn't get OpenShift version")
+	}
+	if version == "" || semver.Compare(fmt.Sprintf("v%s", version), "v4.10.999") > 0 {
+		if podspec.SecurityContext == nil {
+			podspec.SecurityContext = &corev1.PodSecurityContext{}
+		}
+		if podspec.SecurityContext.SeccompProfile == nil {
+			podspec.SecurityContext.SeccompProfile = &corev1.SeccompProfile{}
+		}
+		if len(podspec.SecurityContext.SeccompProfile.Type) == 0 {
+			podspec.SecurityContext.SeccompProfile.Type = corev1.SeccompProfileTypeRuntimeDefault
+		}
+	}
+}
+
+// getClusterVersion returns the OpenShift Cluster version in which the operator is installed
+func getClusterVersion(client client.Client) (string, error) {
+	if !IsVersionAPIAvailable() {
+		return "", nil
+	}
+	clusterVersion := &configv1.ClusterVersion{}
+	err := client.Get(context.TODO(), types.NamespacedName{Name: "version"}, clusterVersion)
+	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return "", nil
+		}
+		return "", err
+	}
+	return clusterVersion.Status.Desired.Version, nil
+}
+
 // generateRandomBytes returns a securely generated random bytes.
 func generateRandomBytes(n int) []byte {
 	b := make([]byte, n)
diff --git a/controllers/argocdexport/job.go b/controllers/argocdexport/job.go
index 663812b7..aeda5d91 100644
--- a/controllers/argocdexport/job.go
+++ b/controllers/argocdexport/job.go
@@ -28,6 +28,7 @@ import (
 
 	argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1"
 	"github.com/argoproj-labs/argocd-operator/common"
+	"github.com/argoproj-labs/argocd-operator/controllers/argocd"
 	"github.com/argoproj-labs/argocd-operator/controllers/argoutil"
 )
 
@@ -164,16 +165,29 @@ func newCronJob(cr *argoprojv1a1.ArgoCDExport) *batchv1.CronJob {
 	}
 }
 
-func newExportPodSpec(cr *argoprojv1a1.ArgoCDExport, argocdName string) corev1.PodSpec {
+func newExportPodSpec(cr *argoprojv1a1.ArgoCDExport, argocdName string, client client.Client) corev1.PodSpec {
 	pod := corev1.PodSpec{}
 
+	boolPtr := func(value bool) *bool {
+		return &value
+	}
+
 	pod.Containers = []corev1.Container{{
 		Command:         getArgoExportCommand(cr),
 		Env:             getArgoExportContainerEnv(cr),
 		Image:           getArgoExportContainerImage(cr),
 		ImagePullPolicy: corev1.PullAlways,
 		Name:            "argocd-export",
-		VolumeMounts:    getArgoExportVolumeMounts(),
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+			RunAsNonRoot: boolPtr(true),
+		},
+		VolumeMounts: getArgoExportVolumeMounts(),
 	}}
 
 	pod.RestartPolicy = corev1.RestartPolicyOnFailure
@@ -191,18 +205,19 @@ func newExportPodSpec(cr *argoprojv1a1.ArgoCDExport, argocdName string) corev1.P
 		RunAsGroup: &id,
 		FSGroup:    &id,
 	}
+	argocd.AddSeccompProfileForOpenShift(client, &pod)
 
 	return pod
 }
 
-func newPodTemplateSpec(cr *argoprojv1a1.ArgoCDExport, argocdName string) corev1.PodTemplateSpec {
+func newPodTemplateSpec(cr *argoprojv1a1.ArgoCDExport, argocdName string, client client.Client) corev1.PodTemplateSpec {
 	return corev1.PodTemplateSpec{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      cr.Name,
 			Namespace: cr.Namespace,
 			Labels:    common.DefaultLabels(cr.Name),
 		},
-		Spec: newExportPodSpec(cr, argocdName),
+		Spec: newExportPodSpec(cr, argocdName, client),
 	}
 }
 
@@ -231,7 +246,7 @@ func (r *ReconcileArgoCDExport) reconcileCronJob(cr *argoprojv1a1.ArgoCDExport)
 		return err
 	}
 	job := newJob(cr)
-	job.Spec.Template = newPodTemplateSpec(cr, argocdName)
+	job.Spec.Template = newPodTemplateSpec(cr, argocdName, r.Client)
 
 	cj.Spec.JobTemplate.Spec = job.Spec
 
@@ -264,7 +279,7 @@ func (r *ReconcileArgoCDExport) reconcileJob(cr *argoprojv1a1.ArgoCDExport) erro
 	if err != nil {
 		return err
 	}
-	job.Spec.Template = newPodTemplateSpec(cr, argocdName)
+	job.Spec.Template = newPodTemplateSpec(cr, argocdName, r.Client)
 
 	if err := controllerutil.SetControllerReference(cr, job, r.Scheme); err != nil {
 		return err
diff --git a/deploy/olm-catalog/argocd-operator/0.4.0/argocd-operator.v0.4.0.clusterserviceversion.yaml b/deploy/olm-catalog/argocd-operator/0.4.0/argocd-operator.v0.4.0.clusterserviceversion.yaml
index c31e9d9c..e8652b5b 100644
--- a/deploy/olm-catalog/argocd-operator/0.4.0/argocd-operator.v0.4.0.clusterserviceversion.yaml
+++ b/deploy/olm-catalog/argocd-operator/0.4.0/argocd-operator.v0.4.0.clusterserviceversion.yaml
@@ -904,6 +904,14 @@ spec:
           - jobs
           verbs:
           - '*'
+        - apiGroups:
+          - config.openshift.io
+          resources:
+          - clusterversions
+          verbs:
+          - get
+          - list
+          - watch
         - apiGroups:
           - monitoring.coreos.com
           resources:
diff --git a/go.mod b/go.mod
index ba8677b1..97cdac72 100644
--- a/go.mod
+++ b/go.mod
@@ -17,6 +17,7 @@ require (
 	github.com/pkg/errors v0.9.1
 	github.com/sethvargo/go-password v0.2.0
 	github.com/stretchr/testify v1.7.0
+	golang.org/x/mod v0.5.1-0.20210830214625-1b1db11ec8f4
 	gopkg.in/yaml.v2 v2.4.0
 	k8s.io/api v0.23.1
 	k8s.io/apimachinery v0.23.1
diff --git a/go.sum b/go.sum
index d84a71b6..e7d5e18b 100644
--- a/go.sum
+++ b/go.sum
@@ -1318,6 +1318,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.5.1-0.20210830214625-1b1db11ec8f4 h1:7Qds88gNaRx0Dz/1wOwXlR7asekh1B1u26wEwN6FcEI=
+golang.org/x/mod v0.5.1-0.20210830214625-1b1db11ec8f4/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
diff --git a/main.go b/main.go
index 656c2a42..e3555702 100644
--- a/main.go
+++ b/main.go
@@ -25,6 +25,7 @@ import (
 
 	monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1"
 	appsv1 "github.com/openshift/api/apps/v1"
+	configv1 "github.com/openshift/api/config/v1"
 	oauthv1 "github.com/openshift/api/oauth/v1"
 	routev1 "github.com/openshift/api/route/v1"
 	templatev1 "github.com/openshift/api/template/v1"
@@ -152,6 +153,14 @@ func main() {
 		}
 	}
 
+	// Set up the scheme for openshift config if available
+	if argocd.IsVersionAPIAvailable() {
+		if err := configv1.Install(mgr.GetScheme()); err != nil {
+			setupLog.Error(err, "")
+			os.Exit(1)
+		}
+	}
+
 	// Setup Schemes for SSO if template instance is available.
 	if argocd.IsTemplateAPIAvailable() {
 		if err := templatev1.Install(mgr.GetScheme()); err != nil {


Test patch:
diff --git a/controllers/argocd/deployment_test.go b/controllers/argocd/deployment_test.go
index 843c01b7..316423db 100644
--- a/controllers/argocd/deployment_test.go
+++ b/controllers/argocd/deployment_test.go
@@ -866,6 +866,15 @@ func TestReconcileArgoCD_reconcileDexDeployment(t *testing.T) {
 					"/usr/local/bin/argocd",
 					"/shared/argocd-dex",
 				},
+				SecurityContext: &corev1.SecurityContext{
+					AllowPrivilegeEscalation: boolPtr(false),
+					Capabilities: &corev1.Capabilities{
+						Drop: []corev1.Capability{
+							"ALL",
+						},
+					},
+					RunAsNonRoot: boolPtr(true),
+				},
 				VolumeMounts: []corev1.VolumeMount{
 					{
 						Name:      "static-files",
@@ -907,6 +916,15 @@ func TestReconcileArgoCD_reconcileDexDeployment(t *testing.T) {
 						ContainerPort: 5558,
 					},
 				},
+				SecurityContext: &corev1.SecurityContext{
+					AllowPrivilegeEscalation: boolPtr(false),
+					Capabilities: &corev1.Capabilities{
+						Drop: []corev1.Capability{
+							"ALL",
+						},
+					},
+					RunAsNonRoot: boolPtr(true),
+				},
 				VolumeMounts: []corev1.VolumeMount{
 					{Name: "static-files", MountPath: "/shared"}},
 				ImagePullPolicy: corev1.PullAlways,
@@ -958,6 +976,15 @@ func TestReconcileArgoCD_reconcileDexDeployment_withUpdate(t *testing.T) {
 					"/usr/local/bin/argocd",
 					"/shared/argocd-dex",
 				},
+				SecurityContext: &corev1.SecurityContext{
+					AllowPrivilegeEscalation: boolPtr(false),
+					Capabilities: &corev1.Capabilities{
+						Drop: []corev1.Capability{
+							"ALL",
+						},
+					},
+					RunAsNonRoot: boolPtr(true),
+				},
 				VolumeMounts: []corev1.VolumeMount{
 					{
 						Name:      "static-files",
@@ -999,6 +1026,15 @@ func TestReconcileArgoCD_reconcileDexDeployment_withUpdate(t *testing.T) {
 						ContainerPort: 5558,
 					},
 				},
+				SecurityContext: &corev1.SecurityContext{
+					AllowPrivilegeEscalation: boolPtr(false),
+					Capabilities: &corev1.Capabilities{
+						Drop: []corev1.Capability{
+							"ALL",
+						},
+					},
+					RunAsNonRoot: boolPtr(true),
+				},
 				VolumeMounts: []corev1.VolumeMount{
 					{Name: "static-files", MountPath: "/shared"}},
 				ImagePullPolicy: corev1.PullAlways,
@@ -1126,6 +1162,15 @@ func TestReconcileArgoCD_reconcileServerDeployment(t *testing.T) {
 					InitialDelaySeconds: 3,
 					PeriodSeconds:       30,
 				},
+				SecurityContext: &corev1.SecurityContext{
+					AllowPrivilegeEscalation: boolPtr(false),
+					Capabilities: &corev1.Capabilities{
+						Drop: []corev1.Capability{
+							"ALL",
+						},
+					},
+					RunAsNonRoot: boolPtr(true),
+				},
 				VolumeMounts: serverDefaultVolumeMounts(),
 			},
 		},
@@ -1331,6 +1376,15 @@ func TestReconcileArgoCD_reconcileServerDeploymentWithInsecure(t *testing.T) {
 					InitialDelaySeconds: 3,
 					PeriodSeconds:       30,
 				},
+				SecurityContext: &corev1.SecurityContext{
+					AllowPrivilegeEscalation: boolPtr(false),
+					Capabilities: &corev1.Capabilities{
+						Drop: []corev1.Capability{
+							"ALL",
+						},
+					},
+					RunAsNonRoot: boolPtr(true),
+				},
 				VolumeMounts: serverDefaultVolumeMounts(),
 			},
 		},
@@ -1407,6 +1461,15 @@ func TestReconcileArgoCD_reconcileServerDeploymentChangedToInsecure(t *testing.T
 					InitialDelaySeconds: 3,
 					PeriodSeconds:       30,
 				},
+				SecurityContext: &corev1.SecurityContext{
+					AllowPrivilegeEscalation: boolPtr(false),
+					Capabilities: &corev1.Capabilities{
+						Drop: []corev1.Capability{
+							"ALL",
+						},
+					},
+					RunAsNonRoot: boolPtr(true),
+				},
 				VolumeMounts: serverDefaultVolumeMounts(),
 			},
 		},
diff --git a/controllers/argocd/notifications_test.go b/controllers/argocd/notifications_test.go
index 143a7add..23ab0f5f 100644
--- a/controllers/argocd/notifications_test.go
+++ b/controllers/argocd/notifications_test.go
@@ -148,6 +148,14 @@ func TestReconcileNotifications_CreateDeployments(t *testing.T) {
 		Image:           argoutil.CombineImageTag(common.ArgoCDDefaultArgoImage, common.ArgoCDDefaultArgoVersion),
 		ImagePullPolicy: corev1.PullAlways,
 		Name:            "argocd-notifications-controller",
+		SecurityContext: &corev1.SecurityContext{
+			AllowPrivilegeEscalation: boolPtr(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{
+					"ALL",
+				},
+			},
+		},
 		VolumeMounts: []corev1.VolumeMount{
 			{
 				Name:      "tls-certs",
diff --git a/controllers/argocd/role_test.go b/controllers/argocd/role_test.go
index 12e88273..615bef0c 100644
--- a/controllers/argocd/role_test.go
+++ b/controllers/argocd/role_test.go
@@ -37,7 +37,7 @@ func TestReconcileArgoCD_reconcileRole(t *testing.T) {
 	assert.Equal(t, expectedRules, reconciledRole.Rules)
 
 	// update reconciledRole policy rules to RedisHa policy rules
-	reconciledRole.Rules = policyRuleForRedisHa()
+	reconciledRole.Rules = policyRuleForRedisHa(r.Client)
 	assert.NoError(t, r.Client.Update(context.TODO(), reconciledRole))
 
 	// Check if the RedisHa policy rules are overwritten to Application Controller
@@ -66,7 +66,7 @@ func TestReconcileArgoCD_reconcileRole_for_new_namespace(t *testing.T) {
 	assert.Equal(t, expectedRoleNamespace, dexRoles[0].ObjectMeta.Namespace)
 	// check no redisHa role is created for the new namespace with managed-by label
 	workloadIdentifier = common.ArgoCDRedisHAComponent
-	expectedRedisHaRules := policyRuleForRedisHa()
+	expectedRedisHaRules := policyRuleForRedisHa(r.Client)
 	redisHaRoles, err := r.reconcileRole(workloadIdentifier, expectedRedisHaRules, a)
 	assert.NoError(t, err)
 	assert.Equal(t, expectedNumberOfRoles, len(redisHaRoles))
@@ -126,7 +126,7 @@ func TestReconcileArgoCD_reconcileClusterRole(t *testing.T) {
 	assert.Equal(t, expectedRules, reconciledClusterRole.Rules)
 
 	// update reconciledRole policy rules to RedisHa policy rules
-	reconciledClusterRole.Rules = policyRuleForRedisHa()
+	reconciledClusterRole.Rules = policyRuleForRedisHa(r.Client)
 	assert.NoError(t, r.Client.Update(context.TODO(), reconciledClusterRole))
 
 	// Check if the RedisHa policy rules are overwritten to Application Controller
diff --git a/controllers/argocd/rolebinding_test.go b/controllers/argocd/rolebinding_test.go
index 45435567..fb3ab833 100644
--- a/controllers/argocd/rolebinding_test.go
+++ b/controllers/argocd/rolebinding_test.go
@@ -63,7 +63,7 @@ func TestReconcileArgoCD_reconcileRoleBinding_for_new_namespace(t *testing.T) {
 
 	// check no redisHa rolebinding is created for the new namespace with managed-by label
 	workloadIdentifier = common.ArgoCDRedisHAComponent
-	expectedRedisHaRules := policyRuleForRedisHa()
+	expectedRedisHaRules := policyRuleForRedisHa(r.Client)
 	assert.NoError(t, r.reconcileRoleBinding(workloadIdentifier, expectedRedisHaRules, a))
 	assert.Error(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: expectedName, Namespace: "newTestNamespace"}, roleBinding))
 }
diff --git a/controllers/argocd/route_test.go b/controllers/argocd/route_test.go
index 0f1e8e55..2272335e 100644
--- a/controllers/argocd/route_test.go
+++ b/controllers/argocd/route_test.go
@@ -17,6 +17,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
 	"github.com/google/go-cmp/cmp"
+	configv1 "github.com/openshift/api/config/v1"
 	routev1 "github.com/openshift/api/route/v1"
 
 	argov1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1"
@@ -205,6 +206,7 @@ func makeReconciler(t *testing.T, acd *argov1alpha1.ArgoCD, objs ...runtime.Obje
 	s := scheme.Scheme
 	s.AddKnownTypes(argov1alpha1.GroupVersion, acd)
 	routev1.Install(s)
+	configv1.Install(s)
 	cl := fake.NewFakeClient(objs...)
 	return &ReconcileArgoCD{
 		Client: cl,
diff --git a/controllers/argocd/service_account_test.go b/controllers/argocd/service_account_test.go
index c7a700ab..f3c5d227 100644
--- a/controllers/argocd/service_account_test.go
+++ b/controllers/argocd/service_account_test.go
@@ -53,7 +53,7 @@ func TestReconcileArgoCD_reconcileServiceAccountPermissions(t *testing.T) {
 	assert.Equal(t, expectedRules, reconciledRole.Rules)
 
 	// undesirable changes
-	reconciledRole.Rules = policyRuleForRedisHa()
+	reconciledRole.Rules = policyRuleForRedisHa(r.Client)
 	assert.NoError(t, r.Client.Update(context.TODO(), reconciledRole))
 
 	// fetch it
diff --git a/controllers/argocd/util_test.go b/controllers/argocd/util_test.go
index 0acfe5b7..65ca70c4 100644
--- a/controllers/argocd/util_test.go
+++ b/controllers/argocd/util_test.go
@@ -627,34 +627,6 @@ func TestSetManagedNamespaces(t *testing.T) {
 	}
 }
 
-func TestGetRedisConf(t *testing.T) {
-	s1 := getRedisConf(true)
-	//assert.Equal(t, "", s1)
-
-	s1 = getRedisConf(false)
-	//assert.Equal(t, "", s1)
-
-	s1 = getRedisSentinelConf(true)
-	//assert.Equal(t, "", s1)
-
-	s1 = getRedisSentinelConf(false)
-	//assert.Equal(t, "", s1)
-
-	a := makeTestArgoCD()
-
-	s1 = getRedisInitScript(a, true)
-	//assert.Equal(t, "", s1)
-
-	s1 = getRedisLivenessScript(false)
-	//assert.Equal(t, "", s1)
-
-	s1 = getRedisReadinessScript(true)
-	//assert.Equal(t, "", s1)
-
-	s1 = getSentinelLivenessScript(true)
-	assert.Equal(t, "", s1)
-}
-
 func TestGenerateRandomString(t *testing.T) {
 
 	// verify the creation of unique strings