devtools/issues: redmine deployment

Change-Id: I71956c4132bf2063e9fc41eb24c4f37657b8fd9d
diff --git a/devtools/issues/redmine.libsonnet b/devtools/issues/redmine.libsonnet
new file mode 100644
index 0000000..420e488
--- /dev/null
+++ b/devtools/issues/redmine.libsonnet
@@ -0,0 +1,123 @@
+local kube = import "../../kube/kube.libsonnet";
+local postgres = import "../../kube/postgres.libsonnet";
+
+{
+    local app = self,
+    local cfg = app.cfg,
+
+    cfg:: {
+        namespace: "redmine",
+        image: "registry.k0.hswaw.net/informatic/redmine@sha256:b04d1fd04549424e505722c9feb0b6741a057cb8f0fab68ad3730ecb167417df",
+        domain: error "domain must be set",
+        storageClassName: "waw-hdd-redundant-3",
+        database: {
+            host: "postgres",
+            name: "redmine",
+            username: "redmine",
+            password: { secretKeyRef: { name: "redmine", key: "postgres_password" } },
+            port: 5432,
+        },
+
+        storage: {
+            endpoint: error "storage.endpoint must be set",
+            region: error "storage.region must be set",
+            bucket: error "storage.bucket must be set",
+            accessKey: error "storage.accessKey must be set",
+            secretKey: error "storage.secretKey must be set",
+        },
+
+        oidc: {
+            server: error "oidc.server must be set",
+            clientID: error "oidc.clientID must be set",
+            clientSecret: error "oidc.clientSecret must be set",
+        },
+    },
+
+    ns: kube.Namespace(app.cfg.namespace),
+
+    postgres: postgres {
+        cfg+: {
+            namespace: cfg.namespace,
+            appName: "redmine",
+            database: cfg.database.name,
+            username: cfg.database.username,
+            password: cfg.database.password,
+            storageClassName: cfg.storageClassName,
+        },
+    },
+
+    deployment: app.ns.Contain(kube.Deployment("redmine")) {
+        spec+: {
+            replicas: 1,
+            template+: {
+                spec+: {
+                    securityContext: {
+                        runAsUser: 999,
+                        runAsGroup: 999,
+                        fsGroup: 999,
+                    },
+                    containers_: {
+                        web: kube.Container("redmine") {
+                            image: cfg.image,
+                            ports_: {
+                                http: { containerPort: 3000 },
+                            },
+                            env_: {
+                                REDMINE_DB_POSTGRES: cfg.database.host,
+                                REDMINE_DB_PORT: cfg.database.port,
+                                REDMINE_DB_USERNAME: cfg.database.username,
+                                REDMINE_DB_PASSWORD: cfg.database.password,
+                                REDMINE_DB_DATABASE: cfg.database.name,
+
+                                REDMINE_SECRET_KEY_BASE: { secretKeyRef: { name: "redmine", key: "secret_key" } },
+
+                                REDMINE_OIDC_SERVER: cfg.oidc.server,
+                                REDMINE_OIDC_CLIENT_ID: cfg.oidc.clientID,
+                                REDMINE_OIDC_CLIENT_SECRET: cfg.oidc.clientSecret,
+                                REDMINE_OIDC_ADMIN_GROUP: "issues-admin",
+
+                                REDMINE_S3_ENDPOINT: cfg.storage.endpoint,
+                                REDMINE_S3_BUCKET: cfg.storage.bucket,
+                                REDMINE_S3_ACCESS_KEY_ID: cfg.storage.accessKey,
+                                REDMINE_S3_SECRET_ACCESS_KEY: cfg.storage.secretKey,
+                                REDMINE_S3_REGION: cfg.storage.region,
+                            },
+                        },
+                    },
+                },
+            },
+        },
+    },
+
+    svc: app.ns.Contain(kube.Service("redmine")) {
+        target_pod:: app.deployment.spec.template,
+    },
+
+    ingress: app.ns.Contain(kube.Ingress("redmine")) {
+        metadata+: {
+            annotations+: {
+                "kubernetes.io/tls-acme": "true",
+                "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
+                "nginx.ingress.kubernetes.io/proxy-body-size": "0",
+            },
+        },
+        spec+: {
+            tls: [
+                {
+                    hosts: [cfg.domain],
+                    secretName: "redmine-tls",
+                },
+            ],
+            rules: [
+                {
+                    host: cfg.domain,
+                    http: {
+                        paths: [
+                            { path: "/", backend: app.svc.name_port },
+                        ]
+                    },
+                }
+            ],
+        },
+    },
+}