diff --git a/devtools/hackdoc/prod.jsonnet b/devtools/hackdoc/prod.jsonnet new file mode 100644 index 00000000..adf38b06 --- /dev/null +++ b/devtools/hackdoc/prod.jsonnet @@ -0,0 +1,60 @@ +local kube = import "../../kube/hscloud.libsonnet"; +local hspki = import "../../kube/hspki.libsonnet"; + +{ + local top = self, + local cfg = self.cfg, + + cfg:: { + name: 'hackdoc', + namespace: 'hackdoc', + domain: 'hackdoc.hackerspace.pl', + depotviewUrl: 'depotview.devtools-prod.svc.cluster.local:4200', + image: 'registry.k0.hswaw.net/q3k/hackdoc:315532800-f4d02581f60b18a8635d026079ed67039cdc45e6', + }, + + local ns = kube.Namespace(cfg.namespace), + + deployment: ns.Contain(kube.Deployment(cfg.name)) { + spec+: { + replicas: 1, + template+: { + spec+: top.pki.PodSpec { + containers_: { + default: top.pki.GoContainer("default") { + image: cfg.image, + executable_: "/devtools/hackdoc", + command+: [ + "-depotview=%s" % [cfg.depotviewUrl], + "-hackdoc_url=https://%s" % [cfg.domain], + "-pub_listen=0.0.0.0:8080", + ], + resources: { + requests: { cpu: "25m", memory: "64Mi" }, + limits: { cpu: "500m", memory: "128Mi" }, + }, + ports_: { + http: { containerPort: 8080 }, + }, + }, + }, + }, + }, + }, + }, + + service: ns.Contain(kube.Service(cfg.name)) { + target:: top.deployment, + }, + + ingress: ns.Contain(kube.SimpleIngress(cfg.name)) { + hosts:: [cfg.domain], + target:: top.service, + }, + + pki: ns.Contain(hspki) { + cfg+: { + name: cfg.name, + } + }, +} diff --git a/devtools/kube/hackdoc.libsonnet b/devtools/kube/hackdoc.libsonnet deleted file mode 100644 index 4fd7ad6a..00000000 --- a/devtools/kube/hackdoc.libsonnet +++ /dev/null @@ -1,31 +0,0 @@ -local mirko = import "../../kube/mirko.libsonnet"; -local kube = import "../../kube/kube.libsonnet"; - -{ - cfg:: { - image: "registry.k0.hswaw.net/q3k/hackdoc:315532800-f4d02581f60b18a8635d026079ed67039cdc45e6", - publicFQDN: error "public FQDN must be set", - }, - - component(cfg ,env):: mirko.Component(env, "hackdoc") { - local hackdoc = self, - cfg+: { - image: cfg.image, - container: hackdoc.GoContainer("main", "/devtools/hackdoc") { - command+: [ - "-depotview=depotview.devtools-prod.svc.cluster.local:4200", - "-hackdoc_url=https://%s" % [cfg.publicFQDN], - "-pub_listen=0.0.0.0:8080", - ], - }, - ports+: { - publicHTTP: { - public: { - port: 8080, - dns: cfg.publicFQDN, - }, - }, - }, - }, - } -} diff --git a/devtools/kube/prod.jsonnet b/devtools/kube/prod.jsonnet index 3bdccd22..56710335 100644 --- a/devtools/kube/prod.jsonnet +++ b/devtools/kube/prod.jsonnet @@ -2,19 +2,15 @@ local mirko = import "../../kube/mirko.libsonnet"; local policies = import "../../kube/policies.libsonnet"; local depotview = import "depotview.libsonnet"; -local hackdoc = import "hackdoc.libsonnet"; local sourcegraph = import "sourcegraph.libsonnet"; { devtools(name):: mirko.Environment(name) { local env = self, local cfg = self.cfg, - + cfg+: { depotview: depotview.cfg, - hackdoc: hackdoc.cfg { - publicFQDN: "hackdoc.hackerspace.pl", - }, sourcegraph: sourcegraph.cfg { publicFQDN: "cs.hackerspace.pl", }, @@ -22,7 +18,6 @@ local sourcegraph = import "sourcegraph.libsonnet"; components: { depotview: depotview.component(cfg.depotview, env), - hackdoc: hackdoc.component(cfg.hackdoc, env), // This is configurated manually through the web interface, q3k has an account // and can create more administrative ones if needed. sourcegraph: sourcegraph.component(cfg.sourcegraph, env), diff --git a/kube/hspki.libsonnet b/kube/hspki.libsonnet new file mode 100644 index 00000000..d6e8d331 --- /dev/null +++ b/kube/hspki.libsonnet @@ -0,0 +1,76 @@ +local kube = import "kube.libsonnet"; + +// HSPKI support +// (This is meant to be a simpler abstraction than mirko.libsonnet) +// To connect certificate to a HSPKI/Mirko service, use PodSpec and Container() or GoContainer() +{ + local top = self, + local cfg = top.cfg, + + metadata:: { + namespace: error "namespace must be set", + }, + + cfg:: { + // name is used to generate certificate and secret names + // and should match name of the Service + name: error "name must be set", + namespace: top.metadata.namespace, + + certName: cfg.name + '-cert', + secretName: cfg.name + '-cert', + + realm: "hswaw.net", + clusterFQDN: "k0.hswaw.net", + }, + + local ns = kube.Namespace(cfg.namespace), + + cert: ns.Contain(kube.Certificate(cfg.certName)) { + spec: { + secretName: cfg.secretName, + duration: "35040h0m0s", // 4 years + issuerRef: { + // Contract with cluster/lib/pki.libsonnet. + name: "pki-ca", + kind: "ClusterIssuer", + }, + local name = cfg.name, + local namespace = cfg.namespace, + commonName: "%s.%s.svc.%s" % [name, namespace, cfg.clusterFQDN], + dnsNames: [ + "%s" % [name], + "%s.%s" % [name, namespace], + "%s.%s.svc" % [name, namespace], + "%s.%s.svc.cluster.local" % [name, namespace], + "%s.%s.svc.%s" % [name, namespace, cfg.clusterFQDN], + ], + }, + }, + + PodSpec:: kube.PodSpec { + volumes_+: { + hspki: { secret: { secretName: cfg.secretName } }, + }, + }, + + Container(name):: kube.Container(name) { + volumeMounts_+: { + hspki: { mountPath: "/mnt/pki" }, + }, + }, + + GoContainer(name):: top.Container(name) { + executable_:: error "executable_ must be set", + command: [ + self.executable_, + "-hspki_realm", cfg.realm, + "-hspki_cluster", cfg.clusterFQDN, + "-hspki_tls_ca_path", "/mnt/pki/ca.crt", + "-hspki_tls_certificate_path", "/mnt/pki/tls.crt", + "-hspki_tls_key_path", "/mnt/pki/tls.key", + // TODO: Remove this after go/hspki services are updated not to require it + "-logtostderr", + ], + } +}