personal/q3k/minecraft: add and deploy bridge

Change-Id: Ie191690414840668f31f3de4cdf809b35c610248
diff --git a/personal/q3k/minecraft/plugin/hscloud/BUILD b/personal/q3k/minecraft/plugin/hscloud/BUILD
index 418c5c5..d53644b 100644
--- a/personal/q3k/minecraft/plugin/hscloud/BUILD
+++ b/personal/q3k/minecraft/plugin/hscloud/BUILD
@@ -1,4 +1,5 @@
 load("//personal/q3k/minecraft/plugin:defs.bzl", "bukkit_plugin")
+
 bukkit_plugin(
     name = "hscloud",
     main = "hscloud.personal.q3k.minecraft.plugin.hscloud.Main",
diff --git a/personal/q3k/minecraft/plugin/hscloud/bridge/BUILD.bazel b/personal/q3k/minecraft/plugin/hscloud/bridge/BUILD.bazel
new file mode 100644
index 0000000..eb05303
--- /dev/null
+++ b/personal/q3k/minecraft/plugin/hscloud/bridge/BUILD.bazel
@@ -0,0 +1,37 @@
+load("@io_bazel_rules_docker//container:container.bzl", "container_image")
+load("@io_bazel_rules_docker//container:container.bzl", "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/personal/q3k/minecraft/plugin/hscloud/bridge",
+    visibility = ["//visibility:private"],
+    deps = [
+        "//personal/q3k/minecraft/plugin/hscloud/proto:go_default_library",
+        "@org_golang_google_grpc//:go_default_library",
+    ],
+)
+
+go_binary(
+    name = "bridge",
+    embed = [":go_default_library"],
+    visibility = ["//visibility:public"],
+)
+
+container_image(
+    name = "bridge_container",
+    base = "@prodimage-bionic//image",
+    files = [":bridge"],
+    directory = "/personal/q3k/minecraft/plugin/hscloud/bridge",
+    entrypoint = "/personal/q3k/minecraft/plugin/hscloud/bridge/bridge",
+)
+
+container_push(
+    name = "bridge_container_push",
+    image = ":bridge_container",
+    format = "Docker",
+    registry = "registry.k0.hswaw.net",
+    repository = "q3k/minecraft-hscloud-bridge",
+    tag = "20200518c",
+)
diff --git a/personal/q3k/minecraft/plugin/hscloud/bridge/main.go b/personal/q3k/minecraft/plugin/hscloud/bridge/main.go
new file mode 100644
index 0000000..f8863be
--- /dev/null
+++ b/personal/q3k/minecraft/plugin/hscloud/bridge/main.go
@@ -0,0 +1,48 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"net/http"
+
+	"google.golang.org/grpc"
+
+	pb "code.hackerspace.pl/hscloud/personal/q3k/minecraft/plugin/hscloud/proto"
+)
+
+var (
+	flagPlugin string
+	flagListen string
+)
+
+func main() {
+	flag.StringVar(&flagPlugin, "plugin", "minecraft.wypierdolzpolski.pl:2137", "address of gRPC plugin")
+	flag.StringVar(&flagListen, "listen", "0.0.0.0:8081", "address to listen at")
+	flag.Parse()
+
+	conn, err := grpc.Dial(flagPlugin, grpc.WithInsecure())
+	if err != nil {
+		log.Fatalf("Dial(%q): %v", flagPlugin, err)
+	}
+
+	client := pb.NewIntrospectorClient(conn)
+
+	http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) {
+		res, err := client.Status(r.Context(), &pb.StatusRequest{})
+		if err != nil {
+			http.Error(w, "internal server error", 500)
+			log.Printf("Status error: %v", err)
+		}
+
+		fmt.Fprintf(w, "# HELP minecraft_players_online Total number of players online.\n")
+		fmt.Fprintf(w, "# TYPE minecraft_players_online gauge\n")
+		fmt.Fprintf(w, "minecraft_players_online %d\n", len(res.Players))
+	})
+
+	log.Printf("Listening on %s", flagListen)
+	err = http.ListenAndServe(flagListen, nil)
+	if err != nil {
+		log.Fatalf("ListenAndServe: %v", err)
+	}
+}
diff --git a/personal/q3k/minecraft/plugin/hscloud/proto/BUILD b/personal/q3k/minecraft/plugin/hscloud/proto/BUILD
index 139d994..903e472 100644
--- a/personal/q3k/minecraft/plugin/hscloud/proto/BUILD
+++ b/personal/q3k/minecraft/plugin/hscloud/proto/BUILD
@@ -1,11 +1,8 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
 load("@rules_proto//proto:defs.bzl", "proto_library")
 load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")
 
