Skelet
This commit is contained in:
commit
0e85c04ca5
0
Dockerfile
Normal file
0
Dockerfile
Normal file
11
Readme.md
Normal file
11
Readme.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
##### GO - ZABBIX - WIREN
|
||||||
|
|
||||||
|
|
||||||
|
Программа подключается к удаленному хосту zabbix и инициализирует wirenboard-датчики
|
||||||
|
ПОсле начинает отправлять данные на сервер.
|
||||||
|
|
||||||
|
Configurator - загрузчик конфигурации, etc..
|
||||||
|
Zabbix - драйвер соединения zabbix
|
||||||
|
Dumper - модуль для промежуточного логгирования|сохранения локально
|
||||||
|
Dashboard - локальный ui с ручками для изменения конфигураций
|
||||||
|
Sensors-API - api для считывания показаний сенсоров/датчиков
|
19
app/main.go
Normal file
19
app/main.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// загрузить настройку
|
||||||
|
// инициализировать подключение к zabbix
|
||||||
|
// инициализировать датчики
|
||||||
|
// запустить локальную веб-ручку для настройки
|
||||||
|
// Записывать в local-db | local-file результаты измерений и асинхронно отправлять в zabbix
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// conn, err := zabbix.NewZabbixSNMP("", "Admin", "zabbix")
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Println("[MAIN] :: Ошибка подключения к zabbix")
|
||||||
|
// }
|
||||||
|
// val, err := conn.ExampleMethod()
|
||||||
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
// fmt.Println("OK", val)
|
||||||
|
}
|
40
docker-compose.yaml
Normal file
40
docker-compose.yaml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# TEST
|
||||||
|
version: '3.7'
|
||||||
|
|
||||||
|
services:
|
||||||
|
zabbix-server:
|
||||||
|
image: zabbix/zabbix-server-mysql:alpine-6.0-latest
|
||||||
|
environment:
|
||||||
|
- DB_SERVER_HOST=zabbix-mysql
|
||||||
|
- MYSQL_USER=root
|
||||||
|
- MYSQL_PASSWORD=zabbix_pwd
|
||||||
|
- MYSQL_DATABASE=zabbix
|
||||||
|
depends_on:
|
||||||
|
- zabbix-mysql
|
||||||
|
ports:
|
||||||
|
- "10051:10051"
|
||||||
|
|
||||||
|
zabbix-web:
|
||||||
|
image: zabbix/zabbix-web-nginx-mysql:alpine-6.0-latest
|
||||||
|
environment:
|
||||||
|
- DB_SERVER_HOST=zabbix-mysql
|
||||||
|
- MYSQL_USER=root
|
||||||
|
- MYSQL_PASSWORD=zabbix_pwd
|
||||||
|
- MYSQL_DATABASE=zabbix
|
||||||
|
- ZBX_SERVER_HOST=zabbix-server
|
||||||
|
depends_on:
|
||||||
|
- zabbix-server
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
|
||||||
|
zabbix-mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=zabbix_pwd
|
||||||
|
- MYSQL_DATABASE=zabbix
|
||||||
|
volumes:
|
||||||
|
- zabbix-mysql-data:/var/lib/mysql
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
zabbix-mysql-data:
|
||||||
|
|
8
go.mod
Normal file
8
go.mod
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module git.moxitech.ru/moxitech/msu_wz_universal
|
||||||
|
|
||||||
|
go 1.22.7
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/cavaliercoder/go-zabbix v0.0.0-20230131181515-93725c39d639 // indirect
|
||||||
|
github.com/gosnmp/gosnmp v1.38.0 // indirect
|
||||||
|
)
|
4
go.sum
Normal file
4
go.sum
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
github.com/cavaliercoder/go-zabbix v0.0.0-20230131181515-93725c39d639 h1:eDTc0yCGN1XoC8M1Nb21GbncV0LCuP4DGroC38YBX1o=
|
||||||
|
github.com/cavaliercoder/go-zabbix v0.0.0-20230131181515-93725c39d639/go.mod h1:o9iZ0ep18zjkTdG1yoCmBZSMAWo2qUXVMxqmEl+6GLo=
|
||||||
|
github.com/gosnmp/gosnmp v1.38.0 h1:I5ZOMR8kb0DXAFg/88ACurnuwGwYkXWq3eLpJPHMEYc=
|
||||||
|
github.com/gosnmp/gosnmp v1.38.0/go.mod h1:FE+PEZvKrFz9afP9ii1W3cprXuVZ17ypCcyyfYuu5LY=
|
12
internal/configurator/conf.go
Normal file
12
internal/configurator/conf.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package configurator
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStandartConfig() *Config {
|
||||||
|
return &Config{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadConfig() *Config {
|
||||||
|
return &Config{}
|
||||||
|
}
|
1
internal/dashboard/dashboard.go
Normal file
1
internal/dashboard/dashboard.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package dashboard
|
0
internal/dashboard/template/template.html
Normal file
0
internal/dashboard/template/template.html
Normal file
1
internal/dumper/dumper.go
Normal file
1
internal/dumper/dumper.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package dumper
|
14
internal/models.go
Normal file
14
internal/models.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package internal
|
||||||
|
|
||||||
|
// Sensor - структура для передачи данных с датчика
|
||||||
|
type Sensor struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
Temperature float64 `json:"tc"`
|
||||||
|
Humindity float64 `json:"hm"`
|
||||||
|
Ts int64 `json:"ts"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SensorBlock - структура для передачи данных нескольких датчиков
|
||||||
|
type SensorBlock struct {
|
||||||
|
Sensors []Sensor `json:"sensors"`
|
||||||
|
}
|
158
internal/zabbix/driver.go
Normal file
158
internal/zabbix/driver.go
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user