go/svc/(dc stuff) -> dc/

We want to start keeping codebases separated per 'team'/intent, to then
have simple OWNER files/trees to specify review rules.

This means dc/ stuff can all be OWNED by q3k, and review will only
involve a +1 for style/readability, instead  of a +2 for approval.

Change-Id: I05afbc4e1018944b841ec0d88cd24cc95bec8bf1
diff --git a/dc/topo/main.go b/dc/topo/main.go
new file mode 100644
index 0000000..fd1fb8f
--- /dev/null
+++ b/dc/topo/main.go
@@ -0,0 +1,79 @@
+package main
+
+//go:generate packr
+
+import (
+	"context"
+	"flag"
+	"io/ioutil"
+
+	"code.hackerspace.pl/hscloud/go/mirko"
+	"github.com/digitalocean/go-netbox/netbox"
+	"github.com/digitalocean/go-netbox/netbox/client"
+	"github.com/golang/glog"
+	"github.com/golang/protobuf/proto"
+
+	"code.hackerspace.pl/hscloud/dc/topo/graph"
+	pb "code.hackerspace.pl/hscloud/dc/topo/proto"
+	"code.hackerspace.pl/hscloud/dc/topo/state"
+)
+
+var (
+	flagConfigPath   string
+	flagNetboxHost   string
+	flagNetboxAPIKey string
+)
+
+func init() {
+	flag.Set("logtostderr", "true")
+}
+
+func main() {
+	flag.StringVar(&flagConfigPath, "config_path", "./topo.pb.text", "Text proto configuration of Topo (per config.proto)")
+	flag.StringVar(&flagNetboxHost, "netbox_host", "netbox.bgp.wtf", "Netbox host")
+	flag.StringVar(&flagNetboxAPIKey, "netbox_api_key", "", "Netbox API key")
+	flag.Parse()
+
+	m := mirko.New()
+	if err := m.Listen(); err != nil {
+		glog.Exitf("Listen(): %v", err)
+	}
+
+	ctx := context.Background()
+
+	data, err := ioutil.ReadFile(flagConfigPath)
+	if err != nil {
+		glog.Exitf("Could not read config: %v", err)
+	}
+
+	config := pb.Config{}
+	proto.UnmarshalText(string(data), &config)
+
+	stm := state.NewManager()
+	err = stm.FetchState(ctx, &config)
+	if err != nil {
+		glog.Exitf("Initial state fetch failed: %v", err)
+	}
+
+	gr := graph.New()
+	err = gr.LoadConfig(&config)
+	if err != nil {
+		glog.Exitf("Initial config load failed: %v", err)
+	}
+
+	client.DefaultSchemes = []string{"https"}
+	nb := netbox.NewNetboxWithAPIKey(flagNetboxHost, flagNetboxAPIKey)
+	err = gr.FeedFromNetbox(ctx, nb)
+	if err != nil {
+		glog.Exitf("Initial netbox feed failed: %v", err)
+	}
+
+	s := NewService(gr, stm)
+	s.Setup(m)
+
+	if err := m.Serve(); err != nil {
+		glog.Exitf("Serve(): %v", err)
+	}
+
+	select {}
+}