From e156b8c215744f260176c3235085714317990c99 Mon Sep 17 00:00:00 2001 From: Evans Mungai Date: Fri, 3 Feb 2023 15:26:36 +0000 Subject: [PATCH] chore: Refactor in cluster analysers (#999) Have all in-cluster analysers implement the same interface. This will help with the implementation of code that requires making calls to all analysers Fixes #995 --- pkg/analyze/analyzer.go | 508 +++++--------------------- pkg/analyze/analyzer_test.go | 6 + pkg/analyze/ceph.go | 37 +- pkg/analyze/ceph_test.go | 6 +- pkg/analyze/cluster_pod_statuses.go | 27 ++ pkg/analyze/cluster_version.go | 36 +- pkg/analyze/configmap.go | 35 +- pkg/analyze/configmap_test.go | 7 +- pkg/analyze/container_runtime.go | 34 +- pkg/analyze/container_runtime_test.go | 6 +- pkg/analyze/crd.go | 37 +- pkg/analyze/deployment_status.go | 38 ++ pkg/analyze/distribution.go | 34 +- pkg/analyze/image_pull_secret.go | 34 +- pkg/analyze/ingress.go | 35 +- pkg/analyze/job_status.go | 38 ++ pkg/analyze/json_compare.go | 37 +- pkg/analyze/json_compare_test.go | 6 +- pkg/analyze/kube_resource.go | 36 +- pkg/analyze/longhorn.go | 23 ++ pkg/analyze/mysql.go | 45 ++- pkg/analyze/node_resources.go | 35 +- pkg/analyze/node_resources_test.go | 6 +- pkg/analyze/postgres.go | 43 ++- pkg/analyze/redis.go | 43 ++- pkg/analyze/registry.go | 43 ++- pkg/analyze/replicaset_status.go | 38 ++ pkg/analyze/secret.go | 35 +- pkg/analyze/secret_test.go | 5 +- pkg/analyze/statefulset_status.go | 38 ++ pkg/analyze/storage_class.go | 45 ++- pkg/analyze/sysctl.go | 28 +- pkg/analyze/sysctl_test.go | 6 +- pkg/analyze/text_analyze.go | 43 ++- pkg/analyze/text_analyze_test.go | 6 +- pkg/analyze/weave.go | 23 ++ pkg/analyze/yaml_compare.go | 37 +- pkg/analyze/yaml_compare_test.go | 6 +- pkg/constants/constants.go | 2 +- 39 files changed, 962 insertions(+), 585 deletions(-) diff --git a/pkg/analyze/analyzer.go b/pkg/analyze/analyzer.go index cb6e470a..14ccc166 100644 --- a/pkg/analyze/analyzer.go +++ b/pkg/analyze/analyzer.go @@ -88,436 +88,33 @@ func Analyze(analyzer *troubleshootv1beta2.Analyze, getFile getCollectedFileCont return nil, errors.New("nil analyzer") } - if analyzer.ClusterVersion != nil { - isExcluded, err := isExcluded(analyzer.ClusterVersion.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeClusterVersion(analyzer.ClusterVersion, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.ClusterVersion.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.StorageClass != nil { - isExcluded, err := isExcluded(analyzer.StorageClass.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeStorageClass(analyzer.StorageClass, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.StorageClass.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.CustomResourceDefinition != nil { - isExcluded, err := isExcluded(analyzer.CustomResourceDefinition.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeCustomResourceDefinition(analyzer.CustomResourceDefinition, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.CustomResourceDefinition.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.Ingress != nil { - isExcluded, err := isExcluded(analyzer.Ingress.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeIngress(analyzer.Ingress, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.Ingress.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.Secret != nil { - isExcluded, err := isExcluded(analyzer.Secret.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeSecret(analyzer.Secret, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.Secret.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.ConfigMap != nil { - isExcluded, err := isExcluded(analyzer.ConfigMap.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeConfigMap(analyzer.ConfigMap, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.ConfigMap.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.ImagePullSecret != nil { - isExcluded, err := isExcluded(analyzer.ImagePullSecret.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeImagePullSecret(analyzer.ImagePullSecret, findFiles) - if err != nil { - return nil, err - } - result.Strict = analyzer.ImagePullSecret.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.DeploymentStatus != nil { - isExcluded, err := isExcluded(analyzer.DeploymentStatus.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - results, err := analyzeDeploymentStatus(analyzer.DeploymentStatus, findFiles) - if err != nil { - return nil, err - } - for i := range results { - results[i].Strict = analyzer.DeploymentStatus.Strict.BoolOrDefaultFalse() - } - return results, nil - } - if analyzer.ClusterResource != nil { - isExcluded, err := isExcluded(analyzer.ClusterResource.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeResource(analyzer.ClusterResource, getFile) - if err != nil { - return nil, err - } - return []*AnalyzeResult{result}, nil - } - if analyzer.StatefulsetStatus != nil { - isExcluded, err := isExcluded(analyzer.StatefulsetStatus.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - results, err := analyzeStatefulsetStatus(analyzer.StatefulsetStatus, findFiles) - if err != nil { - return nil, err - } - for i := range results { - results[i].Strict = analyzer.StatefulsetStatus.Strict.BoolOrDefaultFalse() - } - return results, nil - } - if analyzer.JobStatus != nil { - isExcluded, err := isExcluded(analyzer.JobStatus.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - results, err := analyzeJobStatus(analyzer.JobStatus, findFiles) - if err != nil { - return nil, err - } - for i := range results { - results[i].Strict = analyzer.JobStatus.Strict.BoolOrDefaultFalse() - } - return results, nil - } - if analyzer.ReplicaSetStatus != nil { - isExcluded, err := isExcluded(analyzer.ReplicaSetStatus.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - results, err := analyzeReplicaSetStatus(analyzer.ReplicaSetStatus, findFiles) - if err != nil { - return nil, err - } - for i := range results { - results[i].Strict = analyzer.ReplicaSetStatus.Strict.BoolOrDefaultFalse() - } - return results, nil - } - if analyzer.ClusterPodStatuses != nil { - isExcluded, err := isExcluded(analyzer.ClusterPodStatuses.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - results, err := clusterPodStatuses(analyzer.ClusterPodStatuses, findFiles) - if err != nil { - return nil, err - } - for i := range results { - results[i].Strict = analyzer.ClusterPodStatuses.Strict.BoolOrDefaultFalse() - } - return results, nil - } - if analyzer.ContainerRuntime != nil { - isExcluded, err := isExcluded(analyzer.ContainerRuntime.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeContainerRuntime(analyzer.ContainerRuntime, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.ContainerRuntime.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.Distribution != nil { - isExcluded, err := isExcluded(analyzer.Distribution.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeDistribution(analyzer.Distribution, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.Distribution.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.NodeResources != nil { - isExcluded, err := isExcluded(analyzer.NodeResources.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeNodeResources(analyzer.NodeResources, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.NodeResources.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.TextAnalyze != nil { - isExcluded, err := isExcluded(analyzer.TextAnalyze.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - results, err := analyzeTextAnalyze(analyzer.TextAnalyze, findFiles) - if err != nil { - return nil, err - } - for i := range results { - results[i].Strict = analyzer.TextAnalyze.Strict.BoolOrDefaultFalse() - } - return results, nil - } - if analyzer.YamlCompare != nil { - isExcluded, err := isExcluded(analyzer.YamlCompare.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeYamlCompare(analyzer.YamlCompare, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.YamlCompare.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.JsonCompare != nil { - isExcluded, err := isExcluded(analyzer.JsonCompare.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeJsonCompare(analyzer.JsonCompare, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.JsonCompare.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.Postgres != nil { - isExcluded, err := isExcluded(analyzer.Postgres.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzePostgres(analyzer.Postgres, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.Postgres.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.Mysql != nil { - isExcluded, err := isExcluded(analyzer.Mysql.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeMysql(analyzer.Mysql, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.Mysql.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.Redis != nil { - isExcluded, err := isExcluded(analyzer.Redis.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeRedis(analyzer.Redis, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.Redis.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil - } - if analyzer.CephStatus != nil { - isExcluded, err := isExcluded(analyzer.CephStatus.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := cephStatus(analyzer.CephStatus, getFile) - if err != nil { - return nil, err - } - if result != nil { - result.Strict = analyzer.CephStatus.Strict.BoolOrDefaultFalse() - } - return []*AnalyzeResult{result}, nil - } - if analyzer.Longhorn != nil { - isExcluded, err := isExcluded(analyzer.Longhorn.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - results, err := longhorn(analyzer.Longhorn, getFile, findFiles) - if err != nil { - return nil, err - } - for i := range results { - results[i].Strict = analyzer.Longhorn.Strict.BoolOrDefaultFalse() - } - return results, nil + analyzerInst := getAnalyzer(analyzer) + if analyzerInst == nil { + return []*AnalyzeResult{{ + IsFail: true, + Title: "nonexistent analyzer", + Message: "Analyzer not found", + }}, nil } - if analyzer.RegistryImages != nil { - isExcluded, err := isExcluded(analyzer.RegistryImages.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeRegistry(analyzer.RegistryImages, getFile) - if err != nil { - return nil, err - } - result.Strict = analyzer.RegistryImages.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil + isExcluded, err := analyzerInst.IsExcluded() + if err != nil { + return nil, err + } + if isExcluded { + return nil, nil } - if analyzer.WeaveReport != nil { - isExcluded, err := isExcluded(analyzer.WeaveReport.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - results, err := analyzeWeaveReport(analyzer.WeaveReport, findFiles) - if err != nil { - return nil, err - } - for i := range results { - results[i].Strict = analyzer.WeaveReport.Strict.BoolOrDefaultFalse() - } - return results, nil + results, err := analyzerInst.Analyze(getFile, findFiles) + if err != nil { + return nil, err } - if analyzer.Sysctl != nil { - isExcluded, err := isExcluded(analyzer.Sysctl.Exclude) - if err != nil { - return nil, err - } - if isExcluded { - return nil, nil - } - result, err := analyzeSysctl(analyzer.Sysctl, findFiles) - if err != nil { - return nil, err - } - if result == nil { - return []*AnalyzeResult{}, nil - } - result.Strict = analyzer.Sysctl.Strict.BoolOrDefaultFalse() - return []*AnalyzeResult{result}, nil + if results == nil { + results = []*AnalyzeResult{} } - return nil, errors.New("invalid analyzer") + return results, nil } func GetExcludeFlag(analyzer *troubleshootv1beta2.Analyze) *multitype.BoolOrString { @@ -541,3 +138,70 @@ func GetExcludeFlag(analyzer *troubleshootv1beta2.Analyze) *multitype.BoolOrStri return nil } + +type Analyzer interface { + Title() string + IsExcluded() (bool, error) + Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) +} + +func getAnalyzer(analyzer *troubleshootv1beta2.Analyze) Analyzer { + switch { + case analyzer.ClusterVersion != nil: + return &AnalyzeClusterVersion{analyzer: analyzer.ClusterVersion} + case analyzer.StorageClass != nil: + return &AnalyzeStorageClass{analyzer: analyzer.StorageClass} + case analyzer.CustomResourceDefinition != nil: + return &AnalyzeCustomResourceDefinition{analyzer: analyzer.CustomResourceDefinition} + case analyzer.Ingress != nil: + return &AnalyzeIngress{analyzer: analyzer.Ingress} + case analyzer.Secret != nil: + return &AnalyzeSecret{analyzer: analyzer.Secret} + case analyzer.ConfigMap != nil: + return &AnalyzeConfigMap{analyzer: analyzer.ConfigMap} + case analyzer.ImagePullSecret != nil: + return &AnalyzeImagePullSecret{analyzer: analyzer.ImagePullSecret} + case analyzer.DeploymentStatus != nil: + return &AnalyzeDeploymentStatus{analyzer: analyzer.DeploymentStatus} + case analyzer.StatefulsetStatus != nil: + return &AnalyzeStatefulsetStatus{analyzer: analyzer.StatefulsetStatus} + case analyzer.JobStatus != nil: + return &AnalyzeJobStatus{analyzer: analyzer.JobStatus} + case analyzer.ReplicaSetStatus != nil: + return &AnalyzeReplicaSetStatus{analyzer: analyzer.ReplicaSetStatus} + case analyzer.ClusterPodStatuses != nil: + return &AnalyzeClusterPodStatuses{analyzer: analyzer.ClusterPodStatuses} + case analyzer.ContainerRuntime != nil: + return &AnalyzeContainerRuntime{analyzer: analyzer.ContainerRuntime} + case analyzer.Distribution != nil: + return &AnalyzeDistribution{analyzer: analyzer.Distribution} + case analyzer.NodeResources != nil: + return &AnalyzeNodeResources{analyzer: analyzer.NodeResources} + case analyzer.TextAnalyze != nil: + return &AnalyzeTextAnalyze{analyzer: analyzer.TextAnalyze} + case analyzer.YamlCompare != nil: + return &AnalyzeYamlCompare{analyzer: analyzer.YamlCompare} + case analyzer.JsonCompare != nil: + return &AnalyzeJsonCompare{analyzer: analyzer.JsonCompare} + case analyzer.Postgres != nil: + return &AnalyzePostgres{analyzer: analyzer.Postgres} + case analyzer.Mysql != nil: + return &AnalyzeMysql{analyzer: analyzer.Mysql} + case analyzer.Redis != nil: + return &AnalyzeRedis{analyzer: analyzer.Redis} + case analyzer.CephStatus != nil: + return &AnalyzeCephStatus{analyzer: analyzer.CephStatus} + case analyzer.Longhorn != nil: + return &AnalyzeLonghorn{analyzer: analyzer.Longhorn} + case analyzer.RegistryImages != nil: + return &AnalyzeRegistryImages{analyzer: analyzer.RegistryImages} + case analyzer.WeaveReport != nil: + return &AnalyzeWeaveReport{analyzer: analyzer.WeaveReport} + case analyzer.Sysctl != nil: + return &AnalyzeSysctl{analyzer: analyzer.Sysctl} + case analyzer.ClusterResource != nil: + return &AnalyzeClusterResource{analyzer: analyzer.ClusterResource} + default: + return nil + } +} diff --git a/pkg/analyze/analyzer_test.go b/pkg/analyze/analyzer_test.go index 13e7c47c..0b8b4ad9 100644 --- a/pkg/analyze/analyzer_test.go +++ b/pkg/analyze/analyzer_test.go @@ -65,3 +65,9 @@ func Test_GetExcludeFlag(t *testing.T) { }) } } + +func TestAnalyzeWithNilAnalyzer(t *testing.T) { + got, err := Analyze(nil, nil, nil) + assert.Error(t, err) + assert.Nil(t, got) +} diff --git a/pkg/analyze/ceph.go b/pkg/analyze/ceph.go index d055e4a5..0b9fb87f 100644 --- a/pkg/analyze/ceph.go +++ b/pkg/analyze/ceph.go @@ -100,7 +100,35 @@ type PgMap struct { TotalBytes uint64 `json:"bytes_total"` } -func cephStatus(analyzer *troubleshootv1beta2.CephStatusAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeCephStatus struct { + analyzer *troubleshootv1beta2.CephStatusAnalyze +} + +func (a *AnalyzeCephStatus) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Ceph Status" + } + + return title +} + +func (a *AnalyzeCephStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeCephStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.cephStatus(a.analyzer, getFile) + if err != nil { + return nil, err + } + if result != nil { + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeCephStatus) cephStatus(analyzer *troubleshootv1beta2.CephStatusAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { fileName := path.Join(collect.GetCephCollectorFilepath(analyzer.CollectorName, analyzer.Namespace), "status.json") collected, err := getCollectedFileContents(fileName) @@ -111,13 +139,8 @@ func cephStatus(analyzer *troubleshootv1beta2.CephStatusAnalyze, getCollectedFil return nil, errors.Wrap(err, "failed to read collected ceph status") } - title := analyzer.CheckName - if title == "" { - title = "Ceph Status" - } - analyzeResult := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "rook", // maybe this should be ceph? IconURI: "https://troubleshoot.sh/images/analyzer-icons/rook.svg?w=11&h=16", } diff --git a/pkg/analyze/ceph_test.go b/pkg/analyze/ceph_test.go index 6ec31542..77319b47 100644 --- a/pkg/analyze/ceph_test.go +++ b/pkg/analyze/ceph_test.go @@ -273,7 +273,11 @@ func Test_cephStatus(t *testing.T) { } } - actual, err := cephStatus(&test.analyzer, test.getFile) + a := AnalyzeCephStatus{ + analyzer: &test.analyzer, + } + + actual, err := a.cephStatus(&test.analyzer, test.getFile) req.NoError(err) assert.Equal(t, test.expectResult, actual) diff --git a/pkg/analyze/cluster_pod_statuses.go b/pkg/analyze/cluster_pod_statuses.go index e643ba74..1cae2d34 100644 --- a/pkg/analyze/cluster_pod_statuses.go +++ b/pkg/analyze/cluster_pod_statuses.go @@ -15,6 +15,33 @@ import ( corev1 "k8s.io/api/core/v1" ) +type AnalyzeClusterPodStatuses struct { + analyzer *troubleshootv1beta2.ClusterPodStatuses +} + +func (a *AnalyzeClusterPodStatuses) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + return "Cluster Pod Status" +} + +func (a *AnalyzeClusterPodStatuses) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeClusterPodStatuses) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := clusterPodStatuses(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func clusterPodStatuses(analyzer *troubleshootv1beta2.ClusterPodStatuses, getChildCollectedFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { excludeFiles := []string{} collected, err := getChildCollectedFileContents(filepath.Join(constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_PODS, "*.json"), excludeFiles) diff --git a/pkg/analyze/cluster_version.go b/pkg/analyze/cluster_version.go index 988c7e31..de979057 100644 --- a/pkg/analyze/cluster_version.go +++ b/pkg/analyze/cluster_version.go @@ -10,6 +10,27 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) +type AnalyzeClusterVersion struct { + analyzer *troubleshootv1beta2.ClusterVersion +} + +func (a *AnalyzeClusterVersion) Title() string { + return title(a.analyzer.CheckName) +} + +func (a *AnalyzeClusterVersion) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeClusterVersion) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := analyzeClusterVersion(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + func analyzeClusterVersion(analyzer *troubleshootv1beta2.ClusterVersion, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { clusterInfo, err := getCollectedFileContents("cluster-info/cluster_version.json") if err != nil { @@ -29,19 +50,22 @@ func analyzeClusterVersion(analyzer *troubleshootv1beta2.ClusterVersion, getColl return analyzeClusterVersionResult(k8sVersion, analyzer.Outcomes, analyzer.CheckName) } +func title(checkName string) string { + if checkName == "" { + return "Required Kubernetes Version" + } + + return checkName +} + func analyzeClusterVersionResult(k8sVersion semver.Version, outcomes []*troubleshootv1beta2.Outcome, checkName string) (*AnalyzeResult, error) { for _, outcome := range outcomes { when := "" message := "" uri := "" - title := checkName - if title == "" { - title = "Required Kubernetes Version" - } - result := AnalyzeResult{ - Title: title, + Title: title(checkName), IconKey: "kubernetes_cluster_version", IconURI: "https://troubleshoot.sh/images/analyzer-icons/kubernetes.svg?w=16&h=16", } diff --git a/pkg/analyze/configmap.go b/pkg/analyze/configmap.go index 3641054a..d1cf05a2 100644 --- a/pkg/analyze/configmap.go +++ b/pkg/analyze/configmap.go @@ -8,7 +8,33 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeConfigMap(analyzer *troubleshootv1beta2.AnalyzeConfigMap, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeConfigMap struct { + analyzer *troubleshootv1beta2.AnalyzeConfigMap +} + +func (a *AnalyzeConfigMap) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = fmt.Sprintf("ConfigMap %s", a.analyzer.ConfigMapName) + } + + return title +} + +func (a *AnalyzeConfigMap) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeConfigMap) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeConfigMap(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeConfigMap) analyzeConfigMap(analyzer *troubleshootv1beta2.AnalyzeConfigMap, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { filename := collect.GetConfigMapFileName( &troubleshootv1beta2.ConfigMap{ Namespace: analyzer.Namespace, @@ -28,13 +54,8 @@ func analyzeConfigMap(analyzer *troubleshootv1beta2.AnalyzeConfigMap, getCollect return nil, err } - title := analyzer.CheckName - if title == "" { - title = fmt.Sprintf("ConfigMap %s", analyzer.ConfigMapName) - } - result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_analyze_secret", // TODO: icon IconURI: "https://troubleshoot.sh/images/analyzer-icons/secret.svg?w=13&h=16", } diff --git a/pkg/analyze/configmap_test.go b/pkg/analyze/configmap_test.go index ebfda9fa..09f951c2 100644 --- a/pkg/analyze/configmap_test.go +++ b/pkg/analyze/configmap_test.go @@ -199,7 +199,12 @@ func Test_analyzeConfigMap(t *testing.T) { } return contents, nil } - got, err := analyzeConfigMap(tt.analyzer, getCollectedFileContents) + + a := AnalyzeConfigMap{ + analyzer: tt.analyzer, + } + + got, err := a.analyzeConfigMap(tt.analyzer, getCollectedFileContents) if tt.wantErr { assert.Error(t, err) } else { diff --git a/pkg/analyze/container_runtime.go b/pkg/analyze/container_runtime.go index 5c03d5ab..1d4b2b75 100644 --- a/pkg/analyze/container_runtime.go +++ b/pkg/analyze/container_runtime.go @@ -12,7 +12,33 @@ import ( corev1 "k8s.io/api/core/v1" ) -func analyzeContainerRuntime(analyzer *troubleshootv1beta2.ContainerRuntime, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeContainerRuntime struct { + analyzer *troubleshootv1beta2.ContainerRuntime +} + +func (a *AnalyzeContainerRuntime) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Container Runtime" + } + + return title +} + +func (a *AnalyzeContainerRuntime) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeContainerRuntime) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeContainerRuntime(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeContainerRuntime) analyzeContainerRuntime(analyzer *troubleshootv1beta2.ContainerRuntime, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { collected, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_NODES)) if err != nil { return nil, errors.Wrap(err, "failed to get contents of nodes.json") @@ -28,12 +54,8 @@ func analyzeContainerRuntime(analyzer *troubleshootv1beta2.ContainerRuntime, get foundRuntimes = append(foundRuntimes, node.Status.NodeInfo.ContainerRuntimeVersion) } - title := analyzer.CheckName - if title == "" { - title = "Container Runtime" - } result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_container_runtime", IconURI: "https://troubleshoot.sh/images/analyzer-icons/container-runtime.svg?w=23&h=16", } diff --git a/pkg/analyze/container_runtime_test.go b/pkg/analyze/container_runtime_test.go index c59571f7..beacc83f 100644 --- a/pkg/analyze/container_runtime_test.go +++ b/pkg/analyze/container_runtime_test.go @@ -113,7 +113,11 @@ func Test_containerRuntime(t *testing.T) { return test.files[n], nil } - actual, err := analyzeContainerRuntime(&test.analyzer, getFiles) + a := AnalyzeContainerRuntime{ + analyzer: &test.analyzer, + } + + actual, err := a.analyzeContainerRuntime(&test.analyzer, getFiles) req.NoError(err) assert.Equal(t, &test.expectResult, actual) diff --git a/pkg/analyze/crd.go b/pkg/analyze/crd.go index c5b751d3..980ebe50 100644 --- a/pkg/analyze/crd.go +++ b/pkg/analyze/crd.go @@ -9,8 +9,34 @@ import ( apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" ) -func analyzeCustomResourceDefinition(analyzer *troubleshootv1beta2.CustomResourceDefinition, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - crdData, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_CUSTOM_RESOURCE_DEFINITIONS)) +type AnalyzeCustomResourceDefinition struct { + analyzer *troubleshootv1beta2.CustomResourceDefinition +} + +func (a *AnalyzeCustomResourceDefinition) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = fmt.Sprintf("Custom resource definition %s", a.analyzer.CustomResourceDefinitionName) + } + + return title +} + +func (a *AnalyzeCustomResourceDefinition) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeCustomResourceDefinition) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeCustomResourceDefinition(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeCustomResourceDefinition) analyzeCustomResourceDefinition(analyzer *troubleshootv1beta2.CustomResourceDefinition, getFile getCollectedFileContents) (*AnalyzeResult, error) { + crdData, err := getFile(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_CUSTOM_RESOURCE_DEFINITIONS)) if err != nil { return nil, err } @@ -20,13 +46,8 @@ func analyzeCustomResourceDefinition(analyzer *troubleshootv1beta2.CustomResourc return nil, err } - title := analyzer.CheckName - if title == "" { - title = fmt.Sprintf("Custom resource definition %s", analyzer.CustomResourceDefinitionName) - } - result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_custom_resource_definition", IconURI: "https://troubleshoot.sh/images/analyzer-icons/custom-resource-definition.svg?w=13&h=16", } diff --git a/pkg/analyze/deployment_status.go b/pkg/analyze/deployment_status.go index ca405e39..3302be7f 100644 --- a/pkg/analyze/deployment_status.go +++ b/pkg/analyze/deployment_status.go @@ -11,6 +11,44 @@ import ( appsv1 "k8s.io/api/apps/v1" ) +type AnalyzeDeploymentStatus struct { + analyzer *troubleshootv1beta2.DeploymentStatus +} + +func (a *AnalyzeDeploymentStatus) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + if a.analyzer.Name != "" && a.analyzer.Namespace != "" { + return fmt.Sprintf("%s/%s Deployment Status", a.analyzer.Name, a.analyzer.Name) + } + + if a.analyzer.Name != "" { + return fmt.Sprintf("%s Deployment Status", a.analyzer.Name) + } + if a.analyzer.Namespace != "" { + return fmt.Sprintf("%s Deployment Status", a.analyzer.Namespace) + } + + return "Deployment Status" +} + +func (a *AnalyzeDeploymentStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeDeploymentStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeDeploymentStatus(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeDeploymentStatus(analyzer *troubleshootv1beta2.DeploymentStatus, getFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { if analyzer.Name == "" { return analyzeAllDeploymentStatuses(analyzer, getFileContents) diff --git a/pkg/analyze/distribution.go b/pkg/analyze/distribution.go index 4959b3c0..656c1ca0 100644 --- a/pkg/analyze/distribution.go +++ b/pkg/analyze/distribution.go @@ -47,6 +47,32 @@ const ( k3s Provider = iota ) +type AnalyzeDistribution struct { + analyzer *troubleshootv1beta2.Distribution +} + +func (a *AnalyzeDistribution) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Kubernetes Distribution" + } + + return title +} + +func (a *AnalyzeDistribution) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeDistribution) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeDistribution(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + func CheckApiResourcesForProviders(foundProviders *providers, apiResources []*metav1.APIResourceList, provider string) string { for _, resource := range apiResources { if strings.HasPrefix(resource.GroupVersion, "apps.openshift.io/") { @@ -142,7 +168,7 @@ func ParseNodesForProviders(nodes []corev1.Node) (providers, string) { return foundProviders, stringProvider } -func analyzeDistribution(analyzer *troubleshootv1beta2.Distribution, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +func (a *AnalyzeDistribution) analyzeDistribution(analyzer *troubleshootv1beta2.Distribution, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { var unknownDistribution string collected, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_NODES)) if err != nil { @@ -167,12 +193,8 @@ func analyzeDistribution(analyzer *troubleshootv1beta2.Distribution, getCollecte _ = CheckApiResourcesForProviders(&foundProviders, apiResources, "") } - title := analyzer.CheckName - if title == "" { - title = "Kubernetes Distribution" - } result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_distribution", IconURI: "https://troubleshoot.sh/images/analyzer-icons/distribution.svg?w=20&h=14", } diff --git a/pkg/analyze/image_pull_secret.go b/pkg/analyze/image_pull_secret.go index 29139394..19d3d5c5 100644 --- a/pkg/analyze/image_pull_secret.go +++ b/pkg/analyze/image_pull_secret.go @@ -9,7 +9,33 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/constants" ) -func analyzeImagePullSecret(analyzer *troubleshootv1beta2.ImagePullSecret, getChildCollectedFileContents getChildCollectedFileContents) (*AnalyzeResult, error) { +type AnalyzeImagePullSecret struct { + analyzer *troubleshootv1beta2.ImagePullSecret +} + +func (a *AnalyzeImagePullSecret) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Image Pull Secrets" + } + + return title +} + +func (a *AnalyzeImagePullSecret) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeImagePullSecret) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeImagePullSecret(a.analyzer, findFiles) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeImagePullSecret) analyzeImagePullSecret(analyzer *troubleshootv1beta2.ImagePullSecret, getChildCollectedFileContents getChildCollectedFileContents) (*AnalyzeResult, error) { var excludeFiles = []string{} imagePullSecrets, err := getChildCollectedFileContents(fmt.Sprintf("%s/%s", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_IMAGE_PULL_SECRETS), excludeFiles) if err != nil { @@ -25,13 +51,9 @@ func analyzeImagePullSecret(analyzer *troubleshootv1beta2.ImagePullSecret, getCh passOutcome = outcome.Pass } } - title := analyzer.CheckName - if title == "" { - title = "Image Pull Secrets" - } result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_image_pull_secret", IconURI: "https://troubleshoot.sh/images/analyzer-icons/image-pull-secret.svg?w=16&h=14", IsFail: true, diff --git a/pkg/analyze/ingress.go b/pkg/analyze/ingress.go index ea7244ee..862893ec 100644 --- a/pkg/analyze/ingress.go +++ b/pkg/analyze/ingress.go @@ -10,7 +10,33 @@ import ( extensionsv1beta1 "k8s.io/api/extensions/v1beta1" ) -func analyzeIngress(analyzer *troubleshootv1beta2.Ingress, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeIngress struct { + analyzer *troubleshootv1beta2.Ingress +} + +func (a *AnalyzeIngress) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = fmt.Sprintf("Ingress %s", a.analyzer.IngressName) + } + + return title +} + +func (a *AnalyzeIngress) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeIngress) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeIngress(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeIngress) analyzeIngress(analyzer *troubleshootv1beta2.Ingress, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { ingressData, err := getCollectedFileContents(filepath.Join(constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_INGRESS, fmt.Sprintf("%s.json", analyzer.Namespace))) if err != nil { return nil, err @@ -21,13 +47,8 @@ func analyzeIngress(analyzer *troubleshootv1beta2.Ingress, getCollectedFileConte return nil, err } - title := analyzer.CheckName - if title == "" { - title = fmt.Sprintf("Ingress %s", analyzer.IngressName) - } - result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_ingress", IconURI: "https://troubleshoot.sh/images/analyzer-icons/ingress-controller.svg?w=20&h=13", } diff --git a/pkg/analyze/job_status.go b/pkg/analyze/job_status.go index fdbfc096..37564196 100644 --- a/pkg/analyze/job_status.go +++ b/pkg/analyze/job_status.go @@ -13,6 +13,44 @@ import ( batchv1 "k8s.io/api/batch/v1" ) +type AnalyzeJobStatus struct { + analyzer *troubleshootv1beta2.JobStatus +} + +func (a *AnalyzeJobStatus) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + if a.analyzer.Name != "" && a.analyzer.Namespace != "" { + return fmt.Sprintf("%s/%s Job Status", a.analyzer.Namespace, a.analyzer.Name) + } + + if a.analyzer.Name != "" { + return fmt.Sprintf("%s Job Status", a.analyzer.Name) + } + if a.analyzer.Namespace != "" { + return fmt.Sprintf("%s Job Status", a.analyzer.Namespace) + } + + return "Job Status" +} + +func (a *AnalyzeJobStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeJobStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeJobStatus(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeJobStatus(analyzer *troubleshootv1beta2.JobStatus, getFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { if analyzer.Name == "" { return analyzeAllJobStatuses(analyzer, getFileContents) diff --git a/pkg/analyze/json_compare.go b/pkg/analyze/json_compare.go index 4dc7a112..242d8cfe 100644 --- a/pkg/analyze/json_compare.go +++ b/pkg/analyze/json_compare.go @@ -11,7 +11,33 @@ import ( iutils "github.com/replicatedhq/troubleshoot/pkg/interfaceutils" ) -func analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeJsonCompare struct { + analyzer *troubleshootv1beta2.JsonCompare +} + +func (a *AnalyzeJsonCompare) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.analyzer.CollectorName + } + + return title +} + +func (a *AnalyzeJsonCompare) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeJsonCompare) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeJsonCompare(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { fullPath := filepath.Join(analyzer.CollectorName, analyzer.FileName) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -37,13 +63,8 @@ func analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedF return nil, errors.Wrap(err, "failed to parse expected value as json") } - title := analyzer.CheckName - if title == "" { - title = analyzer.CollectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", } @@ -103,7 +124,7 @@ func analyzeJsonCompare(analyzer *troubleshootv1beta2.JsonCompare, getCollectedF } return &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsFail: true, diff --git a/pkg/analyze/json_compare_test.go b/pkg/analyze/json_compare_test.go index 4fd0bd71..5c7d6f77 100644 --- a/pkg/analyze/json_compare_test.go +++ b/pkg/analyze/json_compare_test.go @@ -551,7 +551,11 @@ func Test_jsonCompare(t *testing.T) { return test.fileContents, nil } - actual, err := analyzeJsonCompare(&test.analyzer, getCollectedFileContents) + a := AnalyzeJsonCompare{ + analyzer: &test.analyzer, + } + + actual, err := a.analyzeJsonCompare(&test.analyzer, getCollectedFileContents) if !test.isError { req.NoError(err) req.Equal(test.expectResult, *actual) diff --git a/pkg/analyze/kube_resource.go b/pkg/analyze/kube_resource.go index f9d82f5d..64a8ae94 100644 --- a/pkg/analyze/kube_resource.go +++ b/pkg/analyze/kube_resource.go @@ -32,6 +32,31 @@ var Filemap = map[string]string{ "StorageClass": fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_STORAGE_CLASS), } +type AnalyzeClusterResource struct { + analyzer *troubleshootv1beta2.ClusterResource +} + +func (a *AnalyzeClusterResource) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.analyzer.CollectorName + } + + return title +} + +func (a *AnalyzeClusterResource) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeClusterResource) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeResource(a.analyzer, getFile) + if err != nil { + return nil, err + } + return []*AnalyzeResult{result}, nil +} + // FindResource locates and returns a kubernetes resource as an interface{} from a support bundle based on some basic selectors // if clusterScoped is false and namespace is not provided, it will default to looking in the "default" namespace func FindResource(kind string, clusterScoped bool, namespace string, name string, getFileContents getCollectedFileContents) (interface{}, error) { @@ -82,7 +107,7 @@ func FindResource(kind string, clusterScoped bool, namespace string, name string } -func analyzeResource(analyzer *troubleshootv1beta2.ClusterResource, getFileContents getCollectedFileContents) (*AnalyzeResult, error) { +func (a *AnalyzeClusterResource) analyzeResource(analyzer *troubleshootv1beta2.ClusterResource, getFileContents getCollectedFileContents) (*AnalyzeResult, error) { selected, err := FindResource(analyzer.Kind, analyzer.ClusterScoped, analyzer.Namespace, analyzer.Name, getFileContents) if err != nil { @@ -100,13 +125,8 @@ func analyzeResource(analyzer *troubleshootv1beta2.ClusterResource, getFileConte return nil, errors.Wrap(err, "failed to parse expected value as yaml doc") } - title := analyzer.CheckName - if title == "" { - title = analyzer.CollectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", } @@ -163,7 +183,7 @@ func analyzeResource(analyzer *troubleshootv1beta2.ClusterResource, getFileConte } return &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsFail: true, diff --git a/pkg/analyze/longhorn.go b/pkg/analyze/longhorn.go index bb70a12b..a9e82445 100644 --- a/pkg/analyze/longhorn.go +++ b/pkg/analyze/longhorn.go @@ -17,6 +17,29 @@ import ( "gopkg.in/yaml.v2" ) +type AnalyzeLonghorn struct { + analyzer *troubleshootv1beta2.LonghornAnalyze +} + +func (a *AnalyzeLonghorn) Title() string { + return "Longhorn analyzer" +} + +func (a *AnalyzeLonghorn) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeLonghorn) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := longhorn(a.analyzer, getFile, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func longhorn(analyzer *troubleshootv1beta2.LonghornAnalyze, getFileContents getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { ns := collect.DefaultLonghornNamespace if analyzer.Namespace != "" { diff --git a/pkg/analyze/mysql.go b/pkg/analyze/mysql.go index bd332cdd..94e486b1 100644 --- a/pkg/analyze/mysql.go +++ b/pkg/analyze/mysql.go @@ -10,13 +10,41 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeMysql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - collectorName := analyzer.CollectorName - if collectorName == "" { - collectorName = "mysql" +type AnalyzeMysql struct { + analyzer *troubleshootv1beta2.DatabaseAnalyze +} + +func (a *AnalyzeMysql) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.collectorName() } - fullPath := path.Join("mysql", fmt.Sprintf("%s.json", collectorName)) + return title +} + +func (a *AnalyzeMysql) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeMysql) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeMysql(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeMysql) collectorName() string { + if a.analyzer.CollectorName != "" { + return a.analyzer.CollectorName + } + return "mysql" +} + +func (a *AnalyzeMysql) analyzeMysql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + fullPath := path.Join("mysql", fmt.Sprintf("%s.json", a.collectorName())) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -28,13 +56,8 @@ func analyzeMysql(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFil return nil, errors.Wrap(err, "failed to unmarshal databased connection result") } - title := analyzer.CheckName - if title == "" { - title = collectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_mysql_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/mysql-analyze.svg", } diff --git a/pkg/analyze/node_resources.go b/pkg/analyze/node_resources.go index ad85d868..37618e6c 100644 --- a/pkg/analyze/node_resources.go +++ b/pkg/analyze/node_resources.go @@ -14,7 +14,33 @@ import ( "k8s.io/apimachinery/pkg/api/resource" ) -func analyzeNodeResources(analyzer *troubleshootv1beta2.NodeResources, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeNodeResources struct { + analyzer *troubleshootv1beta2.NodeResources +} + +func (a *AnalyzeNodeResources) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = "Node Resources" + } + + return title +} + +func (a *AnalyzeNodeResources) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeNodeResources) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeNodeResources(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeNodeResources) analyzeNodeResources(analyzer *troubleshootv1beta2.NodeResources, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { collected, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_NODES)) if err != nil { return nil, errors.Wrap(err, "failed to get contents of nodes.json") @@ -38,13 +64,8 @@ func analyzeNodeResources(analyzer *troubleshootv1beta2.NodeResources, getCollec } } - title := analyzer.CheckName - if title == "" { - title = "Node Resources" - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_node_resources", IconURI: "https://troubleshoot.sh/images/analyzer-icons/node-resources.svg?w=16&h=18", } diff --git a/pkg/analyze/node_resources_test.go b/pkg/analyze/node_resources_test.go index 0aeacc9c..ac8b1c0f 100644 --- a/pkg/analyze/node_resources_test.go +++ b/pkg/analyze/node_resources_test.go @@ -936,7 +936,11 @@ func Test_analyzeNodeResources(t *testing.T) { t.Run(tt.name, func(t *testing.T) { req := require.New(t) - got, err := analyzeNodeResources(tt.analyzer, getExampleNodeContents) + a := AnalyzeNodeResources{ + analyzer: tt.analyzer, + } + + got, err := a.analyzeNodeResources(tt.analyzer, getExampleNodeContents) req.NoError(err) req.Equal(tt.want, got) }) diff --git a/pkg/analyze/postgres.go b/pkg/analyze/postgres.go index 9b15ce85..15a6e050 100644 --- a/pkg/analyze/postgres.go +++ b/pkg/analyze/postgres.go @@ -10,13 +10,43 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzePostgres(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - collectorName := analyzer.CollectorName +type AnalyzePostgres struct { + analyzer *troubleshootv1beta2.DatabaseAnalyze +} + +func (a *AnalyzePostgres) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.collectorName() + } + + return title +} + +func (a *AnalyzePostgres) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzePostgres) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzePostgres(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzePostgres) collectorName() string { + collectorName := a.analyzer.CollectorName if collectorName == "" { collectorName = "postgres" } - fullPath := path.Join("postgres", fmt.Sprintf("%s.json", collectorName)) + return collectorName +} + +func (a *AnalyzePostgres) analyzePostgres(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + fullPath := path.Join("postgres", fmt.Sprintf("%s.json", a.collectorName())) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -28,13 +58,8 @@ func analyzePostgres(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollected return nil, errors.Wrap(err, "failed to unmarshal databased connection result") } - title := analyzer.CheckName - if title == "" { - title = collectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_postgres_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/postgres-analyze.svg", } diff --git a/pkg/analyze/redis.go b/pkg/analyze/redis.go index a9bd6335..b8cf6b59 100644 --- a/pkg/analyze/redis.go +++ b/pkg/analyze/redis.go @@ -10,13 +10,43 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeRedis(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - collectorName := analyzer.CollectorName +type AnalyzeRedis struct { + analyzer *troubleshootv1beta2.DatabaseAnalyze +} + +func (a *AnalyzeRedis) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.collectorName() + } + + return title +} + +func (a *AnalyzeRedis) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeRedis) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeRedis(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeRedis) collectorName() string { + collectorName := a.analyzer.CollectorName if collectorName == "" { collectorName = "redis" } - fullPath := path.Join("redis", fmt.Sprintf("%s.json", collectorName)) + return collectorName +} + +func (a *AnalyzeRedis) analyzeRedis(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + fullPath := path.Join("redis", fmt.Sprintf("%s.json", a.collectorName())) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -28,13 +58,8 @@ func analyzeRedis(analyzer *troubleshootv1beta2.DatabaseAnalyze, getCollectedFil return nil, errors.Wrap(err, "failed to unmarshal database connection result") } - title := analyzer.CheckName - if title == "" { - title = collectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_redis_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/redis-analyze.svg", } diff --git a/pkg/analyze/registry.go b/pkg/analyze/registry.go index eb25e7b4..abababd8 100644 --- a/pkg/analyze/registry.go +++ b/pkg/analyze/registry.go @@ -12,13 +12,43 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeRegistry(analyzer *troubleshootv1beta2.RegistryImagesAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { - collectorName := analyzer.CollectorName +type AnalyzeRegistryImages struct { + analyzer *troubleshootv1beta2.RegistryImagesAnalyze +} + +func (a *AnalyzeRegistryImages) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.collectorName() + } + + return title +} + +func (a *AnalyzeRegistryImages) collectorName() string { + collectorName := a.analyzer.CollectorName if collectorName == "" { collectorName = "images" } - fullPath := path.Join("registry", fmt.Sprintf("%s.json", collectorName)) + return collectorName +} + +func (a *AnalyzeRegistryImages) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeRegistryImages) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeRegistry(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeRegistryImages) analyzeRegistry(analyzer *troubleshootv1beta2.RegistryImagesAnalyze, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { + fullPath := path.Join("registry", fmt.Sprintf("%s.json", a.collectorName())) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -43,13 +73,8 @@ func analyzeRegistry(analyzer *troubleshootv1beta2.RegistryImagesAnalyze, getCol } } - title := analyzer.CheckName - if title == "" { - title = collectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_registry_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/registry-analyze.svg", } diff --git a/pkg/analyze/replicaset_status.go b/pkg/analyze/replicaset_status.go index ca5e7d2f..d4bc2758 100644 --- a/pkg/analyze/replicaset_status.go +++ b/pkg/analyze/replicaset_status.go @@ -14,6 +14,44 @@ import ( "k8s.io/apimachinery/pkg/labels" ) +type AnalyzeReplicaSetStatus struct { + analyzer *troubleshootv1beta2.ReplicaSetStatus +} + +func (a *AnalyzeReplicaSetStatus) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + if a.analyzer.Name != "" && a.analyzer.Namespace != "" { + return fmt.Sprintf("%s/%s ReplicaSet Status", a.analyzer.Namespace, a.analyzer.Name) + } + + if a.analyzer.Name != "" { + return fmt.Sprintf("%s ReplicaSet Status", a.analyzer.Name) + } + if a.analyzer.Namespace != "" { + return fmt.Sprintf("%s ReplicaSet Status", a.analyzer.Namespace) + } + + return "ReplicaSet Status" +} + +func (a *AnalyzeReplicaSetStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeReplicaSetStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeReplicaSetStatus(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeReplicaSetStatus(analyzer *troubleshootv1beta2.ReplicaSetStatus, getFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { if analyzer.Name == "" { return analyzeAllReplicaSetStatuses(analyzer, getFileContents) diff --git a/pkg/analyze/secret.go b/pkg/analyze/secret.go index e4f51285..32486064 100644 --- a/pkg/analyze/secret.go +++ b/pkg/analyze/secret.go @@ -8,7 +8,33 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" ) -func analyzeSecret(analyzer *troubleshootv1beta2.AnalyzeSecret, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeSecret struct { + analyzer *troubleshootv1beta2.AnalyzeSecret +} + +func (a *AnalyzeSecret) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = fmt.Sprintf("Secret %s", a.analyzer.SecretName) + } + + return title +} + +func (a *AnalyzeSecret) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeSecret) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeSecret(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeSecret) analyzeSecret(analyzer *troubleshootv1beta2.AnalyzeSecret, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { filename := collect.GetSecretFileName( &troubleshootv1beta2.Secret{ Namespace: analyzer.Namespace, @@ -28,13 +54,8 @@ func analyzeSecret(analyzer *troubleshootv1beta2.AnalyzeSecret, getCollectedFile return nil, err } - title := analyzer.CheckName - if title == "" { - title = fmt.Sprintf("Secret %s", analyzer.SecretName) - } - result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_analyze_secret", IconURI: "https://troubleshoot.sh/images/analyzer-icons/secret.svg?w=13&h=16", } diff --git a/pkg/analyze/secret_test.go b/pkg/analyze/secret_test.go index 8744b7ee..f8945f1e 100644 --- a/pkg/analyze/secret_test.go +++ b/pkg/analyze/secret_test.go @@ -200,7 +200,10 @@ func Test_analyzeSecret(t *testing.T) { } return contents, nil } - got, err := analyzeSecret(tt.analyzer, getCollectedFileContents) + a := AnalyzeSecret{ + analyzer: tt.analyzer, + } + got, err := a.analyzeSecret(tt.analyzer, getCollectedFileContents) if tt.wantErr { assert.Error(t, err) } else { diff --git a/pkg/analyze/statefulset_status.go b/pkg/analyze/statefulset_status.go index d2836db2..1c874163 100644 --- a/pkg/analyze/statefulset_status.go +++ b/pkg/analyze/statefulset_status.go @@ -11,6 +11,44 @@ import ( appsv1 "k8s.io/api/apps/v1" ) +type AnalyzeStatefulsetStatus struct { + analyzer *troubleshootv1beta2.StatefulsetStatus +} + +func (a *AnalyzeStatefulsetStatus) Title() string { + if a.analyzer.CheckName != "" { + return a.analyzer.CheckName + } + + if a.analyzer.Name != "" && a.analyzer.Namespace != "" { + return fmt.Sprintf("%s/%s Statefulset Status", a.analyzer.Namespace, a.analyzer.Name) + } + + if a.analyzer.Name != "" { + return fmt.Sprintf("%s Statefulset Status", a.analyzer.Name) + } + if a.analyzer.Namespace != "" { + return fmt.Sprintf("%s Statefulset Status", a.analyzer.Namespace) + } + + return "Statefulset Status" +} + +func (a *AnalyzeStatefulsetStatus) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeStatefulsetStatus) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeStatefulsetStatus(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeStatefulsetStatus(analyzer *troubleshootv1beta2.StatefulsetStatus, getFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { if analyzer.Name == "" { return analyzeAllStatefulsetStatuses(analyzer, getFileContents) diff --git a/pkg/analyze/storage_class.go b/pkg/analyze/storage_class.go index 450c6a67..f9564d57 100644 --- a/pkg/analyze/storage_class.go +++ b/pkg/analyze/storage_class.go @@ -9,7 +9,37 @@ import ( storagev1beta1 "k8s.io/api/storage/v1beta1" ) -func analyzeStorageClass(analyzer *troubleshootv1beta2.StorageClass, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeStorageClass struct { + analyzer *troubleshootv1beta2.StorageClass +} + +func (a *AnalyzeStorageClass) Title() string { + title := a.analyzer.CheckName + if title == "" { + if a.analyzer.StorageClassName != "" { + title = fmt.Sprintf("Storage class %s", a.analyzer.StorageClassName) + } else { + title = "Default Storage Class" + } + } + + return title +} + +func (a *AnalyzeStorageClass) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeStorageClass) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeStorageClass(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeStorageClass) analyzeStorageClass(analyzer *troubleshootv1beta2.StorageClass, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { storageClassesData, err := getCollectedFileContents(fmt.Sprintf("%s/%s.json", constants.CLUSTER_RESOURCES_DIR, constants.CLUSTER_RESOURCES_STORAGE_CLASS)) if err != nil { return nil, err @@ -20,23 +50,14 @@ func analyzeStorageClass(analyzer *troubleshootv1beta2.StorageClass, getCollecte return nil, err } - title := analyzer.CheckName - if title == "" { - if analyzer.StorageClassName != "" { - title = fmt.Sprintf("Storage class %s", analyzer.StorageClassName) - } else { - title = "Default Storage Class" - } - } - result := AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_storage_class", IconURI: "https://troubleshoot.sh/images/analyzer-icons/storage-class.svg?w=12&h=12", } for _, storageClass := range storageClasses.Items { - val, _ := storageClass.Annotations["storageclass.kubernetes.io/is-default-class"] + val := storageClass.Annotations["storageclass.kubernetes.io/is-default-class"] if (storageClass.Name == analyzer.StorageClassName) || (analyzer.StorageClassName == "" && val == "true") { result.IsPass = true for _, outcome := range analyzer.Outcomes { diff --git a/pkg/analyze/sysctl.go b/pkg/analyze/sysctl.go index 9ab717b9..98263d76 100644 --- a/pkg/analyze/sysctl.go +++ b/pkg/analyze/sysctl.go @@ -14,10 +14,34 @@ import ( troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" ) +type AnalyzeSysctl struct { + analyzer *troubleshootv1beta2.SysctlAnalyze +} + +func (a *AnalyzeSysctl) Title() string { + return "Sysctl" +} + +func (a *AnalyzeSysctl) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeSysctl) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeSysctl(a.analyzer, findFiles) + if err != nil { + return nil, err + } + if result == nil { + return []*AnalyzeResult{}, nil + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + // The when condition for outcomes in this analyzer is interpreted as "for some node". // For example, "when: net.ipv4.ip_forward = 0" is true if at least one node has IP forwarding // disabled. -func analyzeSysctl(analyzer *troubleshootv1beta2.SysctlAnalyze, findFiles getChildCollectedFileContents) (*AnalyzeResult, error) { +func (a *AnalyzeSysctl) analyzeSysctl(analyzer *troubleshootv1beta2.SysctlAnalyze, findFiles getChildCollectedFileContents) (*AnalyzeResult, error) { excludeFiles := []string{} files, err := findFiles("sysctl/*", excludeFiles) if err != nil { @@ -42,7 +66,7 @@ func analyzeSysctl(analyzer *troubleshootv1beta2.SysctlAnalyze, findFiles getChi if result != nil { result.Title = analyzer.CheckName if result.Title == "" { - result.Title = "Sysctl" + result.Title = a.Title() } return result, nil } diff --git a/pkg/analyze/sysctl_test.go b/pkg/analyze/sysctl_test.go index 6e1599f4..670d218a 100644 --- a/pkg/analyze/sysctl_test.go +++ b/pkg/analyze/sysctl_test.go @@ -403,7 +403,11 @@ func TestAnalyzeSysctl(t *testing.T) { var findFiles = func(glob string, _ []string) (map[string][]byte, error) { return test.files, nil } - got, err := analyzeSysctl(test.analyzer, findFiles) + + a := AnalyzeSysctl{ + analyzer: test.analyzer, + } + got, err := a.analyzeSysctl(test.analyzer, findFiles) assert.NoError(t, err) diff --git a/pkg/analyze/text_analyze.go b/pkg/analyze/text_analyze.go index 6e14f6fd..31b63da0 100644 --- a/pkg/analyze/text_analyze.go +++ b/pkg/analyze/text_analyze.go @@ -13,7 +13,35 @@ import ( troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" ) -func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { +type AnalyzeTextAnalyze struct { + analyzer *troubleshootv1beta2.TextAnalyze +} + +func (a *AnalyzeTextAnalyze) Title() string { + checkName := a.analyzer.CheckName + if checkName == "" { + checkName = a.analyzer.CollectorName + } + + return checkName +} + +func (a *AnalyzeTextAnalyze) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeTextAnalyze) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := a.analyzeTextAnalyze(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + +func (a *AnalyzeTextAnalyze) analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedFileContents getChildCollectedFileContents) ([]*AnalyzeResult, error) { fullPath := filepath.Join(analyzer.CollectorName, analyzer.FileName) excludeFiles := []string{} for _, excludeFile := range analyzer.ExcludeFiles { @@ -25,11 +53,6 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF return nil, errors.Wrapf(err, "failed to read collected file name: %s", fullPath) } - checkName := analyzer.CheckName - if checkName == "" { - checkName = analyzer.CollectorName - } - if len(collected) == 0 { if analyzer.IgnoreIfNoFiles { return nil, nil @@ -37,7 +60,7 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF return []*AnalyzeResult{ { - Title: checkName, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsWarn: true, @@ -50,7 +73,7 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF if analyzer.RegexPattern != "" { for _, fileContents := range collected { - result, err := analyzeRegexPattern(analyzer.RegexPattern, fileContents, analyzer.Outcomes, checkName) + result, err := analyzeRegexPattern(analyzer.RegexPattern, fileContents, analyzer.Outcomes, a.Title()) if err != nil { return nil, err } @@ -62,7 +85,7 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF if analyzer.RegexGroups != "" { for _, fileContents := range collected { - result, err := analyzeRegexGroups(analyzer.RegexGroups, fileContents, analyzer.Outcomes, checkName) + result, err := analyzeRegexGroups(analyzer.RegexGroups, fileContents, analyzer.Outcomes, a.Title()) if err != nil { return nil, err } @@ -78,7 +101,7 @@ func analyzeTextAnalyze(analyzer *troubleshootv1beta2.TextAnalyze, getCollectedF return []*AnalyzeResult{ { - Title: checkName, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsFail: true, diff --git a/pkg/analyze/text_analyze_test.go b/pkg/analyze/text_analyze_test.go index 17822ff9..eab5eb0a 100644 --- a/pkg/analyze/text_analyze_test.go +++ b/pkg/analyze/text_analyze_test.go @@ -727,7 +727,11 @@ func Test_textAnalyze(t *testing.T) { return matching, nil } - actual, err := analyzeTextAnalyze(&test.analyzer, getFiles) + a := AnalyzeTextAnalyze{ + analyzer: &test.analyzer, + } + + actual, err := a.analyzeTextAnalyze(&test.analyzer, getFiles) req.NoError(err) unPointered := []AnalyzeResult{} diff --git a/pkg/analyze/weave.go b/pkg/analyze/weave.go index fd7462e8..9dc17919 100644 --- a/pkg/analyze/weave.go +++ b/pkg/analyze/weave.go @@ -39,6 +39,29 @@ type WeaveAttributes struct { Name string `json:"name"` } +type AnalyzeWeaveReport struct { + analyzer *troubleshootv1beta2.WeaveReportAnalyze +} + +func (a *AnalyzeWeaveReport) Title() string { + return "Weave CNI" +} + +func (a *AnalyzeWeaveReport) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeWeaveReport) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + results, err := analyzeWeaveReport(a.analyzer, findFiles) + if err != nil { + return nil, err + } + for i := range results { + results[i].Strict = a.analyzer.Strict.BoolOrDefaultFalse() + } + return results, nil +} + func analyzeWeaveReport(analyzer *troubleshootv1beta2.WeaveReportAnalyze, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { excludeFiles := []string{} files, err := findFiles(analyzer.ReportFileGlob, excludeFiles) diff --git a/pkg/analyze/yaml_compare.go b/pkg/analyze/yaml_compare.go index 9b72affb..1a9760bf 100644 --- a/pkg/analyze/yaml_compare.go +++ b/pkg/analyze/yaml_compare.go @@ -11,7 +11,33 @@ import ( "gopkg.in/yaml.v2" ) -func analyzeYamlCompare(analyzer *troubleshootv1beta2.YamlCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { +type AnalyzeYamlCompare struct { + analyzer *troubleshootv1beta2.YamlCompare +} + +func (a *AnalyzeYamlCompare) Title() string { + title := a.analyzer.CheckName + if title == "" { + title = a.analyzer.CollectorName + } + + return title +} + +func (a *AnalyzeYamlCompare) IsExcluded() (bool, error) { + return isExcluded(a.analyzer.Exclude) +} + +func (a *AnalyzeYamlCompare) Analyze(getFile getCollectedFileContents, findFiles getChildCollectedFileContents) ([]*AnalyzeResult, error) { + result, err := a.analyzeYamlCompare(a.analyzer, getFile) + if err != nil { + return nil, err + } + result.Strict = a.analyzer.Strict.BoolOrDefaultFalse() + return []*AnalyzeResult{result}, nil +} + +func (a *AnalyzeYamlCompare) analyzeYamlCompare(analyzer *troubleshootv1beta2.YamlCompare, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) { fullPath := filepath.Join(analyzer.CollectorName, analyzer.FileName) collected, err := getCollectedFileContents(fullPath) if err != nil { @@ -37,13 +63,8 @@ func analyzeYamlCompare(analyzer *troubleshootv1beta2.YamlCompare, getCollectedF return nil, errors.Wrap(err, "failed to parse expected value as yaml doc") } - title := analyzer.CheckName - if title == "" { - title = analyzer.CollectorName - } - result := &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", } @@ -100,7 +121,7 @@ func analyzeYamlCompare(analyzer *troubleshootv1beta2.YamlCompare, getCollectedF } return &AnalyzeResult{ - Title: title, + Title: a.Title(), IconKey: "kubernetes_text_analyze", IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg", IsFail: true, diff --git a/pkg/analyze/yaml_compare_test.go b/pkg/analyze/yaml_compare_test.go index 737f4a79..f7d43941 100644 --- a/pkg/analyze/yaml_compare_test.go +++ b/pkg/analyze/yaml_compare_test.go @@ -440,7 +440,11 @@ otherstuff: return test.fileContents, nil } - actual, err := analyzeYamlCompare(&test.analyzer, getCollectedFileContents) + a := AnalyzeYamlCompare{ + analyzer: &test.analyzer, + } + + actual, err := a.analyzeYamlCompare(&test.analyzer, getCollectedFileContents) if !test.isError { req.NoError(err) req.Equal(test.expectResult, *actual) diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 0238224d..40f1781b 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -33,7 +33,7 @@ const ( CLUSTER_RESOURCES_STORAGE_CLASS = "storage-classes" CLUSTER_RESOURCES_CUSTOM_RESOURCE_DEFINITIONS = "custom-resource-definitions" CLUSTER_RESOURCES_CUSTOM_RESOURCES = "custom-resources" - CLUSTER_RESOURCES_IMAGE_PULL_SECRETS = "image-pull-secrets" + CLUSTER_RESOURCES_IMAGE_PULL_SECRETS = "image-pull-secrets" // nolint:gosec CLUSTER_RESOURCES_NODES = "nodes" CLUSTER_RESOURCES_GROUPS = "groups" CLUSTER_RESOURCES_RESOURCES = "resources"