diff --git a/cluster/kube/k0.libsonnet b/cluster/kube/k0.libsonnet index b5feb05f..8d7d49fa 100644 --- a/cluster/kube/k0.libsonnet +++ b/cluster/kube/k0.libsonnet @@ -346,6 +346,10 @@ local rook = import "lib/rook.libsonnet"; { namespace: "matrix", dns: "matrix.hackerspace.pl" }, { namespace: "onlyoffice-prod", dns: "office.hackerspace.pl" }, { namespace: "redmine", dns: "issues.hackerspace.pl" }, + { namespace: "redmine", dns: "b.hackerspace.pl" }, + { namespace: "redmine", dns: "b.hswaw.net" }, + { namespace: "redmine", dns: "xn--137h.hackerspace.pl" }, + { namespace: "redmine", dns: "xn--137h.hswaw.net" }, { namespace: "speedtest", dns: "speedtest.hackerspace.pl" }, { namespace: "sso", dns: "sso.hackerspace.pl" }, diff --git a/devtools/issues/b/BUILD.bazel b/devtools/issues/b/BUILD.bazel new file mode 100644 index 00000000..36933d8b --- /dev/null +++ b/devtools/issues/b/BUILD.bazel @@ -0,0 +1,42 @@ +load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_layer", "container_push") +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go_default_library", + srcs = ["main.go"], + importpath = "code.hackerspace.pl/hscloud/devtools/issues/b", + visibility = ["//visibility:private"], + deps = ["@com_github_golang_glog//:go_default_library"], +) + +go_binary( + name = "b", + embed = [":go_default_library"], + visibility = ["//visibility:public"], +) + +container_layer( + name = "layer_bin", + files = [ + ":b", + ], + directory = "/devtools/issues/", +) + +container_image( + name = "runtime", + base = "@prodimage-bionic//image", + layers = [ + ":layer_bin", + ], +) + +container_push( + name = "push", + image = ":runtime", + format = "Docker", + registry = "registry.k0.hswaw.net", + repository = "q3k/b", + tag = "{BUILD_TIMESTAMP}-{STABLE_GIT_COMMIT}", +) + diff --git a/devtools/issues/b/main.go b/devtools/issues/b/main.go new file mode 100644 index 00000000..8ef81506 --- /dev/null +++ b/devtools/issues/b/main.go @@ -0,0 +1,63 @@ +// A minimal redirector for b/123 style links to redmine. + +package main + +import ( + "fmt" + "regexp" + + "github.com/golang/glog" + + "flag" + "net/http" +) + +func init() { + flag.Set("logtostderr", "true") +} + +var ( + flagListen string + flagTarget string + flagProject string + + reIssue = regexp.MustCompile(`^/([0-9]+)$`) +) + +func main() { + flag.StringVar(&flagListen, "b_listen", "0.0.0.0:8000", "Address to listen at") + flag.StringVar(&flagTarget, "b_target", "issues.hackerspace.pl", "Redmine instance address") + flag.StringVar(&flagProject, "b_project", "hswaw", "Redmine project name") + flag.Parse() + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + scheme := r.URL.Scheme + if scheme == "" { + scheme = "https" + } + if r.URL.Path == "/" { + http.Redirect(w, r, fmt.Sprintf("%s://%s/my/page", scheme, flagTarget), 302) + return + } + if r.URL.Path == "/new" { + http.Redirect(w, r, fmt.Sprintf("%s://%s/projects/%s/issues/new", scheme, flagTarget, flagProject), 302) + return + } + if matches := reIssue.FindStringSubmatch(r.URL.Path); len(matches) == 2 { + num := matches[1] + http.Redirect(w, r, fmt.Sprintf("%s://%s/issues/%s", scheme, flagTarget, num), 302) + return + } + + fmt.Fprintf(w, ` + 🅱️ +
+ `) + }) + + glog.Infof("Listening on %q...", flagListen) + err := http.ListenAndServe(flagListen, nil) + if err != nil { + glog.Exit(err) + } +} diff --git a/devtools/issues/prod.jsonnet b/devtools/issues/prod.jsonnet index 2218716e..14dbbba0 100644 --- a/devtools/issues/prod.jsonnet +++ b/devtools/issues/prod.jsonnet @@ -18,6 +18,15 @@ local redmine = import "./redmine.libsonnet"; namespace: "redmine", domain: "issues.hackerspace.pl", + b: { + domains: [ + "b.hackerspace.pl", + "b.hswaw.net", + "xn--137h.hswaw.net", + "xn--137h.hackerspace.pl", + ], + }, + storage+: { endpoint: "https://object.ceph-waw3.hswaw.net", bucket: "issues", diff --git a/devtools/issues/redmine.libsonnet b/devtools/issues/redmine.libsonnet index 420e488c..9c1ed6a0 100644 --- a/devtools/issues/redmine.libsonnet +++ b/devtools/issues/redmine.libsonnet @@ -18,6 +18,11 @@ local postgres = import "../../kube/postgres.libsonnet"; port: 5432, }, + b: { + domains: [], + image: "registry.k0.hswaw.net/q3k/b:315532800-6cc2f867951e123909b23955cd7bcbcc3ec24f8a", + }, + storage: { endpoint: error "storage.endpoint must be set", region: error "storage.region must be set", @@ -120,4 +125,59 @@ local postgres = import "../../kube/postgres.libsonnet"; ], }, }, + + b: (if std.length(cfg.b.domains) > 0 then { + deployment: app.ns.Contain(kube.Deployment("b")) { + spec+: { + replicas: 3, + template+: { + spec+: { + containers_: { + default: kube.Container("default") { + image: "registry.k0.hswaw.net/q3k/b:315532800-6cc2f867951e123909b23955cd7bcbcc3ec24f8a", + ports_: { + http: { containerPort: 8000 }, + }, + command: [ + "/devtools/issues/b", + ], + }, + }, + }, + }, + }, + }, + svc: app.ns.Contain(kube.Service("b")) { + target_pod:: app.b.deployment.spec.template, + }, + ingress: app.ns.Contain(kube.Ingress("b")) { + metadata+: { + annotations+: { + "kubernetes.io/tls-acme": "true", + "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod", + "nginx.ingress.kubernetes.io/proxy-body-size": "0", + }, + }, + spec+: { + tls: [ + { + hosts: cfg.b.domains, + secretName: "b-tls", + }, + ], + rules: [ + { + host: domain, + http: { + paths: [ + { path: "/", backend: app.b.svc.name_port }, + ] + }, + } + for domain in cfg.b.domains + ], + }, + } + } else {}), + }