Report what an adopted node holds, its firewall and what is reachable, and speak unasked when that changes (hq ADR 0100)
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package reachable
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Defends novox/hq ADR 0100: converging previews every listening socket and every published
|
||||
// container port. Fixtures are captured from a real machine.
|
||||
|
||||
func fixture(t *testing.T, name string) string {
|
||||
t.Helper()
|
||||
raw, err := os.ReadFile("testdata/" + name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return string(raw)
|
||||
}
|
||||
|
||||
func find(rs []Reach, protocol, address string, port int) (Reach, bool) {
|
||||
for _, r := range rs {
|
||||
if r.Protocol == protocol && r.Address == address && r.Port == port {
|
||||
return r, true
|
||||
}
|
||||
}
|
||||
return Reach{}, false
|
||||
}
|
||||
|
||||
func TestSocketsAreReadWithWhatHoldsThem(t *testing.T) {
|
||||
got := Sockets(fixture(t, "ss.txt"))
|
||||
if r, ok := find(got, "tcp", "0.0.0.0", 22); !ok || r.By != "sshd" {
|
||||
t.Errorf("ssh not read: %+v", r)
|
||||
}
|
||||
if r, ok := find(got, "tcp", "::", 445); !ok || r.By != "smbd" {
|
||||
t.Errorf("an IPv6 wildcard listener not read: %+v", r)
|
||||
}
|
||||
if _, ok := find(got, "udp", "fe80::849e:ccff:fea8:24c7", 123); !ok {
|
||||
t.Error("a link-local address with a scope was not read")
|
||||
}
|
||||
if r, ok := find(got, "udp", "127.0.0.1", 53); !ok || r.By != "dnsmasq" {
|
||||
t.Errorf("a loopback udp socket not read: %+v", r)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublishedPortsNameTheirContainerAndItsPort(t *testing.T) {
|
||||
got := Published(fixture(t, "docker-ps.txt"))
|
||||
if r, ok := find(got, "tcp", "0.0.0.0", 8770); !ok || r.By != "whisper" || r.ContainerPort != 8000 || !r.Published {
|
||||
t.Errorf("a published port: %+v", r)
|
||||
}
|
||||
if r, ok := find(got, "tcp", "0.0.0.0", 9001); !ok || r.ContainerPort != 9001 {
|
||||
t.Errorf("a published range was not expanded: %+v", r)
|
||||
}
|
||||
if r, ok := find(got, "tcp", "127.0.0.1", 15673); !ok || r.ContainerPort != 15672 {
|
||||
t.Errorf("a loopback-published port: %+v", r)
|
||||
}
|
||||
for _, r := range got {
|
||||
if r.By == "umami_db" {
|
||||
t.Errorf("an exposed and unpublished port was reported reachable: %+v", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPublishedPortIsReportedOnceAsPublished(t *testing.T) {
|
||||
merged := Merge(Sockets(fixture(t, "ss.txt")), Published(fixture(t, "docker-ps.txt")))
|
||||
n := 0
|
||||
for _, r := range merged {
|
||||
if r.Protocol == "tcp" && r.Address == "0.0.0.0" && r.Port == 8770 {
|
||||
n++
|
||||
if !r.Published {
|
||||
t.Errorf("the runtime's proxy was reported instead of the published port: %+v", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
if n != 1 {
|
||||
t.Errorf("port 8770 reported %d times", n)
|
||||
}
|
||||
if _, ok := find(merged, "tcp", "0.0.0.0", 22); !ok {
|
||||
t.Error("a socket was lost in the merge")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectAsksSsAndTheRuntime(t *testing.T) {
|
||||
var asked []string
|
||||
run := func(_ context.Context, name string, args ...string) (string, error) {
|
||||
asked = append(asked, name+" "+strings.Join(args, " "))
|
||||
if name == "ss" {
|
||||
return fixture(t, "ss.txt"), nil
|
||||
}
|
||||
return fixture(t, "docker-ps.txt"), nil
|
||||
}
|
||||
got, err := Collect(context.Background(), run)
|
||||
if err != nil || len(got) == 0 {
|
||||
t.Fatalf("%v %v", got, err)
|
||||
}
|
||||
if len(asked) != 2 {
|
||||
t.Errorf("asked %v", asked)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user