hswaw: add printservant

Change-Id: Ia972cf7daedef87a7bba62ab2962b369c241d80d
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1890
Reviewed-by: informatic <informatic@hackerspace.pl>
diff --git a/app/inventory/prod.jsonnet b/app/inventory/prod.jsonnet
index 32ba5bf..117622c 100644
--- a/app/inventory/prod.jsonnet
+++ b/app/inventory/prod.jsonnet
@@ -12,7 +12,7 @@
 
     images: {
       app: 'registry.k0.hswaw.net/palid/inventory-31.01.2024-3',
-      labelmaker: 'registry.k0.hswaw.net/radex/spejstore-labelmaker:20240131004254',
+      labelmaker: 'registry.k0.hswaw.net/radex/spejstore-labelmaker:20240201181500',
     },
     oauthClientId: '82fffb65-0bbd-4d18-becd-0ce0b31373cf',
     storageClassName: 'waw-hdd-redundant-3',
@@ -25,8 +25,6 @@
     oauth: { secretKeyRef: { name: cfg.name, key: 'oauth_secret' } },
     s3Secret: { secretKeyRef: { name: cfg.name, key: 's3_secret_key' } },
     s3Access: { secretKeyRef: { name: cfg.name, key: 's3_access_key' } },
-    // Uses http basic auth
-    ipp_printer_url: { secretKeyRef: { name: cfg.name, key: 'ipp_printer_url' } },
   },
 
   local ns = kube.Namespace(cfg.namespace),
@@ -81,12 +79,13 @@
                 LABELMAKER_CODE_PREFIX: 'https://inventory.hackerspace.pl/',
                 LABELMAKER_LABEL_SIZE: '[89, 36]',
                 LABELMAKER_LOCAL_PRINTER_NAME: '',
-                LABELMAKER_IPP_PRINTER_URL: top.secretRefs.ipp_printer_url,
+                LABELMAKER_IPP_PRINTER_URL: '',
+                LABELMAKER_WEBHOOK: 'http://printservant.printservant.svc.cluster.local:3199/print?printer=dymo',
               },
               livenessProbe: {
                 httpGet: { path: '/api/2/health', port: 4567 },
-                initialDelaySeconds: 60,
-                periodSeconds: 60,
+                initialDelaySeconds: 5,
+                periodSeconds: 5 * 60,
               },
             },
           },
diff --git a/hswaw/printservant/OWNERS b/hswaw/printservant/OWNERS
new file mode 100644
index 0000000..f5bb617
--- /dev/null
+++ b/hswaw/printservant/OWNERS
@@ -0,0 +1,2 @@
+owners:
+  - radex
diff --git a/hswaw/printservant/README.md b/hswaw/printservant/README.md
new file mode 100644
index 0000000..93f954e
--- /dev/null
+++ b/hswaw/printservant/README.md
@@ -0,0 +1,12 @@
+# printservant
+
+HTTP to IPP proxy, a.k.a. HSWAW Rube Goldberg printing microservice
+
+Source and docs: https://code.hackerspace.pl/hswaw/printservant
+
+## TL;DR Usage
+
+`GET /print?printer={dymo,zebra,oki,brother}&copies=1` (body: PDF or PNG; or anything if correct Content-Type is passed)
+`GET /` to see full API
+
+in-cluster address: `printservant.printservant.svc.cluster.local:3199`
diff --git a/hswaw/printservant/prod.jsonnet b/hswaw/printservant/prod.jsonnet
new file mode 100644
index 0000000..eff319b
--- /dev/null
+++ b/hswaw/printservant/prod.jsonnet
@@ -0,0 +1,74 @@
+local kube = import "../../kube/hscloud.libsonnet";
+
+{
+    local top = self,
+    local cfg = self.cfg,
+
+    cfg:: {
+        name: 'printservant',
+        namespace: 'printservant',
+        image: 'registry.k0.hswaw.net/radex/printservant:20240202125925',
+    },
+
+    secretRefs:: {
+        basic_auth: { secretKeyRef: { name: cfg.name, key: 'basic_auth' } },
+    },
+
+    local ns = kube.Namespace(cfg.namespace),
+
+    deployment: ns.Contain(kube.Deployment(cfg.name)) {
+        spec+: {
+            replicas: 1,
+            template+: {
+                spec+: {
+                    containers_: {
+                        default: kube.Container("default") {
+                            image: cfg.image,
+                            ports_: {
+                                http: { containerPort: 3199 },
+                            },
+                            env_: {
+                                PRINTSERVANT_PORT: 3199,
+                                PRINTSERVANT_MAX_SIZE_MB: 10,
+                                BASIC_AUTH_SECRET: top.secretRefs.basic_auth, // quirk: must be first *alphabetically*
+                                PRINTSERVANT_CONFIG: std.manifestJsonEx({
+                                    printers: [
+                                        {
+                                            name: 'DYMO_LabelWriter450',
+                                            aliases: ['dymo', 'label'],
+                                            ipp_url: 'https://$(BASIC_AUTH_SECRET)@printmaster.waw.hackerspace.pl:443/printers/DYMO_LabelWriter450',
+                                        },
+                                        {
+                                            name: 'Zebra_GK420T',
+                                            aliases: ['zebra', 'biglabel', '4x6'],
+                                            ipp_url: 'https://$(BASIC_AUTH_SECRET)@printmaster.waw.hackerspace.pl:443/printers/Zebra_GK420T',
+                                        },
+                                        {
+                                            name: 'Brother_MFC8380DN',
+                                            aliases: ['brother', 'franciszek', 'a4'],
+                                            ipp_url: 'https://$(BASIC_AUTH_SECRET)@printmaster.waw.hackerspace.pl:443/printers/Brother_MFC8380DN',
+                                        },
+                                        {
+                                            name: 'OKI_C332',
+                                            aliases: ['oki', 'okiƂ', 'a4_color'],
+                                            ipp_url: 'https://$(BASIC_AUTH_SECRET)@printmaster.waw.hackerspace.pl:443/printers/OKI_C332',
+                                        }
+                                    ]
+                                }, '  '),
+                            },
+                            livenessProbe: {
+                                httpGet: { path: '/health', port: 3199 },
+                                initialDelaySeconds: 5,
+                                periodSeconds: 5 * 60,
+                            },
+                        },
+                    },
+                },
+            },
+        },
+    },
+
+    service: ns.Contain(kube.Service(cfg.name)) {
+        target:: top.deployment,
+    },
+}