56 lines
2.3 KiB
Go
56 lines
2.3 KiB
Go
package apply
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/declaration"
|
|
"github.com/novox/mesh-host/internal/store"
|
|
)
|
|
|
|
// A node is adopted or converged, and a declaration says which it is for (novox/hq ADR 0100).
|
|
//
|
|
// **The two are not interchangeable, and the host knows which it is.** A converged declaration
|
|
// carries the mesh's drop-by-default filter and retires the firewall the node was found with; on
|
|
// an adopted node that closes the machine to everything the predecessor still serves — which is
|
|
// what happened when an operator ran `reconcile` on an adopted control-node and it applied the
|
|
// converged genesis bundle (novox/hq issue 104). The host reported "adopted" in every report and
|
|
// compared nothing. Now it compares, at the point of application, whichever command delivered
|
|
// the declaration.
|
|
//
|
|
// Only the mesh changes a node's mode, and it does so by sending a declaration: the flip arrives
|
|
// over the link as the first converged declaration after adopted ones (`converge` on the
|
|
// controller), and the way back as the first adopted one (`adopt`). So a declaration the link
|
|
// delivers, signed and verified, is the mode's authority and is not checked against the record —
|
|
// it becomes the record. Everything else — the carried bundle, a file, the kept declaration a
|
|
// disconnected node re-applies — is held to the mode already recorded.
|
|
|
|
// ModeOf says which mode a declaration is for.
|
|
func ModeOf(d *declaration.Declaration) string {
|
|
if d.Adoption != nil {
|
|
return store.ModeAdopted
|
|
}
|
|
return store.ModeConverged
|
|
}
|
|
|
|
// CheckMode refuses a declaration whose mode is not the one this node has recorded. A node with
|
|
// no recorded mode — a machine nothing has said a mode to yet — takes either.
|
|
func CheckMode(known store.State, d *declaration.Declaration) error {
|
|
if known.Mode == "" || known.Mode == ModeOf(d) {
|
|
return nil
|
|
}
|
|
act := "`converge`"
|
|
if ModeOf(d) == store.ModeAdopted {
|
|
act = "`adopt`"
|
|
}
|
|
return fmt.Errorf("this node is %s; the declaration says %s — %s declaration is not applied "+
|
|
"to %s node; %s on the controller is the act that changes it, and it sends the "+
|
|
"declaration that does", known.Mode, ModeOf(d), article(ModeOf(d)), article(known.Mode), act)
|
|
}
|
|
|
|
func article(mode string) string {
|
|
if mode == store.ModeAdopted {
|
|
return "an adopted"
|
|
}
|
|
return "a converged"
|
|
}
|