Skip to content

Commit ab9d7db

Browse files
committed
cleanup duplicate code
there is a boolean converter already, using that instead of adding another one.
1 parent 6ae03f6 commit ab9d7db

7 files changed

Lines changed: 53 additions & 81 deletions

File tree

docs/checks/commands/check_tasksched.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ Naemon Config
5656

5757
| Argument | Description |
5858
| --------- | --------------------------------------------------------------------------------------------------------- |
59-
| folder | The folder where the scheduled task is saved. This is used for exact matches, unless recurisive option is enabled. Default: '\' |
59+
| folder | The folder where the scheduled task is saved. This is used for exact matches, unless recursive option is enabled. Default: '\' |
6060
| hidden | Include hidden tasks. Default: 'false' |
6161
| recursive | Include the subfolders of the specified folder as well when searching for scheduled tasks. Default: 'true' |
6262
| timezone | Sets the timezone for time metrics (default is local time) |
63-
| title | Sets the task to check. This corresonds to the title of the scheduled task. Default: '\*' |
63+
| title | Sets the task to check. This corresponds to the title of the scheduled task. Default: '\*' |
6464

6565
## Attributes
6666

pkg/convert/convert.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,9 @@ func BoolE(raw any) (bool, error) {
244244
return val, nil
245245
default:
246246
switch strings.ToLower(fmt.Sprintf("%v", raw)) {
247-
case "1", "enable", "enabled", "true", "yes", "on":
247+
case "1", "enable", "enabled", "true", "t", "yes", "y", "on":
248248
return true, nil
249-
case "0", "disable", "disabled", "false", "no", "off":
249+
case "0", "disable", "disabled", "false", "f", "no", "n", "off":
250250
return false, nil
251251
}
252252
}

