| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package nagios |
| 4 | |
| 5 | import ( |
| 6 | "fmt" |
| 7 | "path/filepath" |
| 8 | "runtime" |
| 9 | "slices" |
| 10 | "strings" |
| 11 | ) |
| 12 | |
| 13 | func (c *Collector) initCollector() error { |
| 14 | job, err := c.compileConfiguredJob() |
| 15 | if err != nil { |
| 16 | return err |
| 17 | } |
| 18 | c.job = job |
| 19 | c.state = newCollectState(c.now(), job.config) |
| 20 | return nil |
| 21 | } |
| 22 | |
| 23 | func (c *Collector) checkCollector() error { |
| 24 | _, err := c.compileConfiguredJob() |
| 25 | return err |
| 26 | } |
| 27 | |
| 28 | func (c *Collector) compileConfiguredJob() (compiledJob, error) { |
| 29 | job, err := compileCollectorConfig(c.Config) |
| 30 | if err != nil { |
| 31 | return compiledJob{}, err |
| 32 | } |
| 33 | |
| 34 | pluginPath, args, err := rewriteScriptCommand(job.config.Plugin, job.config.Args) |
| 35 | if err != nil { |
| 36 | return compiledJob{}, fmt.Errorf("job '%s': %w", job.config.Name, err) |
| 37 | } |
| 38 | job.config.Plugin = pluginPath |
| 39 | job.config.Args = args |
| 40 | |
| 41 | validatedPath, err := c.validatePlugin(job.config.Plugin) |
| 42 | if err != nil { |
| 43 | return compiledJob{}, fmt.Errorf("job '%s': %w", job.config.Name, err) |
| 44 | } |
| 45 | job.config.Plugin = validatedPath |
| 46 | |
| 47 | if runtime.GOOS != "windows" && isKnownInterpreter(job.config.Plugin) { |
| 48 | c.Warningf("job '%s': plugin '%s' appears to be an interpreter; "+ |
| 49 | "Netdata validates the interpreter binary but cannot verify scripts passed in args — "+ |
| 50 | "ensure scripts are root-owned and not writable by group/others", |
| 51 | job.config.Name, job.config.Plugin) |
| 52 | } |
| 53 | |
| 54 | c.warnCadenceResolution(job) |
| 55 | return job, nil |
| 56 | } |
| 57 | |
| 58 | func (c *Collector) warnCadenceResolution(job compiledJob) { |
| 59 | if job.cadenceWarning == "" || job.cadenceWarning == c.cadenceWarning { |
| 60 | return |
| 61 | } |
| 62 | c.Warningf("%s", job.cadenceWarning) |
| 63 | c.cadenceWarning = job.cadenceWarning |
| 64 | } |
| 65 | |
| 66 | var knownInterpreters = []string{ |
| 67 | "bash", "sh", "dash", "zsh", "ksh", "csh", "tcsh", "fish", |
| 68 | "python", "python2", "python3", |
| 69 | "perl", "ruby", "lua", |
| 70 | "powershell", "pwsh", |
| 71 | "cmd", |
| 72 | "node", |
| 73 | "env", |
| 74 | "php", |
| 75 | "tclsh", "wish", "expect", |
| 76 | } |
| 77 | |
| 78 | func isKnownInterpreter(pluginPath string) bool { |
| 79 | base := filepath.Base(pluginPath) |
| 80 | name := strings.TrimSuffix(base, filepath.Ext(base)) |
| 81 | return slices.Contains(knownInterpreters, strings.ToLower(name)) |
| 82 | } |