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(host_analyzer): add host sysctl analyzer #1681

Merged
merged 6 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
56 changes: 56 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 Expand Up @@ -2206,6 +2255,13 @@ spec:
- CIDRRangeAlloc
- desiredCIDR
type: object
sysctl:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
systemPackages:
properties:
collectorName:
Expand Down
7 changes: 7 additions & 0 deletions config/crds/troubleshoot.sh_preflights.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18980,6 +18980,13 @@ spec:
- CIDRRangeAlloc
- desiredCIDR
type: object
sysctl:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
systemPackages:
properties:
collectorName:
Expand Down
7 changes: 7 additions & 0 deletions config/crds/troubleshoot.sh_remotecollectors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,13 @@ spec:
- CIDRRangeAlloc
- desiredCIDR
type: object
sysctl:
properties:
collectorName:
type: string
exclude:
type: BoolString
type: object
systemPackages:
properties:
collectorName:
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
101 changes: 101 additions & 0 deletions pkg/analyze/host_sysctl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
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]
operator := matches[2]
Copy link
Member

@banjoh banjoh Nov 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use ParseComparisonOperator to parse the operator

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thank you! This is pretty useful. I'll use that one too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done via - 258d883

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

switch operator {
case "=", "==", "===":
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], operator)
}
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, operator)
}

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

}
Loading
Loading