cluster/admitomatic: implement basic dns/ns filtering

This is the beginning of a validating admission controller which we will
use to permit end-users access to manage Ingresses.

This first pass implements an ingressFilter, which is the main structure
through which allowed namespace/dns combinations will be allowed. The
interface is currently via a test, but in the future this will likely be
configured via a command line, or via a serialized protobuf config.

Change-Id: I22dbed633ea8d8e1fa02c2a1598f37f02ea1b309
diff --git a/cluster/admitomatic/main.go b/cluster/admitomatic/main.go
new file mode 100644
index 0000000..3178818
--- /dev/null
+++ b/cluster/admitomatic/main.go
@@ -0,0 +1,45 @@
+package main
+
+import (
+	"context"
+	"flag"
+	"net/http"
+	"time"
+
+	"code.hackerspace.pl/hscloud/go/mirko"
+	"github.com/golang/glog"
+)
+
+var (
+	flagListen = "127.0.0.1:8080"
+)
+
+func main() {
+	flag.StringVar(&flagListen, "pub_listen", flagListen, "Address to listen on for HTTP traffic")
+	flag.Parse()
+
+	m := mirko.New()
+	if err := m.Listen(); err != nil {
+		glog.Exitf("Listen(): %v", err)
+	}
+
+	if err := m.Serve(); err != nil {
+		glog.Exitf("Serve(): %v", err)
+	}
+
+	mux := http.NewServeMux()
+	// TODO(q3k): implement admission controller
+	srv := &http.Server{Addr: flagListen, Handler: mux}
+
+	glog.Infof("Listening on %q...", flagListen)
+	go func() {
+		if err := srv.ListenAndServe(); err != nil {
+			glog.Error(err)
+		}
+	}()
+
+	<-m.Done()
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	srv.Shutdown(ctx)
+}