hswaw/kube: refactor
This breaks up hswaw.jsonnet into a component-per-file pattern.
Change-Id: I1b83d44146ae6c3d3f7c5d02abc2c9b764cc0e8e
diff --git a/hswaw/kube/hswaw.jsonnet b/hswaw/kube/hswaw.jsonnet
index e0b5432..905d964 100644
--- a/hswaw/kube/hswaw.jsonnet
+++ b/hswaw/kube/hswaw.jsonnet
@@ -1,191 +1,22 @@
local mirko = import "../../kube/mirko.libsonnet";
local kube = import "../../kube/kube.libsonnet";
+local smsgw = import "smsgw.libsonnet";
+local ldapweb = import "ldapweb.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",
- },
- ldapweb: {
- # Manually built from code.hackerspace.pl/q3k/ldap-web-public.
- image: "registry.k0.hswaw.net/q3k/ldap-web:1571402374",
-
- webFQDN: error "webFQDN must be set",
- },
+ smsgw: smsgw.cfg,
+ ldapweb: ldapweb.cfg,
},
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: {
- local stopgap = self,
-
- 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 },
- ],
- },
- },
-
- mkClientCert(name, cn):: kube.Certificate(name) {
- metadata+: smsgw.metadata,
- spec: {
- secretName: name,
- duration: "35040h0m0s", // 4 years
- issuerRef: {
- // Contract with cluster/lib/pki.libsonnet.
- // Copied over.
- name: "pki-ca",
- kind: "ClusterIssuer",
- },
- commonName: cn,
- },
- },
-
- kasownikCert: stopgap.mkClientCert("smsgw-tcp-rpc-consumer", "kasownik.external.hswaw.net"),
- piorekfCert: stopgap.mkClientCert("smsgw-tcp-rpc-piorekf", "piorekf.person.hswaw.net"),
- }
- },
-
- ldapweb: mirko.Component(env, "ldapweb") {
- local ldapweb = self,
- cfg+: {
- image: cfg.ldapweb.image,
- volumes+: {
- config: kube.ConfigMapVolume(ldapweb.configmap),
- },
- container: ldapweb.Container("main") {
- # Starts by default on port 8000.
- volumeMounts_+: {
- config: { mountPath: "/app/webapp/config.py", subPath: "config.py", },
- },
- },
- ports+: {
- publicHTTP: {
- web: {
- port: 8000,
- dns: env.cfg.ldapweb.webFQDN,
- },
- },
- },
- },
-
- configmap: kube.ConfigMap(ldapweb.makeName("config")) {
- metadata+: ldapweb.metadata,
- data: {
- "config.py": |||
- # -*- coding: utf-8 -*-
- import flask_wtf
- import wtforms
- ldap_url = 'ldap://ldap.hackerspace.pl'
- dn_format = "uid=%s,ou=people,dc=hackerspace,dc=pl"
-
- admin_dn = 'cn=ldapweb,ou=Services,dc=hackerspace,dc=pl'
- admin_pw = 'unused'
-
- hackerspace_name = 'Warsaw Hackerspace'
-
- readable_names = {
- 'commonname': u'Common Name',
- 'givenname': u'Given Name',
- 'gecos': u'GECOS (public name)',
- 'surname': u'Surname',
- 'loginshell': u'Shell',
- 'telephonenumber': 'Phone Number',
- 'mobiletelephonenumber': 'Mobile Number',
- 'sshpublickey': 'SSH Public Key',
- }
-
- full_name = {
- 'cn': 'commonname',
- 'gecos': 'gecos',
- 'sn': 'surname',
- 'mobile': 'mobiletelephonenumber',
- 'l': 'locality',
- }
-
- can_add = set([
- 'telephonenumber',
- 'mobiletelephonenumber',
- 'sshpublickey',
- ])
- can_delete = can_add
- can_modify = can_add | set([
- 'givenname', 'surname', 'commonname', 'gecos',
- ])
- can = { 'add':can_add, 'mod':can_modify, 'del':can_delete }
- admin_required = set()
-
-
- perm_errors = {
- 'add': 'You cannot add this attribute!',
- 'mod': 'You cannot change this attribute!',
- 'del': 'You cannot delete this attribute!',
- }
- std_templates = {
- 'add': 'ops/add.html',
- 'mod': 'ops/mod.html',
- 'del': 'ops/del.html',
- }
-
-
-
- default_field = (wtforms.fields.StringField, {})
- fields = { 'telephonenumber': (wtforms.fields.StringField, {'validators': [wtforms.validators.Regexp(r'[+0-9 ]+')]})}
-
- kadmin_passwd = True
- kadmin_principal_map = "{}@HACKERSPACE.PL"
-
- TOKEN_LENGTH = 32
- |||,
- },
- },
- },
+ smsgw: smsgw.component(cfg.smsgw, env),
+ ldapweb: ldapweb.component(cfg.ldapweb, env),
},
},
diff --git a/hswaw/kube/ldapweb.libsonnet b/hswaw/kube/ldapweb.libsonnet
new file mode 100644
index 0000000..af6320b
--- /dev/null
+++ b/hswaw/kube/ldapweb.libsonnet
@@ -0,0 +1,105 @@
+local mirko = import "../../kube/mirko.libsonnet";
+local kube = import "../../kube/kube.libsonnet";
+
+{
+ cfg:: {
+ # Manually built from code.hackerspace.pl/q3k/ldap-web-public.
+ image: "registry.k0.hswaw.net/q3k/ldap-web:1571402374",
+ webFQDN: error "webFQDN must be set!",
+ },
+
+ component(cfg, env): mirko.Component(env, "ldapweb") {
+ local ldapweb = self,
+ cfg+: {
+ image: cfg.image,
+ volumes+: {
+ config: kube.ConfigMapVolume(ldapweb.configmap),
+ },
+ container: ldapweb.Container("main") {
+ # Starts by default on port 8000.
+ volumeMounts_+: {
+ config: { mountPath: "/app/webapp/config.py", subPath: "config.py", },
+ },
+ },
+ ports+: {
+ publicHTTP: {
+ web: {
+ port: 8000,
+ dns: cfg.webFQDN,
+ },
+ },
+ },
+ },
+
+ configmap: kube.ConfigMap(ldapweb.makeName("config")) {
+ metadata+: ldapweb.metadata,
+ data: {
+ "config.py": |||
+ # -*- coding: utf-8 -*-
+ import flask_wtf
+ import wtforms
+ ldap_url = 'ldap://ldap.hackerspace.pl'
+ dn_format = "uid=%s,ou=people,dc=hackerspace,dc=pl"
+
+ admin_dn = 'cn=ldapweb,ou=Services,dc=hackerspace,dc=pl'
+ admin_pw = 'unused'
+
+ hackerspace_name = 'Warsaw Hackerspace'
+
+ readable_names = {
+ 'commonname': u'Common Name',
+ 'givenname': u'Given Name',
+ 'gecos': u'GECOS (public name)',
+ 'surname': u'Surname',
+ 'loginshell': u'Shell',
+ 'telephonenumber': 'Phone Number',
+ 'mobiletelephonenumber': 'Mobile Number',
+ 'sshpublickey': 'SSH Public Key',
+ }
+
+ full_name = {
+ 'cn': 'commonname',
+ 'gecos': 'gecos',
+ 'sn': 'surname',
+ 'mobile': 'mobiletelephonenumber',
+ 'l': 'locality',
+ }
+
+ can_add = set([
+ 'telephonenumber',
+ 'mobiletelephonenumber',
+ 'sshpublickey',
+ ])
+ can_delete = can_add
+ can_modify = can_add | set([
+ 'givenname', 'surname', 'commonname', 'gecos',
+ ])
+ can = { 'add':can_add, 'mod':can_modify, 'del':can_delete }
+ admin_required = set()
+
+
+ perm_errors = {
+ 'add': 'You cannot add this attribute!',
+ 'mod': 'You cannot change this attribute!',
+ 'del': 'You cannot delete this attribute!',
+ }
+ std_templates = {
+ 'add': 'ops/add.html',
+ 'mod': 'ops/mod.html',
+ 'del': 'ops/del.html',
+ }
+
+
+
+ default_field = (wtforms.fields.StringField, {})
+ fields = { 'telephonenumber': (wtforms.fields.StringField, {'validators': [wtforms.validators.Regexp(r'[+0-9 ]+')]})}
+
+ kadmin_passwd = True
+ kadmin_principal_map = "{}@HACKERSPACE.PL"
+
+ TOKEN_LENGTH = 32
+ |||,
+ },
+ },
+ },
+}
diff --git a/hswaw/kube/smsgw.libsonnet b/hswaw/kube/smsgw.libsonnet
new file mode 100644
index 0000000..a35b892
--- /dev/null
+++ b/hswaw/kube/smsgw.libsonnet
@@ -0,0 +1,81 @@
+local mirko = import "../../kube/mirko.libsonnet";
+local kube = import "../../kube/kube.libsonnet";
+
+{
+ cfg:: {
+ secret: {
+ twilio_token: error "twilio_token must be set",
+ },
+ image: "registry.k0.hswaw.net/q3k/smsgs:1570049853-05c5b491c45de6d960979d4aee8635768f3178e9",
+ webhookFQDN: error "webhookFQDN must be set",
+ },
+
+ component(cfg, env):: mirko.Component(env, "smsgw") {
+ local smsgw = self,
+ cfg+: {
+ image: cfg.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/" % [ cfg.webhookFQDN ],
+ ],
+ },
+ ports+: {
+ publicHTTP: {
+ webhook: {
+ port: 5000,
+ dns: cfg.webhookFQDN,
+ }
+ },
+ },
+ },
+
+ secret: kube.Secret("smsgw") {
+ metadata+: smsgw.metadata,
+ data: cfg.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: {
+ local stopgap = self,
+
+ 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 },
+ ],
+ },
+ },
+
+ mkClientCert(name, cn):: kube.Certificate(name) {
+ metadata+: smsgw.metadata,
+ spec: {
+ secretName: name,
+ duration: "35040h0m0s", // 4 years
+ issuerRef: {
+ // Contract with cluster/lib/pki.libsonnet.
+ // Copied over.
+ name: "pki-ca",
+ kind: "ClusterIssuer",
+ },
+ commonName: cn,
+ },
+ },
+
+ kasownikCert: stopgap.mkClientCert("smsgw-tcp-rpc-consumer", "kasownik.external.hswaw.net"),
+ piorekfCert: stopgap.mkClientCert("smsgw-tcp-rpc-piorekf", "piorekf.person.hswaw.net"),
+ }
+ },
+}