mirror of
https://github.com/jkaninda/mysql-bkup.git
synced 2025-12-06 13:39:41 +01:00
Fix log, add verification of required environment
This commit is contained in:
1
go.mod
1
go.mod
@@ -10,7 +10,6 @@ require (
|
|||||||
github.com/hpcloud/tail v1.0.0
|
github.com/hpcloud/tail v1.0.0
|
||||||
github.com/spf13/cobra v1.8.0
|
github.com/spf13/cobra v1.8.0
|
||||||
golang.org/x/crypto v0.18.0
|
golang.org/x/crypto v0.18.0
|
||||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func scheduledMode() {
|
|||||||
fmt.Println(" Starting MySQL Bkup... ")
|
fmt.Println(" Starting MySQL Bkup... ")
|
||||||
fmt.Println("***********************************")
|
fmt.Println("***********************************")
|
||||||
utils.Info("Running in Scheduled mode")
|
utils.Info("Running in Scheduled mode")
|
||||||
utils.Info("Execution period ", os.Getenv("SCHEDULE_PERIOD"))
|
utils.Info("Execution period %s", os.Getenv("SCHEDULE_PERIOD"))
|
||||||
|
|
||||||
//Test database connexion
|
//Test database connexion
|
||||||
utils.TestDatabaseConnection()
|
utils.TestDatabaseConnection()
|
||||||
@@ -123,13 +123,6 @@ func BackupDatabase(backupFileName string, disableCompression bool) {
|
|||||||
dbPort = os.Getenv("DB_PORT")
|
dbPort = os.Getenv("DB_PORT")
|
||||||
storagePath = os.Getenv("STORAGE_PATH")
|
storagePath = os.Getenv("STORAGE_PATH")
|
||||||
|
|
||||||
// dbHVars Required environment variables for database
|
|
||||||
var dbHVars = []string{
|
|
||||||
"DB_HOST",
|
|
||||||
"DB_PASSWORD",
|
|
||||||
"DB_USERNAME",
|
|
||||||
"DB_NAME",
|
|
||||||
}
|
|
||||||
err := utils.CheckEnvVars(dbHVars)
|
err := utils.CheckEnvVars(dbHVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Error("Please make sure all required environment variables for database are set")
|
utils.Error("Please make sure all required environment variables for database are set")
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/jkaninda/mysql-bkup/utils"
|
"github.com/jkaninda/mysql-bkup/utils"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -16,7 +15,6 @@ func Decrypt(inputFile string, passphrase string) error {
|
|||||||
|
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +30,6 @@ func Encrypt(inputFile string, passphrase string) error {
|
|||||||
|
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,13 +68,7 @@ func RestoreDatabase(file string) {
|
|||||||
if file == "" {
|
if file == "" {
|
||||||
utils.Fatal("Error, file required")
|
utils.Fatal("Error, file required")
|
||||||
}
|
}
|
||||||
// dbHVars Required environment variables for database
|
|
||||||
var dbHVars = []string{
|
|
||||||
"DB_HOST",
|
|
||||||
"DB_PASSWORD",
|
|
||||||
"DB_USERNAME",
|
|
||||||
"DB_NAME",
|
|
||||||
}
|
|
||||||
err := utils.CheckEnvVars(dbHVars)
|
err := utils.CheckEnvVars(dbHVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Error("Please make sure all required environment variables for database are set")
|
utils.Error("Please make sure all required environment variables for database are set")
|
||||||
@@ -90,7 +84,7 @@ func RestoreDatabase(file string) {
|
|||||||
//Decrypt file
|
//Decrypt file
|
||||||
err := Decrypt(filepath.Join(tmpPath, file), gpgPassphrase)
|
err := Decrypt(filepath.Join(tmpPath, file), gpgPassphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatal("Error decrypting file ", file, err)
|
utils.Fatal("Error decrypting file %s %v", file, err)
|
||||||
}
|
}
|
||||||
//Update file name
|
//Update file name
|
||||||
file = RemoveLastExtension(file)
|
file = RemoveLastExtension(file)
|
||||||
@@ -99,11 +93,6 @@ func RestoreDatabase(file string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if utils.FileExists(fmt.Sprintf("%s/%s", tmpPath, file)) {
|
if utils.FileExists(fmt.Sprintf("%s/%s", tmpPath, file)) {
|
||||||
|
|
||||||
err := os.Setenv("mysqlPASSWORD", dbPassword)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
utils.TestDatabaseConnection()
|
utils.TestDatabaseConnection()
|
||||||
|
|
||||||
extension := filepath.Ext(fmt.Sprintf("%s/%s", tmpPath, file))
|
extension := filepath.Ext(fmt.Sprintf("%s/%s", tmpPath, file))
|
||||||
@@ -112,7 +101,7 @@ func RestoreDatabase(file string) {
|
|||||||
str := "zcat " + fmt.Sprintf("%s/%s", tmpPath, file) + " | mysql -h " + os.Getenv("DB_HOST") + " -P " + os.Getenv("DB_PORT") + " -u " + os.Getenv("DB_USERNAME") + " --password=" + os.Getenv("DB_PASSWORD") + " " + os.Getenv("DB_NAME")
|
str := "zcat " + fmt.Sprintf("%s/%s", tmpPath, file) + " | mysql -h " + os.Getenv("DB_HOST") + " -P " + os.Getenv("DB_PORT") + " -u " + os.Getenv("DB_USERNAME") + " --password=" + os.Getenv("DB_PASSWORD") + " " + os.Getenv("DB_NAME")
|
||||||
_, err := exec.Command("bash", "-c", str).Output()
|
_, err := exec.Command("bash", "-c", str).Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatal(fmt.Sprintf("Error, in restoring the database %s", err))
|
utils.Fatal("Error, in restoring the database %v", err)
|
||||||
}
|
}
|
||||||
utils.Done("Database has been restored")
|
utils.Done("Database has been restored")
|
||||||
|
|
||||||
|
|||||||
22
pkg/scp.go
22
pkg/scp.go
@@ -8,7 +8,6 @@ import (
|
|||||||
"github.com/bramvdbogaerde/go-scp/auth"
|
"github.com/bramvdbogaerde/go-scp/auth"
|
||||||
"github.com/jkaninda/mysql-bkup/utils"
|
"github.com/jkaninda/mysql-bkup/utils"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
"golang.org/x/exp/slog"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
@@ -20,16 +19,9 @@ func CopyToRemote(fileName, remotePath string) error {
|
|||||||
sshPort := os.Getenv("SSH_PORT")
|
sshPort := os.Getenv("SSH_PORT")
|
||||||
sshIdentifyFile := os.Getenv("SSH_IDENTIFY_FILE")
|
sshIdentifyFile := os.Getenv("SSH_IDENTIFY_FILE")
|
||||||
|
|
||||||
// SSSHVars Required environment variables for SSH remote server storage
|
|
||||||
var sshHVars = []string{
|
|
||||||
"SSH_USER",
|
|
||||||
"SSH_REMOTE_PATH",
|
|
||||||
"SSH_HOST_NAME",
|
|
||||||
"SSH_PORT",
|
|
||||||
}
|
|
||||||
err := utils.CheckEnvVars(sshHVars)
|
err := utils.CheckEnvVars(sshHVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(fmt.Sprintf("Error checking environment variables\n: %s", err))
|
utils.Error("Error checking environment variables\n: %s", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +33,7 @@ func CopyToRemote(fileName, remotePath string) error {
|
|||||||
if sshPassword == "" {
|
if sshPassword == "" {
|
||||||
return errors.New("SSH_PASSWORD environment variable is required if SSH_IDENTIFY_FILE is empty\n")
|
return errors.New("SSH_PASSWORD environment variable is required if SSH_IDENTIFY_FILE is empty\n")
|
||||||
}
|
}
|
||||||
slog.Warn("Accessing the remote server using password, password is not recommended\n")
|
utils.Warn("Accessing the remote server using password, password is not recommended\n")
|
||||||
clientConfig, _ = auth.PasswordKey(sshUser, sshPassword, ssh.InsecureIgnoreHostKey())
|
clientConfig, _ = auth.PasswordKey(sshUser, sshPassword, ssh.InsecureIgnoreHostKey())
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -77,6 +69,12 @@ func CopyFromRemote(fileName, remotePath string) error {
|
|||||||
sshPort := os.Getenv("SSH_PORT")
|
sshPort := os.Getenv("SSH_PORT")
|
||||||
sshIdentifyFile := os.Getenv("SSH_IDENTIFY_FILE")
|
sshIdentifyFile := os.Getenv("SSH_IDENTIFY_FILE")
|
||||||
|
|
||||||
|
err := utils.CheckEnvVars(sshHVars)
|
||||||
|
if err != nil {
|
||||||
|
utils.Error("Error checking environment variables\n: %s", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
clientConfig, _ := auth.PasswordKey(sshUser, sshPassword, ssh.InsecureIgnoreHostKey())
|
clientConfig, _ := auth.PasswordKey(sshUser, sshPassword, ssh.InsecureIgnoreHostKey())
|
||||||
if sshIdentifyFile != "" && utils.FileExists(sshIdentifyFile) {
|
if sshIdentifyFile != "" && utils.FileExists(sshIdentifyFile) {
|
||||||
clientConfig, _ = auth.PrivateKey(sshUser, sshIdentifyFile, ssh.InsecureIgnoreHostKey())
|
clientConfig, _ = auth.PrivateKey(sshUser, sshIdentifyFile, ssh.InsecureIgnoreHostKey())
|
||||||
@@ -85,7 +83,7 @@ func CopyFromRemote(fileName, remotePath string) error {
|
|||||||
if sshPassword == "" {
|
if sshPassword == "" {
|
||||||
return errors.New("SSH_PASSWORD environment variable is required if SSH_IDENTIFY_FILE is empty\n")
|
return errors.New("SSH_PASSWORD environment variable is required if SSH_IDENTIFY_FILE is empty\n")
|
||||||
}
|
}
|
||||||
slog.Warn("Accessing the remote server using password, password is not recommended\n")
|
utils.Warn("Accessing the remote server using password, password is not recommended\n")
|
||||||
clientConfig, _ = auth.PasswordKey(sshUser, sshPassword, ssh.InsecureIgnoreHostKey())
|
clientConfig, _ = auth.PasswordKey(sshUser, sshPassword, ssh.InsecureIgnoreHostKey())
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -93,7 +91,7 @@ func CopyFromRemote(fileName, remotePath string) error {
|
|||||||
client := scp.NewClient(fmt.Sprintf("%s:%s", sshHostName, sshPort), &clientConfig)
|
client := scp.NewClient(fmt.Sprintf("%s:%s", sshHostName, sshPort), &clientConfig)
|
||||||
|
|
||||||
// Connect to the remote server
|
// Connect to the remote server
|
||||||
err := client.Connect()
|
err = client.Connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("Couldn't establish a connection to the remote server\n")
|
return errors.New("Couldn't establish a connection to the remote server\n")
|
||||||
}
|
}
|
||||||
|
|||||||
16
pkg/var.go
16
pkg/var.go
@@ -19,3 +19,19 @@ var (
|
|||||||
disableCompression = false
|
disableCompression = false
|
||||||
encryption = false
|
encryption = false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// dbHVars Required environment variables for database
|
||||||
|
var dbHVars = []string{
|
||||||
|
"DB_HOST",
|
||||||
|
"DB_PASSWORD",
|
||||||
|
"DB_USERNAME",
|
||||||
|
"DB_NAME",
|
||||||
|
}
|
||||||
|
|
||||||
|
// sshHVars Required environment variables for SSH remote server storage
|
||||||
|
var sshHVars = []string{
|
||||||
|
"SSH_USER",
|
||||||
|
"SSH_REMOTE_PATH",
|
||||||
|
"SSH_HOST_NAME",
|
||||||
|
"SSH_PORT",
|
||||||
|
}
|
||||||
|
|||||||
55
utils/logger.go
Normal file
55
utils/logger.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var currentTime = time.Now().Format("2006/01/02 15:04:05")
|
||||||
|
|
||||||
|
func Info(msg string, args ...any) {
|
||||||
|
formattedMessage := fmt.Sprintf(msg, args...)
|
||||||
|
if len(args) == 0 {
|
||||||
|
fmt.Printf("%s INFO: %s\n", currentTime, msg)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s INFO: %s\n", currentTime, formattedMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn warning message
|
||||||
|
func Warn(msg string, args ...any) {
|
||||||
|
formattedMessage := fmt.Sprintf(msg, args...)
|
||||||
|
if len(args) == 0 {
|
||||||
|
fmt.Printf("%s WARN: %s\n", currentTime, msg)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s WARN: %s\n", currentTime, formattedMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func Error(msg string, args ...any) {
|
||||||
|
formattedMessage := fmt.Sprintf(msg, args...)
|
||||||
|
if len(args) == 0 {
|
||||||
|
fmt.Printf("%s ERROR: %s\n", currentTime, msg)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s ERROR: %s\n", currentTime, formattedMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func Done(msg string, args ...any) {
|
||||||
|
formattedMessage := fmt.Sprintf(msg, args...)
|
||||||
|
if len(args) == 0 {
|
||||||
|
fmt.Printf("%s INFO: %s\n", currentTime, msg)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s INFO: %s\n", currentTime, formattedMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatal(msg string, args ...any) {
|
||||||
|
// Fatal logs an error message and exits the program.
|
||||||
|
formattedMessage := fmt.Sprintf(msg, args...)
|
||||||
|
if len(args) == 0 {
|
||||||
|
fmt.Printf("%s ERROR: %s\n", currentTime, msg)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s ERROR: %s\n", currentTime, formattedMessage)
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/s3"
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||||
"golang.org/x/exp/slog"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -43,7 +42,7 @@ func CreateSession() (*session.Session, error) {
|
|||||||
|
|
||||||
err = CheckEnvVars(awsVars)
|
err = CheckEnvVars(awsVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(fmt.Sprintf("Error checking environment variables\n: %s", err))
|
Error(fmt.Sprintf("Error checking environment variables\n: %s", err))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
// S3 Config
|
// S3 Config
|
||||||
|
|||||||
@@ -10,51 +10,12 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/exp/slog"
|
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Info(msg string, args ...any) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
slog.Info(msg)
|
|
||||||
} else {
|
|
||||||
slog.Info(fmt.Sprintf(msg, args...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func Worn(msg string, args ...any) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
slog.Warn(msg)
|
|
||||||
} else {
|
|
||||||
slog.Warn(fmt.Sprintf(msg, args...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func Error(msg string, args ...any) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
slog.Error(msg)
|
|
||||||
} else {
|
|
||||||
slog.Error(fmt.Sprintf(msg, args...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func Done(msg string, args ...any) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
slog.Info(msg)
|
|
||||||
} else {
|
|
||||||
slog.Info(fmt.Sprintf(msg, args...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func Fatal(msg string, args ...any) {
|
|
||||||
// Fatal logs an error message and exits the program.
|
|
||||||
if len(args) == 0 {
|
|
||||||
slog.Error(msg)
|
|
||||||
} else {
|
|
||||||
slog.Error(fmt.Sprintf(msg, args...))
|
|
||||||
}
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func FileExists(filename string) bool {
|
func FileExists(filename string) bool {
|
||||||
info, err := os.Stat(filename)
|
info, err := os.Stat(filename)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
@@ -150,7 +111,7 @@ func TestDatabaseConnection() {
|
|||||||
cmd.Stderr = &out
|
cmd.Stderr = &out
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(fmt.Sprintf("Error testing database connection: %v\nOutput: %s\n", err, out.String()))
|
Error(fmt.Sprintf("Error testing database connection: %v\nOutput: %s\n", err, out.String()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -196,7 +157,7 @@ func GetEnvVariable(envName, oldEnvName string) string {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
Worn("%s is deprecated, please use %s instead!\n", oldEnvName, envName)
|
Warn("%s is deprecated, please use %s instead!\n", oldEnvName, envName)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user