log backup functions

This commit is contained in:
Vomitblood 2025-02-09 18:51:53 +08:00
parent 5dcb467842
commit c6e7bc2f67
7 changed files with 198 additions and 4 deletions

View file

@ -6,6 +6,7 @@ require (
github.com/fsnotify/fsnotify v1.8.0
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
github.com/jackc/pgx/v5 v5.7.1
github.com/studio-b12/gowebdav v0.10.0
)
require (

View file

@ -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.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
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/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/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=

View 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
}

View file

@ -24,7 +24,7 @@ type LogEntry struct {
} `json:"audit_data"`
}
func watchLogFile(bot *tg.BotAPI) {
func WatchFile(bot *tg.BotAPI) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal("Failed to initialize watcher:", err)

View file

@ -4,7 +4,9 @@ import (
"fmt"
"log"
"github.com/Vomitblood/cspj-application/server/internal/log_backup"
tg "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/studio-b12/gowebdav"
)
const (
@ -18,7 +20,7 @@ type LogEntry struct {
} `json:"audit_data"`
}
func TelegramBotInit() (*tg.BotAPI, error) {
func Init(client *gowebdav.Client) *tg.BotAPI {
bot, err := tg.NewBotAPI(telegramToken)
if err != nil {
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)
}
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) {

View 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
}

View file

@ -5,7 +5,9 @@ import (
"github.com/Vomitblood/cspj-application/server/internal/db"
"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/webdav"
)
func main() {
@ -16,7 +18,16 @@ func main() {
}
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()
}