diff --git a/cmd/preflight/cli/run.go b/cmd/preflight/cli/run.go index 5a3dc58c..130198a1 100644 --- a/cmd/preflight/cli/run.go +++ b/cmd/preflight/cli/run.go @@ -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)) } diff --git a/pkg/analyze/analyzer.go b/pkg/analyze/analyzer.go index 81acb94c..bb1d2a18 100644 --- a/pkg/analyze/analyzer.go +++ b/pkg/analyze/analyzer.go @@ -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) { diff --git a/pkg/analyze/host_analyzer.go b/pkg/analyze/host_analyzer.go new file mode 100644 index 00000000..3ca07dbf --- /dev/null +++ b/pkg/analyze/host_analyzer.go @@ -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 +} diff --git a/pkg/analyze/host_block_devices.go b/pkg/analyze/host_block_devices.go index c4b5fca8..099c88b2 100644 --- a/pkg/analyze/host_block_devices.go +++ b/pkg/analyze/host_block_devices.go @@ -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 { diff --git a/pkg/analyze/host_block_devices_test.go b/pkg/analyze/host_block_devices_test.go index 09e8fd3f..962b96b5 100644 --- a/pkg/analyze/host_block_devices_test.go +++ b/pkg/analyze/host_block_devices_test.go @@ -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 { diff --git a/pkg/analyze/host_certificate.go b/pkg/analyze/host_certificate.go index a31a79be..25efb64c 100644 --- a/pkg/analyze/host_certificate.go +++ b/pkg/analyze/host_certificate.go @@ -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 { diff --git a/pkg/analyze/host_certificate_test.go b/pkg/analyze/host_certificate_test.go index d7a00144..f1fb9854 100644 --- a/pkg/analyze/host_certificate_test.go +++ b/pkg/analyze/host_certificate_test.go @@ -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 { diff --git a/pkg/analyze/host_cpu.go b/pkg/analyze/host_cpu.go index ba315cb6..43ec4e02 100644 --- a/pkg/analyze/host_cpu.go +++ b/pkg/analyze/host_cpu.go @@ -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 { diff --git a/pkg/analyze/host_disk_usage.go b/pkg/analyze/host_disk_usage.go index 29889fdf..a447c740 100644 --- a/pkg/analyze/host_disk_usage.go +++ b/pkg/analyze/host_disk_usage.go @@ -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 { diff --git a/pkg/analyze/host_disk_usage_test.go b/pkg/analyze/host_disk_usage_test.go index 7e734fac..5bd9e1a0 100644 --- a/pkg/analyze/host_disk_usage_test.go +++ b/pkg/analyze/host_disk_usage_test.go @@ -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 { diff --git a/pkg/analyze/host_filesystem_performance.go b/pkg/analyze/host_filesystem_performance.go index 95bc59bb..824b42bb 100644 --- a/pkg/analyze/host_filesystem_performance.go +++ b/pkg/analyze/host_filesystem_performance.go @@ -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 { diff --git a/pkg/analyze/host_filesystem_performance_test.go b/pkg/analyze/host_filesystem_performance_test.go index 60582503..a885f473 100644 --- a/pkg/analyze/host_filesystem_performance_test.go +++ b/pkg/analyze/host_filesystem_performance_test.go @@ -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 { diff --git a/pkg/analyze/host_http.go b/pkg/analyze/host_http.go index b07a7b73..bd44cff2 100644 --- a/pkg/analyze/host_http.go +++ b/pkg/analyze/host_http.go @@ -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 { diff --git a/pkg/analyze/host_http_test.go b/pkg/analyze/host_http_test.go index e24461b4..0190db73 100644 --- a/pkg/analyze/host_http_test.go +++ b/pkg/analyze/host_http_test.go @@ -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 { diff --git a/pkg/analyze/host_httploadbalancer.go b/pkg/analyze/host_httploadbalancer.go index ad2ba771..9b16868e 100644 --- a/pkg/analyze/host_httploadbalancer.go +++ b/pkg/analyze/host_httploadbalancer.go @@ -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 { diff --git a/pkg/analyze/host_ipv4interfaces.go b/pkg/analyze/host_ipv4interfaces.go index 4c08a763..b855c56d 100644 --- a/pkg/analyze/host_ipv4interfaces.go +++ b/pkg/analyze/host_ipv4interfaces.go @@ -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 { diff --git a/pkg/analyze/host_ipv4interfaces_test.go b/pkg/analyze/host_ipv4interfaces_test.go index ed4ee0d2..65bebded 100644 --- a/pkg/analyze/host_ipv4interfaces_test.go +++ b/pkg/analyze/host_ipv4interfaces_test.go @@ -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 { diff --git a/pkg/analyze/host_memory.go b/pkg/analyze/host_memory.go index 12d57b11..1ae99ba7 100644 --- a/pkg/analyze/host_memory.go +++ b/pkg/analyze/host_memory.go @@ -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 { diff --git a/pkg/analyze/host_memory_test.go b/pkg/analyze/host_memory_test.go index a0b70ccf..898ae0b1 100644 --- a/pkg/analyze/host_memory_test.go +++ b/pkg/analyze/host_memory_test.go @@ -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 { diff --git a/pkg/analyze/host_tcp_connect.go b/pkg/analyze/host_tcp_connect.go index 327dc0db..8baa77e4 100644 --- a/pkg/analyze/host_tcp_connect.go +++ b/pkg/analyze/host_tcp_connect.go @@ -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 { diff --git a/pkg/analyze/host_tcp_connect_test.go b/pkg/analyze/host_tcp_connect_test.go index 6cc8064c..04b07263 100644 --- a/pkg/analyze/host_tcp_connect_test.go +++ b/pkg/analyze/host_tcp_connect_test.go @@ -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 { diff --git a/pkg/analyze/host_tcploadbalancer.go b/pkg/analyze/host_tcploadbalancer.go index e6efc102..702b24cd 100644 --- a/pkg/analyze/host_tcploadbalancer.go +++ b/pkg/analyze/host_tcploadbalancer.go @@ -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 { diff --git a/pkg/analyze/host_tcpportstatus.go b/pkg/analyze/host_tcpportstatus.go index 4d03b1fd..62047288 100644 --- a/pkg/analyze/host_tcpportstatus.go +++ b/pkg/analyze/host_tcpportstatus.go @@ -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 { diff --git a/pkg/analyze/host_time.go b/pkg/analyze/host_time.go index a4085776..329da374 100644 --- a/pkg/analyze/host_time.go +++ b/pkg/analyze/host_time.go @@ -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 { diff --git a/pkg/analyze/host_time_test.go b/pkg/analyze/host_time_test.go index 63bc9deb..10c5ca62 100644 --- a/pkg/analyze/host_time_test.go +++ b/pkg/analyze/host_time_test.go @@ -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 { diff --git a/pkg/apis/troubleshoot/v1beta2/hostanalyzer_shared.go b/pkg/apis/troubleshoot/v1beta2/hostanalyzer_shared.go index 5f23e8ac..c4b06a6f 100644 --- a/pkg/apis/troubleshoot/v1beta2/hostanalyzer_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/hostanalyzer_shared.go @@ -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"` } diff --git a/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go b/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go index 0e20ba53..65dd2aea 100644 --- a/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go +++ b/pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go @@ -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 { diff --git a/pkg/collect/host_block_device.go b/pkg/collect/host_block_device.go index b88f2044..bdf7c2db 100644 --- a/pkg/collect/host_block_device.go +++ b/pkg/collect/host_block_device.go @@ -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) diff --git a/pkg/collect/host_certificate.go b/pkg/collect/host_certificate.go index 16ffa639..f68730c7 100644 --- a/pkg/collect/host_certificate.go +++ b/pkg/collect/host_certificate.go @@ -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" } diff --git a/pkg/collect/host_collector.go b/pkg/collect/host_collector.go index a28fb0e8..9a44f2d4 100644 --- a/pkg/collect/host_collector.go +++ b/pkg/collect/host_collector.go @@ -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 } diff --git a/pkg/collect/host_cpu.go b/pkg/collect/host_cpu.go index 032a3ff7..064a46c5 100644 --- a/pkg/collect/host_cpu.go +++ b/pkg/collect/host_cpu.go @@ -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) diff --git a/pkg/collect/host_disk_usage.go b/pkg/collect/host_disk_usage.go index 30162891..db8bf12c 100644 --- a/pkg/collect/host_disk_usage.go +++ b/pkg/collect/host_disk_usage.go @@ -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 diff --git a/pkg/collect/host_filesystem_performance.go b/pkg/collect/host_filesystem_performance.go index 91ba5e98..b6f1b2f7 100644 --- a/pkg/collect/host_filesystem_performance.go +++ b/pkg/collect/host_filesystem_performance.go @@ -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 diff --git a/pkg/collect/host_filesystem_performance_darwin.go b/pkg/collect/host_filesystem_performance_darwin.go index 82b2ac22..075cd5c8 100644 --- a/pkg/collect/host_filesystem_performance_darwin.go +++ b/pkg/collect/host_filesystem_performance_darwin.go @@ -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") } diff --git a/pkg/collect/host_filesystem_performance_linux.go b/pkg/collect/host_filesystem_performance_linux.go index 0303fa43..eb9f4bcd 100644 --- a/pkg/collect/host_filesystem_performance_linux.go +++ b/pkg/collect/host_filesystem_performance_linux.go @@ -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" } diff --git a/pkg/collect/host_filesystem_performance_windows.go b/pkg/collect/host_filesystem_performance_windows.go index 82b2ac22..075cd5c8 100644 --- a/pkg/collect/host_filesystem_performance_windows.go +++ b/pkg/collect/host_filesystem_performance_windows.go @@ -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") } diff --git a/pkg/collect/host_http.go b/pkg/collect/host_http.go index e00f8a44..9aadafae 100644 --- a/pkg/collect/host_http.go +++ b/pkg/collect/host_http.go @@ -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 diff --git a/pkg/collect/host_httploadbalancer.go b/pkg/collect/host_httploadbalancer.go index 26b5b285..6d6d73fa 100644 --- a/pkg/collect/host_httploadbalancer.go +++ b/pkg/collect/host_httploadbalancer.go @@ -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 } diff --git a/pkg/collect/host_ipv4interfaces.go b/pkg/collect/host_ipv4interfaces.go index 4c549211..08dc705f 100644 --- a/pkg/collect/host_ipv4interfaces.go +++ b/pkg/collect/host_ipv4interfaces.go @@ -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() diff --git a/pkg/collect/host_memory.go b/pkg/collect/host_memory.go index 7cf0194e..41ddf1a5 100644 --- a/pkg/collect/host_memory.go +++ b/pkg/collect/host_memory.go @@ -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() diff --git a/pkg/collect/host_network.go b/pkg/collect/host_network.go index 8abd1702..44d990fa 100644 --- a/pkg/collect/host_network.go +++ b/pkg/collect/host_network.go @@ -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 } diff --git a/pkg/collect/host_tcp_connect.go b/pkg/collect/host_tcp_connect.go index 1e1ce03a..4de145bd 100644 --- a/pkg/collect/host_tcp_connect.go +++ b/pkg/collect/host_tcp_connect.go @@ -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, diff --git a/pkg/collect/host_tcploadbalancer.go b/pkg/collect/host_tcploadbalancer.go index 978c18d0..29467629 100644 --- a/pkg/collect/host_tcploadbalancer.go +++ b/pkg/collect/host_tcploadbalancer.go @@ -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{ diff --git a/pkg/collect/host_tcpportstatus.go b/pkg/collect/host_tcpportstatus.go index e06bb3b7..8067a5bf 100644 --- a/pkg/collect/host_tcpportstatus.go +++ b/pkg/collect/host_tcpportstatus.go @@ -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, diff --git a/pkg/collect/host_time.go b/pkg/collect/host_time.go index 96546c3c..e75cf3e2 100644 --- a/pkg/collect/host_time.go +++ b/pkg/collect/host_time.go @@ -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() diff --git a/pkg/debug/log.go b/pkg/debug/log.go new file mode 100644 index 00000000..2e1087e7 --- /dev/null +++ b/pkg/debug/log.go @@ -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...) + } +} diff --git a/pkg/preflight/analyze.go b/pkg/preflight/analyze.go index c0d3dbae..877d9a64 100644 --- a/pkg/preflight/analyze.go +++ b/pkg/preflight/analyze.go @@ -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 -} diff --git a/pkg/preflight/collect.go b/pkg/preflight/collect.go index 5d7900cf..b2e5b937 100644 --- a/pkg/preflight/collect.go +++ b/pkg/preflight/collect.go @@ -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 }