Skip to content

Commit 340e9da

Browse files
Ahmet OeztuerkAhmet Oeztuerk
authored andcommitted
update code for the golangci-lint release v.2.7.0
Remove some of the gosec type linter check exceptions. Latest version of golanci-lint can determine the bounds of variables better and does not raise problems. Split the check_os_updates code into available platforms of: linux, darwin, windows, other. Fix the linting problems that would arise due to unused variables on different platforms.
1 parent 9363b1d commit 340e9da

14 files changed

+395
-326
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@ golangci: tools
353353
# golangci combines a few static code analyzer
354354
# See https://github.com/golangci/golangci-lint
355355
#
356+
@which golangci-lint
357+
@golangci-lint version
356358
@echo " - GOOS=linux"; \
357359
GOOS=linux CGO_ENABLED=0 golangci-lint run --timeout=5m pkg/... cmd/... t/...
358360
@echo " - GOOS=darwin"; \

pkg/convert/convert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func Int32E(raw any) (int32, error) {
156156
return 0, fmt.Errorf("number to large for int32")
157157
}
158158

159-
return int32(num), nil //nolint:gosec // false positive, MaxInt32 has been checked but it not considered by gosec (https://github.com/securego/gosec/issues/1187)
159+
return int32(num), nil
160160
}
161161
}
162162

pkg/humanize/humanize.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func NumF(num int64, precision int) string {
122122
prefix = "-"
123123
}
124124

125-
return prefix + humanizeBytes(uint64(num), 1000, []string{"", "k", "M", "G", "T", "P", "E"}, precision) //nolint:gosec // underflow checked before but not recognized by gosec
125+
return prefix + humanizeBytes(uint64(num), 1000, []string{"", "k", "M", "G", "T", "P", "E"}, precision)
126126
}
127127

128128
// Bytes(82854982) -> 83 MB

pkg/humanize/humanize_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestParseBytes(t *testing.T) {
3030
} else {
3131
require.NoError(t, err)
3232
}
33-
assert.Equalf(t, int64(tst.res), int64(res), "ParseBytes: %s -> %d", tst.in, res) //nolint:gosec // no overflow, fixed range of numbers
33+
assert.Equalf(t, int64(tst.res), int64(res), "ParseBytes: %s -> %d", tst.in, res)
3434
}
3535
}
3636

