The controller's tools can issue a module its bus account
A module's account was mintable only from the controller's command line, so a rollout that gave a module one could not be finished through the mesh's own tools (novox/hq issue 191). The issue verb runs module issue for a module on a machine; the caller pushes the machine after.
This commit is contained in:
@@ -129,6 +129,14 @@ func argvFor(verb string, args map[string]any) ([]string, error) {
|
||||
// Half of either shape: the command says its usage, which names both shapes, and that is
|
||||
// the answer the caller needs.
|
||||
return []string{"rotate"}, nil
|
||||
case "issue":
|
||||
// The same act as `module issue` at a shell (novox/hq design 25 §4): the account is minted
|
||||
// into the mesh's records and delivered at the machine's next push, which is the caller's to
|
||||
// ask for — so the mesh is never pushed as a side effect of a credential.
|
||||
if err := need("node", "module"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []string{"module", "issue", str("module"), "--node", str("node")}, nil
|
||||
case "build":
|
||||
if err := need("repository"); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -73,6 +73,22 @@ func TestRotateTakesAProvisionOrAnOwnSecret(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// `issue` is `module issue` at a shell: the module and the machine, and nothing that would push. A
|
||||
// module's bus account was mintable only from the controller's command line, so an agent working
|
||||
// through the tools could not finish a rollout that gave a module one (novox/hq issue 191).
|
||||
func TestIssueGivesAModuleItsAccountOnAMachine(t *testing.T) {
|
||||
argv, err := argvFor("issue", map[string]any{"node": "ace", "module": "route-proxy"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Join(argv, " ") != "module issue route-proxy --node ace" {
|
||||
t.Fatalf("issue runs %v", argv)
|
||||
}
|
||||
if _, err := argvFor("issue", map[string]any{"module": "route-proxy"}); err == nil {
|
||||
t.Error("an account was issued without saying which machine reads it")
|
||||
}
|
||||
}
|
||||
|
||||
// A required argument missing is refused in the verb's own words, before anything runs.
|
||||
func TestAVerbMissingWhatItNeedsIsRefused(t *testing.T) {
|
||||
if _, err := argvFor("node", map[string]any{}); err == nil || !strings.Contains(err.Error(), `node needs "node"`) {
|
||||
|
||||
Reference in New Issue
Block a user