Reach asks for names on a routed endpoint, and its port stays the manifest's
A routed endpoint's port is how the proxy reaches it and nothing else (ADR 0045): a public service listens from the mesh, only the proxy reaches it, and it is exposed by name. So reach on a routed endpoint asks for names, and the port keeps what the manifest said; on an unrouted one — git over ssh, a mail port, the bus — it governs the port, because there is no name and the port is the only way in. Found by trying to express a real module rather than by review: routed name public because browsers post to it, machine-side port private because it serves a dashboard in cleartext. Under one value for both there was no way to say it, and 'public' would have reopened a port narrowed an hour earlier. novox/hq ADR 0138, corrected in place the same day.
This commit is contained in:
@@ -81,16 +81,23 @@ func TestBothComposesBothNames(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// **The filter reads the same value.** One statement, and the rule it produces is the one the reach
|
||||
// means — which is the whole claim of ADR 0138 and the reason reach is not two settings.
|
||||
func TestTheFilterFollowsTheSameReach(t *testing.T) {
|
||||
// **The filter reads the same value — for an endpoint the proxy does not serve.**
|
||||
//
|
||||
// A routed endpoint's port is how the proxy reaches it and nothing else (ADR 0045): a public service
|
||||
// listens from the mesh, only the proxy reaches it, and it is exposed by name. So on a routed
|
||||
// endpoint the reach asks for a name and the port keeps what the manifest said.
|
||||
func TestAnUnroutedEndpointsPortFollowsItsReach(t *testing.T) {
|
||||
// The same module with its route taken away: now the port is the only way in, so reach governs it.
|
||||
bare := aRoutedWeb()
|
||||
bare.Contributes = nil
|
||||
|
||||
for _, c := range []struct{ reach, want string }{
|
||||
{ReachInternal, FromMesh},
|
||||
{ReachPublic, FromEverywhere},
|
||||
{ReachBoth, FromEverywhere},
|
||||
{ReachMachine, FromMachine},
|
||||
} {
|
||||
r := Resolution{Node: "anchor", Modules: []Manifest{aRoutedWeb()}}
|
||||
r := Resolution{Node: "anchor", Modules: []Manifest{bare}}
|
||||
rules, err := r.Rules(Rendering{Settings: reachSet(c.reach)})
|
||||
if err != nil {
|
||||
t.Fatalf("%s: rules: %v", c.reach, err)
|
||||
@@ -110,6 +117,30 @@ func TestTheFilterFollowsTheSameReach(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// **A public name does not open the machine's port**, which is the case that found this.
|
||||
//
|
||||
// A module whose routed name must be public and whose machine-side port must not be had no way to say
|
||||
// so while one value drove both. Under one value it could not be expressed; the port would reopen.
|
||||
func TestAPublicNameLeavesARoutedPortAsTheManifestSaid(t *testing.T) {
|
||||
r := Resolution{Node: "anchor", Modules: []Manifest{aRoutedWeb()},
|
||||
PublicDomain: "example.test", At: "anchor.internal"}
|
||||
rules, err := r.Rules(Rendering{Settings: reachSet(ReachPublic)})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, rule := range rules {
|
||||
if rule.Port == 3000 && rule.From != FromMesh {
|
||||
t.Fatalf("a public reach opened a routed port to %q; the proxy is how it is reached",
|
||||
rule.From)
|
||||
}
|
||||
}
|
||||
// And the name it asked for is there, so the reach was not simply ignored.
|
||||
public, internal := namesFor(t, aRoutedWeb(), reachSet(ReachPublic))
|
||||
if public != "app.example.test" || internal != "" {
|
||||
t.Fatalf("names are %q and %q, want the public one only", public, internal)
|
||||
}
|
||||
}
|
||||
|
||||
// A reach for a port the module does not listen on reaches nothing, and is refused where it is
|
||||
// written rather than accepted and ignored.
|
||||
func TestAReachForAPortTheModuleDoesNotListenOnIsRefused(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user