Refuse a node's accounts through any verb, and a stale or service-account agent verdict
The generic command verb ran node account and node agent-account, so an agent could name itself the operator account and have the next send grant it root (hq ADR 0266 review). Refuse every node subcommand but list and show through any verb; refuse the operator account as the agent account in both directions and well-known service accounts as an agent account; and count a verdict heard more than 15 minutes ago as not judged, so stopping the node-engine cannot freeze a healthy one. Re-pin mesh-host to its review head.
This commit is contained in:
@@ -27,6 +27,7 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/conditions"
|
||||
"github.com/novox/mesh-controller/internal/inventory"
|
||||
@@ -60,16 +61,27 @@ func agentConfined(ctx context.Context, inv *inventory.Inventory, node string) (
|
||||
if err != nil {
|
||||
return true, false, "", err
|
||||
}
|
||||
confined, why = judgedConfined(n.AgentAccount, h, had)
|
||||
confined, why = judgedConfined(n.AgentAccount, h, had, time.Now())
|
||||
return true, confined, why, nil
|
||||
}
|
||||
|
||||
// judgedConfined is the judgement over one statement, without the store.
|
||||
func judgedConfined(agent string, h inventory.NodeHealth, had bool) (bool, string) {
|
||||
// verdictFreshFor is how old the statement holding the verdict may be, by this controller's clock. A
|
||||
// node-engine states its health on every change and at least every five minutes (mesh-host's sayAnyway), so
|
||||
// three statements missed is a node-engine stopped, or a machine away. **A stale verdict is not a pass**: an
|
||||
// agent that stopped the node-engine must not leave "cannot become root" standing from before.
|
||||
const verdictFreshFor = 15 * time.Minute
|
||||
|
||||
// judgedConfined is the judgement over one statement, without the store, at now.
|
||||
func judgedConfined(agent string, h inventory.NodeHealth, had bool, now time.Time) (bool, string) {
|
||||
if !had {
|
||||
return false, fmt.Sprintf("the agent account %s is not judged: the machine's node-engine has stated "+
|
||||
"nothing of what it runs", agent)
|
||||
}
|
||||
if age := now.Sub(h.HeardAt); age > verdictFreshFor {
|
||||
return false, fmt.Sprintf("the agent account %s is not judged: the machine's newest statement was heard at "+
|
||||
"%s, more than %d minutes ago, and a verdict that old is not a verdict on now", agent,
|
||||
h.HeardAt.Local().Format("2006-01-02 15:04"), int(verdictFreshFor.Minutes()))
|
||||
}
|
||||
if h.Contract < link.RootContract {
|
||||
return false, fmt.Sprintf("the agent account %s is not judged: the machine's node-engine is older than "+
|
||||
"the judging of an account's root (its statement's contract is %d, the judging is %d)",
|
||||
@@ -122,7 +134,7 @@ func probeAgentAccounts(ctx context.Context, d *doctor) ([]conditions.Observatio
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
confined, why := judgedConfined(n.AgentAccount, h, had)
|
||||
confined, why := judgedConfined(n.AgentAccount, h, had, time.Now())
|
||||
if confined {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user