Skip to content

Commit

Permalink
Update changelog
Browse files Browse the repository at this point in the history
Update test workflow
Add some tests
Fix some issues with plugin args
  • Loading branch information
jomann09 committed Feb 4, 2024
1 parent cefb7f3 commit fd0a08d
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 24 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
go-version-file: 'go.mod'

- name: Run Tests
run: make tests
run: make test

- name: Tests Coverage
- name: Test Coverage
run: make coverage
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
??/??/2023 - 1.1.0
02/04/2024 - 1.1.0
==================
- Added integration with ReChecked Manager
- Added integration with ReChecked Manager (https://rechecked.io/rechecked-manager/)
- Added debug logging with -D
- Added $LOCAL_MACHINEID to local variables available
- Updated $HOST to be $LOCAL_HOSTNAME for better local variable names
- Updated spec file to make installs on Ubuntu/Debian add the daemon to systemd
- Fixed issue with plugin output on error not showing stdout
- Fixed problems with disk endpoint when disk does not have a readable size

05/01/2023 - 1.0.3
==================
Expand Down
1 change: 0 additions & 1 deletion build/package/rcagent.spec
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,3 @@ fi
%{_sbindir}/%{name}

%dir %{_libdir}/%{name}/plugins

4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@ go 1.21
require (
github.com/denisbrodbeck/machineid v1.0.1
github.com/go-cmd/cmd v1.4.2
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/iamacarpet/go-win64api v0.0.0-20230324134531-ef6dbdd6db97
github.com/jarcoal/httpmock v1.2.0
github.com/kardianos/service v1.2.2
github.com/shirou/gopsutil/v3 v3.23.12
github.com/stretchr/testify v1.8.4
github.com/tidwall/gjson v1.17.0
golang.org/x/sys v0.16.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/google/cabbie v1.0.5 // indirect
github.com/google/glazier v0.0.0-20240110180336-410eb251bf15 // indirect
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
github.com/scjalliance/comshim v0.0.0-20231116235529-bbacf79a4691 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/logger v1.1.0/go.mod h1:w7O8nrRr0xufejBlQMI83MXqRusvREoJdaAxV+CoAB4=
github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/winops v0.0.0-20210803215038-c8511b84de2b/go.mod h1:ShbX8v8clPm/3chw9zHVwtW3QhrFpL8mXOwNxClt4pg=
Expand Down
48 changes: 41 additions & 7 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package config

import (
"bytes"
"embed"
"encoding/json"
"fmt"
"net/http"
"os"
"path/filepath"
"regexp"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -180,8 +180,15 @@ func InitConfig(file string, defaultFile embed.FS) error {

func ParseConfig() error {

// Load the secrets file
var err error
CfgData.Secrets, err = ParseSecretsFile()
if err != nil {
Log.Error(err)
}

// Parse main config file
err := ParseFile(ConfigDefaultFile)
err = ParseFile(ConfigDefaultFile)
if err != nil {
return err
}
Expand All @@ -201,8 +208,6 @@ func ParseConfig() error {
// actual error but logs issues.
func ParseConfigDir() {

hostname, _ := os.Hostname()

p := GetConfigDirFilePath("")
i, err := os.Stat(p)
if err != nil {
Expand Down Expand Up @@ -255,13 +260,16 @@ func ParseConfigDir() {
continue
}

// Replace host in file before parsing
bytes.ReplaceAll(yamlData, []byte("$HOST"), []byte(hostname))
replaceVariables(&yamlData)

// Replace secrets in file before parsing
if len(CfgData.Secrets) > 0 {
for k, v := range CfgData.Secrets {
bytes.ReplaceAll(yamlData, []byte(k), []byte(v))
// Build regex something like "\$VARIABLE(\s|\r|\n)" and append the group onto variable
re, err := regexp.Compile(fmt.Sprintf("\\$%s(\\s|\\r|\\n)", k))
if err == nil {
yamlData = re.ReplaceAll(yamlData, []byte(v+"$1"))
}
}
}

Expand Down Expand Up @@ -375,6 +383,8 @@ func ParseFile(defaultFile embed.FS) error {
return err
}

replaceVariables(&yamlData)

err = yaml.Unmarshal(yamlData, Settings)
if err != nil {
return err
Expand Down Expand Up @@ -442,6 +452,7 @@ func findConfig() (string, error) {
return "", err
}

// Gets plugin directory (global PluginDir is set during compilation and packaging)
func getPluginDir() string {
if PluginDir != "" {
return PluginDir
Expand All @@ -462,3 +473,26 @@ func getPluginDir() string {
}
return ""
}

// Replaces variables in a file with values using regex to validate line ends/spaces after variables.
func replaceVariables(data *[]byte) {

hostname, _ := os.Hostname()

// Replace $LOCAL_HOSTNAME with local agent hostname
if hostname != "" {
re := regexp.MustCompile(`\$LOCAL_HOSTNAME(\s|\z)`)
*data = re.ReplaceAll(*data, []byte(hostname+"$1"))
}

// Replace all secrets if found
if len(CfgData.Secrets) > 0 {
for k, v := range CfgData.Secrets {
// Build regex something like "\$VARIABLE(\s|\z)" and append the group onto variable
re, err := regexp.Compile(fmt.Sprintf("\\$%s(\\s|\\z)", k))
if err == nil {
*data = re.ReplaceAll(*data, []byte(v+"$1"))
}
}
}
}
29 changes: 29 additions & 0 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"net/http"
"net/url"
"testing"

"github.com/stretchr/testify/assert"
)

func TestOverrides(t *testing.T) {
Expand Down Expand Up @@ -43,3 +45,30 @@ func TestOverrides(t *testing.T) {
}

}

func TestReplaceVariables(t *testing.T) {

// Set a list of secrets to use
CfgData.Secrets = map[string]string{
"TEST_SECRET": "123456",
"HOST": "host123",
}

cfgFile := []byte(`some config
test config: hello
test config host: $HOST
test config secret: $TEST_SECRET
test config no secret: TEST_SECRET
testboth: $TEST_SECRET $HOST`)

replaceVariables(&cfgFile)

assert.Equal(t, `some config
test config: hello
test config host: host123
test config secret: 123456
test config no secret: TEST_SECRET
testboth: 123456 host123`,
string(cfgFile),
"Config variable replacements should match")
}
6 changes: 5 additions & 1 deletion internal/manager/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,12 @@ func getRequest(req *http.Request) ([]byte, error) {
}
defer resp.Body.Close()

bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return []byte{}, err
}

if resp.StatusCode == http.StatusOK {
bodyBytes, err := io.ReadAll(resp.Body)
return bodyBytes, err
}

Expand Down
27 changes: 22 additions & 5 deletions internal/sender/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,38 @@ func runChecks() {
}
config.CfgData.Checks[i].NextRun = now.Add(dur)

fmt.Println(check.Endpoint)

// Run the check and get the value data back, try to send it off if we can
data, err := server.GetDataFromEndpoint(check.Endpoint, check.Options)
if err != nil {
config.Log.Infof("Check Error: %s\n", err)
}

// For normal check results
chk, ok := data.(status.CheckResult)
if ok {
go sendToSenders(chk, check)
config.LogDebugf("%s\n", chk.String())
} else {
config.LogDebug(data)
config.Log.Infof("The check for '%s' is invalid, check endpoints and options, disabling",
check.Name())
config.CfgData.Checks[i].Disabled = true
continue
}

// For plugin results (need to be formatted)
pChk, pOk := data.(status.PluginResults)
if pOk {
go sendToSenders(status.CheckResult{
Exitcode: pChk.ExitCode,
Output: pChk.Output,
}, check)
config.LogDebugf("%s\n", chk.String())
continue
}

// If the check is not CheckResult or PluginResult, then it's invalid so stop trying
config.LogDebug(data)
config.Log.Infof("The check for '%s' is invalid, check endpoints and options, disabling",
check.Name())
config.CfgData.Checks[i].Disabled = true
}
}

Expand Down
19 changes: 13 additions & 6 deletions internal/status/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strings"

"github.com/go-cmd/cmd"
"github.com/google/shlex"
"github.com/rechecked/rcagent/internal/config"
)

Expand Down Expand Up @@ -108,11 +109,7 @@ func (p *Plugin) Run() PluginResults {
out = fmt.Sprintf("%s", s.Error)
s.Exit = 1
} else {
if s.Exit == 0 {
out = strings.Join(s.Stdout, "\n")
} else {
out = strings.Join(s.Stderr, "\n")
}
out = strings.Join(s.Stdout, "\n") + strings.Join(s.Stderr, "\n")
}

return PluginResults{
Expand All @@ -139,7 +136,7 @@ func HandlePlugins(cv config.Values) interface{} {
return res
}

plugin.args = cv.Args
plugin.args = parsePluginArgs(cv.Args)
err = plugin.CreateCmd()
if err == nil {
res = plugin.Run()
Expand Down Expand Up @@ -214,3 +211,13 @@ func isValidUser() bool {
}
return true
}

func parsePluginArgs(args []string) []string {
if len(args) == 1 {
args, err := shlex.Split(args[0])
if err == nil {
return args
}
}
return args
}

0 comments on commit fd0a08d

Please sign in to comment.