An unplaceable line of a left-out module, such as an access nobody placed, failed the whole machine's declaration. Say it among what could not be placed instead, never copy the definition's path past a placement that does not read, and accept a removal only when the decoder is past it.
65 lines
2.7 KiB
Go
65 lines
2.7 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. Until the controller is updated, nothing of it changes on its machines, and what it adds to other modules and the ports opened for it stop. Its data is still backed up as this controller reads it, which may not be what its newer version asks.",
|
|
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
|
|
}
|