Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: New host collector and analyzer for Kernel Configs #1546

Merged
merged 11 commits into from
May 26, 2024
49 changes: 49 additions & 0 deletions config/crds/troubleshoot.sh_analyzers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2299,6 +2299,55 @@ spec:
required:
- outcomes
type: object
kernelConfigs:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- outcomes
type: object
kernelModules:
properties:
annotations:
Expand Down
56 changes: 56 additions & 0 deletions config/crds/troubleshoot.sh_hostcollectors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,55 @@ spec:
required:
- outcomes
type: object
kernelConfigs:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- outcomes
type: object
kernelModules:
properties:
annotations:
Expand Down Expand Up @@ -1338,6 +1387,13 @@ spec:
exclude:
type: BoolString
type: object
kernelConfigs:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
kernelModules:
properties:
collectorName:
Expand Down
56 changes: 56 additions & 0 deletions config/crds/troubleshoot.sh_hostpreflights.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,55 @@ spec:
required:
- outcomes
type: object
kernelConfigs:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- outcomes
type: object
kernelModules:
properties:
annotations:
Expand Down Expand Up @@ -1338,6 +1387,13 @@ spec:
exclude:
type: BoolString
type: object
kernelConfigs:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
kernelModules:
properties:
collectorName:
Expand Down
56 changes: 56 additions & 0 deletions config/crds/troubleshoot.sh_supportbundles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19138,6 +19138,55 @@ spec:
required:
- outcomes
type: object
kernelConfigs:
properties:
annotations:
additionalProperties:
type: string
type: object
checkName:
type: string
collectorName:
type: string
exclude:
type: BoolString
outcomes:
items:
properties:
fail:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
pass:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
warn:
properties:
message:
type: string
uri:
type: string
when:
type: string
type: object
type: object
type: array
strict:
type: BoolString
required:
- outcomes
type: object
kernelModules:
properties:
annotations:
Expand Down Expand Up @@ -19888,6 +19937,13 @@ spec:
exclude:
type: BoolString
type: object
kernelConfigs:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
kernelModules:
properties:
collectorName:
Expand Down
2 changes: 2 additions & 0 deletions pkg/analyze/host_analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func GetHostAnalyzer(analyzer *troubleshootv1beta2.HostAnalyze) (HostAnalyzer, b
return &AnalyzeHostOS{analyzer.HostOS}, true
case analyzer.TextAnalyze != nil:
return &AnalyzeHostTextAnalyze{analyzer.TextAnalyze}, true
case analyzer.KernelConfigs != nil:
return &AnalyzeHostKernelConfigs{analyzer.KernelConfigs}, true
default:
return nil, false
}
Expand Down
116 changes: 116 additions & 0 deletions pkg/analyze/host_kernel_configs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package analyzer

import (
"encoding/json"
"strings"

"github.com/pkg/errors"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/collect"
"github.com/replicatedhq/troubleshoot/pkg/constants"
)

type AnalyzeHostKernelConfigs struct {
hostAnalyzer *troubleshootv1beta2.KernelConfigsAnalyze
}

func (a *AnalyzeHostKernelConfigs) Title() string {
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Kernel Configs")
}

func (a *AnalyzeHostKernelConfigs) IsExcluded() (bool, error) {
return isExcluded(a.hostAnalyzer.Exclude)
}

func (a *AnalyzeHostKernelConfigs) Analyze(
getCollectedFileContents func(string) ([]byte, error), findFiles getChildCollectedFileContents,
) ([]*AnalyzeResult, error) {
hostAnalyzer := a.hostAnalyzer

contents, err := getCollectedFileContents(collect.HostKernelConfigsPath)
if err != nil {
return nil, errors.Wrap(err, "failed to get collected file")
}

kConfigs := collect.KConfigs{}
if err := json.Unmarshal(contents, &kConfigs); err != nil {
return nil, errors.Wrap(err, "failed to read kernel configs")
}

var results []*AnalyzeResult
for _, outcome := range hostAnalyzer.Outcomes {
result := &AnalyzeResult{
Title: a.Title(),
Strict: hostAnalyzer.Strict.BoolOrDefaultFalse(),
}

if err := analyzeSingleOutcome(kConfigs, result, outcome.Pass, constants.OUTCOME_PASS); err != nil {
return nil, errors.Wrap(err, "failed to analyze pass outcome")
}

if err := analyzeSingleOutcome(kConfigs, result, outcome.Fail, constants.OUTCOME_FAIL); err != nil {
return nil, errors.Wrap(err, "failed to analyze fail outcome")
}

if err := analyzeSingleOutcome(kConfigs, result, outcome.Warn, constants.OUTCOME_WARN); err != nil {
return nil, errors.Wrap(err, "failed to analyze warn outcome")
}

results = append(results, result)
}

return results, nil
}

func analyzeSingleOutcome(kConfigs collect.KConfigs, result *AnalyzeResult, outcome *troubleshootv1beta2.SingleOutcome, outcomeType string) error {
if outcome == nil {
return nil
}

if outcome.When == "" {
return errors.New("when attribute is required")
}

isMatch, err := match(kConfigs, outcome.When)
if err != nil {
return errors.Wrap(err, "failed to match")
}

result.Message = outcome.Message
result.URI = outcome.URI

// if no match, set pass outcome to fail
if !isMatch {
if outcomeType == constants.OUTCOME_PASS {
result.IsFail = true
}
return nil
}

switch outcomeType {
case constants.OUTCOME_PASS:
result.IsPass = true
case constants.OUTCOME_FAIL:
result.IsFail = true
case constants.OUTCOME_WARN:
result.IsWarn = true
}

return nil
}

func match(kConfigs collect.KConfigs, when string) (bool, error) {
parts := strings.SplitN(when, "=", 2)
if len(parts) != 2 {
return false, errors.New("invalid when attribute")
}
key, value := parts[0], parts[1]

// check if the key exists
if kConfig, ok := kConfigs[key]; ok {
return kConfig == strings.TrimSpace(value), nil
}

// kernel config not found
return false, nil
}
Loading
Loading