-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.go
199 lines (164 loc) · 5.17 KB
/
config.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package main
import (
"crypto/tls"
"errors"
"fmt"
"net/http"
"strings"
"github.com/spf13/pflag"
)
const SmsLength = 160
type Config struct {
gateway string
target string
targetType string
ring bool
username string
password string
insecure bool
checkState string
checkOutput string
author string
hostName string
serviceName string
comment string
date string
notificationType string
doNotUseTLS bool
useLegacyHttpApi bool
}
func (c *Config) BindArguments(fs *pflag.FlagSet) {
// Basic connection settings
fs.StringVarP(&c.gateway, "gateway", "g", "", "IP/address of the brevis.one gateway (required)")
fs.StringVarP(&c.username, "username", "u", "", "API user name (required)")
fs.StringVarP(&c.password, "password", "p", "", "API user password (required)")
fs.BoolVar(&c.insecure, "insecure", false,
"Skip verification of the TLS certificates (is needed for the default self signed certificate, default false)")
fs.BoolVar(&c.doNotUseTLS, "no-tls", false, "Do NOT use TLS to connect to the gateway (default false)")
fs.BoolVar(&c.useLegacyHttpApi, "use-legacy-http-api", false, "Use old HTTP API (required on older firmware versions, default false)")
// Where to send the message to
fs.StringVarP(&c.target, "target", "T", "", "Target contact, group or phone number (required)")
fs.StringVar(&c.targetType, "target-type", "number", "Target type, one of: number, contact or contactgroup")
fs.BoolVarP(&c.ring, "ring", "R", false, "Add ring mode (also ring the target after sending SMS)")
// Notification data
fs.StringVarP(&c.notificationType, "type", "", "", "Icinga $notification.type$ (required)")
fs.StringVarP(&c.hostName, "host", "H", "", "Icinga $host.name$ (required)")
fs.StringVarP(&c.serviceName, "service", "S", "", "Icinga $service.name$ (required for service notifications)")
fs.StringVarP(&c.checkState, "state", "s", "", "Icinga $host.state$ or $service.state$ (required)")
fs.StringVarP(&c.checkOutput, "output", "o", "", "Icinga $host.output or $service.output$ (required)")
fs.StringVarP(&c.comment, "comment", "C", "", "Icinga $notification.comment$ (optional)")
fs.StringVarP(&c.author, "author", "a", "", "Icinga $notification.author$ (optional)")
fs.StringVar(&c.date, "date", "", "Icinga $icinga.long_date_time$ (optional)")
}
func (c *Config) Validate() error {
if c.gateway == "" {
return errors.New("gateway IP/address not set")
}
if c.username == "" {
return errors.New("username not set")
}
if c.password == "" {
return errors.New("password not set")
}
if c.target == "" {
return errors.New("target not set")
}
if c.targetType != "number" && c.targetType != "contact" && c.targetType != "contactgroup" {
return fmt.Errorf("not a valid targetType: %s", c.targetType)
}
if c.hostName == "" {
return errors.New("hostName must be set")
}
if c.notificationType == "" {
return errors.New("notification type must be set")
}
if c.checkState == "" {
return errors.New("check result state (return code) must be set")
}
return nil
}
func (c *Config) FormatMessage() string {
var msg strings.Builder
if c.date != "" {
msg.WriteString(c.date + "/")
}
if c.notificationType != "" {
msg.WriteString(c.notificationType + ": ")
}
if c.serviceName != "" {
// This is a service notification
msg.WriteString(fmt.Sprintf("%s @ %s - %s", c.serviceName, c.hostName, c.checkState))
} else {
msg.WriteString(fmt.Sprintf("%s - %s", c.hostName, c.checkState))
}
if c.comment != "" {
msg.WriteString(fmt.Sprintf("\r\n\"%s\"", c.comment))
if c.author != "" {
msg.WriteString(fmt.Sprintf(` by %s`, c.author))
}
}
if c.checkOutput != "" {
msg.WriteString("\r\n" + c.checkOutput)
}
// Cut off text longer than a single message
if len(msg.String()) > SmsLength {
return msg.String()[0:SmsLength-4] + "..."
}
return msg.String()
}
func (c *Config) Run() (err error) {
// Setup API client
api := NewApiClient(c.gateway)
// Update client to allow insecure when requested
if c.insecure {
api.Client.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true, // nolint:gosec
},
}
}
api.UseTls = !c.doNotUseTLS
if c.useLegacyHttpApi {
err := api.DoLegacyRequest(c.targetType,
c.target,
c.FormatMessage(),
c.username,
c.password)
if err != nil {
return err
}
} else {
// Login to API
err = api.Login(c.username, c.password)
if err != nil {
return
}
// Sending message via API
message := Message{
Recipients: []Recipient{{
To: c.target,
Target: c.targetType,
}},
Text: c.FormatMessage(),
Provider: "sms",
Type: "default",
}
response, err := api.DoRequest("messages", message)
if err != nil {
err = fmt.Errorf("sending message failed: %s - %w", response, err)
return err
}
// TODO: check response content
// Additional request to ring after sending SMS
if c.ring {
message.Type = "ring"
// TODO: check response content
response, err = api.DoRequest("messages", message)
if err != nil {
err = fmt.Errorf("ringing failed: %s - %w", response, err)
return err
}
}
}
return
}