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
|
// Half of either shape: the command says its usage, which names both shapes, and that is
|
||||||
// the answer the caller needs.
|
// the answer the caller needs.
|
||||||
return []string{"rotate"}, nil
|
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":
|
case "build":
|
||||||
if err := need("repository"); err != nil {
|
if err := need("repository"); err != nil {
|
||||||
return nil, err
|
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.
|
// A required argument missing is refused in the verb's own words, before anything runs.
|
||||||
func TestAVerbMissingWhatItNeedsIsRefused(t *testing.T) {
|
func TestAVerbMissingWhatItNeedsIsRefused(t *testing.T) {
|
||||||
if _, err := argvFor("node", map[string]any{}); err == nil || !strings.Contains(err.Error(), `node needs "node"`) {
|
if _, err := argvFor("node", map[string]any{}); err == nil || !strings.Contains(err.Error(), `node needs "node"`) {
|
||||||
|
|||||||
@@ -129,6 +129,13 @@ var ControllerVerbs = []Verb{
|
|||||||
"module": "an own secret: the module",
|
"module": "an own secret: the module",
|
||||||
"secret": "an own secret: its name in the module's definition",
|
"secret": "an own secret: its name in the module's definition",
|
||||||
}, nil)},
|
}, nil)},
|
||||||
|
{Name: "issue", Description: "Give a module on a machine its account on the bus: minted, and sealed to the " +
|
||||||
|
"machine as the module's own secret named broker, read at the next push of that machine. For a module " +
|
||||||
|
"whose definition declares that secret; refused with the reason otherwise. Issued again, it replaces the account.",
|
||||||
|
Input: schema(map[string]string{
|
||||||
|
"node": "the machine that runs the module",
|
||||||
|
"module": "the module's name",
|
||||||
|
}, []string{"node", "module"})},
|
||||||
{Name: "build", Description: "Have the build machine build a repository. Answers at once with the build's id: " +
|
{Name: "build", Description: "Have the build machine build a repository. Answers at once with the build's id: " +
|
||||||
"`builds` with that id follows it line by line, and the module is registered when the outcome comes.",
|
"`builds` with that id follows it line by line, and the module is registered when the outcome comes.",
|
||||||
Input: schema(map[string]string{
|
Input: schema(map[string]string{
|
||||||
|
|||||||
Reference in New Issue
Block a user