From 808b1915c9ba7411186f72e7a19ac892ba75d97c Mon Sep 17 00:00:00 2001
From: yogananth subramanian <ysubrama@redhat.com>
Date: Mon, 1 Jul 2024 16:28:25 +0530
Subject: [PATCH] Enable RBAC (#60)

Enable RBAC for 1.2 and 1.1.
Patch introduces a new ENV variable ENABLE_RBAC to enable RBAC,
by setting ENABLE_RBAC=true
---
 ci-scripts/rhdh-setup/create_resource.sh      |  1 +
 ci-scripts/rhdh-setup/deploy.sh               | 13 ++++
 .../template/backstage/app-rbac-patch.yaml    |  8 +++
 .../backstage/helm/extravolume-patch-1.1.yaml | 53 ++++++++++++++++
 .../backstage/helm/extravolume-patch-1.2.yaml | 61 +++++++++++++++++++
 .../backstage/helm/rbac-plugin-patch.yaml     |  3 +
 .../template/backstage/rbac-config.yaml       | 11 ++++
 7 files changed, 150 insertions(+)
 create mode 100644 ci-scripts/rhdh-setup/template/backstage/app-rbac-patch.yaml
 create mode 100644 ci-scripts/rhdh-setup/template/backstage/helm/extravolume-patch-1.1.yaml
 create mode 100644 ci-scripts/rhdh-setup/template/backstage/helm/extravolume-patch-1.2.yaml
 create mode 100644 ci-scripts/rhdh-setup/template/backstage/helm/rbac-plugin-patch.yaml
 create mode 100644 ci-scripts/rhdh-setup/template/backstage/rbac-config.yaml

diff --git a/ci-scripts/rhdh-setup/create_resource.sh b/ci-scripts/rhdh-setup/create_resource.sh
index 6ae78ab..6d842ee 100755
--- a/ci-scripts/rhdh-setup/create_resource.sh
+++ b/ci-scripts/rhdh-setup/create_resource.sh
@@ -152,6 +152,7 @@ create_cmp() {
 create_group() {
   token=$(get_token)
   groupname="group${0}"
+  echo "    g, group:default/${groupname}, role:default/perf_admin" >> "$TMP_DIR/group-rbac.yaml"
   curl -s -k --location --request POST "$(keycloak_url)/auth/admin/realms/backstage/groups" \
     -H 'Content-Type: application/json' \
     -H 'Authorization: Bearer '"$token" \
diff --git a/ci-scripts/rhdh-setup/deploy.sh b/ci-scripts/rhdh-setup/deploy.sh
index 8c06b02..8a9f3b6 100755
--- a/ci-scripts/rhdh-setup/deploy.sh
+++ b/ci-scripts/rhdh-setup/deploy.sh
@@ -52,6 +52,7 @@ export API_COUNT="${API_COUNT:-1}"
 export COMPONENT_COUNT="${COMPONENT_COUNT:-1}"
 export KEYCLOAK_USER_PASS=${KEYCLOAK_USER_PASS:-$(mktemp -u XXXXXXXXXX)}
 export AUTH_PROVIDER="${AUTH_PROVIDER:-''}"
+export ENABLE_RBAC="${ENABLE_RBAC:-false}"
 
 export INSTALL_METHOD=helm
 
@@ -157,7 +158,11 @@ backstage_install() {
     if [ "${AUTH_PROVIDER}" == "keycloak" ]; then yq -i '. |= . + {"signInPage":"oauth2Proxy"}' "$TMP_DIR/app-config.yaml"; fi
     if [ "${AUTH_PROVIDER}" == "keycloak" ]; then yq -i '. |= . + {"auth":{"environment":"production","providers":{"oauth2Proxy":{}}}}' "$TMP_DIR/app-config.yaml"; else yq -i '. |= . + {"auth":{"providers":{"guest":{"dangerouslyAllowOutsideDevelopment":true}}}}' "$TMP_DIR/app-config.yaml"; fi
     until envsubst <template/backstage/secret-rhdh-pull-secret.yaml | $clin apply -f -; do $clin delete secret rhdh-pull-secret --ignore-not-found=true; done
+    if ${ENABLE_RBAC}; then yq -i '. |= . + load("template/backstage/app-rbac-patch.yaml")' "$TMP_DIR/app-config.yaml"; fi
     until $clin create configmap app-config-rhdh --from-file "app-config.rhdh.yaml=$TMP_DIR/app-config.yaml"; do $clin delete configmap app-config-rhdh --ignore-not-found=true; done
+    cp template/backstage/rbac-config.yaml "${TMP_DIR}"
+    cat "$TMP_DIR/group-rbac.yaml">> "$TMP_DIR/rbac-config.yaml"
+    $clin apply -f "$TMP_DIR/rbac-config.yaml" --namespace="${RHDH_NAMESPACE}"
     envsubst <template/backstage/plugin-secrets.yaml | $clin apply -f -
     if [ "$INSTALL_METHOD" == "helm" ]; then
         install_rhdh_with_helm
@@ -188,6 +193,14 @@ install_rhdh_with_helm() {
     echo "Installing RHDH Helm chart $RHDH_HELM_RELEASE_NAME from $chart_origin in $RHDH_NAMESPACE namespace"
     cp "$chart_values" "$TMP_DIR/chart-values.temp.yaml"
     if [ "${AUTH_PROVIDER}" == "keycloak" ]; then yq -i '.upstream.backstage |= . + load("template/backstage/helm/oauth2-container-patch.yaml")' "$TMP_DIR/chart-values.temp.yaml"; fi
+    if ${ENABLE_RBAC}; then
+        if helm search repo --devel -r rhdh --version 1.2-1 --fail-on-no-result ; then
+            yq -i '.upstream.backstage |= . + load("template/backstage/helm/extravolume-patch-1.2.yaml")' "$TMP_DIR/chart-values.temp.yaml";
+        else
+            yq -i '.upstream.backstage |= . + load("template/backstage/helm/extravolume-patch-1.1.yaml")' "$TMP_DIR/chart-values.temp.yaml";
+        fi
+        yq -i '.global.dynamic.plugins |= . + load("template/backstage/helm/rbac-plugin-patch.yaml")' "$TMP_DIR/chart-values.temp.yaml";
+    fi
     envsubst \
         '${OPENSHIFT_APP_DOMAIN} \
             ${RHDH_HELM_RELEASE_NAME} \
diff --git a/ci-scripts/rhdh-setup/template/backstage/app-rbac-patch.yaml b/ci-scripts/rhdh-setup/template/backstage/app-rbac-patch.yaml
new file mode 100644
index 0000000..766d943
--- /dev/null
+++ b/ci-scripts/rhdh-setup/template/backstage/app-rbac-patch.yaml
@@ -0,0 +1,8 @@
+---
+permission:
+  enabled: true
+  rbac:
+    policies-csv-file: './rbac/rbac-policy.csv'
+    admin:
+      users:
+        - name: user:default/test1
diff --git a/ci-scripts/rhdh-setup/template/backstage/helm/extravolume-patch-1.1.yaml b/ci-scripts/rhdh-setup/template/backstage/helm/extravolume-patch-1.1.yaml
new file mode 100644
index 0000000..87d8800
--- /dev/null
+++ b/ci-scripts/rhdh-setup/template/backstage/helm/extravolume-patch-1.1.yaml
@@ -0,0 +1,53 @@
+---
+extraVolumeMounts:
+  - name: dynamic-plugins-root
+    mountPath: /opt/app-root/src/dynamic-plugins-root
+  - name: rbac-policy
+    mountPath: /opt/app-root/src/rbac
+extraVolumes:
+  - name: dynamic-plugins-root
+    ephemeral:
+      volumeClaimTemplate:
+        spec:
+          accessModes:
+            - ReadWriteOnce
+          resources:
+            requests:
+              # -- Size of the volume that will contain the dynamic plugins. It should be large enough to contain all the plugins.
+              storage: 2Gi
+  - name: dynamic-plugins
+    configMap:
+      defaultMode: 420
+      name: dynamic-plugins
+      optional: true
+  - name: rbac-policy
+    configMap:
+      defaultMode: 420
+      name: rbac-policy
+  - name: dynamic-plugins-npmrc
+    secret:
+      defaultMode: 420
+      optional: true
+      secretName: dynamic-plugins-npmrc
+initContainers:
+  - name: install-dynamic-plugins
+    image: '{{ include "backstage.image" . }}'
+    command:
+      - ./install-dynamic-plugins.sh
+      - /dynamic-plugins-root
+    env:
+      - name: NPM_CONFIG_USERCONFIG
+        value: /opt/app-root/src/.npmrc.dynamic-plugins
+    imagePullPolicy: Always
+    volumeMounts:
+      - mountPath: /dynamic-plugins-root
+        name: dynamic-plugins-root
+      - mountPath: /opt/app-root/src/dynamic-plugins.yaml
+        name: dynamic-plugins
+        readOnly: true
+        subPath: dynamic-plugins.yaml
+      - mountPath: /opt/app-root/src/.npmrc.dynamic-plugins
+        name: dynamic-plugins-npmrc
+        readOnly: true
+        subPath: .npmrc
+    workingDir: /opt/app-root/src
diff --git a/ci-scripts/rhdh-setup/template/backstage/helm/extravolume-patch-1.2.yaml b/ci-scripts/rhdh-setup/template/backstage/helm/extravolume-patch-1.2.yaml
new file mode 100644
index 0000000..9001641
--- /dev/null
+++ b/ci-scripts/rhdh-setup/template/backstage/helm/extravolume-patch-1.2.yaml
@@ -0,0 +1,61 @@
+---
+extraVolumeMounts:
+  - name: dynamic-plugins-root
+    mountPath: /opt/app-root/src/dynamic-plugins-root
+  - name: diststatic
+    mountPath: /opt/app-root/src/packages/app/dist/static
+  - name: rbac-policy
+    mountPath: /opt/app-root/src/rbac
+extraVolumes:
+  - name: dynamic-plugins-root
+    ephemeral:
+      volumeClaimTemplate:
+        spec:
+          accessModes:
+            - ReadWriteOnce
+          resources:
+            requests:
+              # -- Size of the volume that will contain the dynamic plugins. It should be large enough to contain all the plugins.
+              storage: 2Gi
+  - name: dynamic-plugins
+    configMap:
+      defaultMode: 420
+      name: dynamic-plugins
+      optional: true
+  - name: rbac-policy
+    configMap:
+      defaultMode: 420
+      name: rbac-policy
+  - name: dynamic-plugins-npmrc
+    secret:
+      defaultMode: 420
+      optional: true
+      secretName: dynamic-plugins-npmrc
+  - name: npmcacache
+    emptyDir: {}
+  - name: diststatic
+    emptyDir: {}
+initContainers:
+  - name: install-dynamic-plugins
+    image: '{{ include "backstage.image" . }}'
+    command:
+      - ./install-dynamic-plugins.sh
+      - /dynamic-plugins-root
+    env:
+      - name: NPM_CONFIG_USERCONFIG
+        value: /opt/app-root/src/.npmrc.dynamic-plugins
+    imagePullPolicy: Always
+    volumeMounts:
+      - mountPath: /dynamic-plugins-root
+        name: dynamic-plugins-root
+      - mountPath: /opt/app-root/src/dynamic-plugins.yaml
+        name: dynamic-plugins
+        readOnly: true
+        subPath: dynamic-plugins.yaml
+      - mountPath: /opt/app-root/src/.npmrc.dynamic-plugins
+        name: dynamic-plugins-npmrc
+        readOnly: true
+        subPath: .npmrc
+      - mountPath: /opt/app-root/src/.npm/_cacache
+        name: npmcacache
+    workingDir: /opt/app-root/src
\ No newline at end of file
diff --git a/ci-scripts/rhdh-setup/template/backstage/helm/rbac-plugin-patch.yaml b/ci-scripts/rhdh-setup/template/backstage/helm/rbac-plugin-patch.yaml
new file mode 100644
index 0000000..138fd2b
--- /dev/null
+++ b/ci-scripts/rhdh-setup/template/backstage/helm/rbac-plugin-patch.yaml
@@ -0,0 +1,3 @@
+---
+- package: ./dynamic-plugins/dist/janus-idp-backstage-plugin-rbac
+  disabled: false
diff --git a/ci-scripts/rhdh-setup/template/backstage/rbac-config.yaml b/ci-scripts/rhdh-setup/template/backstage/rbac-config.yaml
new file mode 100644
index 0000000..ac332b6
--- /dev/null
+++ b/ci-scripts/rhdh-setup/template/backstage/rbac-config.yaml
@@ -0,0 +1,11 @@
+kind: ConfigMap
+apiVersion: v1
+metadata:
+  name: rbac-policy
+data:
+  rbac-policy.csv: |
+    p, role:default/perf_admin, kubernetes.proxy, use, allow
+    p, role:default/perf_admin, catalog-entity, read, allow
+    p, role:default/perf_admin, catalog.entity.create, create, allow
+    p, role:default/perf_admin, catalog.location.create, create, allow
+    p, role:default/perf_admin, catalog.location.read, read, allow