Skip to content

Commit

Permalink
feat(host_analyzer): add host sysctl analyzer (#1681)
Browse files Browse the repository at this point in the history
* feat(host_analyzer): add host sysctl analyzer

* chore: add e2e tests to support bundle collection

* chore: missing spec e2e test update

* chore: cleanup remote collector and use parse operator

* chore: update schemas
  • Loading branch information
JGAntunes authored Nov 8, 2024
1 parent 2f62240 commit 197f6de
Show file tree
Hide file tree
Showing 17 changed files with 832 additions and 4 deletions.
49 changes: 49 additions & 0 deletions config/crds/troubleshoot.sh_analyzers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2655,6 +2655,55 @@ spec:
required:
- outcomes
type: object
sysctl:
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
systemPackages:
properties:
annotations:
Expand Down
49 changes: 49 additions & 0 deletions config/crds/troubleshoot.sh_hostcollectors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,55 @@ spec:
required:
- outcomes
type: object
sysctl:
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
systemPackages:
properties:
annotations:
Expand Down
49 changes: 49 additions & 0 deletions config/crds/troubleshoot.sh_hostpreflights.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,55 @@ spec:
required:
- outcomes
type: object
sysctl:
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
systemPackages:
properties:
annotations:
Expand Down
49 changes: 49 additions & 0 deletions config/crds/troubleshoot.sh_supportbundles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19542,6 +19542,55 @@ spec:
required:
- outcomes
type: object
sysctl:
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
systemPackages:
properties:
annotations:
Expand Down
14 changes: 11 additions & 3 deletions examples/preflight/host/sysctl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ metadata:
spec:
collectors:
- sysctl:
collectorName: sysctl
#TODO add analyzer once implemented
analyzers: []
collectorName: host sysctl
analyzers:
- sysctl:
collectorName: host sysctl
outcomes:
- warn:
when: 'kern.ostype == Darwin'
message: "Running sysctl on a Darwin host"
- pass:
when: 'net.ipv4.conf.default.arp_ignore > 0'
message: "ARP ignore is enabled for the default interfaces interfaces on the host."
2 changes: 2 additions & 0 deletions pkg/analyze/host_analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ func GetHostAnalyzer(analyzer *troubleshootv1beta2.HostAnalyze) (HostAnalyzer, b
return &AnalyzeHostJsonCompare{analyzer.JsonCompare}, true
case analyzer.NetworkNamespaceConnectivity != nil:
return &AnalyzeHostNetworkNamespaceConnectivity{analyzer.NetworkNamespaceConnectivity}, true
case analyzer.Sysctl != nil:
return &AnalyzeHostSysctl{analyzer.Sysctl}, true
default:
return nil, false
}
Expand Down
106 changes: 106 additions & 0 deletions pkg/analyze/host_sysctl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package analyzer

import (
"encoding/json"
"fmt"
"strconv"

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

// Ensure `AnalyzeHostSysctl` implements `HostAnalyzer` interface at compile time.
var _ HostAnalyzer = (*AnalyzeHostSysctl)(nil)

type AnalyzeHostSysctl struct {
hostAnalyzer *troubleshootv1beta2.HostSysctlAnalyze
}

func (a *AnalyzeHostSysctl) Title() string {
return hostAnalyzerTitleOrDefault(a.hostAnalyzer.AnalyzeMeta, "Sysctl")
}

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

func (a *AnalyzeHostSysctl) Analyze(
getCollectedFileContents func(string) ([]byte, error), findFiles getChildCollectedFileContents,
) ([]*AnalyzeResult, error) {
result := AnalyzeResult{Title: a.Title()}

// Use the generic function to collect both local and remote data
collectedContents, err := retrieveCollectedContents(
getCollectedFileContents,
collect.HostSysctlPath, // Local path
collect.NodeInfoBaseDir, // Remote base directory
collect.HostSysctlFileName, // Remote file name
)
if err != nil {
return []*AnalyzeResult{&result}, err
}

results, err := analyzeHostCollectorResults(collectedContents, a.hostAnalyzer.Outcomes, a.CheckCondition, a.Title())
if err != nil {
return nil, errors.Wrap(err, "failed to analyze sysctl output")
}

return results, nil
}

// checkCondition checks the condition of the when clause
func (a *AnalyzeHostSysctl) CheckCondition(when string, data []byte) (bool, error) {

sysctl := map[string]string{}
if err := json.Unmarshal(data, &sysctl); err != nil {
return false, errors.Wrap(err, "failed to unmarshal data")
}

// <1:key> <2:operator> <3:value>
matches := sysctlWhenRX.FindStringSubmatch(when)
if len(matches) < 4 {
return false, fmt.Errorf("expected 3 parts in when %q", when)
}

param := matches[1]
expected := matches[3]
opString := matches[2]
operator, err := ParseComparisonOperator(opString)
if err != nil {
return false, errors.Wrap(err, fmt.Sprintf("failed to parse comparison operator %q", opString))
}

if _, ok := sysctl[param]; !ok {
return false, fmt.Errorf("kernel parameter %q does not exist on collected sysctl output", param)
}

switch operator {
case Equal:
return expected == sysctl[param], nil
}

// operator used is an inequality operator, the only valid inputs should be ints, if not we'll error out
value, err := strconv.Atoi(sysctl[param])
if err != nil {
return false, fmt.Errorf("collected sysctl param %q has value %q, cannot be used with provided operator %q", param, sysctl[param], opString)
}
expectedInt, err := strconv.Atoi(expected)
if err != nil {
return false, fmt.Errorf("expected value for sysctl param %q has value %q, cannot be used with provided operator %q", param, expected, opString)
}

switch operator {
case LessThan:
return value < expectedInt, nil
case LessThanOrEqual:
return value <= expectedInt, nil
case GreaterThan:
return value > expectedInt, nil
case GreaterThanOrEqual:
return value >= expectedInt, nil
default:
return false, fmt.Errorf("unsupported operator %q", opString)
}

}
Loading

0 comments on commit 197f6de

Please sign in to comment.