Files
mesh-controller/cmd/mesh-controller/unknown_fields.go
T
jochen af63b233db
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group feat/setting-defaults failed: a member failed
Leave out a module whose stored manifest has an unknown field, and raise it (hq ADR 0262 review)
A key dropped silently ran a module without what its manifest says, and a key inside a block still
failed the whole catalogue. Judge a key by what it is about, and narrow the listing to one machine.
2026-10-08 17:34:53 +02:00

65 lines
2.5 KiB
Go

package main
import (
"context"
"fmt"
"sort"
"github.com/novox/mesh-controller/internal/catalogue"
"github.com/novox/mesh-controller/internal/conditions"
"github.com/novox/mesh-controller/internal/inventory"
)
// A stored manifest with a key this controller does not know (novox/hq ADR 0262). The module is left out
// of every machine's declaration by name; this is the loud half: a condition per module until the
// controller is updated, or the module is registered again in a shape this controller reads.
const (
sourceUnknownFields = "the catalogue"
kindUnknownField = "unknown-field"
)
// unknownFieldObservations is one condition for each module of the catalogue whose stored manifest has
// a key this controller does not know.
func unknownFieldObservations(known map[string]catalogue.Manifest) []conditions.Observation {
names := make([]string, 0, len(known))
for name, m := range known {
if m.UnknownField() != "" {
names = append(names, name)
}
}
sort.Strings(names)
var out []conditions.Observation
for _, name := range names {
m := known[name]
out = append(out, conditions.Observation{
Scope: conditions.ScopeMesh, ID: name, Kind: kindUnknownField, Severity: conditions.Warning,
Resolver: conditions.ResolverOperator, Source: sourceUnknownFields,
Summary: catalogue.UnknownFieldReason(m),
Said: m.UnknownField(),
Headline: name + " is left out until the controller is updated",
Explanation: name + " uses a field this controller does not know, so it is left out of every machine it is on, and nothing of it changes there until the controller is updated.",
Needs: "update the controller, or register " + name + " again at a version this controller knows.",
Resolved: "the controller reads " + name + " again",
})
}
return out
}
// raiseUnknownFields raises those conditions and clears the ones no longer true, on the controller's
// tick. A catalogue that could not be read raises and clears nothing: "none" is not said for "could not
// tell" (ADR 0227 rule 4).
func raiseUnknownFields(ctx context.Context, inv *inventory.Inventory) []string {
if conditionsFrom == nil {
return nil
}
known, err := inv.Catalogue(ctx)
if err != nil {
return []string{fmt.Sprintf("the catalogue could not be read to say which modules it cannot read: %v", err)}
}
if err := conditionsFrom.Reconcile(ctx, sourceUnknownFields, unknownFieldObservations(known)); err != nil {
return []string{fmt.Sprintf("the modules with a field this controller does not know could not be kept as conditions: %v", err)}
}
return nil
}