hswaw/kube: add pretalx
Change-Id: Ia7512aa988022c3c7fd89f81927fbad03f933cf1
diff --git a/hswaw/kube/pretalx.libsonnet b/hswaw/kube/pretalx.libsonnet
new file mode 100644
index 0000000..2388529
--- /dev/null
+++ b/hswaw/kube/pretalx.libsonnet
@@ -0,0 +1,255 @@
+local mirko = import "../../kube/mirko.libsonnet";
+local kube = import "../../kube/kube.libsonnet";
+local postgres = import "../../kube/postgres.libsonnet";
+local redis = import "../../kube/redis.libsonnet";
+
+// Copy over the secret from the ceph cluster namespace to the environment
+// namespace. Eg.
+// cluster=ceph-waw3
+// pool=waw-hdd-redundant-3-object
+// namespace=hswaw-prod
+// kubectl get -n $cluster secret rook-ceph-object-user-$pool-$namespace-pretalx-s3 -o json > hswaw/kube/secrets/plain/prod-pretalx-s3.json
+
+{
+ local cfg = self.cfg,
+ cfg:: {
+ // q3k's fork for S3 support (q3k/s3)
+ image: "registry.k0.hswaw.net/q3k/pretalx-docker:20200217-1581977177",
+ storageClassName: error "storageClassName must be set!",
+ webFQDN: error "webFQDN must be set!",
+
+ smtpPassword: error "smtpPassword must be set!",
+
+ s3: {
+ cluster: "ceph-waw3",
+ pool: "waw-hdd-redundant-3-object",
+ credsSecret: error "credsSecret msut be set",
+ },
+
+ smtp: {
+ server: "mail.hackerspace.pl",
+ from: "pretalx@hackerspace.pl",
+ username: "pretalx",
+ },
+ },
+
+ component(cfg, env): mirko.Component(env, "pretalx") {
+ local pretalx = self,
+ cfg+: {
+ image: cfg.image,
+ volumes+: {
+ data: kube.PersistentVolumeClaimVolume(pretalx.volumeData),
+ config: kube.SecretVolume(pretalx.config),
+ },
+
+ pgpass:: { secretKeyRef: { name: pretalx.makeName("-postgres"), key: "postgres_password", } },
+
+ containers:: {
+ default: pretalx.Container("main") {
+ volumeMounts_+: {
+ data: { mountPath: "/data", },
+ config: { mountPath: "/etc/pretalx" },
+ },
+ workingDir: "/pretalx/src",
+ command: [
+ "gunicorn", "pretalx.wsgi",
+ "--name", "pretalx",
+ "--workers", "4",
+ "--max-requests", "1200",
+ "--max-requests-jitter", "50",
+ "--log-level", "info",
+ "--bind", "0.0.0.0:8080",
+ ],
+ env_: {
+ PRETALX_DB_PASS: pretalx.cfg.pgpass,
+ HOME: "/pretalx",
+ PRETALX_DATA_DIR: "/data",
+ },
+ resources: {
+ // thicc Python
+ requests: {
+ cpu: "100m",
+ memory: "512Mi",
+ },
+ limits: {
+ cpu: "1",
+ memory: "2Gi",
+ },
+ },
+ },
+ worker: pretalx.Container("worker") {
+ volumeMounts_+: {
+ data: { mountPath: "/data", },
+ config: { mountPath: "/etc/pretalx" },
+ },
+ workingDir: "/pretalx/src",
+ command: [
+ "celery", "-A", "pretalx.celery_app", "worker",
+ "-l", "info",
+ ],
+ env_: {
+ PRETALX_DB_PASS: pretalx.cfg.pgpass,
+ HOME: "/pretalx",
+ PRETALX_DATA_DIR: "/data",
+ },
+ resources: {
+ // thicc Python
+ requests: {
+ cpu: "100m",
+ memory: "512Mi",
+ },
+ limits: {
+ cpu: "1",
+ memory: "2Gi",
+ },
+ },
+ },
+ },
+ securityContext: {
+ runAsUser: 999,
+ },
+ ports+: {
+ publicHTTP: {
+ web: {
+ port: 8080,
+ dns: cfg.webFQDN,
+ },
+ },
+ },
+ },
+
+ secret: kube.Secret(pretalx.makeName("secret")) {
+ metadata+: pretalx.metadata,
+ data: {
+ smtpPassword: cfg.smtpPassword,
+ },
+ },
+
+ cronjob: kube.CronJob(pretalx.makeName("runperiodic")) {
+ metadata+: pretalx.metadata,
+ spec+: {
+ schedule: "*/5 * * * *",
+ jobTemplate+: {
+ spec+: {
+ selector:: null,
+ template+: {
+ spec+: {
+ containers_: {
+ runperiodic: kube.Container("runperiodic") {
+ image: cfg.image,
+ workingDir: "/pretalx/src",
+ volumeMounts_+: {
+ config: { mountPath: "/etc/pretalx" },
+ },
+ env_: {
+ PRETALX_DB_PASS: pretalx.cfg.pgpass,
+ HOME: "/pretalx",
+ PRETALX_DATA_DIR: "/data",
+ },
+ command: [
+ "python3", "-m", "pretalx",
+ "runperiodic",
+ ],
+ },
+ },
+ securityContext: {
+ runAsUser: 999,
+ },
+ volumes_+: {
+ config: kube.SecretVolume(pretalx.config),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ config: kube.Secret(pretalx.makeName("-config")) {
+ metadata+: pretalx.metadata,
+ data: {
+ "pretalx.cfg": std.base64(std.manifestIni({
+ sections: {
+ filesystem: {
+ data: "/data", media: "/data/media", logs: "/data/logs",
+ },
+ site: {
+ debug: false,
+ url: "https://%s" % cfg.webFQDN,
+ },
+ s3media: {
+ bucket: "pretalx-prod",
+ access_key_id: std.base64Decode(cfg.s3.credsSecret.data.AccessKey),
+ secret_access_key: std.base64Decode(cfg.s3.credsSecret.data.SecretKey),
+ endpoint: "https://object.ceph-waw3.hswaw.net",
+ },
+ database: {
+ backend: "postgresql",
+ name: "pretalx",
+ user: "pretalx",
+ // password: ... // provided by environment variable from secret
+ host: pretalx.postgres.bouncer.svc.host,
+ //port: 5432
+ },
+ mail: {
+ from: cfg.smtp.from,
+ host: cfg.smtp.server,
+ port: 587,
+ user: cfg.smtp.username,
+ password: cfg.smtpPassword,
+ tls: "True",
+ },
+ celery: {
+ backend: "redis://%s/1" % [pretalx.redis.svc.host],
+ broker: "redis://%s/2" % [pretalx.redis.svc.host],
+ },
+ },
+ })),
+ },
+ },
+
+ postgres: postgres {
+ cfg+: {
+ namespace: pretalx.metadata.namespace,
+ appName: pretalx.makeName("-pretalx"),
+ storageClassName: cfg.storageClassName,
+ prefix: pretalx.makeName("-postgres") + "-",
+ database: "pretalx",
+ username: "pretalx",
+ password: pretalx.cfg.pgpass,
+ },
+ },
+
+ redis: redis {
+ cfg+: {
+ namespace: pretalx.metadata.namespace,
+ appName: pretalx.makeName("-pretalx"),
+ storageClassName: cfg.storageClassName,
+ prefix: pretalx.makeName("-redis") + "-",
+ },
+ },
+
+ volumeData: kube.PersistentVolumeClaim(pretalx.makeName("-data")) {
+ metadata+: pretalx.metadata,
+ spec+: {
+ storageClassName: cfg.storageClassName,
+ accessModes: ["ReadWriteOnce"],
+ resources: {
+ requests: {
+ storage: "5Gi",
+ },
+ },
+ },
+ },
+
+ s3: kube.CephObjectStoreUser(pretalx.makeNameGlobal("-s3")) {
+ metadata+: {
+ namespace: cfg.s3.cluster,
+ },
+ spec: {
+ store: cfg.s3.pool,
+ displayName: pretalx.makeNameGlobal("-s3"),
+ },
+ },
+ },
+}