refactor: Wszystkie pakiety przeniesione do internal
This commit is contained in:
		
							
								
								
									
										75
									
								
								internal/cfg/config.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								internal/cfg/config.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
package cfg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Connection struct {
 | 
			
		||||
	Host   string `json:"Host,omitempty"`
 | 
			
		||||
	User   string `json:"User,omitempty"`
 | 
			
		||||
	Port   uint   `json:"Port,omitempty"`
 | 
			
		||||
	DbName string `json:"DbName,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Config struct {
 | 
			
		||||
	PassFile    string       `json:"Passfile"`
 | 
			
		||||
	PsqlExec    string       `json:"PsqlExec"`
 | 
			
		||||
	SqlDir      string       `json:"SqlDir"`
 | 
			
		||||
	Defaults    Connection   `json:"Defaults"`
 | 
			
		||||
	Connections []Connection `json:"Connections"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetConfig(params Parameters) (config Config, err error) {
 | 
			
		||||
	bytes, err := os.ReadFile(params.ConfigFile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return config, fmt.Errorf("błąd odczytu pliku konfiguracji: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	err = json.Unmarshal(bytes, &config)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return config, fmt.Errorf("błąd parsowania pliku konfiguracji: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	if config.PassFile == "" && params.Passfile != "" {
 | 
			
		||||
		config.PassFile = params.Passfile
 | 
			
		||||
	}
 | 
			
		||||
	if config.PassFile == "" {
 | 
			
		||||
		return config, fmt.Errorf("nie podano Passfile (dodaj w konfiguracji lub użyj flag --passfile)")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if config.SqlDir == "" && params.SqlDir != "" {
 | 
			
		||||
		config.SqlDir = params.SqlDir
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = fixConnections(&config)
 | 
			
		||||
	return config, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fixConnections(config *Config) error {
 | 
			
		||||
	def := config.Defaults
 | 
			
		||||
	for i := range config.Connections {
 | 
			
		||||
		con := &config.Connections[i]
 | 
			
		||||
 | 
			
		||||
		if con.DbName == "" {
 | 
			
		||||
			con.DbName = def.DbName
 | 
			
		||||
		}
 | 
			
		||||
		if con.User == "" {
 | 
			
		||||
			con.User = def.User
 | 
			
		||||
		}
 | 
			
		||||
		if con.Host == "" {
 | 
			
		||||
			con.Host = def.Host
 | 
			
		||||
		}
 | 
			
		||||
		if con.Port == 0 {
 | 
			
		||||
			if def.Port != 0 {
 | 
			
		||||
				con.Port = def.Port
 | 
			
		||||
			} else {
 | 
			
		||||
				con.Port = 5432 // domyślny dla PostgreSQL
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if con.DbName == "" || con.Host == "" || con.User == "" {
 | 
			
		||||
			return fmt.Errorf("opis połączenia z pozycji %d jest niekompletny: %#v", i+1, con)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										137
									
								
								internal/cfg/params.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								internal/cfg/params.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
package cfg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const MULTISQLPASS = "MULTISQLPASS" // nazwa ziennej środowiskowej z hasłem
 | 
			
		||||
 | 
			
		||||
type Parameters struct {
 | 
			
		||||
	ConfigFile string
 | 
			
		||||
	Passfile   string
 | 
			
		||||
	OutDir     string
 | 
			
		||||
	SqlDir     string
 | 
			
		||||
	LogFile    string
 | 
			
		||||
	Verbose    bool
 | 
			
		||||
	AskPass    bool
 | 
			
		||||
	Version    bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var params Parameters
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	flag.BoolVar(¶ms.Verbose, "verbose", false, "Dodatkowe komunkaty diagnostyczne")
 | 
			
		||||
	flag.StringVar(¶ms.ConfigFile, "config", "multisql.conf", "Plik konfiguracji")
 | 
			
		||||
	flag.StringVar(¶ms.Passfile, "passfile", "", "Plik pgpass z hasłami do baz")
 | 
			
		||||
	flag.StringVar(¶ms.OutDir, "outdir", "", "Katalog (istniejący i z prawem do zapisu), do którego generowane są wyniki")
 | 
			
		||||
	flag.StringVar(¶ms.SqlDir, "sqldir", "scripts", "Katalog, w którym znajdują się skrypty do uruchomienia")
 | 
			
		||||
	flag.StringVar(¶ms.LogFile, "log", "", "Plik, do którego zostanie dopisany log programu")
 | 
			
		||||
	flag.BoolVar(¶ms.AskPass, "P", false, "Pytaj o hasło. Jeśli nie podane wymaga się hasła w ")
 | 
			
		||||
	flag.BoolVar(¶ms.Version, "version", false, "Wypisuje wersję i kończy działanie")
 | 
			
		||||
 | 
			
		||||
	flag.Usage = printUsage
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
}
 | 
			
		||||
func GetParams() Parameters {
 | 
			
		||||
	return params
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func printUsage() {
 | 
			
		||||
	fmt.Fprintf(os.Stderr,
 | 
			
		||||
		`
 | 
			
		||||
multisql - uruchamia zestaw skryptów na skonfigurowanej liście baz danych.
 | 
			
		||||
 | 
			
		||||
Program, dla każdej z baz wskazanych w konfiguracji, uruchamia kolejno każdy
 | 
			
		||||
z plików sql wskazanych parametrem lub w pliku konfiguracji poprzez
 | 
			
		||||
uruchomienie narzędzia psql:
 | 
			
		||||
 | 
			
		||||
    psql -f skrypt.sql -w -L log.txt _szczegóły_połaczenia_ 2>stderr.txt  > stdout.txt
 | 
			
		||||
 | 
			
		||||
Skrypty mogą mieć dowolne rozszerzenia ale podkatalogi nie są obsługiwane.
 | 
			
		||||
Pliki wynikowe zapisywane są do katalogu wskazanego w outdir w strukturze o postaci
 | 
			
		||||
output:
 | 
			
		||||
 -> data-godzina-pid
 | 
			
		||||
    -> host-port-baza-user
 | 
			
		||||
	   ->  skrypt.sql
 | 
			
		||||
	       -> log.txt
 | 
			
		||||
	       -> stdout.txt
 | 
			
		||||
		   -> stderr.txt
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Użycie:
 | 
			
		||||
		multisql -outdir /tmp -sqldir /data/skrypty -passfile ./hasla
 | 
			
		||||
 | 
			
		||||
Użycie w trybie szyfrowania:
 | 
			
		||||
		multisql encrypt plik.wynikowy.zaszyfrowany plik.zródłowy
 | 
			
		||||
	lub
 | 
			
		||||
		multisql [-P] decrypt plik.źródłowy.zaszyfrowany [plik.wynikowy.jawny]
 | 
			
		||||
 | 
			
		||||
Opis flag:
 | 
			
		||||
`,
 | 
			
		||||
	)
 | 
			
		||||
	flag.PrintDefaults()
 | 
			
		||||
	fmt.Fprintf(os.Stderr,
 | 
			
		||||
		`
 | 
			
		||||
Plik passfile ma standardowy format .pgpass PostgreSQLa.
 | 
			
		||||
 | 
			
		||||
Plik multisql.conf ma format JSON, np:
 | 
			
		||||
> `,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	c := Config{
 | 
			
		||||
		PassFile: "mypgpass",
 | 
			
		||||
		PsqlExec: "/usr/local/bin/psql",
 | 
			
		||||
		SqlDir:   "/data/skrypty-sql",
 | 
			
		||||
		Defaults: Connection{
 | 
			
		||||
			Port:   5433,
 | 
			
		||||
			User:   "myapp",
 | 
			
		||||
			DbName: "moja-db",
 | 
			
		||||
		},
 | 
			
		||||
		Connections: []Connection{
 | 
			
		||||
			{
 | 
			
		||||
				Host: "10.20.30.01",
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				Host:   "10.20.30.02",
 | 
			
		||||
				DbName: "innadb",
 | 
			
		||||
				User:   "innyuser",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b, _ := json.Marshal(&c)
 | 
			
		||||
	var out bytes.Buffer
 | 
			
		||||
	_ = json.Indent(&out, b, "> ", "\t")
 | 
			
		||||
	_, _ = out.WriteTo(os.Stderr)
 | 
			
		||||
 | 
			
		||||
	fmt.Fprintf(os.Stderr, `
 | 
			
		||||
 | 
			
		||||
PsqlExec jest opcjonalny - jesli nie zostanie podany wyszukuje się programu psql.exe w PATH.
 | 
			
		||||
 | 
			
		||||
Każde połączenie w tablicy Connections może zawierać Host, Port, User i DbName.
 | 
			
		||||
Brakujące wartości są uzupełniane z sekcji Defaults (która ma taki sam
 | 
			
		||||
format jak obiekt w Connections).
 | 
			
		||||
 | 
			
		||||
Parametry mają pierwszeństwo przed wartościami w konfiguracji.
 | 
			
		||||
 | 
			
		||||
Format pliku passfile jest następujący:
 | 
			
		||||
 | 
			
		||||
    hostname:port:database:username:password
 | 
			
		||||
 | 
			
		||||
W szczegółach opisano go na https://www.postgresql.org/docs/current/libpq-pgpass.html.
 | 
			
		||||
 | 
			
		||||
Aktualnie obsługiwana jest jedynie zaszyforowana postać pliku. Przed użyciem należy
 | 
			
		||||
plik zaszyfrować:
 | 
			
		||||
 | 
			
		||||
    multsql encrypt pgpass.encrypted  pgpass
 | 
			
		||||
 | 
			
		||||
Przy użyciu (odszyfrowaniu) pliku, hasło jest pobierane ze zmiennej
 | 
			
		||||
środowiskowej %s lub z klawiatury, jeśli użyto opcji -P.
 | 
			
		||||
 | 
			
		||||
`, MULTISQLPASS)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user