Files
Evans Mungai 53113c0170 feat: goldpinger collector and analyser (#1398)
* 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
2023-12-12 11:02:41 +00:00

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
}