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