-
Notifications
You must be signed in to change notification settings - Fork 0
/
check.go
147 lines (129 loc) · 4.19 KB
/
check.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package main
import (
"encoding/base64"
"fmt"
"strings"
"text/template"
)
type CommandParam struct {
Name string `yaml:"name" json:"name"`
Display string `yaml:"display,omitempty" json:"display,omitempty"`
Help string `yaml:"help,omitempty" json:"help,omitempty"`
Mandatory ConvertibleBoolean `yaml:"mandatory,omitempty" json:"mandatory,omitempty"`
Default string `yaml:"default,omitempty" json:"default,omitempty"`
Encode string `yaml:"encode,omitempty" json:"encode,omitempty"`
Type string `yaml:"type,omitempty" json:"type,omitempty"`
}
// UnmarshalYAML implements the yaml.Unmarshaler interface for CommandParam.
func (p *CommandParam) UnmarshalYAML(unmarshal func(interface{}) error) error {
type plain CommandParam
p.Name = "<not set>"
p.Mandatory = false
p.Default = "<not set>"
if err := unmarshal((*plain)(p)); err != nil {
return err
}
if p.Name == "" || p.Name == "<not set>" {
return fmt.Errorf("invalid paramater name")
}
return nil
}
// checkConfig contains parameters for a nrpe command to check
type CheckConfig struct {
Command string `yaml:"command" json:"command"`
CommandLine string `yaml:"command_line" json:"command_line"`
CommandParams []CommandParam `yaml:"params" json:"params"`
cmd_tmpl *template.Template
}
// UnmarshalYAML implements the yaml.Unmarshaler interface for CheckConfig.
func (check *CheckConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
type plain CheckConfig
var err error
check.Command = "<not set>"
if err := unmarshal((*plain)(check)); err != nil {
return err
}
if check.Command == "" || check.Command == "<not set>" {
return fmt.Errorf("invalid command")
}
if check.CommandLine == "" && len(check.CommandParams) > 0 {
return fmt.Errorf("invalid command line")
}
check.cmd_tmpl = template.New("command")
check.cmd_tmpl, err = check.cmd_tmpl.Parse(check.CommandLine)
if err != nil {
return fmt.Errorf("command_line template %s is invalid: %s", check.CommandLine, err)
}
return nil
}
// build the command paramater to send to nrpe_exporter
// check each CheckConfig.CommandParams: mandatory, default, encoding
// use CheckConfig.CommandLine template has final res
func (check *CheckConfig) Build(check_conf *CheckJSON) (string, error) {
// var err error
var (
value any
r_value string
ok bool
)
// build a symbols table for the template
formatter := make(map[string]any)
for _, param := range check.CommandParams {
value = 0
if value, ok = check_conf.Params[param.Name]; ok {
if param.Encode == "base64" {
if r_value, ok = value.(string); ok {
msg := []byte(r_value)
value = base64.StdEncoding.EncodeToString(msg)
}
}
formatter[param.Name] = value
} else if param.Default != "<not set>" {
formatter[param.Name] = param.Default
} else if param.Mandatory {
return "", fmt.Errorf("mandatory parameter '%s' not set", param.Name)
}
}
tmp_res := new(strings.Builder)
err := ((*template.Template)(check.cmd_tmpl)).Execute(tmp_res, &formatter)
if err != nil {
return "", err
}
// obtain final string from builder
return tmp_res.String(), nil
}
func (check *CheckConfig) Play(poller *PollerConfig, check_conf *CheckJSON) (map[string]any, error) {
// var res []byte
target_host := check_conf.Target
if check_conf.Target == "" {
return nil, fmt.Errorf("target host is empty")
}
cmd_params, err := check.Build(check_conf)
if err != nil {
return nil, err
}
params := make(map[string]string)
params["ssl"] = "true"
params["command"] = check.Command
params["result_message"] = "true"
params["target"] = target_host
params["params"] = cmd_params
resp, data, err := poller.client.Get("export", params, false)
// ok
if err != nil {
return nil, err
} else if resp.StatusCode() != 200 {
body := resp.Body()
if len(body) > 0 {
return nil, fmt.Errorf("status: %s\nmessage: %s", resp.Status(), body)
} else {
return nil, fmt.Errorf("status: %s", resp.Status())
}
} /* else if data != nil {
// if cmd, ok := data[command].(map[string]any); ok {
// cmd["service"] = service
// }
// res, _ = json.MarshalIndent(data, "", " ")
}*/
return data, err
}