List the provider-elsewhere store test, read a machine's domain as its profile, reuse the settings read once, and refuse a nested own name (hq ADR 0346, review 228)
mesh/merge-gate head 7a0c219f961e merged into trunk 332fbaa9b175 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
mesh/repo-check head 7a0c219f961e merged into trunk 332fbaa9b175 — pass: its merge-check.sh passed
mesh/delivery delivered
mesh/merge-gate head 7a0c219f961e merged into trunk 332fbaa9b175 — pass: builds build-agent, mesh-controller → ace, g14, novox, shanks; no bus step; every …
mesh/repo-check head 7a0c219f961e merged into trunk 332fbaa9b175 — pass: its merge-check.sh passed
mesh/delivery delivered
This commit is contained in:
@@ -684,7 +684,7 @@ func artifactStoreOnNetwork(ctx context.Context, inv *inventory.Inventory,
|
||||
if !offers {
|
||||
continue
|
||||
}
|
||||
serves, err := servedOnNode(ctx, inv, machine, m, catalogue.ArtifactStoreProvision)
|
||||
serves, _, err := servedOnNode(ctx, inv, machine, m, catalogue.ArtifactStoreProvision)
|
||||
if err != nil {
|
||||
return "", "", false, fmt.Errorf("reading where %s puts the artifact store: %w", machine, err)
|
||||
}
|
||||
|
||||
@@ -291,10 +291,9 @@ func theRestOfTheMesh(ctx context.Context, inv *inventory.Inventory,
|
||||
caps, _ := inv.ProfileOf(ctx, n.Name)
|
||||
// Its public domain too (novox/hq ADR 0346): a provider elsewhere serves its own composed names,
|
||||
// and composes them as its own plan does, under its own domain.
|
||||
domain, err := inv.PublicDomainOf(ctx, n.Name)
|
||||
if err != nil {
|
||||
return catalogue.World{}, err
|
||||
}
|
||||
// Read as its profile is: a machine whose domain cannot be read (removed since the list was read)
|
||||
// composes no public name, which leaves the key out and says so, and fails no other machine's plan.
|
||||
domain, _ := inv.PublicDomainOf(ctx, n.Name)
|
||||
others = append(others, candidate{
|
||||
catalogue.Node{Name: n.Name, Site: siteOf[n.Name], Capabilities: caps,
|
||||
At: onNetwork[n.Name], PublicDomain: domain}, theirs})
|
||||
@@ -316,16 +315,12 @@ func theRestOfTheMesh(ctx context.Context, inv *inventory.Inventory,
|
||||
// What that module says a consumer needs to know, with that node's settings on
|
||||
// it: a port somebody moved on the provider is a port its consumers must be told
|
||||
// about, and the two coming from different places is how they come to disagree.
|
||||
serves, err := servedOnNode(ctx, inv, o.node.Name, m, name)
|
||||
serves, layers, err := servedOnNode(ctx, inv, o.node.Name, m, name)
|
||||
if err != nil {
|
||||
return catalogue.World{}, err
|
||||
}
|
||||
// And its own composed names, as that node composes them (novox/hq ADR 0346): a name it
|
||||
// does not compose leaves the key out, said under each consumer's need.
|
||||
layers, err := inv.SettingsFor(ctx, o.node.Name, m.Module)
|
||||
if err != nil {
|
||||
return catalogue.World{}, err
|
||||
}
|
||||
serves, leftOut, err := got.ServedOwnNames(m, name, serves, catalogue.WithDefaults(m, layers))
|
||||
if err != nil {
|
||||
return catalogue.World{}, err
|
||||
@@ -1592,19 +1587,20 @@ func managerPublicKeyFor(
|
||||
// artifact store's trust and the references composed through it (04-ISSUES/102). Unreadable
|
||||
// given ports are that node's refusal to report, not this reader's.
|
||||
func servedOnNode(ctx context.Context, inv *inventory.Inventory, node string,
|
||||
m catalogue.Manifest, provision string) (map[string]any, error) {
|
||||
m catalogue.Manifest, provision string) (map[string]any, []catalogue.Layer, error) {
|
||||
ports, layers, err := portsGivenOn(ctx, inv, node, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
serves := catalogue.ServedOn(m, provision, ports)
|
||||
if len(serves) > 0 {
|
||||
serves, err = catalogue.Settle(serves, catalogue.WithDefaults(m, layers))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
return serves, nil
|
||||
// The layers too, read once, for what is filled after (novox/hq ADR 0346).
|
||||
return serves, layers, nil
|
||||
}
|
||||
|
||||
// portsGivenOn is where a node puts a module's ports — assigned, then given over them — and the
|
||||
|
||||
@@ -135,6 +135,9 @@ func CheckServes(m Manifest) []string {
|
||||
for _, key := range sortedAnyKeys(m.Serves[provision]) {
|
||||
text, ok := m.Serves[provision][key].(string)
|
||||
if !ok {
|
||||
// A provider's own name is filled only in a value of its own (novox/hq ADR 0346): one
|
||||
// nested in a list or an object would be served as the placeholder, unsaid.
|
||||
problems = append(problems, nestedOwnNames(m, provision, key, m.Serves[provision][key])...)
|
||||
continue
|
||||
}
|
||||
// A probe identity, because what is checked is the shape of the statement and not
|
||||
|
||||
@@ -171,3 +171,32 @@ func quoted(values []string) []string {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// nestedOwnNames refuses a `${bound:…}` inside a served list or object: only a string value of its own is
|
||||
// filled (ServedOwnNames), so a nested one would reach the consumer as the placeholder (ADR 0346 §5).
|
||||
func nestedOwnNames(m Manifest, provision, key string, value any) []string {
|
||||
var found []string
|
||||
var walk func(v any)
|
||||
walk = func(v any) {
|
||||
switch x := v.(type) {
|
||||
case string:
|
||||
found = append(found, bound.FindAllString(x, -1)...)
|
||||
case []any:
|
||||
for _, e := range x {
|
||||
walk(e)
|
||||
}
|
||||
case map[string]any:
|
||||
for _, k := range sortedAnyKeys(x) {
|
||||
walk(x[k])
|
||||
}
|
||||
}
|
||||
}
|
||||
walk(value)
|
||||
if len(found) == 0 {
|
||||
return nil
|
||||
}
|
||||
return []string{fmt.Sprintf(
|
||||
"%s serves %s, and the value it serves as %q holds %s inside a list or an object: a provider's own "+
|
||||
"name is filled only in a string value of its own (novox/hq ADR 0346)",
|
||||
m.Module, provision, key, strings.Join(found, ", "))}
|
||||
}
|
||||
|
||||
@@ -143,6 +143,11 @@ func TestAServedNameIsCheckedWhenTheDefinitionIsRead(t *testing.T) {
|
||||
t.Errorf("%s: want a refusal saying %q, got %v", bad, want, err)
|
||||
}
|
||||
}
|
||||
nested := strings.Replace(aRegistryForge, `"public-root":"https://${bound:route:name-web}/api/packages/novox/npm/"`,
|
||||
`"roots":["https://${bound:route:name-web}/x"]`, 1)
|
||||
if _, err := ParseManifest([]byte(nested)); err == nil || !strings.Contains(err.Error(), "inside a list or an object") {
|
||||
t.Errorf("a nested own name is refused, not served as the placeholder: %v", err)
|
||||
}
|
||||
if _, err := ParseManifest([]byte(aRegistryForge)); err != nil {
|
||||
t.Fatalf("its own name is accepted: %v", err)
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -58,3 +58,4 @@
|
||||
./cmd/mesh-controller TestASettingsWalkStopsBeforeADataMoveAndPassesOverAMachineAway
|
||||
./cmd/mesh-controller TestACrossingSendSupersedesASettingsGate
|
||||
./cmd/mesh-controller TestASettingsWalkFailsOnARefusalThatCannotClear
|
||||
./cmd/mesh-controller TestAProviderElsewhereServesItsOwnComposedName
|
||||
|
||||
Reference in New Issue
Block a user