This commit is contained in:
moxitech 2024-10-23 04:51:07 +07:00
commit 0e85c04ca5
12 changed files with 268 additions and 0 deletions

0
Dockerfile Normal file
View File

11
Readme.md Normal file
View 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
View 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
View 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
View 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
View 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=

View File

@ -0,0 +1,12 @@
package configurator
type Config struct {
}
func NewStandartConfig() *Config {
return &Config{}
}
func ReadConfig() *Config {
return &Config{}
}

View File

@ -0,0 +1 @@
package dashboard

View File

@ -0,0 +1 @@
package dumper

14
internal/models.go Normal file
View 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
View 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)
}
}