Skip to content

Commit

Permalink
chore: Refactor in-cluster analyzers
Browse files Browse the repository at this point in the history
Have all in-cluster analysers implement the same interface. This
will help with the implementation of code that requires making
calls to all analysers
  • Loading branch information
banjoh committed Feb 1, 2023
1 parent 0f6e633 commit 3910278
Show file tree
Hide file tree
Showing 39 changed files with 962 additions and 585 deletions.
508 changes: 86 additions & 422 deletions pkg/analyze/analyzer.go

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions pkg/analyze/analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
37 changes: 30 additions & 7 deletions pkg/analyze/ceph.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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",
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/analyze/ceph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
27 changes: 27 additions & 0 deletions pkg/analyze/cluster_pod_statuses.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
36 changes: 30 additions & 6 deletions pkg/analyze/cluster_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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",
}
Expand Down
35 changes: 28 additions & 7 deletions pkg/analyze/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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",
}
Expand Down
7 changes: 6 additions & 1 deletion pkg/analyze/configmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
34 changes: 28 additions & 6 deletions pkg/analyze/container_runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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",
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/analyze/container_runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
37 changes: 29 additions & 8 deletions pkg/analyze/crd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,45 @@ 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
}

var crds apiextensionsv1beta1.CustomResourceDefinitionList
if err := json.Unmarshal(crdData, &crds); err != 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
}

title := analyzer.CheckName
if title == "" {
title = fmt.Sprintf("Custom resource definition %s", analyzer.CustomResourceDefinitionName)
var crds apiextensionsv1beta1.CustomResourceDefinitionList
if err := json.Unmarshal(crdData, &crds); err != nil {
return nil, err
}

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",
}
Expand Down
38 changes: 38 additions & 0 deletions pkg/analyze/deployment_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 3910278

Please sign in to comment.