Merge "Fix the shebang."
diff --git a/app/gerrit/kube/gerrit.libsonnet b/app/gerrit/kube/gerrit.libsonnet
index 2cd6f59..d78f8f4 100644
--- a/app/gerrit/kube/gerrit.libsonnet
+++ b/app/gerrit/kube/gerrit.libsonnet
@@ -72,6 +72,9 @@
                     canonicalWebUrl = https://%(domain)s/
                     serverId = %(identity)s
 
+                [sshd]
+                    advertisedAddress  = %(domain)s
+
                 [container]
                     javaOptions = -Djava.security.edg=file:/dev/./urandom
 
diff --git a/go/svc/invoice/BUILD.bazel b/bgpwtf/invoice/BUILD.bazel
similarity index 83%
rename from go/svc/invoice/BUILD.bazel
rename to bgpwtf/invoice/BUILD.bazel
index 05fcd23..c85bb4d 100644
--- a/go/svc/invoice/BUILD.bazel
+++ b/bgpwtf/invoice/BUILD.bazel
@@ -9,13 +9,13 @@
         "render.go",
         "statusz.go",
     ],
-    importpath = "code.hackerspace.pl/hscloud/go/svc/invoice",
+    importpath = "code.hackerspace.pl/hscloud/bgpwtf/invoice",
     visibility = ["//visibility:private"],
     deps = [
+        "//bgpwtf/invoice/proto:go_default_library",
+        "//bgpwtf/invoice/templates:go_default_library",
         "//go/mirko:go_default_library",
         "//go/statusz:go_default_library",
-        "//go/svc/invoice/templates:go_default_library",
-        "//proto/invoice:go_default_library",
         "@com_github_golang_glog//:go_default_library",
         "@com_github_golang_protobuf//proto:go_default_library",
         "@com_github_mattn_go_sqlite3//:go_default_library",
diff --git a/go/svc/invoice/calc.go b/bgpwtf/invoice/calc.go
similarity index 90%
rename from go/svc/invoice/calc.go
rename to bgpwtf/invoice/calc.go
index 5df763f..9c411da 100644
--- a/go/svc/invoice/calc.go
+++ b/bgpwtf/invoice/calc.go
@@ -3,7 +3,7 @@
 import (
 	"time"
 
-	pb "code.hackerspace.pl/hscloud/proto/invoice"
+	pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto"
 )
 
 func calculateInvoiceData(p *pb.Invoice) {
diff --git a/go/svc/invoice/main.go b/bgpwtf/invoice/main.go
similarity index 98%
rename from go/svc/invoice/main.go
rename to bgpwtf/invoice/main.go
index 4a80441..d93034c 100644
--- a/go/svc/invoice/main.go
+++ b/bgpwtf/invoice/main.go
@@ -8,8 +8,8 @@
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 
+	pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto"
 	"code.hackerspace.pl/hscloud/go/mirko"
-	pb "code.hackerspace.pl/hscloud/proto/invoice"
 )
 
 var (
diff --git a/go/svc/invoice/model.go b/bgpwtf/invoice/model.go
similarity index 98%
rename from go/svc/invoice/model.go
rename to bgpwtf/invoice/model.go
index d628e1a..1fb89b9 100644
--- a/go/svc/invoice/model.go
+++ b/bgpwtf/invoice/model.go
@@ -13,7 +13,7 @@
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 
-	pb "code.hackerspace.pl/hscloud/proto/invoice"
+	pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto"
 )
 
 type model struct {
diff --git a/proto/invoice/BUILD.bazel b/bgpwtf/invoice/proto/BUILD.bazel
similarity index 61%
rename from proto/invoice/BUILD.bazel
rename to bgpwtf/invoice/proto/BUILD.bazel
index 0108f44..51f85fe 100644
--- a/proto/invoice/BUILD.bazel
+++ b/bgpwtf/invoice/proto/BUILD.bazel
@@ -2,22 +2,22 @@
 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
 
 proto_library(
-    name = "invoice_proto",
+    name = "proto_proto",
     srcs = ["invoice.proto"],
     visibility = ["//visibility:public"],
 )
 
 go_proto_library(
-    name = "invoice_go_proto",
+    name = "proto_go_proto",
     compilers = ["@io_bazel_rules_go//proto:go_grpc"],
-    importpath = "code.hackerspace.pl/hscloud/proto/invoice",
-    proto = ":invoice_proto",
+    importpath = "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto",
+    proto = ":proto_proto",
     visibility = ["//visibility:public"],
 )
 
 go_library(
     name = "go_default_library",
-    embed = [":invoice_go_proto"],
-    importpath = "code.hackerspace.pl/hscloud/proto/invoice",
+    embed = [":proto_go_proto"],
+    importpath = "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto",
     visibility = ["//visibility:public"],
 )
diff --git a/proto/invoice/invoice.proto b/bgpwtf/invoice/proto/invoice.proto
similarity index 96%
rename from proto/invoice/invoice.proto
rename to bgpwtf/invoice/proto/invoice.proto
index a5c6a84..75720b7 100644
--- a/proto/invoice/invoice.proto
+++ b/bgpwtf/invoice/proto/invoice.proto
@@ -1,6 +1,6 @@
 syntax = "proto3";
-
 package invoice;
+option go_package = "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto";
 
 message Item {
     string title = 1;
diff --git a/go/svc/invoice/render.go b/bgpwtf/invoice/render.go
similarity index 96%
rename from go/svc/invoice/render.go
rename to bgpwtf/invoice/render.go
index 03dcd77..693aa62 100644
--- a/go/svc/invoice/render.go
+++ b/bgpwtf/invoice/render.go
@@ -8,8 +8,8 @@
 
 	wkhtml "github.com/sebastiaanklippert/go-wkhtmltopdf"
 
-	"code.hackerspace.pl/hscloud/go/svc/invoice/templates"
-	pb "code.hackerspace.pl/hscloud/proto/invoice"
+	pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto"
+	"code.hackerspace.pl/hscloud/bgpwtf/invoice/templates"
 )
 
 var (
diff --git a/go/svc/invoice/statusz.go b/bgpwtf/invoice/statusz.go
similarity index 97%
rename from go/svc/invoice/statusz.go
rename to bgpwtf/invoice/statusz.go
index 0a64ce4..9490660 100644
--- a/go/svc/invoice/statusz.go
+++ b/bgpwtf/invoice/statusz.go
@@ -7,9 +7,9 @@
 	"sort"
 	"time"
 
+	pb "code.hackerspace.pl/hscloud/bgpwtf/invoice/proto"
 	"code.hackerspace.pl/hscloud/go/mirko"
 	"code.hackerspace.pl/hscloud/go/statusz"
-	pb "code.hackerspace.pl/hscloud/proto/invoice"
 	"github.com/golang/glog"
 )
 
diff --git a/go/svc/invoice/templates/BUILD.bazel b/bgpwtf/invoice/templates/BUILD.bazel
similarity index 74%
rename from go/svc/invoice/templates/BUILD.bazel
rename to bgpwtf/invoice/templates/BUILD.bazel
index 7874687..4756da4 100644
--- a/go/svc/invoice/templates/BUILD.bazel
+++ b/bgpwtf/invoice/templates/BUILD.bazel
@@ -13,6 +13,6 @@
     srcs = [
         ":templates_bindata",  # keep
     ],
-    importpath = "code.hackerspace.pl/hscloud/go/svc/invoice/templates",  # keep
-    visibility = ["//go/svc/invoice:__subpackages__"],
+    importpath = "code.hackerspace.pl/hscloud/bgpwtf/invoice/templates",  # keep
+    visibility = ["//bgpwtf/invoice:__subpackages__"],
 )
diff --git a/go/svc/invoice/templates/invoice_en.html b/bgpwtf/invoice/templates/invoice_en.html
similarity index 100%
rename from go/svc/invoice/templates/invoice_en.html
rename to bgpwtf/invoice/templates/invoice_en.html
diff --git a/go/svc/invoice/templates/invoice_pl.html b/bgpwtf/invoice/templates/invoice_pl.html
similarity index 100%
rename from go/svc/invoice/templates/invoice_pl.html
rename to bgpwtf/invoice/templates/invoice_pl.html
diff --git a/go/svc/speedtest/.gitignore b/bgpwtf/speedtest/.gitignore
similarity index 100%
rename from go/svc/speedtest/.gitignore
rename to bgpwtf/speedtest/.gitignore
diff --git a/go/svc/speedtest/BUILD b/bgpwtf/speedtest/BUILD.bazel
similarity index 79%
rename from go/svc/speedtest/BUILD
rename to bgpwtf/speedtest/BUILD.bazel
index 3425af9..cc431d0 100644
--- a/go/svc/speedtest/BUILD
+++ b/bgpwtf/speedtest/BUILD.bazel
@@ -12,14 +12,14 @@
 go_library(
     name = "static_go",
     srcs = [":static"],
-    importpath = "code.hackerspace.pl/hscloud/go/svc/speedtest/static",
+    importpath = "code.hackerspace.pl/hscloud/bgpwtf/speedtest/static",
     visibility = ["//visibility:public"],
 )
 
 container_image(
     name="latest",
     base="@prodimage-bionic//image",
-    files = ["//go/svc/speedtest/backend:backend"],
+    files = ["//bgpwtf/speedtest/backend:backend"],
     directory = "/hscloud",
     entrypoint = ["/hscloud/backend"],
 )
@@ -30,9 +30,9 @@
     outs = ["version.sh"],
     executable = True,
     cmd = """
-        local=bazel/go/svc/speedtest:latest
+        local=bazel/bgpwtf/speedtest:latest
         tag=$$(date +%s)
-        remote=registry.k0.hswaw.net/go/svc/speedtest:$$tag
+        remote=registry.k0.hswaw.net/bgpwtf/speedtest:$$tag
 
         docker tag $$local $$remote
         docker push $$remote
diff --git a/go/svc/speedtest/LICENSE b/bgpwtf/speedtest/LICENSE
similarity index 100%
rename from go/svc/speedtest/LICENSE
rename to bgpwtf/speedtest/LICENSE
diff --git a/go/svc/speedtest/README.md b/bgpwtf/speedtest/README.md
similarity index 100%
rename from go/svc/speedtest/README.md
rename to bgpwtf/speedtest/README.md
diff --git a/go/svc/speedtest/backend/BUILD.bazel b/bgpwtf/speedtest/backend/BUILD.bazel
similarity index 81%
rename from go/svc/speedtest/backend/BUILD.bazel
rename to bgpwtf/speedtest/backend/BUILD.bazel
index 28ecc88..54ea2f6 100644
--- a/go/svc/speedtest/backend/BUILD.bazel
+++ b/bgpwtf/speedtest/backend/BUILD.bazel
@@ -3,11 +3,11 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "code.hackerspace.pl/hscloud/go/svc/speedtest/backend",
+    importpath = "code.hackerspace.pl/hscloud/bgpwtf/speedtest/backend",
     visibility = ["//visibility:private"],
     deps = [
         "@com_github_golang_glog//:go_default_library",
-        "//go/svc/speedtest:static_go", # keep
+        "//bgpwtf/speedtest:static_go", # keep
     ],
 )
 
diff --git a/go/svc/speedtest/backend/main.go b/bgpwtf/speedtest/backend/main.go
similarity index 94%
rename from go/svc/speedtest/backend/main.go
rename to bgpwtf/speedtest/backend/main.go
index 80c1c8c..7d4aece 100644
--- a/go/svc/speedtest/backend/main.go
+++ b/bgpwtf/speedtest/backend/main.go
@@ -27,7 +27,7 @@
 
 	"github.com/golang/glog"
 
-	"code.hackerspace.pl/hscloud/go/svc/speedtest/static"
+	"code.hackerspace.pl/hscloud/bgpwtf/speedtest/static"
 )
 
 var (
@@ -131,13 +131,13 @@
 		json.NewEncoder(w).Encode(res)
 	})
 	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
-		w.Write(static.Data["go/svc/speedtest/index.html"])
+		w.Write(static.Data["bgpwtf/speedtest/index.html"])
 	})
 	http.HandleFunc("/speedtest.js", func(w http.ResponseWriter, r *http.Request) {
-		w.Write(static.Data["go/svc/speedtest/speedtest.js"])
+		w.Write(static.Data["bgpwtf/speedtest/speedtest.js"])
 	})
 	http.HandleFunc("/speedtest_worker.js", func(w http.ResponseWriter, r *http.Request) {
-		w.Write(static.Data["go/svc/speedtest/speedtest_worker.js"])
+		w.Write(static.Data["bgpwtf/speedtest/speedtest_worker.js"])
 	})
 
 	glog.Infof("Starting up at %v", flagBind)
diff --git a/go/svc/speedtest/backend/main_test.go b/bgpwtf/speedtest/backend/main_test.go
similarity index 100%
rename from go/svc/speedtest/backend/main_test.go
rename to bgpwtf/speedtest/backend/main_test.go
diff --git a/go/svc/speedtest/index.html b/bgpwtf/speedtest/index.html
similarity index 100%
rename from go/svc/speedtest/index.html
rename to bgpwtf/speedtest/index.html
diff --git a/go/svc/speedtest/kube/prod.jsonnet b/bgpwtf/speedtest/kube/prod.jsonnet
similarity index 97%
rename from go/svc/speedtest/kube/prod.jsonnet
rename to bgpwtf/speedtest/kube/prod.jsonnet
index e53fd45..fc6e083 100644
--- a/go/svc/speedtest/kube/prod.jsonnet
+++ b/bgpwtf/speedtest/kube/prod.jsonnet
@@ -9,7 +9,7 @@
         domain: "speedtest.hackerspace.pl",
 
         tag: "1563032542",
-        image: "registry.k0.hswaw.net/go/svc/speedtest:" + cfg.tag,
+        image: "registry.k0.hswaw.net/bgpwtf/speedtest:" + cfg.tag,
 
         resources: {
             requests: {
diff --git a/go/svc/speedtest/speedtest.js b/bgpwtf/speedtest/speedtest.js
similarity index 100%
rename from go/svc/speedtest/speedtest.js
rename to bgpwtf/speedtest/speedtest.js
diff --git a/go/svc/speedtest/speedtest_worker.js b/bgpwtf/speedtest/speedtest_worker.js
similarity index 100%
rename from go/svc/speedtest/speedtest_worker.js
rename to bgpwtf/speedtest/speedtest_worker.js
diff --git a/cluster/clustercfg/clustercfg.py b/cluster/clustercfg/clustercfg.py
index 41614c7..24fa745 100644
--- a/cluster/clustercfg/clustercfg.py
+++ b/cluster/clustercfg/clustercfg.py
@@ -44,7 +44,7 @@
 def pki_config(key):
     raw = subprocess.check_output([
         'nix', 'eval', '--raw',
-        '( (import ' + local_root + '/nix/toplevel.nix ).pki.' + key + '.json )',
+        '( (import ' + local_root + '/cluster/nix/toplevel.nix ).pki.' + key + '.json )',
     ])
     return json.loads(raw)
 
@@ -203,7 +203,7 @@
 
     # Upload NixOS config
     for f in ['toplevel', 'cluster-configuration']:
-        r.put(local=os.path.join(local_root, 'nix/{}.nix'.format(f)),
+        r.put(local=os.path.join(local_root, 'cluster/nix/{}.nix'.format(f)),
               remote='/etc/nixos/{}.nix'.format(f))
 
     r.run('nixos-rebuild switch')
@@ -228,8 +228,10 @@
     elif mode == "config":
         print('etcd peer:')
         print(json.dumps(pki_config('etcdPeer'), indent=2))
-        print('etcd client:')
-        print(json.dumps(pki_config('etcdClient'), indent=2))
+        print('etcd server:')
+        print(json.dumps(pki_config('etcd.server'), indent=2))
+        print('etcd client (kube):')
+        print(json.dumps(pki_config('etcd.kube'), indent=2))
     else:
         usage()
         return 1
diff --git a/nix/cluster-configuration.nix b/cluster/nix/cluster-configuration.nix
similarity index 100%
rename from nix/cluster-configuration.nix
rename to cluster/nix/cluster-configuration.nix
diff --git a/nix/configuration.sample.nix b/cluster/nix/configuration.sample.nix
similarity index 100%
rename from nix/configuration.sample.nix
rename to cluster/nix/configuration.sample.nix
diff --git a/nix/toplevel.nix b/cluster/nix/toplevel.nix
similarity index 100%
rename from nix/toplevel.nix
rename to cluster/nix/toplevel.nix
diff --git a/dc/m6220-proxy/BUILD.bazel b/dc/m6220-proxy/BUILD.bazel
index 50fa692..1d737b5 100644
--- a/dc/m6220-proxy/BUILD.bazel
+++ b/dc/m6220-proxy/BUILD.bazel
@@ -10,8 +10,8 @@
     visibility = ["//visibility:private"],
     deps = [
         "//dc/m6220-proxy/proto:go_default_library",
+        "//dc/proto:go_default_library",
         "//go/mirko:go_default_library",
-        "//proto/infra:go_default_library",
         "@com_github_golang_glog//:go_default_library",
         "@com_github_ziutek_telnet//:go_default_library",
         "@org_golang_google_grpc//codes:go_default_library",
diff --git a/dc/m6220-proxy/main.go b/dc/m6220-proxy/main.go
index 6fd972d..f4c348b 100644
--- a/dc/m6220-proxy/main.go
+++ b/dc/m6220-proxy/main.go
@@ -15,7 +15,7 @@
 	"google.golang.org/grpc/status"
 
 	pb "code.hackerspace.pl/hscloud/dc/m6220-proxy/proto"
-	ipb "code.hackerspace.pl/hscloud/proto/infra"
+	dpb "code.hackerspace.pl/hscloud/dc/proto"
 )
 
 var (
@@ -70,7 +70,7 @@
 	return res, nil
 }
 
-func (s *service) parseInterfaceStatus(res *ipb.GetPortsResponse, lines []string) error {
+func (s *service) parseInterfaceStatus(res *dpb.GetPortsResponse, lines []string) error {
 	if len(lines) < 4 {
 		return fmt.Errorf("need at least 4 lines of output, got %d", len(lines))
 	}
@@ -104,20 +104,20 @@
 		speedStr := parts[len(parts)-4]
 		stateStr := parts[len(parts)-2]
 
-		port := &ipb.SwitchPort{
+		port := &dpb.SwitchPort{
 			Name: portName,
 		}
 		if speedStr == "100" {
-			port.Speed = ipb.SwitchPort_SPEED_100M
+			port.Speed = dpb.SwitchPort_SPEED_100M
 		} else if speedStr == "1000" {
-			port.Speed = ipb.SwitchPort_SPEED_1G
+			port.Speed = dpb.SwitchPort_SPEED_1G
 		} else if speedStr == "10000" {
-			port.Speed = ipb.SwitchPort_SPEED_10G
+			port.Speed = dpb.SwitchPort_SPEED_10G
 		}
 		if stateStr == "Up" {
-			port.LinkState = ipb.SwitchPort_LINKSTATE_UP
+			port.LinkState = dpb.SwitchPort_LINKSTATE_UP
 		} else if stateStr == "Down" {
-			port.LinkState = ipb.SwitchPort_LINKSTATE_DOWN
+			port.LinkState = dpb.SwitchPort_LINKSTATE_DOWN
 		}
 
 		res.Ports = append(res.Ports, port)
@@ -126,7 +126,7 @@
 	return nil
 }
 
-func (s *service) parseInterfaceConfig(port *ipb.SwitchPort, lines []string) error {
+func (s *service) parseInterfaceConfig(port *dpb.SwitchPort, lines []string) error {
 	glog.Infof("%+v", port)
 	for _, line := range lines {
 		glog.Infof("%s: %q", port.Name, line)
@@ -137,23 +137,23 @@
 
 		if len(parts) >= 2 && parts[0] == "switchport" {
 			if parts[1] == "mode" {
-				if port.PortMode != ipb.SwitchPort_PORTMODE_INVALID {
+				if port.PortMode != dpb.SwitchPort_PORTMODE_INVALID {
 					return fmt.Errorf("redefinition of switchport mode")
 				}
 				if parts[2] == "access" {
-					port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
+					port.PortMode = dpb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
 				} else if parts[2] == "trunk" {
-					port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED
+					port.PortMode = dpb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED
 				} else if parts[2] == "general" {
-					port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC
+					port.PortMode = dpb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC
 				} else {
-					port.PortMode = ipb.SwitchPort_PORTMODE_MANGLED
+					port.PortMode = dpb.SwitchPort_PORTMODE_MANGLED
 				}
 			}
 
 			if parts[1] == "access" {
-				if port.PortMode == ipb.SwitchPort_PORTMODE_INVALID {
-					port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
+				if port.PortMode == dpb.SwitchPort_PORTMODE_INVALID {
+					port.PortMode = dpb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
 				}
 				if len(parts) > 3 && parts[2] == "vlan" {
 					vlan, err := strconv.Atoi(parts[3])
@@ -183,34 +183,34 @@
 			}
 			port.Mtu = int32(mtu)
 		} else if len(parts) >= 2 && parts[0] == "spanning-tree" && parts[1] == "portfast" {
-			port.SpanningTreeMode = ipb.SwitchPort_SPANNING_TREE_MODE_PORTFAST
+			port.SpanningTreeMode = dpb.SwitchPort_SPANNING_TREE_MODE_PORTFAST
 		}
 	}
 
 	// no mode -> access
-	if port.PortMode == ipb.SwitchPort_PORTMODE_INVALID {
-		port.PortMode = ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
+	if port.PortMode == dpb.SwitchPort_PORTMODE_INVALID {
+		port.PortMode = dpb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED
 	}
 
 	// apply defaults
 	if port.Mtu == 0 {
 		port.Mtu = 1500
 	}
-	if port.SpanningTreeMode == ipb.SwitchPort_SPANNING_TREE_MODE_INVALID {
-		port.SpanningTreeMode = ipb.SwitchPort_SPANNING_TREE_MODE_AUTO_PORTFAST
+	if port.SpanningTreeMode == dpb.SwitchPort_SPANNING_TREE_MODE_INVALID {
+		port.SpanningTreeMode = dpb.SwitchPort_SPANNING_TREE_MODE_AUTO_PORTFAST
 	}
 
 	// sanitize
-	if port.PortMode == ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED {
+	if port.PortMode == dpb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED {
 		port.VlanTagged = []int32{}
 		port.Prefixes = []string{}
 		if port.VlanNative == 0 {
 			port.VlanNative = 1
 		}
-	} else if port.PortMode == ipb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED {
+	} else if port.PortMode == dpb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED {
 		port.VlanNative = 0
 		port.Prefixes = []string{}
-	} else if port.PortMode == ipb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC {
+	} else if port.PortMode == dpb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC {
 		port.Prefixes = []string{}
 		if port.VlanNative == 0 {
 			port.VlanNative = 1
@@ -219,13 +219,13 @@
 	return nil
 }
 
-func (s *service) GetPorts(ctx context.Context, req *ipb.GetPortsRequest) (*ipb.GetPortsResponse, error) {
+func (s *service) GetPorts(ctx context.Context, req *dpb.GetPortsRequest) (*dpb.GetPortsResponse, error) {
 	cli, err := s.connect()
 	if err != nil {
 		return nil, status.Error(codes.Unavailable, "could not connect to switch")
 	}
 	defer s.disconnect()
-	res := &ipb.GetPortsResponse{}
+	res := &dpb.GetPortsResponse{}
 
 	statusLines, _, err := cli.runCommand(ctx, "show interface status")
 	if err != nil {
@@ -267,7 +267,7 @@
 	}
 
 	pb.RegisterM6220ProxyServer(m.GRPC(), s)
-	ipb.RegisterSwitchControlServer(m.GRPC(), s)
+	dpb.RegisterSwitchControlServer(m.GRPC(), s)
 
 	if err := m.Serve(); err != nil {
 		glog.Exitf("Serve(): %v", err)
diff --git a/dc/proto/BUILD.bazel b/dc/proto/BUILD.bazel
new file mode 100644
index 0000000..cfee72e
--- /dev/null
+++ b/dc/proto/BUILD.bazel
@@ -0,0 +1,23 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+proto_library(
+    name = "proto_proto",
+    srcs = ["dc.proto"],
+    visibility = ["//visibility:public"],
+)
+
+go_proto_library(
+    name = "proto_go_proto",
+    compilers = ["@io_bazel_rules_go//proto:go_grpc"],
+    importpath = "code.hackerspace.pl/hscloud/dc/proto",
+    proto = ":proto_proto",
+    visibility = ["//visibility:public"],
+)
+
+go_library(
+    name = "go_default_library",
+    embed = [":proto_go_proto"],
+    importpath = "code.hackerspace.pl/hscloud/dc/proto",
+    visibility = ["//visibility:public"],
+)
diff --git a/proto/infra/control.proto b/dc/proto/dc.proto
similarity index 95%
rename from proto/infra/control.proto
rename to dc/proto/dc.proto
index 3377f51..2b242ec 100644
--- a/proto/infra/control.proto
+++ b/dc/proto/dc.proto
@@ -1,5 +1,6 @@
 syntax = "proto3";
-package infra;
+package dc;
+option go_package = "code.hackerspace.pl/hscloud/dc/proto";
 
 message GetPortsRequest {
 };
diff --git a/dc/topo/BUILD.bazel b/dc/topo/BUILD.bazel
index c10300c..83673e3 100644
--- a/dc/topo/BUILD.bazel
+++ b/dc/topo/BUILD.bazel
@@ -9,13 +9,13 @@
     importpath = "code.hackerspace.pl/hscloud/dc/topo",
     visibility = ["//visibility:private"],
     deps = [
+        "//dc/proto:go_default_library",
         "//dc/topo/assets:go_default_library",
         "//dc/topo/graph:go_default_library",
         "//dc/topo/proto:go_default_library",
         "//dc/topo/state:go_default_library",
         "//go/mirko:go_default_library",
         "//go/statusz:go_default_library",
-        "//proto/infra:go_default_library",
         "@com_github_digitalocean_go_netbox//netbox:go_default_library",
         "@com_github_digitalocean_go_netbox//netbox/client:go_default_library",
         "@com_github_golang_glog//:go_default_library",
diff --git a/dc/topo/service.go b/dc/topo/service.go
index 8919939..84eda5d 100644
--- a/dc/topo/service.go
+++ b/dc/topo/service.go
@@ -11,8 +11,8 @@
 
 	"code.hackerspace.pl/hscloud/go/mirko"
 	"code.hackerspace.pl/hscloud/go/statusz"
-	ipb "code.hackerspace.pl/hscloud/proto/infra"
 
+	dpb "code.hackerspace.pl/hscloud/dc/proto"
 	"code.hackerspace.pl/hscloud/dc/topo/assets"
 	"code.hackerspace.pl/hscloud/dc/topo/graph"
 	"code.hackerspace.pl/hscloud/dc/topo/state"
@@ -152,22 +152,22 @@
 		for _, po := range sw.Ports {
 			state := "INVALID"
 			switch po.Proto.LinkState {
-			case ipb.SwitchPort_LINKSTATE_DOWN:
+			case dpb.SwitchPort_LINKSTATE_DOWN:
 				state = "DOWN"
-			case ipb.SwitchPort_LINKSTATE_UP:
+			case dpb.SwitchPort_LINKSTATE_UP:
 				state = "UP"
 			}
 			mode := "INVALID"
 			switch po.Proto.PortMode {
-			case ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED:
+			case dpb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED:
 				mode = fmt.Sprintf("UNTAGGED (%d)", po.Proto.VlanNative)
-			case ipb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED:
+			case dpb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED:
 				mode = fmt.Sprintf("TAGGED (%v)", po.Proto.VlanTagged)
-			case ipb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC:
+			case dpb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC:
 				mode = "GENERIC"
-			case ipb.SwitchPort_PORTMODE_ROUTED:
+			case dpb.SwitchPort_PORTMODE_ROUTED:
 				mode = "ROUTED"
-			case ipb.SwitchPort_PORTMODE_MANGLED:
+			case dpb.SwitchPort_PORTMODE_MANGLED:
 				mode = "MANGLED"
 			}
 
diff --git a/dc/topo/state/BUILD.bazel b/dc/topo/state/BUILD.bazel
index 892e302..fefb3ef 100644
--- a/dc/topo/state/BUILD.bazel
+++ b/dc/topo/state/BUILD.bazel
@@ -6,9 +6,9 @@
     importpath = "code.hackerspace.pl/hscloud/dc/topo/state",
     visibility = ["//visibility:public"],
     deps = [
+        "//dc/proto:go_default_library",
         "//dc/topo/proto:go_default_library",
         "//go/pki:go_default_library",
-        "//proto/infra:go_default_library",
         "@org_golang_google_grpc//:go_default_library",
     ],
 )
diff --git a/dc/topo/state/state.go b/dc/topo/state/state.go
index 116a55a..e264827 100644
--- a/dc/topo/state/state.go
+++ b/dc/topo/state/state.go
@@ -7,24 +7,24 @@
 
 	"google.golang.org/grpc"
 
+	dpb "code.hackerspace.pl/hscloud/dc/proto"
 	"code.hackerspace.pl/hscloud/go/pki"
-	ipb "code.hackerspace.pl/hscloud/proto/infra"
 
 	pb "code.hackerspace.pl/hscloud/dc/topo/proto"
 )
 
 type SwitchportState struct {
-	Proto *ipb.SwitchPort
+	Proto *dpb.SwitchPort
 }
 
 type SwitchState struct {
 	Name  string
 	Ports []*SwitchportState
-	Stub  ipb.SwitchControlClient
+	Stub  dpb.SwitchControlClient
 }
 
 func (s *SwitchState) Fetch(ctx context.Context) error {
-	req := ipb.GetPortsRequest{}
+	req := dpb.GetPortsRequest{}
 	res, err := s.Stub.GetPorts(ctx, &req)
 	if err != nil {
 		return fmt.Errorf("GetPorts: %v", err)
@@ -65,7 +65,7 @@
 
 		s.Switches[sw.Name] = &SwitchState{
 			Name: sw.Name,
-			Stub: ipb.NewSwitchControlClient(conn),
+			Stub: dpb.NewSwitchControlClient(conn),
 		}
 		err := s.Switches[sw.Name].Fetch(ctx)
 		if err != nil {
diff --git a/go/svc/invoice/proto/BUILD.bazel b/go/svc/invoice/proto/BUILD.bazel
deleted file mode 100644
index 6c78fa3..0000000
--- a/go/svc/invoice/proto/BUILD.bazel
+++ /dev/null
@@ -1,8 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["generate.go"],
-    importpath = "code.hackerspace.pl/hscloud/go/svc/invoice/proto",
-    visibility = ["//visibility:public"],
-)
diff --git a/go/svc/invoice/proto/generate.go b/go/svc/invoice/proto/generate.go
deleted file mode 100644
index b0f6618..0000000
--- a/go/svc/invoice/proto/generate.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package proto
-
-//go:generate protoc -I.. ../inboice.proto --go_out=plugins=grpc:.
diff --git a/hswaw/README.md b/hswaw/README.md
new file mode 100644
index 0000000..cb11d17
--- /dev/null
+++ b/hswaw/README.md
@@ -0,0 +1,4 @@
+hscloud/hswaw
+=============
+
+Services and systems related to the Warsaw Hackerspace (ie. the physical place, not its cloud/ISP infrastructure).
diff --git a/go/svc/leasifier/BUILD.bazel b/hswaw/leasifier/BUILD.bazel
similarity index 81%
rename from go/svc/leasifier/BUILD.bazel
rename to hswaw/leasifier/BUILD.bazel
index c03fb35..1873ad8 100644
--- a/go/svc/leasifier/BUILD.bazel
+++ b/hswaw/leasifier/BUILD.bazel
@@ -6,12 +6,12 @@
         "main.go",
         "statusz.go",
     ],
-    importpath = "code.hackerspace.pl/hscloud/go/svc/leasifier",
+    importpath = "code.hackerspace.pl/hscloud/hswaw/leasifier",
     visibility = ["//visibility:private"],
     deps = [
         "//go/mirko:go_default_library",
         "//go/statusz:go_default_library",
-        "//proto/hswaw:go_default_library",
+        "//hswaw/proto:go_default_library",
         "@com_github_golang_glog//:go_default_library",
     ],
 )
diff --git a/hswaw/leasifier/README.md b/hswaw/leasifier/README.md
new file mode 100644
index 0000000..a88bbe3
--- /dev/null
+++ b/hswaw/leasifier/README.md
@@ -0,0 +1 @@
+Leasifier, a checkinator backend service.
diff --git a/go/svc/leasifier/main.go b/hswaw/leasifier/main.go
similarity index 98%
rename from go/svc/leasifier/main.go
rename to hswaw/leasifier/main.go
index a7ac49e..74ce88d 100644
--- a/go/svc/leasifier/main.go
+++ b/hswaw/leasifier/main.go
@@ -15,7 +15,7 @@
 	"github.com/golang/glog"
 
 	mirko "code.hackerspace.pl/hscloud/go/mirko"
-	hpb "code.hackerspace.pl/hscloud/proto/hswaw"
+	hpb "code.hackerspace.pl/hscloud/hswaw/proto"
 )
 
 type lease struct {
diff --git a/go/svc/leasifier/statusz.go b/hswaw/leasifier/statusz.go
similarity index 100%
rename from go/svc/leasifier/statusz.go
rename to hswaw/leasifier/statusz.go
diff --git a/proto/hswaw/BUILD b/hswaw/proto/BUILD.bazel
similarity index 63%
rename from proto/hswaw/BUILD
rename to hswaw/proto/BUILD.bazel
index d7bc9f1..5e98007 100644
--- a/proto/hswaw/BUILD
+++ b/hswaw/proto/BUILD.bazel
@@ -2,22 +2,22 @@
 load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
 
 proto_library(
-    name = "hswaw_proto",
+    name = "proto_proto",
     srcs = ["checkinator.proto"],
     visibility = ["//visibility:public"],
 )
 
 go_proto_library(
-    name = "hswaw_go_proto",
+    name = "proto_go_proto",
     compilers = ["@io_bazel_rules_go//proto:go_grpc"],
-    importpath = "code.hackerspace.pl/hscloud/proto/hswaw",
-    proto = ":hswaw_proto",
+    importpath = "code.hackerspace.pl/hscloud/hswaw/proto",
+    proto = ":proto_proto",
     visibility = ["//visibility:public"],
 )
 
 go_library(
     name = "go_default_library",
-    embed = [":hswaw_go_proto"],
-    importpath = "code.hackerspace.pl/hscloud/proto/hswaw",
+    embed = [":proto_go_proto"],
+    importpath = "code.hackerspace.pl/hscloud/hswaw/proto",
     visibility = ["//visibility:public"],
 )
diff --git a/proto/hswaw/checkinator.proto b/hswaw/proto/checkinator.proto
similarity index 83%
rename from proto/hswaw/checkinator.proto
rename to hswaw/proto/checkinator.proto
index 1023727..882083c 100644
--- a/proto/hswaw/checkinator.proto
+++ b/hswaw/proto/checkinator.proto
@@ -1,5 +1,6 @@
 syntax = "proto3";
 package hswaw;
+option go_package = "code.hackerspace.pl/hscloud/hswaw/proto";
 
 message LeasifierLeasesRequest {
 };
diff --git a/proto/infra/BUILD.bazel b/proto/infra/BUILD.bazel
deleted file mode 100644
index c9214e7..0000000
--- a/proto/infra/BUILD.bazel
+++ /dev/null
@@ -1,23 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-
-proto_library(
-    name = "infra_proto",
-    srcs = ["control.proto"],
-    visibility = ["//visibility:public"],
-)
-
-go_proto_library(
-    name = "infra_go_proto",
-    compilers = ["@io_bazel_rules_go//proto:go_grpc"],
-    importpath = "code.hackerspace.pl/hscloud/proto/infra",
-    proto = ":infra_proto",
-    visibility = ["//visibility:public"],
-)
-
-go_library(
-    name = "go_default_library",
-    embed = [":infra_go_proto"],
-    importpath = "code.hackerspace.pl/hscloud/proto/infra",
-    visibility = ["//visibility:public"],
-)