diff --git a/config/crds/troubleshoot.sh_analyzers.yaml b/config/crds/troubleshoot.sh_analyzers.yaml index 42bd1a19d..680e60d6d 100644 --- a/config/crds/troubleshoot.sh_analyzers.yaml +++ b/config/crds/troubleshoot.sh_analyzers.yaml @@ -616,6 +616,7 @@ spec: required: - collectorName - outcomes + - reason type: object goldpinger: properties: diff --git a/config/crds/troubleshoot.sh_preflights.yaml b/config/crds/troubleshoot.sh_preflights.yaml index 50f30a2ae..1663d2026 100644 --- a/config/crds/troubleshoot.sh_preflights.yaml +++ b/config/crds/troubleshoot.sh_preflights.yaml @@ -616,6 +616,7 @@ spec: required: - collectorName - outcomes + - reason type: object goldpinger: properties: diff --git a/config/crds/troubleshoot.sh_supportbundles.yaml b/config/crds/troubleshoot.sh_supportbundles.yaml index 8a4c81fb7..6e2e66ac8 100644 --- a/config/crds/troubleshoot.sh_supportbundles.yaml +++ b/config/crds/troubleshoot.sh_supportbundles.yaml @@ -647,6 +647,7 @@ spec: required: - collectorName - outcomes + - reason type: object goldpinger: properties: diff --git a/pkg/analyze/event.go b/pkg/analyze/event.go index bda910279..b3aabf9e6 100644 --- a/pkg/analyze/event.go +++ b/pkg/analyze/event.go @@ -1,12 +1,14 @@ package analyzer import ( + "bytes" "encoding/json" "fmt" "path" "regexp" "strconv" "strings" + "text/template" "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" @@ -40,6 +42,11 @@ func (a *AnalyzeEvent) IsExcluded() (bool, error) { } func (a *AnalyzeEvent) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + // required check + if a.analyzer.Reason == "" { + return nil, errors.New("reason is required") + } + // read collected events based on namespace namespace := getNamespace(a.analyzer.Namespace) fullPath := path.Join(constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_EVENTS, namespace) @@ -191,6 +198,21 @@ func decorateMessage(message string, event *corev1.Event) string { if event == nil { return message } - out := fmt.Sprintf("%s. Name: %s Message: %s", message, event.InvolvedObject.Name, event.Message) - return out + out := fmt.Sprintf("Event matched. Reason: %s Name: %s Message: %s", event.Reason, event.InvolvedObject.Name, event.Message) + + tmpl := template.New("event") + msgTmpl, err := tmpl.Parse(message) + if err != nil { + klog.V(2).Infof("failed to parse message template: %v", err) + return out + } + + var m bytes.Buffer + err = msgTmpl.Execute(&m, event) + if err != nil { + klog.V(2).Infof("failed to render message template: %v", err) + return out + } + + return strings.TrimSpace(m.String()) } diff --git a/pkg/analyze/event_test.go b/pkg/analyze/event_test.go index 3cdd5e66f..fcb60f090 100644 --- a/pkg/analyze/event_test.go +++ b/pkg/analyze/event_test.go @@ -15,7 +15,55 @@ func TestAnalyzeEvent(t *testing.T) { analyzer troubleshootv1beta2.EventAnalyze expectResult []AnalyzeResult files map[string][]byte + err error }{ + { + name: "reason is required", + analyzer: troubleshootv1beta2.EventAnalyze{ + CollectorName: "event-collector-0", + Kind: "Pod", + Namespace: "default", + Outcomes: []*troubleshootv1beta2.Outcome{ + { + Fail: &troubleshootv1beta2.SingleOutcome{ + When: "true", + Message: "test", + }, + }, + }, + }, + err: errors.New("reason is required"), + files: map[string][]byte{ + "cluster-resources/events/default.json": []byte(` + { + "kind": "EventList", + "apiVersion": "v1", + "metadata": { + "resourceVersion": "722" + }, + "items": [ + { + "kind": "Event", + "apiVersion": "v1", + "metadata": { + "name": "nginx-rc", + "namespace": "default", + "creationTimestamp": "2022-01-01T00:00:00Z" + }, + "involvedObject": { + "kind": "Pod", + "name": "nginx-rc-12345", + "namespace": "default" + }, + "reason": "OOMKilled", + "message": "The container was killed due to an out-of-memory condition.", + "type": "Warning" + } + ] + } + `), + }, + }, { name: "fail when OOMKilled event is present", analyzer: troubleshootv1beta2.EventAnalyze{ @@ -27,7 +75,7 @@ func TestAnalyzeEvent(t *testing.T) { { Fail: &troubleshootv1beta2.SingleOutcome{ When: "true", - Message: "OOMKilled event detected", + Message: "Detect OOMKilled event with {{ .InvolvedObject.Kind }}-{{ .InvolvedObject.Name }} with message {{ .Message }}", }, Pass: &troubleshootv1beta2.SingleOutcome{ When: "false", @@ -44,7 +92,7 @@ func TestAnalyzeEvent(t *testing.T) { IsFail: true, IsWarn: false, IsPass: false, - Message: "OOMKilled event detected. Name: nginx-rc-12345 Message: The container was killed due to an out-of-memory condition.", + Message: "Detect OOMKilled event with Pod-nginx-rc-12345 with message The container was killed due to an out-of-memory condition.", }, }, files: map[string][]byte{ @@ -174,8 +222,12 @@ func TestAnalyzeEvent(t *testing.T) { analyzer: &test.analyzer, } actual, err := a.Analyze(getFile, findFiles) - req.NoError(err) + if test.err != nil { + req.EqualError(err, test.err.Error()) + return + } + req.NoError(err) unPointered := []AnalyzeResult{} for _, v := range actual { unPointered = append(unPointered, *v) diff --git a/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go b/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go index 05a28a8fa..0ecfd7a2e 100644 --- a/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/analyzer_shared.go @@ -237,7 +237,7 @@ type EventAnalyze struct { CollectorName string `json:"collectorName" yaml:"collectorName"` Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` - Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Reason string `json:"reason" yaml:"reason"` RegexPattern string `json:"regex,omitempty" yaml:"regex,omitempty"` Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"` } diff --git a/schemas/analyzer-troubleshoot-v1beta2.json b/schemas/analyzer-troubleshoot-v1beta2.json index bd7159eb3..07cdce604 100644 --- a/schemas/analyzer-troubleshoot-v1beta2.json +++ b/schemas/analyzer-troubleshoot-v1beta2.json @@ -828,7 +828,8 @@ "type": "object", "required": [ "collectorName", - "outcomes" + "outcomes", + "reason" ], "properties": { "annotations": { diff --git a/schemas/preflight-troubleshoot-v1beta2.json b/schemas/preflight-troubleshoot-v1beta2.json index b5651cf01..aac4e0b5b 100644 --- a/schemas/preflight-troubleshoot-v1beta2.json +++ b/schemas/preflight-troubleshoot-v1beta2.json @@ -828,7 +828,8 @@ "type": "object", "required": [ "collectorName", - "outcomes" + "outcomes", + "reason" ], "properties": { "annotations": { diff --git a/schemas/supportbundle-troubleshoot-v1beta2.json b/schemas/supportbundle-troubleshoot-v1beta2.json index ffb6fd0d9..b7677aa60 100644 --- a/schemas/supportbundle-troubleshoot-v1beta2.json +++ b/schemas/supportbundle-troubleshoot-v1beta2.json @@ -874,7 +874,8 @@ "type": "object", "required": [ "collectorName", - "outcomes" + "outcomes", + "reason" ], "properties": { "annotations": {