Skip to content

Commit 009829c

Browse files
Merge pull request #577 from nachtmaar/template-textanalyzer-message
Template message in outcome block when using textAnalyzer
2 parents 374a655 + 4404849 commit 009829c

File tree

2 files changed

+136
-3
lines changed

2 files changed

+136
-3
lines changed

pkg/analyze/text_analyze.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package analyzer
22

33
import (
4+
"bytes"
45
"fmt"
56
"path/filepath"
67
"regexp"
78
"strconv"
89
"strings"
10+
"text/template"
911

1012
"github.com/pkg/errors"
1113
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
@@ -169,7 +171,11 @@ func analyzeRegexGroups(pattern string, collected []byte, outcomes []*troublesho
169171

170172
if isMatch {
171173
result.IsFail = true
172-
result.Message = outcome.Fail.Message
174+
tplMessage, err := templateRegExGroup(outcome.Fail.Message, foundMatches)
175+
if err != nil {
176+
return result, errors.Wrap(err, "failed to template message in outcome.Fail block")
177+
}
178+
result.Message = tplMessage
173179
result.URI = outcome.Fail.URI
174180

175181
return result, nil
@@ -182,7 +188,11 @@ func analyzeRegexGroups(pattern string, collected []byte, outcomes []*troublesho
182188

183189
if isMatch {
184190
result.IsWarn = true
185-
result.Message = outcome.Warn.Message
191+
tplMessage, err := templateRegExGroup(outcome.Warn.Message, foundMatches)
192+
if err != nil {
193+
return result, errors.Wrap(err, "failed to template message in outcome.Warn block")
194+
}
195+
result.Message = tplMessage
186196
result.URI = outcome.Warn.URI
187197

188198
return result, nil
@@ -195,7 +205,11 @@ func analyzeRegexGroups(pattern string, collected []byte, outcomes []*troublesho
195205

196206
if isMatch {
197207
result.IsPass = true
198-
result.Message = outcome.Pass.Message
208+
tplMessage, err := templateRegExGroup(outcome.Pass.Message, foundMatches)
209+
if err != nil {
210+
return result, errors.Wrap(err, "failed to template message in outcome.Pass block")
211+
}
212+
result.Message = tplMessage
199213
result.URI = outcome.Pass.URI
200214

201215
return result, nil
@@ -206,6 +220,20 @@ func analyzeRegexGroups(pattern string, collected []byte, outcomes []*troublesho
206220
return result, nil
207221
}
208222

223+
// templateRegExGroup takes a tpl and replaces the variables using matches.
224+
func templateRegExGroup(tpl string, matches map[string]string) (string, error) {
225+
t, err := template.New("").Parse(tpl)
226+
if err != nil {
227+
return "", err
228+
}
229+
var msg bytes.Buffer
230+
err = t.Execute(&msg, matches)
231+
if err != nil {
232+
return "", err
233+
}
234+
return msg.String(), nil
235+
}
236+
209237
func compareRegex(conditional string, foundMatches map[string]string) (bool, error) {
210238
if conditional == "" {
211239
return true, nil

pkg/analyze/text_analyze_test.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,111 @@ func Test_textAnalyze(t *testing.T) {
477477
"text-collector-1/cfile-1.txt": []byte("value: 2\nother: 10"),
478478
},
479479
},
480+
// This test ensures that the Outcomes.Pass.Message can be templated using the findings of the regular expression groups.
481+
{
482+
name: "Outcome pass message is templated with regex groups",
483+
analyzer: troubleshootv1beta2.TextAnalyze{
484+
Outcomes: []*troubleshootv1beta2.Outcome{
485+
{
486+
Pass: &troubleshootv1beta2.SingleOutcome{
487+
When: `Feature == insert-feature-name-here`,
488+
Message: "Feature {{ .Feature }} is enabled for CR {{ .CRName }} in namespace {{ .Namespace }}",
489+
},
490+
},
491+
},
492+
CollectorName: "text-collector-templated-regex-message",
493+
FileName: "cfile-1.txt",
494+
RegexGroups: `"name":\s*"(?P<CRName>.*?)".*namespace":\s*"(?P<Namespace>.*?)".*feature":\s*.*"(?P<Feature>insert-feature-name-here.*?)"`,
495+
},
496+
expectResult: []AnalyzeResult{
497+
{
498+
IsPass: true,
499+
IsWarn: false,
500+
IsFail: false,
501+
Title: "text-collector-templated-regex-message",
502+
Message: "Feature insert-feature-name-here is enabled for CR insert-cr-name-here in namespace default",
503+
IconKey: "kubernetes_text_analyze",
504+
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg?w=13&h=16",
505+
},
506+
},
507+
files: map[string][]byte{
508+
"text-collector-templated-regex-message/cfile-1.txt": []byte(`{"level":"INFO","timestamp":"2022-05-17T20:37:41Z","caller":"controller/controller.go:317","message":"Feature enabled","context":{"name":"insert-cr-name-here","namespace":"default","feature":"insert-feature-name-here"}}`),
509+
},
510+
},
511+
// This test ensures that the Outcomes.Warn.Message can be templated using the findings of the regular expression groups.
512+
{
513+
name: "Outcome warn message is templated with regex groups",
514+
analyzer: troubleshootv1beta2.TextAnalyze{
515+
Outcomes: []*troubleshootv1beta2.Outcome{
516+
{
517+
Pass: &troubleshootv1beta2.SingleOutcome{
518+
When: `Warning == ""`,
519+
Message: "No warning found",
520+
},
521+
},
522+
// The Warn case is triggered if warning != ""
523+
{
524+
Warn: &troubleshootv1beta2.SingleOutcome{
525+
Message: "Warning for CR with name {{ .CRName }} in namespace {{ .Namespace }}",
526+
},
527+
},
528+
},
529+
CollectorName: "text-collector-templated-regex-message",
530+
FileName: "cfile-1.txt",
531+
RegexGroups: `"name":\s*"(?P<CRName>.*?)".*namespace":\s*"(?P<Namespace>.*?)".*warning":\s*.*"(?P<Error>mywarning.*?)"`,
532+
},
533+
expectResult: []AnalyzeResult{
534+
{
535+
IsPass: false,
536+
IsWarn: true,
537+
IsFail: false,
538+
Title: "text-collector-templated-regex-message",
539+
Message: "Warning for CR with name insert-cr-name-here in namespace default",
540+
IconKey: "kubernetes_text_analyze",
541+
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg?w=13&h=16",
542+
},
543+
},
544+
files: map[string][]byte{
545+
"text-collector-templated-regex-message/cfile-1.txt": []byte(`{"level":"WARN","timestamp":"2022-05-17T20:37:41Z","caller":"controller/controller.go:317","message":"Reconciler error","context":{"name":"insert-cr-name-here","namespace":"default","warning":"mywarning"}}`),
546+
},
547+
},
548+
// This test ensures that the Outcomes.Fail.Message can be templated using the findings of the regular expression groups.
549+
{
550+
name: "Outcome fail message is templated with regex groups",
551+
analyzer: troubleshootv1beta2.TextAnalyze{
552+
Outcomes: []*troubleshootv1beta2.Outcome{
553+
{
554+
Pass: &troubleshootv1beta2.SingleOutcome{
555+
When: `Error == ""`,
556+
Message: "No error found",
557+
},
558+
},
559+
// The Fail case is triggered if warning != ""
560+
{
561+
Fail: &troubleshootv1beta2.SingleOutcome{
562+
Message: "Error for CR with name {{ .CRName }} in namespace {{ .Namespace }}",
563+
},
564+
},
565+
},
566+
CollectorName: "text-collector-templated-regex-message",
567+
FileName: "cfile-1.txt",
568+
RegexGroups: `"name":\s*"(?P<CRName>.*?)".*namespace":\s*"(?P<Namespace>.*?)".*error":\s*.*"(?P<Error>myerror.*?)"`,
569+
},
570+
expectResult: []AnalyzeResult{
571+
{
572+
IsPass: false,
573+
IsWarn: false,
574+
IsFail: true,
575+
Title: "text-collector-templated-regex-message",
576+
Message: "Error for CR with name insert-cr-name-here in namespace default",
577+
IconKey: "kubernetes_text_analyze",
578+
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg?w=13&h=16",
579+
},
580+
},
581+
files: map[string][]byte{
582+
"text-collector-templated-regex-message/cfile-1.txt": []byte(`{"level":"ERROR","timestamp":"2022-05-17T20:37:41Z","caller":"controller/controller.go:317","message":"Reconciler error","context":{"name":"insert-cr-name-here","namespace":"default","error":"myerror"}}`),
583+
},
584+
},
480585
}
481586

482587
for _, test := range tests {

0 commit comments

Comments
 (0)