# # # # bundle agent postgresql(cfg_param) { vars: "default_version" string => "15"; debian:: "default_version" string => "15"; any:: "default_cfg" data => '{ "bind_address":"127.0.0.1", "user":"postgres", "port":"5432", "backup_dir":"/var/backups/psql", "version":"$(default_version)", }'; classes: "settings_exists" expression => isvariable("cfg_param[settings]"); vars: settings_exists:: "settings_keys" slist => getindices(@(cfg_param[settings])); "settings[$(settings_keys)]" string => "$(cfg_param[settings][$(settings_keys)])"; #!settings_exists: any:: "cfg" data => mergedata(@(default_cfg),@(cfg_param)); freebsd:: "user" string => "postgres"; "server_pkgs" slist => {"postgresql17-server"}; "client_pkgs" slist => {"postgresql17-client"}; "version" string => "17"; "service_name" string => "postgresql-server"; "cfg_dir" string => "/usr/local/etc/postgresql"; # "cfg_file" string => "/usr/local/etc/postgresql/"; "bin_dir" string => "/usr/local/bin"; "default_datadir" string => "/var/db/postgresql"; "postgres_cmd" string => "/usr/local/libexec/mysqld"; debian:: "user" string => "postgres"; "version" string => "$(cfg[version])"; "server_pkgs" slist => {"postgresql-$(version)"}; "client_pkgs" slist => {"postgresql-client-$(version)"}; "service_name" string => "postgresql"; "cfg_dir" string => "/etc/postgresql/$(version)/main"; "cfg_file" string => "$(cfg_dir)/postgresql.conf"; "bin_dir" string => "/usr/bin"; "default_datadir" string => "/var/lib/postgresql"; "postgres_cmd" string => "/usr/sbin/mysqld"; "pg_hba_conf" string => "$(cfg_dir)/pg_hba.conf"; "postgresql_conf" string => "$(cfg_dir)/postgresql.conf"; fedora|centos:: # Fedora (and probably RedHat) require a database initialization after installation: # postgresql-setup --initdb --unit postgresql # this populates the data / config dir with the required files "user" string => "postgres"; "server_pkgs" slist => {"postgresql-server"}; "client_pkgs" slist => {"postgresql"}; "version" string => ""; "service_name" string => "postgresql.service"; "cfg_dir" string => "/var/lib/pgsql/data"; "cfg_file" string => "/var/lib/pgsql/data/postgresql.conf"; "hba_file" string => "/var/lib/pgsql/data/pg_hba.conf"; "bin_dir" string => "/usr/bin"; "default_datadir" string => "/var/lib/pgsql/data"; "postgres_cmd" string => "/usr/bin/postgres"; any:: "psql_cmd" string => "$(bin_dir)/psql"; "pg_dump_cmd" string => "$(bin_dir)/pg_dump"; reports: } bundle agent install_postgresql_server(cfg) { classes: # "type_$(mysql.type)" ; vars: # "psql_idx" slist => getindices(@(cfg[settings][config])); # "settings[mysqld][$(mysqld_idx)]" string => "$(cfg[settings][mysqld][$(mysqld_idx)])"; # "datadir" string => ifelse( # isvariable("cfg[settings][mysqld][datadir]"), # "$(cfg[settings][mysqld][datadir])", # "$(mysql.default_datadir)" # ); # type_mariadb:: # "install_db_exe" string => ifelse( # fileexists("$(mysql.bin_dir)/mysql_install_db"), # "$(mysql.bin_dir)/mysql_install_db", # "$(mysql.bin_dir)/mariadb-install-db" # ); # "install_db_cmd" string => "if [ ! -d $(datadir)/mysql ]; then $(install_db_exe) --user=$(mysql.user)>/dev/null ; fi"; # type_mysql8:: # "install_db_cmd" string => "if [ ! -d $(datadir)/mysql ]; then $(mysql.mysqld_cmd) --initialize-insecure --user=$(mysql.user); fi"; # "j" string => storejson(@(cfg)); methods: "any" usebundle => postgresql(@(cfg)), handle => "postgresql_cfg_done"; "any" usebundle => wmde_install_packages(@(postgresql.server_pkgs),"postgresql_server"); files: "$(postgresql.pg_hba_conf)" edit_line => postgresql_ensure_line_present("host all all 0.0.0.0/0 scram-sha-256"), classes => if_repaired("postgresql_repaired"), depends_on => { "postgresql_server_pkgs_installed","postgresql_running" }; "$(postgresql.cfg[backup_dir])/." perms => mog("750","$(postgresql.user)","$(postgresql.user)"), create => "true", depends_on => { "postgresql_server_pkgs_installed" }; "$(postgresql.postgresql_conf)" edit_line => set_variable_values("postgresql.settings"), classes => if_repaired("postgresql_repaired"), depends_on => { "postgresql_server_pkgs_installed" }; services: "$(postgresql.service_name)" depends_on => {"postgresql_server_pkgs_installed"}, service_policy => "start", handle => "postgresql_running"; postgresql_repaired:: "$(postgresql.service_name)" service_policy => "restart", depends_on => {"postgresql_running"}; reports: } bundle agent install_postgresql_client { methods: # "any" usebundle => wmde_install_packages(@(mysql.client_pkgs),"mysql_client"), # handle => "mysql_client_installed"; } body contain postgresql_psql_cmd { useshell=>"useshell"; exec_owner => "$(postgresql.user)"; } bundle edit_line postgresql_ensure_line_present(line_to_ensure) { insert_lines: "$(line_to_ensure)" comment => "Füge die gewünschte Zeile hinzu, falls sie fehlt"; } bundle agent postgresql_table_exists(dbdef,table_name) { vars: "pass_arg" string => ifelse ( isvariable("dbdef[db_pass]"), "-p$(dbdef[db_pass])", "" ); "host_arg" string => ifelse ( isvariable("dbdef[db_host]"), "-h$(dbdef[db_host])", "" ); "user_arg" string => ifelse ( isvariable("dbdef[db_user]"), "-u$(dbdef[db_user])", "" ); "xargs" string => "$(pass_arg) $(host_arg) $(user_arg)"; "classname" string => "mysql_$(dbdef[db_name])_$(table_name)_exists"; "cmd" string => 'mysql $(xargs) -e "show tables LIKE \'$(table_name)\'" $(dbdef[db_name]) > /tmp/$(dbdef[db_name]).check && if grep -q \'$(table_name)\' /tmp/$(dbdef[db_name]).check ; then echo "+$(classname)"; else echo "-$(classname)"; fi'; commands: "$(cmd)" contain => mysql_cmd, inform => "false", module => "true"; reports: } bundle agent postgresql_backup_all(cfg) { vars: "cmd" string => '$(mysql.mysql_cmd) -N -e \'show databases\' | while read dbname; do $(mysql.mysqldump_cmd) --default-character-set=utf8mb4 --complete-insert --routines --triggers --single-transaction --max_allowed_packet=512M "$dbname" > $(cfg[backup_dir])/"$dbname".sql; done'; reports: # "CMD: $(cmd)"; } bundle agent postgresql_backup_db(cfg,file) { classes: "type_$(mysql.type)" ; vars: "table_exists_cmd" string => '$(mysql.mysql_cmd) -e "show tables LIKE \'$(table_name)\'" $(cdfg[db_name]) | grep -q $(table_name)'; "cmd" string => "$(mysql.mysqldump_cmd) --default-character-set=utf8mb4 --no-tablespaces --complete-insert --routines --triggers --single-transaction --max_allowed_packet=512M -h$(cfg[db_host]) -u$(cfg[db_user]) -p$(cfg[db_pass]) $(cfg[db_name]) >$(file)"; } # # Create cronjob # @param cfg definition for database, db_user, db_host, db_pass, db_name # @param file file to dump database into # @table_name a table in the database which has to exist, if not no dump will be done # @run "true" or "false", means create cron job or not # # # Create cronjob # @param cfg definition for database, db_user, db_host, db_pass, db_name # @param file file to dump database into # @run "true" or "false", means create cron job or not # bundle agent create_pgdump_cron(cfg,file,run) { classes: "create_cron" expression => strcmp("$(run)","true"); vars: "cron" string => ifelse( isvariable("cfg[db_cron]"), "$(cfg[db_cron])", "0 1 * * * " ); "user_args" string => "-U$(cfg[db_user]) -h$(cfg[db_host]) "; "table_exists_cmd" string => "/bin/sh -c ' [ \"`PGPASSWORD=\\\"$(cfg[db_pass])\\\" $(postgresql.psql_cmd) $(user_args) -d $(cfg[db_name]) -t -c \"SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = '\\''$(cfg[db_check_table])'\\'');\"`\" = \" t\" ]'"; "backup_cmd" string => "/bin/sh -c 'PGPASSWORD=\"$(cfg[db_pass])\" $(postgresql.pg_dump_cmd) $(user_args) -F p --inserts -f $(file) $(cfg[db_name])'"; files: !create_cron:: "/etc/cron.d/pgdump-$(cfg[db_name])" delete=>tidy; create_cron:: "/etc/cron.d/pgdump-$(cfg[db_name])" perms => m("644"), create => "true", content => " # # /etc/cron.d/mysqldump-$(cfg[db_name]) # SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin $(cron) root $(table_exists_cmd) && $(backup_cmd) "; } bundle agent create_postgresql_db(cfg) { classes: "do_restore" expression => strcmp("$(cfg[db_restore])","true"); "do_backup" expression => strcmp("$(cfg[db_backup])","true"); vars: "db_name" string => "$(cfg[db_name])"; "db_user" string => "$(cfg[db_user])"; "host" string => "$(cfg[db_user_host])"; "db_pass" string => "$(cfg[db_pass])"; "create_db_cmd" string => "echo \"SELECT 'CREATE DATABASE $(db_name)' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$(db_name)')\gexec\" | $(postgresql.psql_cmd) "; "create_user_cmd" string => "USER_EXISTS=`psql -tAc \"SELECT 1 FROM pg_roles WHERE rolname='$(db_user)'\"` && [ \"$USER_EXISTS\" != \"1\" ] && psql -c \"CREATE USER $(db_user) WITH PASSWORD '$(db_pass)';\" || psql -c \"ALTER USER $(db_user) WITH PASSWORD '$(db_pass)';\" > /dev/null"; "grant_cmd" string => "$(postgresql.psql_cmd) -d $(db_name) -c \"GRANT ALL PRIVILEGES ON DATABASE $(db_name) TO $(db_user); GRANT ALL ON SCHEMA public TO $(db_user);\" > /dev/null"; methods: do_restore:: "any" usebundle => restore_postgres_db_conditional(@(cfg),"$(postgresql.cfg[backup_dir])/$(cfg[db_name])-pgdmp.sql"), depends_on => { "postgresql_$(cfg[db_name])$(cfg[db_user])_grant_created" }; do_backup:: "any" usebundle => create_pgdump_cron(@(cfg),"$(postgresql.cfg[backup_dir])/$(cfg[db_name])-pgdmp.sql","true"); !do_backup:: "any" usebundle => create_pgdump_cron(@(cfg),"$(postgresql.cfg[backup_dir])/$(cfg[db_name])-pgdmp.sql","false"); commands: "$(create_db_cmd)" handle => "postgresql_$(cfg[db_name])_created", contain => postgresql_psql_cmd, inform => "false"; "$(create_user_cmd)" handle => "postgresql_$(cfg[db_user])_created", contain => postgresql_psql_cmd, inform => "false"; "$(grant_cmd)" contain => postgresql_psql_cmd, inform => "false", depends_on => { "postgresql_$(cfg[db_name])_created", "postgresql_$(cfg[db_user])_created" }, handle => "postgresql_$(cfg[db_name])$(cfg[db_user])_grant_created"; reports: # "CCC $(create_user_cmd)"; # "POSTGRESQL ARGS: $(args)"; # # "CREA USER: $(create_user_cmd)"; # string => "USER_EXISTS=`psql -tAc \"SELECT 1 FROM pg_roles WHERE rolname='$(db_user)'\"`", # } bundle agent restore_postgresql_db(cfg,file) { commands: "$(mysql.mysql_cmd)" args => "-h$(cfg[db_host]) -u$(cfg[db_user]) -p$(cfg[db_pass]) $(cfg[db_name]) < $(file)", contain => wmde_cmd_useshell; } bundle agent restore_postgres_db_conditional(cfg,file) { classes: "backup_exists" expression => fileexists("$(file)"); vars: "user_args" string => "-U$(cfg[db_user]) -h$(cfg[db_host]) "; "table_not_exists_cmd" string => "/bin/sh -c '! [ \"`PGPASSWORD=\\\"$(cfg[db_pass])\\\" $(postgresql.psql_cmd) $(user_args) -d $(cfg[db_name]) -t -c \"SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = '\\''$(cfg[db_check_table])'\\'');\"`\" = \" t\" ]'"; "restore_cmd" string => "PGPASSWORD=\"$(cfg[db_pass])\" $(postgresql.psql_cmd) $(user_args) -d$(cfg[db_name]) < $(file)"; classes: "check_table_not_exists" expression => returnszero("$(table_not_exists_cmd)","useshell"); commands: backup_exists&check_table_not_exists:: "$(restore_cmd)" contain => wmde_cmd_useshell; reports: # "RESTORE_CMD: $(restore_cmd)"; # backup_exists:: # "Restore possible"; }