mirror of
https://github.com/replicatedhq/troubleshoot.git
synced 2026-04-15 07:16:34 +00:00
* feat: goldpinger analyser Analyser to generate a report from goldpinger results * Add goldpinger testdata * Goldpinger collector * Improvements after running tests * More minor updates after further testing * Better error message if a container fails to start * A few more updates * Add goldpinger e2e test * Update schemas * Clean up help installs in e2e tests * Add resource limits to goldpinger pods * Some minor improvements * Some more changes noted when writing docs * Update schemas * A few more updates when testing with kURL * Log goldpinger tests * Tests before exit code
136 lines
3.7 KiB
Go
136 lines
3.7 KiB
Go
package analyzer
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/pkg/errors"
|
|
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
|
"github.com/replicatedhq/troubleshoot/pkg/constants"
|
|
)
|
|
|
|
type AnalyzeGoldpinger struct {
|
|
analyzer *troubleshootv1beta2.GoldpingerAnalyze
|
|
}
|
|
|
|
type checkAllOutput struct {
|
|
Hosts []struct {
|
|
HostIP string `json:"hostIP"`
|
|
PodIP string `json:"podIP"`
|
|
PodName string `json:"podName"`
|
|
} `json:"hosts"`
|
|
Responses map[string]struct {
|
|
HostIP string `json:"hostIP"`
|
|
PodIP string `json:"podIP"`
|
|
OK bool `json:"OK"`
|
|
Response struct {
|
|
PodResults map[string]struct {
|
|
HostIP string `json:"hostIP"`
|
|
OK bool `json:"OK"`
|
|
PingTime string `json:"pingTime"`
|
|
PodIP string `json:"podIP"`
|
|
Response struct {
|
|
BootTime string `json:"boot_time"`
|
|
} `json:"response"`
|
|
Error string `json:"error"`
|
|
ResponseTimeMS int `json:"response-time-ms"`
|
|
StatusCode int `json:"status-code"`
|
|
} `json:"podResults"`
|
|
} `json:"response"`
|
|
} `json:"responses"`
|
|
}
|
|
|
|
func (a *AnalyzeGoldpinger) Title() string {
|
|
title := a.analyzer.CheckName
|
|
if title == "" {
|
|
title = a.collectorName()
|
|
}
|
|
|
|
return title
|
|
}
|
|
|
|
func (a *AnalyzeGoldpinger) IsExcluded() (bool, error) {
|
|
return isExcluded(a.analyzer.Exclude)
|
|
}
|
|
|
|
func (a *AnalyzeGoldpinger) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
|
|
caoFilePath := constants.GP_CHECK_ALL_RESULTS_PATH
|
|
// To allow analysing older support bundles, we can provide a custom file path
|
|
if a.analyzer.FilePath != "" {
|
|
caoFilePath = a.analyzer.FilePath
|
|
}
|
|
|
|
collected, err := getFile(caoFilePath)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "failed to read collected file path: %q", caoFilePath)
|
|
}
|
|
|
|
var cao checkAllOutput
|
|
err = json.Unmarshal(collected, &cao)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to unmarshal collected goldpinger output")
|
|
}
|
|
|
|
return a.podPingsAnalysis(&cao), nil
|
|
}
|
|
|
|
func (a *AnalyzeGoldpinger) collectorName() string {
|
|
if a.analyzer.CollectorName != "" {
|
|
return a.analyzer.CollectorName
|
|
}
|
|
return "goldpinger"
|
|
}
|
|
|
|
func (a *AnalyzeGoldpinger) podPingsAnalysis(cao *checkAllOutput) []*AnalyzeResult {
|
|
results := []*AnalyzeResult{}
|
|
|
|
for _, host := range cao.Hosts {
|
|
// Check if the pod from a host has any ping errors from other pods
|
|
targetPod := host.PodName
|
|
pingsSucceeded := true
|
|
for srcPod, resp := range cao.Responses {
|
|
res := &AnalyzeResult{
|
|
IconKey: "kubernetes",
|
|
Strict: a.analyzer.Strict.BoolOrDefaultFalse(),
|
|
}
|
|
|
|
// Get ping result for the pod
|
|
podResult, ok := resp.Response.PodResults[targetPod]
|
|
if !ok {
|
|
// Pod not found in ping results from the source pod
|
|
res.IsWarn = true
|
|
res.Title = fmt.Sprintf("Missing ping results for %q pod", targetPod)
|
|
res.Message = fmt.Sprintf("Ping result for %q pod from %q pod is missing", targetPod, srcPod)
|
|
pingsSucceeded = false
|
|
|
|
results = append(results, res)
|
|
continue
|
|
}
|
|
|
|
if !podResult.OK {
|
|
// Ping was not successful
|
|
res.IsFail = true
|
|
res.Title = fmt.Sprintf("Ping from %q pod to %q pod failed", srcPod, targetPod)
|
|
res.Message = fmt.Sprintf("Ping error: %s", podResult.Error)
|
|
pingsSucceeded = false
|
|
|
|
results = append(results, res)
|
|
continue
|
|
}
|
|
}
|
|
|
|
// If all pings succeeded, add a pass result
|
|
if pingsSucceeded {
|
|
results = append(results, &AnalyzeResult{
|
|
IconKey: "kubernetes",
|
|
Strict: a.analyzer.Strict.BoolOrDefaultFalse(),
|
|
IsPass: true,
|
|
Title: fmt.Sprintf("Pings to %q pod succeeded", targetPod),
|
|
Message: fmt.Sprintf("Pings to %q pod from all other pods in the cluster succeeded", targetPod),
|
|
})
|
|
}
|
|
}
|
|
|
|
return results
|
|
}
|