Module state is hq ADR 0202: 0201 landed first for a provider's derivations
This commit is contained in:
@@ -60,7 +60,7 @@ type Membership struct {
|
||||
Emits string `json:"emits"`
|
||||
Reaches map[string][]string `json:"reaches,omitempty"`
|
||||
Tools string `json:"tools"`
|
||||
// State is every bucket the module's code may reach, by the name it uses (novox/hq ADR 0201).
|
||||
// State is every bucket the module's code may reach, by the name it uses (novox/hq ADR 0202).
|
||||
State []StateIssued `json:"state,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/nats-io/nats.go/jetstream"
|
||||
)
|
||||
|
||||
// A module's state on the bus (novox/hq ADR 0201): key-value buckets the controller creates from what
|
||||
// A module's state on the bus (novox/hq ADR 0202): key-value buckets the controller creates from what
|
||||
// the module declared, and issues to each assignment in its membership by the name the module uses —
|
||||
// its own state by the local name, another module's as `<module>.<name>`.
|
||||
//
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
// timeout, not a refusal (measured, novox/hq research 024). So what a module may reach is decided here,
|
||||
// from its membership, and refused with the reason before anything is sent.
|
||||
|
||||
// StateIssued is one bucket an assignment may reach (ADR 0201).
|
||||
// StateIssued is one bucket an assignment may reach (ADR 0202).
|
||||
type StateIssued struct {
|
||||
Name string `json:"name"`
|
||||
Bucket string `json:"bucket"`
|
||||
@@ -61,7 +61,7 @@ func (c *Conn) issuedState(module, name string) (StateIssued, error) {
|
||||
m := c.Membership(module)
|
||||
if m == nil {
|
||||
return StateIssued{}, fmt.Errorf("%s has no membership issued on %s yet, so no state of it is reachable "+
|
||||
"until the mesh issues one (novox/hq ADR 0201)", module, c.node)
|
||||
"until the mesh issues one (novox/hq ADR 0202)", module, c.node)
|
||||
}
|
||||
var names []string
|
||||
for _, s := range m.State {
|
||||
@@ -76,7 +76,7 @@ func (c *Conn) issuedState(module, name string) (StateIssued, error) {
|
||||
issued = strings.Join(names, ", ")
|
||||
}
|
||||
return StateIssued{}, fmt.Errorf("%s keeps and reads no state called %q: it declares what it keeps under "+
|
||||
"`state` and what it reads under `reads` as <module>.<name>, and was issued: %s (novox/hq ADR 0201)",
|
||||
"`state` and what it reads under `reads` as <module>.<name>, and was issued: %s (novox/hq ADR 0202)",
|
||||
module, name, issued)
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ func (c *Conn) StatePut(module, name, key string, value json.RawMessage) (uint64
|
||||
if field := credentialField(value); field != "" {
|
||||
return 0, fmt.Errorf("%s's %s.%s carries a field %q, which names a credential: no secret is kept in state, "+
|
||||
"sealed or not — a bucket is a stream, and a machine joining a year later reads it whole. Name the "+
|
||||
"secret and fetch it on request/reply (novox/hq ADR 0201, design 32 §10)", module, name, key, field)
|
||||
"secret and fetch it on request/reply (novox/hq ADR 0202, design 32 §10)", module, name, key, field)
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), StateTimeout)
|
||||
defer cancel()
|
||||
@@ -209,14 +209,14 @@ func (c *Conn) writable(module, name string) (StateIssued, error) {
|
||||
if dot := strings.LastIndex(name, "."); dot > 0 {
|
||||
owner = name[:dot]
|
||||
}
|
||||
return s, fmt.Errorf("%s reads %s and does not keep it: only %s's own instances write it (novox/hq ADR 0201)",
|
||||
return s, fmt.Errorf("%s reads %s and does not keep it: only %s's own instances write it (novox/hq ADR 0202)",
|
||||
module, name, owner)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// StateWatch hands deliver the current value of every key matching the pattern — none that is
|
||||
// deleted — and then every change, in order (ADR 0201). It returns once the current values are
|
||||
// deleted — and then every change, in order (ADR 0202). It returns once the current values are
|
||||
// delivered; deliver is called from one goroutine, one change at a time, and an error from it is said
|
||||
// and the watch goes on: state is not a queue, and the next change, or the next start, reads it again.
|
||||
// The pattern is a key, with `*` for one name and `**` for the rest; empty is every key.
|
||||
@@ -314,7 +314,7 @@ func valueOf(raw []byte) json.RawMessage {
|
||||
|
||||
// credentialEndings are the ends of a field name that say its value is a credential. A guard against
|
||||
// the ordinary mistake, not a determined one: a sealed value is plain text to anything inspecting it,
|
||||
// so the rule is checked where it can be and said to be partial (ADR 0201).
|
||||
// so the rule is checked where it can be and said to be partial (ADR 0202).
|
||||
var credentialEndings = []string{"password", "passwd", "secret", "token", "credential", "credentials",
|
||||
"authorization", "apikey", "privatekey", "accesskey", "cookie"}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// A value naming a credential anywhere in it is found (novox/hq ADR 0201) — the guard against the
|
||||
// A value naming a credential anywhere in it is found (novox/hq ADR 0202) — the guard against the
|
||||
// ordinary mistake — and a value that only mentions tokens as a count is not.
|
||||
func TestACredentialNamedFieldIsFoundAnywhereInAValue(t *testing.T) {
|
||||
for value, want := range map[string]string{
|
||||
|
||||
Reference in New Issue
Block a user