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