-proto_library(
-    name = "hscloud_proto",
-    srcs = ["hscloud.proto"],
-)
-
 java_proto_library(
     name = "hscloud_java_proto",
     deps = [":hscloud_proto"],
@@ -18,3 +15,24 @@
     deps = [":hscloud_java_proto"],
     visibility = ["//visibility:public"],
 )
+
+proto_library(
+    name = "hscloud_proto",
+    srcs = ["hscloud.proto"],
+    visibility = ["//visibility:public"],
+)
+
+go_proto_library(
+    name = "hscloud_go_proto",
+    compilers = ["@io_bazel_rules_go//proto:go_grpc"],
+    importpath = "code.hackerspace.pl/hscloud/personal/q3k/minecraft/plugin/hscloud/proto",
+    proto = ":hscloud_proto",
+    visibility = ["//visibility:public"],
+)
+
+go_library(
+    name = "go_default_library",
+    embed = [":hscloud_go_proto"],
+    importpath = "code.hackerspace.pl/hscloud/personal/q3k/minecraft/plugin/hscloud/proto",
+    visibility = ["//visibility:public"],
+)
diff --git a/personal/q3k/minecraft/plugin/hscloud/proto/hscloud.proto b/personal/q3k/minecraft/plugin/hscloud/proto/hscloud.proto
index 05b8da7..a578e23 100644
--- a/personal/q3k/minecraft/plugin/hscloud/proto/hscloud.proto
+++ b/personal/q3k/minecraft/plugin/hscloud/proto/hscloud.proto
@@ -2,6 +2,7 @@
 package hscloud.personal.q3k.minecraft.plugin.hscloud;
 option java_package = "hscloud.personal.q3k.minecraft.plugin.hscloud.proto";
 option java_outer_classname = "Proto";
+option go_package = "hscloud";
 
 service Introspector {
     rpc Status(StatusRequest) returns (StatusResponse);
diff --git a/personal/q3k/minecraft/prod.jsonnet b/personal/q3k/minecraft/prod.jsonnet
index 491a28a..eef3b35 100644
--- a/personal/q3k/minecraft/prod.jsonnet
+++ b/personal/q3k/minecraft/prod.jsonnet
@@ -166,6 +166,16 @@
                                     web: { containerPort: 8080 },
                                 },
                             },
+                            bridge: kube.Container("bridge") {
+                                image: "registry.k0.hswaw.net/q3k/minecraft-hscloud-bridge:20200518c",
+                                command: [
+                                    "/personal/q3k/minecraft/plugin/hscloud/bridge/bridge",
+                                    "-plugin", "127.0.0.1:2137",
+                                ],
+                                ports_: {
+                                    bridge: { containerPort: 8081 },
+                                },
+                            },
                         },
                     },
                 },
@@ -179,6 +189,7 @@
                 ports: [
                     { name: "minecraft", port: 25565, targetPort: 25565, protocol: "TCP" },
                     { name: "web", port: 80, targetPort: 8080, protocol: "TCP" },
+                    { name: "bridge", port: 8080, targetPort: 8081, protocol: "TCP" },
                     { name: "grpc", port: 2137, targetPort: 2137, protocol: "TCP" },
                 ],
                 type: "LoadBalancer",