smsgw: productionize, implement kube/mirko

This productionizes smsgw.

We also add some jsonnet machinery to provide a unified service for Go
micro/mirkoservices.

This machinery provides all the nice stuff:
 - a deployment
 - a service for all your types of pots
 - TLS certificates for HSPKI

We also update and test hspki for a new name scheme.

Change-Id: I292d00f858144903cbc8fe0c1c26eb1180d636bc
diff --git a/hswaw/kube/hswaw.jsonnet b/hswaw/kube/hswaw.jsonnet
new file mode 100644
index 0000000..d8a5131
--- /dev/null
+++ b/hswaw/kube/hswaw.jsonnet
@@ -0,0 +1,96 @@
+local mirko = import "../../kube/mirko.libsonnet";
+local kube = import "../../kube/kube.libsonnet";
+
+{
+    hswaw(name):: mirko.Environment(name) {
+        local env = self,
+        local cfg = self.cfg,
+
+        cfg+: {
+            smsgw: {
+                secret: {
+                    twilio_token: error "twilio_token must be set",
+                },
+                image: "registry.k0.hswaw.net/q3k/smsgs:1570049853-05c5b491c45de6d960979d4aee8635768f3178e9",
+                webhookFQDN: error "webhookFQDN must be set",
+            },
+        },
+
+        components: {
+            smsgw: mirko.Component(env, "smsgw") {
+                local smsgw = self,
+                cfg+: {
+                    image: cfg.smsgw.image,
+                    container: smsgw.GoContainer("main", "/smsgw/smsgw") {
+                        env_: {
+                            TWILIO_TOKEN: kube.SecretKeyRef(smsgw.secret, "twilio_token"),
+                        },
+                        command+: [
+                            "-twilio_friendly_phone", "48732168371",
+                            "-twilio_sid", "AC806ed4bf4b6c80c8f8ea686379b69518",
+                            "-twilio_token", "$(TWILIO_TOKEN)",
+                            "-webhook_listen", "0.0.0.0:5000",
+                            "-webhook_public", "https://%s/" % [ env.cfg.smsgw.webhookFQDN ],
+                        ],
+                    },
+                    ports+: {
+                        publicHTTP: {
+                            webhook: {
+                                port: 5000,
+                                dns: env.cfg.smsgw.webhookFQDN,
+                            }
+                        },
+                    },
+                },
+
+                secret: kube.Secret("smsgw") {
+                    metadata+: smsgw.metadata,
+                    data: env.cfg.smsgw.secret,
+                },
+
+                // Temporary machinery to access gRPC from outsite.
+                // In the future, this will be handled by a proxy/API gateway.
+                // For now, we need this running.
+                // TODO(q3k): remove this when we have an API GW or proxy.
+                stopgap: {
+                    rpcLB: kube.Service("smsgw-tcp-rpc") {
+                        metadata+: smsgw.metadata,
+                        target_pod: smsgw.deployment.spec.template,
+                        spec+: {
+                            type: "LoadBalancer",
+                            ports: [
+                                { name: "grpc-external", port: 443, targetPort: 4200 },
+                            ],
+                        },
+                    },
+
+                    rpcCertificate: kube.Certificate("smsgw-tcp-rpc-consumer") {
+                        metadata+: smsgw.metadata,
+                        spec: {
+                            secretName: "smsgw-tcp-rpc-consumer",
+                            duration: "35040h0m0s", // 4 years
+                            issuerRef: {
+                                // Contract with cluster/lib/pki.libsonnet.
+                                // Copied over.
+                                name: "pki-ca",
+                                kind: "ClusterIssuer",
+                            },
+                            commonName: "kasownik.external.hswaw.net",
+                        },
+                    },
+                }
+            },
+        },
+    },
+
+    prod: self.hswaw("hswaw-prod") {
+        cfg+: {
+            smsgw+: {
+                secret+: {
+                    twilio_token: std.base64(std.split(importstr "secrets/plain/prod-twilio-token", "\n")[0]),
+                },
+                webhookFQDN: "smsgw-webhook-prod.hswaw.net",
+            }
+        },
+    },
+}