Skip to content

Commit

Permalink
feat(host_sysctl): add host sysctl collector
Browse files Browse the repository at this point in the history
  • Loading branch information
JGAntunes committed Nov 6, 2024
1 parent e272683 commit f55ce1e
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pkg/apis/troubleshoot/v1beta2/hostcollector_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ type HostDNS struct {
Hostnames []string `json:"hostnames" yaml:"hostnames"`
}

type HostSysctl struct {
HostCollectorMeta `json:",inline" yaml:",inline"`
}

type HostCollect struct {
CPU *CPU `json:"cpu,omitempty" yaml:"cpu,omitempty"`
Memory *Memory `json:"memory,omitempty" yaml:"memory,omitempty"`
Expand Down
16 changes: 16 additions & 0 deletions pkg/apis/troubleshoot/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions pkg/collect/host_sysctl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package collect

import (
"bytes"
"os/exec"

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

var _ HostCollector = (*CollectHostSysctl)(nil)

var execCommand = exec.Command

const HostSysctlPath = `host-collectors/system/sysctl.txt`

type CollectHostSysctl struct {
hostCollector *troubleshootv1beta2.HostSysctl
BundlePath string
}

func (c *CollectHostSysctl) Title() string {
return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, "Sysctl")
}

func (c *CollectHostSysctl) IsExcluded() (bool, error) {
return isExcluded(c.hostCollector.Exclude)
}

func (c *CollectHostSysctl) Collect(progressChan chan<- interface{}) (map[string][]byte, error) {

cmd := execCommand("sysctl", "-a")
out, err := cmd.Output()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
return nil, errors.Wrapf(err, "failed to run sysctl exit-code=%d stderr=%s", exitErr.ExitCode(), exitErr.Stderr)
} else {
return nil, errors.Wrap(err, "failed to run sysctl")
}
}

output := NewResult()
output.SaveResult(c.BundlePath, HostSysctlPath, bytes.NewBuffer(out))
return output, nil
}
117 changes: 117 additions & 0 deletions pkg/collect/host_sysctl_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package collect

import (
"io"
"os/exec"
"testing"

troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/multitype"
"github.com/stretchr/testify/require"
)

type execStub struct {
cmd *exec.Cmd
name string
args []string
}

func (s *execStub) testExecCommand(name string, args ...string) *exec.Cmd {
s.name = name
s.args = args
return s.cmd
}

func setExecStub(c *exec.Cmd) {
e := &execStub{
cmd: c,
}
execCommand = e.testExecCommand
}

func TestCollectHostSysctl_Error(t *testing.T) {
req := require.New(t)
setExecStub(exec.Command("sh", "-c", "exit 1"))

tmpDir := t.TempDir()
c := &CollectHostSysctl{
BundlePath: tmpDir,
}

_, err := c.Collect(nil)
req.ErrorContains(err, "failed to run sysctl exit-code=1")
}

func TestCollectHostSysctl(t *testing.T) {
req := require.New(t)
cmdOut := `
net.ipv4.conf.all.arp_evict_nocarrier = 1
net.ipv4.conf.all.arp_filter = 0
net.ipv4.conf.all.arp_ignore = 0
`
setExecStub(exec.Command("echo", "-n", cmdOut))

tmpDir := t.TempDir()
c := &CollectHostSysctl{
BundlePath: tmpDir,
}

out, err := c.Collect(nil)
req.NoError(err)
res := CollectorResult(out)
reader, err := res.GetReader(tmpDir, HostSysctlPath)
req.NoError(err)
actualOut, err := io.ReadAll(reader)
req.NoError(err)
req.Equal(string(actualOut), cmdOut)
}

func TestCollectHostSysctl_Title(t *testing.T) {
req := require.New(t)

// Default title is set
c := &CollectHostSysctl{
hostCollector: &troubleshootv1beta2.HostSysctl{
HostCollectorMeta: troubleshootv1beta2.HostCollectorMeta{},
},
}
req.Equal("Sysctl", c.Title())

// Configured title is set
c = &CollectHostSysctl{
hostCollector: &troubleshootv1beta2.HostSysctl{
HostCollectorMeta: troubleshootv1beta2.HostCollectorMeta{
CollectorName: "foobar",
},
},
}
req.Equal("foobar", c.Title())
}

func TestCollectHostSysctl_IsExcluded(t *testing.T) {
req := require.New(t)

// Exclude is true
c := &CollectHostSysctl{
hostCollector: &troubleshootv1beta2.HostSysctl{
HostCollectorMeta: troubleshootv1beta2.HostCollectorMeta{
Exclude: multitype.FromBool(true),
},
},
}
isExcluded, err := c.IsExcluded()
req.NoError(err)
req.Equal(true, isExcluded)

// Exclude is false
c = &CollectHostSysctl{
hostCollector: &troubleshootv1beta2.HostSysctl{
HostCollectorMeta: troubleshootv1beta2.HostCollectorMeta{
Exclude: multitype.FromBool(false),
},
},
}
isExcluded, err = c.IsExcluded()
req.NoError(err)
req.Equal(false, isExcluded)
}

0 comments on commit f55ce1e

Please sign in to comment.