pkg/nrpe/nrpe.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func BuildPacketV4(packetType, statusCode uint16, statusLine []byte) *Packet {
133133
binary.BigEndian.PutUint32(packet.crc32, 0)
134134
binary.BigEndian.PutUint16(packet.statusCode, statusCode)
135135
binary.BigEndian.PutUint16(packet.alignment, 0)
136-
binary.BigEndian.PutUint32(packet.dataLength, uint32(dataLength)) //nolint:gosec // dataLength cannot exceed NrpeV4MaxPacketDataLength which is smaller than MaxUint32
136+
binary.BigEndian.PutUint32(packet.dataLength, uint32(dataLength))
137137

138138
copy(packet.data, statusLine)
139139
packet.data[dataLength-1] = 0 // add null byte

pkg/snclient/check_os_updates.go

Lines changed: 3 additions & 297 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,8 @@ package snclient
33
import (
44
"cmp"
55
"context"
6-
_ "embed"
76
"fmt"
8-
"os"
9-
"regexp"
10-
"runtime"
117
"slices"
12-
"strings"
138

149
"github.com/consol-monitoring/snclient/pkg/convert"
1510
)
@@ -18,17 +13,6 @@ func init() {
1813
AvailableChecks["check_os_updates"] = CheckEntry{"check_os_updates", NewCheckOSUpdates}
1914
}
2015

21-
//go:embed embed/scripts/windows/check_os_updates.ps1
22-
var checkOSupdatesPS1 string
23-
24-
var (
25-
reAPTSecurity = regexp.MustCompile(`(Debian-Security:|Ubuntu:[^/]*/[^-]*-security)`)
26-
reAPTEntry = regexp.MustCompile(`^Inst\s+(\S+)\s+\[([^\[]+)\]\s+\((\S+)\s+(.*)\s+\[(\S+)\]\)`)
27-
reYUMEntry = regexp.MustCompile(`^(\S+)\.(\S+)\s+(\S+)\s+(\S+)`)
28-
reOSXEntry = regexp.MustCompile(`^\*\s+Label:\s+(.*)$`)
29-
reOSXDetails = regexp.MustCompile(`^Title:.*Version:\s(\S+), `)
30-
)
31-
3216
type CheckOSUpdates struct {
3317
snc *Agent
3418
system string
@@ -81,41 +65,10 @@ If you only want to be notified about security related updates:
8165
func (l *CheckOSUpdates) Check(ctx context.Context, snc *Agent, check *CheckData, _ []Argument) (*CheckResult, error) {
8266
l.snc = snc
8367

84-
found := 0
85-
ok, err := l.addAPT(ctx, check)
86-
if err != nil {
87-
return nil, err
88-
}
89-
if ok {
90-
found++
91-
}
92-
93-
ok, err = l.addYUM(ctx, check)
94-
if err != nil {
95-
return nil, err
96-
}
97-
if ok {
98-
found++
99-
}
100-
101-
ok, err = l.addOSX(ctx, check)
102-
if err != nil {
103-
return nil, err
104-
}
105-
if ok {
106-
found++
107-
}
68+
addedOsBackendCount, osBackendAddErr := l.addOSBackends(ctx, check)
10869

109-
ok, err = l.addWindows(ctx, check)
110-
if err != nil {
111-
return nil, err
112-
}
113-
if ok {
114-
found++
115-
}
116-
117-
if found == 0 {
118-
return nil, fmt.Errorf("no suitable package system found, supported systems are apt, yum, osx and windows")
70+
if addedOsBackendCount == 0 {
71+
return nil, fmt.Errorf("no suitable package system found, supported systems are apt, yum, osx and windows. found errors: %w", osBackendAddErr)
11972
}
12073

12174
count := 0
@@ -173,250 +126,3 @@ func (l *CheckOSUpdates) Check(ctx context.Context, snc *Agent, check *CheckData
173126

174127
return check.Finalize()
175128
}
176-
177-
// get packages from apt
178-
func (l *CheckOSUpdates) addAPT(ctx context.Context, check *CheckData) (bool, error) {
179-
switch l.system {
180-
case "auto":
181-
if runtime.GOOS != "linux" {
182-
return false, nil
183-
}
184-
_, err := os.Stat("/usr/bin/apt-get")
185-
if os.IsNotExist(err) {
186-
return false, nil
187-
}
188-
case "apt":
189-
default:
190-
return false, nil
191-
}
192-
193-
if l.update {
194-
output, stderr, rc, err := l.snc.execCommand(ctx, "apt-get update", DefaultCmdTimeout)
195-
if err != nil {
196-
return true, fmt.Errorf("apt-get update failed: %s\n%s", err.Error(), stderr)
197-
}
198-
if rc != 0 {
199-
return true, fmt.Errorf("apt-get update failed: %s\n%s", output, stderr)
200-
}
201-
}
202-
203-
output, stderr, rc, err := l.snc.execCommand(ctx, "apt-get upgrade -o 'Debug::NoLocking=true' -s -qq", DefaultCmdTimeout)
204-
if err != nil {
205-
return true, fmt.Errorf("apt-get upgrade failed: %s\n%s", err.Error(), stderr)
206-
}
207-
if rc != 0 {
208-
return true, fmt.Errorf("apt-get upgrade failed: %s\n%s", output, stderr)
209-
}
210-
211-
l.parseAPT(output, check)
212-
213-
return true, nil
214-
}
215-
216-
func (l *CheckOSUpdates) parseAPT(output string, check *CheckData) {
217-
for line := range strings.SplitSeq(output, "\n") {
218-
matches := reAPTEntry.FindStringSubmatch(line)
219-
security := "0"
220-
if reAPTSecurity.MatchString(line) {
221-
security = "1"
222-
}
223-
if len(matches) < 5 {
224-
continue
225-
}
226-
check.listData = append(check.listData, map[string]string{
227-
"security": security,
228-
"package": matches[1],
229-
"version": matches[3],
230-
"old_version": matches[2],
231-
"repository": matches[4],
232-
"arch": matches[5],
233-
})
234-
}
235-
}
236-
237-
// get packages from yum
238-
func (l *CheckOSUpdates) addYUM(ctx context.Context, check *CheckData) (bool, error) {
239-
switch l.system {
240-
case "auto":
241-
if runtime.GOOS != "linux" {
242-
return false, nil
243-
}
244-
_, err := os.Stat("/usr/bin/yum")
245-
if os.IsNotExist(err) {
246-
return false, nil
247-
}
248-
case "yum":
249-
default:
250-
return false, nil
251-
}
252-
253-
yumOpts := " -C"
254-
if l.update {
255-
yumOpts = ""
256-
}
257-
258-
output, stderr, exitCode, err := l.snc.execCommand(ctx, "yum check-update --security -q"+yumOpts, DefaultCmdTimeout)
259-
if err != nil {
260-
return true, fmt.Errorf("yum check-update failed: %s\n%s", err.Error(), stderr)
261-
}
262-
if exitCode != 0 && exitCode != 100 {
263-
return true, fmt.Errorf("yum check-update failed: %s\n%s", output, stderr)
264-
}
265-
packageLookup := l.parseYUM(output, "1", check, nil)
266-
267-
output, stderr, exitCode, err = l.snc.execCommand(ctx, "yum check-update -q"+yumOpts, DefaultCmdTimeout)
268-
if err != nil {
269-
return true, fmt.Errorf("yum check-update failed: %s\n%s", err.Error(), stderr)
270-
}
271-
if exitCode != 0 && exitCode != 100 {
272-
return true, fmt.Errorf("yum check-update failed: %s\n%s", output, stderr)
273-
}
274-
l.parseYUM(output, "0", check, packageLookup)
275-
276-
return true, nil
277-
}
278-
279-
func (l *CheckOSUpdates) parseYUM(output, security string, check *CheckData, skipPackages map[string]bool) map[string]bool {
280-
packages := map[string]bool{}
281-
for line := range strings.SplitSeq(output, "\n") {
282-
if strings.HasPrefix(line, "Obsoleting Packages") {
283-
break
284-
}
285-
matches := reYUMEntry.FindStringSubmatch(line)
286-
if len(matches) < 3 {
287-
continue
288-
}
289-
if skipPackages[matches[1]] {
290-
continue
291-
}
292-
packages[matches[1]] = true
293-
check.listData = append(check.listData, map[string]string{
294-
"security": security,
295-
"package": matches[1],
296-
"version": matches[2],
297-
"old_version": "",
298-
"repository": matches[3],
299-
"arch": matches[2],
300-
})
301-
}
302-
303-
return packages
304-
}
305-
306-
// get packages from osx softwareupdate
307-
func (l *CheckOSUpdates) addOSX(ctx context.Context, check *CheckData) (bool, error) {
308-
switch l.system {
309-
case "auto":
310-
if runtime.GOOS != "darwin" {
311-
return false, nil
312-
}
313-
_, err := os.Stat("/usr/sbin/softwareupdate")
314-
if os.IsNotExist(err) {
315-
return false, nil
316-
}
317-
case "osx":
318-
default:
319-
return false, nil
320-
}
321-
322-
opts := " --no-scan"
323-
if l.update {
324-
opts = ""
325-
}
326-
327-
output, stderr, exitCode, err := l.snc.execCommand(ctx, "softwareupdate -l"+opts, DefaultCmdTimeout)
328-
if err != nil {
329-
return true, fmt.Errorf("softwareupdate failed: %s\n%s", err.Error(), stderr)
330-
}
331-
if exitCode != 0 {
332-
return true, fmt.Errorf("softwareupdate failed: %s\n%s", output, stderr)
333-
}
334-
335-
l.parseOSX(output, check)
336-
337-
return true, nil
338-
}
339-
340-
func (l *CheckOSUpdates) parseOSX(output string, check *CheckData) {
341-
var lastEntry map[string]string
342-
for line := range strings.SplitSeq(output, "\n") {
343-
if lastEntry != nil {
344-
matches := reOSXDetails.FindStringSubmatch(line)
345-
if len(matches) > 1 {
346-
lastEntry["version"] = matches[1]
347-
348-
continue
349-
}
350-
}
351-
matches := reOSXEntry.FindStringSubmatch(line)
352-
if len(matches) < 2 {
353-
continue
354-
}
355-
entry := map[string]string{
356-
"security": "0",
357-
"package": matches[1],
358-
"version": "",
359-
"old_version": "",
360-
"repository": "",
361-
"arch": "",
362-
}
363-
check.listData = append(check.listData, entry)
364-
lastEntry = entry
365-
}
366-
}
367-
368-
// get packages from windows powershell
369-
func (l *CheckOSUpdates) addWindows(ctx context.Context, check *CheckData) (bool, error) {
370-
switch l.system {
371-
case "auto":
372-
if runtime.GOOS != "windows" {
373-
return false, nil
374-
}
375-
case "windows":
376-
default:
377-
return false, nil
378-
}
379-
380-
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdatesearcher-search
381-
// https://learn.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdate
382-
cmd := powerShellCmd(ctx, checkOSupdatesPS1)
383-
if l.update {
384-
cmd.Env = append(cmd.Env, "ONLINE_SEARCH=1")
385-
}
386-
output, stderr, exitCode, _, err := l.snc.runExternalCommand(ctx, cmd, DefaultCmdTimeout)
387-
if err != nil {
388-
return true, fmt.Errorf("getting pending updates failed: %s\n%s", err.Error(), stderr)
389-
}
390-
if exitCode != 0 {
391-
return true, fmt.Errorf("getting pending updates failed: %s\n%s", output, stderr)
392-
}
393-
394-
l.parseWindows(output, check)
395-
396-
return true, nil
397-
}
398-
399-
func (l *CheckOSUpdates) parseWindows(output string, check *CheckData) {
400-
var lastEntry map[string]string
401-
for line := range strings.SplitSeq(output, "\n") {
402-
if strings.HasPrefix(line, "Category: ") {
403-
if strings.Contains(line, "Security") || strings.Contains(line, "Critical") {
404-
lastEntry["security"] = "1"
405-
}
406-
407-
continue
408-
}
409-
if pkg, ok := strings.CutPrefix(line, "Title: "); ok {
410-
entry := map[string]string{
411-
"security": "0",
412-
"package": pkg,
413-
"version": "",
414-
"old_version": "",
415-
"repository": "",
416-
"arch": "",
417-
}
418-
check.listData = append(check.listData, entry)
419-
lastEntry = entry
420-
}
421-
}
422-
}

0 commit comments

Comments
 (0)