Upload code
This commit is contained in:
parent
00affe877b
commit
07200a4055
20
src/conf.json.sample
Normal file
20
src/conf.json.sample
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"Interfaces": [
|
||||||
|
{
|
||||||
|
"DisplayName": "MainInterface",
|
||||||
|
"IpOrInterfaceName": "enp2s0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DisplayName": "SecondInterface",
|
||||||
|
"IpOrInterfaceName": "enp3s0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"WaitTimeSec": 15,
|
||||||
|
"PingAddr": "8.8.8.8",
|
||||||
|
|
||||||
|
"TelegramConf": {
|
||||||
|
"BotToken": "Token",
|
||||||
|
"ChatID": "Id",
|
||||||
|
"SendSilent": "false"
|
||||||
|
}
|
||||||
|
}
|
11
src/go.mod
Normal file
11
src/go.mod
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module multiwan_informer
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534 // indirect
|
||||||
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20220420153159-1850ba15e1be // indirect
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
|
||||||
|
)
|
17
src/go.sum
Normal file
17
src/go.sum
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534 h1:dhy9OQKGBh4zVXbjwbxxHjRxMJtLXj3zfgpBYQaR4Q4=
|
||||||
|
github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
|
||||||
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
|
golang.org/x/net v0.0.0-20220420153159-1850ba15e1be h1:yx80W7nvY5ySWpaU8UWaj5o9e23YgO9BRhQol7Lc+JI=
|
||||||
|
golang.org/x/net v0.0.0-20220420153159-1850ba15e1be/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||||
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
198
src/main.go
Normal file
198
src/main.go
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func messFormat(iface Interface, successful bool) string {
|
||||||
|
if successful {
|
||||||
|
return fmt.Sprintf("✅ Inteface *%s* now is *up*!", iface.DisplayName)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("❌ Inteface *%s* now is *down!*", iface.DisplayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
config := loadConfig()
|
||||||
|
|
||||||
|
validateConfig(config)
|
||||||
|
|
||||||
|
pingable := []PingData{}
|
||||||
|
|
||||||
|
data, dataOk := loadData()
|
||||||
|
|
||||||
|
if !dataOk {
|
||||||
|
sendMessage("📁 *Data file is not readable*", config.TelegramConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
for iface_indx, iface := range config.Interfaces {
|
||||||
|
var ping_param string = "-S " // default ping ip
|
||||||
|
if net.ParseIP(iface.IpOrInterfaceName) == nil {
|
||||||
|
ping_param = "-I "
|
||||||
|
} // ping interface
|
||||||
|
|
||||||
|
pingResult := ping("-w " + fmt.Sprint(config.WaitTimeSec) + " " + ping_param + iface.IpOrInterfaceName + " " + config.PingAddr)
|
||||||
|
|
||||||
|
pingable = append(pingable, PingData{iface.IpOrInterfaceName, pingResult, time.Now()})
|
||||||
|
|
||||||
|
if dataOk {
|
||||||
|
getIndex := func() int {
|
||||||
|
for i, element := range data {
|
||||||
|
if element.Name == iface.IpOrInterfaceName {
|
||||||
|
return (i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
idx := getIndex()
|
||||||
|
|
||||||
|
if idx == -1 { // send message if interface not exist in data
|
||||||
|
sendMessage(messFormat(iface, pingResult), config.TelegramConf)
|
||||||
|
} else if data[idx].Successful != pingResult { // send messages if the result is different from what is in the data
|
||||||
|
if pingResult {
|
||||||
|
deltaTime := pingable[iface_indx].LastEdit.Sub(data[idx].LastEdit)
|
||||||
|
sendMessage(
|
||||||
|
messFormat(iface, pingResult)+
|
||||||
|
fmt.Sprintf("\n⏳ Down time: *%d* days *%d* hours *%d* min *%d* sec", int(deltaTime.Hours())/24, int(deltaTime.Hours())%24, int(deltaTime.Minutes())%60, int(deltaTime.Seconds())%60%60),
|
||||||
|
config.TelegramConf)
|
||||||
|
} else {
|
||||||
|
sendMessage(
|
||||||
|
messFormat(iface, pingResult),
|
||||||
|
config.TelegramConf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // send message if data not loaded
|
||||||
|
sendMessage(messFormat(iface, pingResult), config.TelegramConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
filse, _ := json.Marshal(pingable)
|
||||||
|
|
||||||
|
_ = ioutil.WriteFile("data.json", filse, 0644)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ping(params string) bool {
|
||||||
|
Command := fmt.Sprintf("ping -c 1 %s > /dev/null && echo true || echo false", params)
|
||||||
|
output, err := exec.Command("/bin/sh", "-c", Command).Output()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
real_ip := strings.TrimSpace(string(output))
|
||||||
|
if real_ip == "false" {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendMessage(mess string, tg_conf Telegram) bool {
|
||||||
|
resp, err := http.Get("https://api.telegram.org/bot" + tg_conf.BotToken + "/sendMessage?parse_mode=Markdown&chat_id=" + tg_conf.ChatID + "&disable_notification=" + tg_conf.SendSilent + "&text=" + url.QueryEscape(mess))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode == 200 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadData() ([]PingData, bool) {
|
||||||
|
file, _ := os.Open("data.json")
|
||||||
|
defer file.Close()
|
||||||
|
decoder := json.NewDecoder(file)
|
||||||
|
data := []PingData{}
|
||||||
|
err := decoder.Decode(&data)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Data file error:", err)
|
||||||
|
return []PingData{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfig() Configuration {
|
||||||
|
file, _ := os.Open("conf.json")
|
||||||
|
defer file.Close()
|
||||||
|
decoder := json.NewDecoder(file)
|
||||||
|
configuration := Configuration{}
|
||||||
|
err := decoder.Decode(&configuration)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return configuration
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateConfig(conf Configuration) {
|
||||||
|
if !(len(conf.Interfaces) > 0) {
|
||||||
|
log.Fatalln("You haven't added interfaces")
|
||||||
|
}
|
||||||
|
|
||||||
|
if conf.PingAddr == "" || !(conf.WaitTimeSec > 0) {
|
||||||
|
log.Fatalln("Bad config")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Telegram
|
||||||
|
resp, err := http.Get("https://api.telegram.org/bot" + conf.TelegramConf.BotToken + "/getMe")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var result map[string]interface{}
|
||||||
|
json.Unmarshal([]byte(body), &result)
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 || fmt.Sprintf("%v", result["ok"]) != "true" {
|
||||||
|
log.Fatalln("Failed to connect to bot")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// config structs
|
||||||
|
type Configuration struct {
|
||||||
|
Interfaces []Interface
|
||||||
|
WaitTimeSec int
|
||||||
|
PingAddr string
|
||||||
|
|
||||||
|
TelegramConf Telegram
|
||||||
|
}
|
||||||
|
|
||||||
|
type Interface struct {
|
||||||
|
DisplayName string
|
||||||
|
IpOrInterfaceName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Telegram struct {
|
||||||
|
BotToken string
|
||||||
|
ChatID string
|
||||||
|
SendSilent string
|
||||||
|
}
|
||||||
|
|
||||||
|
// data struct
|
||||||
|
|
||||||
|
type PingData struct {
|
||||||
|
Name string
|
||||||
|
Successful bool
|
||||||
|
LastEdit time.Time
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user