diff --git a/postgresql.cf b/postgresql.cf new file mode 100644 index 0000000..4126c01 --- /dev/null +++ b/postgresql.cf @@ -0,0 +1,359 @@ +# +# +# +# +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"; + +}