cluster/admitomatic: finish up service

This turns admitomatic into a self-standing service that can be used as
an admission controller.

I've tested this E2E on a local k3s server, and have some early test
code for that - but that'll land up in a follow up CR, as it first needs
to be cleaned up.

Change-Id: I46da0fc49f9d1a3a1a96700a36deb82e5057249b
diff --git a/cluster/admitomatic/config/BUILD.bazel b/cluster/admitomatic/config/BUILD.bazel
new file mode 100644
index 0000000..0344526
--- /dev/null
+++ b/cluster/admitomatic/config/BUILD.bazel
@@ -0,0 +1,23 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+proto_library(
+    name = "config_proto",
+    srcs = ["config.proto"],
+    visibility = ["//visibility:public"],
+)
+
+go_proto_library(
+    name = "config_go_proto",
+    importpath = "code.hackerspace.pl/hscloud/cluster/admitomatic/config",
+    proto = ":config_proto",
+    visibility = ["//visibility:public"],
+)
+
+go_library(
+    name = "go_default_library",
+    embed = [":config_go_proto"],
+    importpath = "code.hackerspace.pl/hscloud/cluster/admitomatic/config",
+    visibility = ["//visibility:public"],
+)
diff --git a/cluster/admitomatic/config/config.proto b/cluster/admitomatic/config/config.proto
new file mode 100644
index 0000000..460c571
--- /dev/null
+++ b/cluster/admitomatic/config/config.proto
@@ -0,0 +1,37 @@
+syntax = "proto3";
+package config;
+option go_package = "code.hackerspace.pl/hscloud/cluster/admitomatic/config";
+
+// Admitomatic configuration, passed as a text proto, for
+// example:
+//
+//  $ cat sample.pb.text
+//  allow_domain { namespace: "example" dns: "*.example.com" }
+//  allow_domain {
+//    namespace: "personal-q3k" dns: "foo.q3k.org"
+//  }
+//  allow_domain {
+//    namespace: "personal-q3k" dns: "bar.q3k.org"
+//  }
+//
+message Config {
+    // List of domains that are allowed to be configured as
+    // ingresses in a given namespace. If a domain does not
+    // appear in this list, it will be allowed to run in any
+    // namespace.
+    repeated AllowDomain allow_domain = 1;
+}
+
+message AllowDomain {
+    // namespace is a kubernetes namespace. An empty string is
+    // treated as the 'default' namespace.
+    string namespace = 1;
+    // dns is a domain name like 'example.com' or a wildcard
+    // like '*.foo.example.com'.
+    // Wildcards match domains at any level beneath the root,
+    // so the example above would match 'bar.foo.example.com'
+    // and 'baz.bar.foo.example.com'. However, they do not
+    // catch the root itself, ie. the above would not catch
+    // 'foo.example.com'.
+    string dns = 2;
+}
diff --git a/cluster/admitomatic/config/sample.pb.text b/cluster/admitomatic/config/sample.pb.text
new file mode 100644
index 0000000..21e98bc
--- /dev/null
+++ b/cluster/admitomatic/config/sample.pb.text
@@ -0,0 +1,7 @@
+allow_domain { namespace: "example" dns: "*.example.com" }
+allow_domain {
+  namespace: "personal-q3k" dns: "foo.q3k.org"
+}
+allow_domain {
+  namespace: "personal-q3k" dns: "bar.q3k.org"
+}