mirror of
https://github.com/replicatedhq/troubleshoot.git
synced 2026-09-03 00:47:17 +00:00
Merge pull request #334 from replicatedhq/host-preflgihts-ux
Host preflight ux improvements
This commit is contained in:
@@ -93,6 +93,7 @@ func runPreflights(v *viper.Viper, arg string) error {
|
||||
|
||||
s := spin.New()
|
||||
go func() {
|
||||
lastMsg := ""
|
||||
for {
|
||||
select {
|
||||
case msg, ok := <-progressCh:
|
||||
@@ -104,6 +105,10 @@ func runPreflights(v *viper.Viper, arg string) error {
|
||||
c := color.New(color.FgHiRed)
|
||||
c.Println(fmt.Sprintf("%s\r * %v", cursor.ClearEntireLine(), msg))
|
||||
case string:
|
||||
if lastMsg == msg {
|
||||
break
|
||||
}
|
||||
lastMsg = msg
|
||||
c := color.New(color.FgCyan)
|
||||
c.Println(fmt.Sprintf("%s\r * %s", cursor.ClearEntireLine(), msg))
|
||||
}
|
||||
|
||||
+23
-92
@@ -1,6 +1,7 @@
|
||||
package analyzer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -40,100 +41,30 @@ func isExcluded(excludeVal multitype.BoolOrString) (bool, error) {
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
func HostAnalyze(hostAnalyzer *troubleshootv1beta2.HostAnalyze, getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
|
||||
if hostAnalyzer.CPU != nil {
|
||||
result, err := analyzeHostCPU(hostAnalyzer.CPU, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.TCPLoadBalancer != nil {
|
||||
result, err := analyzeHostTCPLoadBalancer(hostAnalyzer.TCPLoadBalancer, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.HTTPLoadBalancer != nil {
|
||||
result, err := analyzeHostHTTPLoadBalancer(hostAnalyzer.HTTPLoadBalancer, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.DiskUsage != nil {
|
||||
result, err := analyzeHostDiskUsage(hostAnalyzer.DiskUsage, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.Memory != nil {
|
||||
result, err := analyzeHostMemory(hostAnalyzer.Memory, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.TCPPortStatus != nil {
|
||||
result, err := analyzeHostTCPPortStatus(hostAnalyzer.TCPPortStatus, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.HTTP != nil {
|
||||
result, err := analyzeHostHTTP(hostAnalyzer.HTTP, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.Time != nil {
|
||||
result, err := analyzeHostTime(hostAnalyzer.Time, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.BlockDevices != nil {
|
||||
result, err := analyzeHostBlockDevices(hostAnalyzer.BlockDevices, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.TCPConnect != nil {
|
||||
result, err := analyzeHostTCPConnect(hostAnalyzer.TCPConnect, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.IPV4Interfaces != nil {
|
||||
result, err := analyzeHostIPV4Interfaces(hostAnalyzer.IPV4Interfaces, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.FilesystemPerformance != nil {
|
||||
result, err := analyzeHostFilesystemPerformance(hostAnalyzer.FilesystemPerformance, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
}
|
||||
if hostAnalyzer.Certificate != nil {
|
||||
result, err := analyzeHostCertificate(hostAnalyzer.Certificate, getFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []*AnalyzeResult{result}, nil
|
||||
func HostAnalyze(hostAnalyzer *troubleshootv1beta2.HostAnalyze, getFile getCollectedFileContents, findFiles getChildCollectedFileContents) []*AnalyzeResult {
|
||||
analyzer, ok := GetHostAnalyzer(hostAnalyzer)
|
||||
if !ok {
|
||||
return NewAnalyzeResultError(analyzer, errors.New("invalid analyzer"))
|
||||
}
|
||||
|
||||
return nil, errors.New("invalid analyzer")
|
||||
isExcluded, _ := analyzer.IsExcluded()
|
||||
if isExcluded {
|
||||
return nil
|
||||
}
|
||||
|
||||
result, err := analyzer.Analyze(getFile)
|
||||
if err != nil {
|
||||
return NewAnalyzeResultError(analyzer, errors.Wrap(err, "analyze"))
|
||||
}
|
||||
return []*AnalyzeResult{result}
|
||||
}
|
||||
|
||||
func NewAnalyzeResultError(analyzer HostAnalyzer, err error) []*AnalyzeResult {
|
||||
return []*AnalyzeResult{{
|
||||
IsFail: true,
|
||||
Title: analyzer.Title(),
|
||||
Message: fmt.Sprintf("Analyzer Failed: %v", err),
|
||||
}}
|
||||
}
|
||||
|
||||
func Analyze(analyzer *troubleshootv1beta2.Analyze, getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package analyzer
|
||||
|
||||
import troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
|
||||
type HostAnalyzer interface {
|
||||
Title() string
|
||||
IsExcluded() (bool, error)
|
||||
Analyze(getFile func(string) ([]byte, error)) (*AnalyzeResult, error)
|
||||
}
|
||||
|
||||
func GetHostAnalyzer(analyzer *troubleshootv1beta2.HostAnalyze) (HostAnalyzer, bool) {
|
||||
switch {
|
||||
case analyzer.CPU != nil:
|
||||
return &AnalyzeHostCPU{analyzer.CPU}, true
|
||||
case analyzer.Memory != nil:
|
||||
return &AnalyzeHostMemory{analyzer.Memory}, true
|
||||
case analyzer.TCPLoadBalancer != nil:
|
||||
return &AnalyzeHostTCPLoadBalancer{analyzer.TCPLoadBalancer}, true
|
||||
case analyzer.HTTPLoadBalancer != nil:
|
||||
return &AnalyzeHostHTTPLoadBalancer{analyzer.HTTPLoadBalancer}, true
|
||||
case analyzer.DiskUsage != nil:
|
||||
return &AnalyzeHostDiskUsage{analyzer.DiskUsage}, true
|
||||
case analyzer.TCPPortStatus != nil:
|
||||
return &AnalyzeHostTCPPortStatus{analyzer.TCPPortStatus}, true
|
||||
case analyzer.HTTP != nil:
|
||||
return &AnalyzeHostHTTP{analyzer.HTTP}, true
|
||||
case analyzer.Time != nil:
|
||||
return &AnalyzeHostTime{analyzer.Time}, true
|
||||
case analyzer.BlockDevices != nil:
|
||||
return &AnalyzeHostBlockDevices{analyzer.BlockDevices}, true
|
||||
case analyzer.TCPConnect != nil:
|
||||
return &AnalyzeHostTCPConnect{analyzer.TCPConnect}, true
|
||||
case analyzer.IPV4Interfaces != nil:
|
||||
return &AnalyzeHostIPV4Interfaces{analyzer.IPV4Interfaces}, true
|
||||
case analyzer.FilesystemPerformance != nil:
|
||||
return &AnalyzeHostFilesystemPerformance{analyzer.FilesystemPerformance}, true
|
||||
case analyzer.Certificate != nil:
|
||||
return &AnalyzeHostCertificate{analyzer.Certificate}, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func hostAnalyzerTitleOrDefault(meta troubleshootv1beta2.AnalyzeMeta, defaultTitle string) string {
|
||||
if meta.CheckName != "" {
|
||||
return meta.CheckName
|
||||
}
|
||||
return defaultTitle
|
||||
}
|
||||
@@ -12,7 +12,21 @@ import (
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
)
|
||||
|
||||
func analyzeHostBlockDevices(hostAnalyzer *troubleshootv1beta2.BlockDevicesAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostBlockDevices struct {
|
||||
hostAnalyzer *troubleshootv1beta2.BlockDevicesAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostBlockDevices) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Block Devices")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostBlockDevices) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostBlockDevices) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
contents, err := getCollectedFileContents("system/block_devices.json")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get collected file")
|
||||
@@ -25,11 +39,7 @@ func analyzeHostBlockDevices(hostAnalyzer *troubleshootv1beta2.BlockDevicesAnaly
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "Block Devices"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -162,7 +162,7 @@ func TestAnalyzeBlockDevices(t *testing.T) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
result, err := analyzeHostBlockDevices(test.hostAnalyzer, getCollectedFileContents)
|
||||
result, err := (&AnalyzeHostBlockDevices{test.hostAnalyzer}).Analyze(getCollectedFileContents)
|
||||
if test.expectErr {
|
||||
req.Error(err)
|
||||
} else {
|
||||
|
||||
@@ -7,7 +7,21 @@ import (
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func analyzeHostCertificate(hostAnalyzer *troubleshootv1beta2.CertificateAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostCertificate struct {
|
||||
hostAnalyzer *troubleshootv1beta2.CertificateAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostCertificate) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Certificate Key Pair")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostCertificate) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostCertificate) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
collectorName := hostAnalyzer.CollectorName
|
||||
if collectorName == "" {
|
||||
collectorName = "certificate"
|
||||
@@ -21,11 +35,7 @@ func analyzeHostCertificate(hostAnalyzer *troubleshootv1beta2.CertificateAnalyze
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "Certificate Key Pair"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -320,7 +320,7 @@ func TestAnalyzeCertificate(t *testing.T) {
|
||||
return []byte(test.status), nil
|
||||
}
|
||||
|
||||
result, err := analyzeHostCertificate(test.hostAnalyzer, getCollectedFileContents)
|
||||
result, err := (&AnalyzeHostCertificate{test.hostAnalyzer}).Analyze(getCollectedFileContents)
|
||||
if test.expectErr {
|
||||
req.Error(err)
|
||||
} else {
|
||||
|
||||
+16
-6
@@ -10,7 +10,21 @@ import (
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
)
|
||||
|
||||
func analyzeHostCPU(hostAnalyzer *troubleshootv1beta2.CPUAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostCPU struct {
|
||||
hostAnalyzer *troubleshootv1beta2.CPUAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostCPU) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Number of CPUs")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostCPU) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostCPU) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
contents, err := getCollectedFileContents("system/cpu.json")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get collected file")
|
||||
@@ -23,11 +37,7 @@ func analyzeHostCPU(hostAnalyzer *troubleshootv1beta2.CPUAnalyze, getCollectedFi
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "Number of CPUs"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -12,7 +12,21 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
func analyzeHostDiskUsage(hostAnalyzer *troubleshootv1beta2.DiskUsageAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostDiskUsage struct {
|
||||
hostAnalyzer *troubleshootv1beta2.DiskUsageAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostDiskUsage) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, fmt.Sprintf("Disk Usage %s", a.hostAnalyzer.CollectorName))
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostDiskUsage) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostDiskUsage) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
key := collect.HostDiskUsageKey(hostAnalyzer.CollectorName)
|
||||
contents, err := getCollectedFileContents(key)
|
||||
if err != nil {
|
||||
@@ -26,11 +40,7 @@ func analyzeHostDiskUsage(hostAnalyzer *troubleshootv1beta2.DiskUsageAnalyze, ge
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = fmt.Sprintf("Disk Usage %s", hostAnalyzer.CollectorName)
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -367,7 +367,7 @@ func TestAnalyzeHostDiskUsage(t *testing.T) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
result, err := analyzeHostDiskUsage(test.hostAnalyzer, getCollectedFileContents)
|
||||
result, err := (&AnalyzeHostDiskUsage{test.hostAnalyzer}).Analyze(getCollectedFileContents)
|
||||
if test.expectErr {
|
||||
req.Error(err)
|
||||
} else {
|
||||
|
||||
@@ -13,7 +13,21 @@ import (
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
)
|
||||
|
||||
func analyzeHostFilesystemPerformance(hostAnalyzer *troubleshootv1beta2.FilesystemPerformanceAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostFilesystemPerformance struct {
|
||||
hostAnalyzer *troubleshootv1beta2.FilesystemPerformanceAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostFilesystemPerformance) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Filesystem Performance")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostFilesystemPerformance) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostFilesystemPerformance) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
collectorName := hostAnalyzer.CollectorName
|
||||
if collectorName == "" {
|
||||
collectorName = "filesystemPerformance"
|
||||
@@ -31,11 +45,7 @@ func analyzeHostFilesystemPerformance(hostAnalyzer *troubleshootv1beta2.Filesyst
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "Filesystem Performance"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -352,7 +352,7 @@ func TestAnalyzeHostFilesystemPerformance(t *testing.T) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
result, err := analyzeHostFilesystemPerformance(test.hostAnalyzer, getCollectedFileContents)
|
||||
result, err := (&AnalyzeHostFilesystemPerformance{test.hostAnalyzer}).Analyze(getCollectedFileContents)
|
||||
if test.expectErr {
|
||||
req.Error(err)
|
||||
} else {
|
||||
|
||||
@@ -17,7 +17,21 @@ type httpResult struct {
|
||||
Response *collect.HTTPResponse
|
||||
}
|
||||
|
||||
func analyzeHostHTTP(hostAnalyzer *troubleshootv1beta2.HTTPAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostHTTP struct {
|
||||
hostAnalyzer *troubleshootv1beta2.HTTPAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostHTTP) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "HTTP Request")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostHTTP) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostHTTP) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
name := filepath.Join("http", "result.json")
|
||||
if hostAnalyzer.CollectorName != "" {
|
||||
name = filepath.Join("http", hostAnalyzer.CollectorName+".json")
|
||||
@@ -34,11 +48,7 @@ func analyzeHostHTTP(hostAnalyzer *troubleshootv1beta2.HTTPAnalyze, getCollected
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "HTTP Request"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -91,7 +91,7 @@ func TestAnalyzeHostHTTP(t *testing.T) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
result, err := analyzeHostHTTP(test.hostAnalyzer, getCollectedFileContents)
|
||||
result, err := (&AnalyzeHostHTTP{test.hostAnalyzer}).Analyze(getCollectedFileContents)
|
||||
if test.expectErr {
|
||||
req.Error(err)
|
||||
} else {
|
||||
|
||||
@@ -10,7 +10,21 @@ import (
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
)
|
||||
|
||||
func analyzeHostHTTPLoadBalancer(hostAnalyzer *troubleshootv1beta2.HTTPLoadBalancerAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostHTTPLoadBalancer struct {
|
||||
hostAnalyzer *troubleshootv1beta2.HTTPLoadBalancerAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostHTTPLoadBalancer) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "HTTP Load Balancer")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostHTTPLoadBalancer) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostHTTPLoadBalancer) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
collectorName := hostAnalyzer.CollectorName
|
||||
if collectorName == "" {
|
||||
collectorName = "httpLoadBalancer"
|
||||
@@ -28,11 +42,7 @@ func analyzeHostHTTPLoadBalancer(hostAnalyzer *troubleshootv1beta2.HTTPLoadBalan
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "HTTP Load Balancer"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -11,7 +11,21 @@ import (
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func analyzeHostIPV4Interfaces(hostAnalyzer *troubleshootv1beta2.IPV4InterfacesAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostIPV4Interfaces struct {
|
||||
hostAnalyzer *troubleshootv1beta2.IPV4InterfacesAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostIPV4Interfaces) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "IPv4 Interfaces")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostIPV4Interfaces) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostIPV4Interfaces) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
contents, err := getCollectedFileContents("system/ipv4Interfaces.json")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get collected file")
|
||||
@@ -24,11 +38,7 @@ func analyzeHostIPV4Interfaces(hostAnalyzer *troubleshootv1beta2.IPV4InterfacesA
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "IPv4 Interfaces"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -88,7 +88,7 @@ func TestAnalyzeIPV4Interfaces(t *testing.T) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
result, err := analyzeHostIPV4Interfaces(test.hostAnalyzer, getCollectedFileContents)
|
||||
result, err := (&AnalyzeHostIPV4Interfaces{test.hostAnalyzer}).Analyze(getCollectedFileContents)
|
||||
if test.expectErr {
|
||||
req.Error(err)
|
||||
} else {
|
||||
|
||||
@@ -11,7 +11,21 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
func analyzeHostMemory(hostAnalyzer *troubleshootv1beta2.MemoryAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostMemory struct {
|
||||
hostAnalyzer *troubleshootv1beta2.MemoryAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostMemory) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Amount of Memory")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostMemory) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostMemory) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
contents, err := getCollectedFileContents("system/memory.json")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get collected file")
|
||||
@@ -24,11 +38,7 @@ func analyzeHostMemory(hostAnalyzer *troubleshootv1beta2.MemoryAnalyze, getColle
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "Amount of Memory"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -164,7 +164,7 @@ func TestAnalyzeHostMemory(t *testing.T) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
result, err := analyzeHostMemory(test.hostAnalyzer, getCollectedFileContents)
|
||||
result, err := (&AnalyzeHostMemory{test.hostAnalyzer}).Analyze(getCollectedFileContents)
|
||||
if test.expectErr {
|
||||
req.Error(err)
|
||||
} else {
|
||||
|
||||
@@ -10,7 +10,21 @@ import (
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
)
|
||||
|
||||
func analyzeHostTCPConnect(hostAnalyzer *troubleshootv1beta2.TCPConnectAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostTCPConnect struct {
|
||||
hostAnalyzer *troubleshootv1beta2.TCPConnectAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTCPConnect) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "TCP Connection Attempt")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTCPConnect) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTCPConnect) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
fullPath := path.Join("connect", fmt.Sprintf("%s.json", hostAnalyzer.CollectorName))
|
||||
|
||||
collected, err := getCollectedFileContents(fullPath)
|
||||
@@ -24,11 +38,7 @@ func analyzeHostTCPConnect(hostAnalyzer *troubleshootv1beta2.TCPConnectAnalyze,
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "TCP Connection Attempt"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -79,7 +79,7 @@ func TestAnalyzeTCPConnect(t *testing.T) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
result, err := analyzeHostTCPConnect(test.hostAnalyzer, getCollectedFileContents)
|
||||
result, err := (&AnalyzeHostTCPConnect{test.hostAnalyzer}).Analyze(getCollectedFileContents)
|
||||
if test.expectErr {
|
||||
req.Error(err)
|
||||
} else {
|
||||
|
||||
@@ -10,7 +10,21 @@ import (
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
)
|
||||
|
||||
func analyzeHostTCPLoadBalancer(hostAnalyzer *troubleshootv1beta2.TCPLoadBalancerAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostTCPLoadBalancer struct {
|
||||
hostAnalyzer *troubleshootv1beta2.TCPLoadBalancerAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTCPLoadBalancer) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "TCP Load Balancer")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTCPLoadBalancer) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTCPLoadBalancer) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
collectorName := hostAnalyzer.CollectorName
|
||||
if collectorName == "" {
|
||||
collectorName = "tcpLoadBalancer"
|
||||
@@ -29,11 +43,7 @@ func analyzeHostTCPLoadBalancer(hostAnalyzer *troubleshootv1beta2.TCPLoadBalance
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "TCP Load Balancer"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -10,7 +10,21 @@ import (
|
||||
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
||||
)
|
||||
|
||||
func analyzeHostTCPPortStatus(hostAnalyzer *troubleshootv1beta2.TCPPortStatusAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostTCPPortStatus struct {
|
||||
hostAnalyzer *troubleshootv1beta2.TCPPortStatusAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTCPPortStatus) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "TCP Port Status")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTCPPortStatus) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTCPPortStatus) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
fullPath := path.Join("tcpPortStatus", "tcpPortStatus.json")
|
||||
if hostAnalyzer.CollectorName != "" {
|
||||
fullPath = path.Join("tcpPortStatus", fmt.Sprintf("%s.json", hostAnalyzer.CollectorName))
|
||||
@@ -27,11 +41,7 @@ func analyzeHostTCPPortStatus(hostAnalyzer *troubleshootv1beta2.TCPPortStatusAna
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "TCP Port Status"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -17,7 +17,21 @@ const (
|
||||
UnsynchronizedInactive = "unsynchronized+inactive"
|
||||
)
|
||||
|
||||
func analyzeHostTime(hostAnalyzer *troubleshootv1beta2.TimeAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
type AnalyzeHostTime struct {
|
||||
hostAnalyzer *troubleshootv1beta2.TimeAnalyze
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTime) Title() string {
|
||||
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Time")
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTime) IsExcluded() (bool, error) {
|
||||
return isExcluded(a.hostAnalyzer.Exclude)
|
||||
}
|
||||
|
||||
func (a *AnalyzeHostTime) Analyze(getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
|
||||
hostAnalyzer := a.hostAnalyzer
|
||||
|
||||
contents, err := getCollectedFileContents("system/time.json")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get collected file")
|
||||
@@ -30,11 +44,7 @@ func analyzeHostTime(hostAnalyzer *troubleshootv1beta2.TimeAnalyze, getCollected
|
||||
|
||||
result := AnalyzeResult{}
|
||||
|
||||
title := hostAnalyzer.CheckName
|
||||
if title == "" {
|
||||
title = "Time"
|
||||
}
|
||||
result.Title = title
|
||||
result.Title = a.Title()
|
||||
|
||||
for _, outcome := range hostAnalyzer.Outcomes {
|
||||
if outcome.Fail != nil {
|
||||
|
||||
@@ -219,7 +219,7 @@ func TestAnalyzeHostTime(t *testing.T) {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
result, err := analyzeHostTime(test.hostAnalyzer, getCollectedFileContents)
|
||||
result, err := (&AnalyzeHostTime{test.hostAnalyzer}).Analyze(getCollectedFileContents)
|
||||
if test.expectErr {
|
||||
req.Error(err)
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package v1beta2
|
||||
|
||||
import "github.com/replicatedhq/troubleshoot/pkg/multitype"
|
||||
|
||||
type CPUAnalyze struct {
|
||||
AnalyzeMeta `json:",inline" yaml:",inline"`
|
||||
Outcomes []*Outcome `json:"outcomes" yaml:"outcomes"`
|
||||
@@ -100,6 +98,4 @@ type HostAnalyze struct {
|
||||
FilesystemPerformance *FilesystemPerformanceAnalyze `json:"filesystemPerformance,omitempty" yaml:"filesystemPerformance,omitempty"`
|
||||
|
||||
Certificate *CertificateAnalyze `json:"certificate,omitempty" yaml:"certificate,omitempty"`
|
||||
|
||||
Exclude multitype.BoolOrString `json:"exclude,omitempty" yaml:"exclude,omitempty"`
|
||||
}
|
||||
|
||||
@@ -103,7 +103,6 @@ type HostCollect struct {
|
||||
TCPConnect *TCPConnect `json:"tcpConnect,omitempty" yaml:"tcpConnect,omitempty"`
|
||||
FilesystemPerformance *FilesystemPerformance `json:"filesystemPerformance,omitempty" yaml:"filesystemPerformance,omitempty"`
|
||||
Certificate *Certificate `json:"certificate,omitempty" yaml:"certificate,omitempty"`
|
||||
Exclude multitype.BoolOrString `json:"exclude,omitempty" yaml:"exclude,omitempty"`
|
||||
}
|
||||
|
||||
func (c *HostCollect) GetName() string {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
type BlockDeviceInfo struct {
|
||||
@@ -28,7 +29,19 @@ type BlockDeviceInfo struct {
|
||||
const lsblkColumns = "NAME,KNAME,PKNAME,TYPE,MAJ:MIN,SIZE,FSTYPE,MOUNTPOINT,SERIAL,RO,RM"
|
||||
const lsblkFormat = `NAME=%q KNAME=%q PKNAME=%q TYPE=%q MAJ:MIN="%d:%d" SIZE="%d" FSTYPE=%q MOUNTPOINT=%q SERIAL=%q RO="%d" RM="%d0"`
|
||||
|
||||
func HostBlockDevices(c *HostCollector) (map[string][]byte, error) {
|
||||
type CollectHostBlockDevices struct {
|
||||
hostCollector *troubleshootv1beta2.HostBlockDevices
|
||||
}
|
||||
|
||||
func (c *CollectHostBlockDevices) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "Block Devices")
|
||||
}
|
||||
|
||||
func (c *CollectHostBlockDevices) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostBlockDevices) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
var devices []BlockDeviceInfo
|
||||
|
||||
cmd := exec.Command("lsblk", "--noheadings", "--bytes", "--pairs", "-o", lsblkColumns)
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
const KeyPairMissing = "key-pair-missing"
|
||||
@@ -15,10 +17,22 @@ const KeyPairMismatch = "key-pair-mismatch"
|
||||
const KeyPairInvalid = "key-pair-invalid"
|
||||
const KeyPairValid = "key-pair-valid"
|
||||
|
||||
func HostCertificate(c *HostCollector) (map[string][]byte, error) {
|
||||
type CollectHostCertificate struct {
|
||||
hostCollector *troubleshootv1beta2.Certificate
|
||||
}
|
||||
|
||||
func (c *CollectHostCertificate) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "Certificate Key Pair")
|
||||
}
|
||||
|
||||
func (c *CollectHostCertificate) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostCertificate) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
var result = KeyPairValid
|
||||
|
||||
_, err := tls.LoadX509KeyPair(c.Collect.Certificate.CertificatePath, c.Collect.Certificate.KeyPath)
|
||||
_, err := tls.LoadX509KeyPair(c.hostCollector.CertificatePath, c.hostCollector.KeyPath)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no such file") {
|
||||
result = KeyPairMissing
|
||||
@@ -29,7 +43,7 @@ func HostCertificate(c *HostCollector) (map[string][]byte, error) {
|
||||
} else if strings.Contains(err.Error(), "private key does not match public key") {
|
||||
result = KeyPairMismatch
|
||||
} else if strings.Contains(err.Error(), "failed to parse private key") {
|
||||
if encrypted, _ := isEncryptedKey(c.Collect.Certificate.KeyPath); encrypted {
|
||||
if encrypted, _ := isEncryptedKey(c.hostCollector.KeyPath); encrypted {
|
||||
result = KeyPairEncrypted
|
||||
} else {
|
||||
result = KeyPairInvalid
|
||||
@@ -39,7 +53,7 @@ func HostCertificate(c *HostCollector) (map[string][]byte, error) {
|
||||
}
|
||||
}
|
||||
|
||||
collectorName := c.Collect.Certificate.CollectorName
|
||||
collectorName := c.hostCollector.CollectorName
|
||||
if collectorName == "" {
|
||||
collectorName = "certificate"
|
||||
}
|
||||
|
||||
@@ -1,60 +1,51 @@
|
||||
package collect
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
type HostCollector struct {
|
||||
Collect *troubleshootv1beta2.HostCollect
|
||||
type HostCollector interface {
|
||||
Title() string
|
||||
IsExcluded() (bool, error)
|
||||
Collect(progressChan chan<- interface{}) (map[string][]byte, error)
|
||||
}
|
||||
|
||||
type HostCollectors []*HostCollector
|
||||
|
||||
func (c *HostCollector) RunCollectorSync() (result map[string][]byte, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = errors.Errorf("recovered rom panic: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
if c.Collect.CPU != nil {
|
||||
result, err = HostCPU(c)
|
||||
} else if c.Collect.Memory != nil {
|
||||
result, err = HostMemory(c)
|
||||
} else if c.Collect.TCPLoadBalancer != nil {
|
||||
result, err = HostTCPLoadBalancer(c)
|
||||
} else if c.Collect.HTTPLoadBalancer != nil {
|
||||
result, err = HostHTTPLoadBalancer(c)
|
||||
} else if c.Collect.DiskUsage != nil {
|
||||
result, err = HostDiskUsage(c)
|
||||
} else if c.Collect.TCPPortStatus != nil {
|
||||
result, err = HostTCPPortStatus(c)
|
||||
} else if c.Collect.HTTP != nil {
|
||||
result, err = HostHTTP(c)
|
||||
} else if c.Collect.Time != nil {
|
||||
result, err = HostTime(c)
|
||||
} else if c.Collect.BlockDevices != nil {
|
||||
result, err = HostBlockDevices(c)
|
||||
} else if c.Collect.TCPConnect != nil {
|
||||
result, err = HostTCPConnect(c)
|
||||
} else if c.Collect.IPV4Interfaces != nil {
|
||||
result, err = HostIPV4Interfaces(c)
|
||||
} else if c.Collect.FilesystemPerformance != nil {
|
||||
result, err = HostFilesystemPerformance(c)
|
||||
} else if c.Collect.Certificate != nil {
|
||||
result, err = HostCertificate(c)
|
||||
} else {
|
||||
err = errors.New("no spec found to run")
|
||||
return
|
||||
func GetHostCollector(collector *troubleshootv1beta2.HostCollect) (HostCollector, bool) {
|
||||
switch {
|
||||
case collector.CPU != nil:
|
||||
return &CollectHostCPU{collector.CPU}, true
|
||||
case collector.Memory != nil:
|
||||
return &CollectHostMemory{collector.Memory}, true
|
||||
case collector.TCPLoadBalancer != nil:
|
||||
return &CollectHostTCPLoadBalancer{collector.TCPLoadBalancer}, true
|
||||
case collector.HTTPLoadBalancer != nil:
|
||||
return &CollectHostHTTPLoadBalancer{collector.HTTPLoadBalancer}, true
|
||||
case collector.DiskUsage != nil:
|
||||
return &CollectHostDiskUsage{collector.DiskUsage}, true
|
||||
case collector.TCPPortStatus != nil:
|
||||
return &CollectHostTCPPortStatus{collector.TCPPortStatus}, true
|
||||
case collector.HTTP != nil:
|
||||
return &CollectHostHTTP{collector.HTTP}, true
|
||||
case collector.Time != nil:
|
||||
return &CollectHostTime{collector.Time}, true
|
||||
case collector.BlockDevices != nil:
|
||||
return &CollectHostBlockDevices{collector.BlockDevices}, true
|
||||
case collector.TCPConnect != nil:
|
||||
return &CollectHostTCPConnect{collector.TCPConnect}, true
|
||||
case collector.IPV4Interfaces != nil:
|
||||
return &CollectHostIPV4Interfaces{collector.IPV4Interfaces}, true
|
||||
case collector.FilesystemPerformance != nil:
|
||||
return &CollectHostFilesystemPerformance{collector.FilesystemPerformance}, true
|
||||
case collector.Certificate != nil:
|
||||
return &CollectHostCertificate{collector.Certificate}, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
func hostCollectorTitleOrDefault(meta troubleshootv1beta2.HostCollectorMeta, defaultTitle string) string {
|
||||
if meta.CollectorName != "" {
|
||||
return meta.CollectorName
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *HostCollector) GetDisplayName() string {
|
||||
return c.Collect.GetName()
|
||||
return defaultTitle
|
||||
}
|
||||
|
||||
+14
-1
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
)
|
||||
|
||||
@@ -12,7 +13,19 @@ type CPUInfo struct {
|
||||
PhysicalCount int `json:"physicalCount"`
|
||||
}
|
||||
|
||||
func HostCPU(c *HostCollector) (map[string][]byte, error) {
|
||||
type CollectHostCPU struct {
|
||||
hostCollector *troubleshootv1beta2.CPU
|
||||
}
|
||||
|
||||
func (c *CollectHostCPU) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "CPU Info")
|
||||
}
|
||||
|
||||
func (c *CollectHostCPU) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostCPU) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
cpuInfo := CPUInfo{}
|
||||
|
||||
logicalCount, err := cpu.Counts(true)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/shirou/gopsutil/disk"
|
||||
)
|
||||
|
||||
@@ -15,14 +16,26 @@ type DiskUsageInfo struct {
|
||||
UsedBytes uint64 `json:"used_bytes"`
|
||||
}
|
||||
|
||||
func HostDiskUsage(c *HostCollector) (map[string][]byte, error) {
|
||||
type CollectHostDiskUsage struct {
|
||||
hostCollector *troubleshootv1beta2.DiskUsage
|
||||
}
|
||||
|
||||
func (c *CollectHostDiskUsage) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, fmt.Sprintf("Disk Usage %s", c.hostCollector.CollectorName))
|
||||
}
|
||||
|
||||
func (c *CollectHostDiskUsage) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostDiskUsage) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
result := map[string][]byte{}
|
||||
|
||||
if c.Collect.DiskUsage == nil {
|
||||
if c.hostCollector == nil {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
pathExists, err := traverseFiletreeDirExists(c.Collect.DiskUsage.Path)
|
||||
pathExists, err := traverseFiletreeDirExists(c.hostCollector.Path)
|
||||
if err != nil {
|
||||
return result, errors.Wrap(err, "traverse file tree")
|
||||
}
|
||||
@@ -39,7 +52,7 @@ func HostDiskUsage(c *HostCollector) (map[string][]byte, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to marshal disk space info")
|
||||
}
|
||||
key := HostDiskUsageKey(c.Collect.DiskUsage.CollectorName)
|
||||
key := HostDiskUsageKey(c.hostCollector.CollectorName)
|
||||
result[key] = b
|
||||
|
||||
return result, nil
|
||||
|
||||
@@ -4,12 +4,30 @@ import (
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
type CollectHostFilesystemPerformance struct {
|
||||
hostCollector *troubleshootv1beta2.FilesystemPerformance
|
||||
}
|
||||
|
||||
func (c *CollectHostFilesystemPerformance) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "Filesystem Performance")
|
||||
}
|
||||
|
||||
func (c *CollectHostFilesystemPerformance) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostFilesystemPerformance) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
return collectHostFilesystemPerformance(c.hostCollector)
|
||||
}
|
||||
|
||||
type FSPerfResults struct {
|
||||
Min time.Duration
|
||||
Max time.Duration
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package collect
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func HostFilesystemPerformance(c *HostCollector) (map[string][]byte, error) {
|
||||
func collectHostFilesystemPerformance(hostCollector *troubleshootv1beta2.FilesystemPerformance) (map[string][]byte, error) {
|
||||
return nil, errors.New("Filesystem performance collector is only implemented for Linux")
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
@@ -33,33 +34,33 @@ func (d Durations) Swap(i, j int) {
|
||||
d[i], d[j] = d[j], d[i]
|
||||
}
|
||||
|
||||
func HostFilesystemPerformance(c *HostCollector) (map[string][]byte, error) {
|
||||
func collectHostFilesystemPerformance(hostCollector *troubleshootv1beta2.FilesystemPerformance) (map[string][]byte, error) {
|
||||
var operationSize uint64 = 1024
|
||||
if c.Collect.FilesystemPerformance.OperationSizeBytes != 0 {
|
||||
operationSize = c.Collect.FilesystemPerformance.OperationSizeBytes
|
||||
if hostCollector.OperationSizeBytes != 0 {
|
||||
operationSize = hostCollector.OperationSizeBytes
|
||||
}
|
||||
|
||||
var fileSize uint64 = 10 * 1024 * 1024
|
||||
if c.Collect.FilesystemPerformance.FileSize != "" {
|
||||
quantity, err := resource.ParseQuantity(c.Collect.FilesystemPerformance.FileSize)
|
||||
if hostCollector.FileSize != "" {
|
||||
quantity, err := resource.ParseQuantity(hostCollector.FileSize)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse fileSize %q", c.Collect.FilesystemPerformance.FileSize)
|
||||
return nil, errors.Wrapf(err, "failed to parse fileSize %q", hostCollector.FileSize)
|
||||
}
|
||||
fileSizeInt64, ok := quantity.AsInt64()
|
||||
if !ok {
|
||||
return nil, errors.Wrapf(err, "failed to parse fileSize %q", c.Collect.FilesystemPerformance.FileSize)
|
||||
return nil, errors.Wrapf(err, "failed to parse fileSize %q", hostCollector.FileSize)
|
||||
}
|
||||
fileSize = uint64(fileSizeInt64)
|
||||
}
|
||||
|
||||
if c.Collect.FilesystemPerformance.Directory == "" {
|
||||
if hostCollector.Directory == "" {
|
||||
return nil, errors.New("Directory is required to collect filesystem performance info")
|
||||
}
|
||||
// TODO: clean up this directory if its created
|
||||
if err := os.MkdirAll(c.Collect.FilesystemPerformance.Directory, 0700); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to mkdir %q", c.Collect.FilesystemPerformance.Directory)
|
||||
if err := os.MkdirAll(hostCollector.Directory, 0700); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to mkdir %q", hostCollector.Directory)
|
||||
}
|
||||
filename := filepath.Join(c.Collect.FilesystemPerformance.Directory, "fsperf")
|
||||
filename := filepath.Join(hostCollector.Directory, "fsperf")
|
||||
|
||||
f, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
@@ -92,11 +93,11 @@ func HostFilesystemPerformance(c *HostCollector) (map[string][]byte, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "write to %s", filename)
|
||||
}
|
||||
if c.Collect.FilesystemPerformance.Sync {
|
||||
if hostCollector.Sync {
|
||||
if err := f.Sync(); err != nil {
|
||||
return nil, errors.Wrapf(err, "sync %s", filename)
|
||||
}
|
||||
} else if c.Collect.FilesystemPerformance.Datasync {
|
||||
} else if hostCollector.Datasync {
|
||||
if err := syscall.Fdatasync(int(f.Fd())); err != nil {
|
||||
return nil, errors.Wrapf(err, "datasync %s", filename)
|
||||
}
|
||||
@@ -208,7 +209,7 @@ func HostFilesystemPerformance(c *HostCollector) (map[string][]byte, error) {
|
||||
|
||||
fsPerf.IOPS = int(iops)
|
||||
|
||||
collectorName := c.Collect.FilesystemPerformance.CollectorName
|
||||
collectorName := hostCollector.CollectorName
|
||||
if collectorName == "" {
|
||||
collectorName = "filesystemPerformance"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package collect
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func HostFilesystemPerformance(c *HostCollector) (map[string][]byte, error) {
|
||||
func collectHostFilesystemPerformance(hostCollector *troubleshootv1beta2.FilesystemPerformance) (map[string][]byte, error) {
|
||||
return nil, errors.New("Filesystem performance collector is only implemented for Linux")
|
||||
}
|
||||
|
||||
@@ -5,10 +5,24 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func HostHTTP(c *HostCollector) (map[string][]byte, error) {
|
||||
httpCollector := c.Collect.HTTP
|
||||
type CollectHostHTTP struct {
|
||||
hostCollector *troubleshootv1beta2.HostHTTP
|
||||
}
|
||||
|
||||
func (c *CollectHostHTTP) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "HTTP Request")
|
||||
}
|
||||
|
||||
func (c *CollectHostHTTP) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostHTTP) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
httpCollector := c.hostCollector
|
||||
|
||||
var response *http.Response
|
||||
var err error
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"path"
|
||||
@@ -14,18 +13,32 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/debug"
|
||||
"github.com/segmentio/ksuid"
|
||||
)
|
||||
|
||||
func HostHTTPLoadBalancer(c *HostCollector) (map[string][]byte, error) {
|
||||
listenAddress := fmt.Sprintf("0.0.0.0:%d", c.Collect.HTTPLoadBalancer.Port)
|
||||
type CollectHostHTTPLoadBalancer struct {
|
||||
hostCollector *troubleshootv1beta2.HTTPLoadBalancer
|
||||
}
|
||||
|
||||
func (c *CollectHostHTTPLoadBalancer) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "HTTP Load Balancer")
|
||||
}
|
||||
|
||||
func (c *CollectHostHTTPLoadBalancer) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostHTTPLoadBalancer) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
listenAddress := fmt.Sprintf("0.0.0.0:%d", c.hostCollector.Port)
|
||||
|
||||
timeout := 60 * time.Minute
|
||||
if c.Collect.HTTPLoadBalancer.Timeout != "" {
|
||||
if c.hostCollector.Timeout != "" {
|
||||
var err error
|
||||
timeout, err = time.ParseDuration(c.Collect.HTTPLoadBalancer.Timeout)
|
||||
timeout, err = time.ParseDuration(c.hostCollector.Timeout)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse timeout %q", c.Collect.HTTPLoadBalancer.Timeout)
|
||||
return nil, errors.Wrapf(err, "failed to parse timeout %q", c.hostCollector.Timeout)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +92,7 @@ func HostHTTPLoadBalancer(c *HostCollector) (map[string][]byte, error) {
|
||||
networkStatus = NetworkStatusBindPermissionDenied
|
||||
break
|
||||
}
|
||||
log.Println(err.Error())
|
||||
debug.Println(err.Error())
|
||||
networkStatus = NetworkStatusErrorOther
|
||||
break
|
||||
}
|
||||
@@ -87,10 +100,11 @@ func HostHTTPLoadBalancer(c *HostCollector) (map[string][]byte, error) {
|
||||
break
|
||||
}
|
||||
|
||||
networkStatus = attemptPOST(c.Collect.HTTPLoadBalancer.Address, requestToken, responseToken)
|
||||
networkStatus = attemptPOST(c.hostCollector.Address, requestToken, responseToken)
|
||||
|
||||
if networkStatus == NetworkStatusErrorOther || networkStatus == NetworkStatusConnectionTimeout {
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
progressChan <- errors.Errorf("http post %s: network status %q", c.hostCollector.Address, networkStatus)
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -107,8 +121,8 @@ func HostHTTPLoadBalancer(c *HostCollector) (map[string][]byte, error) {
|
||||
}
|
||||
|
||||
name := path.Join("httpLoadBalancer", "httpLoadBalancer.json")
|
||||
if c.Collect.HTTPLoadBalancer.CollectorName != "" {
|
||||
name = path.Join("httpLoadBalancer", fmt.Sprintf("%s.json", c.Collect.HTTPLoadBalancer.CollectorName))
|
||||
if c.hostCollector.CollectorName != "" {
|
||||
name = path.Join("httpLoadBalancer", fmt.Sprintf("%s.json", c.hostCollector.CollectorName))
|
||||
}
|
||||
|
||||
return map[string][]byte{
|
||||
@@ -137,7 +151,7 @@ func attemptPOST(address string, request []byte, response []byte) NetworkStatus
|
||||
buf := bytes.NewBuffer(request)
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", address, buf)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
debug.Println(err.Error())
|
||||
return NetworkStatusErrorOther
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,22 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func HostIPV4Interfaces(c *HostCollector) (map[string][]byte, error) {
|
||||
type CollectHostIPV4Interfaces struct {
|
||||
hostCollector *troubleshootv1beta2.IPV4Interfaces
|
||||
}
|
||||
|
||||
func (c *CollectHostIPV4Interfaces) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "IPv4 Interfaces")
|
||||
}
|
||||
|
||||
func (c *CollectHostIPV4Interfaces) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostIPV4Interfaces) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
var ipv4Interfaces []net.Interface
|
||||
|
||||
interfaces, err := net.Interfaces()
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
)
|
||||
|
||||
@@ -11,7 +12,19 @@ type MemoryInfo struct {
|
||||
Total uint64 `json:"total"`
|
||||
}
|
||||
|
||||
func HostMemory(c *HostCollector) (map[string][]byte, error) {
|
||||
type CollectHostMemory struct {
|
||||
hostCollector *troubleshootv1beta2.Memory
|
||||
}
|
||||
|
||||
func (c *CollectHostMemory) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "Amount of Memory")
|
||||
}
|
||||
|
||||
func (c *CollectHostMemory) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostMemory) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
memoryInfo := MemoryInfo{}
|
||||
|
||||
vmstat, err := mem.VirtualMemory()
|
||||
|
||||
+14
-12
@@ -2,12 +2,12 @@ package collect
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/debug"
|
||||
"github.com/segmentio/ksuid"
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ type NetworkStatusResult struct {
|
||||
Status NetworkStatus `json:"status"`
|
||||
}
|
||||
|
||||
func checkTCPConnection(listenAddress string, dialAddress string, timeout time.Duration) (NetworkStatus, error) {
|
||||
func checkTCPConnection(progressChan chan<- interface{}, listenAddress string, dialAddress string, timeout time.Duration) (NetworkStatus, error) {
|
||||
lstn, err := net.Listen("tcp", listenAddress)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "address already in use") {
|
||||
@@ -66,7 +66,8 @@ func checkTCPConnection(listenAddress string, dialAddress string, timeout time.D
|
||||
conn, err := net.DialTimeout("tcp", dialAddress, 50*time.Millisecond)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "i/o timeout") {
|
||||
time.Sleep(time.Millisecond * 50)
|
||||
progressChan <- err
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
@@ -79,26 +80,27 @@ func checkTCPConnection(listenAddress string, dialAddress string, timeout time.D
|
||||
return NetworkStatusConnected, nil
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond * 50)
|
||||
progressChan <- errors.New("failed to verify connection to server")
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func handleTestConnection(conn net.Conn, requestToken []byte, responseToken []byte) bool {
|
||||
defer func() {
|
||||
if err := conn.Close(); err != nil {
|
||||
fmt.Println(err.Error())
|
||||
debug.Println(err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
if err := conn.SetReadDeadline(time.Now().Add(50 * time.Millisecond)); err != nil {
|
||||
fmt.Printf("Server failed to set read deadline: %v", err)
|
||||
debug.Printf("Server failed to set read deadline: %v\n", err)
|
||||
return false
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
_, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
fmt.Printf("Server failed to read: %v", err)
|
||||
debug.Printf("Server failed to read: %v\n", err)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -107,12 +109,12 @@ func handleTestConnection(conn net.Conn, requestToken []byte, responseToken []by
|
||||
}
|
||||
|
||||
if err := conn.SetWriteDeadline(time.Now().Add(50 * time.Millisecond)); err != nil {
|
||||
fmt.Printf("Server failed to set write deadline: %v", err)
|
||||
debug.Printf("Server failed to set write deadline: %v\n", err)
|
||||
return false
|
||||
}
|
||||
|
||||
if _, err := conn.Write(responseToken); err != nil {
|
||||
fmt.Printf("Server failed to write: %v", err)
|
||||
debug.Printf("Server failed to write: %v\n", err)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -122,12 +124,12 @@ func handleTestConnection(conn net.Conn, requestToken []byte, responseToken []by
|
||||
func verifyConnectionToServer(conn net.Conn, requestToken []byte, responseToken []byte) bool {
|
||||
defer func() {
|
||||
if err := conn.Close(); err != nil {
|
||||
fmt.Println(err.Error())
|
||||
debug.Println(err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
if err := conn.SetWriteDeadline(time.Now().Add(50 * time.Millisecond)); err != nil {
|
||||
fmt.Printf("Client failed to set write deadline: %v", err)
|
||||
debug.Printf("Client failed to set write deadline: %v\n", err)
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -137,7 +139,7 @@ func verifyConnectionToServer(conn net.Conn, requestToken []byte, responseToken
|
||||
}
|
||||
|
||||
if err := conn.SetReadDeadline(time.Now().Add(50 * time.Millisecond)); err != nil {
|
||||
fmt.Printf("Client failed to set read deadline: %v", err)
|
||||
debug.Printf("Client failed to set read deadline: %v\n", err)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -9,17 +9,30 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func HostTCPConnect(c *HostCollector) (map[string][]byte, error) {
|
||||
address := c.Collect.TCPConnect.Address
|
||||
type CollectHostTCPConnect struct {
|
||||
hostCollector *troubleshootv1beta2.TCPConnect
|
||||
}
|
||||
|
||||
func (c *CollectHostTCPConnect) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "TCP Connection Attempt")
|
||||
}
|
||||
|
||||
func (c *CollectHostTCPConnect) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostTCPConnect) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
address := c.hostCollector.Address
|
||||
|
||||
timeout := 10 * time.Second
|
||||
if c.Collect.TCPConnect.Timeout != "" {
|
||||
if c.hostCollector.Timeout != "" {
|
||||
var err error
|
||||
timeout, err = time.ParseDuration(c.Collect.TCPConnect.Timeout)
|
||||
timeout, err = time.ParseDuration(c.hostCollector.Timeout)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse timeout %q", c.Collect.TCPConnect.Timeout)
|
||||
return nil, errors.Wrapf(err, "failed to parse timeout %q", c.hostCollector.Timeout)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +45,7 @@ func HostTCPConnect(c *HostCollector) (map[string][]byte, error) {
|
||||
return nil, errors.Wrap(err, "failed to marshal result")
|
||||
}
|
||||
|
||||
name := path.Join("connect", fmt.Sprintf("%s.json", c.Collect.TCPConnect.CollectorName))
|
||||
name := path.Join("connect", fmt.Sprintf("%s.json", c.hostCollector.CollectorName))
|
||||
|
||||
return map[string][]byte{
|
||||
name: b,
|
||||
|
||||
@@ -7,22 +7,35 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func HostTCPLoadBalancer(c *HostCollector) (map[string][]byte, error) {
|
||||
listenAddress := fmt.Sprintf("0.0.0.0:%d", c.Collect.TCPLoadBalancer.Port)
|
||||
dialAddress := c.Collect.TCPLoadBalancer.Address
|
||||
type CollectHostTCPLoadBalancer struct {
|
||||
hostCollector *troubleshootv1beta2.TCPLoadBalancer
|
||||
}
|
||||
|
||||
func (c *CollectHostTCPLoadBalancer) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "TCP Load Balancer")
|
||||
}
|
||||
|
||||
func (c *CollectHostTCPLoadBalancer) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostTCPLoadBalancer) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
listenAddress := fmt.Sprintf("0.0.0.0:%d", c.hostCollector.Port)
|
||||
dialAddress := c.hostCollector.Address
|
||||
|
||||
timeout := 60 * time.Minute
|
||||
if c.Collect.TCPLoadBalancer.Timeout != "" {
|
||||
if c.hostCollector.Timeout != "" {
|
||||
var err error
|
||||
timeout, err = time.ParseDuration(c.Collect.TCPLoadBalancer.Timeout)
|
||||
timeout, err = time.ParseDuration(c.hostCollector.Timeout)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse durection")
|
||||
}
|
||||
}
|
||||
|
||||
networkStatus, err := checkTCPConnection(listenAddress, dialAddress, timeout)
|
||||
networkStatus, err := checkTCPConnection(progressChan, listenAddress, dialAddress, timeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -37,8 +50,8 @@ func HostTCPLoadBalancer(c *HostCollector) (map[string][]byte, error) {
|
||||
}
|
||||
|
||||
name := path.Join("tcpLoadBalancer", "tcpLoadBalancer.json")
|
||||
if c.Collect.TCPLoadBalancer.CollectorName != "" {
|
||||
name = path.Join("tcpLoadBalancer", fmt.Sprintf("%s.json", c.Collect.TCPLoadBalancer.CollectorName))
|
||||
if c.hostCollector.CollectorName != "" {
|
||||
name = path.Join("tcpLoadBalancer", fmt.Sprintf("%s.json", c.hostCollector.CollectorName))
|
||||
}
|
||||
|
||||
return map[string][]byte{
|
||||
|
||||
@@ -8,22 +8,35 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
func HostTCPPortStatus(c *HostCollector) (map[string][]byte, error) {
|
||||
dialAddress := ""
|
||||
listenAddress := fmt.Sprintf("0.0.0.0:%d", c.Collect.TCPPortStatus.Port)
|
||||
type CollectHostTCPPortStatus struct {
|
||||
hostCollector *troubleshootv1beta2.TCPPortStatus
|
||||
}
|
||||
|
||||
if c.Collect.TCPPortStatus.Interface != "" {
|
||||
iface, err := net.InterfaceByName(c.Collect.TCPPortStatus.Interface)
|
||||
func (c *CollectHostTCPPortStatus) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "TCP Port Status")
|
||||
}
|
||||
|
||||
func (c *CollectHostTCPPortStatus) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostTCPPortStatus) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
dialAddress := ""
|
||||
listenAddress := fmt.Sprintf("0.0.0.0:%d", c.hostCollector.Port)
|
||||
|
||||
if c.hostCollector.Interface != "" {
|
||||
iface, err := net.InterfaceByName(c.hostCollector.Interface)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "lookup interface %s", c.Collect.TCPPortStatus.Interface)
|
||||
return nil, errors.Wrapf(err, "lookup interface %s", c.hostCollector.Interface)
|
||||
}
|
||||
ip, err := getIPv4FromInterface(iface)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "get ipv4 address for interface %s", c.Collect.TCPPortStatus.Interface)
|
||||
return nil, errors.Wrapf(err, "get ipv4 address for interface %s", c.hostCollector.Interface)
|
||||
}
|
||||
listenAddress = fmt.Sprintf("%s:%d", ip, c.Collect.TCPPortStatus.Port)
|
||||
listenAddress = fmt.Sprintf("%s:%d", ip, c.hostCollector.Port)
|
||||
dialAddress = listenAddress
|
||||
}
|
||||
|
||||
@@ -32,10 +45,10 @@ func HostTCPPortStatus(c *HostCollector) (map[string][]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dialAddress = fmt.Sprintf("%s:%d", ip, c.Collect.TCPPortStatus.Port)
|
||||
dialAddress = fmt.Sprintf("%s:%d", ip, c.hostCollector.Port)
|
||||
}
|
||||
|
||||
networkStatus, err := checkTCPConnection(listenAddress, dialAddress, 10*time.Second)
|
||||
networkStatus, err := checkTCPConnection(progressChan, listenAddress, dialAddress, 10*time.Second)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -49,8 +62,8 @@ func HostTCPPortStatus(c *HostCollector) (map[string][]byte, error) {
|
||||
}
|
||||
|
||||
name := path.Join("tcpPortStatus", "tcpPortStatus.json")
|
||||
if c.Collect.TCPPortStatus.CollectorName != "" {
|
||||
name = path.Join("tcpPortStatus", fmt.Sprintf("%s.json", c.Collect.TCPPortStatus.CollectorName))
|
||||
if c.hostCollector.CollectorName != "" {
|
||||
name = path.Join("tcpPortStatus", fmt.Sprintf("%s.json", c.hostCollector.CollectorName))
|
||||
}
|
||||
return map[string][]byte{
|
||||
name: b,
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/godbus/dbus"
|
||||
"github.com/pkg/errors"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
)
|
||||
|
||||
type NTPStatus string
|
||||
@@ -18,7 +19,19 @@ type TimeInfo struct {
|
||||
NTPActive bool `json:"ntp_active"`
|
||||
}
|
||||
|
||||
func HostTime(c *HostCollector) (map[string][]byte, error) {
|
||||
type CollectHostTime struct {
|
||||
hostCollector *troubleshootv1beta2.HostTime
|
||||
}
|
||||
|
||||
func (c *CollectHostTime) Title() string {
|
||||
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "TCP Port Status")
|
||||
}
|
||||
|
||||
func (c *CollectHostTime) IsExcluded() (bool, error) {
|
||||
return isExcluded(c.hostCollector.Exclude)
|
||||
}
|
||||
|
||||
func (c *CollectHostTime) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
||||
timeInfo := TimeInfo{}
|
||||
|
||||
conn, err := dbus.SystemBus()
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var logger = log.New(os.Stderr, "[debug]", log.Lshortfile)
|
||||
|
||||
func Print(v ...interface{}) {
|
||||
if viper.GetBool("debug") {
|
||||
log.Print(v...)
|
||||
}
|
||||
}
|
||||
|
||||
func Printf(format string, v ...interface{}) {
|
||||
if viper.GetBool("debug") {
|
||||
log.Printf(format, v...)
|
||||
}
|
||||
}
|
||||
|
||||
func Println(v ...interface{}) {
|
||||
if viper.GetBool("debug") {
|
||||
log.Println(v...)
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,10 @@ package preflight
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
analyze "github.com/replicatedhq/troubleshoot/pkg/analyze"
|
||||
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/multitype"
|
||||
)
|
||||
|
||||
// Analyze runs the analyze phase of preflight checks
|
||||
@@ -67,40 +64,8 @@ func doAnalyze(allCollectedData map[string][]byte, analyzers []*troubleshootv1be
|
||||
}
|
||||
|
||||
for _, hostAnalyzer := range hostAnalyzers {
|
||||
if excluded, _ := isExcluded(hostAnalyzer.Exclude); excluded {
|
||||
continue
|
||||
}
|
||||
analyzeResult, err := analyze.HostAnalyze(hostAnalyzer, getCollectedFileContents, getChildCollectedFileContents)
|
||||
if err != nil {
|
||||
analyzeResult = []*analyze.AnalyzeResult{
|
||||
{
|
||||
IsFail: true,
|
||||
Title: "Analyzer Failed",
|
||||
Message: err.Error(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if analyzeResult != nil {
|
||||
analyzeResults = append(analyzeResults, analyzeResult...)
|
||||
}
|
||||
analyzeResult := analyze.HostAnalyze(hostAnalyzer, getCollectedFileContents, getChildCollectedFileContents)
|
||||
analyzeResults = append(analyzeResults, analyzeResult...)
|
||||
}
|
||||
return analyzeResults
|
||||
}
|
||||
|
||||
func isExcluded(excludeVal multitype.BoolOrString) (bool, error) {
|
||||
if excludeVal.Type == multitype.Bool {
|
||||
return excludeVal.BoolVal, nil
|
||||
}
|
||||
|
||||
if excludeVal.StrVal == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
parsed, err := strconv.ParseBool(excludeVal.StrVal)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "failed to parse bool string")
|
||||
}
|
||||
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func (cr ClusterCollectResult) IsRBACAllowed() bool {
|
||||
|
||||
type HostCollectResult struct {
|
||||
AllCollectedData map[string][]byte
|
||||
Collectors collect.HostCollectors
|
||||
Collectors []collect.HostCollector
|
||||
Spec *troubleshootv1beta2.HostPreflight
|
||||
}
|
||||
|
||||
@@ -53,12 +53,12 @@ func CollectHost(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (Collec
|
||||
|
||||
allCollectedData := make(map[string][]byte)
|
||||
|
||||
var collectors collect.HostCollectors
|
||||
var collectors []collect.HostCollector
|
||||
for _, desiredCollector := range collectSpecs {
|
||||
collector := collect.HostCollector{
|
||||
Collect: desiredCollector,
|
||||
collector, ok := collect.GetHostCollector(desiredCollector)
|
||||
if ok {
|
||||
collectors = append(collectors, collector)
|
||||
}
|
||||
collectors = append(collectors, &collector)
|
||||
}
|
||||
|
||||
collectResult := HostCollectResult{
|
||||
@@ -67,12 +67,15 @@ func CollectHost(opts CollectOpts, p *troubleshootv1beta2.HostPreflight) (Collec
|
||||
}
|
||||
|
||||
for _, collector := range collectors {
|
||||
if excluded, _ := isExcluded(collector.Collect.Exclude); excluded {
|
||||
isExcluded, _ := collector.IsExcluded()
|
||||
if isExcluded {
|
||||
continue
|
||||
}
|
||||
result, err := collector.RunCollectorSync()
|
||||
|
||||
opts.ProgressChan <- fmt.Sprintf("[%s] Running collector...", collector.Title())
|
||||
result, err := collector.Collect(opts.ProgressChan)
|
||||
if err != nil {
|
||||
opts.ProgressChan <- errors.Errorf("failed to run collector: %s: %v\n", collector.GetDisplayName(), err)
|
||||
opts.ProgressChan <- errors.Errorf("failed to run collector: %s: %v", collector.Title(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user