Log a refused wording without what it quotes, and keep the secret-given words within bounds
The reviewer found that the logged reason quoted the refused fragment: a hash-shaped secret would reach the journal, and a changing clock time defeated the once-per-kind dedupe. The reason is now logged without its quoted fragment, the test resets the dedupe so it repeats, and a module name too long for the headline falls back to the machine.
This commit is contained in:
@@ -228,9 +228,16 @@ const kindSecretGiven = "secret-given"
|
|||||||
func secretGivenObservation(node, module, name, how string, at time.Time) conditions.Observation {
|
func secretGivenObservation(node, module, name, how string, at time.Time) conditions.Observation {
|
||||||
key := node + "." + module + "." + name
|
key := node + "." + module + "." + name
|
||||||
where := module + " on " + node
|
where := module + " on " + node
|
||||||
|
// Within the bounds whatever the names' length: the module and machine, else the module, else the machine.
|
||||||
headline := "New secret given for " + where
|
headline := "New secret given for " + where
|
||||||
if len(headline) > conditions.HeadlineMax {
|
for _, h := range []string{"New secret given for " + module, "New secret given on " + node} {
|
||||||
headline = "New secret given for " + module
|
if len(headline) > conditions.HeadlineMax {
|
||||||
|
headline = h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolved := "You saw that " + module + " was given a new secret"
|
||||||
|
if len(resolved) > conditions.HeadlineMax+20 {
|
||||||
|
resolved = "You saw that a new secret was given on " + node
|
||||||
}
|
}
|
||||||
return conditions.Observation{Scope: conditions.ScopeMachine, ID: key, Token: kindSecretGiven, Kind: kindSecretGiven,
|
return conditions.Observation{Scope: conditions.ScopeMachine, ID: key, Token: kindSecretGiven, Kind: kindSecretGiven,
|
||||||
Machine: node, Severity: conditions.Urgent, Source: kindSecretGiven,
|
Machine: node, Severity: conditions.Urgent, Source: kindSecretGiven,
|
||||||
@@ -240,7 +247,7 @@ func secretGivenObservation(node, module, name, how string, at time.Time) condit
|
|||||||
Explanation: fmt.Sprintf("The secret %s of %s was given %s. If you gave it, nothing else is needed. If you "+
|
Explanation: fmt.Sprintf("The secret %s of %s was given %s. If you gave it, nothing else is needed. If you "+
|
||||||
"did not, somebody else now holds what %s acts with.", secretNameWords(name), where, how, module),
|
"did not, somebody else now holds what %s acts with.", secretNameWords(name), where, how, module),
|
||||||
Needs: "silence this if you just gave it; if you did not, give it again yourself so that only you hold it.",
|
Needs: "silence this if you just gave it; if you did not, give it again yourself so that only you hold it.",
|
||||||
Resolved: "You saw that " + module + " was given a new secret",
|
Resolved: resolved,
|
||||||
Actions: []conditions.Action{conditions.SilenceAction(conditions.Key(conditions.ScopeMachine, key, kindSecretGiven))}}
|
Actions: []conditions.Action{conditions.SilenceAction(conditions.Key(conditions.ScopeMachine, key, kindSecretGiven))}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -215,11 +215,14 @@ func TestTheSecretGivenConditionSaysItselfInPlainWords(t *testing.T) {
|
|||||||
t.Error("the words carry the value")
|
t.Error("the words carry the value")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// A long module name keeps the headline within its bound.
|
// A long module name keeps the headline and the resolved line within their bounds.
|
||||||
o := secretGivenObservation("anchor", "a-module-with-a-rather-long-name-indeed", "api-key", "at the controller's terminal", at)
|
for _, module := range []string{"a-module-with-a-rather-long-name-indeed",
|
||||||
if why, ok := conditions.PlainWords(conditions.Words{Headline: o.Headline, Explanation: o.Explanation,
|
"a-module-with-a-name-so-long-that-no-headline-could-ever-hold-it"} {
|
||||||
Resolved: o.Resolved, Needs: o.Needs, Actions: o.Actions}, o.Machine); !ok {
|
o := secretGivenObservation("anchor", module, "api-key", "at the controller's terminal", at)
|
||||||
t.Errorf("a long module name: %s", why)
|
if why, ok := conditions.PlainWords(conditions.Words{Headline: o.Headline, Explanation: o.Explanation,
|
||||||
|
Resolved: o.Resolved, Needs: o.Needs, Actions: o.Actions}, o.Machine); !ok {
|
||||||
|
t.Errorf("the module %s: %s", module, why)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -151,11 +151,17 @@ func unworded(o Observation, why string) {
|
|||||||
Unworded(o, why)
|
Unworded(o, why)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, seen := loggedUnworded.LoadOrStore(o.Kind+"\x00"+why, true); !seen {
|
// The reason without what it quotes of the words: a quoted fragment may be a hash-shaped secret, and a
|
||||||
log.Printf("the condition kind %q is said in the scope's words, not its own: %s", o.Kind, why)
|
// fragment that changes (a clock time) would log a new line every time.
|
||||||
|
reason := quotedFragment.ReplaceAllString(why, "")
|
||||||
|
if _, seen := loggedUnworded.LoadOrStore(o.Kind+"\x00"+reason, true); !seen {
|
||||||
|
log.Printf("the condition kind %q is said in the scope's words, not its own: %s", o.Kind, reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// quotedFragment is what a reason of the plain rule quotes of the words it refused, at its end.
|
||||||
|
var quotedFragment = regexp.MustCompile(` \([^()]*\)$`)
|
||||||
|
|
||||||
// The plain rule's shapes.
|
// The plain rule's shapes.
|
||||||
var (
|
var (
|
||||||
hexID = regexp.MustCompile(`\b[0-9a-f]{7,40}\b`)
|
hexID = regexp.MustCompile(`\b[0-9a-f]{7,40}\b`)
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -256,18 +255,28 @@ func TestBorrowedWordsAreLogged(t *testing.T) {
|
|||||||
before := Unworded
|
before := Unworded
|
||||||
Unworded = nil
|
Unworded = nil
|
||||||
t.Cleanup(func() { Unworded = before })
|
t.Cleanup(func() { Unworded = before })
|
||||||
|
loggedUnworded.Clear()
|
||||||
|
t.Cleanup(loggedUnworded.Clear)
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
|
writer := log.Writer()
|
||||||
log.SetOutput(&out)
|
log.SetOutput(&out)
|
||||||
t.Cleanup(func() { log.SetOutput(os.Stderr) })
|
t.Cleanup(func() { log.SetOutput(writer) })
|
||||||
for i := 0; i < 3; i++ {
|
// A time that changes each observation, and a hash-shaped word: one line, quoting neither.
|
||||||
|
for _, at := range []string{"23:32", "23:33", "23:34"} {
|
||||||
if _, err := k.Observe(t.Context(), Observation{Scope: ScopeMachine, ID: "ace", Kind: "test-clock", Machine: "ace",
|
if _, err := k.Observe(t.Context(), Observation{Scope: ScopeMachine, ID: "ace", Kind: "test-clock", Machine: "ace",
|
||||||
Severity: Warning, Source: "test", Summary: "s", Headline: "ace was given a secret",
|
Severity: Warning, Source: "test", Summary: "s", Headline: "ace was given a secret",
|
||||||
Explanation: "It was given at 23:32.", Resolved: "Seen"}); err != nil {
|
Explanation: "It was given at " + at + ".", Resolved: "Seen"}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if got := out.String(); strings.Count(got, "\n") != 1 || !strings.Contains(got, `"test-clock"`) ||
|
if _, err := k.Observe(t.Context(), Observation{Scope: ScopeMachine, ID: "ace", Kind: "test-hash", Machine: "ace",
|
||||||
!strings.Contains(got, "a clock time or date") {
|
Severity: Warning, Source: "test", Summary: "s", Headline: "ace was given 0123abcd4567ef89",
|
||||||
|
Explanation: "It was given.", Resolved: "Seen"}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if got := out.String(); strings.Count(got, "\n") != 2 || !strings.Contains(got, `"test-clock"`) ||
|
||||||
|
!strings.Contains(got, "a clock time or date") || strings.Contains(got, "23:3") ||
|
||||||
|
!strings.Contains(got, `"test-hash"`) || strings.Contains(got, "0123abcd4567ef89") {
|
||||||
t.Errorf("the log said %q", got)
|
t.Errorf("the log said %q", got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user