pkg/snclient/check_drivesize.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func (l *CheckDrivesize) Build() *CheckData {
114114
{name: "drive_or_id", description: "Drive letter if present if not use id"},
115115
{name: "drive_or_name", description: "Drive letter if present if not use name"},
116116
{name: "fstype", description: "Filesystem type"},
117-
{name: "mounted", description: "Flag whether drive is mounter (0/1)"},
117+
{name: "mounted", description: "Flag whether drive is mounter (0/1)", unit: UBool},
118118

119119
{name: "free", description: "Free (human readable) bytes", unit: UByte},
120120
{name: "free_bytes", description: "Number of free bytes", unit: UByte},
@@ -141,14 +141,14 @@ func (l *CheckDrivesize) Build() *CheckData {
141141

142142
{name: "media_type", description: "Windows only: numeric media type of drive"},
143143
{name: "type", description: "Windows only: type of drive, ex.: fixed, cdrom, ramdisk, remote, removable, unknown"},
144-
{name: "readable", description: "Windows only: flag drive is readable (0/1)"},
145-
{name: "writable", description: "Windows only: flag drive is writable (0/1)"},
146-
{name: "removable", description: "Windows only: flag drive is removable (0/1)"},
147-
{name: "erasable", description: "Windows only: flag whether if drive is erasable (0/1)"},
148-
{name: "hotplug", description: "Windows only: flag drive is hotplugable (0/1)"},
144+
{name: "readable", description: "Windows only: flag drive is readable (0/1)", unit: UBool},
145+
{name: "writable", description: "Windows only: flag drive is writable (0/1)", unit: UBool},
146+
{name: "removable", description: "Windows only: flag drive is removable (0/1)", unit: UBool},
147+
{name: "erasable", description: "Windows only: flag whether if drive is erasable (0/1)", unit: UBool},
148+
{name: "hotplug", description: "Windows only: flag drive is hotplugable (0/1)", unit: UBool},
149149

150150
{name: "remote_name", description: "Windows only: the remote name of the drive, if it uses a network name"},
151-
{name: "persistent", description: "Windows only: if the network drive is mounted as persistent (0/1)"},
151+
{name: "persistent", description: "Windows only: if the network drive is mounted as persistent (0/1)", unit: UBool},
152152
{name: "localised_remote_path", description: "Windows only: If the path is given as a remote path, and that remote path has an assigned logical drive," +
153153
" this is the replaced path under that logical drive."},
154154
},

pkg/snclient/check_tasksched.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ func (l *CheckTasksched) Build() *CheckData {
4545
"timezone": {description: "Sets the timezone for time metrics (default is local time)"},
4646
"title": {
4747
value: &l.TaskTitle,
48-
description: fmt.Sprintf("Sets the task to check. This corresonds to the title of the scheduled task. Default: '%s'", CheckTaskschedDefaultTaskTitle),
48+
description: fmt.Sprintf("Sets the task to check. This corresponds to the title of the scheduled task. Default: '%s'", CheckTaskschedDefaultTaskTitle),
4949
},
5050
"folder": {
5151
value: &l.Folder,
52-
description: fmt.Sprintf("The folder where the scheduled task is saved. This is used for exact matches, unless recurisive option is enabled. Default: '%s'",
52+
description: fmt.Sprintf("The folder where the scheduled task is saved. This is used for exact matches, unless recursive option is enabled. Default: '%s'",
5353
CheckTaskschedDefaultFolder),
5454
},
5555
"recursive": {

pkg/snclient/condition.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ import (
1616
)
1717

1818
var (
19-
// ^ and $ are used to capture the whole string
20-
// (\-?\d+\.\d+|\-?\d+) -> capture group one, two options separated by | first is a decimal with dot , second is a direct number
21-
// \s* -> any number of whitespace between the second group
22-
// (\D+) -> capture group two, one or more non-digit characters
2319
reConditionValueUnit = regexp.MustCompile(`^(\-?\d+\.\d+|\-?\d+)\s*(\D+)$`)
2420
reCuddleKeyword = regexp.MustCompile(`^([A-Za-z_]+)([!=><~]+)(.*)$`)
2521
reCuddleOperator = regexp.MustCompile(`^([!=><~]+)(.*?)$`)
@@ -466,6 +462,8 @@ func (c *Condition) compareEmpty() bool {
466462
// tries keyword_pct for % unit and keyword_bytes for B unit
467463
// returns value from keyword unless found already
468464
func (c *Condition) getVarValue(data map[string]string) (varStr string, ok bool) {
465+
unit := c.getUnit(c.keyword)
466+
469467
switch {
470468
case c.unit == "%":
471469
varStr, ok = data[c.keyword+"_pct"]
@@ -486,6 +484,18 @@ func (c *Condition) getVarValue(data map[string]string) (varStr string, ok bool)
486484

487485
varStr, ok = data[c.keyword]
488486

487+
if ok && unit == UBool {
488+
valBool, err := convert.BoolE(varStr)
489+
if err != nil {
490+
log.Errorf("condition based on non-bool value: %s", err.Error())
491+
}
492+
if valBool {
493+
return "true", true
494+
}
495+
496+
return "false", true
497+
}
498+
489499
return varStr, ok
490500
}
491501

@@ -833,13 +843,11 @@ func (c *Condition) expandUnitByType(str string) error {
833843
case UBool:
834844
// boolean units are not in the form of '<number> <unit>'
835845
// need to handle them before regex condition checks.
836-
newVal, oldVal, err := utils.ParseAndReplaceBoolAttributes(str)
846+
newVal, err := convert.BoolE(str)
837847
if err != nil {
838848
return fmt.Errorf("invalid boolean value: %s", err.Error())
839849
}
840-
c.original = oldVal
841850
c.value = newVal
842-
c.unit = ""
843851

844852
return nil
845853
default:

pkg/snclient/condition_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,31 @@ func TestConditionStrings(t *testing.T) {
9191
}
9292
}
9393

94+
func TestConditionBool(t *testing.T) {
95+
for _, check := range []struct {
96+
key string
97+
value string
98+
condition string
99+
expect bool
100+
deterministic bool
101+
}{
102+
{"mounted", "1", "mounted = 1", true, true},
103+
{"mounted", "0", "mounted = 1", false, true},
104+
{"mounted", "0", "mounted = 0", true, true},
105+
{"mounted", "1", "mounted = true", true, true},
106+
{"mounted", "0", "mounted = true", false, true},
107+
{"mounted", "0", "mounted = false", true, true},
108+
} {
109+
cond, err := NewCondition(check.condition, &[]CheckAttribute{{name: "mounted", unit: UBool}})
110+
require.NoError(t, err)
111+
112+
compare := map[string]string{check.key: check.value}
113+
res, ok := cond.Match(compare)
114+
assert.Equalf(t, check.expect, res, "Compare(%s) -> (%v) %v", check.condition, check.value, check.expect)
115+
assert.Equalf(t, check.deterministic, ok, "Compare(%s) -> determined: (%v) %v", check.condition, check.value, check.deterministic)
116+
}
117+
}
118+
94119
func TestConditionParseErrors(t *testing.T) {
95120
for _, check := range []struct {
96121
threshold string

pkg/utils/utils.go

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -81,67 +81,6 @@ func ExpandDuration(val string) (res float64, err error) {
8181
return 0, fmt.Errorf("expandDuration: cannot parse duration, unknown format in %s", val)
8282
}
8383

84-
var (
85-
truthyValues = []string{"1", "true", "enabled", "yes", "y", "on", "t"}
86-
falseyValues = []string{"0", "false", "disabled", "no", "n", "off", "f"}
87-
)
88-
89-
var (
90-
truthyRegex, truthyReplacements = replacePatterns(truthyValues, "true")
91-
falseyRegex, falseyReplacements = replacePatterns(falseyValues, "false")
92-
)
93-
94-
// replacePatterns builds a regex that matches any of the given words as whole words,
95-
// and returns the pattern and a replacement map (lowercase match → replacement).
96-
func replacePatterns(words []string, replacement string) (regex *regexp.Regexp, replacements map[string]string) {
97-
escaped := make([]string, len(words))
98-
replacementMap := make(map[string]string)
99-
for i, word := range words {
100-
lowercase := strings.ToLower(word)
101-
escaped[i] = regexp.QuoteMeta(lowercase)
102-
replacementMap[lowercase] = replacement
103-
}
104-
pattern := `(?i)\b(` + strings.Join(escaped, "|") + `)\b`
105-
106-
return regexp.MustCompile(pattern), replacementMap
107-
}
108-
109-
// ParseAndReplaceBoolAttributes replaces all known truthy/falsey tokens in val
110-
// with "true"/"false" (case‑insensitive whole‑word match).
111-
// Returns the modified string, the original string, and an error if any
112-
// unrecognized boolean‑like token is found (optional).
113-
func ParseAndReplaceBoolAttributes(val string) (newVal, oldVal string, err error) {
114-
oldVal = val
115-
foundValues := 0
116-
117-
newVal = truthyRegex.ReplaceAllStringFunc(val, func(match string) string {
118-
if replacement, ok := truthyReplacements[strings.ToLower(match)]; ok {
119-
foundValues++
120-
121-
return replacement
122-
}
123-
124-
return ""
125-
})
126-
127-
newVal = falseyRegex.ReplaceAllStringFunc(newVal, func(match string) string {
128-
if replacement, ok := falseyReplacements[strings.ToLower(match)]; ok {
129-
foundValues++
130-
131-
return replacement
132-
}
133-
134-
return ""
135-
})
136-
137-
if foundValues == 0 {
138-
err = fmt.Errorf("attribute of type bool can not be parsed: '%s' needs to be one of '%s' or '%s'",
139-
val, strings.Join(falseyValues, " "), strings.Join(truthyValues, " "))
140-
}
141-
142-
return newVal, oldVal, err
143-
}
144-
14584
// returns time/duration in target unit with given precision
14685
func TimeUnitF(num uint64, targetUnit string, precision int) float64 {
14786
for _, factor := range TimeFactors {

0 commit comments

Comments
 (0)