log backup functions
This commit is contained in:
parent
5dcb467842
commit
c6e7bc2f67
|
@ -6,6 +6,7 @@ require (
|
||||||
github.com/fsnotify/fsnotify v1.8.0
|
github.com/fsnotify/fsnotify v1.8.0
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
||||||
github.com/jackc/pgx/v5 v5.7.1
|
github.com/jackc/pgx/v5 v5.7.1
|
||||||
|
github.com/studio-b12/gowebdav v0.10.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
|
@ -20,8 +20,12 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/studio-b12/gowebdav v0.10.0 h1:Yewz8FFiadcGEu4hxS/AAJQlHelndqln1bns3hcJIYc=
|
||||||
|
github.com/studio-b12/gowebdav v0.10.0/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
|
||||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
|
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||||
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
|
|
60
server/internal/log_backup/log_backup.go
Normal file
60
server/internal/log_backup/log_backup.go
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package log_backup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/Vomitblood/cspj-application/server/internal/webdav"
|
||||||
|
"github.com/studio-b12/gowebdav"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: use values from config file
|
||||||
|
var localLogPaths = []string{
|
||||||
|
"/path/to/file1.log",
|
||||||
|
"/path/to/file2.log",
|
||||||
|
}
|
||||||
|
|
||||||
|
var remoteFiles = []string{
|
||||||
|
"/my/remote/folder/file1.log",
|
||||||
|
"/my/remote/folder/file2.log",
|
||||||
|
}
|
||||||
|
|
||||||
|
func BackupLogs(client *gowebdav.Client) error {
|
||||||
|
// check if there are equal number of local and remote file paths
|
||||||
|
if len(localLogPaths) != len(remoteFiles) {
|
||||||
|
return fmt.Errorf("mismatch between local log paths and remote paths")
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop through each file and upload it
|
||||||
|
for i := range localLogPaths {
|
||||||
|
err := webdav.UploadFile(client, localLogPaths[i], remoteFiles[i])
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error uploading file %s: %v", localLogPaths[i], err)
|
||||||
|
return fmt.Errorf("error uploading file %s: %v", localLogPaths[i], err)
|
||||||
|
} else {
|
||||||
|
log.Printf("Successfully uploaded file: %s", localLogPaths[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RestoreLogs(client *gowebdav.Client) error {
|
||||||
|
// check if there are equal number of local and remote file paths
|
||||||
|
if len(remoteFiles) != len(localLogPaths) {
|
||||||
|
return fmt.Errorf("mismatch between remote files and local paths")
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop through each remote file and download it
|
||||||
|
for i := range remoteFiles {
|
||||||
|
err := webdav.DownloadFile(client, remoteFiles[i], localLogPaths[i])
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error downloading file %s: %v", remoteFiles[i], err)
|
||||||
|
return fmt.Errorf("error downloading file %s: %v", remoteFiles[i], err)
|
||||||
|
} else {
|
||||||
|
log.Printf("Successfully downloaded file: %s", remoteFiles[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ type LogEntry struct {
|
||||||
} `json:"audit_data"`
|
} `json:"audit_data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func watchLogFile(bot *tg.BotAPI) {
|
func WatchFile(bot *tg.BotAPI) {
|
||||||
watcher, err := fsnotify.NewWatcher()
|
watcher, err := fsnotify.NewWatcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Failed to initialize watcher:", err)
|
log.Fatal("Failed to initialize watcher:", err)
|
||||||
|
|
|
@ -4,7 +4,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/Vomitblood/cspj-application/server/internal/log_backup"
|
||||||
tg "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
tg "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
|
"github.com/studio-b12/gowebdav"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -18,7 +20,7 @@ type LogEntry struct {
|
||||||
} `json:"audit_data"`
|
} `json:"audit_data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func TelegramBotInit() (*tg.BotAPI, error) {
|
func Init(client *gowebdav.Client) *tg.BotAPI {
|
||||||
bot, err := tg.NewBotAPI(telegramToken)
|
bot, err := tg.NewBotAPI(telegramToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Failed to create Telegram bot:", err)
|
log.Fatal("Failed to create Telegram bot:", err)
|
||||||
|
@ -33,7 +35,50 @@ func TelegramBotInit() (*tg.BotAPI, error) {
|
||||||
log.Fatal("Failed to send test message:", err)
|
log.Fatal("Failed to send test message:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bot, nil
|
go handleUpdates(bot, client)
|
||||||
|
|
||||||
|
return bot
|
||||||
|
}
|
||||||
|
|
||||||
|
// function to handle commands from user on tg
|
||||||
|
func handleUpdates(bot *tg.BotAPI, webdavClient *gowebdav.Client) {
|
||||||
|
u := tg.NewUpdate(0)
|
||||||
|
u.Timeout = 60
|
||||||
|
updates := bot.GetUpdatesChan(u)
|
||||||
|
|
||||||
|
for update := range updates {
|
||||||
|
if update.Message != nil {
|
||||||
|
command := update.Message.Text
|
||||||
|
|
||||||
|
// /backup_logs
|
||||||
|
if command == "/backup_logs" {
|
||||||
|
err := log_backup.BackupLogs(webdavClient)
|
||||||
|
if err != nil {
|
||||||
|
sendTelegramResponse(bot, fmt.Sprintf("Failed to backup logs: %v", err))
|
||||||
|
} else {
|
||||||
|
sendTelegramResponse(bot, "Successfully backed up log files")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for /download_logs command to download files from WebDAV
|
||||||
|
if command == "/restore_logs" {
|
||||||
|
err := log_backup.RestoreLogs(webdavClient)
|
||||||
|
if err != nil {
|
||||||
|
sendTelegramResponse(bot, fmt.Sprintf("Failed to restore logs: %v", err))
|
||||||
|
} else {
|
||||||
|
sendTelegramResponse(bot, "Successfully restored log files")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendTelegramResponse(bot *tg.BotAPI, message string) {
|
||||||
|
msg := tg.NewMessage(telegramChatID, message)
|
||||||
|
_, err := bot.Send(msg)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to send Telegram message:", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendTelegramAlert(bot *tg.BotAPI, message string) {
|
func SendTelegramAlert(bot *tg.BotAPI, message string) {
|
||||||
|
|
73
server/internal/webdav/webdav.go
Normal file
73
server/internal/webdav/webdav.go
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
package webdav
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/studio-b12/gowebdav"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WebDAVClient struct {
|
||||||
|
Client *gowebdav.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TODO: use values from config file
|
||||||
|
webdavURL = "https://webdav.vomitblood.com"
|
||||||
|
webdavUser = "Vomitblood"
|
||||||
|
webdavPassword = "alpine"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Init() *gowebdav.Client {
|
||||||
|
// initialize the webdav client
|
||||||
|
client := gowebdav.NewClient(webdavURL, webdavUser, webdavPassword)
|
||||||
|
|
||||||
|
// establish a connection to the webdav server
|
||||||
|
err := client.Connect()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to connect to WebDAV server: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Connected to WebDAV server")
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateDirectory(client *gowebdav.Client, remoteDir string) error {
|
||||||
|
err := client.Mkdir(remoteDir, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create directory %s: %v", remoteDir, err)
|
||||||
|
}
|
||||||
|
log.Printf("Created directory: %s", remoteDir)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UploadFile(client *gowebdav.Client, localFilePath string, remoteFilePath string) error {
|
||||||
|
bytes, err := os.ReadFile(localFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read file %s: %v", localFilePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.Write(remoteFilePath, bytes, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to upload file %s: %v", localFilePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Uploaded file: %s to %s", localFilePath, remoteFilePath)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DownloadFile(client *gowebdav.Client, remoteFilePath string, localFilePath string) error {
|
||||||
|
bytes, err := client.Read(remoteFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to download file %s: %v", remoteFilePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(localFilePath, bytes, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to save downloaded file %s: %v", localFilePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Downloaded file: %s to %s", remoteFilePath, localFilePath)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -5,7 +5,9 @@ import (
|
||||||
|
|
||||||
"github.com/Vomitblood/cspj-application/server/internal/db"
|
"github.com/Vomitblood/cspj-application/server/internal/db"
|
||||||
"github.com/Vomitblood/cspj-application/server/internal/http_server"
|
"github.com/Vomitblood/cspj-application/server/internal/http_server"
|
||||||
|
"github.com/Vomitblood/cspj-application/server/internal/log_watcher"
|
||||||
"github.com/Vomitblood/cspj-application/server/internal/telegram"
|
"github.com/Vomitblood/cspj-application/server/internal/telegram"
|
||||||
|
"github.com/Vomitblood/cspj-application/server/internal/webdav"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -16,7 +18,16 @@ func main() {
|
||||||
}
|
}
|
||||||
defer db.DbPool.Close()
|
defer db.DbPool.Close()
|
||||||
|
|
||||||
go telegram.TelegramBotInit()
|
// init webdav client
|
||||||
|
client := webdav.Init()
|
||||||
|
|
||||||
|
// init telegram bot
|
||||||
|
tgBot := telegram.Init(client)
|
||||||
|
|
||||||
|
// start log watcher
|
||||||
|
go log_watcher.WatchFile(tgBot)
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
http_server.ServeApi()
|
http_server.ServeApi()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue