159 lines
3.5 KiB
Go
159 lines
3.5 KiB
Go
package zabbix
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gosnmp/gosnmp"
|
|
)
|
|
|
|
type ZabbixSNMP struct {
|
|
Target string
|
|
Port uint16
|
|
Community string
|
|
Version gosnmp.SnmpVersion
|
|
}
|
|
|
|
type Sensor struct {
|
|
ID string `json:"id"`
|
|
TC float64 `json:"tc"`
|
|
PA float64 `json:"pa"`
|
|
TS int64 `json:"ts"`
|
|
}
|
|
|
|
// NewZabbixSNMP creates a new instance of ZabbixSNMP with default SNMP parameters
|
|
func NewZabbixSNMP(target string, community string, version gosnmp.SnmpVersion) *ZabbixSNMP {
|
|
return &ZabbixSNMP{
|
|
Target: target,
|
|
Port: 161,
|
|
Community: community,
|
|
Version: version,
|
|
}
|
|
}
|
|
|
|
// Get retrieves a value from the SNMP target for the specified OID
|
|
func (z *ZabbixSNMP) Get(oid string) (interface{}, error) {
|
|
snmp := &gosnmp.GoSNMP{
|
|
Target: z.Target,
|
|
Port: z.Port,
|
|
Community: z.Community,
|
|
Version: z.Version,
|
|
Timeout: time.Duration(2) * time.Second,
|
|
Retries: 1,
|
|
}
|
|
|
|
err := snmp.Connect()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect: %v", err)
|
|
}
|
|
defer snmp.Conn.Close()
|
|
|
|
response, err := snmp.Get([]string{oid})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get oid: %v", err)
|
|
}
|
|
|
|
if len(response.Variables) < 1 {
|
|
return nil, fmt.Errorf("no result found for oid: %s", oid)
|
|
}
|
|
|
|
return formatSNMPValue(response.Variables[0]), nil
|
|
}
|
|
|
|
// formatSNMPValue formats the SNMP value based on its type
|
|
func formatSNMPValue(pdu gosnmp.SnmpPDU) interface{} {
|
|
switch pdu.Type {
|
|
case gosnmp.OctetString:
|
|
return string(pdu.Value.([]byte))
|
|
default:
|
|
return pdu.Value
|
|
}
|
|
}
|
|
|
|
// Walk retrieves all values under the provided OID prefix
|
|
func (z *ZabbixSNMP) Walk(oid string) (map[string]interface{}, error) {
|
|
snmp := &gosnmp.GoSNMP{
|
|
Target: z.Target,
|
|
Port: z.Port,
|
|
Community: z.Community,
|
|
Version: z.Version,
|
|
Timeout: time.Duration(2) * time.Second,
|
|
Retries: 1,
|
|
}
|
|
|
|
err := snmp.Connect()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect: %v", err)
|
|
}
|
|
defer snmp.Conn.Close()
|
|
|
|
results := make(map[string]interface{})
|
|
err = snmp.Walk(oid, func(pdu gosnmp.SnmpPDU) error {
|
|
results[pdu.Name] = formatSNMPValue(pdu)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to walk oid: %v", err)
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
// SendSensorData sends sensor data to a remote Zabbix server
|
|
func SendSensorData(url string, sensor Sensor) error {
|
|
data, err := json.Marshal(sensor)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to marshal sensor data: %v", err)
|
|
}
|
|
|
|
resp, err := http.Post(url, "application/json", bytes.NewBuffer(data))
|
|
if err != nil {
|
|
return fmt.Errorf("failed to send data to Zabbix: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("received non-OK response from Zabbix: %d", resp.StatusCode)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Example usage
|
|
func Example() {
|
|
snmpClient := NewZabbixSNMP("192.168.1.1", "public", gosnmp.Version2c)
|
|
|
|
// Get a specific OID value
|
|
value, err := snmpClient.Get("1.3.6.1.2.1.1.1.0")
|
|
if err != nil {
|
|
fmt.Printf("Error: %v\n", err)
|
|
return
|
|
}
|
|
fmt.Printf("Value: %v\n", value)
|
|
|
|
// Walk a subtree of OIDs
|
|
values, err := snmpClient.Walk("1.3.6.1.2.1.1")
|
|
if err != nil {
|
|
fmt.Printf("Error: %v\n", err)
|
|
return
|
|
}
|
|
for k, v := range values {
|
|
fmt.Printf("%s: %v\n", k, v)
|
|
}
|
|
|
|
// Send sensor data to Zabbix server
|
|
sensor := Sensor{
|
|
ID: "sensor123",
|
|
TC: 23.5,
|
|
PA: 101.3,
|
|
TS: time.Now().Unix(),
|
|
}
|
|
err = SendSensorData("http://zabbix-server/api/sensordata", sensor)
|
|
if err != nil {
|
|
fmt.Printf("Error sending sensor data: %v\n", err)
|
|
}
|
|
}
|