Upload code

This commit is contained in:
Sergey Karmanov 2022-04-28 20:56:20 +03:00
parent 00affe877b
commit 07200a4055
Signed by: serega404
GPG Key ID: 97CADD982D88DF68
4 changed files with 246 additions and 0 deletions

20
src/conf.json.sample Normal file
View 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
View 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
View 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
View 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
}