| 1 | package edge |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "encoding/pem" |
| 6 | "fmt" |
| 7 | "io" |
| 8 | "net" |
| 9 | "os" |
| 10 | "path/filepath" |
| 11 | "testing" |
| 12 | |
| 13 | "github.com/carlosframework/platform/internal/release" |
| 14 | ) |
| 15 | |
| 16 | const dbfBackhaulHost = "console.backhaul.test" |
| 17 | |
| 18 | // TestDBForwardBackhaulPairHelper is not a test of its own: the root |
| 19 | // package's TestDBForwardThroughTheBackhaulHop builds this package's test |
| 20 | // binary and runs this as a helper process. It stands up two real edges |
| 21 | // over one bucket, as TestBackhaulE2EAcrossTwoEdges does: annie, home of |
| 22 | // console.backhaul.test, routed to DBF_BACKHAUL_UPSTREAM (the real console |
| 23 | // the parent serves), and betty, which serves no host and so backhauls every |
| 24 | // request for it to annie. It writes the test CA to DBF_BACKHAUL_DIR/ca.pem, |
| 25 | // prints betty's TLS address on a line starting "DBF-BACKHAUL ", and serves |
| 26 | // until its stdin closes. |
| 27 | func TestDBForwardBackhaulPairHelper(t *testing.T) { |
| 28 | if os.Getenv("DBF_BACKHAUL_HELPER") != "1" { |
| 29 | t.Skip("a helper process for the root package's TestDBForwardThroughTheBackhaulHop") |
| 30 | } |
| 31 | upstream, dir := os.Getenv("DBF_BACKHAUL_UPSTREAM"), os.Getenv("DBF_BACKHAUL_DIR") |
| 32 | e2eQuietLogs(t) |
| 33 | bucket := t.TempDir() |
| 34 | seed := release.NewDirStore(bucket) |
| 35 | if err := MintMeshKey(context.Background(), seed); err != nil { |
| 36 | t.Fatal(err) |
| 37 | } |
| 38 | ca := newE2ECA(t) |
| 39 | ca.publish(t, seed, dbfBackhaulHost) |
| 40 | home := newBackhaulEdge(t, bucket, "annie", ca, nil, map[string]string{dbfBackhaulHost: upstream}) |
| 41 | sender := newBackhaulEdge(t, bucket, "betty", ca, nil, nil) |
| 42 | eip, port, err := net.SplitHostPort(home.tlsAddr) |
| 43 | if err != nil { |
| 44 | t.Fatal(err) |
| 45 | } |
| 46 | oldPort, oldCAs := backhaulPort, backhaulRootCAs |
| 47 | backhaulPort, backhaulRootCAs = port, ca.pool |
| 48 | t.Cleanup(func() { backhaulPort, backhaulRootCAs = oldPort, oldCAs }) |
| 49 | putJSON(t, seed, "control/edges/annie.json", fmt.Sprintf(`{"v":1,"box":"annie","eip":%q,"hosts":{%q:{"role":"home"}}}`, eip, dbfBackhaulHost)) |
| 50 | bEIP, _, err := net.SplitHostPort(sender.tlsAddr) |
| 51 | if err != nil { |
| 52 | t.Fatal(err) |
| 53 | } |
| 54 | putJSON(t, seed, "control/edges/betty.json", fmt.Sprintf(`{"v":1,"box":"betty","eip":%q,"hosts":{}}`, bEIP)) |
| 55 | for _, be := range []*backhaulEdge{home, sender} { |
| 56 | if err := be.mirror.Refresh(context.Background()); err != nil { |
| 57 | t.Fatal(err) |
| 58 | } |
| 59 | refreshHomeMap(t, be.homes) |
| 60 | } |
| 61 | caPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: ca.root.Raw}) |
| 62 | if err := os.WriteFile(filepath.Join(dir, "ca.pem"), caPEM, 0o600); err != nil { |
| 63 | t.Fatal(err) |
| 64 | } |
| 65 | fmt.Println("DBF-BACKHAUL " + sender.tlsAddr) |
| 66 | io.Copy(io.Discard, os.Stdin) |
| 67 | } |
| 68 | |