diff --git a/apache.cf b/apache.cf index f1c4752..7dfe3e8 100644 --- a/apache.cf +++ b/apache.cf @@ -335,125 +335,124 @@ methods: } -bundle agent apache_vhost -(site_param) +bundle agent apache_vhost(site_param) { -classes: - "delete" expression => $(site[disable]); - "use_ssl" expression => $(site[ssl]); - "use_certbot" expression => strcmp("certbot","$(site[ssl_cert])"); - "do_logrotate" expression => $(site[logrotate]); + classes: + "delete" expression => $(site[disable]); + "use_ssl" expression => $(site[ssl]); + "use_certbot" expression => strcmp("certbot","$(site[ssl_cert])"); + "do_logrotate" expression => $(site[logrotate]); -vars: - # "email":$(apache.admin_email), + vars: + # "email":$(apache.admin_email), - "site_defaults" data => ' - { - "aliases":[], - "ssl_cert":"certbot", - "doc_root":"$(apache.www_dir)/$(site_param[domain])", - "doc_root_options":"Indexes FollowSymLinks", - "php":true, - "php_handler":"$(apache.default_php_handler)", - "logging80":true, - "logging443":true, - "logrotate":false, - } - '; + "site_defaults" data => ' + { + "aliases":[], + "ssl_cert":"certbot", + "doc_root":"$(apache.www_dir)/$(site_param[domain])", + "doc_root_options":"Indexes FollowSymLinks", + "php":true, + "php_handler":"$(apache.default_php_handler)", + "logging80":true, + "logging443":true, + "logrotate":false, + } + '; - "site" data => mergedata(site_defaults,site_param); + "site" data => mergedata(site_defaults,site_param); - "cert_file" string => "$(certbot.certbot_dir)/live/$(site[domain])"; + "cert_file" string => "$(certbot.certbot_dir)/live/$(site[domain])"; - "template_file" - string => - "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/httpd-vhost.conf.mustache"; + "template_file" + string => + "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/httpd-vhost.conf.mustache"; - "domain_file" string => "$(apache.cfg_dir)/Vhosts/$(site[domain]).conf"; - "domain_dir" string => "$(apache.www_dir)/$(site[domain])"; + "domain_file" string => "$(apache.cfg_dir)/Vhosts/$(site[domain]).conf"; + "domain_dir" string => "$(apache.www_dir)/$(site[domain])"; - "ssl_cert" string => ifelse( use_certbot, - "$(certbot.certbot_dir)/live/$(site[domain])/fullchain.pem", - "$(site[ssl_cert])"); - "ssl_key" string => ifelse( use_certbot, - "$(certbot.certbot_dir)/live/$(site[domain])/privkey.pem", - "$(site[ssl_key])"); + "ssl_cert" string => ifelse( use_certbot, + "$(certbot.certbot_dir)/live/$(site[domain])/fullchain.pem", + "$(site[ssl_cert])"); + "ssl_key" string => ifelse( use_certbot, + "$(certbot.certbot_dir)/live/$(site[domain])/privkey.pem", + "$(site[ssl_key])"); - use_ssl&(use_certbot):: - "vhostdeps" slist => { - "apache_ssl_created$(site[domain])", - "apache_vhost_dir_cleaned" - }; - (!use_ssl)|(!use_certbot):: - "vhostdeps" slist => { - "apache_vhost_dir_cleaned" - }; -files: + use_ssl&(use_certbot):: + "vhostdeps" slist => { + "apache_ssl_created$(site[domain])", + "apache_vhost_dir_cleaned" + }; + (!use_ssl)|(!use_certbot):: + "vhostdeps" slist => { + "apache_vhost_dir_cleaned" + }; + files: - delete:: - "$(domain_file)" - delete => tidy, - classes => if_repaired(apache_restart); - - !delete:: - "$(domain_file)" - perms => uperm("$(apache.www_user)","$(apache.www_group)","644"), - create => "true", - edit_template => "$(template_file)", - template_method => "mustache", - handle => "vhost_cfg_done$(site[domain])", - depends_on => @(vhostdeps), - classes => if_repaired("apache_vhost_restart"); + delete:: + "$(domain_file)" + delete => tidy, + classes => if_repaired(apache_restart); + + !delete:: + "$(domain_file)" + perms => uperm("$(apache.www_user)","$(apache.www_group)","644"), + create => "true", + edit_template => "$(template_file)", + template_method => "mustache", + handle => "vhost_cfg_done$(site[domain])", + depends_on => @(vhostdeps), + classes => if_repaired("apache_vhost_restart"); - "$(domain_dir)/." - create => "true", - perms => uperm("$(apache.www_user)","$(apache.www_group)","750"); + "$(domain_dir)/." + create => "true", + perms => uperm("$(apache.www_user)","$(apache.www_group)","750"); -methods: - use_ssl&use_certbot:: - "any" usebundle => certbot_cert(@(site),"$(apache.default_html_dir)"), #,"$(site[domain])"), - handle => "apache_ssl_created$(site[domain])"; + methods: + "any" + usebundle => install_logrot; - "apache_vhost_restart":: - "any" usebundle => restart_apache("$(site[domain])"), - depends_on => { - "vhost_cfg_done$(site[domain])", - "apache_ssl_created$(site[domain])" }; - + use_ssl&use_certbot:: + "any" usebundle => certbot_cert(@(site),"$(apache.default_html_dir)"), #,"$(site[domain])"), + handle => "apache_ssl_created$(site[domain])"; - (!use_ssl)|(!use_certbot):: - "apache_vhost_restart":: - "any" usebundle => restart_apache("$(site[domain])"), - depends_on => {"vhost_cfg_done$(site[domain])" }; + apache_vhost_restart&(use_ssl&use_certbot):: + "any" + usebundle => restart_apache("$(site[domain])"), + depends_on => { + "vhost_cfg_done$(site[domain])", + "apache_ssl_created$(site[domain])" }; - "any" usebundle => install_logrot; + (!use_ssl&apache_vhost_restart)|(!use_certbot&apache_vhost_restart):: + "any" + usebundle => restart_apache("$(site[domain])"), + depends_on => {"vhost_cfg_done$(site[domain])" }; -files: - do_logrotate:: - "$(logrot.dir)/$(site[domain])" - create => "true", - edit_defaults => backup("false"), - edit_template => "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/httpd-weblogrot.mustache", - template_method => "mustache"; -commands: - + files: + do_logrotate:: + "$(logrot.dir)/$(site[domain])" + create => "true", + edit_defaults => backup("false"), + edit_template => "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/httpd-weblogrot.mustache", + template_method => "mustache"; - "echo" - args => "$(site[domain]).conf >> $(sys.workdir)/data/agent/apache/domains.txt", - inform => "false", - depends_on => {"vhost_cfg_done$(site[domain])"}, - contain => wmde_cmd_useshell; + commands: + "echo" + args => "$(site[domain]).conf >> $(sys.workdir)/data/agent/apache/domains.txt", + inform => "false", + depends_on => {"vhost_cfg_done$(site[domain])"}, + contain => wmde_cmd_useshell; -reports: -# "SITE: $(site[domain]): $(site[logrotate])"; -# !do_logrotate:: -# "LOGOROOTATE FOR $(site[domain]): FALSE"; -# do_logrotate:: -# "LOGOROOTATE FOR $(site[domain]): TRUE"; + reports: +# "SITE: $(site[domain]): $(site[logrotate])"; +# !do_logrotate:: +# "LOGOROOTATE FOR $(site[domain]): FALSE"; +# do_logrotate:: +# "LOGOROOTATE FOR $(site[domain]): TRUE"; } diff --git a/lego.cf b/lego.cf index e346635..cfd7f75 100644 --- a/lego.cf +++ b/lego.cf @@ -4,99 +4,132 @@ bundle agent lego { -vars: - "pkgs" slist => { - "lego" - }; - "exe" string => "/usr/bin/lego"; - "data_dir" string => "/etc/lego"; -debian:: - "exe" string => "/usr/bin/lego"; - "data_dir" string => "/etc/lego"; - "pkgs" slist => { - "lego","cron" - }; - -freebsd:: - "exe" string => "/usr/local/bin/lego"; - "data_dir" string => "/usr/local/etc/lego"; + vars: + "pkgs" slist => { + "lego" + }; + "exe" string => "/usr/bin/lego"; + "data_dir" string => "/etc/lego"; + debian:: + "exe" string => "/usr/bin/lego"; + "data_dir" string => "/etc/lego"; + "pkgs" slist => { + "lego","cron" + }; + freebsd:: + "exe" string => "/usr/local/bin/lego"; + "data_dir" string => "/usr/local/etc/lego"; } bundle agent install_lego { -methods: - "any" usebundle => wmde_install_packages( @(lego.pkgs),"lego"); -files: - "$(lego.data_dir)/." - create => "true", - perms => m("750"), - depends_on => {"lego_pkgs_installed"}, - handle => "lego_installed"; - + methods: + "any" usebundle => wmde_install_packages( @(lego.pkgs),"lego"); + files: + "$(lego.data_dir)/." + create => "true", + perms => m("750"), + depends_on => {"lego_pkgs_installed"}, + handle => "lego_installed"; } +bundle agent lego_dns_certs(sites) +{ + vars: + "idx" + slist => getindices(@(sites)); + methods: + "$(idx)" + usebundle => lego_dns_cert(@(sites[$(idx)])); +} bundle agent lego_dns_cert(site) { -vars: - # command to read all domains a certificate contains - "cert_test_cmd" string => "$(def.wmde_lib)/scripts/get-domains-from-cert.sh $(lego.data_dir)/certificates/$(site[domain]).crt"; + vars: + # command to read all domains a certificate contains + "cert_test_cmd" string => "$(def.wmde_lib)/scripts/get-domains-from-cert.sh $(lego.data_dir)/certificates/$(site[domain]).crt"; - "ds" slist => {"$(site[domain])"}; - "domains" slist => sort(mergedata(@(ds),getvalues(@(site[aliases])))); - "domains_txt" string => string_mustache("{{#-top-}}{{.}} {{/-top-}}",@(domains)); - "args" string => string_mustache( - "-d {{domain}} {{#aliases}} -d {{.}} {{/aliases}}", - @(site) - ); + "ds" slist => {"$(site[domain])"}; + "domains" slist => sort(mergedata(@(ds),getvalues(@(site[aliases])))); + "domains_txt" string => string_mustache("{{#-top-}}{{.}} {{/-top-}}",@(domains)); + "args" string => string_mustache( + "-d {{domain}} {{#aliases}} -d {{.}} {{/aliases}}", + @(site) + ); - "current_domains_txt" string => execresult("/bin/sh $(cert_test_cmd)","useshell"), - if => isvariable ("site[domain]"), - handle=>"lego_current_domains_ready"; + "current_domains_txt" string => execresult("/bin/sh $(cert_test_cmd)","useshell"), + if => isvariable ("site[domain]"), + handle=>"lego_current_domains_ready"; -classes: - "run_lego" - expression => not (strcmp("$(current_domains_txt) ","$(domains_txt)")), - depends_on => {"lego_current_domains_ready"}; + "site_domain" string => string_replace(string_replace("$(site[domain])", "-", "_"), ".", "_"); -files: - "/etc/cron.d/lego-$(site[domain])" - create => "true", - content => "0 0 * * * root $(site[dnsapi][key]) $(lego.exe) --path $(lego.data_dir) --email $(site[email]) --dns $(site[dnsapi][provider]) $(args) $(site[lego_renew_raw]) renew $(site[lego_renew_raw2])", - depends_on => {"lego_installed"}; - + "site_options" + data => mergedata( "site", parsejson('{ "lego_bin": "$(lego.exe)", "lego_data_dir": "$(lego.data_dir)" }') ), + handle => "site_options_ready"; -commands: - run_lego:: - "$(site[dnsapi][key]) $(lego.exe) --path $(lego.data_dir) --accept-tos $(site[lego_raw]) --email $(site[email]) --dns $(site[dnsapi][provider]) $(args) run" - contain => wmde_cmd_useshell, - depends_on => {"lego_installed"}; + classes: + "run_lego" + expression => not (strcmp("$(current_domains_txt) ","$(domains_txt)")), + depends_on => {"lego_current_domains_ready"}; -# "$(certbot.exe)" -# depends_on => {"certbot_installed","certbot_dry_run_ok"}, -# args => "certonly --agree-tos -n $(webroot_arg) --expand --email $(site[email]) $(args)"; - - - -reports: - - - -# "COMMAND: $(cert_test_cmd)"; -# "CMP: $(current_domains_txt) $(domains_txt)"; - -# "LEG IS INSTALLED" depends_on => {"lego_installed"}; - - -# run_lego:: -# "$(lego.exe)"; -# "--path $(lego.data_dir) --accept-tos --email $(site[email]) --dns $(site[dnsapi][provider]) $(args) run"; - #depends_on => {"lego_installed"}, - + files: + "/etc/cron.d/lego_$(site_domain)" + create => "true", + content => "# Managed by CFEngine +$(site[dnsapi][key]) +0 0 * * * root $(lego.exe) --path $(lego.data_dir) --email $(site[email]) --dns $(site[dnsapi][provider]) $(args) $(site[lego_renew_raw]) renew $(site[lego_renew_raw2]) +", + depends_on => {"lego_installed"}; + systemd:: + "/etc/systemd/system/lego_$(site_domain).timer" + perms => mog('644','root','root'), + copy_from => local_cp("$(sys.workdir)/inputs/wmdelib/templates/lego.timer.txt"), + depends_on => { "lego_installed" }, + classes => if_repaired( "systemd_timer_units" ), + handle => "systemd_timer_$(site_domain)_copied"; + "/etc/systemd/system/lego_$(site_domain).service" + perms => mog('644','root','root'), + edit_template => "$(sys.workdir)/inputs/wmdelib/templates/lego.service.txt", + template_data => @{site_options}, + template_method => "mustache", + depends_on => { "lego_installed", "site_options_ready" }, + classes => if_repaired( "systemd_service_units" ), + handle => "systemd_service_$(site_domain)_copied"; + "/etc/lego/hosting.de.env" + content => "$(site[dnsapi][key])", + perms => mog( "0600", "root", "root"), + depends_on => { "lego_installed" }; + + commands: + run_lego:: + "$(site[dnsapi][key]) $(lego.exe) --path $(lego.data_dir) --accept-tos $(site[lego_raw]) --email $(site[email]) --dns $(site[dnsapi][provider]) $(args) run" + contain => wmde_cmd_useshell, + depends_on => {"lego_installed"}; + + systemd_timer_units|systemd_service_units:: + "/usr/bin/systemctl" + args => "daemon-reload"; + + services: + systemd:: + "lego_$(site_domain).timer" + service_policy => "start", + service_method => generic_systemd_at_boot, + depends_on => { "systemd_timer_$(site_domain)_copied" }; + + reports: +# "COMMAND: $(cert_test_cmd)"; +# "CMP: $(current_domains_txt) $(domains_txt)"; + +# "LEG IS INSTALLED" depends_on => {"lego_installed"}; +# run_lego:: +# "$(lego.exe)"; +# "--path $(lego.data_dir) --accept-tos --email $(site[email]) --dns $(site[dnsapi][provider]) $(args) run"; +# depends_on => {"lego_installed"}, # run_lego:: # "MUST RUN LEGO"; diff --git a/lib.cf b/lib.cf index c0d9db6..50bc864 100644 --- a/lib.cf +++ b/lib.cf @@ -122,39 +122,39 @@ reports: bundle agent wmde_service(service_name,start_cond, restart_cond) { -classes: - freebsd:: - "service_running" expression => returnszero("/usr/sbin/service $(service_name) onestatus >/dev/null 2>&1", "useshell"); + classes: + freebsd:: + "service_running" expression => returnszero("/usr/sbin/service $(service_name) onestatus >/dev/null 2>&1", "useshell"); -commands: - - "freebsd&(!service_running)&($(start_cond))":: - "/usr/sbin/service" - args => "$(service_name) onestart >/dev/null 2>&1", - contain => wmde_cmd_useshell, - handle => "$(handle)_service_started"; - "freebsd&(service_running)&($(start_cond))":: - "/usr/bin/true" - inform => "false", - handle => "$(handle)_service_started"; - - "freebsd&($(restart_cond))":: - "/usr/sbin/service" - args => "$(service_name) onerestart >/dev/null 2>&1", - contain => wmde_cmd_useshell, - handle => "$(handle)_service_restarted"; - -services: - "(!freebsd)&($(start_cond))":: - "$(service_name)" - service_policy => "start", - handle => "$(handle)_service_started"; + commands: - "(!freebsd)&($(restart_cond))":: - "$(service_name)" - service_policy => "restart", - handle => "$(handle)_service_restarted"; -reports: + "freebsd&(!service_running)&($(start_cond))":: + "/usr/sbin/service" + args => "$(service_name) onestart >/dev/null 2>&1", + contain => wmde_cmd_useshell, + handle => "$(handle)_service_started"; + "freebsd&(service_running)&($(start_cond))":: + "/usr/bin/true" + inform => "false", + handle => "$(handle)_service_started"; + + "freebsd&($(restart_cond))":: + "/usr/sbin/service" + args => "$(service_name) onerestart >/dev/null 2>&1", + contain => wmde_cmd_useshell, + handle => "$(handle)_service_restarted"; + + services: + "(!freebsd)&($(start_cond))":: + "$(service_name)" + service_policy => "start", + handle => "$(handle)_service_started"; + + "(!freebsd)&($(restart_cond))":: + "$(service_name)" + service_policy => "restart", + handle => "$(handle)_service_restarted"; + reports: } @@ -186,27 +186,33 @@ bundle agent download_and_untar( install_dir, test_file ) +# @brief Download and untar a tar archive at specified location +# @param name String used for unique handles and classes +# @param sync_src Path to tar archive on the policy hub +# @param sync_dst Path to destination of download archive +# @param install_dir Destination directory for untarred archive +# @param test_file Conditional file for existence of untarred archive { -classes: - "$(name)_untar" expression => not(fileexists("$(test_file)")); + classes: + "$(name)_untar" expression => not(fileexists("$(test_file)")); -files: - "$(sync_dst)" - copy_from => sync_cp("$(sync_src)","$(sys.policy_hub)"), - handle => "$(name)_tgz_copied", - classes => if_repaired ("$(name)_untar"), - perms => m(644); + files: + "$(sync_dst)" + copy_from => sync_cp("$(sync_src)","$(sys.policy_hub)"), + handle => "$(name)_tgz_copied", + classes => if_repaired ("$(name)_untar"), + perms => m(644); -commands: + commands: + "$(name)_untar":: + "/usr/bin/tar" + args => "xzvf $(sync_dst) -C $(install_dir)", + depends_on => {"$(name)_tgz_copied"}, + handle => "$(name)_untarred"; - "$(name)_untar":: - "/usr/bin/tar" - args => "xzvf $(sync_dst) -C $(install_dir)", - depends_on => {"$(name)_tgz_copied"}, - handle => "$(name)_untarred"; -reports: -# "TESTFILE: $(test_file)"; - + reports: + # "TESTFILE: $(test_file)"; + } @@ -327,13 +333,213 @@ methods: reports: } -# Args: -# method string Either `wget` or anything else (not implemented?) -# src string Source URL of the file to download -# dst string ? -# cls string Prefix for classes used in the bundle -# prms_arg data JSON for { m(string): mode, o(string): uid, g(string): gid } +bundle agent dearmor_gpg_key( key_file, dearmored_key_path ) +# @brief Dearmor a GPG key +# @param key_file Path of the key file to dearmor +# @todo Still needs work +{ + vars: + "gpg_pkg" + slist => {"gpg"}; + methods: + "Ensure presence of gpg" + usebundle => wmde_install_packages( @(gpg_pkg) , "gpg"), + handle => "gpg_installed"; + files: + "$(keyrings_dir)/$(key_name)" + perms => mog( "0644", "root", "root" ), + depends_on => { "dearmored_key" }; + commands: + "/usr/bin/gpg" + arglist => { "--dearmor", "--yes", "--output", "$(keyrings_dir)/$(key_name)"}, + depends_on => { "gpg_installed" }, + handle => "dearmored_key"; + +} + +bundle agent _install_apt_repo( name, url, key_url, _key_name ) +# @brief Configure an apt repository +# @param name Unique name of the repository, used for filenames +# @param url URL of the repository +# @param key_url URL for downloading the signing key +# @param _key_name Name of the signing key, only for compatibility +# +# Drop-in for Tobias' install_apt_repo. +{ + methods: + "Install component main of repository" + usebundle => _install_apt_repository( "$(name)", "$(url)", "$(key_url)", "$(sys.os_release[VERSION_CODENAME])", "main" ); +} + +bundle agent _install_apt_repository( name, url, key_url, suite, components ) +# @brief Configure an apt repository +# @param name Unique name of the repository, used for filenames +# @param url URL of the repository +# @param key_url URL for downloading the signing key +# @param suite Name of the suite to use, e.g. "stable", "bookworm", "nimble" +# @param components Whitespace separated string of names of components to enable, e.g. "main" or "main universe multiverse" +# +# Replacement for install_apt_repo from Tobias. Does not need a shell script. +# What are suites and components? See +# https://gist.github.com/CodingKoopa/3b30afe8c91e3950f6b124cd2abe3b6b +{ + vars: + "keyrings_dir" + string => "/etc/apt/keyrings"; + "sources_dir" + string => "/etc/apt/sources.list.d"; + "key_name" + string => lastnode( "$(key_url)", "/" ), + handle => "key_name_defined"; + "key_extension" + string => lastnode( "key_name", "\."), + depends_on => { "key_name_defined" }; + "sources_data" + data => '{ "URL": "$(url)", "Suite": "main" }'; + "pkgs" slist => { + "curl", + "ca-certificates", + "lsb-release" + }; + dearmor:: + "final_key_name" + string => string_replace( "$(key_name)", ".asc", ".gpg"), + handle => "final_key_name_defined"; + !dearmor:: + "final_key_name" + string => "$(key_name)", + handle => "final_key_name_defined"; + key_url_has_content:: + "source_template" + string => "deb [signed-by=$(keyrings_dir)/$(final_key_name)] $(url) $(suite) $(components)", + depends_on => { "final_key_name_defined" }, + handle => "source_template_defined"; + !key_url_has_content:: + "source_template" + string => "deb $(url) $(suite) $(components)", + handle => "source_template_defined"; + classes: + "name_exists" expression => isvariable( "name" ); + "url_exists" expression => isvariable( "url" ); + "key_url_exists" expression => isvariable( "key_url" ); + name_exists:: + "name_is_string" expression => strcmp( "string", type( "name", "false" ) ); + name_is_string:: + "name_has_content" expression => isgreaterthan( string_length( "$(name)" ), "0" ); + url_exists:: + "url_is_string" expression => strcmp( "string", type( "url", "false" ) ); + url_is_string:: + "url_has_content" expression => isgreaterthan( string_length( "$(url)" ), "7" ); # "https?://.+" + key_url_exists:: + "key_url_is_string" expression => strcmp( "string", type( "key_url", "false" ) ); + key_url_is_string:: + "key_url_has_content" expression => isgreaterthan( string_length( "$(key_url)" ), "7" ); + key_url_has_content:: + "dearmor" + expression => strcmp( "asc", $(key_extension) ), + scope => "bundle"; + debian|ubuntu:: + "do_install" expression => not( or( fileexists( "$(sources_dir)/$(name).list" ), fileexists( "$(sources_dir)/$(name).sources" ) ) ); + files: + do_install:: + "$(keyrings_dir)/." + create => "true", + perms => mog( "755", "root", "root" ), + handle => "keyrings_dir"; + "$(sources_dir)/$(name).list" + content => "$(source_template)", + perms => mog( "0644", "root", "root" ), + depends_on => { "source_template_defined" }, + handle => "$(name)_list_created", + classes => if_repaired( "repo_repaired" ); + "$(keyrings_dir)/$(final_key_name)" + perms => mog( "0644", "root", "root"), + depends_on => { "final_key_name_defined", "$(name)_signing_key" }, + handle => "set_perms"; + methods: + do_install:: + "Ensure necessary packages" + usebundle => wmde_install_packages( @(pkgs), "apt_repo" ), + handle => "apt_repo_pkgs_installed"; + do_install & key_url_has_content:: + "Ensure presence of signing key" + usebundle => curl_file( "$(key_url)", "$(keyrings_dir)/" ), + depends_on => { "keyrings_dir" }, + handle => "$(name)_signing_key"; + do_install & dearmor:: + "Dearmor the GPG key" + usebundle => dearmor_gpg_key( "$(keyrings_dir)/$(key_name)", "$(keyrings_dir)/$(final_key_name)" ), + depends_on => { "$(name)_signing_key", "final_key_name_defined" }, + handle => "key_dearmored"; + commands: + repo_repaired:: + "/usr/bin/apt-get" + args => "update", + depends_on => { "$(name)_list_created" }; +} + +bundle agent enable_ppa( ppa ) +# @brief Enable a PPA +# @param ppa URL to the PPA to enable +{ + vars: + "pkg" slist => { "software-properties-common" }; + methods: + "Ensure add-apt-repository is present" + usebundle => wmde_install_packages( @(pkg), "software_properties_common"), + handle => "add_apt_repository"; + commands: + "/usr/bin/add-apt-repository" + args => "--yes --ppa $(ppa)", + depends_on => {"add_apt_repository"}; +} + +bundle agent curl_file( url, destination ) +# @depends paths +# @brief Download a file from a network location +# +# Use `curl` to download a file from a network location. See the curl(1) man page for +# a list of protocols supported by curl. +# +# Source: https://gist.github.com/bahamat/9aeaf8964f01c368a6c5 +# +# @param url The full URL to the requested resource +# @param destination The full local path to store the downloaded resource data +# +# Example: +# +# ```cf3 +# vars: +# "url" string => "http://s3.amazonaws.com/cfengine.package-repos/tarballs/cfengine-3.6.5.tar.gz"; +# "file" string => "/tmp/cfengine-3.6.5.tar.gz"; +# methods: +# "download" usebundle => curl_file("$(url)","$(file)"); +# ``` +{ + vars: + "file_date" + string => "-z $(file)", + ifvarclass => fileexists("$(file)"); + "curlflags" string => "--silent --location --remote-name --continue-at -"; + + defaults: + "file_date" string => " "; + + commands: + "/usr/bin/curl $(file_date) $(curlflags) --output-dir $(destination) $(url)"; +} + bundle agent download_file(method,src,dst,cls,prms_arg) +# @brief Download a file to specific location and set permissions. +# @param method string Either `wget`, `wget_simple` or anything else (not implemented?) +# @param src string Source URL of the file to download +# @param dst string Destination for the downloaded file +# @param cls string Prefix for classes used in the bundle +# @param prms_arg data JSON for { m(string): mode, o(string): uid, g(string): gid } +# +# method wget will download to a specific file while method wget_simple +# will accept the remote filename and puts the file at a specified +# destination. { vars: "prms_default" data => '{ @@ -344,11 +550,15 @@ vars: "prms" data => mergedata(@(prms_default),parsejson($(prms_arg))); + wget:: + "wget_args" string => "-q --timestamping -O $(dst) $(src) || (rm -f $(dst) && /usr/bin/false) "; + wget_simple:: + "wget_args" string => "-q --timestamping -P $(dst) $(src)"; + classes: "$(method)"; - wget:: + wget | wget_simple:: "run_wget" expression => not(fileexists($(dst))); - files: policyhub:: "$(dst)" @@ -357,34 +567,35 @@ files: perms => mog ("$(prms[m])","$(prms[o])","$(prms[g])"); methods: wget:: - "any" usebundle => "install_wget"; #, handle=>"wget_installed"; + "any" usebundle => "install_wget"; #, handle=>"wget_installed"; commands: run_wget:: "$(wget.exe)" - args => "-q -O $(dst) $(src) || (rm -f $(dst) && /usr/bin/false) ", - contain => wmde_cmd_useshell, - handle => "$(cls)_downloaded", - classes => results("namespace","$(cls)"), - depends_on => {"wget_installed"}, - inform => "true"; + args => "$(wget_args)", + contain => wmde_cmd_useshell, + handle => "$(cls)_downloaded", + classes => results("namespace","$(cls)"), + depends_on => {"wget_installed"}, + inform => "true"; "/usr/bin/true" - inform => "false", - depends_on => {"$(cls)_downloaded"}, - classes => if_repaired("$(cls)_kept"); - - - (!run_wget)&(wget):: + inform => "false", + depends_on => {"$(cls)_downloaded"}, + classes => if_repaired("$(cls)_kept"); + + + (wget|wget_simple) & !run_wget:: "/usr/bin/true" inform => "false", classes => if_repaired("$(cls)_kept"); files: + !wget_simple:: "$(dst)" - perms => mog ("$(prms[m])","$(prms[o])","$(prms[g])"), - depends_on => {"$(cls)_downloaded"}; + perms => mog ("$(prms[m])","$(prms[o])","$(prms[g])"), + depends_on => {"$(cls)_downloaded"}; reports: } @@ -443,19 +654,32 @@ files: } -bundle agent create_cron_job(name,time,command) +bundle agent create_cron_job( name, time, command ) +# @brief Create a cron job +# @param name filename of the cronjob +# @param time cron time pattern +# @param command command to execute prepended by the user account under which to run the command +# +# Usage example +# ```cf3 +# bundle agent main { +# methods: +# "Ensure Nextcloud's cronjob is setup" +# usebundle => create_cron_job( "my_cronjob", "*/5 * * * *", "www-data /usr/bin/php -f /var/www/nextcloud/cron.php "); +# } +# ``` { -methods: - "any" usebundle => cron; -files: - "$(cron.cron_d)/$(name)" - create => "true", - content => "# + methods: + "any" usebundle => cron; + files: + "$(cron.cron_d)/$(name)" + create => "true", + content => "# # Managed by CFEngine # $(time) $(command) ", - depends_on => {"cron_d_created"}; + depends_on => {"cron_d_created"}; } diff --git a/lxc-host.cf b/lxc-host.cf index 1b2bf1c..1d086bf 100644 --- a/lxc-host.cf +++ b/lxc-host.cf @@ -26,6 +26,15 @@ bundle agent lxc_host( cfg ) 'lxc_hosts_d' string => '$(lxc_path)/hosts.d'; debian:: 'pkg_list' slist => { 'lxc','lxc-templates','debian-archive-keyring' }; + 'lxc_nft_path' string => '/usr/local/bin'; + 'lxc_down_nft' string => '$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/lxc_host/lxc-net-down.nft.txt'; + 'lxc_net_override' string => '$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/lxc_host/lxc-net.override.conf'; + debian_11:: + 'lxc_up_nft' string => '$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/lxc_host/debian11.lxc-net-up.nft.txt'; + 'lxc_hook_net' string => '$(sys.workdir)/inputs/$(def.wmde_libdir)/scripts/lxc_host/debian11.lxc-hook-net.sh'; + debian_12|debian_13:: + 'lxc_up_nft' string => '$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/lxc_host/debian12.lxc-net-up.nft.txt'; + 'lxc_hook_net' string => '$(sys.workdir)/inputs/$(def.wmde_libdir)/scripts/lxc_host/debian12.lxc-hook-net.sh'; ubuntu:: 'pkg_list' slist => { 'lxc','lxc-templates','ubuntu-archive-keyring' }; fedora|centos|redhat:: @@ -59,10 +68,36 @@ bundle agent lxc_host( cfg ) depends_on => { "lxc_installed" }; "/usr/local/bin/lxc-hooks" perms => mog('700','root','root'), - copy_from => local_cp("$(sys.workdir)/inputs/wmdelib/scripts/lxc-hooks.sh"), + copy_from => local_cp("$(sys.workdir)/inputs/wmdelib/scripts/lxc_host/lxc-hooks.sh"), depends_on => { "lxc_installed" }, handle => "lxchookscript"; - + debian_11|debian_12|debian_13:: + '$(lxc_nft_path)/lxc-net-up.nft' + perms => mog('700','root','root'), + copy_from => local_cp('$(lxc_up_nft)'), + depends_on => { 'lxc_installed' }, + handle => 'lxc_up_nft_copied'; + '$(lxc_nft_path)/lxc-net-down.nft' + perms => mog('700','root','root'), + copy_from => local_cp('$(lxc_down_nft)'), + depends_on => { 'lxc_installed' }, + handle => 'lxc_down_nft_copied'; + '/etc/systemd/system/lxc-net.service.d/.' + perms => mog('755','root','root'), + create => 'true', + depends_on => { 'lxc_installed' }, + handle => 'lxc_net_override_dir'; + '/etc/systemd/system/lxc-net.service.d/override.conf' + perms => mog('644','root','root'), + copy_from => local_cp('$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/lxc_host/lxc-net.override.conf'), + depends_on => { 'lxc_installed' }, + classes => results('namespace','lxc_net'), + handle => 'lxc_net_override'; + "/usr/local/bin/lxc-hook-net" + perms => mog('700','root','root'), + copy_from => local_cp("$(lxc_hook_net)"), + depends_on => { "lxc_installed", "lxchookscript" }, + handle => "lxchooknet"; debian|ubuntu:: "$(lxc_net_path)" perms => mog('644','root', 'root'), @@ -76,6 +111,16 @@ bundle agent lxc_host( cfg ) template_method => 'mustache', edit_template => "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/lxc_host/$(lxc_default_tmpl)", depends_on => { "lxc_installed" }; + commands: + lxc_net_repaired:: + "/usr/bin/systemctl" + args => "daemon-reload", + handle => "lxc_net_reloaded"; + services: + lxc_net_repaired:: + "lxc-net.service" + service_policy => "restart", + depends_on => { 'lxc_net_reloaded' }; } body acl lxc_dnsmasq @@ -99,7 +144,7 @@ body acl lxc_dnsmasq # "group": "", # "autostart": true, # "policy": "absent|present", -# "state": "stopped|running", +# "state": "stopped|running|manual", # }'; # name # lxc.container.conf: @@ -108,10 +153,11 @@ bundle agent lxc( cfg ) { classes: "cfg_array" expression => strcmp( type( "cfg", "true" ), "data array" ); + vars: cfg_array:: "index" slist => getindices( @(cfg) ); - + methods: cfg_array:: "Iterate over config array: $(index)" @@ -119,7 +165,6 @@ bundle agent lxc( cfg ) !cfg_array:: "Forward config to" usebundle => _lxc( @(cfg) ); - files: reports: cfg_array:: @@ -138,6 +183,8 @@ bundle agent _lxc( cfg ) "lxc_host_file_exists" expression => fileexists( "$(lxc_host_file)" ), scope => "bundle"; "lxc_policy_exists" expression => isvariable( "cfg[policy]" ); "lxc_state_exists" expression => isvariable( "cfg[state]" ); + "lxc_ports_exists" expression => isvariable( "cfg[ports]" ); + "lxc_raw_lines_exists" expression => isvariable( "cfg[raw_lines]" ); lxc_policy_exists:: "lxc_policy_valid" expression => regcmp( "(absent|present)", "$(cfg[policy])" ); lxc_policy_valid:: @@ -145,13 +192,17 @@ bundle agent _lxc( cfg ) !lxc_policy_exists:: 'present'; lxc_state_exists:: - "lxc_state_valid" expression => regcmp( "(stopped|running)", "$(cfg[state])" ); + "lxc_state_valid" expression => regcmp( "(stopped|running|manual)", "$(cfg[state])" ); lxc_state_valid:: 'running' expression => strcmp( "running", "$(cfg[state])" ); + lxc_state_valid:: + 'manual' expression => strcmp( "manual", "$(cfg[state])" ); !lxc_state_exists:: 'running'; lxc_exists:: "lxc_correct_distribution" expression => regline( '^# Parameters passed to the template: --dist $(cfg[dist]) --arch $(cfg[arch]) --release $(cfg[release])$', "$(lxc_dir)/config" ), scope => "bundle"; + lxc_ports_exists:: + "ports_array" expression => strcmp( type( "cfg[ports]", "false" ), "data" ); vars: "lxc_host_file" string => "$(lxc_host.lxc_hosts_d)/$(cfg[name])"; @@ -160,10 +211,18 @@ bundle agent _lxc( cfg ) 'autostart' string => $(cfg[autostart]); 'group' string => $(cfg[group]); + files: + ports_array:: + "/var/lib/lxc/$(cfg[name])/ports" + edit_template => "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/lxc_host/port_forwarding.mustache", + template_data => @(cfg), + template_method => "mustache", +# depends_on => { "lxc_$(cfg[name])_created" }, + handle => "$(cfg[name])_ports_created"; !lxc_exists & present:: "/var/lib/lxc/$(cfg[name])/config" - edit_line => lxc_config( "$(autostart)", "$(group)" ), + edit_line => lxc_config( "$(autostart)", "$(group)", @(cfg[raw_lines]) ), depends_on => { "lxc_$(cfg[name])_created" }, handle => "$(cfg[name])_config_created"; methods: @@ -191,11 +250,13 @@ bundle agent _lxc( cfg ) "Ensure running state of container ($(cfg[name]))" usebundle => lxc_start( @(cfg[name]) ), handle => "lxc_$(cfg[name])_started"; - present & !running:: + present & !(running | manual):: "Ensure stopped state of container ($(cfg[name]))" usebundle => lxc_stop( @(cfg[name]) ), handle => "lxc_$(cfg[name])_stopped"; reports: + "_lxc: raw_lines_$(cfg[name]) [$(lxc_raw_type)] enthält $(cfg[raw_lines])"; + "_lxc: raw_lines_arg_$(cfg[name]) [$(lxc_raw_type)] enthält ($-Notation) $(raw_lines_arg_$(cfg[name]))"; lxc_exists & lxc_correct_distribution:: "LX Container $(cfg[name]) already configured, nothing to do"; !lxc_exists & present:: @@ -208,26 +269,31 @@ bundle agent _lxc( cfg ) "LXC $(cfg[name]) should now be in state STOPPED."; } -bundle edit_line lxc_config( autostart, group ) +bundle edit_line lxc_config( autostart, group, raw ) { classes: "autostart_true" - expression => some( $(autostart_lc), true_statements ), - depends_on => { "$(autostart)_lowercased" }; + expression => some( $(autostart_lc), true_statements ), + depends_on => { "$(autostart)_lowercased" }; "group_provided" - expression => isgreaterthan( $(group_length), 0 ); + expression => isgreaterthan( $(group_length), 0 ), + depends_on => { "group_length_measured" }; vars: "autostart_lc" - string => string_downcase( $(autostart) ), - handle => "$(autostart)_lowercased"; + string => string_downcase( $(autostart) ), + handle => "$(autostart)_lowercased"; "group_length" - int => string_length( $(group) ); + int => string_length( $(group) ), + handle => "group_length_measured"; "true_statements" slist => { "yes", "true", "on", "1" }, handle => "truth"; insert_lines: "# This file is managed by CFEngine. Manual changes will be overwritten." - location => first_line; + location => first_line, + handle => "warning"; + "$(raw)" + depends_on => { "warning" }; autostart_true:: "lxc.start.auto = 1"; !autostart_true:: @@ -235,8 +301,9 @@ bundle edit_line lxc_config( autostart, group ) group_provided:: "lxc.group = $(group)"; reports: - "autostart ist $(autostart)"; - "group ist $(group)"; + "lxc_config 1: autostart ist $(autostart)"; + "lxc_config 2: group ist $(group)"; + "lxc_config 3: raw enthält $(raw)"; } body location first_line @@ -246,6 +313,13 @@ body location first_line select_line_matching => ".*"; } +body location last_line +{ + before_after => "after"; + first_last => "last"; + select_line_matching => ".*"; +} + bundle agent lxc_add_static_mapping( cfg ) { files: @@ -271,6 +345,11 @@ bundle agent lxc_remove_static_mapping( cfg ) "mapped $(cfg[name]) to $(cfg[ip])"; } +bundle agent lxc_add_port_forwarding_rule_config( cfg ) +{ + +} + # When files for static mappings are added dnsmasq automatically loads # them. But dnsmasq doesn't remove them automatically again when the # file gets removed. diff --git a/mailserver.cf b/mailserver.cf index f3f2ace..21d5d5c 100644 --- a/mailserver.cf +++ b/mailserver.cf @@ -46,6 +46,7 @@ vars: "roundcube_db_pass":"roundcube-secret", "roundcube_version":"1.6.4", "roundcube_password_recovery":false, + "roundcube_settings":"", "vimb_rememberme_salt":"Xa])o3GwVe-$8>-vz}y~+&D\C!2Ni+_AeocxD^ZhGQz-H/8", @@ -62,17 +63,16 @@ vars: "postmaster_mail":"postmaster@$(sys.host)", "webmaster_mail":"webmaster@$(sys.host)", - "sympa_listmaster":"tobias.herre@wikimedia.de", - "sympa_dir":"/var/mail/sympa" + "sympa_listmaster":"tobias.herre@wikimedia.de, sandro.halank@wikimedia.de", + "sympa_dir":"/var/mail/sympa", + "sympa_db_pass":"sympa-db-secret" + }'; -# "sympa_arc_dir": "$(sympa_dir)/arc"; -# "sympa_home_dir": "$(sympa_dir)/list_data"; -# "sympa_bounce_dir": "$(sympa_dir)/bounce"; - + "cfg" data => mergedata(@(default_cfg),@(param_cfg)); @@ -132,6 +132,7 @@ Alias /vimbadmin $(apache.www_dir)/$(cfg[vimb_domain])/public "security_salt":"$(cfg[vimb_security_salt])", "rememberme_salt":"$(cfg[vimb_rememberme_salt])", "password_salt":"$(cfg[vimb_password_salt])", + "skin":"wmde" }'; @@ -141,12 +142,14 @@ Alias /vimbadmin $(apache.www_dir)/$(cfg[vimb_domain])/public "aliases":[ ], "email":"$(cfg[webmaster_mail])", "disable":false, - "php_handler":"$(cfg[php_handler])", + "xxphp_handler":"$(cfg[php_handler])", + "aaaphp_handler":"proxy:unix:$(php.fpm_socket)|fcgi://localhost/", + "php_handler":"proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost/", "doc_root":"$(apache.www_dir)/$(cfg[webmail_domain])/public/", "ssl":true, "raw":" " - }'; + }'; #, depends_on => {"aia_php_installed"} ; "roundcube_cfg" data =>'{ "db_host":"$(cfg[db_host])", @@ -163,7 +166,9 @@ Alias /vimbadmin $(apache.www_dir)/$(cfg[vimb_domain])/public "settings":{ "imap_host":"\'tls://$(cfg[imap_domain]):143\'", "smtp_host":"\'tls://$(cfg[smtp_domain]):587\'", - "plugins":"$(roundcube_plugins)" + "plugins":"$(roundcube_plugins)", + "skin":"\'wmde\'", + }, "keep_installer":true }'; @@ -275,8 +280,8 @@ Alias /vimbadmin $(apache.www_dir)/$(cfg[vimb_domain])/public mail_location = $(cfg[mail_location]) mail_privileged_group=mail log_path = /var/log/dovecot.log -mail_debug=yes -auth_debug=yes +#mail_debug=yes +#auth_debug=yes protocol sieve { @@ -372,7 +377,7 @@ managesieve_max_line_length = 65536 "{ -o smtpd_tls_auth_only = yes }", "{ -o smtp_tls_note_starttls_offer = yes }", "{ -o smtpd_milters = unix:/var/spool/postfix/private/opendkim }", - + "{ -o message_size_limit = 30971520 }", ], @@ -392,7 +397,7 @@ managesieve_max_line_length = 65536 "args":[ "{ -o smtpd_relay_restrictions = permit_mynetworks reject_unauth_destination }", "{ -o smtpd_recipient_restrictions = permit_mynetworks reject_unauth_destination }" - "{ -o smtpd_recipient_restrictions = permit_mynetworks reject_unlisted_recipient reject_unauth_destination reject_unknown_recipient_domain reject_rbl_client ix.dnsbl.manitu.net reject_rbl_client zen.spamhaus.org }", + "{ -o smtpd_recipient_restrictions = permit_mynetworks reject_unlisted_recipient reject_unauth_destination reject_unknown_recipient_domain reject_rbl_client ix.dnsbl.manitu.net }", "{ -o smtpd_client_restrictions = permit_mynetworks reject_unknown_reverse_client_hostname reject_unauth_pipelining }", "{ -o smtpd_helo_restrictions = permit_mynetworks reject_invalid_hostname reject_unknown_hostname reject_non_fqdn_hostname }", "{ -o smtpd_relay_restrictions = permit_mynetworks defer_unauth_destination }", @@ -409,6 +414,9 @@ managesieve_max_line_length = 65536 "{ -o smtpd_tls_session_cache_timeout = 3600s }", "{ -o smtpd_tls_key_file = $(certbot.certbot_dir)/live/$(cfg[imap_domain])/privkey.pem }", "{ -o smtpd_tls_cert_file = $(certbot.certbot_dir)/live/$(cfg[imap_domain])/fullchain.pem }", + "{ -o message_size_limit = 30971520 }", + + ], } @@ -427,31 +435,73 @@ mynetworks=$(cfg[mynetworks]) local_recipient_maps = unix:passwd.byname $alias_maps virtual_transport = lmtp:unix:private/dovecot-lmtp -virtual_alias_maps = mysql:$(postfix_vimbadmin_sql.virtual_alias_maps) +virtual_alias_maps = mysql:$(postfix_vimbadmin_sql.virtual_alias_maps) hash:/etc/postfix/fwd.tsv +transport_maps = hash:/etc/sympa/sympa_transport hash:$(sympa_general_transport) + virtual_mailbox_domains = mysql:$(postfix_vimbadmin_sql.virtual_domains_maps) -virtual_mailbox_maps = mysql:$(postfix_vimbadmin_sql.virtual_mailbox_maps) +virtual_mailbox_maps = hash:$(sympa.conf_dir)/sympa_transport hash:$(sympa_general_transport) mysql:$(postfix_vimbadmin_sql.virtual_mailbox_maps) inet_protocols = ipv4 smtp_tls_security_level = may message_size_limit = 26214400 " , - "master_raw":"" + "master_raw":" +# +# Sympa +# +$(sympa.postfix_master_cfg) +# +", + } '; + "sympa_db" data => '{ + "db_name":"sympa", + "db_user":"sympa", + "db_host":"$(cfg[db_host])", + "db_pass":"$(cfg[sympa_db_pass])", + "db_user_host":"%", + "db_type":"mysql" + }'; + + "sympa_db_json" string => storejson(@(sympa_db)); + + + "sympa_dir" string => "$(cfg[sympa_dir])"; + "sympa_arc_dir" string => "$(sympa_dir)/arc"; + "sympa_home_dir" string => "$(sympa_dir)/list_data"; + "sympa_bounce_dir" string => "$(sympa_dir)/bounce"; + "sympa_domain" string => "$(cfg[sympa_domain])"; + + + "sympa_site" data => '{ + "domain" : "$(sympa_domain)", + "aliases" : [], + "email": "$(cfg[postmaster_mail])", + "disable": false, + "ssl": true, + "raw": " + $(sympa.apache_cfg) + " + }'; + "sympa_site_json" string => storejson(@(sympa_site)); + + + "cfg_json" string => storejson(@(cfg)); + + "sympa_domains_json" string => storejson( @(cfg[sympa_domains])); "sympa_cfg" data => '{ "version":"6.2.72", - "backup_dir":"$(wmde_mail.backup_dir)/sympa", + "backup_dir":"$(cfg[backup_dir])/sympa", "db_settings":$(sympa_db_json), - "settings": { - - "domain":"$(sympa_domain)", - "wwsympa_url":"$(wwsympa_url)", - "listmaster":"$(sympa_listmaster)", + "domain":"$(cfg[sympa_domain])", + "wwsympa_url":"$(cfg[wwsympa_url])", + "listmaster":"$(cfg[sympa_listmaster])", "sendmail_aliases":"$(sympa.conf_dir)/sympa_transport", "aliases_program":"/usr/sbin/postmap", "db_type":"$(sympa_db[db_type])", @@ -465,66 +515,23 @@ message_size_limit = 26214400 "etc":"/mnt/mail-vol/sympa/etc" } , - "domains":{ - "dewp.org": { - "settings":{ - "wwsympa_url":"https://$(sympa_domain)/dewp.org", - "http_host":"$(sympa_domain)", - "domain":"dewp.org", - "title":"Diese Domain ist zu Testzwecken hier" - } - } - , - "wikipedia.de": { - "settings":{ - "wwsympa_url":"https://$(sympa_domain)/wikipedia.de", - "http_host":"$(sympa_domain)" - } - } - , - "wikimedia.de": { - "settings":{ - "wwsympa_url":"https://$(sympa_domain)/wikimedia.de", - "http_host":"$(sympa_domain)" - } - } - , - "wikimail.info": { - "settings":{ - "wwsympa_url":"https://$(sympa_domain)/wikimail.info", - "http_host":"$(sympa_domain)" - } - } - } - - , - "domains_old":[ - { - "domain":"dewp.org", - "wwsympa_url":"https://$(sympa_domain)/dewp.org", - "http_host":"$(sympa_domain)" - } - , - { - "domain":"wikimedia.de", - "wwsympa_url":"https://$(sympa_domain)/wmde", - "http_host":"$(sympa_domain)" - } - , - { - "domain":"wikipedia.de", - "wwsympa_url":"https://lists.dewp.org/wikipedia.de", - "http_host":"list.dewp.org" - } - ] + "domains": $(sympa_domains_json) + }', handle => "wmde_mail_sympa_cfg_ready"; + "sympa_general_transport" string => "$(postfix.maps_dir)/sympa_general"; - + "sympa_cfg_json" string => storejson(@(sympa_cfg)); reports: +# "SYMPA DOMAIN $(sympa_domain)"; +# "SYMPA_DB_JSON: $(sympa_db_json)"; +# "SYMPA_CFG_JSON: $(sympa_cfg_json)"; +# "SYMPA_DOMAINS_JSON $(sympa_domains_json)"; +# "SYMPA_SITE $(sympa_site_json)"; +# "CFG $(cfg_json)"; users: "$(cfg[vmail_user])" @@ -581,6 +588,20 @@ methods: "any" usebundle => opendkim(@(opendkim_cfg)); + "any" usebundle => sympa; + "any" usebundle => install_sympa(@(sympa_cfg)), + depends_on => { +# "wmde_mail_sympa_site_installed", +# "wmde_mail_sympa_cfg_ready" + },handle => "wmde_mail_sympa_installed"; + + + "any" usebundle => sympa_postfix_sql(@(sympa_db)); + "any" usebundle => sympa_create_postfix_general_maps(@(sympa_cfg),"$(aia_mailserver.sympa_general_transport)"); + "any" usebundle => sympa_create_postfix_maps; + + + files: "$(roundcube_cfg[backup_dir])/." create=>"true", @@ -598,6 +619,11 @@ methods: "any" usebundle => create_mysql_db(@(aia_mailserver.vimb_db)), depends_on => {"aia_mysql_installed"}; + "any" usebundle => create_mysql_db(@(aia_mailserver.sympa_db)), + depends_on => {"aia_mysql_installed"}; + + + "any" usebundle => create_mysql_db(@(aia_mailserver.roundcube_cfg)), depends_on => {"aia_mysql_installed"}; @@ -605,32 +631,43 @@ methods: bundle agent aia_install_apache { +vars: + "php_settings" + data => '{ + "upload_max_filesize":"20M", + "post_max_size":"20M", + }'; methods: "any" usebundle => apache; "any" usebundle => install_apache, - depends_on => {"aia_php_installed"}; + depends_on => {"aia_php_installed","aia_phpfpm_installed"}; - "any" usebundle => install_php_fpm,handle=>"aia_php_installed"; + "any" usebundle => php( "8.2", @(php_settings) ), + handle=>"aia_php_installed"; + + "any" usebundle => _install_php_fpm("8.2"), + handle=>"aia_phpfpm_installed"; } bundle agent aia_install_sites { vars: + "aliasdoms_json" string => storejson( @(aia_mailserver.cfg[imap_alias_domains])) ; "mail_site" data => '{ "domain":"$(aia_mailserver.cfg[imap_domain])", - "aliases":[ - "$(aia_mailserver.cfg[smtp_domain])" - ], + "aliases": $(aliasdoms_json), "email":"$(aia_mailserver.cfg[webmaster_mail])", "disable":false, }'; + methods: "any" usebundle => apache_vhost(@(aia_mailserver.vimb_site)); "any" usebundle => apache_vhost(@(aia_mailserver.roundcube_site)); "any" usebundle => apache_vhost(@(aia_mailserver.rspamd_site)); + "any" usebundle => apache_vhost(@(aia_mailserver.sympa_site)); "any" usebundle => certbot_cert(@(mail_site),"$(apache.web_root)"); diff --git a/mysql.cf b/mysql.cf index 44ef509..a818165 100644 --- a/mysql.cf +++ b/mysql.cf @@ -349,7 +349,10 @@ vars: "db_pass" string => "$(cfg[db_pass])"; "args" string => "pnunf"; type_mariadb:: - "args" string => "-e \"CREATE DATABASE IF NOT EXISTS $(db_name); GRANT ALL PRIVILEGES ON $(db_name).* TO '$(db_user)'@'$(host)' IDENTIFIED BY '$(db_pass)'; \" "; +# "args" string => "-e \"CREATE DATABASE IF NOT EXISTS $(db_name); GRANT ALL PRIVILEGES ON $(db_name).* TO '$(db_user)'@'$(host)' IDENTIFIED BY '$(db_pass)'; \" "; + + "args" string => "-e \"CREATE DATABASE IF NOT EXISTS $(db_name); CREATE USER IF NOT EXISTS '$(db_user)'@'$(host)' IDENTIFIED BY '$(db_pass)'; GRANT ALL PRIVILEGES ON $(db_name).* TO '$(db_user)'@'$(host)'; \" "; + type_mysql8:: "args" string => "-e \"CREATE DATABASE IF NOT EXISTS $(db_name); CREATE USER IF NOT EXISTS '$(db_user)'@'$(host)'; ALTER USER '$(db_user)'@'$(host)' IDENTIFIED BY '$(db_pass)'; GRANT RELOAD ON *.* to '$(db_user)'@'$(host)'; GRANT ALL PRIVILEGES ON $(db_name).* TO '$(db_user)'@'$(host)';\" "; diff --git a/nginx.cf b/nginx.cf index 4e142f7..7b951c7 100644 --- a/nginx.cf +++ b/nginx.cf @@ -37,56 +37,115 @@ any:: bundle agent install_nginx { -methods: - "any" usebundle => wmde_install_packages(@(nginx.pkgs),"nginx"); + methods: + "any" usebundle => wmde_install_packages(@(nginx.pkgs),"nginx"); -files: - "$(nginx.www_dir)/." - create=>"true", - perms => m("755"), - depends_on => { "nginx_pkgs_installed" }, - handle => "nginx_www_dir_created"; + files: + "$(nginx.www_dir)/." + create=>"true", + perms => m("755"), + depends_on => { "nginx_pkgs_installed" }, + handle => "nginx_www_dir_created"; - "$(nginx.default_html_dir)/." - create=>"true", - perms => uperm("$(nginx.www_user)","$(nginx.www_group)","755"), - depends_on => {"nginx_www_dir_created"}, - handle=>"nginx_default_html_dir_created"; + "$(nginx.default_html_dir)/." + create=>"true", + perms => mog("755","$(nginx.www_user)","$(nginx.www_group)"), + depends_on => {"nginx_www_dir_created"}, + handle=>"nginx_default_html_dir_created"; -files: - "$(sys.workdir)/data/agent/nginx/." - create => "true", - handle => "nginx_work_dir_created"; + files: + "$(sys.workdir)/data/agent/nginx/." + create => "true", + handle => "nginx_work_dir_created"; -methods: - "any" usebundle => wmde_enable_service("nginx"); - "any" usebundle => wmde_service("$(nginx.service_name)","nginx_kept","nginx_repaired"), - depends_on => @(nginx.service_deps) ; + methods: + "any" usebundle => wmde_enable_service("nginx"); + "any" usebundle => wmde_service("$(nginx.service_name)","nginx_kept","nginx_repaired"), + depends_on => @(nginx.service_deps) ; - - -commands: - "/bin/sh" - args => "$(sys.workdir)/inputs/$(def.wmde_libdir)/scripts/del-files-not-in-list.sh $(nginx.vhost_cfg_dir) $(sys.workdir)/data/agent/nginx/domains.txt && echo dummy.conf > $(sys.workdir)/data/agent/nginx/domains.txt", - inform => "false", - handle => "nginx_vhost_dir_cleaned", -# depends_on => {"nginx_dummy_conf_created"}, - contain => wmde_cmd_useshell; + commands: + "/bin/sh" + args => "$(sys.workdir)/inputs/$(def.wmde_libdir)/scripts/del-files-not-in-list.sh $(nginx.vhost_cfg_dir) $(sys.workdir)/data/agent/nginx/domains.txt && echo dummy.conf > $(sys.workdir)/data/agent/nginx/domains.txt", + inform => "false", + handle => "nginx_vhost_dir_cleaned", +# depends_on => {"nginx_dummy_conf_created"}, + contain => wmde_cmd_useshell; } -bundle agent nginx_vhost(site_param) +bundle agent nginx_vhosts( sites ) { -classes: - "delete" expression => $(site[disable]); - "use_ssl" expression => $(site[ssl]); - "use_certbot" expression => strcmp("certbot","$(site[ssl_cert])"); - "use_lego" expression => strcmp("lego","$(site[ssl_cert])"); - "do_logrotate" expression => $(site[logrotate]); - vars: - "site_defaults" data => ' - { + "idx" slist => getindices(@(sites)); +methods: + "$(idx)" usebundle => nginx_vhost(@(sites[$(idx)])); + +reports: +} + +bundle agent nginx_vhost( site_param ) +# @brief Configure a single vhost / server block in nginx conf.d subdir +# @param site_param data See below for full description +# +# The site_param data object consists of a JSON description of the site to +# be configured. +# { +# "domain":"sub.example.org", +# "aliases":[ "sub.example.net", "sub.example.de" ], +# "doc_root":"$(nginx.www_dir)/$(site_param[domain])", +# "doc_root_options":"Indexes FollowSymLinks", +# "logging80":true|false, +# "logging443":true|false, +# "logrotate":true|false, +# "listen":"*:80", +# "use_ssl": true|false, +# "sslraw":"", +# "raw":"", +# "ssl":true|false, +# "dnsapi":$(dnsapi), +# "ssl_cert":"lego|certbot", +# "email":"noc@example.org", +# "lego_raw":"", +# "lego_renew_raw":"", +# "lego_renew_raw2":" && /usr/local/bin/reload_nginx.sh", +# "disable":true|false, +# "delete": true|false, +# "do_logrotate": true|false +# } +# domain The main `server_name` to configure the server block. This +# value is used to identify this config. +# aliases A list of alternative `server_name`s for this server block. +# doc_root Path in the filesystem to use for the `root`. +# doc_root_options Options for the server block. Currently unused. +# logging80 Boolean if to log non-ssl traffic. Currently unused. +# logging443 Boolean if to log ssl traffic. Currently unused. +# listen String value to use for the `listen` directive. +# sslraw Multi-line string value for additional ssl config options to +# add raw. +# email Email string for Let's Encrypt certificate account. +# ssl Boolean if to enable a secondary server block with ssl config. +# dnsapi JSON object for dns01 challenge, used for lego +# ssl_cert "lego" or "certbot", which client to use. "lego" allows use +# of dns01 challenges and supports many DNS hosting APIs. +# lego_raw ? +# lego_renew_raw ? +# lego_renew_raw2 ? +# raw Multi-line string value for additional config options to +# add raw. +# disable Boolean if to disable the server block. +# delete Boolean if to delete the server block. +# do_logrotate Boolean if to configure logrotation for this server block. + +{ + classes: + "delete" expression => $(site[disable]); + "use_ssl" expression => $(site[ssl]); + "use_certbot" expression => strcmp("certbot","$(site[ssl_cert])"); + "use_lego" expression => strcmp("lego","$(site[ssl_cert])"); + "do_logrotate" expression => $(site[logrotate]); + + vars: + "site_defaults" data => '{ "aliases":[], "ssl_cert":"certbot", "doc_root":"$(nginx.www_dir)/$(site_param[domain])", @@ -96,90 +155,90 @@ vars: "logrotate":false, "listen":"*:80", "sslraw":"" - } - '; - "site" data => mergedata(site_defaults,site_param); - "cert_file" string => "$(certbot.certbot_dir)/live/$(site[domain])"; + }'; + "site" data => mergedata(site_defaults,site_param); + "cert_file" string => "$(certbot.certbot_dir)/live/$(site[domain])"; - "template_file" string => "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/nginx-vhost.conf.mustache"; + "template_file" string => "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/nginx-vhost.conf.mustache"; - "domain_file" string => "$(nginx.vhost_cfg_dir)/$(site[domain]).conf"; - "domain_dir" string => "$(nginx.www_dir)/$(site[domain])"; + "domain_file" string => "$(nginx.vhost_cfg_dir)/$(site[domain]).conf"; + "domain_dir" string => "$(nginx.www_dir)/$(site[domain])"; - "ssl_cert" string => ifelse( use_certbot, - "$(certbot.certbot_dir)/live/$(site[domain])/fullchain.pem", - "$(site[ssl_cert])"); - "ssl_key" string => ifelse( use_certbot, - "$(certbot.certbot_dir)/live/$(site[domain])/privkey.pem", - "$(site[ssl_key])"); + "ssl_cert" string => ifelse( use_certbot, + "$(certbot.certbot_dir)/live/$(site[domain])/fullchain.pem", + "$(site[ssl_cert])"); + "ssl_key" string => ifelse( use_certbot, + "$(certbot.certbot_dir)/live/$(site[domain])/privkey.pem", + "$(site[ssl_key])"); - use_lego:: - "ssl_cert" string => "$(lego.data_dir)/certificates/$(site[domain]).crt"; - "ssl_key" string => "$(lego.data_dir)/certificates/$(site[domain]).key"; + use_lego:: + "ssl_cert" string => "$(lego.data_dir)/certificates/$(site[domain]).crt"; + "ssl_key" string => "$(lego.data_dir)/certificates/$(site[domain]).key"; + + use_ssl&(use_certbot|use_lego):: + "vhostdeps" slist => { + "nginx_ssl_created$(site[domain])", + "nginx_vhost_dir_cleaned" + }; - - use_ssl&(use_certbot|use_lego):: - "vhostdeps" slist => { - "nginx_ssl_created$(site[domain])", - "nginx_vhost_dir_cleaned" - }; - - - (!use_ssl)|(!use_certbot)|(!use_lego):: - "vhostdeps" slist => { - "nginx_vhost_dir_cleaned" - }; + (!use_ssl)|(!use_certbot)|(!use_lego):: + "vhostdeps" slist => { + "nginx_vhost_dir_cleaned" + }; files: + delete:: + "$(domain_file)" + delete => tidy, + classes => if_repaired(nginx_restart); + !delete:: + "$(domain_file)" + perms => mog("644","$(nginx.www_user)","$(nginx.www_group)"), + create => "true", + edit_template => "$(template_file)", + template_method => "mustache", + handle => "vhost_cfg_done$(site[domain])", + depends_on => @(vhostdeps), + classes => results("bundle","domain_config"); - delete:: - "$(domain_file)" - delete => tidy, - classes => if_repaired(nginx_restart); - - !delete:: - "$(domain_file)" - perms => uperm("$(nginx.www_user)","$(nginx.www_group)","644"), - create => "true", - edit_template => "$(template_file)", - template_method => "mustache", - handle => "vhost_cfg_done$(site[domain])", - depends_on => @(vhostdeps), - classes => results("bundle","domain_config"); - - "$(domain_dir)/." - create => "true", - perms => uperm("$(nginx.www_user)","$(nginx.www_group)","750"); + "$(domain_dir)/." + create => "true", + perms => mog("750","$(nginx.www_user)","$(nginx.www_group)"); methods: use_ssl&use_certbot:: - "any" usebundle => certbot_cert(@(site),"$(nginx.default_html_dir)"), #,"$(site[domain])"), - handle => "nginx_ssl_created$(site[domain])"; + "any" + usebundle => certbot_cert(@(site),"$(nginx.default_html_dir)"), #,"$(site[domain])"), + handle => "nginx_ssl_created$(site[domain])"; - "any" usebundle => nginx_restart_service("$(nginx.service_name)","$(site[domain])"), - if => "domain_config_repaired", - depends_on => { - "vhost_cfg_done$(site[domain])", - "nginx_ssl_created$(site[domain])" - }; + "any" + usebundle => nginx_restart_service("$(nginx.service_name)","$(site[domain])"), + if => "domain_config_repaired", + depends_on => { + "vhost_cfg_done$(site[domain])", + "nginx_ssl_created$(site[domain])" + }; use_ssl&use_lego:: - "any" usebundle => lego_dns_cert(@(site)), #,"$(site[domain])"), - handle => "nginx_ssl_created$(site[domain])"; + "any" + usebundle => lego_dns_cert(@(site)), #,"$(site[domain])"), + handle => "nginx_ssl_created$(site[domain])"; - "any" usebundle => nginx_restart_service("$(nginx.service_name)","$(site[domain])"), - if => "domain_config_repaired", - depends_on => { - "vhost_cfg_done$(site[domain])", - "nginx_ssl_created$(site[domain])" - }; + "any" + usebundle => nginx_restart_service("$(nginx.service_name)","$(site[domain])"), + if => "domain_config_repaired", + depends_on => { + "vhost_cfg_done$(site[domain])", + "nginx_ssl_created$(site[domain])" + }; ((!use_ssl)|(!use_certbot)):: - "any" usebundle => nginx_restart_service("$(nginx.service_name)","$(site[domain])"), - if => "domain_config_repaired", - depends_on => {"vhost_cfg_done$(site[domain])" }; + "any" + usebundle => nginx_restart_service("$(nginx.service_name)","$(site[domain])"), + if => "domain_config_repaired", + depends_on => {"vhost_cfg_done$(site[domain])" }; files: # do_logrotate:: @@ -226,8 +285,9 @@ commands: methods: !nginx_do_not_restart:: - "any" usebundle => wmde_restart_service($(service_name),$(domain)), - depends_on => {"nginx_syntax_ok_$(domain)"}; + "any" + usebundle => wmde_restart_service($(service_name),$(domain)), + depends_on => {"nginx_syntax_ok_$(domain)"}; reports: # "RESTART NGINX" depends_on => {"nginx_syntax_ok_$(domain)"}; @@ -238,12 +298,111 @@ reports: -bundle agent nginx_vhosts(sites) +bundle agent nginx_matomo +(site) { -vars: - "idx" slist => getindices(@(sites)); +vars: + "pid" string => "/var/run/matomo-logger-$(site[domain]).pid"; + "log" string => "$(nginx.log_dir)/$(site[domain])-access.log"; + "siteid" string => "$(site[matomoid])"; + "logger_script" string => "/tmp/matomo-logger-$(site[domain]).sh"; +freebsd:: + "analyt_cmd" string => "/usr/local/bin/python3.9 $(matomo.log_importer)"; +debian:: + "analyt_cmd" string => "/usr/bin/python3 $(matomo.log_importer)"; +centos:: + "analyt_cmd" string => "/usr/bin/python3 $(matomo.log_importer)"; + +matomo:: + "cmd" string => "/usr/bin/pkill -P `cat $(pid)` ; exec /bin/sh -c 'echo $$ > $(pid); echo \"hello\" | /usr/bin/tail -n+1 -f $(log) | $(analyt_cmd) --token-auth=$(site[matomotoken]) --disable-bulk-tracking --idsite=$(siteid) --url=$(site[matomosite]) --exclude-path=/wp-login.php --exclude-path=/wp-json/\\* --recorders=1 --recorder-max-payload-size=1 --log-format-name=ncsa_extended --exclude-path=\\*.php --exclude-path=/wp-admin/\\* - > /dev/null' +"; +!matomo:: + "cmd" string => ""; +any:: + "cmd_esc" string => escape ($(cmd)); + # "cmd": "$(cmd_esc)", + + "site_str" string => storejson(@(site)); +# "site_json" string => '{ +# "site" : "$(site_str)" +# }'; + + "site_json" string => '{ + "cmd": "$(cmd)", + "service": "$(apache.service_name)", + "site": $(site_str) + }'; + + "template_file" + string => "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/httpd-weblogrot-matomo.mustache"; + methods: - "$(idx)" usebundle => nginx_vhost(@(sites[$(idx)])); + "any" usebundle => install_logrot; + +files: + "$(logrot.dir)/$(site[domain])" + create => "true", + edit_defaults => backup("false"), + edit_template => "$(template_file)", + template_method => "mustache"; +# template_data => parsejson("$(site_json)"); + + matomo:: + "$(pid)" + create => "true"; + + + "$(logger_script)" + create => "true", + perms => m("755"), + content => '#!/bin/sh +if [ "$1" != "child" ]; then + "$(logger_script)" child & +else + setsid >/dev/null 2>&1 + exec 0<&- 1>/dev/null 2>&1 + $(cmd) +fi +', + handle => "loggerscript_$(site[domain])_created"; + + +classes: + "matomo" expression => isvariable("site[matomoid]"); + + +commands: + matomo:: + "/bin/sh -c " + args => "'kill -0 `cat $(pid)` && echo -start_matomo || echo +start_matomo'", + inform => "false", + module => "true"; + + start_matomo:: + "$(logger_script)" + args => "$(logger_script)", + contain => wmde_cmd_useshell, + depends_on => {"loggerscript_$(site[domain])_created"}; + + +# "/bin/sh" +# args => "$(logger_script) &", +# contain => wmde_cmd_useshell, +# depends_on => {"loggerscript_$(site[domain])_created"}; + +methods: +# start_matomo:: +# "call" usebundle => daemonize( "/bin/sh $(logger_script)" ), +# depends_on => {"loggerscript_$(site[domain])_created"}; reports: + #start_matomo:: + # "MUST START - WHY"; + + #"ESC ESC $(site_json)"; + +matomo:: + } + + diff --git a/php.cf b/php.cf index 97f0e44..5a31399 100644 --- a/php.cf +++ b/php.cf @@ -2,6 +2,169 @@ # # +bundle agent _install_php( version ) +{ +classes: + "manage_repo"; + + vars: + freebsd:: + "pkgs" slist => { + "php$(version)-ctype", + "php$(version)-curl", + "php$(version)-dom", + "php$(version)-exif", + "php$(version)-fileinfo", + "php$(version)-filter", + "php$(version)-gd", + "php$(version)-gettext", + "php$(version)-iconv", + "php$(version)-intl", + "php$(version)-ldap", + "php$(version)-mbstring", + "php$(version)-mysqli", + "php$(version)-pdo", + "php$(version)-pdo_mysql", + "php$(version)-pdo_pgsql", + "php$(version)-pdo_sqlite", + "php$(version)-pecl-imagick", + "php$(version)-pgsql", + "php$(version)-phar", + "php$(version)-session", + "php$(version)-simplexml", + "php$(version)-sqlite3", + "php$(version)-tokenizer", + "php$(version)-xml", + "php$(version)-zip", + "php$(version)-zlib", + }; + + debian:: + "pkgs" slist => { + "php$(version)-apcu", + "php$(version)-cli", + "php$(version)-common", + "php$(version)-curl", + "php$(version)-gd", + "php$(version)-imagick", + "php$(version)-intl", + "php$(version)-ldap", + "php$(version)-mbstring", + "php$(version)-memcache", + "php$(version)-mysql", + "php$(version)-pgsql", + "php$(version)-redis", + "php$(version)-xml", + "php$(version)-zip", + }; + "apt_repo_url" string => "https://packages.sury.org/php/"; + "apt_repo_key" string => "https://packages.sury.org/php/apt.gpg"; + "apt_repo_key_name" string=> "deb.sury.org-php.gpg"; + + ubuntu:: + "pkgs" slist => { + "php$(version)-apcu", + "php$(version)-common", + "php$(version)-mbstring", + "php$(version)-memcache", + "php$(version)-mysql", + "php$(version)-pgsql", + "php$(version)-redis", + "php$(version)-xml", + "php$(version)-zip", + "php-gd", + "php-geshi", + "php-json", + }; + "apt_repo_url" string => "https://ppa.launchpadcontent.net/ondrej/php/ubuntu/"; + + centos:: + "pkgs" slist => { + "php$(version)-cli", + "php$(version)-common", + "php$(version)-gd", + "php$(version)-intl", + "php$(version)-ldap", + "php$(version)-mbstring", + "php$(version)-mysqlnd", + "php$(version)-pecl-imagick-im6", + "php$(version)-pgsql", + "php$(version)-process", + "php$(version)-xml", + "php-pecl-apcu", + "php-pecl-json-post", + "php-pecl-zip", + }; + + methods: + debian&manage_repo:: + "Ensure repo is setup" + usebundle => _install_apt_repo("php","$(apt_repo_url)","$(apt_repo_key)","$(apt_repo_key_name)"), + handle => "php_repo_ready"; + + ubunut&manage_repo:: + "Ensure repo is setup" + usebundle => enable_ppa( "$(apt_repo_url)" ), + handle => "php_repo_ready"; + + centos:: + "Ensure repo is setup" + usebundle => php_install_centos_repos, + handle => "php_repo_ready"; + + any:: + "Ensure php packages are installed" + usebundle => wmde_install_packages(@(pkgs),"php"), + depends_on => {"php_repo_ready"}; +} + +bundle agent _install_php_fpm( version ) +# @brief Install packages required for php-fpm +# @param version Version to install. +{ + defaults: + debian:: + "version" string => "8.0"; + ubuntu:: + "version" string => "8.2"; + centos:: + "version" string => "8.3"; + freebsd:: + "version" string => "82"; + vars: + debian|ubuntu:: + "fpm_pkgs" slist => { "php$(version)-fpm" }; + "fpm_socket" string => "/run/php/php$(version)-fpm.sock"; + "fpm_socket_type" string => "unix:"; + "fpm_service_name" string => "php$(version)-fpm"; + centos:: + "fpm_pkgs" slist => { "php-fpm" }; + "fpm_socket" string => "/run/php-fpm/www.sock"; + "fpm_socket_type" string => "unix:"; + "fpm_service_name" string => "php$(version)-fpm"; + freebsd:: + "fpm_pkgs" slist => {}; + "fpm_socket" string => "127.0.0.1:9000"; + "fpm_socket_type" string => "fcgi://"; + "fpm_service_name" string => "php-fpm"; + + methods: + "Ensure the PHP packages are installed" + usebundle => _install_php( $(version) ); + "Ensure the PHP-FPM packages are installed" + usebundle => wmde_install_packages( @(fpm_pkgs),"php_fpm" ); + + "Enable the php-fpm service" + usebundle => wmde_enable_service("$(fpm_service_name)"); + + "Start or restart the php-fpm service" + usebundle => wmde_service( "$(fpm_service_name)", "php_kept|php_fpm_kept", "php_repaired|php_fpm_repaired" ), + depends_on => { "php_fpm_pkgs_installed", "php_pkgs_installed" }; + reports: +# "php ????"; +} + + bundle agent install_php { classes: @@ -62,6 +225,7 @@ vars: "php$(version)-curl", "php$(version)-imagick", "php$(version)-ldap", + "php$(version)-gmp", # "php$(version)-json" }; @@ -173,136 +337,150 @@ commands: methods: } -bundle agent php(settings) + + +bundle agent php( requested_version, settings ) { -vars: - "ini_files" slist => { }; + classes: + "rv_exists" expression => isvariable( "requested_version" ), scope => "bundle"; + vars: + "ini_files" slist => { }; + "version" string => ifelse( + "debian.!ubuntu", "8.0", + "ubuntu", "8.2", + "centos", "8.3", + "freebsd", "82", + ""); + rv_exists:: + "version" string => "$(requested_version)"; - debian:: - "version" string => "8.0"; - "ini_files" slist => { -# "/etc/php/$(php.version)/apache2/php.ini", -# "/etc/php/$(php.version)/fpm/php.ini" - }; + debian:: + "ini_files" slist => { +# "/etc/php/$(php.version)/apache2/php.ini", +# "/etc/php/$(php.version)/fpm/php.ini" + "/etc/php/$(php.version)/fpm/conf.d/50-wmde.ini", + "/etc/php/$(php.version)/cli/conf.d/50-wmde.ini" + }; + "settings_index" + slist => getindices( "settings" ), + handle => "settings_indexed"; - "cli_exe" string => "/usr/bin/php"; + "cli_exe" string => "/usr/bin/php"; - "fpm_pkgs" slist => { "php$(version)-fpm" }; - "fpm_service_name" string => "php$(version)-fpm"; - "fpm_socket" string => "/run/php/php$(version)-fpm.sock"; - "fpm_socket_type" string => "unix:"; + "fpm_pkgs" slist => { "php$(version)-fpm" }; + "fpm_service_name" string => "php$(version)-fpm"; + "fpm_socket" string => "/run/php/php$(version)-fpm.sock"; + "fpm_socket_type" string => "unix:"; - "apt_repo_url" string => "https://packages.sury.org/php/"; - "apt_repo_key" string => "https://packages.sury.org/php/apt.gpg"; - "apt_repo_key_name" string=> "deb.sury.org-php.gpg"; + "apt_repo_url" string => "https://packages.sury.org/php/"; + "apt_repo_key" string => "https://packages.sury.org/php/apt.gpg"; + "apt_repo_key_name" string=> "deb.sury.org-php.gpg"; - "apache_m" string => "php"; - "apache_f" string => "libphp$(php.version)"; + "apache_m" string => "php"; + "apache_f" string => "libphp$(php.version)"; - ubuntu:: - "apt_repo_url" string => "https://ppa.launchpadcontent.net/ondrej/php/ubuntu/"; - "apt_repo_key" string => ""; - "apt_repo_key_name" string=> ""; + ubuntu:: + "apt_repo_url" string => "https://ppa.launchpadcontent.net/ondrej/php/ubuntu/"; + "apt_repo_key" string => ""; + "apt_repo_key_name" string=> ""; - ubuntu_22:: - "version" string => "8.2"; - - - freebsd:: - "ini_files" slist => { + freebsd:: + "ini_files" slist => { # "/etc/php/$(install_php.version)/apache2/php.ini", # "/etc/php/$(install_php.version)/fpm/php.ini" - }; - "cli_exe" string => "/usr/local/bin/php"; - "version" string => "8.2"; - "bsdvs" string => "82"; - "apache_m" string => "php"; - "apache_f" string => "libphp"; - "fpm_pkgs" slist => {}; - "fpm_service_name" string => "php-fpm"; - "fpm_socket" string => "127.0.0.1:9000"; - "fpm_socket_type" string => "fcgi://"; + }; + "cli_exe" string => "/usr/local/bin/php"; + "bsdvs" string => string_replace( "$(version)", ".", ""); + "apache_m" string => "php"; + "apache_f" string => "libphp"; + "fpm_pkgs" slist => {}; + "fpm_service_name" string => "php-fpm"; + "fpm_socket" string => "127.0.0.1:9000"; + "fpm_socket_type" string => "fcgi://"; - centos:: - "cli_exe" string => "/usr/bin/php"; - "version" string => "8.1"; - "fpm_pkgs" slist => { "php-fpm" }; - "fpm_service_name" string => "php$(version)-fpm"; - "fpm_socket" string => "/run/php-fpm/www.sock"; - "fpm_socket_type" string => "unix:"; + centos:: + "cli_exe" string => "/usr/bin/php"; + "version" string => "8.1"; + "fpm_pkgs" slist => { "php-fpm" }; + "fpm_service_name" string => "php$(version)-fpm"; + "fpm_socket" string => "/run/php-fpm/www.sock"; + "fpm_socket_type" string => "unix:"; -files: - "$(ini_files)" - create => "true", - edit_template => "$(sys.workdir)/inputs/$(wmde_libdir)/templates/php.ini.mustache", - template_method => "mustache", - template_data => @(settings), - classes => if_repaired(php_repaired); + files: + debian:: + "$(ini_files)" + link_from => ln_s("/etc/php/$(php.version)/mods-available/wmde_custom_settings.ini"); + "/etc/php/$(php.version)/mods-available/wmde_custom_settings.ini" + edit_template => "$(sys.workdir)/inputs/$(def.wmde_libdir)/templates/php_confd.ini.mustache", + template_method => "mustache", + template_data => @(settings), + perms => m("644"), + classes => if_repaired(php_repaired); # TODO: bislang kein Reload des FPM-Dienstes nach Änderung - -#methods: -# "any" usebundle => install_php; -reports: -# "PHP VERSION: $(ini_files) V:$(install_php.version)"; +# methods: +# "any" usebundle => install_php; +# reports: +# "PHP VERSION: $(ini_files) V:$(install_php.version)"; } bundle agent install_php_fpm { -vars: - "service_deps" slist => { - "php_fpm_pkgs_installed", - "php_pkgs_installed" - }; - freebsd:: + vars: "service_deps" slist => { - "php_pkgs_installed" - }; - "service_name" string => "$(php.fpm_service_name)"; - "service_cfg_name" string => "php_fpm"; - -methods: - "any" usebundle => install_php; - "any" usebundle => wmde_install_packages(@(php.fpm_pkgs),"php_fpm"); - - "any" usebundle => wmde_enable_service("$(this.bundle)"); + "php_fpm_pkgs_installed", + "php_pkgs_installed" + }; + freebsd:: + "service_deps" slist => { + "php_pkgs_installed" + }; + "service_name" string => "$(php.fpm_service_name)"; + "service_cfg_name" string => "php_fpm"; + + methods: + "any" usebundle => install_php; + "any" usebundle => wmde_install_packages(@(php.fpm_pkgs),"php_fpm"); + + "any" usebundle => wmde_enable_service("$(this.bundle)"); - "any" usebundle => wmde_service("$(php.fpm_service_name)","php_kept|php_fpm_kept","php_repaired|php_fpm_repaired"), - depends_on => @(service_deps); -reports: -# "php ????"; + "any" + usebundle => wmde_service("$(php.fpm_service_name)","php_kept|php_fpm_kept","php_repaired|php_fpm_repaired"), + depends_on => @(service_deps); + reports: +# "php ????"; } bundle agent php_composer(cfg) { -vars: - "installer" string => "$(sys.workdir)/data/php/composer-setup.php"; - "exe" string => "/usr/local/bin/composer"; -classes: - "php_composer_install" expression => not(fileexists("$(exe)")); + vars: + "installer" string => "$(sys.workdir)/data/php/composer-setup.php"; + "exe" string => "/usr/local/bin/composer"; + classes: + "php_composer_install" expression => not(fileexists("$(exe)")); -vars: + vars: -files: - "$(sys.workdir)/data/php/." - create => "true", - handle => "php_dir_created"; -commands: - php_composer_install:: - "$(wget.exe) -q -O $(installer) https://getcomposer.org/installer" - handle => "php_composer_installer_downloaded", - depends_on => {"php_dir_created"}; - - "export HOME=/root && $(php.cli_exe) $(installer) --install-dir=/usr/local/bin --filename=composer" - handle => "php_composer_installed", - contain => wmde_cmd_useshell, - depends_on => {"php_composer_installer_downloaded"}; + files: + "$(sys.workdir)/data/php/." + create => "true", + handle => "php_dir_created"; + commands: + php_composer_install:: + "$(wget.exe) -q -O $(installer) https://getcomposer.org/installer" + handle => "php_composer_installer_downloaded", + depends_on => {"php_dir_created"}; - -methods: - "any" usebundle => install_php; + "export HOME=/root && $(php.cli_exe) $(installer) --install-dir=/usr/local/bin --filename=composer" + handle => "php_composer_installed", + contain => wmde_cmd_useshell, + depends_on => {"php_composer_installer_downloaded"}; + + + methods: + "any" usebundle => install_php; "any" usebundle => install_wget; } diff --git a/postfix.cf b/postfix.cf index 53d3195..5203ca7 100644 --- a/postfix.cf +++ b/postfix.cf @@ -49,6 +49,7 @@ vars: "group" string => "postfix"; "mail_owner" string => "postfix"; "postmap_cmd" string => "/usr/sbin/postmap"; + "postalias_cmd" string => "/usr/sbin/postalias"; centos:: "pkgs" slist => { diff --git a/roundcube.cf b/roundcube.cf index 9aa985f..d78eee6 100644 --- a/roundcube.cf +++ b/roundcube.cf @@ -244,13 +244,14 @@ bundle agent configure_roundcube(cfg) vars: "settings[db_dsnw]" string => "'mysql://$(cfg[db_user]):$(cfg[db_pass])@$(cfg[db_host])/$(cfg[db_name])'"; - "settings[language]" string => "'us_EN'"; + "settings[language]" string => "'de_DE'"; # enigma disabled "settings[plugins]" string => "['acl', 'archive', 'attachment_reminder', 'emoticons', 'hide_blockquote', 'identicon', 'jqueryui', 'managesieve', 'markasjunk', 'newmail_notifier', 'password', 'vcard_attachments', 'zipdownload']"; "idx" slist => getindices(@(cfg[settings])); "settings[$(idx)]" string => "$(cfg[settings][$(idx)])"; - +reports: +# "ROUNDCUBE $(settings)"; methods: "any" usebundle => mysql_table_exists(@(cfg),"users"); diff --git a/scripts/lxc-hooks.sh b/scripts/lxc-hooks.sh deleted file mode 100644 index 7c9e543..0000000 --- a/scripts/lxc-hooks.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -printf "Tut nix im Moment" diff --git a/sympa.cf b/sympa.cf index 15780d3..27a4141 100644 --- a/sympa.cf +++ b/sympa.cf @@ -91,7 +91,8 @@ vars: - SetHandler \\\"proxy:unix:$(sympa.wwsympa_socket)|fcgi://\\\" + #SetHandler \\\"proxy:unix:$(sympa.wwsympa_socket)|fcgi://\\\" + SetHandler \\\"proxy:unix:$(sympa.wwsympa_socket)|fcgi://localhost/\\\" Require all granted @@ -256,7 +257,7 @@ bundle agent sympa_update_config(cfg) vars: "default_settings" data => '{ "aliases_db_type":"hash", - "aliases_program":"$(postfix.postmap_cmd)", + "aliases_program":"$(postfix.postalias_cmd)", "sendmail_aliases":"$(sympa.sendmail_aliases)", "db_type":"$(cfg[db_settings][db_type])", "db_name":"$(cfg[db_settings][db_name])", @@ -590,11 +591,11 @@ methods: reports: - run_backup:: - "SYMPA IS RUN BACKUP"; +# run_backup:: +# "SYMPA IS RUN BACKUP"; - !run_backup:: - "SYMPA DOES NOT RUN BACKUP"; +# !run_backup:: +# "SYMPA DOES NOT RUN BACKUP"; } diff --git a/templates/nanorc.mustache b/templates/nanorc.mustache index d0c46b8..f269f46 100644 --- a/templates/nanorc.mustache +++ b/templates/nanorc.mustache @@ -1,5 +1,3 @@ -set tabsize 4 - ## Sample initialization file for GNU nano. ## ## For the options that take parameters, the default value is shown. @@ -97,7 +95,7 @@ set locking ## mouse clicks can be used to place the cursor, set the mark (with a ## double click), and execute shortcuts. The mouse will work in the ## X Window System, and on the console when gpm is running. -set mouse +# set mouse ## Switch on multiple file buffers (inserting a file will put it into ## a separate buffer). diff --git a/templates/roundcube-config.inc.php.mustache b/templates/roundcube-config.inc.php.mustache index 6020b03..d7ccb7d 100644 --- a/templates/roundcube-config.inc.php.mustache +++ b/templates/roundcube-config.inc.php.mustache @@ -72,7 +72,7 @@ $config['plugins'] = ['acl', 'archive', 'attachment_reminder', 'emoticons', 'eni // the default locale setting (leave empty for auto-detection) // RFC1766 formatted language name like en_US, de_DE, de_CH, fr_FR, pt_BR -$config['language']='us_EN'; +$config['language']='de_DE'; -$config['mail_domain'] = 'ms.plamix.org'; +$config['mail_domain'] = 'ms.wmde.org'; diff --git a/vimbadmin.cf b/vimbadmin.cf index 39bd473..dd7ae5f 100644 --- a/vimbadmin.cf +++ b/vimbadmin.cf @@ -32,6 +32,8 @@ vars: "vsettings[identity.name]" string => "Vimb Support"; "vsettings[identity.autobot.email]" string => "$(cfg[server_email_address])"; "vsettings[identity.mailer.email]" string => "$(cfg[server_email_address])"; + "vsettings[resources.smarty.skin]" string => "$(cfg[skin])"; + diff --git a/wget.cf b/wget.cf index 675d765..16f71b7 100644 --- a/wget.cf +++ b/wget.cf @@ -10,7 +10,7 @@ vars: centos:: "pkgs" slist => {"wget","tar","bzip2","xz","unzip"}; debian:: - "pkgs" slist => {"wget"}; + "pkgs" slist => {"wget", "curl"}; any::