-
Notifications
You must be signed in to change notification settings - Fork 490
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
333fd6b
commit 0461fad
Showing
10 changed files
with
291 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -339,6 +339,10 @@ type AlertNode struct { | |
// Send alert to Talk. | ||
// tick:ignore | ||
TalkHandlers []*TalkHandler `tick:"Talk"` | ||
|
||
// Send alert using SNMPtraps. | ||
// tick:ignore | ||
SnmpHandlers []*SnmpHandler `tick:"Snmp"` | ||
} | ||
|
||
func newAlertNode(wants EdgeType) *AlertNode { | ||
|
@@ -1254,3 +1258,76 @@ func (a *AlertNode) Talk() *TalkHandler { | |
type TalkHandler struct { | ||
*AlertNode | ||
} | ||
|
||
// Send the alert using SNMP traps. | ||
// To allow Kapacitor to post SNMP traps, | ||
// | ||
// Example: | ||
// [snmp] | ||
// enabled = true | ||
// target-ip = "127.0.0.1" | ||
// target-port = 9162 | ||
// community = "public" | ||
// version = "2c" | ||
// state-changes-only = false | ||
// | ||
// In order to not post a message every alert interval | ||
// use AlertNode.StateChangesOnly so that only events | ||
// where the alert changed state are posted to the channel. | ||
// | ||
// Example: | ||
// stream | ||
// |alert() | ||
// .snmp() | ||
// .trap('1.3.6.1.2.1.1.7', 'i', {{ Index field value }}) | ||
// | ||
// Send alerts to `target-ip:target-port` on OID '1.3.6.1.2.1.1.7' | ||
// | ||
// tick:property | ||
func (a *AlertNode) Snmp(trap ...[]interface{}) *SnmpHandler { | ||
snmp := &SnmpHandler{ | ||
AlertNode: a, | ||
TrapList: trap, | ||
} | ||
a.SnmpHandlers = append(a.SnmpHandlers, snmp) | ||
return snmp | ||
} | ||
|
||
// Email AlertHandler | ||
// tick:embedded:AlertNode.Email | ||
type SnmpHandler struct { | ||
*AlertNode | ||
|
||
// List of email recipients. | ||
// tick:ignore | ||
TrapList [][]interface{} `tick:"Trap"` | ||
} | ||
|
||
// Define the To addresses for the email alert. | ||
// Multiple calls append to the existing list of addresses. | ||
// If empty uses the addresses from the configuration. | ||
// | ||
// Example: | ||
// |alert() | ||
// .id('{{ .Name }}') | ||
// // Email subject | ||
// .meassage('{{ .ID }}:{{ .Level }}') | ||
// //Email body as HTML | ||
// .details(''' | ||
//<h1>{{ .ID }}</h1> | ||
//<b>{{ .Message }}</b> | ||
//Value: {{ index .Fields "value" }} | ||
//''') | ||
// .email('[email protected]') | ||
// .to('[email protected]') | ||
// .to('[email protected]') | ||
// | ||
// All three email addresses will receive the alert message. | ||
// | ||
// Passing addresses to the `email` property directly or using the `email.to` property is the same. | ||
// tick:property | ||
func (h *SnmpHandler) Trap(trap ...interface{}) *SnmpHandler { | ||
// TODO check element validity | ||
h.TrapList = append(h.TrapList, trap) | ||
return h | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package snmp | ||
|
||
type Config struct { | ||
// Whether Snmptrap is enabled. | ||
Enabled bool `toml:"enabled"` | ||
// NMS IP (Network Management Station). | ||
TargetIp string `toml:"target-ip"` | ||
// NMS port | ||
TargetPort int `toml:"target-port"` | ||
// SNMP Community | ||
Community string `toml:"community"` | ||
// SNMP Version | ||
Version string `toml:"version"` | ||
// Whether all alerts should automatically use stateChangesOnly mode. | ||
// Only applies if global is also set. | ||
StateChangesOnly bool `toml:"state-changes-only"` | ||
} | ||
|
||
func NewConfig() Config { | ||
return Config{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package snmp | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"log" | ||
"strconv" | ||
|
||
"github.com/influxdata/kapacitor" | ||
"github.com/k-sone/snmpgo" | ||
) | ||
|
||
type Service struct { | ||
targetIp string | ||
targetPort int | ||
community string | ||
version string | ||
stateChangesOnly bool | ||
logger *log.Logger | ||
} | ||
|
||
func NewService(c Config, l *log.Logger) *Service { | ||
return &Service{ | ||
targetIp: c.TargetIp, | ||
targetPort: c.TargetPort, | ||
community: c.Community, | ||
version: c.Version, | ||
stateChangesOnly: c.StateChangesOnly, | ||
logger: l, | ||
} | ||
} | ||
|
||
func (s *Service) Open() error { | ||
return nil | ||
} | ||
|
||
func (s *Service) Close() error { | ||
return nil | ||
} | ||
|
||
func (s *Service) StateChangesOnly() bool { | ||
return s.stateChangesOnly | ||
} | ||
|
||
func (s *Service) Alert(traps [][]interface{}, level kapacitor.AlertLevel) error { | ||
address := s.targetIp + strconv.Itoa(s.targetPort) | ||
snmp, err := snmpgo.NewSNMP(snmpgo.SNMPArguments{ | ||
Version: snmpgo.V2c, | ||
Address: address, | ||
Retries: 1, | ||
Community: s.community, | ||
}) | ||
|
||
var varBinds snmpgo.VarBinds | ||
for _, trap := range traps { | ||
fmt.Printf("\n\n\nREERRRR %s", trap) | ||
oid_str := trap[0].(string) | ||
oid_type_raw := trap[1].(string) | ||
oid, _ := snmpgo.NewOid(oid_str) | ||
// http://docstore.mik.ua/orelly/networking_2ndEd/snmp/ch10_03.htm | ||
switch oid_type_raw { | ||
case "a": | ||
return errors.New("Snmptrap Datatype 'IP address' not supported") | ||
case "c": | ||
oid_value, err := strconv.ParseInt(trap[2].(string), 10, 64) | ||
if err != nil { | ||
return err | ||
} | ||
varBinds = append(varBinds, snmpgo.NewVarBind(oid, snmpgo.NewCounter64(uint64(oid_value)))) | ||
case "d": | ||
return errors.New("Snmptrap Datatype 'Decimal string' not supported") | ||
case "i": | ||
oid_value, err := strconv.ParseInt(trap[2].(string), 10, 64) | ||
if err != nil { | ||
return err | ||
} | ||
varBinds = append(varBinds, snmpgo.NewVarBind(oid, snmpgo.NewInteger(int32(oid_value)))) | ||
case "n": | ||
varBinds = append(varBinds, snmpgo.NewVarBind(oid, snmpgo.NewNull())) | ||
case "o": | ||
return errors.New("Snmptrap Datatype 'Object ID' not supported") | ||
case "s": | ||
oid_value := []byte(trap[2].(string)) | ||
varBinds = append(varBinds, snmpgo.NewVarBind(oid, snmpgo.NewOctetString(oid_value))) | ||
case "t": | ||
oid_value, err := strconv.ParseInt(trap[2].(string), 10, 64) | ||
if err != nil { | ||
return err | ||
} | ||
varBinds = append(varBinds, snmpgo.NewVarBind(oid, snmpgo.NewTimeTicks(uint32(oid_value)))) | ||
case "u": | ||
return errors.New("Snmptrap Datatype 'Unsigned integer' not supported") | ||
case "x": | ||
return errors.New("Snmptrap Datatype 'Hexadecimal string' not supported") | ||
default: | ||
return errors.New("Snmptrap Datatype not supported: " + oid_type_raw) | ||
} | ||
} | ||
|
||
if err = snmp.Open(); err != nil { | ||
// Failed to open connection | ||
fmt.Println(err) | ||
return err | ||
} | ||
defer snmp.Close() | ||
|
||
if err = snmp.V2Trap(varBinds); err != nil { | ||
// Failed to request | ||
fmt.Println(err) | ||
return err | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters