Fix mesh-mail-web's manifest: operators is type list, the listen word names its port number (issue 1262)
The controller refused the manifest: config.operators declared type "array" (not one of the controller's
five types, novox/hq ADR 0348 §4 — the word is "list"), and the bundle's env word MESH_MAIL_WEB_LISTEN said
${port:web} (a bundle's word takes the port NUMBER a listens entry gives, novox/hq ADR 0192; mesh-controller
internal/catalogue/port_into.go portsFilledInto matches it against listens[].Port, never an endpoint's
label). Fixed to type "list" and ${port:8099} (the listens entry's own port). main.go and the integration
harness already read/write a plain port number, so neither needed a change. manifest_test.go now asserts
both: config.operators.Type == "list", and the listen word equals ${port:<the listens entry's port>};
confirmed each independently fails against the old values before this fix.
This commit is contained in:
@@ -14,6 +14,7 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -109,9 +110,11 @@ func TestTheManifestSaysWhatTheCodeDoes(t *testing.T) {
|
||||
if len(m.Listens) != 1 || m.Listens[0].Name != "web" || m.Listens[0].From != "mesh" || m.Listens[0].Protocol != "tcp" {
|
||||
t.Fatalf("listens %+v, want exactly one, named web, from the mesh only", m.Listens)
|
||||
}
|
||||
// "list" is the controller's own word for a trusted array value (novox/hq ADR 0348 §4); "array" is not
|
||||
// one of its five types (number, string, boolean, object, list) and the controller refuses it.
|
||||
op, ok := m.Config["operators"]
|
||||
if !ok || op.Type != "array" || !op.Trusted || len(op.Default) != 0 {
|
||||
t.Fatalf("config.operators %+v, want a trusted array defaulting to nobody", op)
|
||||
if !ok || op.Type != "list" || !op.Trusted || len(op.Default) != 0 {
|
||||
t.Fatalf("config.operators %+v, want a trusted list defaulting to nobody", op)
|
||||
}
|
||||
// No database, no state bucket, no writable directory beyond the account's own state dir: only the
|
||||
// account (a user resource, not writable), the state directory, and the two files rendered into it.
|
||||
@@ -161,8 +164,13 @@ func TestTheManifestSaysWhatTheCodeDoes(t *testing.T) {
|
||||
t.Fatalf("the bundle reads %s at %s, which does not match resource %s's path", k, a[0].Env[k], v)
|
||||
}
|
||||
}
|
||||
if a[0].Env["MESH_MAIL_WEB_LISTEN"] != "${port:web}" {
|
||||
t.Fatalf("MESH_MAIL_WEB_LISTEN is %q, want the web endpoint's port", a[0].Env["MESH_MAIL_WEB_LISTEN"])
|
||||
// A bundle's word is ${port:<the number a listens entry gives>}, never the endpoint's own name
|
||||
// (novox/hq ADR 0192; mesh-controller internal/catalogue/port_into.go portsFilledInto matches it against
|
||||
// listens[].Port, a plain number, not a label like "web"). len(m.Listens)==1 is already checked above.
|
||||
wantListen := fmt.Sprintf("${port:%d}", m.Listens[0].Port)
|
||||
if a[0].Env["MESH_MAIL_WEB_LISTEN"] != wantListen {
|
||||
t.Fatalf("MESH_MAIL_WEB_LISTEN is %q, want %q (the listens entry's own port number)",
|
||||
a[0].Env["MESH_MAIL_WEB_LISTEN"], wantListen)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
],
|
||||
"config": {
|
||||
"operators": {
|
||||
"type": "array",
|
||||
"type": "list",
|
||||
"description": "The Keycloak identities (the ID token's preferred_username) let to sign in; nobody by default (novox/hq ADR 0440 §3).",
|
||||
"trusted": true,
|
||||
"default": []
|
||||
@@ -112,7 +112,7 @@
|
||||
"env": {
|
||||
"MESH_MAIL_WEB_OPERATORS": "${dir:state}/operators.json",
|
||||
"MESH_MAIL_WEB_OIDC": "${dir:state}/oidc.json",
|
||||
"MESH_MAIL_WEB_LISTEN": "${port:web}"
|
||||
"MESH_MAIL_WEB_LISTEN": "${port:8099}"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user