cluster/kube: finish rook operator
diff --git a/cluster/kube/lib/rook.libsonnet b/cluster/kube/lib/rook.libsonnet
index 7327500..13e3f56 100644
--- a/cluster/kube/lib/rook.libsonnet
+++ b/cluster/kube/lib/rook.libsonnet
@@ -143,5 +143,159 @@
             },
         },
 
+        sa: kube.ServiceAccount("rook-ceph-system") {
+            metadata+: env.metadata,
+        },
+
+        crs: {
+            clusterMgmt: kube.ClusterRole("rook-ceph-cluster-mgmt") {
+                metadata+: env.metadata {
+                    namespace:: null,
+                },
+                rules: [
+                    {
+                        apiGroups: [""],
+                        resources: ["secrets", "pods", "pods/log", "services", "configmaps"],
+                        verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
+                    },
+                    {
+                        apiGroups: ["apps"],
+                        resources: ["deployments", "daemonsets", "replicasets"],
+                        verbs: ["get", "list", "watch", "create", "update", "delete"],
+                    },
+                ],
+            },
+            global: kube.ClusterRole("rook-ceph-global") {
+                metadata+: env.metadata {
+                    namespace:: null,
+                },
+                rules: [
+                    {
+                        apiGroups: [""],
+                        resources: ["pods", "nodes", "nodes/proxy"],
+                        verbs: ["get", "list", "watch"],
+                    },
+                    {
+                        apiGroups: [""],
+                        resources: ["events", "persistentvolumes", "persistentvolumeclaims", "endpoints"],
+                        verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
+                    },
+                    {
+                        apiGroups: ["storage.k8s.io"],
+                        resources: ["storageclasses"],
+                        verbs: ["get", "list", "watch", "create", "update", "delete"],
+                    },
+                    {
+                        apiGroups: ["ceph.rook.io"],
+                        resources: ["*"],
+                        verbs: ["*"],
+                    },
+                    {
+                        apiGroups: ["rook.io"],
+                        resources: ["*"],
+                        verbs: ["*"],
+                    },
+                ],
+            },
+            mgrCluster: kube.ClusterRole("rook-ceph-mgr-cluster") {
+                metadata+: env.metadata {
+                    namespace:: null,
+                },
+                rules: [
+                    {
+                        apiGroups: [""],
+                        resources: ["configmaps", "nodes", "nodes/proxy"],
+                        verbs: ["get", "list", "watch"],
+                    },
+                ]
+            },
+        },
+
+        crb: kube.ClusterRoleBinding("ceph-rook-global") {
+            metadata+: env.metadata,
+            roleRef: {
+                apiGroup: "rbac.authorization.k8s.io",
+                kind: "ClusterRole",
+                name: env.crs.global.metadata.name,
+            },
+            subjects: [
+                {
+                    kind: "ServiceAccount",
+                    name: env.sa.metadata.name,
+                    namespace: env.sa.metadata.namespace,
+                },
+            ],
+        },
+
+        role: kube.Role("ceph-rook-system") {
+            metadata+: env.metadata,
+            rules: [
+                {
+                    apiGroups: [""],
+                    resources: ["pods", "configmaps"],
+                    verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
+                },
+                {
+                    apiGroups: ["apps"],
+                    resources: ["daemonsets"],
+                    verbs: ["get", "list", "watch", "create", "update", "delete"],
+                },
+            ],
+        },
+
+        rb: kube.RoleBinding("ceph-rook-system") {
+            metadata+: env.metadata,
+            roleRef: {
+                apiGroup: "rbac.authorization.k8s.io",
+                kind: "Role",
+                name: env.role.metadata.name,
+            },
+            subjects: [
+                {
+                    kind: "ServiceAccount",
+                    name: env.sa.metadata.name,
+                    namespace: env.sa.metadata.namespace,
+                },
+            ],
+        },
+
+        operator: kube.Deployment("rook-ceph-operator") {
+            metadata+: env.metadata,
+            spec+: {
+                template+: {
+                    spec+: {
+                        serviceAccountName: env.sa.metadata.name,
+                        containers_: {
+                            operator: kube.Container("rook-ceph-operator") {
+                                image: cfg.image,
+                                args: ["ceph", "operator"],
+                                volumeMounts_: {
+                                    "rook-config": { mountPath: "/var/lib/rook" },
+                                    "default-config-dir": { mountPath: "/etc/ceph" },
+                                },
+                                env_: {
+                                    LIB_MODULES_DIR_PATH: "/run/current-system/kernel-modules/lib/modules/",
+                                    ROOK_ALLOW_MULTIPLE_FILESYSTEMS: "false",
+                                    ROOK_LOG_LEVEL: "info",
+                                    ROOK_MON_HEALTHCHECK_INTERVAL: "45s",
+                                    ROOK_MON_OUT_TIMEOUT: "600s",
+                                    ROOK_DISCOVER_DEVICES_INTERVAL: "60m",
+                                    ROOK_HOSTPATH_REQUIRES_PRIVILEGED: "false",
+                                    ROOK_ENABLE_SELINUX_RELABELING: "true",
+                                    ROOK_ENABLE_FSGROUP: "true",
+                                    NODE_NAME: kube.FieldRef("spec.nodeName"),
+                                    POD_NAME: kube.FieldRef("metadata.name"),
+                                    POD_NAMESPACE: kube.FieldRef("metadata.namespace"),
+                                },
+                            },
+                        },
+                        volumes_: {
+                            "rook-config": { emptyDir: {} },
+                            "default-config-dir": { emptyDir: {} },
+                        },
+                    },
+                },
+            },
+        },
     },
 }