cluster/identd/kubenat: implement

This is a library to find pod information for a given TCP 4-tuple.

Change-Id: I254983e579e3aaa04c0c5491851f4af94a3f4249
diff --git a/cluster/identd/kubenat/kubenat_test.go b/cluster/identd/kubenat/kubenat_test.go
new file mode 100644
index 0000000..78afd22
--- /dev/null
+++ b/cluster/identd/kubenat/kubenat_test.go
@@ -0,0 +1,43 @@
+package kubenat
+
+import (
+	"context"
+	"flag"
+	"net"
+	"testing"
+)
+
+func TestResolvePod(t *testing.T) {
+	t.Skip("needs containerd running on host and unhardcoded test data")
+	flag.Set("logtostderr", "true")
+
+	ctx, ctxC := context.WithCancel(context.Background())
+	defer ctxC()
+
+	r, err := NewResolver(ctx, "/tmp/conntrack", "/tmp/containerd.sock")
+	if err != nil {
+		t.Fatalf("NewResolver: %v", err)
+	}
+
+	pi, err := r.ResolvePod(ctx, &Tuple4{
+		RemoteIP:   net.IPv4(185, 191, 225, 10),
+		RemotePort: 6697,
+		LocalIP:    net.IPv4(185, 236, 240, 36),
+		LocalPort:  53449,
+	})
+	if err != nil {
+		t.Fatalf("ResolvePod: %v", err)
+	}
+	if want, got := net.IPv4(10, 10, 26, 23), pi.PodIP; !want.Equal(got) {
+		t.Errorf("Wanted pod IP %v, got %v", want, got)
+	}
+	if want, got := uint16(54782), pi.PodTranslatedPort; want != got {
+		t.Errorf("Wanted pod port %d, got %d", want, got)
+	}
+	if want, got := "matrix", pi.KubernetesNamespace; want != got {
+		t.Errorf("Wanted pod namespace %q, got %q", want, got)
+	}
+	if want, got := "appservice-irc-freenode-68977cdd5f-kfzl6", pi.Name; want != got {
+		t.Errorf("Wanted pod name %q, got %q", want, got)
+	}
+}