ADR 0593 §6: composed-<node> is written again, by the node's engine, each composition with its plan. The verb composition finds a published revision by the digest the have and want name, its resources', so a plan on the record does not hide it. The golden node grant also reads the indexer's verdicts, which compose-candidate takes for a candidate's manifests. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
50 lines
2.1 KiB
Go
50 lines
2.1 KiB
Go
// Package nodegrant is the grant the grants part composes for a node's engine (its principal of kind node), as a golden
|
|
// file the node-engine's tests run under (novox/hq ADR 0593 §1): the composer of the bus's user list is the grants
|
|
// part's own, so this repository holds what it composes for a node rather than calling it. testdata/node.json is that
|
|
// grant for the node NODE, captured from mesh-sdk's buscompose.PermissionsFor at 3d87ddc, with what this release adds
|
|
// to it (ADR 0593 §6, §7): the node's writes of its own composition state, and its reads of the indexer's candidates
|
|
// and of its verdicts on their manifests.
|
|
// When the grants part changes a node's grant, this file changes with it in the same group.
|
|
package nodegrant
|
|
|
|
import (
|
|
_ "embed"
|
|
"encoding/json"
|
|
"strings"
|
|
)
|
|
|
|
//go:embed testdata/node.json
|
|
var golden []byte
|
|
|
|
// Permissions is a node's grant: the subjects it may publish to, those refused though an allow covers them, those it
|
|
// may subscribe to, and whether it may answer a request once on its reply subject.
|
|
type Permissions struct {
|
|
Publish []string
|
|
PublishDeny []string
|
|
Subscribe []string
|
|
AllowResponses bool
|
|
}
|
|
|
|
// For is the grant of node, with the served keys (`<node>.<module>.<key>` of mesh-config's resolved values) it may
|
|
// read of another node: each one read by its watch and by a direct get, as the grants part grants a served read.
|
|
func For(node string, servedReads ...string) Permissions {
|
|
var p Permissions
|
|
if err := json.Unmarshal(golden, &p); err != nil {
|
|
panic("nodegrant: the golden grant is not JSON: " + err.Error())
|
|
}
|
|
swap := func(in []string) []string {
|
|
out := make([]string, len(in))
|
|
for i, s := range in {
|
|
out[i] = strings.ReplaceAll(s, "NODE", node)
|
|
}
|
|
return out
|
|
}
|
|
p.Publish, p.PublishDeny, p.Subscribe = swap(p.Publish), swap(p.PublishDeny), swap(p.Subscribe)
|
|
for _, key := range servedReads {
|
|
p.Publish = append(p.Publish,
|
|
"$JS.API.CONSUMER.CREATE.KV_mesh-config_resolved.*.$KV.mesh-config_resolved."+key,
|
|
"$JS.API.DIRECT.GET.KV_mesh-config_resolved.$KV.mesh-config_resolved."+key)
|
|
}
|
|
return p
|
|
}
|