cluster/kube: Centralize namespace admin RoleBindings

Change-Id: Iec3505b2f4a1647e67cf47cf189c77534b5be6ac
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1696
Reviewed-by: q3k <q3k@hackerspace.pl>
diff --git a/app/matrix/global.jsonnet b/app/matrix/global.jsonnet
deleted file mode 100644
index a829745..0000000
--- a/app/matrix/global.jsonnet
+++ /dev/null
@@ -1,24 +0,0 @@
-local kube = import "../../kube/kube.libsonnet";
-
-// Global resources specific to Matrix deployments. Currently this is only RBAC objects.
-
-{
-    // Allow non-staff admin access to matrix.0x3c.pl.
-    admin0x3c: kube.RoleBinding("admins") {
-        metadata+: {
-            namespace: "matrix-0x3c",
-        },
-        roleRef: {
-            apiGroup: "rbac.authorization.k8s.io",
-            kind: "ClusterRole",
-            name: "system:admin-namespace",
-        },
-        subjects: [
-            {
-                apiGroup: "rbac.authorization.k8s.io",
-                kind: "User",
-                name: "not7cd@hackerspace.pl",
-            },
-        ],
-    },
-}
diff --git a/cluster/kube/k0-admins.jsonnet b/cluster/kube/k0-admins.jsonnet
new file mode 100644
index 0000000..96e44ad
--- /dev/null
+++ b/cluster/kube/k0-admins.jsonnet
@@ -0,0 +1,7 @@
+// Only the admins (per-namespace RoleBindings)
+
+local k0 = (import "k0.libsonnet").k0;
+
+{
+    admins: k0.admins,
+}
diff --git a/cluster/kube/k0.libsonnet b/cluster/kube/k0.libsonnet
index 7a0f69b..81627ac 100644
--- a/cluster/kube/k0.libsonnet
+++ b/cluster/kube/k0.libsonnet
@@ -11,6 +11,7 @@
 local cockroachdb = import "lib/cockroachdb.libsonnet";
 local registry = import "lib/registry.libsonnet";
 local rook = import "lib/rook.libsonnet";
+local admins = import "lib/admins.libsonnet";
 
 {
     k0: {
@@ -375,5 +376,37 @@
                 },
             },
         },
+
+        // Configuration of RoleBindings
+        admins: admins.NamespaceAdmins {
+            // Cluster staff have full access to all namespaces
+            // To give non-staff users admin access scoped to a given namespace,
+            // add them to the list below.
+            // (system:admin-namespace role is given to <user>@hackerspace.pl)
+            namespaces:: {
+                "inventory": [
+                    "radex",
+                    "palid",
+                ],
+                "site": [
+                    "ar",
+                    "radex",
+                ],
+                "valheim": [
+                    "patryk",
+                    "palid",
+                ],
+                "matrix-0x3c": [
+                    "not7cd",
+                ],
+                "hswaw-prod": [
+                    "ar",
+                    "radex",
+                ],
+                "ldapweb": [
+                    "radex",
+                ],
+            }
+        }
     },
 }
diff --git a/cluster/kube/lib/admins.libsonnet b/cluster/kube/lib/admins.libsonnet
new file mode 100644
index 0000000..a0e1553
--- /dev/null
+++ b/cluster/kube/lib/admins.libsonnet
@@ -0,0 +1,26 @@
+local kube = import "../../../kube/kube.libsonnet";
+
+{
+    local createNamespaceRoleBinding(namespace, users) = kube.RoleBinding("admins") {
+        metadata+: {
+            namespace: namespace,
+        },
+        roleRef: {
+            apiGroup: "rbac.authorization.k8s.io",
+            kind: "ClusterRole",
+            name: "system:admin-namespace",
+        },
+        subjects: [
+            kube.User("%s@hackerspace.pl" % [user])
+            for user in users
+        ],
+    },
+    NamespaceAdmins: {
+        namespaces:: error "namespaces not set",
+        local namespaces = self.namespaces,
+        roleBindings: [
+            createNamespaceRoleBinding(namespace, namespaces[namespace])
+            for namespace in std.objectFields(namespaces)
+        ],
+    },
+}
diff --git a/games/valheim/prod.jsonnet b/games/valheim/prod.jsonnet
index 82e2907..35661ea 100644
--- a/games/valheim/prod.jsonnet
+++ b/games/valheim/prod.jsonnet
@@ -192,19 +192,6 @@
     # Make namespace for valheim.
     ns: kube.Namespace("valheim"),
 
-    # Allow patryk and palid to administer this namespace via the namespace-admin clusterrole.
-    adminRB: top.ns.Contain(kube.RoleBinding("sso:admins")) {
-        subjects: [
-            { apiGroup: "rbac.authorization.k8s.io", kind: "User", name: "%s@hackerspace.pl" % [u] }
-            for u in ["patryk", "palid"]
-        ],
-        roleRef: {
-            apiGroup: "rbac.authorization.k8s.io",
-            kind: "ClusterRole",
-            name: "system:admin-namespace",
-        },
-    },
-
     q3k: top.env(top.ns, "q3k") {
         cfg+: {
             ns: "valheim",
diff --git a/hswaw/kube/hswaw.jsonnet b/hswaw/kube/hswaw.jsonnet
index f7206ad..172cda3 100644
--- a/hswaw/kube/hswaw.jsonnet
+++ b/hswaw/kube/hswaw.jsonnet
@@ -67,19 +67,4 @@
             },
         },
     },
-
-    admins: kube.RoleBinding("admins") {
-        metadata+: {
-            namespace: "hswaw-prod",
-        },
-        roleRef: {
-            apiGroup: "rbac.authorization.k8s.io",
-            kind: "ClusterRole",
-            name: "system:admin-namespace",
-        },
-        subjects: [
-            kube.User("ar@hackerspace.pl"),
-            kube.User("radex@hackerspace.pl"),
-        ],
-    },
 }