mirror of
https://github.com/jkaninda/mysql-bkup.git
synced 2025-12-06 21:49:40 +01:00
318 lines
9.4 KiB
Go
318 lines
9.4 KiB
Go
/*
|
|
MIT License
|
|
|
|
Copyright (c) 2023 Jonas Kaninda
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
package pkg
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/jkaninda/mysql-bkup/utils"
|
|
"github.com/spf13/cobra"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
type Database struct {
|
|
Host string `yaml:"host"`
|
|
Port string `yaml:"port"`
|
|
Name string `yaml:"name"`
|
|
User string `yaml:"user"`
|
|
Password string `yaml:"password"`
|
|
Path string `yaml:"path"`
|
|
}
|
|
type Config struct {
|
|
Databases []Database `yaml:"databases"`
|
|
CronExpression string `yaml:"cronExpression"`
|
|
}
|
|
|
|
type dbConfig struct {
|
|
dbHost string
|
|
dbPort string
|
|
dbName string
|
|
dbUserName string
|
|
dbPassword string
|
|
}
|
|
type targetDbConfig struct {
|
|
targetDbHost string
|
|
targetDbPort string
|
|
targetDbUserName string
|
|
targetDbPassword string
|
|
targetDbName string
|
|
}
|
|
type TgConfig struct {
|
|
Token string
|
|
ChatId string
|
|
}
|
|
type BackupConfig struct {
|
|
backupFileName string
|
|
backupRetention int
|
|
disableCompression bool
|
|
prune bool
|
|
remotePath string
|
|
encryption bool
|
|
usingKey bool
|
|
passphrase string
|
|
publicKey string
|
|
storage string
|
|
cronExpression string
|
|
}
|
|
type FTPConfig struct {
|
|
host string
|
|
user string
|
|
password string
|
|
port string
|
|
remotePath string
|
|
}
|
|
type AzureConfig struct {
|
|
accountName string
|
|
accountKey string
|
|
containerName string
|
|
}
|
|
|
|
// SSHConfig holds the SSH connection details
|
|
type SSHConfig struct {
|
|
user string
|
|
password string
|
|
hostName string
|
|
port string
|
|
identifyFile string
|
|
}
|
|
type AWSConfig struct {
|
|
endpoint string
|
|
bucket string
|
|
accessKey string
|
|
secretKey string
|
|
region string
|
|
remotePath string
|
|
disableSsl bool
|
|
forcePathStyle bool
|
|
}
|
|
|
|
func initDbConfig(cmd *cobra.Command) *dbConfig {
|
|
// Set env
|
|
utils.GetEnv(cmd, "dbname", "DB_NAME")
|
|
dConf := dbConfig{}
|
|
dConf.dbHost = os.Getenv("DB_HOST")
|
|
dConf.dbPort = os.Getenv("DB_PORT")
|
|
dConf.dbName = os.Getenv("DB_NAME")
|
|
dConf.dbUserName = os.Getenv("DB_USERNAME")
|
|
dConf.dbPassword = os.Getenv("DB_PASSWORD")
|
|
|
|
err := utils.CheckEnvVars(dbHVars)
|
|
if err != nil {
|
|
utils.Error("Please make sure all required environment variables for database are set")
|
|
utils.Fatal("Error checking environment variables: %s", err)
|
|
}
|
|
return &dConf
|
|
}
|
|
|
|
func getDatabase(database Database) *dbConfig {
|
|
return &dbConfig{
|
|
dbHost: database.Host,
|
|
dbPort: database.Port,
|
|
dbName: database.Name,
|
|
dbUserName: database.User,
|
|
dbPassword: database.Password,
|
|
}
|
|
}
|
|
|
|
// loadSSHConfig loads the SSH configuration from environment variables
|
|
func loadSSHConfig() (*SSHConfig, error) {
|
|
utils.GetEnvVariable("SSH_HOST", "SSH_HOST_NAME")
|
|
sshVars := []string{"SSH_USER", "SSH_HOST", "SSH_PORT", "REMOTE_PATH"}
|
|
err := utils.CheckEnvVars(sshVars)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error missing environment variables: %w", err)
|
|
}
|
|
|
|
return &SSHConfig{
|
|
user: os.Getenv("SSH_USER"),
|
|
password: os.Getenv("SSH_PASSWORD"),
|
|
hostName: os.Getenv("SSH_HOST"),
|
|
port: os.Getenv("SSH_PORT"),
|
|
identifyFile: os.Getenv("SSH_IDENTIFY_FILE"),
|
|
}, nil
|
|
}
|
|
func loadFtpConfig() *FTPConfig {
|
|
// Initialize data configs
|
|
fConfig := FTPConfig{}
|
|
fConfig.host = utils.GetEnvVariable("FTP_HOST", "FTP_HOST_NAME")
|
|
fConfig.user = os.Getenv("FTP_USER")
|
|
fConfig.password = os.Getenv("FTP_PASSWORD")
|
|
fConfig.port = os.Getenv("FTP_PORT")
|
|
fConfig.remotePath = os.Getenv("REMOTE_PATH")
|
|
err := utils.CheckEnvVars(ftpVars)
|
|
if err != nil {
|
|
utils.Error("Please make sure all required environment variables for FTP are set")
|
|
utils.Fatal("Error missing environment variables: %s", err)
|
|
}
|
|
return &fConfig
|
|
}
|
|
func loadAzureConfig() *AzureConfig {
|
|
// Initialize data configs
|
|
aConfig := AzureConfig{}
|
|
aConfig.containerName = os.Getenv("AZURE_STORAGE_CONTAINER_NAME")
|
|
aConfig.accountName = os.Getenv("AZURE_STORAGE_ACCOUNT_NAME")
|
|
aConfig.accountKey = os.Getenv("AZURE_STORAGE_ACCOUNT_KEY")
|
|
|
|
err := utils.CheckEnvVars(azureVars)
|
|
if err != nil {
|
|
utils.Error("Please make sure all required environment variables for Azure Blob storage are set")
|
|
utils.Fatal("Error missing environment variables: %s", err)
|
|
}
|
|
return &aConfig
|
|
}
|
|
|
|
func initAWSConfig() *AWSConfig {
|
|
// Initialize AWS configs
|
|
aConfig := AWSConfig{}
|
|
aConfig.endpoint = utils.GetEnvVariable("AWS_S3_ENDPOINT", "S3_ENDPOINT")
|
|
aConfig.accessKey = utils.GetEnvVariable("AWS_ACCESS_KEY", "ACCESS_KEY")
|
|
aConfig.secretKey = utils.GetEnvVariable("AWS_SECRET_KEY", "SECRET_KEY")
|
|
aConfig.bucket = utils.GetEnvVariable("AWS_S3_BUCKET_NAME", "BUCKET_NAME")
|
|
aConfig.remotePath = utils.GetEnvVariable("AWS_S3_PATH", "S3_PATH")
|
|
|
|
aConfig.region = os.Getenv("AWS_REGION")
|
|
disableSsl, err := strconv.ParseBool(os.Getenv("AWS_DISABLE_SSL"))
|
|
if err != nil {
|
|
disableSsl = false
|
|
}
|
|
forcePathStyle, err := strconv.ParseBool(os.Getenv("AWS_FORCE_PATH_STYLE"))
|
|
if err != nil {
|
|
forcePathStyle = false
|
|
}
|
|
aConfig.disableSsl = disableSsl
|
|
aConfig.forcePathStyle = forcePathStyle
|
|
err = utils.CheckEnvVars(awsVars)
|
|
if err != nil {
|
|
utils.Error("Please make sure all required environment variables for AWS S3 are set")
|
|
utils.Fatal("Error checking environment variables: %s", err)
|
|
}
|
|
return &aConfig
|
|
}
|
|
func initBackupConfig(cmd *cobra.Command) *BackupConfig {
|
|
utils.SetEnv("STORAGE_PATH", storagePath)
|
|
utils.GetEnv(cmd, "cron-expression", "BACKUP_CRON_EXPRESSION")
|
|
utils.GetEnv(cmd, "path", "REMOTE_PATH")
|
|
// Get flag value and set env
|
|
remotePath := utils.GetEnvVariable("REMOTE_PATH", "SSH_REMOTE_PATH")
|
|
storage = utils.GetEnv(cmd, "storage", "STORAGE")
|
|
prune := false
|
|
backupRetention := utils.GetIntEnv("BACKUP_RETENTION_DAYS")
|
|
if backupRetention > 0 {
|
|
prune = true
|
|
}
|
|
disableCompression, _ = cmd.Flags().GetBool("disable-compression")
|
|
_, _ = cmd.Flags().GetString("mode")
|
|
passphrase := os.Getenv("GPG_PASSPHRASE")
|
|
_ = utils.GetEnv(cmd, "path", "AWS_S3_PATH")
|
|
cronExpression := os.Getenv("BACKUP_CRON_EXPRESSION")
|
|
|
|
publicKeyFile, err := checkPubKeyFile(os.Getenv("GPG_PUBLIC_KEY"))
|
|
if err == nil {
|
|
encryption = true
|
|
usingKey = true
|
|
} else if passphrase != "" {
|
|
encryption = true
|
|
usingKey = false
|
|
}
|
|
// Initialize backup configs
|
|
config := BackupConfig{}
|
|
config.backupRetention = backupRetention
|
|
config.disableCompression = disableCompression
|
|
config.prune = prune
|
|
config.storage = storage
|
|
config.encryption = encryption
|
|
config.remotePath = remotePath
|
|
config.passphrase = passphrase
|
|
config.publicKey = publicKeyFile
|
|
config.usingKey = usingKey
|
|
config.cronExpression = cronExpression
|
|
return &config
|
|
}
|
|
|
|
type RestoreConfig struct {
|
|
s3Path string
|
|
remotePath string
|
|
storage string
|
|
file string
|
|
bucket string
|
|
usingKey bool
|
|
passphrase string
|
|
privateKey string
|
|
}
|
|
|
|
func initRestoreConfig(cmd *cobra.Command) *RestoreConfig {
|
|
utils.SetEnv("STORAGE_PATH", storagePath)
|
|
utils.GetEnv(cmd, "path", "REMOTE_PATH")
|
|
|
|
// Get flag value and set env
|
|
s3Path := utils.GetEnv(cmd, "path", "AWS_S3_PATH")
|
|
remotePath := utils.GetEnvVariable("REMOTE_PATH", "SSH_REMOTE_PATH")
|
|
storage = utils.GetEnv(cmd, "storage", "STORAGE")
|
|
file = utils.GetEnv(cmd, "file", "FILE_NAME")
|
|
bucket := utils.GetEnvVariable("AWS_S3_BUCKET_NAME", "BUCKET_NAME")
|
|
passphrase := os.Getenv("GPG_PASSPHRASE")
|
|
privateKeyFile, err := checkPrKeyFile(os.Getenv("GPG_PRIVATE_KEY"))
|
|
if err == nil {
|
|
usingKey = true
|
|
} else if passphrase != "" {
|
|
usingKey = false
|
|
}
|
|
|
|
// Initialize restore configs
|
|
rConfig := RestoreConfig{}
|
|
rConfig.s3Path = s3Path
|
|
rConfig.remotePath = remotePath
|
|
rConfig.storage = storage
|
|
rConfig.bucket = bucket
|
|
rConfig.file = file
|
|
rConfig.storage = storage
|
|
rConfig.passphrase = passphrase
|
|
rConfig.usingKey = usingKey
|
|
rConfig.privateKey = privateKeyFile
|
|
return &rConfig
|
|
}
|
|
func initTargetDbConfig() *targetDbConfig {
|
|
tdbConfig := targetDbConfig{}
|
|
tdbConfig.targetDbHost = os.Getenv("TARGET_DB_HOST")
|
|
tdbConfig.targetDbPort = utils.EnvWithDefault("TARGET_DB_PORT", "3306")
|
|
tdbConfig.targetDbName = os.Getenv("TARGET_DB_NAME")
|
|
tdbConfig.targetDbUserName = os.Getenv("TARGET_DB_USERNAME")
|
|
tdbConfig.targetDbPassword = os.Getenv("TARGET_DB_PASSWORD")
|
|
|
|
err := utils.CheckEnvVars(tdbRVars)
|
|
if err != nil {
|
|
utils.Error("Please make sure all required environment variables for the target database are set")
|
|
utils.Fatal("Error checking target database environment variables: %s", err)
|
|
}
|
|
return &tdbConfig
|
|
}
|
|
func loadConfigFile() (string, error) {
|
|
backupConfigFile, err := checkConfigFile(os.Getenv("BACKUP_CONFIG_FILE"))
|
|
if err == nil {
|
|
return backupConfigFile, nil
|
|
}
|
|
return "", fmt.Errorf("backup config file not found")
|
|
}
|