Created
January 14, 2015 16:07
-
-
Save peckpeck/f556364e84e85f275e98 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_alive_check | |
{ | |
vars: | |
"sites_to_check" slist => { "http://localhost:8080/rudder/api/status", "http://localhost:8080/endpoint/api/status" }; | |
methods: | |
"any" usebundle => generic_alive_check("${sites_to_check}"); | |
} | |
bundle agent generic_alive_check(site_to_check) | |
{ | |
vars: | |
"sitename" string => canonify("${site_to_check}"); | |
"cleanup_failed_classes" slist => { "site_down_once_${sitename}", "site_alivecheck_restart_jetty_${sitename}" }; | |
"failed_result_class" string => "site_down_once_${sitename}", | |
ifvarclass => "!site_down_once_${sitename}.!first_iteration_passed"; | |
"site_failure_persist_time" string => "10", | |
ifvarclass => "!site_down_once_${sitename}.!first_iteration_passed"; | |
"failed_result_class" string => "site_alivecheck_restart_jetty_${sitename}", | |
ifvarclass => "site_down_once_${sitename}.!first_iteration_passed"; | |
"site_failure_persist_time" string => "0", | |
ifvarclass => "site_down_once_${sitename}.!first_iteration_passed"; | |
classes: | |
"first_iteration_passed" expression => "any"; | |
methods: | |
"any" usebundle => generic_process_check_process(".*java.*/opt/rudder/jetty7/start.jar", "rudder-jetty", "true"), | |
ifvarclass => "site_alivecheck_restart_jetty_${sitename}", | |
classes => set_persist_classes("site_alivecheck_jetty_restarted_${sitename}", "site_down_once_${sitename}" ,"0"); | |
commands: | |
"/usr/bin/curl -s ${site_to_check} |/bin/grep -q OK" | |
contain => in_shell_silent, | |
classes => set_persist_classes_alivecheck("site_ok", "${failed_result_class}", "@{generic_alive_check.cleanup_failed_classes}", "${site_failure_persist_time}"), | |
comment => "Checking if ${site_to_check} is alive"; | |
reports: | |
linux:: | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#The ${site_to_check} web application is running" | |
ifvarclass => "site_ok.!site_down_once_${sitename}"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#This is the first time the ${site_to_check} web application failed to respond. Deferring the restart." | |
ifvarclass => "site_down_once_${sitename}.!site_alivecheck_restart_jetty_${sitename}"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#The ${site_to_check} web application failed to respond for the second time. Restarting rudder-jetty NOW !" | |
ifvarclass => "site_alivecheck_restart_jetty_${sitename}"; | |
} | |
body classes set_persist_classes_alivecheck(repaired, failed, cancelifok, length) | |
{ | |
promise_kept => { "${repaired}" }; | |
promise_repaired => { "${repaired}" }; | |
repair_failed => { "${failed}" }; | |
repair_denied => { "${failed}" }; | |
repair_timeout => { "${failed}" }; | |
cancel_kept => {"@{cancelifok}"}; | |
cancel_repaired => {"@{cancelifok}"}; | |
cancel_notkept => {"${repaired}"}; | |
persist_time => "${length}"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_logrotate_check | |
{ | |
files: | |
debian:: | |
"/etc/logrotate.d/rudder" | |
copy_from => copy_digest("${sys.workdir}/inputs/distributePolicy/logrotate.conf/rudder.debian"), | |
classes => kept_if_else("rudder_logrotate_conf_ok", "rudder_logrotate_conf_copied", "cannot_copy_rudder_logrotate_conf"), | |
comment => "Copying the logrotate configuration for Debian-like system"; | |
redhat:: | |
"/etc/logrotate.d/rudder" | |
copy_from => copy_digest("${sys.workdir}/inputs/distributePolicy/logrotate.conf/rudder.rhel"), | |
classes => kept_if_else("rudder_logrotate_conf_ok", "rudder_logrotate_conf_copied", "cannot_copy_rudder_logrotate_conf"), | |
comment => "Copying the logrotate configuration for Debian-like system"; | |
!debian.!redhat:: | |
"/etc/logrotate.d/rudder" | |
copy_from => copy_digest("${sys.workdir}/inputs/distributePolicy/logrotate.conf/rudder.debian"), | |
classes => kept_if_else("rudder_logrotate_conf_ok", "rudder_logrotate_conf_copied", "cannot_copy_rudder_logrotate_conf"), | |
comment => "Copying the logrotate configuration for Debian-like system"; | |
reports: | |
linux:: | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#The logrotate configuration is correct" | |
ifvarclass => "rudder_logrotate_conf_ok.!rudder_logrotate_conf_copied.!cannot_copy_rudder_logrotate_conf"; | |
"@@DistributePolicy@@Repaired@@root-DP#@root-distributePolicy##${g.uuid}@#The logrotate configuration has been updated" | |
ifvarclass => "rudder_logrotate_conf_copied.!cannot_copy_rudder_logrotate_conf"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#The logrotate configuration could not be updated" | |
ifvarclass => "cannot_copy_rudder_logrotate_conf"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_postgres_check | |
{ | |
vars: | |
SuSE:: | |
"configuration_statements" slist => { "host all rudder ::1/128 md5", "host all rudder 127.0.0.1/32 md5" }; | |
commands: | |
SuSE:: | |
"/etc/init.d/postgresql" | |
args => "restart", | |
classes => kept_if_else("psql_restart_ok", "psql_restart_ok", "psql_restart_error"), | |
ifvarclass => "psql_conf_updated"; | |
files: | |
SuSE:: | |
"/var/lib/pgsql/data/pg_hba.conf" | |
edit_line => prepend("${configuration_statements}"), | |
edit_defaults => noempty_backup, | |
classes => kept_if_else("psql_conf_ok", "psql_conf_updated", "psql_conf_update_error"), | |
comment => "Edit the SuSE postgresql configuration to enable account-less logins"; | |
reports: | |
SuSE:: | |
# Report about the configuration file edition | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#The SuSE specific postgresql configuration is present" | |
ifvarclass => "psql_conf_ok.!psql_conf_updated.!psql_conf_update_error"; | |
"@@DistributePolicy@@Repaired@@root-DP#@root-distributePolicy##${g.uuid}@#The SuSE specific postgresql configuration has been added" | |
ifvarclass => "psql_conf_updated.!psql_conf_update_error"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#The SuSE specific postgresql configuration could not be added" | |
ifvarclass => "psql_conf_update_error"; | |
# Reports about Postgres restart status | |
"@@DistributePolicy@@Inform@@root-DP#@root-distributePolicy##${g.uuid}@#PostgreSQL has been restarted" | |
ifvarclass => "psql_restart_ok"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#PostgreSQL restart has failed! Rudder is most certainly broken..." | |
ifvarclass => "psql_restart_error"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_apache_webdav_check | |
{ | |
vars: | |
# I WANT to use this but there is no crypt support... yet | |
# "dav_password" string => hash("rudder","crypt"); | |
"dav_user[1]" string => "rudder"; | |
"dav_password[1]" string => "PoBZbSkW/8bcE"; | |
"iterator" slist => getindices("dav_user"); | |
debian:: | |
"webdav_check_wwwgroup" string => "www-data"; | |
!debian:: | |
"webdav_check_wwwgroup" string => "www"; | |
files: | |
"${g.rudder_base}/etc/htpasswd-webdav" | |
create => "true", | |
edit_line => insert_lines("${dav_user[${iterator}]}:${dav_password[${iterator}]}"), | |
edit_defaults => empty_backup, | |
perms => mog("640", "root", "${webdav_check_wwwgroup}"), | |
classes => kept_if_else("rudder_apache_davpassword_ok", "rudder_apache_davpassword_changed", "rudder_apache_davpassword_failed"), | |
comment => "Verifying the Rudder WebDAV user and password"; | |
reports: | |
linux:: | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#The Rudder WebDAV user and password are OK" | |
ifvarclass => "rudder_apache_davpassword_ok.!rudder_apache_davpassword_changed.!rudder_apache_davpassword_failed"; | |
"@@DistributePolicy@@Repaired@@root-DP#@root-distributePolicy##${g.uuid}@#The Rudder WebDAV user and password were updated" | |
ifvarclass => "rudder_apache_davpassword_changed.!rudder_apache_davpassword_failed"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#The Rudder WebDAV user and password could not be updated" | |
ifvarclass => "rudder_apache_davpassword_failed"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# Path of the promises files on the machine | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_ldap_check | |
{ | |
vars: | |
"ldap_rudder_user" string => "rudder"; | |
"ldap_rudder_cleartext_password" string => "secret"; | |
# We'd like to generate the password but a strange convergeance bug prevents this. You have to generate the hashed string manually if required. | |
# "ldap_rudder_hashed_password" string => execresult("/opt/rudder/sbin/slappasswd -s ${ldap_rudder_cleartext_password}", "noshell"); | |
"ldap_rudder_hashed_password" string => "{SSHA}UK0Ut/7QsceF3ZHJl6nXotlEvh8ECzZx"; | |
"ldap_dot_properties" slist => { "${g.rudder_base}/etc/inventory-web.properties", "${g.rudder_base}/etc/rudder-web.properties" }; | |
files: | |
"${g.rudder_base}/etc/openldap/slapd.conf" | |
edit_line => ldap_password_slapd("${ldap_rudder_hashed_password}"), | |
perms => mog("600", "root", "root"), | |
classes => kept_if_else("rudder_ldap_slapd_password_ok", "rudder_ldap_slapd_password_changed", "rudder_ldap_slapd_password_failed"), | |
comment => "Verifying the Rudder LDAP password in slapd.conf"; | |
"${ldap_dot_properties}" | |
edit_line => ldap_password_properties("${ldap_rudder_cleartext_password}"), | |
perms => mog("600", "root", "root"), | |
classes => kept_if_else("rudder_ldap_prop_password_ok", "rudder_ldap_prop_password_changed", "rudder_ldap_prop_password_failed"), | |
comment => "Verifying the Rudder LDAP password in the properties files"; | |
methods: | |
"any" usebundle => generic_process_check_process("/opt/rudder/libexec/slapd", "rudder-slapd", "true"), | |
ifvarclass => "rudder_ldap_slapd_password_changed"; | |
"any" usebundle => generic_process_check_process(".*java.*/opt/rudder/jetty7/start.jar", "rudder-jetty", "true"), | |
ifvarclass => "rudder_ldap_prop_password_changed"; | |
reports: | |
linux:: | |
# slapd configuration | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#The Rudder OpenLDAP daemon password is OK" | |
ifvarclass => "rudder_ldap_slapd_password_ok.!rudder_ldap_slapd_password_changed.!rudder_ldap_slapd_password_failed"; | |
"@@DistributePolicy@@Repaired@@root-DP#@root-distributePolicy##${g.uuid}@#The Rudder OpenLDAP daemon password has been updated" | |
ifvarclass => "rudder_ldap_slapd_password_changed.!rudder_ldap_slapd_password_failed"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#The Rudder OpenLDAP daemon password failed to update" | |
ifvarclass => "rudder_ldap_slapd_password_failed"; | |
# properties configuration | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#The Rudder LDAP properties files passwords are OK" | |
ifvarclass => "rudder_ldap_prop_password_ok.!rudder_ldap_prop_password_changed.!rudder_ldap_prop_password_failed"; | |
"@@DistributePolicy@@Repaired@@root-DP#@root-distributePolicy##${g.uuid}@#The Rudder LDAP properties files passwords were updated" | |
ifvarclass => "rudder_ldap_prop_password_changed.!rudder_ldap_prop_password_failed"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#The Rudder LDAP properties files passwords failed to update" | |
ifvarclass => "rudder_ldap_prop_password_failed"; | |
} | |
bundle edit_line ldap_password_slapd(password) | |
{ | |
delete_lines: | |
"rootpw.*"; | |
insert_lines: | |
"rootpw ${password}" | |
location => after("rootdn.*"); | |
} | |
bundle edit_line ldap_password_properties(password) | |
{ | |
delete_lines: | |
"ldap.authpw.*"; | |
insert_lines: | |
"ldap.authpw=${password}" | |
location => after("ldap.authdn.*"); | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_integrity_check | |
{ | |
files: | |
"${g.rudder_var}/configuration-repository" | |
create => "true", | |
action => WarnOnly, | |
classes => if_else("rudder_integrity_ok", "rudder_integrity_failed"); | |
reports: | |
linux:: | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#The ${g.rudder_var}/configuration-repository directory is present" | |
ifvarclass => "rudder_integrity_ok.!rudder_integrity_failed"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#EMERGENCY: THE ${g.rudder_var}/configuration-repository DIRECTORY IS *ABSENT*. THIS ORCHESTRATOR WILL *NOT* OPERATE CORRECTLY." | |
ifvarclass => "!rudder_integrity_ok|rudder_integrity_failed"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# Configure rsyslog on the orchestrator | |
# This will provide promises to add the backports repos to Debian Lenny: | |
# - in sources.list | |
# - default apt_preferences to upgrade packages installed from backports | |
# - a package_method to install packages from backports via cfengine | |
bundle agent setup_debian_backports | |
{ | |
vars: | |
"apt_source_line" slist => { "deb http://backports.debian.org/debian-backports lenny-backports" }; | |
"apt_components" slist => { "main" }; | |
files: | |
debian_5:: | |
"/etc/apt/sources.list" | |
comment => "Include extra apt repos", | |
edit_line => append_if_no_lines("${apt_source_line} ${apt_components}"), | |
edit_defaults => noempty_backup, | |
classes => if_repaired("apt_sources_updated"); | |
"/etc/apt/preferences" | |
comment => "Set automatic upgrades for packages installed from backports (recommended setting from backports.debian.org)", | |
create => "true", | |
edit_line => append_if_no_lines("Package: *${const.n}Pin: release a=lenny-backports${const.n}Pin-Priority: 200"), | |
edit_defaults => noempty_backup, | |
classes => if_repaired("apt_preferences_repaired"); | |
commands: | |
apt_sources_updated:: | |
"/usr/bin/aptitude" | |
args => "update"; | |
reports: | |
apt_sources_updated:: | |
"apt's sources.list was edited, and an aptitude update will now run"; | |
apt_preferences_repaired:: | |
"apt's /etc/apt/preferences file was changed"; | |
} | |
bundle agent install_rsyslogd | |
{ | |
packages: | |
policy_server.debian_5.!SuSE:: | |
"rsyslog" | |
package_policy => "add", | |
package_method => debian_backports, | |
classes => cf2_if_else("rsyslog_installed", "cant_install_rsyslog"), | |
comment => "Installing rsyslog using apt backports"; | |
"rsyslog-pgsql" | |
package_policy => "add", | |
package_method => debian_backports, | |
classes => cf2_if_else("rsyslog_pgsql_installed", "cant_install_rsyslog_pgsql"), | |
comment => "Installing rsyslog_pgsql using apt backports"; | |
policy_server.!debian_5.!SuSE:: | |
"rsyslog" | |
package_policy => "add", | |
package_method => generic, | |
classes => cf2_if_else("rsyslog_installed", "cant_install_rsyslog"), | |
comment => "Installing rsyslog using apt backports"; | |
"rsyslog-pgsql" | |
package_policy => "add", | |
package_method => generic, | |
classes => cf2_if_else("rsyslog_pgsql_installed", "cant_install_rsyslog_pgsql"), | |
comment => "Installing rsyslog_pgsql using apt backports"; | |
files: | |
policy_server:: | |
"/etc/rsyslog.d/rudder.conf" | |
copy_from => copy_digest("${sys.workdir}/inputs/distributePolicy/rsyslog.conf/rudder.conf"), | |
classes => cf2_if_else("rudder_rsyslog_conf_copied", "cannot_copy_rudder_rsyslog_conf"), | |
comment => "Copying rsyslog conf"; | |
"/etc/rsyslog.conf" | |
edit_line => append_if_no_lines("$IncludeConfig /etc/rsyslog.d/*.conf"), | |
edit_defaults => noempty_backup, | |
comment => "Add the rsyslog.conf.d include if not already present", | |
classes => cf2_if_else("rsyslog_inc_ok" , "rsyslog_inc_failed"); | |
policy_server.!SuSE:: | |
"/etc/rsyslog.d/pgsql.conf" | |
edit_line => comment_all(), | |
edit_defaults => noempty_backup, | |
classes => cf2_if_else("rudder_rsyslog_pgsql", "cannot_update_rudder_rsyslog_pgsql"), | |
comment => "Removing the logging of all in the database"; | |
commands: | |
policy_server.(rsyslog_installed|rsyslog_pgsql_installed|rudder_rsyslog_conf_copied|rudder_rsyslog_pgsql).!SuSE:: | |
"/etc/init.d/rsyslog" | |
args => "restart", | |
classes => cf2_if_else("rsyslog_restarted", "cant_restart_rsyslog"), | |
comment => "restarting rsyslog"; | |
policy_server.(rsyslog_installed|rsyslog_pgsql_installed|rudder_rsyslog_conf_copied|rudder_rsyslog_pgsql).SuSE:: | |
"/etc/init.d/syslog" | |
args => "restart", | |
classes => cf2_if_else("rsyslog_restarted", "cant_restart_rsyslog"), | |
comment => "restarting rsyslog"; | |
reports: | |
cant_install_rsyslog|cant_install_rsyslog_pgsql:: | |
"Fatal : Can't install rsyslog or rsyslog_pgsql on the Rudder root server !"; | |
cannot_copy_rudder_rsyslog_conf:: | |
"Fatal : Can't copy the rsyslog configuration !"; | |
rsyslog_inc_failed:: | |
"Fatal : Can't enable the rsyslog include directory !"; | |
cant_restart_rsyslog:: | |
"Fatal : Can't restart rsyslog !"; | |
cannot_update_rudder_rsyslog_pgsql:: | |
"Fatal : Cannot update the pgsql configuration !"; | |
rsyslog_restarted:: | |
"Info : Restarted rsyslog"; | |
} | |
# Package method to install packages from debian-backports | |
body package_method debian_backports | |
{ | |
debian:: | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/dpkg -l"; | |
package_list_name_regex => "ii\s+([^\s]+).*"; | |
package_list_version_regex => "ii\s+[^\s]+\s+([^\s]+).*"; | |
package_installed_regex => ".*"; # all reported are installed | |
package_name_convention => "${name}"; | |
package_list_update_ifelapsed => "240"; # 4 hours | |
debian.have_aptitude:: | |
package_add_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o Aptitude::Delete-Unused=false -t lenny-backports --assume-yes install"; | |
package_list_update_command => "/usr/bin/aptitude update"; | |
package_delete_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o Aptitude::Delete-Unused=false --assume-yes -q remove"; | |
package_update_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o Aptitude::Delete-Unused=false --assume-yes install"; | |
package_verify_command => "/usr/bin/aptitude show"; | |
package_noverify_regex => "(State: not installed|E: Unable to locate package .*)"; | |
debian.!have_aptitude:: | |
package_add_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o APT::Get::AutomaticRemove=false --yes -t lenny-backports install"; | |
package_list_update_command => "/usr/bin/apt-get update"; | |
package_delete_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o APT::Get::AutomaticRemove=false --yes -q remove"; | |
package_update_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o APT::Get::AutomaticRemove=false --yes install"; | |
package_verify_command => "/usr/bin/dpkg -s"; | |
package_noverify_returncode => "1"; | |
} | |
bundle edit_line comment_all() | |
{ | |
replace_patterns: | |
# comment all lines | |
"^[^#](.*)" | |
replace_with => comments; | |
} | |
body replace_with comments | |
{ | |
replace_value => "#${match.1}"; # backreference 0 | |
occurrences => "all"; # first, last all | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_init_check() | |
{ | |
vars: | |
"service[1][binary]" string => "/opt/rudder/libexec/slapd"; | |
"service[1][initscript]" string => "rudder-slapd"; | |
"service[2][binary]" string => ".*java.*/opt/rudder/jetty7/start.jar"; | |
"service[2][initscript]" string => "rudder-jetty"; | |
"service[3][binary]" string => "postgres: writer process"; | |
"service[3][initscript]" string => "postgresql"; | |
"service[4][binary]" string => "/var/cfengine/bin/cf-.*"; | |
"service[4][initscript]" string => "cfengine3"; | |
"service[5][binary]" string => "apache2"; | |
"service[5][initscript]" string => "apache2"; | |
"index" slist => getindices("service"); | |
methods: | |
"any" usebundle => generic_process_check_process("${service[${index}][binary]}", "${service[${index}][initscript]}", "false"); | |
"any" usebundle => generic_process_check_bootstart("${service[${index}][binary]}", "${service[${index}][initscript]}"); | |
} | |
bundle agent generic_process_check_process(binary, initscript, force_restart) | |
{ | |
vars: | |
"canoname" string => canonify("${binary}"); | |
classes: | |
"forced_trigger_${canoname}" expression => strcmp("${force_restart}", "true"); | |
processes: | |
# check the service status | |
"${binary}" | |
comment => "Check the process status", | |
restart_class => "process_restart_${canoname}", | |
classes => kept_if_else("service_running_${canoname}", "service_anomaly_${canoname}", "service_error_${canoname}"); | |
commands: | |
"/etc/init.d/${initscript}" | |
args => "restart </dev/null >/dev/null 2>/dev/null", | |
contain => in_shell_silent, | |
# action => bg("0", "120"), | |
classes => kept_if_else("process_restart_ok_${canoname}", "process_restart_ok_${canoname}", "process_restart_error_${canoname}"), | |
ifvarclass => "process_restart_${canoname}|forced_trigger_${canoname}"; | |
reports: | |
linux:: | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#The ${initscript} process is already running" | |
ifvarclass => "!process_restart_${canoname}.!forced_trigger_${canoname}"; | |
"@@DistributePolicy@@Repaired@@root-DP#@root-distributePolicy##${g.uuid}@#The ${initscript} process was not running and has been restarted" | |
ifvarclass => "process_restart_${canoname}.process_restart_ok_${canoname}.!forced_trigger_${canoname}"; | |
"@@DistributePolicy@@Repaired@@root-DP#@root-distributePolicy##${g.uuid}@#The ${initscript} process has been restarted" | |
ifvarclass => "process_restart_ok_${canoname}.forced_trigger_${canoname}"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#The ${initscript} process couldn't be restarted" | |
ifvarclass => "process_restart_error_${canoname}"; | |
} | |
bundle agent generic_process_check_bootstart(binary, initscript) | |
{ | |
vars: | |
"canoname" string => canonify("${binary}"); | |
commands: | |
(SuSE|redhat):: | |
"/sbin/chkconfig" | |
args => "--check ${initscript}", | |
classes => if_else("service_bootstarted_${canoname}", "service_unbootstarted_${canoname}"), | |
comment => "Check if the service ${initscript} is started on boot"; | |
"/sbin/insserv" | |
args => "-d ${initscript}", | |
classes => if_else("service_bootstarted_ok_${canoname}", "service_bootstarted_fail_${canoname}"), | |
ifvarclass => "service_unbootstarted_${canoname}", | |
comment => "Set the service ${initscript} to start on boot"; | |
debian:: | |
"/usr/sbin/update-rc.d ${initscript} remove \&\& /usr/sbin/update-rc.d ${initscript} defaults" | |
contain => in_shell, | |
classes => if_else("service_bootstarted_ok_${canoname}", "service_bootstarted_fail_${canoname}"), | |
ifvarclass => "service_unbootstarted_${canoname}", | |
comment => "Set the service ${initscript} to start on boot"; | |
files: | |
debian:: | |
"/etc/rc2.d/S.*${initscript}.*" | |
create => "true", | |
action => WarnOnly, | |
classes => if_else("service_bootstarted_${canoname}", "service_unbootstarted_${canoname}"); | |
reports: | |
linux:: | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#${initscript} is started on boot as required" | |
ifvarclass => "service_bootstarted_${canoname}"; | |
"@@DistributePolicy@@Repaired@@root-DP#@root-distributePolicy##${g.uuid}@#${initscript} has been set to start on boot" | |
ifvarclass => "!service_bootstarted_${canoname}.service_bootstarted_ok_${canoname}"; | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#Could not set ${initscript} to start on boot!" | |
ifvarclass => "!service_bootstarted_${canoname}.service_bootstarted_fail_${canoname}"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# Fetch the promises from the server to be available for others machines | |
# Must not do it on the RootServer though... | |
bundle agent propagatePromises | |
{ | |
vars: | |
any:: | |
"server_data" string => "${server_info.policy_files}/share"; #actual directory with data to propagate | |
"client_data" string => "/var/rudder/share/"; #where to put the files on the client when downloaded | |
files: | |
root_server:: | |
"${g.rudder_tools}" | |
copy_from => copy("${g.rudder_base}/share/tools"), | |
depth_search => recurse_visible("inf"), | |
comment => "Fetching the tools for the promises execution", | |
classes => if_else("tools_propagated", "could_not_propagate_tools"); | |
!root_server:: | |
"${client_data}" #that's a loop on each files in client_inputs | |
copy_from => remote("${server_info.cfserved}","${server_data}"), | |
depth_search => recurse_visible("inf"), | |
comment => "Fetching the promises to propagate", | |
classes => if_else("promises_propagated", "could_not_propagate_promise"); | |
"${g.rudder_tools}" | |
copy_from => remote("${server_info.cfserved}","${g.rudder_tools}"), | |
depth_search => recurse_visible("inf"), | |
comment => "Fetching the tools for the promises execution", | |
classes => if_else("tools_propagated", "could_not_propagate_tools"); | |
"${sys.workdir}/masterfiles" | |
copy_from => remote("${server_info.cfserved}","${sys.workdir}/masterfiles"), | |
depth_search => recurse_visible("inf"), | |
file_select => no_license_dat, #We don't want to propagate a wrong license.dat | |
comment => "Fetching the bootstrap promises", | |
classes => if_else("masterfiles_propagated", "could_not_propagate_masterfiles"); | |
"${sys.workdir}/masterfiles/license.dat" | |
copy_from => local_cp("${sys.workdir}/inputs/license.dat"), | |
comment => "Putting the right license in the bootstrap", | |
classes => if_else("license_copied", "could_not_copy_license"); | |
reports: | |
could_not_propagate_promise:: | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#Cannot propagate policy files"; | |
could_not_propagate_tools:: | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#Cannot propagate tools"; | |
could_not_propagate_masterfiles:: | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#Cannot propagate masterfiles"; | |
could_not_copy_license:: | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#Cannot copy local license"; | |
} | |
# Sending the inventory to cmdb (or syncing with the server if we are a simple relay) | |
bundle agent sendInventoryToCmdb | |
{ | |
files: | |
root_server:: | |
"${g.rudder_inventories}/incoming" | |
transformer => "${g.rudder_tools}/send-clean.sh http://localhost:8080/endpoint/upload/ ${this.promiser} ${g.rudder_inventories}/received/ ${g.rudder_inventories}/failed/", | |
depth_search => recurse_visible(1), | |
file_select => all_files, | |
classes => if_else("inventory_sent", "cant_send_inventory"), | |
comment => "Sending the inventory to the cmdb"; | |
# NEED TO DO THE RSYNC PART | |
reports: | |
inventory_sent:: | |
"@@DistributePolicy@@Success@@root-DP#@root-distributePolicy##${g.uuid}@#The inventory has been successfully added to the cmdb"; | |
cant_send_inventory:: | |
"@@DistributePolicy@@Error@@root-DP#@root-distributePolicy##${g.uuid}@#Could not send the inventory to the cmdb"; | |
} | |
body file_select all_files | |
{ | |
leaf_name => { ".*\..*" }; | |
file_result => "leaf_name"; | |
} | |
body file_select no_license_dat | |
{ | |
leaf_name => { "license\.dat" }; | |
file_result => "!leaf_name"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
####################################################### | |
# | |
# promises.cf | |
# | |
####################################################### | |
body common control | |
{ | |
inputs => { | |
"common/site.cf", "common/update.cf", "common/process_matching.cf", "common/cfengine_stdlib.cf","common/cf-served.cf","common/library.cf","common/core-lib.cf", "common/rudder_stdlib.cf", "distributePolicy/propagatePromises.cf", "distributePolicy/rsyslogConf.cf", "distributePolicy/initCheck.cf", "distributePolicy/postgresCheck.cf", "distributePolicy/logrotateCheck.cf", "distributePolicy/integrityCheck.cf", "distributePolicy/apacheCheck.cf", "distributePolicy/ldapCheck.cf", "distributePolicy/aliveCheck.cf" | |
}; | |
bundlesequence => { @{va.bs} , "setup_debian_backports", "install_rsyslogd", "propagatePromises", "sendInventoryToCmdb", "root_init_check", "root_postgres_check", "root_logrotate_check", "root_integrity_check", "root_apache_webdav_check", "root_ldap_check", "root_alive_check" }; | |
output_prefix => "rudder"; | |
} | |
bundle common va | |
{ | |
vars: | |
"bs" slist => { "clean_red_button", "set_red_button", "update", "process_matching", "check_cf_processes", "check_uuid" | |
#, "executor" | |
}; | |
# definition of the machine roles | |
classes: | |
"root_server" expression => "any"; | |
"policy_server" expression => "any"; | |
} | |
########################################################## | |
# Red Button part. | |
# When the file ${sys.workdir}/inputs/stop exists, we must stop the | |
# execution of the agent on all client machines | |
########################################################## | |
bundle agent clean_red_button() | |
{ | |
commands: | |
safe.policy_server:: | |
"${sys.workdir}/bin/cf-runagent" | |
args => "-Dsafe", | |
comment => "Propagate the safe information to children"; | |
files: | |
safe.policy_server:: | |
"${g.rudder_var}/share/[a-f0-9A-F\-]+/rules/cfengine-(community|nova)/stopFile" | |
delete => tidy, | |
comment => "Deleting the stop file on clients promises, cfengine is good to go"; | |
safe.!policy_server:: | |
"${sys.workdir}/inputs/stopFile" | |
delete => tidy, | |
comment => "Deleting the stop file, cfengine is good to go"; | |
reports: | |
safe:: | |
"@@Common@@Inform@@hasPolicyServer-root#@common-root##${g.uuid}@#Authorizing Cfengine to restart"; | |
} | |
bundle agent set_red_button() | |
{ | |
classes: | |
policy_server:: | |
"danger" expression => fileexists("${g.rudder_var}/share/root/stopFile"); | |
methods: | |
danger:: | |
"any" usebundle => setStopFile; | |
danger.policy_server:: | |
"any" usebundle => stopClients; | |
} | |
bundle agent setStopFile | |
{ | |
files: | |
danger.!policy_server:: | |
"${sys.workdir}/inputs/stop" | |
create => "true"; | |
danger.policy_server:: | |
"${g.rudder_var}/share/[a-f0-9A-F\-]+/rules/cfengine-(community|nova)/stopFile" | |
create => "true"; | |
reports: | |
danger.!policy_server:: | |
"@@Common@@Inform@@hasPolicyServer-root#@common-root##${g.uuid}@#Creating stop file"; | |
danger.policy_server:: | |
"@@Common@@Inform@@hasPolicyServer-root#@common-root##${g.uuid}@#Creating stop files for clients"; | |
} | |
bundle agent stopClients | |
{ | |
classes: | |
policy_server:: | |
"danger" expression => fileexists("${g.rudder_var}/share/root/stopFile"); | |
commands: | |
danger.policy_server:: | |
"${sys.workdir}/bin/cf-runagent" | |
args => "-Ddanger", | |
comment => "Propagate the danger information to children"; | |
reports: | |
danger.policy_server:: | |
"@@Common@@Inform@@hasPolicyServer-root#@common-root##${g.uuid}@#gStopping all Cfengine operation"; | |
} | |
bundle agent check_red_button_status() | |
{ | |
classes: | |
!policy_server:: | |
"should_not_continue" expression => fileexists("${sys.workdir}/inputs/stopFile"); | |
} | |
################################################### | |
# Check that CFengine services are up | |
################################################### | |
bundle agent check_cf_processes | |
{ | |
processes: | |
"${sys.workdir}/bin/cf-serverd" restart_class => "start_server"; | |
"${sys.workdir}/bin/cf-execd" restart_class => "start_executor"; | |
commands: | |
start_server:: | |
"${sys.cf_serverd}", | |
action => u_ifwin_bg, | |
classes => outcome("server"); | |
start_executor:: | |
"${sys.cf_execd}", | |
action => u_ifwin_bg, | |
classes => outcome("executor"); | |
} | |
####################################################### | |
# UUID file enforcing | |
bundle agent check_uuid | |
{ | |
files: | |
"${g.uuid_file}" | |
create => "true", | |
edit_line => enforce_content("${g.uuid}"), | |
edit_defaults => empty_backup, | |
perms => m("644"), | |
comment => "Setting the uuid variable in a machine"; | |
} | |
####################################################### | |
body agent control | |
{ | |
# if default runtime is 5 mins we need this for long jobs | |
ifelapsed => "1"; | |
#define here some environment variables | |
environment => { "DEBIAN_FRONTEND=noninteractive" }; | |
agentfacility => "LOG_LOCAL6"; | |
} | |
####################################################### | |
body executor control | |
{ | |
splaytime => "1"; | |
exec_command => "${sys.workdir}/bin/cf-agent -f failsafe.cf && ${sys.workdir}/bin/cf-agent"; | |
schedule => { "Min00", "Min05", "Min10", "Min15", "Min20", "Min25", "Min30", "Min35", "Min40", "Min45", "Min50", "Min55" }; | |
executorfacility => "LOG_DAEMON"; | |
} | |
# Not currently used | |
bundle agent executor | |
{ | |
# processes: | |
# linux.!nova_edition:: | |
# "cf-execd" | |
# restart_class => "start_cfexecd"; #call a class | |
# commands: | |
# start_cfexecd:: #define a class | |
# "/var/cfengine/bin/cf-execd";l | |
files: | |
linux.!nova_edition:: | |
"${g.crontab}" | |
create => "true", | |
edit_line => upgrade_cfexecd; | |
} | |
######################################################## | |
# Not currently used | |
bundle edit_line upgrade_cfexecd | |
{ | |
classes: | |
"exec_fix" not => regline(".*cf-execd.*","${edit.filename}"); | |
insert_lines: | |
exec_fix:: | |
"0,5,10,15,20,25,30,35,40,45,50,55 * * * * /var/cfengine/bin/cf-execd -F"; | |
reports: | |
exec_fix:: | |
"Added a 5 minute schedule to crontabs to verify cf-execd is up"; | |
} | |
####################################################### | |
body reporter control | |
{ | |
reports => { "classes", "audit", "all_locks", "hashes", "performance", "last_seen", "monitor_history" }; | |
build_directory => "${sys.workdir}/reports"; | |
report_output => "xml"; | |
} | |
####################################################### | |
#Enforce that the file only contains this information | |
bundle edit_line enforce_content(str) | |
{ | |
delete_lines: | |
"${str}" not_matching => "true"; | |
insert_lines: | |
"${str}"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# Path of the promises files on the machine | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# Failsafe file | |
# | |
body common control | |
{ | |
bundlesequence => { "init_files", "update" }; | |
inputs => { "common/update.cf" }; | |
} | |
bundle common g | |
{ | |
vars: | |
linux|cygwin:: | |
"rudder_base" string => "/opt/rudder"; | |
"rudder_var" string => "/var/rudder"; | |
"rudder_bin" string => "${rudder_base}/bin"; | |
"rudder_sbin" string => "${rudder_base}/sbin"; | |
"rudder_base_sbin" string => "${rudder_base}/sbin"; #folder where tools are installed | |
"rudder_tools" string => "${rudder_var}/tools"; | |
"rudder_ncf" string => "${rudder_var}/ncf"; | |
any:: | |
"excludedreps" slist => { "\.X11", ".*kde.*", "\.svn", "perl" }; | |
"rudder_tools_origin" string => "/var/rudder/tools"; | |
"rudder_ncf_origin_common" string => "/usr/share/ncf/tree"; | |
"rudder_ncf_origin_local" string => "/var/rudder/configuration-repository/ncf"; | |
"uuid" string => "root"; | |
# definition of the machine roles | |
classes: | |
"root_server" expression => "any"; | |
"policy_server" expression => "any"; | |
} | |
############################################ | |
#generate a key if not present | |
bundle agent init_files | |
{ | |
vars: | |
"components" slist => { "cf-agent", "cf-serverd", "cf-execd", "cf-monitord", "cf-promises", "cf-runagent", "cf-key", "cf-hub" }; | |
nova_edition:: | |
"cfengine_install_path" string => "/usr/local"; | |
community_edition:: | |
"cfengine_install_path" string => "/opt/rudder"; | |
classes: | |
"missing_key" not => fileexists("${sys.workdir}/ppkeys/localhost.priv"); | |
files: | |
linux|cygwin:: | |
"${sys.workdir}/bin/${components}" | |
perms => u_p("700"), | |
copy_from => cp("${cfengine_install_path}/bin/${components}","localhost"), | |
action => immediate; | |
commands: | |
cygwin.missing_key:: | |
"${sys.workdir}/bin/cf-key.exe"; | |
windows.missing_key.!cygwin:: | |
"\"${sys.workdir}\bin\cf-key\""; | |
linux.missing_key:: | |
"${sys.workdir}/bin/cf-key"; | |
} | |
body depth_search recurse(d) | |
{ | |
depth => "${d}"; | |
} | |
#perms validation | |
body perms u_p(p) | |
{ | |
mode => "${p}"; | |
} | |
#server may be a list | |
body copy_from cp(from,server) | |
{ | |
servers => { "${server}" }; | |
source => "${from}"; | |
compare => "digest"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
body action immediate | |
{ | |
ifelapsed => "0"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
####################################################### | |
# | |
# Site specific promises | |
# | |
####################################################### | |
bundle common g | |
{ | |
vars: | |
SuSE:: | |
"crontab" string => "/var/spool/cron/tabs/root"; | |
!SuSE:: | |
"crontab" string => "/var/spool/cron/crontabs/root"; | |
windows:: | |
"rudder_base" string => "${sys.winprogdir}\Rudder"; | |
"rudder_bin" string => "${rudder_base}\bin"; | |
"rudder_sbin" string => "${rudder_base}\sbin"; | |
"rudder_var" string => "${sys.winprogdir}\Rudder\var"; | |
"rudder_var_tmp" string => "${rudder_var}\tmp"; # tmp generated data | |
"rudder_base_sbin" string => "${rudder_base}\sbin"; #folder where tools are installed | |
"rudder_inventories" string => "${rudder_var}\inventories"; | |
"rudder_base_sbin_arg" string => "${sys.winprogdir}\Rudder\sbin"; # for the installer command line | |
"rudder_ncf" string => "${rudder_var}\ncf"; | |
# DEPRECATED: This variable is used in pre-2.9 Techniques. | |
"rudder_dependencies" string => "${rudder_sbin}"; | |
windows.!cygwin:: | |
"cfengine_share_directory" string => "c:\opt\hive\cf-served"; | |
"uuid_file" string => "${rudder_base}\uuid.hive"; | |
linux|cygwin:: | |
"rudder_base" string => "/opt/rudder"; | |
"rudder_var" string => "/var/rudder"; | |
"rudder_bin" string => "${rudder_base}/bin"; | |
"rudder_sbin" string => "${rudder_base}/sbin"; | |
"rudder_var_tmp" string => "${rudder_var}/tmp"; # tmp generated data | |
"rudder_base_sbin" string => "${rudder_base}/sbin"; #folder where tools are installed | |
"rudder_inventories" string => "${rudder_var}/inventories"; | |
"uuid_file" string => "${rudder_base}/etc/uuid.hive"; | |
"rudder_ncf" string => "${rudder_var}/ncf"; | |
# DEPRECATED: This variable is used in pre-2.9 Techniques. | |
"rudder_dependencies" string => "${rudder_var}/tools"; | |
any:: | |
"uuid" string => "root"; | |
"server_shares_folder" string => "/var/rudder/share/${uuid}/share"; | |
"rudder_tools" string => "/var/rudder/tools"; | |
"rudder_ncf_origin_common" string => "/usr/share/ncf/tree"; | |
"rudder_ncf_origin_local" string => "/var/rudder/configuration-repository/ncf"; | |
# DEPRECATED: This variable is used in pre-2.9 Techniques. | |
"rudder_dependencies_origin" string => "/var/rudder/tools"; | |
} | |
##################################################################################### | |
# Copyright 2012 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# Rudder Promise Body and Bundle Library | |
# | |
# This library includes standardized bundles and bodies to be used as part of the | |
# "best practices" in the Techniques writing | |
# | |
################################################## | |
# classes body | |
################################################## | |
# | |
# Automatically defines classes bases on a given prefix | |
# The classes are defined based on the romises outcome | |
# | |
body classes rudder_common_classes(prefix) | |
{ | |
promise_kept => { "${prefix}_kept" }; | |
promise_repaired => { "${prefix}_repaired" }; | |
repair_failed => { "${prefix}_failed" , "${prefix}_error" }; | |
repair_denied => { "${prefix}_denied" , "${prefix}_error" }; | |
repair_timeout => { "${prefix}_timeout", "${prefix}_error" }; | |
} | |
################################################## | |
# files bundles | |
################################################## | |
# | |
# Insert the standard Rudder disclaimer into a file | |
# | |
bundle edit_line rudder_common_disclaimer | |
{ | |
insert_lines: | |
"############################################################# | |
### This file is protected by your Rudder infrastructure. ### | |
### Manually editing the file might lead your Rudder ### | |
### infrastructure to change back the server's ### | |
### configuration and/or to raise a compliance alert. ### | |
############################################################# | |
" | |
location => start, | |
insert_type => "preserve_block"; | |
} | |
# | |
# Select files older than X months | |
# | |
body file_select rudder_common_months_old(months) | |
{ | |
mtime => irange(0,ago(0,"${months}",0,0,0,0)); | |
file_result => "mtime"; | |
} | |
# | |
# Select files older than X days | |
# | |
body file_select rudder_common_days_old(days) | |
{ | |
mtime => irange(0,ago(0,0,"${days}",0,0,0)); | |
file_result => "mtime"; | |
} | |
# | |
# Select files older than X hours | |
# | |
body file_select rudder_common_hours_old(hours) | |
{ | |
mtime => irange(0,ago(0,0,0,"${hours}",0,0)); | |
file_result => "mtime"; | |
} | |
# | |
# Select files older than X minutes | |
# | |
body file_select rudder_common_minutes_old(minutes) | |
{ | |
mtime => irange(0,ago(0,0,0,0,"${minutes}",0)); | |
file_result => "mtime"; | |
} | |
################################################ | |
# Reporting bundles | |
################################################ | |
# | |
# Create and send a report to the server | |
# This bundle takes 6 parameters : | |
# technique_name : the name of the technique, human readable | |
# status : the status of the Component, among the following values | |
# result_success | |
# result_error | |
# result_repaired | |
# log_repaired (for logging only) | |
# log_warn (for logging only) | |
# log_info (for logging only) | |
# log_debug (for logging only) | |
# log_trace (for logging only) | |
# identifier : the identifier of the current Rule and Directive | |
# component_name : the name of the component within the Technique | |
# component_key : the value of the component reference variable (or None if undefined) | |
# message : An explanation message understandable by a human | |
# | |
bundle agent rudder_common_report(technique_name, status, identifier, component_name, component_key, message) | |
{ | |
reports: | |
cfengine_3:: | |
"@@${technique_name}@@${status}@@${identifier}@@${component_name}@@${component_key}@@${g.execRun}##${g.uuid}@#${message}"; | |
} | |
# | |
# Automatically create reports based on existing classes starting by | |
# class_prefix (as defined by the body classes rudder_common_classes) | |
# Takes 6 parameters | |
# technique_name : the name of the technique, human readable | |
# class_prefix : the prefix of a set of classes to reporting on (suffixes with "kept", "repaired" or "error") | |
# identifier : the identifier of the current Rule and Directive | |
# component_name : the name of the component within the Technique | |
# component_key : the value of the component reference variable (None if it does not exists) | |
# message_prefix : The begining of an explanation message understandable by a human | |
# | |
bundle agent rudder_common_reports_generic(technique_name, class_prefix, identifier, component_name, component_key, message_prefix) | |
{ | |
methods: | |
"success" | |
usebundle => rudder_common_report("${technique_name}", "result_success", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was correct"), | |
ifvarclass => "${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; | |
"repaired" | |
usebundle => rudder_common_report("${technique_name}", "result_repaired", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was repaired"), | |
ifvarclass => "${class_prefix}_repaired.!${class_prefix}_error"; | |
"error" | |
usebundle => rudder_common_report("${technique_name}", "result_error", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} could not be repaired"), | |
ifvarclass => "${class_prefix}_error"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
########################################################################### | |
# Copyright (C) Cfengine AS | |
# | |
# This program is free software; you can redistribute it and/or modify it | |
# under the terms of the GNU General Public License as published by the | |
# Free Software Foundation; version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# To the extent this program is licensed as part of the Enterprise | |
# versions of Cfengine, the applicable Commerical Open Source License | |
# (COSL) may apply to this file if you as a licensee so wish it. See | |
# included file COSL.txt. | |
########################################################################### | |
# | |
# Cfengine Community Open Promise-Body Library | |
# | |
# This initiative started by Cfengine promotes a | |
# standardized set of names and promise specifications | |
# for template functionality within Cfengine 3. | |
# | |
# The aim is to promote an industry standard for | |
# naming of configuration patterns, leading to a | |
# de facto middleware of standardized syntax. | |
# | |
# Names should be intuitive and parameters should be | |
# minimal to assist readability and comprehensibility. | |
# Contributions to this file are voluntarily given to | |
# the cfengine community, and are moderated by Cfengine. | |
# No liability or warranty for misuse is implied. | |
# | |
# If you add to this file, please try to make the | |
# contributions "self-documenting". Comments made | |
# after the bundle/body statement are retained in | |
# the online docs | |
# | |
# Subversion : $Rev: 71 $ | |
# For Cfengine Core: 3.1.0 | |
################################################### | |
# If you find Cfengine useful, please consider # | |
# purchasing a commercial version of the software.# | |
################################################### | |
################################################### | |
# edit_line bundles | |
################################################### | |
bundle edit_line insert_lines(lines) | |
{ | |
insert_lines: | |
"${lines}" | |
comment => "Append lines if they don't exist"; | |
} | |
## | |
bundle edit_line comment_lines_matching(regex,comment) | |
# Comment lines of a file matching a regex | |
{ | |
replace_patterns: | |
"^(${regex})$" | |
replace_with => comment("${comment}"), | |
comment => "Search and replace string"; | |
} | |
## | |
bundle edit_line uncomment_lines_matching(regex,comment) | |
# Uncomment lines of a file where the regex matches | |
# the text after the comment string | |
{ | |
replace_patterns: | |
"^${comment}\s?(${regex})$" | |
replace_with => uncomment, | |
comment => "Uncomment lines matching a regular expression"; | |
} | |
## | |
bundle edit_line comment_lines_containing(regex,comment) | |
# Comment lines of a file containing a regex | |
{ | |
replace_patterns: | |
"^(.*${regex}.*)$" | |
replace_with => comment("${comment}"), | |
comment => "Comment out lines in a file"; | |
} | |
## | |
bundle edit_line uncomment_lines_containing(regex,comment) | |
# Uncomment lines of a file where the regex matches | |
# the text after the comment string | |
{ | |
replace_patterns: | |
"^${comment}\s?(.*${regex}.*)$" | |
replace_with => uncomment, | |
comment => "Uncomment a line containing a fragment"; | |
} | |
## | |
bundle edit_line delete_lines_matching(regex) | |
{ | |
delete_lines: | |
"${regex}" | |
comment => "Delete lines matching regular expressions"; | |
} | |
## | |
bundle edit_line warn_lines_matching(regex) | |
{ | |
delete_lines: | |
"${regex}" | |
comment => "Warn about lines in a file", | |
action => warn_only; | |
} | |
## | |
bundle edit_line append_if_no_line(str) | |
{ | |
insert_lines: | |
"${str}" | |
comment => "Append a line to the file if it doesn't already exist"; | |
} | |
## | |
bundle edit_line append_if_no_lines(list) | |
{ | |
insert_lines: | |
"${list}" | |
comment => "Append lines to the file if they don't already exist"; | |
} | |
## | |
bundle edit_line resolvconf(search,list) | |
# search is the search domains with space | |
# list is an slist of nameserver addresses | |
{ | |
delete_lines: | |
"search.*" comment => "Reset search lines from resolver"; | |
"nameserver.*" comment => "Reset nameservers in resolver"; | |
insert_lines: | |
"search ${search}" comment => "Add search domains to resolver"; | |
"nameserver ${list}" comment => "Add name servers to resolver"; | |
} | |
## | |
bundle edit_line set_variable_values(v) | |
# Sets the RHS of variables in the file of the form | |
# LHS = RHS | |
# Adds a new line if no LHS exists, repairs RHS values if one does exist | |
# | |
# To use: | |
# 1) Define an array, where the keys are the LHS and the values are the RHS | |
# "stuff[lhs-1]" string => "rhs1"; | |
# "stuff[lhs-2]" string => "rhs2"; | |
# 2) The parameter passed to the edit_line promise is the fully qualified | |
# name of the array (i.e., "bundlename.stuff") WITHOUT any "$" or "@" | |
{ | |
vars: | |
"index" slist => getindices("${v}"); | |
# Be careful if the index string contains funny chars | |
"cindex[${index}]" string => canonify("${index}"); | |
field_edits: | |
# match a line starting like the key = something | |
"\s*${index}\s*=.*" | |
edit_field => col("=","2","$(${v}[${index}])","set"), | |
classes => if_ok("$(cindex[${index}])_in_file"), | |
comment => "Match a line starting like key = something"; | |
insert_lines: | |
"${index}=$(${v}[${index}])", | |
comment => "Insert a variable definition", | |
ifvarclass => "!$(cindex[${index}])_in_file"; | |
} | |
## | |
bundle edit_line append_users_starting(v) | |
# For adding to /etc/passwd or etc/shadow, needs | |
# an array v[username] string => "line..." | |
{ | |
vars: | |
"index" slist => getindices("${v}"); | |
classes: | |
"add_${index}" not => userexists("${index}"); | |
insert_lines: | |
"$(${v}[${index}])", | |
comment => "Append users into a password file format", | |
ifvarclass => "add_${index}"; | |
} | |
## | |
bundle edit_line append_groups_starting(v) | |
# For adding groups to /etc/group, needs | |
# an array v[groupname] string => "line..." | |
{ | |
vars: | |
"index" slist => getindices("${v}"); | |
classes: | |
"add_${index}" not => groupexists("${index}"); | |
insert_lines: | |
"$(${v}[${index}])", | |
comment => "Append users into a group file format", | |
ifvarclass => "add_${index}"; | |
} | |
## | |
bundle edit_line set_user_field(user,field,val) | |
# Set the value of field number "field" in | |
# a :-field formatted file like /etc/passwd | |
{ | |
field_edits: | |
"${user}:.*" | |
comment => "Edit a user attribute in the password file", | |
edit_field => col(":","${field}","${val}","set"); | |
} | |
## | |
bundle edit_line append_user_field(group,field,allusers) | |
# For adding users to to a file like /etc/group | |
# at field position "field", comma separated subfields | |
{ | |
vars: | |
"val" slist => { @{allusers} }; | |
field_edits: | |
"${group}:.*" | |
comment => "Append users into a password file format", | |
edit_field => col(":","${field}","${val}","alphanum"); | |
} | |
## | |
bundle edit_line expand_template(templatefile) | |
# Read in the named text file and expand ${var} | |
# inside the file | |
{ | |
insert_lines: | |
"${templatefile}" | |
insert_type => "file", | |
comment => "Expand variables in the template file", | |
expand_scalars => "true"; | |
} | |
## | |
bundle agent cronjob(commands,user,hours,mins) | |
# For adding lines to crontab for a user | |
# methods: | |
# "cron" usebundle => cronjob("/bin/ls","mark","*","5,10"); | |
{ | |
vars: | |
SuSE:: | |
"crontab" string => "/var/spool/cron/tabs"; | |
!SuSE:: | |
"crontab" string => "/var/spool/cron/crontabs"; | |
files: | |
"${crontab}/${user}" | |
comment => "A user's regular batch jobs are added to this file", | |
create => "true", | |
edit_line => append_if_no_line("${mins} ${hours} * * * ${commands}"), | |
perms => mo("644","${user}"); | |
processes: | |
"cron" | |
comment => "Most crons need to be huped after file changes", | |
signals => { "hup" }; | |
} | |
## | |
## editing bodies | |
## | |
body edit_field quoted_var(newval,method) | |
{ | |
field_separator => "\""; | |
select_field => "2"; | |
value_separator => " "; | |
field_value => "${newval}"; | |
field_operation => "${method}"; | |
extend_fields => "false"; | |
allow_blank_fields => "true"; | |
} | |
## | |
body edit_field col(split,col,newval,method) | |
{ | |
field_separator => "${split}"; | |
select_field => "${col}"; | |
value_separator => ","; | |
field_value => "${newval}"; | |
field_operation => "${method}"; | |
extend_fields => "true"; | |
allow_blank_fields => "true"; | |
} | |
## | |
body replace_with value(x) | |
{ | |
replace_value => "${x}"; | |
occurrences => "all"; | |
} | |
## | |
body select_region INI_section(x) | |
{ | |
select_start => "\[${x}\]\s*"; | |
select_end => "\[.*\]\s*"; | |
} | |
## | |
## edit_defaults | |
## | |
body edit_defaults std_defs | |
{ | |
empty_file_before_editing => "false"; | |
edit_backup => "false"; | |
max_file_size => "300000"; | |
} | |
## | |
body edit_defaults empty | |
{ | |
empty_file_before_editing => "true"; | |
edit_backup => "false"; | |
max_file_size => "300000"; | |
} | |
## | |
## location | |
## | |
body location start | |
{ | |
before_after => "before"; | |
} | |
## | |
body location after(str) | |
{ | |
before_after => "after"; | |
select_line_matching => "${str}"; | |
} | |
## | |
## replace_with | |
## | |
## | |
body replace_with comment(c) | |
{ | |
replace_value => "${c} $(match.1)"; | |
occurrences => "all"; | |
} | |
## | |
body replace_with uncomment | |
{ | |
replace_value => "$(match.1)"; | |
occurrences => "all"; | |
} | |
#################################################### | |
## agent bodyparts | |
#################################################### | |
## | |
## action | |
## | |
body action if_elapsed(x) | |
{ | |
ifelapsed => "${x}"; | |
expireafter => "${x}"; | |
} | |
## | |
body action measure_performance(x) | |
{ | |
measurement_class => "Detect changes in ${this.promiser}"; | |
ifelapsed => "${x}"; | |
expireafter => "${x}"; | |
} | |
## | |
body action warn_only | |
{ | |
action_policy => "warn"; | |
ifelapsed => "60"; | |
} | |
## | |
body action bg(elapsed,expire) | |
{ | |
ifelapsed => "${elapsed}"; | |
expireafter => "${expire}"; | |
background => "true"; | |
} | |
## | |
body action ifwin_bg | |
{ | |
windows:: | |
background => "true"; | |
} | |
## | |
body action immediate | |
{ | |
ifelapsed => "0"; | |
} | |
## | |
body action policy(p) | |
{ | |
action_policy => "${p}"; | |
} | |
## | |
# Log a message to log=[/file|stdout] | |
body action log_repaired(log,message) | |
{ | |
log_string => "${sys.date}, ${message}"; | |
log_repaired => "${log}"; | |
} | |
## | |
## contain | |
## | |
body contain silent | |
{ | |
no_output => "true"; | |
} | |
## | |
body contain in_dir(s) | |
{ | |
chdir => "${s}"; | |
} | |
## | |
body contain in_dir_shell(s) | |
{ | |
chdir => "${s}"; | |
useshell => "true"; | |
} | |
## | |
body contain silent_in_dir(s) | |
{ | |
chdir => "${s}"; | |
no_output => "true"; | |
} | |
## | |
body contain in_shell | |
{ | |
useshell => "true"; | |
} | |
## | |
body contain setuid(x) | |
{ | |
exec_owner => "${x}"; | |
useshell => "false"; | |
} | |
## | |
body contain setuid_sh(x) | |
{ | |
exec_owner => "${x}"; | |
useshell => "true"; | |
} | |
## | |
body contain setuidgid_sh(owner,group) | |
{ | |
exec_owner => "${owner}"; | |
exec_group => "${group}"; | |
useshell => "true"; | |
} | |
## | |
body contain jail(owner,root,dir) | |
{ | |
exec_owner => "${owner}"; | |
useshell => "true"; | |
chdir => "${dir}"; | |
chroot => "${root}"; | |
} | |
## | |
## classes | |
## | |
body classes if_repaired(x) | |
{ | |
promise_repaired => { "${x}" }; | |
} | |
## | |
body classes if_else(yes,no) | |
{ | |
promise_kept => { "${yes}" }; | |
promise_repaired => { "${yes}" }; | |
repair_failed => { "${no}" }; | |
repair_denied => { "${no}" }; | |
repair_timeout => { "${no}" }; | |
} | |
## | |
body classes cf2_if_else(yes,no) | |
# meant to match cf2 semantics | |
{ | |
promise_repaired => { "${yes}" }; | |
repair_failed => { "${no}" }; | |
repair_denied => { "${no}" }; | |
repair_timeout => { "${no}" }; | |
} | |
## | |
body classes if_notkept(x) | |
{ | |
repair_failed => { "${x}" }; | |
repair_denied => { "${x}" }; | |
repair_timeout => { "${x}" }; | |
} | |
## | |
body classes if_ok(x) | |
{ | |
promise_repaired => { "${x}" }; | |
promise_kept => { "${x}" }; | |
} | |
## | |
## Persistent classes | |
## | |
body classes state_repaired(x) | |
{ | |
promise_repaired => { "${x}" }; | |
persist_time => "10"; | |
} | |
## | |
body classes enumerate(x) | |
# | |
# This is used by commercial editions to count | |
# instances of jobs in a cluster | |
# | |
{ | |
promise_repaired => { "mXC_${x}" }; | |
promise_kept => { "mXC_${x}" }; | |
persist_time => "15"; | |
} | |
################################################### | |
# agent bundles | |
################################################### | |
##.................................................. | |
## files promises | |
##.................................................. | |
## | |
## copy_from | |
## | |
body copy_from secure_cp(from,server) | |
{ | |
source => "${from}"; | |
servers => { "${server}" }; | |
compare => "digest"; | |
encrypt => "true"; | |
verify => "true"; | |
} | |
## | |
body copy_from remote_cp(from,server) | |
{ | |
servers => { "${server}" }; | |
source => "${from}"; | |
compare => "mtime"; | |
} | |
## | |
body copy_from local_cp(from) | |
{ | |
source => "${from}"; | |
} | |
## | |
body copy_from perms_cp(from) | |
{ | |
source => "${from}"; | |
preserve => "true"; | |
} | |
## | |
# Copy only if the file does not already exist, i.e. seed the placement | |
body copy_from seed_cp(from) | |
{ | |
source => "${from}"; | |
compare => "exists"; | |
} | |
## | |
body copy_from sync_cp(from,server) | |
{ | |
servers => { "${server}" }; | |
source => "${from}"; | |
purge => "true"; | |
preserve => "true"; | |
} | |
## | |
body copy_from no_backup_cp(from) | |
{ | |
source => "${from}"; | |
copy_backup => "false"; | |
} | |
## | |
body copy_from no_backup_rcp(from,server) | |
{ | |
servers => { "${server}" }; | |
source => "${from}"; | |
compare => "mtime"; | |
copy_backup => "false"; | |
} | |
## | |
## link_from | |
## | |
body link_from ln_s(x) | |
{ | |
link_type => "symlink"; | |
source => "${x}"; | |
when_no_source => "force"; | |
} | |
## | |
body link_from linkchildren(tofile) | |
{ | |
source => "${tofile}"; | |
link_type => "symlink"; | |
when_no_source => "force"; | |
link_children => "true"; | |
when_linking_children => "if_no_such_file"; # "override_file"; | |
} | |
## | |
## perms | |
## | |
body perms m(mode) | |
{ | |
mode => "${mode}"; | |
} | |
## | |
body perms mo(mode,user) | |
{ | |
owners => { "${user}" }; | |
mode => "${mode}"; | |
} | |
## | |
body perms mog(mode,user,group) | |
{ | |
owners => { "${user}" }; | |
groups => { "${group}" }; | |
mode => "${mode}"; | |
} | |
## | |
body perms og(u,g) | |
{ | |
owners => { "${u}" }; | |
groups => { "${g}" }; | |
} | |
## | |
body perms owner(user) | |
{ | |
owners => { "${user}" }; | |
} | |
## | |
## ACLS (extended Unix perms) | |
## | |
body acl access_generic(acl) | |
# default/inherited ACLs are left unchanged, | |
# applicable for both files and directory on all platforms | |
{ | |
acl_method => "overwrite"; | |
aces => { "@{acl}" }; | |
} | |
## | |
body acl strict | |
# NOTE: May need to take ownership of file/dir | |
# to be sure no-one else is allowed access | |
{ | |
acl_method => "overwrite"; | |
windows:: | |
aces => { "user:Administrator:rwx" }; | |
!windows:: | |
aces => { "user:root:rwx" }; | |
} | |
## | |
## depth_search | |
## | |
body depth_search recurse(d) | |
{ | |
depth => "${d}"; | |
xdev => "true"; | |
} | |
## | |
body depth_search recurse_ignore(d,list) | |
{ | |
depth => "${d}"; | |
exclude_dirs => { @{list} }; | |
} | |
## | |
## delete | |
## | |
body delete tidy | |
{ | |
dirlinks => "delete"; | |
rmdirs => "true"; | |
} | |
## | |
## rename | |
## | |
body rename disable | |
{ | |
disable => "true"; | |
} | |
## | |
body rename rotate(level) | |
{ | |
rotate => "${level}"; | |
} | |
## | |
body rename to(file) | |
{ | |
newname => "${file}"; | |
} | |
## | |
## file_select | |
## | |
body file_select name_age(name,days) | |
{ | |
leaf_name => { "${name}" }; | |
mtime => irange(0,ago(0,0,"${days}",0,0,0)); | |
file_result => "mtime.leaf_name"; | |
} | |
## | |
body file_select days_old(days) | |
{ | |
mtime => irange(0,ago(0,0,"${days}",0,0,0)); | |
file_result => "mtime"; | |
} | |
## | |
body file_select size_range(from,to) | |
{ | |
search_size => irange("${from}","${to}"); | |
file_result => "size"; | |
} | |
## | |
body file_select exclude(name) | |
{ | |
leaf_name => { "${name}"}; | |
file_result => "!leaf_name"; | |
} | |
## | |
body file_select plain | |
{ | |
file_types => { "plain" }; | |
file_result => "file_types"; | |
} | |
body file_select dirs | |
{ | |
file_types => { "dir" }; | |
file_result => "file_types"; | |
} | |
## | |
body file_select by_name(names) | |
{ | |
leaf_name => { @{names}}; | |
file_result => "leaf_name"; | |
} | |
## | |
body file_select ex_list(names) | |
{ | |
leaf_name => { @{names}}; | |
file_result => "!leaf_name"; | |
} | |
## | |
## changes | |
## | |
body changes detect_all_change | |
# This is fierce, and will cost disk cycles | |
{ | |
hash => "best"; | |
report_changes => "all"; | |
update_hashes => "yes"; | |
} | |
## | |
body changes detect_content | |
# This is a cheaper alternative | |
{ | |
hash => "md5"; | |
report_changes => "content"; | |
update_hashes => "yes"; | |
} | |
## | |
body changes noupdate | |
# Use on (small) files that should never change | |
{ | |
hash => "sha256"; | |
report_changes => "content"; | |
update_hashes => "no"; | |
} | |
## | |
body changes diff | |
# Generates diff report (Nova and above) | |
{ | |
hash => "sha256"; | |
report_changes => "content"; | |
report_diffs => "true"; | |
update_hashes => "yes"; | |
} | |
##-------------------------------------------------------------- | |
## Packages promises | |
##-------------------------------------------------------------- | |
body package_method zypper | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; | |
package_patch_list_command => "/usr/bin/zypper patches"; | |
package_installed_regex => "i.*"; | |
package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_patch_installed_regex => ".*Installed.*|.*Not Applicable.*"; | |
package_patch_name_regex => "[^|]+\|\s+([^\s]+).*"; | |
package_patch_version_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_name_convention => "${name}"; | |
package_add_command => "/usr/bin/zypper --non-interactive install"; | |
package_delete_command => "/usr/bin/zypper --non-interactive remove --force-resolution"; | |
package_update_command => "/usr/bin/zypper --non-interactive update"; | |
package_patch_command => "/usr/bin/zypper --non-interactive patch$"; # $ means no args | |
package_verify_command => "/usr/bin/zypper --non-interactive verify$"; | |
} | |
## | |
body package_method apt | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/dpkg -l"; | |
package_list_name_regex => "ii\s+([^\s]+).*"; | |
package_list_version_regex => "ii\s+[^\s]+\s+([^\s]+).*"; | |
package_installed_regex => ".*"; # all reported are installed | |
package_name_convention => "${name}"; | |
package_list_update_ifelapsed => "240"; # 4 hours | |
have_aptitude:: | |
package_add_command => "/usr/bin/aptitude --assume-yes install"; | |
package_list_update_command => "/usr/bin/aptitude update"; | |
package_delete_command => "/usr/bin/aptitude --assume-yes remove"; | |
package_update_command => "/usr/bin/aptitude --assume-yes install"; | |
package_verify_command => "/usr/bin/aptitude show"; | |
package_noverify_regex => "(State: not installed|E: Unable to locate package .*)"; | |
!have_aptitude:: | |
package_add_command => "/usr/bin/apt-get --yes install"; | |
package_list_update_command => "/usr/bin/apt-get update"; | |
package_delete_command => "/usr/bin/apt-get --yes remove"; | |
package_update_command => "/usr/bin/apt-get --yes install"; | |
package_verify_command => "/usr/bin/dpkg -s"; | |
package_noverify_returncode => "1"; | |
} | |
## | |
body package_method rpm_version(repo) | |
{ | |
package_changes => "individual"; | |
package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version} | %{arch}\n\""; | |
package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s|]+).*"; | |
package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s|]+).*"; | |
package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_installed_regex => "i.*"; | |
package_file_repositories => { "${repo}" }; | |
package_name_convention => "${name}-${version}-${arch}.rpm"; | |
package_add_command => "/bin/rpm -ivh "; | |
package_delete_command => "/bin/rpm -e --nodeps"; | |
package_verify_command => "/bin/rpm -V"; | |
package_update_command => "/bin/rpm -Uvh "; | |
package_noverify_regex => ".*[^\s].*"; | |
} | |
## | |
body package_method msi_implicit(repo) | |
# Use whole file name as promiser, e.g. "7-Zip-4.50-x86_64.msi", | |
# the name, version and arch is then deduced from the promiser | |
{ | |
package_changes => "individual"; | |
package_file_repositories => { "${repo}" }; | |
package_installed_regex => ".*"; | |
package_name_convention => "${name}-${version}-${arch}.msi"; | |
package_delete_convention => "${firstrepo}${name}-${version}-${arch}.msi"; | |
package_name_regex => "^(\S+)-(\d+\.?)+"; | |
package_version_regex => "^\S+-((\d+\.?)+)"; | |
package_arch_regex => "^\S+-[\d\.]+-(.*).msi"; | |
package_add_command => "\"${sys.winsysdir}\msiexec.exe\" /qn /i"; | |
package_update_command => "\"${sys.winsysdir}\msiexec.exe\" /qn /i"; | |
package_delete_command => "\"${sys.winsysdir}\msiexec.exe\" /qn /x"; | |
} | |
## | |
body package_method msi_explicit(repo) | |
# use software name as promiser, e.g. "7-Zip", and explicitly | |
# specify any package_version and package_arch | |
{ | |
package_changes => "individual"; | |
package_file_repositories => { "${repo}" }; | |
package_installed_regex => ".*"; | |
package_name_convention => "${name}-${version}-${arch}.msi"; | |
package_delete_convention => "${firstrepo}${name}-${version}-${arch}.msi"; | |
package_add_command => "\"${sys.winsysdir}\msiexec.exe\" /qn /i"; | |
package_update_command => "\"${sys.winsysdir}\msiexec.exe\" /qn /i"; | |
package_delete_command => "\"${sys.winsysdir}\msiexec.exe\" /qn /x"; | |
} | |
## | |
body package_method yum | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/yum list installed"; | |
package_patch_list_command => "/usr/bin/yum check-update"; | |
# Remember to escape special characters like | | |
package_list_name_regex => "([^.]+).*"; | |
package_list_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_list_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_installed_regex => ".*installed.*"; | |
package_name_convention => "${name}.${arch}"; | |
package_delete_convention => "${name}"; | |
package_list_update_ifelapsed => "240"; | |
package_patch_installed_regex => ""; | |
package_patch_name_regex => "([^.]+).*"; | |
package_patch_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_patch_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_add_command => "/usr/bin/yum -y install"; | |
package_delete_command => "/bin/rpm -e"; | |
package_verify_command => "/bin/rpm -V"; | |
} | |
## | |
body package_method yum_rpm | |
# Contributed by Trond Hasle Amundsen | |
# More efficient package method for RedHat - uses rpm to list instead of yum | |
# Notes: | |
# - using ${name}.${arch} instead of ${name} for package_name_convention | |
# causes uninstallation to fail. | |
# - using allmatches to remove for all architectures | |
# | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'"; | |
package_patch_list_command => "/usr/bin/yum check-update"; | |
package_list_name_regex => "^(\S+?)\s\S+?\s\S+$"; | |
package_list_version_regex => "^\S+?\s(\S+?)\s\S+$"; | |
package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$"; | |
package_installed_regex => ".*"; | |
package_name_convention => "${name}"; | |
package_patch_installed_regex => ""; | |
package_patch_name_regex => "([^.]+).*"; | |
package_patch_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_patch_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_add_command => "/usr/bin/yum -y install"; | |
package_update_command => "/usr/bin/yum -y update"; | |
package_delete_command => "/bin/rpm -e --allmatches"; | |
package_verify_command => "/bin/rpm -V"; | |
} | |
## | |
# The solaris package system is poorly designed, with too many different | |
# names to track. See the example in tests/units/unit_package_solaris.cf | |
# to see how to use this | |
body package_method solaris (pkgname, spoolfile, adminfile) | |
{ | |
package_changes => "individual"; | |
package_list_command => "/usr/bin/pkginfo -l"; | |
package_multiline_start => "\s*PKGINST:\s+[^\s]+"; | |
package_list_name_regex => "\s*PKGINST:\s+([^\s]+)"; | |
package_list_version_regex => "\s*VERSION:\s+([^\s]+)"; | |
package_list_arch_regex => "\s*ARCH:\s+([^\s]+)"; | |
package_installed_regex => "\s*STATUS:\s*(completely|partially)\s+installed.*"; | |
package_name_convention => "${name}"; | |
package_add_command => "/usr/sbin/pkgadd -n -a /tmp/${adminfile} -d /tmp/${spoolfile}"; | |
package_delete_command => "/usr/sbin/pkgrm -n -a /tmp/${adminfile}"; | |
} | |
## | |
body package_method freebsd | |
{ | |
package_changes => "individual"; | |
# Could use rpm for this | |
package_list_command => "/usr/sbin/pkg_info"; | |
# Remember to escape special characters like | | |
package_list_name_regex => "([^-]+).*"; | |
package_list_version_regex => "[^-]+-([^\s]+).*"; | |
package_name_regex => "([^-]+).*"; | |
package_version_regex => "[^-]+-([^\s]+).*"; | |
package_installed_regex => ".*"; | |
package_name_convention => "${name}-${version}"; | |
package_add_command => "/usr/sbin/pkg_add -r"; | |
package_delete_command => "/usr/sbin/pkg_delete"; | |
} | |
## | |
# Single bundle for all the similar managers simplifies promises | |
body package_method generic | |
{ | |
SuSE:: | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; | |
package_patch_list_command => "/usr/bin/zypper patches"; | |
package_installed_regex => "i.*"; | |
package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_patch_installed_regex => ".*Installed.*|.*Not Applicable.*"; | |
package_patch_name_regex => "[^|]+\|\s+([^\s]+).*"; | |
package_patch_version_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_name_convention => "${name}"; | |
package_add_command => "/usr/bin/zypper --non-interactive install"; | |
package_delete_command => "/usr/bin/zypper --non-interactive remove --force-resolution"; | |
package_update_command => "/usr/bin/zypper --non-interactive update"; | |
package_patch_command => "/usr/bin/zypper --non-interactive patch$"; # $ means no args | |
package_verify_command => "/usr/bin/zypper --non-interactive verify$"; | |
redhat:: | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; | |
package_patch_list_command => "/usr/bin/yum check-update"; | |
package_installed_regex => "i.*"; | |
package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_name_convention => "${name}"; | |
package_list_update_ifelapsed => "240"; | |
package_patch_installed_regex => ""; | |
package_patch_name_regex => "([^.]+).*"; | |
package_patch_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_patch_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_add_command => "/usr/bin/yum -y install"; | |
package_delete_command => "/bin/rpm -e"; | |
package_verify_command => "/bin/rpm -V"; | |
debian:: | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/dpkg -l"; | |
package_list_name_regex => "ii\s+([^\s]+).*"; | |
package_list_version_regex => "ii\s+[^\s]+\s+([^\s]+).*"; | |
package_installed_regex => ".*"; # all reported are installed | |
package_name_convention => "${name}"; | |
package_list_update_ifelapsed => "240"; # 4 hours | |
debian.have_aptitude:: | |
package_add_command => "/usr/bin/aptitude --assume-yes install"; | |
package_list_update_command => "/usr/bin/aptitude update"; | |
package_delete_command => "/usr/bin/aptitude --assume-yes remove"; | |
package_update_command => "/usr/bin/aptitude --assume-yes install"; | |
package_verify_command => "/usr/bin/aptitude show"; | |
package_noverify_regex => "(State: not installed|E: Unable to locate package .*)"; | |
debian.!have_aptitude:: | |
package_add_command => "/usr/bin/apt-get --yes install"; | |
package_list_update_command => "/usr/bin/apt-get update"; | |
package_delete_command => "/usr/bin/apt-get --yes remove"; | |
package_update_command => "/usr/bin/apt-get --yes install"; | |
package_verify_command => "/usr/bin/dpkg -s"; | |
package_noverify_returncode => "1"; | |
freebsd:: | |
package_changes => "individual"; | |
package_list_command => "/usr/sbin/pkg_info"; | |
package_list_name_regex => "([^-]+).*"; | |
package_list_version_regex => "[^-]+-([^\s]+).*"; | |
package_name_regex => "([^-]+).*"; | |
package_version_regex => "[^-]+-([^\s]+).*"; | |
package_installed_regex => ".*"; | |
package_name_convention => "${name}-${version}"; | |
package_add_command => "/usr/sbin/pkg_add -r"; | |
package_delete_command => "/usr/sbin/pkg_delete"; | |
} | |
##------------------------------------------------------- | |
## storage promises | |
##------------------------------------------------------- | |
body volume min_free_space(free) | |
{ | |
check_foreign => "false"; | |
freespace => "${free}"; | |
sensible_size => "10000"; | |
sensible_count => "2"; | |
} | |
## | |
body mount nfs(server,source) | |
{ | |
mount_type => "nfs"; | |
mount_source => "${source}"; | |
mount_server => "${server}"; | |
edit_fstab => "true"; | |
} | |
## | |
body mount nfs_p(server,source,perm) | |
{ | |
mount_type => "nfs"; | |
mount_source => "${source}"; | |
mount_server => "${server}"; | |
mount_options => {"${perm}"}; | |
edit_fstab => "true"; | |
} | |
## | |
body mount unmount | |
{ | |
mount_type => "nfs"; | |
edit_fstab => "true"; | |
unmount => "true"; | |
} | |
##------------------------------------------------------- | |
## process promises | |
##------------------------------------------------------- | |
body process_select exclude_procs(x) | |
{ | |
command => "${x}"; | |
process_result => "!command"; | |
} | |
## | |
body process_count check_range(name,lower,upper) | |
{ | |
match_range => irange("${lower}","${upper}"); | |
out_of_range_define => { "${name}_out_of_range" }; | |
} | |
## | |
## service promises | |
## | |
body service_method bootstart | |
{ | |
service_autostart_policy => "boot_time"; | |
service_dependence_chain => "start_parent_services"; | |
windows:: | |
service_type => "windows"; | |
} | |
## | |
body service_method force_deps | |
{ | |
service_dependence_chain => "all_related"; | |
windows:: | |
service_type => "windows"; | |
} | |
#################################################### | |
## monitor bodyparts | |
#################################################### | |
body match_value scan_log(line) | |
{ | |
select_line_matching => "${line}"; | |
track_growing_file => "true"; | |
} | |
## | |
body action sample_rate(x) | |
{ | |
ifelapsed => "${x}"; | |
expireafter => "10"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# This our core-library of common | |
# function. That's our knowledge ! | |
# | |
# Just bodies and editbundles here | |
# | |
############################################ | |
body depth_search recurse_visible(d) | |
{ | |
depth => "${d}"; | |
exclude_dirs => { "\..*" }; | |
} | |
#perms validation | |
body perms u_p(p) | |
{ | |
mode => "${p}"; | |
} | |
######################################################### | |
#server may be a list | |
body copy_from cp(from,server) | |
{ | |
servers => { "${server}" }; | |
source => "${from}"; | |
compare => "digest"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
body copy_from scp(from, server,trustkey,preserve,purge) | |
{ | |
servers => { "${server}" }; | |
source => "${from}"; | |
compare => "digest"; | |
encrypt => "true"; | |
verify => "true"; | |
trustkey => "${trustkey}"; | |
preserve => "${preserve}"; #preserver permissions | |
purge => "${purge}"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
# This is an evolved version of copy_from scp that uses local copies if we are | |
# running on a policy server instead of copying from a localhost remote blindly. | |
body copy_from rudder_copy_from(from, server,compare,trustkey,preserve,purge) { | |
source => "$(from)"; | |
compare => "$(compare)"; | |
encrypt => "true"; | |
verify => "true"; | |
trustkey => "${trustkey}"; | |
preserve => "${preserve}"; # Preserve the permissions | |
purge => "${purge}"; | |
copy_backup => "timestamp"; | |
!root_server:: | |
servers => { "${server}" }; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
body copy_from copy(from) { | |
source => "$(from)"; | |
copy_backup => "false"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
body copy_from copy(from) | |
{ | |
source => "${from}"; | |
copy_backup => "false"; | |
preserve => "true"; | |
} | |
body copy_from copy_digest(from) | |
{ | |
source => "${from}"; | |
copy_backup => "timestamp"; | |
preserve => "true"; | |
compare => "digest"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# Just bodies and editbundles here | |
# | |
############################################ | |
#perms validation | |
body perms p(user,mode) | |
{ | |
owners => { "${user}" }; | |
mode => "${mode}"; | |
} | |
############################################ | |
body file_select cf3_files | |
{ | |
leaf_name => { "cf-.*" }; | |
file_result => "leaf_name"; | |
} | |
######################################################### | |
body changes lay_trip_wire | |
{ | |
hash => "best"; | |
report_changes => "content"; | |
update_hashes => "yes"; | |
} | |
######################################################## | |
body action longjob | |
{ | |
ifelapsed => "240"; # run only every 4 hours | |
} | |
####################################################### | |
# For the library | |
####################################################### | |
body edit_defaults noempty_backup | |
{ | |
empty_file_before_editing => "false"; | |
edit_backup => "timestamp"; # we want to keep a track of everything | |
max_file_size => "1024000"; | |
} | |
body edit_defaults empty_backup | |
{ | |
empty_file_before_editing => "true"; | |
edit_backup => "timestamp"; | |
max_file_size => "1024000"; | |
} | |
body edit_defaults def_no_backup | |
{ | |
empty_file_before_editing => "false"; | |
edit_backup => "false"; | |
max_file_size => "1024000"; | |
} | |
######################################################## | |
######################################################## | |
bundle edit_line DeleteLinesMatching(regex) | |
{ | |
delete_lines: | |
"${regex}", | |
action => WarnOnly; | |
} | |
######################################################## | |
body action WarnOnly | |
{ | |
action_policy => "warn"; | |
ifelapsed => "60"; | |
} | |
######################################## | |
# Bodies | |
######################################## | |
body replace_with With(x) | |
{ | |
replace_value => "${x}"; | |
occurrences => "all"; | |
} | |
######################################## | |
################################ | |
# For commands with a > | |
################################ | |
body contain outputable | |
{ | |
useshell => "true"; | |
no_output=> "false"; | |
} | |
################################ | |
# Process is launched ? | |
################################ | |
body process_count islaunched(class) | |
{ | |
match_range => irange("1", "500"); | |
in_range_define => { "${class}"}; | |
out_of_range_define => {"no_${class}"}; | |
} | |
########################################################################################### | |
# Persistent class | |
# If the promise is repaired, define repaired for length minutes and undefine failed | |
# If the promise is not kept, undefine repaired and define failed for length minutes | |
########################################################################################## | |
body classes persistant_class(repaired, failed, length) | |
{ | |
promise_repaired => { "${repaired}" }; | |
repair_failed => { "${failed}" }; | |
repair_denied => { "${failed}" }; | |
repair_timeout => { "${failed}" }; | |
cancel_repaired => {"${failed}"}; | |
cancel_notkept => {"${repaired}"}; | |
persist_time => "${length}"; | |
} | |
########################################################################################### | |
# Persistent class | |
# If the promise is repaired/kept, define repaired for length minutes and undefine failed | |
# If the promise is not kept, undefine repaired and define failed for length minutes | |
########################################################################################## | |
body classes set_persist_classes(repaired, failed, length) | |
{ | |
promise_kept => { "${repaired}" }; | |
promise_repaired => { "${repaired}" }; | |
repair_failed => { "${failed}" }; | |
repair_denied => { "${failed}" }; | |
repair_timeout => { "${failed}" }; | |
cancel_kept => {"${failed}"}; | |
cancel_repaired => {"${failed}"}; | |
cancel_notkept => {"${repaired}"}; | |
persist_time => "${length}"; | |
} | |
################################################ | |
# kept_if_else | |
# set kept if the promise is kept | |
# yes if repaired | |
# no if cannot repair | |
################################################ | |
body classes kept_if_else(kept, yes,no) | |
{ | |
promise_kept => { "${kept}" }; | |
promise_repaired => { "${yes}" }; | |
repair_failed => { "${no}" }; | |
repair_denied => { "${no}" }; | |
repair_timeout => { "${no}" }; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# Define what an agent has to do when it updates | |
# its promises | |
# | |
#simple copy method | |
body copy_from remote(server, path) | |
{ | |
servers => { | |
"${server}" | |
}; | |
encrypt => "true"; | |
trustkey => "true"; | |
source => "${path}"; | |
compare => "digest"; | |
preserve => "true"; #preserver permissions | |
verify => "true"; | |
purge => "false"; | |
owners => {"root"}; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
bundle common server_info | |
{ | |
vars: | |
any:: | |
"cfserved" string => "%%POLICY_SERVER_HOSTNAME%%"; | |
"policy_files" string => "/var/rudder/share/root"; #directory where to look for promises in the server for that client | |
} | |
bundle agent update | |
{ | |
vars: | |
"client_inputs" string => "${sys.workdir}/inputs"; #where to put the files on the client when downloaded | |
nova_edition:: | |
"server_inputs" string => "${server_info.policy_files}/rules/cfengine-nova"; #actual directory with promises | |
community_edition:: | |
"server_inputs" string => "${server_info.policy_files}/rules/cfengine-community"; #actual directory with promises | |
files: | |
any:: | |
"${g.rudder_ncf}/." | |
create => "true", | |
comment => "Make sure the ncf directory exists"; | |
"${g.rudder_ncf}/common" | |
copy_from => remote("${server_info.cfserved}", "${g.rudder_ncf_origin_common}"), | |
depth_search => recurse("inf"), | |
action => immediate, | |
classes => success("rudder_ncf_common_updated", "rudder_ncf_common_update_error", "rudder_ncf_common_updated_ok"), | |
comment => "Update the common Rudder ncf instance"; | |
"${g.rudder_ncf}/local" | |
copy_from => remote("${server_info.cfserved}", "${g.rudder_ncf_origin_local}"), | |
depth_search => recurse("inf"), | |
action => immediate, | |
classes => success("rudder_ncf_local_updated", "rudder_ncf_local_update_error", "rudder_ncf_local_updated_ok"), | |
comment => "Update the local Rudder ncf instance"; | |
!root_server:: | |
"${g.rudder_tools}" | |
copy_from => remote("${server_info.cfserved}", "${g.rudder_tools}"), | |
depth_search => recurse("inf"), | |
action => immediate, | |
classes => success("rudder_tools_updated_ok", "rudder_tools_update_error"); | |
"${client_inputs}" | |
copy_from => remote("${server_info.cfserved}","${server_inputs}"), | |
depth_search => recurse("inf"), | |
action => immediate, | |
classes => success("config", "no_update"); | |
processes: | |
config:: | |
"cf-serverd" restart_class => "start_server"; | |
config.!windows:: | |
"cf-execd" restart_class => "start_exec"; | |
commands: | |
start_exec.!windows:: | |
"${sys.cf_execd}", | |
action => u_ifwin_bg, | |
classes => outcome("executor"); | |
start_exec.cygwin:: | |
"${sys.cf_execd}", | |
action => u_ifwin_bg, | |
classes => outcome("executor"); | |
start_server:: | |
"${sys.cf_serverd}", | |
action => u_ifwin_bg, | |
classes => outcome("server"); | |
######################################################### | |
services: | |
config.windows:: | |
"CfengineNovaExec" | |
service_policy => "start", | |
service_method => u_bootstart, | |
classes => outcome("executor"), | |
comment => "Start the executor windows service now and at boot time"; | |
reports: | |
server_ok:: | |
"@@HasPolicyServer@@Inform@@hasPolicyServer-root#@common-root##${g.uuid}@#Started the server - system ready to serve"; | |
executor_ok:: | |
"@@HasPolicyServer@@Inform@@hasPolicyServer-root#@common-root##${g.uuid}@#Started the scheduler - system functional"; | |
no_update:: | |
"@@HasPolicyServer@@Error@@hasPolicyServer-root#@common-root##${g.uuid}@#Cannot update policy files"; | |
rudder_tools_update_error:: | |
"@@HasPolicyServer@@Error@@hasPolicyServer-root#@common-root##${g.uuid}@#Cannot update Rudder tools"; | |
rudder_ncf_common_update_error:: | |
"@@HasPolicyServer@@Error@@hasPolicyServer-root#@common-root##${g.uuid}@#Cannot update Rudder common ncf instance"; | |
rudder_ncf_local_update_error:: | |
"@@HasPolicyServer@@Error@@hasPolicyServer-root#@common-root##${g.uuid}@#Cannot update Rudder local ncf instance"; | |
} | |
############################################ | |
body classes outcome(x) | |
{ | |
promise_repaired => {"${x}_ok"}; | |
} | |
############################################ | |
body action u_background | |
{ | |
background => "true"; | |
} | |
############################################ | |
body classes success(if, else) | |
{ | |
promise_repaired => {"${if}"}; | |
repair_failed => { "${else}" }; | |
repair_denied => { "${else}" }; | |
repair_timeout => { "${else}" }; | |
} | |
############################################ | |
body action u_ifwin_bg | |
{ | |
windows:: | |
background => "true"; | |
} | |
body service_method u_bootstart | |
{ | |
service_autostart_policy => "boot_time"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent process_matching | |
{ | |
vars: | |
# This deliberately excludes cf-execd which is handled separately below | |
"cf_components" slist => { "cf-key", | |
"cf-monitord", "cf-promises", | |
"cf-runagent", "cf-serverd" }; | |
windows:: | |
"stop_signal" string => "kill"; | |
!windows:: | |
"stop_signal" string => "term"; | |
classes: | |
"restart_cf" expression => "Hr05.Min00_05"; | |
processes: | |
restart_cf.!policy_server:: | |
"${cf_components}" signals => { "${stop_signal}" }; | |
restart_cf.policy_server:: | |
"${sys.workdir}/bin/${cf_components}" signals => { "${stop_signal}" }; | |
restart_cf.!windows:: | |
"${sys.workdir}/bin/cf-execd" signals => { "${stop_signal}" }; | |
commands: | |
restart_cf.!windows:: | |
"${sys.cf_serverd}"; | |
"${sys.cf_execd}"; | |
services: | |
restart_cf.windows:: | |
"CfengineNovaExec" | |
service_policy => "stop", | |
comment => "Stop the executor service, part of scheduled restart"; | |
"CfengineNovaExec" | |
service_policy => "start", | |
comment => "Start the executor service, part of scheduled restart"; | |
reports: | |
restart_cf:: | |
"Reloaded configuration of all Cfengine components"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
####################################################### | |
# | |
# Server specific configuration | |
# | |
####################################################### | |
bundle server access_rules | |
{ | |
access: | |
policy_server:: | |
"root" | |
handle => "policy_server_uuid", | |
resource_type => "literal", | |
admit => {".*"}; | |
"${def.dir_masterfiles}" | |
handle => "grant_access_policy", | |
comment => "Grant access to the policy updates", | |
maproot => { @{def.acl} }, | |
admit => { @{def.acl} }; | |
"${g.rudder_tools}" | |
maproot => { @{def.acl} }, | |
admit => { @{def.acl} }; | |
"${g.rudder_ncf_origin_common}" | |
maproot => { @{def.acl} }, | |
admit => { @{def.acl} }; | |
"${g.rudder_ncf_origin_local}" | |
maproot => { @{def.acl} }, | |
admit => { @{def.acl} }; | |
any:: | |
# the policy server must have access to the cfengine folder | |
"${sys.workdir}" | |
maproot => { host2ip("%%POLICY_SERVER_HOSTNAME%%"), escape("%%POLICY_SERVER_HOSTNAME%%") }, | |
admit => { host2ip("%%POLICY_SERVER_HOSTNAME%%"), escape("%%POLICY_SERVER_HOSTNAME%%") }; | |
roles: | |
# Allow user root to set any class | |
".*" authorize => { "root" }; | |
} | |
bundle common def | |
{ | |
vars: | |
"policy_server" string => "%%POLICY_SERVER_HOSTNAME%%"; | |
"dir_masterfiles" string => translatepath("${sys.workdir}/masterfiles"); | |
# List here the IP masks that we grant access to on the server | |
policy_server:: | |
"acl" slist => { | |
"%%POLICY_SERVER_ALLOWED_NETWORKS%%" | |
}; | |
!policy_server:: | |
"acl" slist => { | |
"${def.policy_server}" | |
}; | |
} | |
body server control | |
{ | |
trustkeysfrom => { | |
"127.0.0.0/8" , "::1", | |
@{def.acl} , | |
host2ip("%%POLICY_SERVER_HOSTNAME%%"), "%%POLICY_SERVER_HOSTNAME%%" | |
}; #trustkey allows the exchange of keys | |
allowconnects => { | |
@{def.acl} , | |
host2ip("%%POLICY_SERVER_HOSTNAME%%"), "%%POLICY_SERVER_HOSTNAME%%" | |
}; | |
maxconnections => "1000"; | |
logallconnections => "true"; | |
cfruncommand => "${sys.workdir}/bin/cf-agent -f failsafe.cf && ${sys.workdir}/bin/cf-agent"; | |
allowusers => { "root" }; | |
skipverify => { "127.0.0.0/8" , "::1", @{def.acl} }; | |
community_edition:: | |
port => "5309"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_alive_check | |
{ | |
vars: | |
"sites_to_check" slist => { "http://localhost:8080/rudder/api/status", "http://localhost:8080/endpoint/api/status" }; | |
methods: | |
"any" usebundle => generic_alive_check("${sites_to_check}"); | |
} | |
bundle agent generic_alive_check(site_to_check) | |
{ | |
vars: | |
"sitename" string => canonify("${site_to_check}"); | |
"cleanup_failed_classes" slist => { "site_down_once_${sitename}", "site_alivecheck_restart_jetty_${sitename}" }; | |
"failed_result_class" string => "site_down_once_${sitename}", | |
ifvarclass => "!site_down_once_${sitename}.!first_iteration_passed"; | |
"site_failure_persist_time" string => "10", | |
ifvarclass => "!site_down_once_${sitename}.!first_iteration_passed"; | |
"failed_result_class" string => "site_alivecheck_restart_jetty_${sitename}", | |
ifvarclass => "site_down_once_${sitename}.!first_iteration_passed"; | |
"site_failure_persist_time" string => "0", | |
ifvarclass => "site_down_once_${sitename}.!first_iteration_passed"; | |
classes: | |
"first_iteration_passed" expression => "any"; | |
methods: | |
"any" usebundle => generic_process_check_process(".*java.*/opt/rudder/jetty7/start.jar", "rudder-jetty", "true"), | |
ifvarclass => "site_alivecheck_restart_jetty_${sitename}", | |
classes => set_persist_classes("site_alivecheck_jetty_restarted_${sitename}", "site_down_once_${sitename}" ,"0"); | |
commands: | |
"/usr/bin/curl -s ${site_to_check} |/bin/grep -q OK" | |
contain => in_shell_silent, | |
classes => set_persist_classes_alivecheck("site_ok", "${failed_result_class}", "@{generic_alive_check.cleanup_failed_classes}", "${site_failure_persist_time}"), | |
comment => "Checking if ${site_to_check} is alive"; | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${site_to_check} web application is running" | |
ifvarclass => "site_ok.!site_down_once_${sitename}"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#This is the first time the ${site_to_check} web application failed to respond. Deferring the restart." | |
ifvarclass => "site_down_once_${sitename}.!site_alivecheck_restart_jetty_${sitename}"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${site_to_check} web application failed to respond for the second time. Restarting rudder-jetty NOW !" | |
ifvarclass => "site_alivecheck_restart_jetty_${sitename}"; | |
} | |
body classes set_persist_classes_alivecheck(repaired, failed, cancelifok, length) | |
{ | |
promise_kept => { "${repaired}" }; | |
promise_repaired => { "${repaired}" }; | |
repair_failed => { "${failed}" }; | |
repair_denied => { "${failed}" }; | |
repair_timeout => { "${failed}" }; | |
cancel_kept => {"@{cancelifok}"}; | |
cancel_repaired => {"@{cancelifok}"}; | |
cancel_notkept => {"${repaired}"}; | |
persist_time => "${length}"; | |
} | |
##################################################################################### | |
# Copyright 2011-2014 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_logrotate_check | |
{ | |
vars: | |
(debian_5|debian_6).!ubuntu:: | |
"logrotate_file" string => "${sys.workdir}/inputs/distributePolicy/logrotate.conf/rudder.old-debian"; | |
debian.!(debian_5|debian_6).!ubuntu:: | |
"logrotate_file" string => "${sys.workdir}/inputs/distributePolicy/logrotate.conf/rudder.debian"; | |
ubuntu:: | |
"logrotate_file" string => "${sys.workdir}/inputs/distributePolicy/logrotate.conf/rudder.ubuntu"; | |
redhat:: | |
"logrotate_file" string => "${sys.workdir}/inputs/distributePolicy/logrotate.conf/rudder.rhel"; | |
!debian.!ubuntu.!redhat:: | |
"logrotate_file" string => "${sys.workdir}/inputs/distributePolicy/logrotate.conf/rudder.suse"; | |
files: | |
"/etc/logrotate.d/rudder" | |
copy_from => copy_digest("${logrotate_file}"), | |
classes => kept_if_else("rudder_logrotate_conf_ok", "rudder_logrotate_conf_copied", "cannot_copy_rudder_logrotate_conf"), | |
comment => "Copying the logrotate configuration"; | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The logrotate configuration is correct" | |
ifvarclass => "rudder_logrotate_conf_ok.!rudder_logrotate_conf_copied.!cannot_copy_rudder_logrotate_conf"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The logrotate configuration has been updated" | |
ifvarclass => "rudder_logrotate_conf_copied.!cannot_copy_rudder_logrotate_conf"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The logrotate configuration could not be updated" | |
ifvarclass => "cannot_copy_rudder_logrotate_conf"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_postgres_check | |
{ | |
vars: | |
SuSE:: | |
"configuration_statements" slist => { "host all rudder ::1/128 md5", "host all rudder 127.0.0.1/32 md5" }; | |
files: | |
SuSE:: | |
"/var/lib/pgsql/data/pg_hba.conf" | |
edit_line => prepend("${configuration_statements}"), | |
edit_defaults => noempty_backup, | |
classes => kept_if_else("psql_conf_ok", "psql_conf_updated", "psql_conf_update_error"), | |
comment => "Edit the SuSE postgresql configuration to enable account-less logins"; | |
commands: | |
SuSE:: | |
"/etc/init.d/postgresql" | |
args => "restart", | |
classes => kept_if_else("psql_restart_ok", "psql_restart_ok", "psql_restart_error"), | |
ifvarclass => "psql_conf_updated"; | |
reports: | |
SuSE:: | |
# Report about the configuration file edition | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The SuSE specific postgresql configuration is present" | |
ifvarclass => "psql_conf_ok.!psql_conf_updated.!psql_conf_update_error"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The SuSE specific postgresql configuration has been added" | |
ifvarclass => "psql_conf_updated.!psql_conf_update_error"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The SuSE specific postgresql configuration could not be added" | |
ifvarclass => "psql_conf_update_error"; | |
# Reports about Postgres restart status | |
"@@DistributePolicy@@log_info@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#PostgreSQL has been restarted" | |
ifvarclass => "psql_restart_ok"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#PostgreSQL restart has failed! Rudder is most certainly broken..." | |
ifvarclass => "psql_restart_error"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_integrity_check | |
{ | |
files: | |
"${g.rudder_var}/configuration-repository" | |
create => "true", | |
action => WarnOnly, | |
classes => if_else("rudder_integrity_ok", "rudder_integrity_failed"); | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${g.rudder_var}/configuration-repository directory is present" | |
ifvarclass => "rudder_integrity_ok.!rudder_integrity_failed"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#EMERGENCY: THE ${g.rudder_var}/configuration-repository DIRECTORY IS *ABSENT*. THIS ORCHESTRATOR WILL *NOT* OPERATE CORRECTLY." | |
ifvarclass => "!rudder_integrity_ok|rudder_integrity_failed"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# Configure rsyslog on the orchestrator | |
# This will provide promises to add the backports repos to Debian Lenny: | |
# - in sources.list | |
# - default apt_preferences to upgrade packages installed from backports | |
# - a package_method to install packages from backports via cfengine | |
bundle agent setup_debian_backports | |
{ | |
vars: | |
"apt_source_line" slist => { "deb http://backports.debian.org/debian-backports lenny-backports" }; | |
"apt_components" slist => { "main" }; | |
files: | |
debian_5:: | |
"/etc/apt/sources.list" | |
comment => "Include extra apt repos", | |
edit_line => append_if_no_lines("${apt_source_line} ${apt_components}"), | |
edit_defaults => noempty_backup, | |
classes => if_repaired("apt_sources_updated"); | |
"/etc/apt/preferences" | |
comment => "Set automatic upgrades for packages installed from backports (recommended setting from backports.debian.org)", | |
create => "true", | |
edit_line => append_if_no_lines("Package: *${const.n}Pin: release a=lenny-backports${const.n}Pin-Priority: 200"), | |
edit_defaults => noempty_backup, | |
classes => if_repaired("apt_preferences_repaired"); | |
commands: | |
apt_sources_updated:: | |
"/usr/bin/aptitude" | |
args => "update"; | |
reports: | |
apt_sources_updated:: | |
"apt's sources.list was edited, and an aptitude update will now run"; | |
apt_preferences_repaired:: | |
"apt's /etc/apt/preferences file was changed"; | |
} | |
bundle agent install_rsyslogd | |
{ | |
vars: | |
# This will only read the first line if several match | |
"rsyslog_port_defined" int => getfields("rudder.syslog.port\s*=\s*[0-9]+\s*","/opt/rudder/etc/rudder-web.properties","=","rsyslog_port"); | |
# Use standard rsyslog port number by default if not set in rudder-web.properties | |
rsyslog_port_not_found:: | |
"rsyslog_port[2]" string => "514"; | |
classes: | |
# There is no "equals" function for ints in CFEngine (currently, at least) so we compare strings | |
"rsyslog_port_not_found" expression => strcmp("${rsyslog_port_defined}","0"); | |
"rsyslog_port_too_many" expression => isgreaterthan("${rsyslog_port_defined}","1"); | |
files: | |
policy_server:: | |
"/etc/rsyslog.d/rudder.conf" | |
create => "true", | |
edit_line => expand_template("${sys.workdir}/inputs/distributePolicy/rsyslog.conf/rudder.conf"), | |
edit_defaults => empty_backup, | |
classes => cf2_if_else("rudder_rsyslog_conf_copied", "cannot_copy_rudder_rsyslog_conf"), | |
comment => "Copying rsyslog conf"; | |
"/etc/rsyslog.conf" | |
edit_line => append_if_no_lines("$IncludeConfig /etc/rsyslog.d/*.conf"), | |
edit_defaults => noempty_backup, | |
comment => "Add the rsyslog.conf.d include if not already present", | |
classes => cf2_if_else("rsyslog_inc_ok" , "rsyslog_inc_failed"); | |
policy_server.!SuSE:: | |
"/etc/rsyslog.d/pgsql.conf" | |
edit_line => comment_all(), | |
edit_defaults => noempty_backup, | |
classes => cf2_if_else("rudder_rsyslog_pgsql", "cannot_update_rudder_rsyslog_pgsql"), | |
comment => "Removing the logging of all in the database"; | |
packages: | |
policy_server.debian_5.!SuSE:: | |
"rsyslog" | |
package_policy => "add", | |
package_method => debian_backports, | |
classes => cf2_if_else("rsyslog_installed", "cant_install_rsyslog"), | |
comment => "Installing rsyslog using apt backports"; | |
"rsyslog-pgsql" | |
package_policy => "add", | |
package_method => debian_backports, | |
classes => cf2_if_else("rsyslog_pgsql_installed", "cant_install_rsyslog_pgsql"), | |
comment => "Installing rsyslog_pgsql using apt backports"; | |
policy_server.!debian_5.!SuSE:: | |
"rsyslog" | |
package_policy => "add", | |
package_method => generic, | |
classes => cf2_if_else("rsyslog_installed", "cant_install_rsyslog"), | |
comment => "Installing rsyslog using apt backports"; | |
"rsyslog-pgsql" | |
package_policy => "add", | |
package_method => generic, | |
classes => cf2_if_else("rsyslog_pgsql_installed", "cant_install_rsyslog_pgsql"), | |
comment => "Installing rsyslog_pgsql using apt backports"; | |
commands: | |
policy_server.(rsyslog_installed|rsyslog_pgsql_installed|rudder_rsyslog_conf_copied|rudder_rsyslog_pgsql).!SuSE:: | |
"/etc/init.d/rsyslog" | |
args => "restart", | |
classes => cf2_if_else("rsyslog_restarted", "cant_restart_rsyslog"), | |
comment => "restarting rsyslog"; | |
policy_server.(rsyslog_installed|rsyslog_pgsql_installed|rudder_rsyslog_conf_copied|rudder_rsyslog_pgsql).SuSE:: | |
"/etc/init.d/syslog" | |
args => "restart", | |
classes => cf2_if_else("rsyslog_restarted", "cant_restart_rsyslog"), | |
comment => "restarting rsyslog"; | |
reports: | |
cant_install_rsyslog|cant_install_rsyslog_pgsql:: | |
"Fatal : Can't install rsyslog or rsyslog_pgsql on the Rudder root server !"; | |
cannot_copy_rudder_rsyslog_conf:: | |
"Fatal : Can't copy the rsyslog configuration !"; | |
rsyslog_inc_failed:: | |
"Fatal : Can't enable the rsyslog include directory !"; | |
cant_restart_rsyslog:: | |
"Fatal : Can't restart rsyslog !"; | |
cannot_update_rudder_rsyslog_pgsql:: | |
"Fatal : Cannot update the pgsql configuration !"; | |
rsyslog_restarted:: | |
"Info : Restarted rsyslog"; | |
rsyslog_port_not_found:: | |
"Error: rsyslog port number is not set in /opt/rudder/etc/rudder-web.properties"; | |
rsyslog_port_too_many:: | |
"Warning: rsyslog port number has been set several times in /opt/rudder/etc/rudder-web.properties"; | |
} | |
# Package method to install packages from debian-backports | |
body package_method debian_backports | |
{ | |
debian:: | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/dpkg -l"; | |
package_list_name_regex => "ii\s+([^\s]+).*"; | |
package_list_version_regex => "ii\s+[^\s]+\s+([^\s]+).*"; | |
package_installed_regex => ".*"; # all reported are installed | |
package_name_convention => "${name}"; | |
package_list_update_ifelapsed => "240"; # 4 hours | |
debian.have_aptitude:: | |
package_add_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o Aptitude::Delete-Unused=false -t lenny-backports --assume-yes install"; | |
package_list_update_command => "/usr/bin/aptitude update"; | |
package_delete_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o Aptitude::Delete-Unused=false --assume-yes -q remove"; | |
package_update_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o Aptitude::Delete-Unused=false --assume-yes install"; | |
package_verify_command => "/usr/bin/aptitude show"; | |
package_noverify_regex => "(State: not installed|E: Unable to locate package .*)"; | |
debian.!have_aptitude:: | |
package_add_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o APT::Get::AutomaticRemove=false --yes -t lenny-backports install"; | |
package_list_update_command => "/usr/bin/apt-get update"; | |
package_delete_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o APT::Get::AutomaticRemove=false --yes -q remove"; | |
package_update_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef -o APT::Get::AutomaticRemove=false --yes install"; | |
package_verify_command => "/usr/bin/dpkg -s"; | |
package_noverify_returncode => "1"; | |
} | |
bundle edit_line comment_all() | |
{ | |
replace_patterns: | |
# comment all lines | |
"^[^#](.*)" | |
replace_with => comments; | |
} | |
body replace_with comments | |
{ | |
replace_value => "#${match.1}"; # backreference 0 | |
occurrences => "all"; # first, last all | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_init_check() | |
{ | |
vars: | |
"service[1][binary]" string => "/opt/rudder/libexec/slapd"; | |
"service[1][initscript]" string => "rudder-slapd"; | |
"service[2][binary]" string => ".*java.*/opt/rudder/jetty7/start.jar"; | |
"service[2][initscript]" string => "rudder-jetty"; | |
"service[3][binary]" string => "postgres: writer process"; | |
"service[3][initscript]" string => "postgresql"; | |
"service[5][binary]" string => "apache2"; | |
"service[5][initscript]" string => "apache2"; | |
"index" slist => getindices("service"); | |
methods: | |
"any" usebundle => generic_process_check_process("${service[${index}][binary]}", "${service[${index}][initscript]}", "false"); | |
"any" usebundle => generic_process_check_bootstart("${service[${index}][binary]}", "${service[${index}][initscript]}"); | |
} | |
bundle agent generic_process_check_process(binary, initscript, force_restart) | |
{ | |
vars: | |
"canoname" string => canonify("${binary}"); | |
classes: | |
"forced_trigger_${canoname}" expression => strcmp("${force_restart}", "true"); | |
processes: | |
# check the service status | |
"${binary}" | |
comment => "Check the process status", | |
restart_class => "process_restart_${canoname}", | |
classes => kept_if_else("service_running_${canoname}", "service_anomaly_${canoname}", "service_error_${canoname}"); | |
commands: | |
"/etc/init.d/${initscript}" | |
args => "restart </dev/null >/dev/null 2>/dev/null", | |
contain => in_shell_silent, | |
# action => bg("0", "120"), | |
classes => kept_if_else("process_restart_ok_${canoname}", "process_restart_ok_${canoname}", "process_restart_error_${canoname}"), | |
ifvarclass => "process_restart_${canoname}|forced_trigger_${canoname}"; | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${initscript} process is already running" | |
ifvarclass => "!process_restart_${canoname}.!forced_trigger_${canoname}"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${initscript} process was not running and has been restarted" | |
ifvarclass => "process_restart_${canoname}.process_restart_ok_${canoname}.!forced_trigger_${canoname}"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${initscript} process has been restarted" | |
ifvarclass => "process_restart_ok_${canoname}.forced_trigger_${canoname}"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${initscript} process couldn't be restarted" | |
ifvarclass => "process_restart_error_${canoname}"; | |
} | |
bundle agent generic_process_check_bootstart(binary, initscript) | |
{ | |
vars: | |
"canoname" string => canonify("${binary}"); | |
files: | |
debian:: | |
"/etc/rc2.d/S.*${initscript}.*" | |
create => "true", | |
action => WarnOnly, | |
classes => if_else("service_bootstarted_${canoname}", "service_unbootstarted_${canoname}"); | |
commands: | |
(SuSE|redhat):: | |
"/sbin/chkconfig" | |
args => "--check ${initscript}", | |
classes => if_else("service_bootstarted_${canoname}", "service_unbootstarted_${canoname}"), | |
comment => "Check if the service ${initscript} is started on boot"; | |
"/sbin/insserv" | |
args => "-d ${initscript}", | |
classes => if_else("service_bootstarted_ok_${canoname}", "service_bootstarted_fail_${canoname}"), | |
ifvarclass => "service_unbootstarted_${canoname}", | |
comment => "Set the service ${initscript} to start on boot"; | |
debian:: | |
"/usr/sbin/update-rc.d ${initscript} remove && /usr/sbin/update-rc.d ${initscript} defaults" | |
contain => in_shell, | |
classes => if_else("service_bootstarted_ok_${canoname}", "service_bootstarted_fail_${canoname}"), | |
ifvarclass => "service_unbootstarted_${canoname}", | |
comment => "Set the service ${initscript} to start on boot"; | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#${initscript} is started on boot as required" | |
ifvarclass => "service_bootstarted_${canoname}"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#${initscript} has been set to start on boot" | |
ifvarclass => "!service_bootstarted_${canoname}.service_bootstarted_ok_${canoname}"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#Could not set ${initscript} to start on boot!" | |
ifvarclass => "!service_bootstarted_${canoname}.service_bootstarted_fail_${canoname}"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_technique_reload | |
{ | |
vars: | |
"root_technique_reload_rest_url" string => "http://localhost:8080/rudder/api/techniqueLibrary/reload"; | |
classes: | |
"root_technique_reload_trigger" expression => fileexists("${g.rudder_base}/etc/force_technique_reload"); | |
files: | |
root_technique_reload_rest_call_repaired:: | |
"${g.rudder_base}/etc/force_technique_reload" | |
delete => tidy, | |
comment => "Deleting the force_technique_reload file because it is no longer relevant"; | |
commands: | |
root_technique_reload_trigger:: | |
"/usr/bin/curl -s ${root_technique_reload_rest_url} |/bin/grep -q OK" | |
contain => in_shell_silent, | |
classes => rudder_common_classes("root_technique_reload_rest_call"), | |
comment => "Reload the Technique library using the Rudder API"; | |
reports: | |
root_technique_reload_trigger:: | |
"@@DistributePolicy@@log_info@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${g.rudder_base}/etc/force_technique_reload file is present. Reloading Technique library..."; | |
root_technique_reload_rest_call_repaired:: | |
"@@DistributePolicy@@log_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Technique library has been reloaded."; | |
root_technique_reload_rest_call_failed:: | |
"@@DistributePolicy@@log_warn@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Technique library failed to reload. Will try again next time"; | |
} | |
##################################################################################### | |
# Copyright 2012 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle common p | |
{ | |
vars: | |
"no" int => getfields("RUDDER_PSQL_PASSWORD:.*","/opt/rudder/etc/rudder-passwords.conf",":","psql_password"); | |
"no2" int => getfields("RUDDER_OPENLDAP_BIND_PASSWORD:.*","/opt/rudder/etc/rudder-passwords.conf",":","ldap_password"); | |
"properties_files" slist => { "${g.rudder_base}/etc/rudder-web.properties", "${g.rudder_base}/etc/inventory-web.properties" }; | |
"managed_files" slist => { "@{properties_files}", "/root/.pgpass", "${g.rudder_base}/etc/openldap/slapd.conf" }; | |
} | |
bundle agent root_password_check_disclaimer | |
{ | |
vars: | |
"disclaim" slist => { "@{p.managed_files}" }; | |
files: | |
"${disclaim}" | |
edit_line => insert_rudder_disclaimer, | |
comment => "Insert a disclaimer into Rudder"; | |
} | |
bundle agent root_password_check_file | |
{ | |
vars: | |
"pgpass[1]" string => "localhost"; | |
"pgpass[2]" string => "5432"; | |
"pgpass[3]" string => "rudder"; | |
"pgpass[4]" string => "rudder"; | |
"pgpass[5]" string => "${p.psql_password[2]}"; | |
files: | |
"${g.rudder_base}/etc/rudder-passwords.conf" | |
perms => mog("600", "root", "root"), | |
classes => kept_if_else("file_ok", "file_repaired", "file_error"); | |
"/root/.pgpass" | |
create => "true", | |
edit_line => root_password_check_file_pgpass("root_password_check_file.pgpass"); | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder passwords file is present and secure" | |
ifvarclass => "file_ok.!file_repaired.!file_error"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder passwords file permissions were fixed" | |
ifvarclass => "file_repaired.!file_error"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#EMERGENCY: THE ${g.rudder_base}/etc/rudder-passwords.conf FILE IS *ABSENT*. THIS RUDDER SERVER WILL *NOT* OPERATE CORRECTLY." | |
ifvarclass => "file_error"; | |
} | |
bundle agent root_password_check_ldap | |
{ | |
vars: | |
# Build an array using ldap configuration values | |
"rudder[ldap.authpw]" string => "${p.ldap_password[2]}"; | |
"slapd[rootpw]" string => "${p.ldap_password[2]}"; # Looks like a bug, I can not use execresult("/opt/rudder/sbin/slappasswd -s ${p.ldap_password[2]}","noshell"); | |
"prop_edit" slist => { "@{p.properties_files}" }; | |
files: | |
"${prop_edit}" | |
edit_line => set_variable_values("root_password_check_ldap.rudder"), | |
classes => kept_if_else("rudder_web_password_integrity_ok", "rudder_web_password_integrity_changed", "rudder_web_password_integrity_failed"), | |
comment => "Verifying the Rudder Webapp properties file passwords and users"; | |
"${g.rudder_base}/etc/openldap/slapd.conf" | |
edit_line => update_slapd("root_password_check_ldap.slapd"), | |
classes => kept_if_else("rudder_ldap_password_integrity_ok", "rudder_ldap_password_integrity_changed", "rudder_ldap_password_integrity_failed"), | |
comment => "Verifying the Rudder LDAP file password and user"; | |
commands: | |
rudder_ldap_password_integrity_changed:: | |
"/etc/init.d/rudder-slapd restart" | |
contain => in_shell, | |
classes => if_else("slapd_restarted", "slapd_restart_failed"); | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder Webapp configuration files are OK (checked LDAP password)" | |
ifvarclass => "rudder_web_password_integrity_ok.!rudder_web_password_integrity_changed.!rudder_web_password_integrity_failed"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder Webapp configuration files were updated with a new LDAP password" | |
ifvarclass => "rudder_web_password_integrity_changed.!rudder_web_password_integrity_failed"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder Webapp configuration files could not be updated to set the LDAP password" | |
ifvarclass => "rudder_web_password_integrity_failed"; | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The OpenLDAP configuration file is OK (checked rootdn password)" | |
ifvarclass => "rudder_ldap_password_integrity_ok.!rudder_ldap_password_integrity_changed.!rudder_ldap_password_integrity_failed"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The OpenLDAP configuration file was updated with a new rootdn password" | |
ifvarclass => "rudder_ldap_password_integrity_changed.!rudder_ldap_password_integrity_failed"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The OpenLDAP configuration file could not be updated to set the rootdn password" | |
ifvarclass => "rudder_ldap_password_integrity_failed"; | |
"@@DistributePolicy@@log_info@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#rudder-slapd has been restarted" | |
ifvarclass => "slapd_restarted"; | |
} | |
bundle agent root_password_check_psql | |
{ | |
vars: | |
"no" int => getfields("RUDDER_PSQL_PASSWORD:.*","/opt/rudder/etc/rudder-passwords.conf",":","psql_pass"); | |
# Build an array using PSQL configuration values | |
"rudder[rudder.jdbc.password]" string => "${p.psql_password[2]}"; | |
classes: | |
"psql_cant_connect" not => returnszero("/usr/bin/psql --host localhost --username rudder --dbname rudder --quiet --output /dev/null --command 'select 1'","noshell"); | |
files: | |
"${g.rudder_base}/etc/rudder-web.properties" | |
edit_line => set_variable_values("root_password_check_psql.rudder"), | |
classes => kept_if_else("rudder_web_password_integrity_ok", "rudder_web_password_integrity_changed", "rudder_web_password_integrity_failed"), | |
comment => "Verifying the Rudder Webapp properties file passwords and users"; | |
commands: | |
psql_cant_connect:: | |
"/usr/bin/psql -q -c \"ALTER USER rudder WITH PASSWORD '${p.psql_password[2]}'\"" | |
contain => setuid_sh("postgres"), | |
classes => if_else("postgres_updated", "postgres_update_failed"); | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder Webapp configuration files are OK (checked SQL password)" | |
ifvarclass => "rudder_web_password_integrity_ok.!rudder_web_password_integrity_changed.!rudder_web_password_integrity_failed"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder Webapp configuration files were updated with a new SQL password" | |
ifvarclass => "rudder_web_password_integrity_changed.!rudder_web_password_integrity_failed"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder Webapp configuration files could not be updated to set the SQL password" | |
ifvarclass => "rudder_web_password_integrity_failed"; | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder PostgreSQL user account's password is correct and works" | |
ifvarclass => "!psql_cant_connect"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder PostgreSQL user account's password has been changed" | |
ifvarclass => "postgres_updated"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder PostgreSQL user account's password could not be changed!" | |
ifvarclass => "postgres_update_failed"; | |
} | |
bundle agent root_password_restart_jetty | |
{ | |
commands: | |
rudder_web_password_integrity_changed:: | |
"/etc/init.d/rudder-jetty restart </dev/null >/dev/null 2>/dev/null" | |
contain => in_shell, | |
classes => if_else("jetty_restarted", "jetty_restart_failed"); | |
reports: | |
"@@DistributePolicy@@log_info@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#Jetty has been restarted" | |
ifvarclass => "jetty_restarted"; | |
} | |
bundle agent root_password_check_dav | |
{ | |
vars: | |
debian:: | |
"webdav_check_wwwgroup" string => "www-data"; | |
!debian:: | |
"webdav_check_wwwgroup" string => "www"; | |
SuSE:: | |
"htpasswd_bin" string => "/usr/bin/htpasswd2"; | |
!SuSE:: | |
"htpasswd_bin" string => "/usr/bin/htpasswd"; | |
classes: | |
"dav_cant_connect" not => returnszero("/usr/bin/curl -f -u ${g.davuser}:${g.davpw} -T /etc/motd http://localhost/inventory-updates/motd","noshell"); | |
files: | |
"${g.rudder_base}/etc/htpasswd-webdav" | |
create => "true", | |
perms => mog("640", "root", "${webdav_check_wwwgroup}"); | |
commands: | |
dav_cant_connect:: | |
# Apache reads this file when it's changed, no need to restart or reload it after it's changed | |
"${htpasswd_bin}" | |
args => "-b ${g.rudder_base}/etc/htpasswd-webdav ${g.davuser} ${g.davpw}", | |
classes => kept_if_else("rudder_apache_davpassword_ok", "rudder_apache_davpassword_changed", "rudder_apache_davpassword_failed"), | |
comment => "Repairing the Rudder WebDAV user and password"; | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder WebDAV user and password are OK" | |
ifvarclass => "!dav_cant_connect"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder WebDAV user and password were updated" | |
ifvarclass => "rudder_apache_davpassword_changed.!rudder_apache_davpassword_failed"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Rudder WebDAV user and password could not be updated" | |
ifvarclass => "rudder_apache_davpassword_failed"; | |
} | |
bundle edit_line update_slapd(tab) | |
{ | |
vars: | |
"index" slist => getindices("${tab}"); | |
delete_lines: | |
"${index}.*"; | |
insert_lines: | |
"${index} ${${tab}[${index}]}" location => after("^rootdn.*"); | |
} | |
bundle edit_line root_password_check_file_pgpass(parameter) | |
{ | |
vars: | |
"indices" slist => getindices(${parameter}); | |
field_edits: | |
"localhost:5432:rudder:.*" | |
# Set field of the file to parameter | |
edit_field => col(":","${indices}","${${parameter}[${indices}]}","set"); | |
insert_lines: | |
"localhost:5432:rudder:${${parameter}[4]}:${${parameter}[5]}"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# Fetch the promises from the server to be available for others machines | |
# Must not do it on the RootServer though... | |
bundle agent propagatePromises | |
{ | |
vars: | |
"server_data" string => "${server_info.policy_files}/share"; #actual directory with data to propagate | |
"client_data" string => "${g.rudder_var}/share/"; #where to put the files on the client when downloaded | |
files: | |
root_server:: | |
"${g.rudder_tools}" | |
copy_from => copy("${g.rudder_base}/share/tools"), | |
depth_search => recurse_visible("inf"), | |
comment => "Fetching the tools for the promises execution", | |
classes => if_else("tools_propagated", "could_not_propagate_tools"); | |
!root_server:: | |
"${client_data}" #that's a loop on each files in client_inputs | |
copy_from => remote("${server_info.cfserved}","${server_data}"), | |
depth_search => recurse_visible("inf"), | |
comment => "Fetching the promises to propagate", | |
classes => if_else("promises_propagated", "could_not_propagate_promise"); | |
"${g.rudder_tools}" | |
copy_from => remote("${server_info.cfserved}","${g.rudder_tools}"), | |
depth_search => recurse_visible("inf"), | |
comment => "Fetching the tools for the promises execution", | |
classes => if_else("tools_propagated", "could_not_propagate_tools"); | |
"${sys.workdir}/masterfiles" | |
copy_from => remote("${server_info.cfserved}","${sys.workdir}/masterfiles"), | |
depth_search => recurse_visible("inf"), | |
file_select => no_license_dat, #We don't want to propagate a wrong license.dat | |
comment => "Fetching the bootstrap promises", | |
classes => if_else("masterfiles_propagated", "could_not_propagate_masterfiles"); | |
"${sys.workdir}/masterfiles/license.dat" | |
copy_from => local_cp("${sys.workdir}/inputs/license.dat"), | |
comment => "Putting the right license in the bootstrap", | |
classes => if_else("license_copied", "could_not_copy_license"); | |
reports: | |
could_not_propagate_promise:: | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@propagatePromises@@None@@${g.execRun}##${g.uuid}@#Cannot propagate policy files"; | |
could_not_propagate_tools:: | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@propagatePromises@@None@@${g.execRun}##${g.uuid}@#Cannot propagate tools"; | |
could_not_propagate_masterfiles:: | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@propagatePromises@@None@@${g.execRun}##${g.uuid}@#Cannot propagate masterfiles"; | |
could_not_copy_license:: | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@propagatePromises@@None@@${g.execRun}##${g.uuid}@#Cannot copy local license"; | |
} | |
# Sending the inventory to cmdb (or syncing with the server if we are a simple relay) | |
bundle agent sendInventoryToCmdb | |
{ | |
files: | |
root_server:: | |
"${g.rudder_inventories}/incoming" | |
transformer => "${g.rudder_tools}/send-clean.sh http://localhost:8080/endpoint/upload/ ${this.promiser} ${g.rudder_inventories}/received/ ${g.rudder_inventories}/failed/", | |
depth_search => recurse_visible(1), | |
file_select => all_files, | |
classes => if_else("inventory_sent", "rudder_send_inventory_to_cmdb_cant_send_inventory"), | |
comment => "Sending the inventory to the cmdb"; | |
"${g.rudder_inventories}/accepted-nodes-updates" | |
transformer => "${g.rudder_tools}/send-clean.sh http://localhost:8080/endpoint/upload/ ${this.promiser} ${g.rudder_inventories}/received/ ${g.rudder_inventories}/failed/", | |
depth_search => recurse_visible(1), | |
file_select => all_files, | |
classes => if_else("inventory_sent", "rudder_send_inventory_to_cmdb_cant_send_inventory"), | |
comment => "Sending the inventory to the cmdb"; | |
# NEED TO DO THE RSYNC PART | |
reports: | |
inventory_sent.!rudder_send_inventory_to_cmdb_cant_send_inventory:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#Incoming inventories were successfully added to Rudder"; | |
rudder_send_inventory_to_cmdb_cant_send_inventory:: | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#Some inventories failed to add successfully to Rudder"; | |
} | |
body file_select all_files | |
{ | |
leaf_name => { ".*\..*" }; | |
file_result => "leaf_name"; | |
} | |
body file_select no_license_dat | |
{ | |
leaf_name => { "license\.dat" }; | |
file_result => "!leaf_name"; | |
} | |
##################################################################################### | |
# Copyright 2012-2013 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent root_networks_check | |
{ | |
vars: | |
"networks" string => join("${const.n}Allow from ","def.acl"); | |
"file_path" string => "/opt/rudder/etc/rudder-networks.conf"; | |
redhat:: | |
"apache_init" string => "httpd"; | |
!redhat:: | |
"apache_init" string => "apache2"; | |
files: | |
"${file_path}" | |
create => "true", | |
perms => mog("644", "root", "root"), | |
edit_defaults => empty_backup, | |
edit_line => insert_lines("Allow from 127.0.0.0/8${const.n}Allow from ${networks}"), | |
classes => kept_if_else("rudder_networks_ok", "rudder_networks_repaired","rudder_networks_failed"), | |
comment => "Copying rudder apache configuration"; | |
commands: | |
rudder_networks_repaired:: | |
"/etc/init.d/${apache_init}" | |
args => "reload", | |
classes => if_else("apache_restarted", "apache_restart_failed"); | |
reports: | |
cfengine:: | |
"@@DistributePolicy@@result_success@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${file_path} apache configuration file is OK" | |
ifvarclass => "rudder_networks_ok.!rudder_networks_repaired.!rudder_networks_failed"; | |
"@@DistributePolicy@@result_repaired@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${file_path} apache configuration file has been corrected" | |
ifvarclass => "rudder_networks_repaired.!rudder_networks_failed"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The ${file_path} apache configuration file was NOT edited because of an error" | |
ifvarclass => "rudder_networks_failed"; | |
"@@DistributePolicy@@log_info@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Apache HTTPd has been reloaded successfully" | |
ifvarclass => "apache_restarted.!apache_restart_failed"; | |
"@@DistributePolicy@@result_error@@root-DP@@root-distributePolicy@@00@@reports@@None@@${g.execRun}##${g.uuid}@#The Apache HTTPd failed to restart" | |
ifvarclass => "apache_restart_failed"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
############################################################ | |
# Fetch PERL and Curl | |
############################################################ | |
bundle agent fetchFusionTools | |
{ | |
packages: | |
debian:: | |
"curl" | |
package_policy => "add", | |
package_method => apt, | |
classes => rudder_common_classes("fetchFusionTools_install_curl"), | |
comment => "Installing curl using apt"; | |
redhat:: | |
"curl" | |
package_policy => "add", | |
package_method => rudder_yum, | |
classes => rudder_common_classes("fetchFusionTools_install_curl"), | |
comment => "Installing curl using yum"; | |
reports: | |
fetchFusionTools_install_curl_error:: | |
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@tools@@None@@${g.execRun}##${g.uuid}@#Installing 'curl' failed. Inventory registration will fail if curl is unavailable"; | |
} | |
body perms myperms | |
{ | |
mode => "0700"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# Definition of variables and classes usefull for all the VM part | |
# Detect the existence of installed VM containenr on the computer | |
bundle common virtualMachines | |
{ | |
vars: | |
# Files names for the installed VM lists | |
"VBoxListFile" string => "${g.rudder_var_tmp}/VBoxList.list"; | |
"VMWareListFile" string => "${g.rudder_var_tmp}/VMWareList.list"; | |
"VMWareScript_ServerLocation" string => "${g.rudder_tools}/vmware_info.sh"; | |
# Attribut name for the VM tag in the inventory file | |
"VBoxAttr" string => "VBox"; | |
"VMWareAttr" string => "VMWare"; | |
# Tools for fetching data | |
"VMWareScript" string => "${g.inventory_directory}/vmware_info.sh"; | |
windows.!cygwin:: | |
"virtual_box_install_path" string => execresult("${sys.winsysdir}\cmd.exe /c \"echo %VBOX_INSTALL_PATH%\"", "noshell"), | |
comment => "Looking for VirtualBox environment variables"; | |
cygwin:: | |
"virtual_box_install_path" string => execresult("/usr/bin/echo $VBOX_INSTALL_PATH | /usr/bin/sed ''s/\\/\//g'' ", "useshell"), | |
comment => "Looking for VirtualBox environment variables"; | |
classes: | |
linux:: | |
"VirtualBoxInstalled" expression => fileexists("/usr/bin/VBoxManage"), | |
comment => "Checking installation of VirtualBox"; | |
"VMWareInstalled" expression => fileexists("/usr/bin/wmrun"), | |
comment => "Checking installation of VMWare"; | |
windows:: | |
"VirtualBoxInstalled" not => regcmp("", "${virtual_box_install_path}"); | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# This file launch a fusion-inventory agent | |
# inventory in local. | |
# If fusion agent is not installed, | |
# the installation is done | |
# | |
# Then the inventory file is improved with external informations (UUID, cf-key, VMs) | |
bundle agent doInventory | |
{ | |
vars: | |
# If curl is available, use it | |
!windows.curl_installed:: | |
"download_command" string => "${g.rudder_curl} -s -f --proxy '' -o \"${g.rudder_var_tmp}/uuid.txt\" http://${server_info.cfserved}/uuid"; | |
# If not, use minicurl instead | |
!windows.!curl_installed:: | |
"download_command" string => "${g.minicurl} --get --file \"${g.rudder_var_tmp}/uuid.txt\" --url http://${server_info.cfserved}/uuid"; | |
# On windows, always use curl | |
windows:: | |
"download_command" string => "\"${g.rudder_base_sbin}\curl\curl.exe\" -s -f --noproxy '${server_info.cfserved}' -o \"${g.rudder_var_tmp}\uuid.txt\" http://${server_info.cfserved}/uuid"; | |
uuid_succesfully_downloaded:: | |
"policy_server_uuid" string => readfile("${g.rudder_var_tmp}/uuid.txt", 50); | |
classes: | |
# The force_inventory class may be specified by the user at runtime, or defined here | |
"force_inventory" expression => fileexists("${g.rudder_base}/etc/force_inventory"); | |
uuid_succesfully_downloaded:: | |
"uuid_valid" expression => regcmp("[a-z0-9-]+","${policy_server_uuid}"); | |
"uuid_validity_checked" | |
expression => "any", | |
comment => "This dummy class is just used for ordering the report using !uuid_valid below"; | |
methods: | |
uuid_valid.(!inventory_sent|force_inventory):: | |
"any" usebundle => fusionAgent; | |
"any" usebundle => listInstalledVM; | |
"any" usebundle => generateExtraInformations; | |
"any" usebundle => turnUsersToUnicode; | |
"any" usebundle => addInformationsToInventory; | |
"any" usebundle => moveInventoryToFinalDestination; | |
"any" usebundle => sendInventory; | |
"any" usebundle => cleanForceInventoryFlagFile; | |
commands: | |
"${download_command}" | |
comment => "Getting the uuid from the server", | |
classes => if_else("uuid_succesfully_downloaded","could_not_download_uuid"); | |
reports: | |
could_not_download_uuid:: | |
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not retrieve the UUID of the policy server"; | |
uuid_succesfully_downloaded.uuid_validity_checked.!uuid_valid:: | |
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not retrieve a valid UUID from the policy server"; | |
# Send reports to confirm this PT's success even if we don't need to send an inventory | |
inventory_sent:: | |
"@@Inventory@@log_info@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#An inventory was already sent less than 8 hours ago"; | |
!(Night.splaying).!force_inventory:: | |
"@@Inventory@@result_success@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Next inventory scheduled between 00:00 and 06:00"; | |
} | |
bundle common inventory | |
{ | |
vars: | |
windows:: | |
# Files names | |
"UserListFile_cp" string => "\"${g.rudder_var_tmp}\UserList.tmp\""; | |
"UserListFile" string => "\"${g.rudder_var_tmp}\UserList.list\""; | |
any:: | |
"CPUIDFile" string => "${g.rudder_var_tmp}/cpuid.arc"; | |
classes: | |
windows:: | |
"rudder_inventory_cpuid_tool_present" expression => fileexists("\"${g.rudder_tools}\cpuid-windows-V1.0.vbs\""); | |
"rudder_inventory_userlist_tool_present" expression => fileexists("${g.rudder_tools}\userlist.bat"); | |
!windows:: | |
"rudder_inventory_cpuid_tool_present" expression => fileexists("${g.rudder_tools}/cpuid-linux-V1.0.sh"); | |
} | |
bundle agent fusionAgent { | |
vars: | |
SuSE.xen_dom0:: | |
"xen_tools_package" string => "xen-tools"; | |
SuSE.xen_domu_pv:: | |
"xen_tools_package" string => "xen-tools-domU"; | |
debian:: | |
"xen_tools_package" string => "xenstore-utils"; | |
(redhat|centos):: | |
"xen_tools_package" string => "xen"; | |
files: | |
!windows|cygwin:: | |
"${g.rudder_var_tmp}/inventory/." | |
create => "true", | |
comment => "Creating inventory directory", | |
classes => if_ok("inventoryfoldercreated"); | |
"${g.rudder_var_reports}/." | |
create => "true"; | |
windows.!cygwin:: | |
"${g.rudder_var_tmp}\inventory\." | |
create => "true", | |
comment => "Creating inventory directory", | |
classes => if_ok("inventoryfoldercreated"); | |
"${g.rudder_var_reports}\." | |
create => "true"; | |
packages: | |
xen:: | |
"${xen_tools_package}" | |
package_policy => "add", | |
package_method => generic, | |
classes => cf2_if_else("xen_installed", "cant_install_xen"), | |
comment => "Installing xen package for extended data"; | |
commands: | |
!windows.inventoryfoldercreated:: | |
"${g.rudder_base}/bin/run-inventory --local=${g.rudder_var_tmp}/inventory --scan-homedirs" | |
classes => cf2_if_else("run_inventory", "inventory_failed"), | |
comment => "Generating inventory, in the temporary folder"; | |
windows:: | |
"\"c:\Program Files\Rudder\sbin\run-inventory.bat\"" | |
args => "--local=\"${g.rudder_var_tmp}\inventory\" --scan-homedirs 2>nul", | |
contain => in_shell, | |
classes => cf2_if_else("run_inventory", "inventory_failed"), | |
comment => "Generating inventory"; | |
reports: | |
run_inventory:: | |
"@@Inventory@@log_debug@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Running inventory"; | |
inventory_failed:: | |
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not execute the inventory"; | |
cant_install_curl:: | |
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not install curl"; | |
cant_install_ocs:: | |
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not install ocs"; | |
curl_installed:: | |
"@@Inventory@@log_info@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Curl installed"; | |
cant_install_xen:: | |
"@@Inventory@@result_error@@hasPolicyServer-root@@common-root@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not install xen utils on xen systems"; | |
xen_installed:: | |
"@@Inventory@@log_info@@hasPolicyServer-root@@common-root@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Xen utils installed"; | |
} | |
# List all installed VM on the machine (based on VirtualBox) | |
# CAUTION : Issue with path containing a whitespace, it's not working with windows | |
bundle agent listInstalledVM | |
{ | |
files: | |
VirtualBoxInstalled:: | |
"${virtualMachines.VBoxListFile}" | |
create => "true", | |
edit_line => xmlify(${virtualMachines.VBoxAttr}), | |
comment => "Converting file into pseudo XML"; | |
VMWareInstalled:: | |
"${virtualMachines.VMWareListFile}" | |
create => "true", | |
edit_line => xmlify(${virtualMachines.VMWareAttr}), | |
comment => "Converting file into pseudo XML"; | |
commands: | |
linux.VirtualBoxInstalled:: | |
"/usr/bin/VBoxManage" | |
args => "-q list vms > ${virtualMachines.VBoxListFile}", | |
contain => outputable, | |
classes => cf2_if_else("vb_listed", "cant_list_vb"), | |
comment => "Generating file with list of VM"; | |
windows.VirtualBoxInstalled:: | |
"\"${virtualMachines.virtual_box_install_path}VBoxManage.exe\"" | |
args => "-q list vms > ${virtualMachines.VBoxListFile}", | |
contain => outputable, | |
classes => cf2_if_else("vb_listed", "cant_list_vb"), | |
comment => "Generating file with list of VM"; | |
linux.VMWareInstalled:: | |
"${virtualMachines.VMWareScript}" | |
contain => outputable, | |
args => " > ${virtualMachines.VMWareListFile}", | |
classes => cf2_if_else("vm_listed", "cant_list_vm"), | |
comment => "Generating file with list of VM"; | |
windows.VMWareInstalled:: | |
"${virtualMachines.VMWareScript}" | |
contain => outputable, | |
args => " > ${virtualMachines.VMWareListFile}", | |
classes => cf2_if_else("vm_listed", "cant_list_vm"), | |
comment => "Generating file with list of VM"; | |
reports: | |
cant_list_vm:: | |
"@@Inventory@@log_warn@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not list installed VMWare machines"; | |
cant_list_vb:: | |
"@@Inventory@@log_warn@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not list installed VirtualBox machines"; | |
} | |
bundle agent generateExtraInformations | |
{ | |
commands: | |
windows.rudder_inventory_userlist_tool_present:: | |
"\"${g.rudder_tools}\userlist.bat\"" | |
args => " > ${inventory.UserListFile_cp} ", | |
contain => outputable, | |
classes => cf2_if_else("userlist", "userlist_fail"), | |
comment => "Generating file with list of users"; | |
windows.rudder_inventory_cpuid_tool_present:: | |
"${sys.winsysdir}\cscript.exe" | |
args => "/Nologo \"${g.rudder_tools}/cpuid-windows-V1.0.vbs\" > \"${inventory.CPUIDFile}\"", | |
contain => outputable, | |
classes => cf2_if_else("cpuid", "cpuid_fail"), | |
comment => "Generating file with CPUID information"; | |
linux.rudder_inventory_cpuid_tool_present:: | |
"${g.rudder_tools}/cpuid-linux-V1.0.sh" | |
args => " > ${inventory.CPUIDFile}", | |
contain => outputable, | |
classes => cf2_if_else("cpuid", "cpuid_fail"), | |
comment => "Generating file with CPUID information"; | |
android:: | |
"${g.rudder_tools}/cpuid-android-V1.0.sh" | |
args => " > ${inventory.CPUIDFile}", | |
contain => outputable, | |
classes => cf2_if_else("cpuid", "cpuid_fail"), | |
comment => "Generating file with CPUID information"; | |
reports: | |
userlist:: | |
"@@Inventory@@log_debug@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Generated the userlist"; | |
cpuid:: | |
"@@Inventory@@log_debug@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Generated the CPUID"; | |
userlist_fail:: | |
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not generate the user list"; | |
cpuid_fail:: | |
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not generate the cpuid"; | |
!rudder_inventory_userlist_tool_present:: | |
"@@Inventory@@log_debug@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#The user list generation tool is not present yet. Skipping..."; | |
!rudder_inventory_cpuid_tool_present:: | |
"@@Inventory@@log_debug@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#The CPUID generation tool is not present yet. Skipping..."; | |
} | |
bundle agent turnUsersToUnicode | |
{ | |
commands: | |
windows:: | |
"\"${g.rudder_tools}\iconv.exe\"" | |
args => " -f CP850 -t UTF-8 ${inventory.UserListFile_cp} > ${inventory.UserListFile} ", | |
contain => outputable_dir("${g.rudder_tools}"), | |
classes => cf2_if_else("userlist", "userlist_fail"), | |
comment => "Generating file with list of users in UTF"; | |
reports: | |
windows:: | |
"@@Inventory@@log_debug@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#This is a windows machine. User list has been converted to Unicode"; | |
} | |
# adding data to the inventory : | |
# UUID and CFKey in <DEVICEID>, | |
# list of VM in <CONTENT> | |
bundle agent addInformationsToInventory | |
{ | |
vars: | |
windows.!cygwin:: | |
"CFKEY" string => execresult("${sys.winsysdir}\cmd.exe /c \"type \"${sys.workdir}\ppkeys\localhost.pub\"\"", "noshell"); | |
"USER" string => getenv("USERNAME", 40); | |
"RUDDERUUID" string => execresult("${sys.winsysdir}\cscript.exe /Nologo \"${g.rudder_tools}/uuid.vbs\"","noshell"); | |
"polserv_uuid" string => readfile( "${g.rudder_var_tmp}\uuid.txt" , "50" ); | |
# Somehow, using the variable rather than the path fails with readstringlist | |
"users" slist => { readstringlist("C:\Program Files\Rudder\var\tmp\UserList.list","#.*","[\n| |\r]",50,4000) }; | |
cygwin:: | |
"mywinpath" string => execresult("/usr/bin/echo $WINDIR ", "useshell"); | |
"CFKEY" string => execresult("/usr/bin/cat ${sys.workdir}/ppkeys/localhost.pub", "noshell"); | |
"USER" string => execresult("/usr/bin/whoami", "noshell"); | |
"RUDDERUUID" string => execresult("${sys.winsysdir}\cscript.exe /Nologo ${g.rudder_tools}/uuid.vbs","noshell"); | |
"polserv_uuid" string => readfile( "${g.rudder_var_tmp}/uuid.txt" , "50" ); | |
"users" slist => { readstringlist("${inventory.UserListFile}","#.*","[\n| |\r]",10,4000) }; | |
xen.SuSE.xen_domu_pv:: | |
"VMRUDDERUUID" string => execresult("/bin/xenstore-read vm","noshell"); | |
xen.(centos|redhat|(SuSE.xen_dom0)):: | |
"VMRUDDERUUID" string => execresult("/usr/bin/xenstore-read vm","noshell"); | |
xen.(!SuSE.!centos.!redhat):: | |
"VMRUDDERUUID" string => execresult("/usr/sbin/xenstore-read vm","noshell"); | |
xen.xenrudderuuid:: | |
"RUDDERUUID" string => "${vmarray[1]}"; | |
linux.!xen:: | |
"RUDDERUUID" string => execresult("/usr/sbin/dmidecode -s system-uuid","noshell"); | |
aix:: | |
"RUDDERUUID" string => execresult("/usr/bin/uname -f", "noshell"); | |
!windows.!android:: | |
"CFKEY" string => execresult("/bin/cat ${sys.workdir}/ppkeys/localhost.pub", "noshell"); | |
"USER" string => execresult("/usr/bin/whoami", "noshell"); | |
"usersnumber" int => readstringarray("userslist","/etc/passwd","#[^\n]*",":",50,16000); | |
"users" slist => getindices("userslist"); | |
!windows:: | |
"polserv_uuid" string => readfile( "${g.rudder_var_tmp}/uuid.txt" , "50" ); | |
android:: | |
"RUDDERUUID" string => execresult("/system/xbin/sqlite3 /data/data/com.android.providers.settings/databases/settings.db \"select value from secure where name = 'android_id'\"", "noshell"); | |
"CFKEY" string => execresult("/system/bin/cat ${sys.workdir}/ppkeys/localhost.pub", "noshell"); | |
"USER" string => execresult("/system/xbin/whoami", "noshell"); | |
"usersnumber" int => "1"; | |
"users" slist => {"root"}; | |
"android_kernelname" string => "linux"; | |
"android_kernelversion" string => execresult("/system/xbin/uname -r", "noshell"); | |
"android_name" string => "Android"; | |
"android_version" string => execresult("/system/bin/getprop ro.build.version.release", "noshell"); | |
"android_fullname" string => "Android ${android_version}"; | |
"logdate" string => execresult("/system/bin/date '+%Y-%m-%d %H:%M:%S'", "noshell"); | |
classes: | |
xen:: | |
"xenrudderuuid" expression => regextract("/vm/(.*)", "${VMRUDDERUUID}", "vmarray"); | |
any:: | |
"uuiddefined" expression => isvariable("RUDDERUUID"); | |
files: | |
windows:: | |
"C:/Progra~1/Rudder/var/tmp/inventory/.*.ocs" | |
#"${g.esc_rudder_var_tmp}\inventory\.*.ocs" | |
edit_line => add_information_to_inventory(${RUDDERUUID}, ${CFKEY}, ${USER}, ${polserv_uuid}), | |
edit_defaults => def_no_backup; | |
"C:/Progra~1/Rudder/var/tmp/inventory/.*.ocs" | |
#"${g.esc_rudder_var_tmp}\inventory\.*.ocs" | |
edit_line => add_users_information_to_inventory(@{addInformationsToInventory.users}), | |
edit_defaults => def_no_backup; | |
!windows.uuiddefined:: | |
"${g.rudder_var_tmp}/inventory/.*.ocs" | |
edit_line => add_information_to_inventory(${RUDDERUUID}, ${CFKEY}, ${USER}, ${polserv_uuid}), | |
edit_defaults => def_no_backup; | |
"${g.rudder_var_tmp}/inventory/.*.ocs" | |
edit_line => add_users_information_to_inventory(@{addInformationsToInventory.users}), | |
edit_defaults => def_no_backup; | |
android:: | |
"${g.rudder_var_tmp}/inventory/.*.ocs" | |
edit_line => add_information_to_android_inventory(${android_fullname}, ${android_kernelname}, ${android_kernelversion}, ${android_name}, ${android_version}), | |
edit_defaults => def_no_backup; | |
"${g.rudder_var_tmp}/inventory/.*.ocs" | |
edit_line => add_accesslog_to_android_inventory(${logdate}), | |
edit_defaults => def_no_backup; | |
} | |
# Move the inventory file in the shared directory | |
bundle agent moveInventoryToFinalDestination | |
{ | |
files: | |
"${g.rudder_inventories}" | |
copy_from => copy("${g.rudder_var_tmp}/inventory"), | |
depth_search => recurse_visible(1), | |
file_select => inventory_files, | |
comment => "Moving inventory files to the final location"; | |
} | |
# Send the file to the promises server | |
bundle agent sendInventory | |
{ | |
vars: | |
"download_endpoint" string => "http://${server_info.cfserved}/inventories/"; | |
# If curl is available, use it | |
!windows.curl_installed:: | |
"download_command_prefix" string => "${g.rudder_curl} -f -s --proxy '' --user ${g.davuser}:${g.davpw} -T"; | |
"download_command_suffix" string => "${download_endpoint}"; | |
# If not, use minicurl instead | |
!windows.!curl_installed:: | |
"download_command_prefix" string => "${g.minicurl} --put --authentication ${g.davuser}:${g.davpw} --file"; | |
"download_command_suffix" string => "--url ${download_endpoint}"; | |
# On windows, always use curl | |
windows:: | |
"download_command_prefix" string => "\"${g.rudder_base_sbin}\curl\curl.exe\" -f -s --noproxy '${server_info.cfserved}' --user ${g.davuser}:${g.davpw} -T"; | |
"download_command_suffix" string => "${download_endpoint}"; | |
files: | |
!windows:: | |
"${g.rudder_inventories}" | |
transformer => "${download_command_prefix} ${this.promiser} ${download_command_suffix}", | |
depth_search => recurse_visible(1), | |
file_select => inventory_files, | |
classes => persistant_class("inventory_sent", "cant_send_inventory", 480), | |
comment => "Sending the inventory to the server"; | |
# On windows, the this.promiser variable is not evaluated the same way. We are forced to duplicate this block | |
windows:: | |
"${g.rudder_inventories}" | |
transformer => "${download_command_prefix} \"${this.promiser}\" ${download_command_suffix}", | |
depth_search => recurse_visible(1), | |
file_select => inventory_files, | |
classes => persistant_class("inventory_sent", "cant_send_inventory", 480), | |
comment => "Sending the inventory to the server"; | |
# Once we've successfully sent all inventories, remove them | |
!windows.inventory_sent.!cant_send_inventory:: | |
"${g.rudder_inventories}" | |
transformer => "${g.rudder_rm} -f ${this.promiser}", | |
depth_search => recurse_visible(1), | |
file_select => inventory_files, | |
classes => if_else("inventory_file_deleted", "cant_delete_inventory_file"), | |
comment => "Cleaning up inventory files already sent to the server"; | |
"${g.rudder_var_tmp}/inventory" | |
transformer => "${g.rudder_rm} -f ${this.promiser}", | |
depth_search => recurse_visible(1), | |
file_select => inventory_files, | |
classes => if_else("inventory_file_deleted", "cant_delete_inventory_file"), | |
comment => "Cleaning up inventory files already sent to the server"; | |
reports: | |
inventory_sent:: | |
"@@Inventory@@result_success@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#The inventory has been successfully sent"; | |
cant_send_inventory:: | |
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not send the inventory"; | |
cant_delete_inventory_file:: | |
"@@Inventory@@log_warn@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not delete inventory file after sending to server"; | |
} | |
##################################################### | |
#Adding the list of Virtual Machines into the report | |
#Adding the ids in the report | |
##################################################### | |
bundle edit_line add_information_to_inventory(RUDDERUUID, CFKEY, USER, POLSRVUUID) | |
{ | |
insert_lines: | |
"<UUID>${g.uuid}</UUID>${const.n}<USER>${USER}</USER>${const.n}<AGENTSNAME>${const.n}</AGENTSNAME>${const.n}<MACHINEID>${RUDDERUUID}</MACHINEID>${const.n}<CFKEY>${CFKEY}</CFKEY>${const.n}<HOSTNAME>${sys.fqhost}</HOSTNAME>${const.n}<POLICY_SERVER>${POLSRVUUID}</POLICY_SERVER>${const.n}" | |
location => after_deviceid, | |
insert_type => "preserve_block", | |
comment => "Add the UUID and CFKEY tags in the inventory file"; | |
any:: | |
"<VMS>${const.n}</VMS>${const.n}<USERSLIST>${const.n}</USERSLIST>" | |
insert_type => "preserve_block", | |
location => after_content; | |
rudder_inventory_cpuid_tool_present:: | |
"${inventory.CPUIDFile}" | |
insert_type => "file", | |
location => after_location("<HOSTNAME>"), | |
comment => "Adding the CPUID data in the inventory file"; | |
nova_edition:: | |
"<AGENTNAME>Nova</AGENTNAME>" | |
location => after_location("<AGENTSNAME>"), | |
comment => "Adding the agent data in the inventory file"; | |
community_edition:: | |
"<AGENTNAME>Community</AGENTNAME>" | |
location => after_location("<AGENTSNAME>"), | |
comment => "Adding the agent data in the inventory file"; | |
VirtualBoxInstalled:: | |
"${virtualMachines.VBoxListFile}" | |
insert_type => "file", | |
location => after_location("<VMS>"), | |
comment => "Adding the list of VM in the inventory file"; | |
VMWareInstalled:: | |
"${virtualMachines.VMWareListFile}" | |
insert_type => "file", | |
location => after_vm, | |
comment => "Adding the list of VM in the inventory file"; | |
} | |
bundle edit_line add_information_to_android_inventory(fullname, kernelname, kernelversion, name, version) | |
{ | |
insert_lines: | |
android:: | |
"<OPERATINGSYSTEM>${const.n}<FULL_NAME>${fullname}</FULL_NAME>${const.n}<KERNEL_NAME>${kernelname}</KERNEL_NAME>${const.n}<KERNEL_VERSION>${kernelversion}</KERNEL_VERSION>${const.n}<NAME>${name}</NAME>${const.n}<VERSION>${version}</VERSION>${const.n}</OPERATINGSYSTEM>" | |
location => after_location("<CONTENT>"), | |
insert_type => "preserve_block", | |
comment => "Adding the list of OPERATINGSYSTEM part"; | |
} | |
#this bundle is necessary for OCSInventory (but not for fusioninventory) | |
bundle edit_line add_accesslog_to_android_inventory(logdate) | |
{ | |
insert_lines: | |
android:: | |
"<ACCESSLOG><LOGDATE>${logdate}</LOGDATE></ACCESSLOG>" | |
location => after_location("</OPERATINGSYSTEM>"), | |
comment => "Adding log date"; | |
} | |
bundle edit_line add_users_information_to_inventory(userlist) | |
{ | |
insert_lines: | |
(windows.rudder_inventory_userlist_tool_present)|!windows:: | |
"<USER>${userlist}</USER>${const.n}" location => after_users, | |
comment => "Add the UUID and CFKEY tags in the inventory file"; | |
} | |
#Locators | |
body location after_location(pos) | |
{ | |
select_line_matching => ".*${pos}.*"; | |
before_after => "after"; | |
} | |
body location after_deviceid | |
{ | |
select_line_matching => ".*<DEVICEID>.*"; | |
before_after => "after"; | |
} | |
body location after_content | |
{ | |
select_line_matching => ".*<CONTENT>.*"; | |
before_after => "after"; | |
} | |
body location after_vm | |
{ | |
select_line_matching => ".*<VMS>.*"; | |
before_after => "after"; | |
} | |
body location after_users | |
{ | |
select_line_matching => ".*<USERSLIST>.*"; | |
before_after => "after"; | |
} | |
############### | |
# Editors | |
############## | |
# Convert a simple list in <VM TYPe="vmtype"><NAME>machine_name</NAME><UUID>value<UUID></VM> | |
bundle edit_line xmlify(ATTR) | |
{ | |
replace_patterns: | |
"\"(.*)\" \{(.*)\}" | |
replace_with=> xmled(${ATTR}); | |
} | |
body replace_with xmled(attribute) | |
{ | |
replace_value => "<VM TYPE=\"${attribute}\"><NAME>${match.1}</NAME><UUID>${match.2}</UUID></VM>"; | |
} | |
# select the inventory files that has the right extension | |
#I'd like to select also those older than 4 hours (ctime => irange(ago(0,0,0,4,0,0),now);) not working... | |
# (for some reason, ocs duplicated files over time) | |
body file_select inventory_files | |
{ | |
any:: | |
leaf_name => { ".*.ocs" }; | |
file_result => "leaf_name"; | |
#windows:: | |
# leaf_name => { ".*.xml" }; | |
# file_result => "leaf_name"; | |
} | |
body perms inventory_perms | |
{ | |
mode => "0700"; | |
} | |
body file_select one_day_age | |
# | |
# we can build old "include", "exclude", and "ignore" | |
# from these as standard patterns - these bodies can | |
# form a library of standard patterns | |
# | |
{ | |
mtime => irange(ago(1,0,0,0,0,0),ago(0,0,1,0,0,0)); | |
file_result => "mtime"; | |
} | |
bundle agent cleanForceInventoryFlagFile | |
{ | |
files: | |
"${g.rudder_base}/etc/force_inventory" | |
delete => tidy, | |
ifvarclass => "inventory_sent"; # if the force inventory file was present, and we successfully sent an inventory, clean up the flag file | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
####################################################### | |
# | |
# promises.cf | |
# | |
####################################################### | |
bundle common rudder_roles | |
{ | |
vars: | |
windows.!cygwin:: | |
"rudder_base" string => "${sys.winprogdir}\Rudder"; | |
"uuid_file" string => "${rudder_base}\etc\uuid.hive"; | |
!windows.!android:: | |
"rudder_base" string => "/opt/rudder"; | |
"uuid_file" string => "${rudder_base}/etc/uuid.hive"; | |
android:: | |
"rudder_base" string => "/data/rudder"; | |
"uuid_file" string => "${rudder_base}/etc/uuid.hive"; | |
any:: | |
"uuid" string => readfile("${uuid_file}", 60); | |
classes: | |
# Abort if no uuid is defined | |
"should_not_continue" not => fileexists("${uuid_file}"); | |
} | |
body common control | |
{ | |
any:: | |
output_prefix => "rudder"; | |
inputs => { | |
@{va.inputs_list} | |
}; | |
policy_server:: | |
bundlesequence => { @(va.bs),"setup_debian_backports","install_rsyslogd","propagatePromises","root_init_check","root_postgres_check","root_logrotate_check","root_integrity_check","root_technique_reload","root_networks_check","root_alive_check","root_password_check_file","root_password_check_ldap","root_password_check_psql","root_password_check_dav","root_password_restart_jetty", "fetchFusionTools", "virtualMachines", "doInventory", "sendInventoryToCmdb", @(va.end)}; | |
!policy_server:: | |
bundlesequence => { @{va.bs} , "fetchFusionTools", "virtualMachines", "doInventory" , @{va.end}}; | |
} | |
bundle common va | |
{ | |
vars: | |
policy_server:: | |
"bs" slist => { "startExecution", "check_disable_agent", "clean_red_button", "update", "set_red_button", "internal_security", "process_matching", "check_cf_processes", "check_uuid", "check_cron_daemon", "garbage_collection", "check_binaries_freshness" | |
}; | |
"inputs_list" slist => { | |
@(va.common_inputs),"distributePolicy/1.0/propagatePromises.cf","distributePolicy/1.0/rsyslogConf.cf","distributePolicy/1.0/initCheck.cf","distributePolicy/1.0/postgresCheck.cf","distributePolicy/1.0/logrotateCheck.cf","distributePolicy/1.0/integrityCheck.cf","distributePolicy/1.0/techniqueReload.cf","distributePolicy/1.0/networkCheck.cf","distributePolicy/1.0/aliveCheck.cf","distributePolicy/1.0/passwordCheck.cf" | |
}; | |
!policy_server:: | |
"bs" slist => { "startExecution", "check_disable_agent", "update", "internal_security", "process_matching", "check_cf_processes", "check_cron_daemon", "garbage_collection", "check_binaries_freshness" | |
}; | |
"inputs_list" slist => { | |
@{va.common_inputs} | |
}; | |
any:: | |
"end" slist => { "endExecution" }; | |
"common_inputs" slist => { | |
"common/1.0/cf-served.cf","common/1.0/cfengine_stdlib.cf","common/1.0/rudder_stdlib.cf","common/1.0/rudder_lib.cf","common/1.0/process_matching.cf","common/1.0/internal_security.cf","common/1.0/site.cf","common/1.0/update.cf","inventory/1.0/fetchFusionTools.cf","inventory/1.0/virtualMachines.cf","inventory/1.0/fusionAgent.cf" | |
}; | |
# definition of the machine roles | |
classes: | |
# Policy Server is a machine which delivers promises | |
"policy_server" expression => strcmp("root", "${rudder_roles.uuid}"); | |
# Root Server is the top policy server machine | |
"root_server" expression => strcmp("root", "${rudder_roles.uuid}"); | |
} | |
######################################################### | |
# Control execution | |
######################################################### | |
bundle agent startExecution | |
{ | |
reports: | |
cfengine_3:: | |
"@@Common@@log_info@@hasPolicyServer-root@@common-root@@00@@common@@StartRun@@${g.execRun}##${g.uuid}@#Start execution"; | |
} | |
bundle agent endExecution | |
{ | |
reports: | |
cfengine_3:: | |
"@@Common@@log_info@@hasPolicyServer-root@@common-root@@00@@common@@EndRun@@${g.execRun}##${g.uuid}@#End execution"; | |
rudder_promises_generated_error|no_update:: | |
"********************************************************************************* | |
* rudder-agent could not get an updated configuration from the policy server. * | |
* This can be caused by a network issue, an unavailable server, or if this * | |
* node has not yet been accepted in the Rudder root server. * | |
*********************************************************************************"; | |
} | |
########################################################## | |
# Check for "disable-agent" file and cleanly stop and | |
# warn about this if it is present | |
########################################################## | |
bundle agent check_disable_agent | |
{ | |
vars: | |
"components" slist => { "cf-serverd", "cf-execd", "cf-monitord" }; | |
classes: | |
"should_disable_agent" expression => fileexists("${g.rudder_disable_agent_file}"); | |
# Only define this class when we're ready to die - this is a special class name in "abortclasses" | |
"should_not_continue" | |
expression => "should_disable_agent", | |
ifvarclass => "abort_report_done"; | |
processes: | |
should_disable_agent:: | |
"${sys.workdir}/bin/${components}" | |
signals => { "term", "kill" }; | |
reports: | |
should_disable_agent:: | |
"FATAL: The file ${g.rudder_disable_agent_file} is present. Rudder will kill all running daemons and halt immediately." | |
classes => if_ok("abort_report_done"); | |
} | |
########################################################## | |
# Red Button part. | |
# When the file ${sys.workdir}/inputs/stop exists, we must stop the | |
# execution of the agent on all client machines | |
########################################################## | |
bundle agent clean_red_button() | |
{ | |
commands: | |
safe.policy_server:: | |
"${sys.workdir}/bin/cf-runagent" | |
args => "-Dsafe", | |
comment => "Propagate the safe information to children"; | |
files: | |
safe.policy_server:: | |
"${g.rudder_var}/share/[a-f0-9A-F\-]+/rules/cfengine-(community|nova)/stopFile" | |
delete => tidy, | |
comment => "Deleting the stop file on clients promises, cfengine is good to go"; | |
safe.!policy_server:: | |
"${sys.workdir}/inputs/stopFile" | |
delete => tidy, | |
comment => "Deleting the stop file, cfengine is good to go"; | |
reports: | |
safe:: | |
"@@Common@@result_repaired@@hasPolicyServer-root@@common-root@@00@@Red Button@@None@@${g.execRun}##${g.uuid}@#Authorizing Cfengine to restart"; | |
} | |
bundle agent set_red_button() | |
{ | |
classes: | |
policy_server:: | |
"danger" expression => fileexists("${g.rudder_var}/share/root/stopFile"); | |
methods: | |
danger:: | |
"any" usebundle => setStopFile; | |
danger.policy_server:: | |
"any" usebundle => stopClients; | |
} | |
bundle agent setStopFile | |
{ | |
files: | |
danger.!policy_server:: | |
"${sys.workdir}/inputs/stopFile" | |
create => "true"; | |
danger.policy_server:: | |
"${g.rudder_var}/share/[a-f0-9A-F\-]+/rules/cfengine-(community|nova)/stopFile" | |
create => "true"; | |
reports: | |
danger.!policy_server:: | |
"@@Common@@result_repaired@@hasPolicyServer-root@@common-root@00@@Red Button@@None@@${g.execRun}##${g.uuid}@#Creating local stop file for this node"; | |
danger.policy_server:: | |
"@@Common@@result_repaired@@hasPolicyServer-root@@common-root@@00@@Red Button@@None@@${g.execRun}##${g.uuid}@#Creating stop files for all clients of this policy server"; | |
} | |
bundle agent stopClients | |
{ | |
classes: | |
policy_server:: | |
"danger" expression => fileexists("${g.rudder_var}/share/root/stopFile"); | |
commands: | |
danger.policy_server:: | |
"${sys.workdir}/bin/cf-runagent" | |
args => "-Ddanger", | |
comment => "Propagate the danger information to children"; | |
reports: | |
danger.policy_server:: | |
"@@Common@@log_repaired@@hasPolicyServer-root@@common-root@@00@@Red Button@@None@@${g.execRun}##${g.uuid}@#Actively stopping CFEngine operations on all clients of this policy server (via cf-runagent)"; | |
} | |
bundle agent check_red_button_status() | |
{ | |
classes: | |
!policy_server:: | |
"should_not_continue" expression => fileexists("${sys.workdir}/inputs/stopFile"); | |
reports: | |
!should_not_continue:: | |
"@@Common@@result_success@@hasPolicyServer-root@@common-root@@00@@Red Button@@None@@${g.execRun}##${g.uuid}@#Red Button is not in effect, continuing as normal..."; | |
} | |
################################################### | |
# Check that CFengine services are up | |
################################################### | |
bundle agent check_cf_processes | |
{ | |
processes: | |
!windows:: | |
"${sys.workdir}/bin/cf-serverd" restart_class => "start_server"; | |
"${sys.workdir}/bin/cf-execd" restart_class => "start_executor"; | |
# If there is more than 2 cf-execd's, it means cf-execd is starting to | |
# go crazy, so we ask politely to these processes to shut down. | |
"${sys.workdir}/bin/cf-execd" | |
process_count => check_range("execd", "0","2"), | |
signals => { "term" }, | |
classes => if_repaired("execd_has_gone_wild"), | |
comment => "Checking if cf-execd has gone wild"; | |
# The same when there is more than 5 cf-agents | |
"${sys.workdir}/bin/cf-agent" | |
process_count => check_range("agent", "0","5"), | |
signals => { "term" }, | |
classes => if_repaired("agent_has_gone_wild"), | |
comment => "Checking if cf-agent has gone wild"; | |
# If there is more than 5 cf-execd's/cf-agents, it means that they are really | |
# going crazy. Let's be a bit less polite and more violent about killing them. | |
# | |
# These two promises overlap, because when you go past the 5-limit treshold, | |
# you still leave a chance for them to die with SIGTERM before the SIGKILL. | |
# | |
# Reason: The backend databases that stores the classes and some runtime | |
# parameters do really not appreciate beeing killed violently and may prevent | |
# the agent from operating properly. | |
"${sys.workdir}/bin/cf-execd" | |
process_count => check_range("execd", "0","5"), | |
signals => { "kill" }, | |
classes => if_repaired("execd_has_gone_really_wild"), | |
comment => "Checking if cf-execd has gone really wild"; | |
"${sys.workdir}/bin/cf-agent" | |
process_count => check_range("agent", "0","8"), | |
signals => { "kill" }, | |
classes => if_repaired("agent_has_gone_really_wild"), | |
comment => "Checking if cf-agent has gone really wild"; | |
windows:: | |
# Windows does only implement SIGTERM. Using SIGKILL here makes no sense | |
"cf-agent" | |
process_count => check_range("agent", "0","5"), | |
signals => { "term" }, | |
classes => if_repaired("agent_has_gone_wild"), | |
comment => "Checking if cf-agent has gone wild"; | |
services: | |
# By design, there can be only one cf-execd service running on Windows | |
windows:: | |
"CfengineNovaExec" | |
service_policy => "start", | |
service_method => u_bootstart, | |
comment => "Start the executor windows service now and at boot time"; | |
commands: | |
start_server:: | |
"${sys.cf_serverd}" | |
action => u_ifwin_bg, | |
classes => outcome("server"); | |
start_executor:: | |
"${sys.cf_execd}" | |
action => u_ifwin_bg, | |
classes => outcome("executor"); | |
reports: | |
!execd_has_gone_wild.!execd_has_gone_really_wild.!agent_has_gone_wild.!agent_has_gone_really_wild:: | |
"@@Common@@result_success@@hasPolicyServer-root@@common-root@@00@@Process checking@@None@@${g.execRun}##${g.uuid}@#There is an acceptable number of cf-execd processes (between 0 and 2) and cf-agent processes (between 0 and 5)"; | |
execd_has_gone_wild.!execd_has_gone_really_wild:: | |
"@@Common@@result_repaired@@hasPolicyServer-root@@common-root@@00@@Process checking@@None@@${g.execRun}##${g.uuid}@#Warning, more than 2 cf-execd processes were detected. They have been sent a graceful termination signal."; | |
execd_has_gone_really_wild:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Process checking@@None@@${g.execRun}##${g.uuid}@#ALERT: more than 5 cf-execd processes were detected. Killing processes that do not respect graceful termination signals."; | |
agent_has_gone_wild.!agent_has_gone_really_wild:: | |
"@@Common@@result_repaired@@hasPolicyServer-root@@common-root@@00@@Process checking@@None@@${g.execRun}##${g.uuid}@#Warning, more than 5 cf-agent processes were detected. They have been sent a graceful termination signal."; | |
agent_has_gone_really_wild:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Process checking@@None@@${g.execRun}##${g.uuid}@#ALERT: more than 8 cf-agent processes were detected. Killing processes that do not respect graceful termination signals."; | |
} | |
####################################################### | |
# UUID file enforcing | |
bundle agent check_uuid | |
{ | |
files: | |
"${g.uuid_file}" | |
create => "true", | |
edit_line => enforce_content("${g.uuid}"), | |
edit_defaults => noempty_backup, | |
perms => m("644"), | |
comment => "Setting the uuid variable in a machine"; | |
} | |
####################################################### | |
# Check if the cron daemon is running | |
# This only works with unix flavoured systems too | |
bundle agent check_cron_daemon | |
{ | |
vars: | |
redhat:: | |
"cron_bin" string => "crond$"; | |
"cron_restartcmd" string => "/etc/init.d/crond restart"; | |
ubuntu:: | |
"cron_bin" string => "cron$"; | |
"cron_restartcmd" string => "/etc/init.d/cron restart"; | |
!(redhat|ubuntu):: | |
"cron_bin" string => "/usr/sbin/cron$"; | |
"cron_restartcmd" string => "/etc/init.d/cron restart"; | |
processes: | |
!android.!windows:: | |
"${cron_bin}" | |
restart_class => "restart_crond"; | |
commands: | |
restart_crond:: | |
"${cron_restartcmd}" | |
comment => "Restarting crond", | |
classes => kept_if_else("crond_ok", "crond_restarted" , "crond_failed"); | |
reports: | |
crond_failed:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@CRON Daemon@@None@@${g.execRun}##${g.uuid}@#The CRON daemon was not running and could not be restarted"; | |
crond_restarted:: | |
"@@Common@@result_repaired@@hasPolicyServer-root@@common-root@@00@@CRON Daemon@@None@@${g.execRun}##${g.uuid}@#The CRON daemon has been successfully restarted"; | |
!restart_crond.!crond_restarted.!crond_failed.!android:: | |
"@@Common@@result_success@@hasPolicyServer-root@@common-root@@00@@CRON Daemon@@None@@${g.execRun}##${g.uuid}@#The CRON daemon is running"; | |
android|windows:: | |
"@@Common@@result_na@@hasPolicyServer-root@@common-root@@00@CRON Daemon@@None@@${g.execRun}##${g.uuid}@#This is a system without CRON: CRON verifications skipped !"; | |
} | |
######################################################## | |
# Trash every output report older than 30 days # | |
######################################################## | |
bundle agent garbage_collection | |
{ | |
files: | |
"${sys.workdir}/outputs" | |
delete => tidy, | |
file_select => days_old("7"), | |
depth_search => recurse("inf"); | |
"${g.rudder_var}/modified-files" | |
delete => tidy, | |
file_select => days_old("30"), | |
depth_search => recurse("inf"); | |
} | |
####################################################### | |
# Copy the CFengine binaries from the /opt repository | |
# to the CFengine working directory | |
bundle agent check_binaries_freshness | |
{ | |
vars: | |
community_edition:: | |
"components" slist => { "cf-agent", "cf-serverd", "cf-execd", "cf-monitord", "cf-promises", "cf-runagent", "cf-key", "rpmvercmp" }; | |
files: | |
!android.!nova_edition:: | |
"${sys.workdir}/bin/${components}" | |
perms => u_p("700"), | |
copy_from => cp("${g.rudder_bin}/${components}", "localhost"), | |
classes => kept_if_else("binaries_fresh", "binaries_rotten", "binaries_missing"), | |
action => immediate, | |
comment => "Copying the CFengine binaries from ${g.rudder_sbin}/sbin to ${sys.workdir}/bin"; | |
reports: | |
binaries_fresh.!binaries_rotten.!binaries_missing:: | |
"@@Common@@result_success@@hasPolicyServer-root@@common-root@@00@@Binaries update@@None@@${g.execRun}##${g.uuid}@#The CFengine binaries in ${sys.workdir}/bin are up to date"; | |
binaries_rotten.!binaries_missing:: | |
"@@Common@@result_repaired@@hasPolicyServer-root@@common-root@@00@@Binaries update@@None@@${g.execRun}##${g.uuid}@#The CFengine binaries have been updated in ${sys.workdir}/bin"; | |
binaries_missing:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Binaries update@@None@@${g.execRun}##${g.uuid}@#An error occurred while updating the CFengine binaries in ${sys.workdir}/bin"; | |
android:: | |
"@@Common@@result_success@@hasPolicyServer-root@@common-root@@00@@Binaries update@@None@@${g.execRun}##${g.uuid}@#This is an android machine: no CFEngine binaries update needed"; | |
nova_edition:: | |
"@@Common@@result_na@@hasPolicyServer-root@@common-root@@00@@Binaries update@@None@@${g.execRun}##${g.uuid}@#This is an CFEngine enterprise system: binaries update are handled differently"; | |
} | |
####################################################### | |
body agent control | |
{ | |
# if default runtime is 5 mins we need this for long jobs | |
ifelapsed => "1"; | |
#define here some environment variables | |
environment => { "DEBIAN_FRONTEND=noninteractive" }; | |
abortclasses => { "should_not_continue", "could_not_download_uuid" }; | |
agentfacility => "LOG_LOCAL6"; | |
# Repository where to put the copy of modified files | |
!windows:: | |
default_repository => "/var/rudder/modified-files"; | |
# we can not depend on DNS for mobile devices or NATed device | |
any:: | |
skipidentify => "true"; | |
} | |
####################################################### | |
body executor control | |
{ | |
splaytime => "1"; | |
schedule => { "Min00", "Min05", "Min10", "Min15", "Min20", "Min25", "Min30", "Min35", "Min40", "Min45", "Min50", "Min55" }; | |
executorfacility => "LOG_DAEMON"; | |
windows:: | |
# CFEngine best practice is to use full paths on Windows | |
exec_command => "${sys.cf_agent} -f \"${sys.workdir}\inputs\failsafe.cf\" & ${sys.cf_agent}"; | |
!windows:: | |
exec_command => "${sys.cf_agent} -f failsafe.cf && ${sys.cf_agent}"; | |
} | |
######################################################## | |
#Enforce that the file only contains this information | |
bundle edit_line enforce_content(str) | |
{ | |
delete_lines: | |
"${str}" not_matching => "true"; | |
insert_lines: | |
"${str}"; | |
} | |
body process_count system_check_process_count(name, max, min) | |
{ | |
match_range => irange("${min}","${max}"); | |
out_of_range_define => { "${name}_is_defective" }; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# Failsafe file | |
# | |
body common control | |
{ | |
bundlesequence => { "check_lock_db_problem", "init_files", "update" }; | |
inputs => { "common/1.0/update.cf" }; | |
output_prefix => "rudder"; | |
} | |
body agent control { | |
# we can not depend on DNS for mobile devices or NATed device | |
any:: | |
skipidentify => "true"; | |
} | |
bundle common g | |
{ | |
vars: | |
android:: | |
"rudder_base" string => "/data/rudder"; | |
"rudder_var" string => "/data/rudder"; | |
!windows.!android:: | |
"rudder_base" string => "/opt/rudder"; | |
solaris:: | |
"rudder_var" string => "/opt/rudder/var"; | |
!windows.!solaris.!android:: | |
"rudder_var" string => "/var/rudder"; | |
!windows:: | |
"rudder_bin" string => "${rudder_base}/bin"; | |
"rudder_sbin" string => "${rudder_base}/sbin"; | |
"rudder_base_sbin" string => "${rudder_base}/sbin"; #folder where tools are installed | |
"rudder_tools" string => "${rudder_var}/tools"; | |
"rudder_ncf" string => "${rudder_var}/ncf"; | |
"uuid_file" string => "${rudder_base}/etc/uuid.hive"; | |
windows:: | |
"rudder_base" string => "${sys.winprogdir}\Rudder"; | |
"rudder_bin" string => "${rudder_base}\bin"; | |
"rudder_var" string => "${sys.winprogdir}\Rudder\var"; | |
"rudder_sbin" string => "${rudder_base}\sbin"; | |
"rudder_tools" string => "${rudder_sbin}"; | |
"rudder_ncf" string => "${rudder_var}\ncf"; | |
"uuid_file" string => "${rudder_base}\etc\uuid.hive"; | |
# The time at which the execution started | |
(linux|cygwin).!(centos_3|redhat_3|centos_4|redhat_4):: | |
"execRun" string => execresult("/bin/date --rfc-3339=second", "noshell"); | |
(linux|cygwin).(centos_3|redhat_3|centos_4|redhat_4):: | |
"execRun" string => execresult("/bin/date -u \"+%Y-%m-%d %T+00:00\"", "noshell"); | |
windows.!cygwin:: | |
"execRun" string => execresult("\"${g.rudder_sbin}\getDate.bat\"", "noshell"); | |
android:: | |
"execRun" string => execresult("/system/xbin/date \"+%Y-%m-%d %T+02:00\"", "noshell"); | |
aix:: | |
# AIX's date command doesn't have a "%z" option, so we fake it by using UTC | |
"execRun" string => execresult("/bin/date -u \"+%Y-%m-%d %T+00:00\"", "noshell"); | |
!linux.!cygwin.!windows.!android.!aix:: | |
"execRun" string => execresult("/bin/date \"+%Y-%m-%d %T%:z\"", "noshell"); | |
any:: | |
"uuid" string => readfile("${g.uuid_file}", 60); | |
"excludedreps" slist => { "\.X11", ".*kde.*", "\.svn", "perl" }; | |
"rudder_tools_origin" string => "/var/rudder/tools"; | |
"rudder_ncf_origin_common" string => "/usr/share/ncf/tree"; | |
"rudder_ncf_origin_local" string => "/var/rudder/configuration-repository/ncf"; | |
"rudder_tools_updated_origin" string => "${rudder_tools_origin}/rudder_tools_updated"; | |
"rudder_tools_updated" string => "${rudder_tools}/rudder_tools_updated"; | |
} | |
bundle common rudder_roles | |
{ | |
classes: | |
# Abort if no uuid is defined | |
"should_not_continue" not => fileexists("${g.uuid_file}"); | |
# Policy Server is a machine which delivers promises | |
"policy_server" expression => strcmp("root","${g.uuid}"); | |
# Root Server is the top policy server machine | |
"root_server" expression => strcmp("root","${g.uuid}"); | |
# We are in the failsafe phase | |
"failsafe" expression => "any"; | |
} | |
############################################ | |
#generate a key if not present | |
bundle agent init_files | |
{ | |
vars: | |
"components" slist => { "cf-agent", "cf-serverd", "cf-execd", "cf-monitord", "cf-promises", "cf-runagent", "cf-key", "cf-hub" }; | |
nova_edition:: | |
"cfengine_install_path" string => "/usr/local"; | |
community_edition:: | |
"cfengine_install_path" string => "${g.rudder_base}"; | |
classes: | |
"missing_key" not => fileexists("${sys.workdir}/ppkeys/localhost.priv"); | |
files: | |
cfengine_community.!windows:: | |
"${sys.workdir}/bin/${components}" | |
perms => u_p("700"), | |
copy_from => cp("${cfengine_install_path}/bin/${components}","localhost"), | |
action => immediate; | |
commands: | |
cygwin.missing_key:: | |
"${sys.workdir}/bin/cf-key.exe"; | |
windows.missing_key.!cygwin:: | |
"\"${sys.workdir}\bin\cf-key\""; | |
!windows.!cygwin.missing_key:: | |
"${sys.workdir}/bin/cf-key"; | |
} | |
# This bundle will check the "last successful inputs update", and if it is older | |
# than 1 hour, remove cf_lock.db (and only this DB), to give CFEngine a chance | |
# to run properly again. | |
bundle agent check_lock_db_problem{ | |
vars: | |
cfengine_3_0|cfengine_3_1|cfengine_3_2:: | |
"cf_lock_filename" string => "cf_lock.db"; | |
!(cfengine_3_0|cfengine_3_1|cfengine_3_2):: | |
"cf_lock_filename" string => "cf_lock.tcdb"; | |
files: | |
# The aim of this promise is to create a class when this file is older | |
# than one hour. The class can not be created without touching but in | |
# order to not modifing the mtime we use warn_only. | |
"${sys.workdir}/last_successful_inputs_update" | |
file_select => over_an_hour, | |
touch => "true", | |
action => warn_only, | |
classes => success("last_successful_inputs_update_too_old", "last_successful_inputs_update_check_error", "last_successful_inputs_update_ok"); | |
"${sys.workdir}/state/${cf_lock_filename}" | |
delete => tidy, | |
ifvarclass => "last_successful_inputs_update_too_old", | |
classes => success("cf_lock_removed", "cf_lock_error_removing", "cf_lock_not_deleted"); | |
reports: | |
cf_lock_removed:: | |
"@@Common@@log_repaired@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Promises had not been updated for over an hour, this could indicate a broken lockfile. cf_lock DB file was removed."; | |
cf_lock_error_removing:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Promises have not been updated for over an hour, this could indicate a broken lockfile, but an error occured when trying to remove it"; | |
} | |
body file_select over_an_hour() | |
{ | |
# Select file which are older than one hour | |
# Use of positive mtime instead of negative one | |
# In order to avoid corner effects | |
mtime => irange(ago(0,0,0,1,0,0), now); | |
file_result => "!mtime"; | |
} | |
body depth_search recurse(d) | |
{ | |
depth => "${d}"; | |
} | |
#perms validation | |
body perms u_p(p) | |
{ | |
mode => "${p}"; | |
} | |
#server may be a list | |
body copy_from cp(from,server) | |
{ | |
servers => { "${server}" }; | |
source => "${from}"; | |
compare => "digest"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
body action immediate | |
{ | |
ifelapsed => "0"; | |
} | |
body depth_search recurse_ignore(d,list) | |
{ | |
depth => "${d}"; | |
exclude_dirs => { @{list} }; | |
} | |
body delete tidy | |
{ | |
dirlinks => "delete"; | |
rmdirs => "true"; | |
} | |
body action warn_only | |
{ | |
action_policy => "warn"; | |
ifelapsed => "60"; | |
} | |
body file_select exclude(name) | |
{ | |
leaf_name => { "$(name)"}; | |
file_result => "!leaf_name"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
####################################################### | |
# | |
# Site specific promises | |
# | |
####################################################### | |
bundle common g | |
{ | |
vars: | |
android:: | |
"rudder_base" string => "/data/rudder"; | |
"rudder_var" string => "/data/rudder"; | |
"rudder_curl" string => "/system/bin/curl"; | |
"rudder_rm" string => "/system/xbin/rm"; | |
!windows.!android:: | |
"rudder_base" string => "/opt/rudder"; | |
"rudder_curl" string => "/usr/bin/curl"; | |
"rudder_rm" string => "/bin/rm"; | |
solaris:: | |
"rudder_var" string => "/opt/rudder/var"; | |
!solaris.!windows.!android:: | |
"rudder_var" string => "/var/rudder"; | |
!windows:: | |
"rudder_bin" string => "${rudder_base}/bin"; | |
"rudder_sbin" string => "${rudder_base}/sbin"; | |
"rudder_var_tmp" string => "${rudder_var}/tmp"; # tmp generated data | |
"rudder_base_sbin" string => "${rudder_base}/sbin"; #folder where tools are installed | |
"rudder_inventories" string => "${rudder_var}/inventories"; | |
"uuid_file" string => "${rudder_base}/etc/uuid.hive"; | |
"rudder_disable_agent_file" string => "${rudder_base}/etc/disable-agent"; | |
"rudder_tools" string => "${rudder_var}/tools"; | |
"rudder_ncf" string => "${rudder_var}/ncf"; | |
"crontab" string => "/etc/crontab"; | |
# DEPRECATED: This variable is used in pre-2.9 Techniques. | |
"rudder_dependencies" string => "${rudder_var}/tools"; | |
windows:: | |
"rudder_base" string => "${sys.winprogdir}\Rudder"; | |
"rudder_bin" string => "${rudder_base}\bin"; | |
"rudder_sbin" string => "${rudder_base}\sbin"; | |
"rudder_var" string => "${sys.winprogdir}\Rudder\var"; | |
"rudder_var_tmp" string => "${rudder_var}\tmp"; # tmp generated data | |
"rudder_base_sbin" string => "${rudder_base}\sbin"; #folder where tools are installed | |
"rudder_inventories" string => "${rudder_var}\inventories"; | |
"rudder_base_sbin_arg" string => "${sys.winprogdir}\Rudder\sbin"; # for the installer command line | |
"rudder_tools" string => "${rudder_sbin}"; | |
"rudder_ncf" string => "${rudder_base}\ncf"; | |
"escaped_workdir" string => escape("${sys.workdir}"); | |
"rudder_curl" string => "${rudder_base_sbin}\curl\curl.exe"; | |
# DEPRECATED: This variable is used in pre-2.9 Techniques. | |
"rudder_dependencies" string => "${rudder_sbin}"; | |
"uuid_file" string => "${rudder_base}\etc\uuid.hive"; | |
"rudder_disable_agent_file" string => "${rudder_base}\etc\disable-agent"; | |
any:: | |
"uuid" string => readfile("${g.uuid_file}", 60); | |
"server_shares_folder" string => "/var/rudder/share/${uuid}/promises/shares"; | |
"rudder_var_reports" string => "${rudder_var}/reports"; | |
"davuser" string => "rudder"; | |
"davpw" string => "rudder"; | |
"minicurl" string => "${rudder_bin}/rudder-perl ${sys.workdir}/inputs/common/utilities/minicurl"; | |
"excludedreps" slist => { "\.X11", ".*kde.*", "\.svn", "perl" }; | |
"rudder_tools_origin" string => "/var/rudder/tools"; | |
"rudder_ncf_common_origin" string => "/var/rudder/ncf/common"; | |
"rudder_ncf_origin_common" string => "/usr/share/ncf/tree"; | |
"rudder_ncf_origin_local" string => "/var/rudder/configuration-repository/ncf"; | |
"rudder_tools_updated_origin" string => "${rudder_tools_origin}/rudder_tools_updated"; | |
"rudder_tools_updated" string => "${rudder_tools}/rudder_tools_updated"; | |
# DEPRECATED: This variable is used in pre-2.9 Techniques. | |
"rudder_dependencies_origin" string => "/var/rudder/tools"; | |
# The time at which the execution started | |
(linux|cygwin).!(centos_3|redhat_3|centos_4|redhat_4):: | |
"execRun" string => execresult("/bin/date --rfc-3339=second", "noshell"); | |
(linux|cygwin).(centos_3|redhat_3|centos_4|redhat_4):: | |
# We would like to use date's "--rfc-3339=second" option here, but it is not available on older OSes (RHEL 3/4, AIX 5...) | |
"execRun" string => execresult("/bin/date -u \"+%Y-%m-%d %T+00:00\"", "noshell"); | |
windows.!cygwin:: | |
"execRun" string => execresult("\"${g.rudder_sbin}\getDate.bat\"", "noshell"); | |
android:: | |
"execRun" string => execresult("/system/xbin/date \"+%Y-%m-%d %T%z\" | sed 's/\([-+][0-9][0-9]\)\([0-9][0-9]\)$/\1:\2/'", "useshell"); | |
aix:: | |
# AIX's date command doesn't have a "%z" option, so we fake it by using UTC | |
"execRun" string => execresult("/bin/date -u \"+%Y-%m-%d %T+00:00\"", "noshell"); | |
!linux.!cygwin.!windows.!android.!aix:: | |
"execRun" string => execresult("/bin/date \"+%Y-%m-%d %T%:z\"", "noshell"); | |
classes: | |
"curl_installed" expression => isexecutable("${rudder_curl}"); | |
} | |
##################################################################################### | |
# Copyright 2011-2012 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# This is Rudder's library of common CFEngine functions. | |
# | |
# Only bodies and editbundles are to be appended here !!! | |
# | |
##################################################################################### | |
################################################### | |
# Knowledge from the original stdlib | |
################################################### | |
# Uses a specific prefix to avoid collision | |
# when the stdlib will be updated | |
################################################### | |
bundle common rudder_debian_knowledge | |
# @depends paths | |
# @brief common Rudder Debian knowledge bundle | |
# | |
# This common bundle has useful information about Debian. | |
{ | |
vars: | |
"dpkg_compare_equal" string => "/usr/bin/dpkg --compare-versions '${v1}' eq '${v2}'"; | |
"dpkg_compare_less" string => "/usr/bin/dpkg --compare-versions '${v1}' lt '${v2}'"; | |
} | |
bundle common rudder_rpm_knowledge | |
# @depends paths | |
# @brief common Rudder RPM knowledge bundle | |
# | |
# This common bundle has useful information about platforms using RPM | |
{ | |
vars: | |
"rpm_compare_equal" string => "${sys.workdir}/bin/rpmvercmp '${v1}' eq '${v2}'"; | |
"rpm_compare_less" string => "${sys.workdir}/bin/rpmvercmp '${v1}' lt '${v2}'"; | |
} | |
################################################### | |
body depth_search recurse_visible(d) | |
{ | |
depth => "${d}"; | |
exclude_dirs => { "\..*" }; | |
} | |
#perms validation | |
body perms u_p(p) | |
{ | |
mode => "${p}"; | |
} | |
######################################################### | |
#server may be a list | |
body copy_from cp(from,server) | |
{ | |
servers => { "${server}" }; | |
source => "${from}"; | |
compare => "digest"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
body copy_from scp(from, server,compare,trustkey,preserve,purge) | |
{ | |
servers => { "${server}" }; | |
source => "${from}"; | |
compare => "${compare}"; | |
encrypt => "true"; | |
verify => "true"; | |
trustkey => "${trustkey}"; | |
preserve => "${preserve}"; #preserver permissions | |
purge => "${purge}"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
# This is an evolved version of copy_from scp that uses local copies if we are | |
# running on a policy server instead of copying from a localhost remote blindly. | |
body copy_from rudder_copy_from(from, server,compare,trustkey,preserve,purge) { | |
source => "${from}"; | |
compare => "${compare}"; | |
encrypt => "true"; | |
verify => "true"; | |
trustkey => "${trustkey}"; | |
preserve => "${preserve}"; # Preserve the permissions | |
purge => "${purge}"; | |
copy_backup => "timestamp"; | |
!root_server:: | |
servers => { "${server}" }; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
body copy_from copy(from) | |
{ | |
source => "${from}"; | |
copy_backup => "false"; | |
preserve => "true"; | |
} | |
body copy_from copy_digest(from) | |
{ | |
source => "${from}"; | |
copy_backup => "timestamp"; | |
preserve => "true"; | |
compare => "digest"; | |
} | |
######################################################### | |
body classes class_trigger(if,else,kept) | |
{ | |
promise_kept => { "${kept}" }; | |
promise_repaired => { "${if}" }; | |
repair_failed => { "${else}" }; | |
repair_denied => { "${else}" }; | |
repair_timeout => { "${else}" }; | |
} | |
######################################################### | |
body location append | |
{ | |
before_after => "after"; | |
} | |
######################################################### | |
body package_method yum_remi | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/yum list installed"; | |
package_list_name_regex => "([^.]+).*"; | |
package_list_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_list_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_installed_regex => ".*installed.*"; | |
package_name_convention => "${name}.${arch}"; | |
package_delete_convention => "${name}"; | |
package_add_command => "/usr/bin/yum --enablerepo=remi -y install"; | |
package_delete_command => "/bin/rpm -e"; | |
package_verify_command => "/bin/rpm -V"; | |
} | |
#perms validation | |
body perms p(user,mode) | |
{ | |
owners => { "${user}" }; | |
mode => "${mode}"; | |
} | |
############################################ | |
body file_select cf3_files | |
{ | |
leaf_name => { "cf-.*" }; | |
file_result => "leaf_name"; | |
} | |
######################################################### | |
body changes lay_trip_wire | |
{ | |
hash => "best"; | |
report_changes => "content"; | |
update_hashes => "yes"; | |
} | |
######################################################## | |
body action longjob | |
{ | |
ifelapsed => "240"; # run only every 4 hours | |
} | |
####################################################### | |
# For the library | |
####################################################### | |
body edit_defaults noempty_backup | |
{ | |
empty_file_before_editing => "false"; | |
edit_backup => "timestamp"; # we want to keep a track of everything | |
max_file_size => "1024000"; | |
} | |
body edit_defaults empty_backup | |
{ | |
empty_file_before_editing => "true"; | |
edit_backup => "timestamp"; | |
max_file_size => "1024000"; | |
} | |
body edit_defaults def_no_backup | |
{ | |
empty_file_before_editing => "false"; | |
edit_backup => "false"; | |
max_file_size => "1024000"; | |
} | |
######################################################## | |
######################################################## | |
bundle edit_line DeleteLinesMatching(regex) | |
{ | |
delete_lines: | |
"${regex}" | |
action => WarnOnly; | |
} | |
######################################################## | |
body action WarnOnly | |
{ | |
action_policy => "warn"; | |
} | |
######################################## | |
# Bodies | |
######################################## | |
body replace_with With(x) | |
{ | |
replace_value => "${x}"; | |
occurrences => "all"; | |
} | |
######################################## | |
################################ | |
# For commands with a > | |
################################ | |
body contain outputable | |
{ | |
useshell => "true"; | |
no_output=> "false"; | |
} | |
################################ | |
# For commands with a >, in a dir | |
################################ | |
body contain outputable_dir(dir) | |
{ | |
useshell => "true"; | |
no_output=> "false"; | |
chdir => "${dir}"; | |
} | |
################################ | |
# Process is launched ? | |
################################ | |
body process_count islaunched(class) | |
{ | |
match_range => irange("1", "500"); | |
in_range_define => { "${class}"}; | |
out_of_range_define => {"no_${class}"}; | |
} | |
########################################################################################### | |
# Cancel class | |
# Cancel every classes passed by argument | |
########################################################################################## | |
body classes cancel_all_classes(class_to_cancel) { | |
cancel_kept => { "${class_to_cancel}" }; | |
cancel_repaired => { "${class_to_cancel}" }; | |
cancel_notkept => { "${class_to_cancel}" }; | |
} | |
########################################################################################### | |
# Persistent class | |
# If the promise is repaired, define repaired for length minutes and undefine failed | |
# If the promise is not kept, undefine repaired and define failed for length minutes | |
########################################################################################## | |
body classes persistant_class(repaired, failed, length) | |
{ | |
promise_repaired => { "${repaired}" }; | |
repair_failed => { "${failed}" }; | |
repair_denied => { "${failed}" }; | |
repair_timeout => { "${failed}" }; | |
cancel_repaired => {"${failed}"}; | |
cancel_notkept => {"${repaired}"}; | |
persist_time => "${length}"; | |
} | |
########################################################################################### | |
# Persistent class | |
# If the promise is repaired/kept, define repaired for length minutes and undefine failed | |
# If the promise is not kept, undefine repaired and define failed for length minutes | |
########################################################################################## | |
body classes set_persist_classes(repaired, failed, length) | |
{ | |
promise_kept => { "${repaired}" }; | |
promise_repaired => { "${repaired}" }; | |
repair_failed => { "${failed}" }; | |
repair_denied => { "${failed}" }; | |
repair_timeout => { "${failed}" }; | |
cancel_kept => {"${failed}"}; | |
cancel_repaired => {"${failed}"}; | |
cancel_notkept => {"${repaired}"}; | |
persist_time => "${length}"; | |
} | |
################################################ | |
# kept_if_else | |
# set kept if the promise is kept | |
# yes if repaired | |
# no if cannot repair | |
################################################ | |
body classes kept_if_else(kept, yes,no) | |
{ | |
promise_kept => { "${kept}" }; | |
promise_repaired => { "${yes}" }; | |
repair_failed => { "${no}" }; | |
repair_denied => { "${no}" }; | |
repair_timeout => { "${no}" }; | |
} | |
######################################### | |
# Make a local copy with a digest check # | |
######################################### | |
body copy_from digest_cp(from) | |
{ | |
source => "${from}"; | |
compare => "digest"; | |
copylink_patterns => { ".*" }; | |
} | |
################################################ | |
# kept_if_else with persistant classes | |
# set kept if the promise is kept | |
# yes if repaired | |
# no if cannot repair | |
################################################ | |
body classes kept_if_else_persist(kept, repaired, failed, persist) { | |
promise_kept => { "${kept}" }; | |
promise_repaired => { "${repaired}" }; | |
repair_failed => { "${failed}" }; | |
repair_denied => { "${failed}" }; | |
repair_timeout => { "${failed}" }; | |
persist_time => "${persist}"; | |
} | |
################################################ | |
# Special kept_if_else | |
# set kept if the promise is kept | |
# yes if repaired | |
# no if cannot repair | |
# Trigger an additionnal promise if repaired | |
################################################ | |
body classes kept_if_else_hook(kept,yes,no,hook) | |
{ | |
promise_kept => { "${kept}" }; | |
promise_repaired => { "${yes}", "${hook}" }; | |
repair_failed => { "${no}" }; | |
repair_denied => { "${no}" }; | |
repair_timeout => { "${no}" }; | |
} | |
################################################ | |
# Simple group adjustment body | |
################################################ | |
body perms group(group) | |
{ | |
groups => { "${group}" }; | |
} | |
################################################ | |
# Same as recurse but without xdev | |
# and including the current dir | |
################################################ | |
body depth_search recurse_with_current(d) | |
{ | |
depth => "${d}"; | |
include_basedir => "true"; | |
xdev => "false"; | |
} | |
######################################################################## | |
# Mount an NFS share, and allow the user to select if it is persistent # | |
######################################################################## | |
body mount rudder_nfs(server,source,type,persistence) | |
{ | |
mount_type => "${type}"; | |
mount_source => "${source}"; | |
mount_server => "${server}"; | |
edit_fstab => "${persistence}"; | |
} | |
######################################################################## | |
# Same as std_defs, allowing user to specify the file erase policy # | |
######################################################################## | |
body edit_defaults rudder_empty_select(select) | |
{ | |
empty_file_before_editing => "${select}"; | |
max_file_size => "1024000"; | |
edit_backup => "timestamp"; | |
} | |
######################################################################## | |
# Handle a directory recursively, including the dir itself # | |
######################################################################## | |
body depth_search recurse_withroot(d) | |
{ | |
depth => "${d}"; | |
# xdev => "true"; | |
include_basedir => "true"; | |
} | |
######################################################################## | |
# Change group and mode of a file/directory # | |
######################################################################## | |
body perms mg(mode,group) | |
{ | |
groups => { "${group}" }; | |
mode => "${mode}"; | |
} | |
######################################################################## | |
# Select a file using a date AND a pattern # | |
######################################################################## | |
body file_select date_pattern(age, pattern) | |
{ | |
mtime => irange("0", ago(0,0,"${age}",0,0,0)); | |
leaf_name => { "${pattern}" }; | |
file_result => "leaf_name.mtime"; | |
} | |
######################################################################## | |
# Install a package using rug # | |
######################################################################## | |
body package_method rudder_rug | |
{ | |
package_changes => "individual"; | |
package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; | |
package_patch_list_command => "/usr/bin/rug patches"; | |
package_list_update_ifelapsed => "240"; | |
package_installed_regex => "i.*"; | |
package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_patch_installed_regex => ".*Installed.*|.*Not Applicable.*"; | |
package_patch_name_regex => "[^|]+\|\s+([^\s]+).*"; | |
package_patch_version_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_name_convention => "${name}"; | |
package_add_command => "/usr/bin/rug install -y"; | |
package_delete_command => "/usr/bin/rug remove -y"; | |
package_update_command => "/usr/bin/rug update -y"; | |
#Unsure about the behavior of this command ... | |
#package_patch_command => "/usr/bin/rug patch-info"; | |
package_verify_command => "/usr/bin/rug verify -y$"; # $ means no args | |
# make correct version comparisons | |
package_version_less_command => "${rudder_rpm_knowledge.rpm_compare_less}"; | |
package_version_equal_command => "${rudder_rpm_knowledge.rpm_compare_equal}"; | |
} | |
######################################################################## | |
# Install a package using yum but with a check from rpm # | |
######################################################################## | |
body package_method rudder_yum | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'"; | |
package_list_name_regex => "^(\S+?)\s\S+?\s\S+$"; | |
package_list_version_regex => "^\S+?\s(\S+?)\s\S+$"; | |
package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$"; | |
package_installed_regex => ".*"; | |
package_name_convention => "${name}"; | |
package_list_update_command => "/usr/bin/yum --quiet check-update"; | |
package_list_update_ifelapsed => "240"; | |
package_patch_name_regex => "([^.]+).*"; | |
package_patch_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_patch_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_add_command => "/usr/bin/yum -y install"; | |
package_update_command => "/usr/bin/yum -y update"; | |
package_patch_command => "/usr/bin/yum -y update"; | |
package_delete_command => "/bin/rpm -e --nodeps --allmatches"; | |
package_verify_command => "/bin/rpm -V"; | |
# make correct version comparisons | |
package_version_less_command => "${rudder_rpm_knowledge.rpm_compare_less}"; | |
package_version_equal_command => "${rudder_rpm_knowledge.rpm_compare_equal}"; | |
} | |
################################################### | |
# edit_line prepend | |
################################################### | |
bundle edit_line prepend(lines) | |
{ | |
insert_lines: | |
"${lines}" | |
comment => "Prepending line : ${lines}", | |
location => start; | |
} | |
################################################### | |
# edit_line rudder_line_insertion | |
################################################### | |
bundle edit_line rudder_line_insertion(lines, location) | |
{ | |
insert_lines: | |
"${lines}" | |
comment => "Adding line: ${lines}", | |
location => rudder_location_before_after("${location}"); | |
} | |
######################################################### | |
body location rudder_location_before_after(location) | |
{ | |
before_after => "${location}"; | |
} | |
################################################### | |
# edit_line replace_line | |
################################################### | |
bundle edit_line replace_line(regex,replacement) | |
{ | |
replace_patterns: | |
"${regex}" | |
replace_with => With("${replacement}"), | |
comment => "Replace every occurence of ${regex} with ${replacement}"; | |
} | |
################################################### | |
# edit_line from_to | |
################################################### | |
bundle edit_line from_to(from,to) | |
{ | |
delete_lines: | |
"${from}" comment => "Reset ${from}"; | |
insert_lines: | |
"${to}" comment => "Add ${to}"; | |
} | |
################################################### | |
# contain in_shell_silent | |
################################################### | |
body contain in_shell_silent | |
{ | |
useshell => "true"; | |
no_output => "true"; | |
} | |
################################################### | |
# edit_line insert_rudder_disclaimer | |
################################################### | |
bundle edit_line insert_rudder_disclaimer | |
{ | |
insert_lines: | |
"## File managed by Rudder - Edit with caution, some changes may disappear (especially passwords) ##" | |
location => start; | |
} | |
##################################################################################### | |
# Copyright 2012 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# Rudder Promise Body and Bundle Library | |
# | |
# This library includes standardized bundles and bodies to be used as part of the | |
# "best practices" in the Techniques writing | |
# | |
################################################## | |
# classes body | |
################################################## | |
# | |
# Automatically defines classes bases on a given prefix | |
# The classes are defined based on the romises outcome | |
# | |
body classes rudder_common_classes(prefix) | |
{ | |
promise_kept => { "${prefix}_kept" }; | |
promise_repaired => { "${prefix}_repaired" }; | |
repair_failed => { "${prefix}_failed" , "${prefix}_error" }; | |
repair_denied => { "${prefix}_denied" , "${prefix}_error" }; | |
repair_timeout => { "${prefix}_timeout", "${prefix}_error" }; | |
} | |
################################################## | |
# files bundles | |
################################################## | |
# | |
# Insert the standard Rudder disclaimer into a file | |
# | |
bundle edit_line rudder_common_disclaimer | |
{ | |
insert_lines: | |
"############################################################# | |
### This file is protected by your Rudder infrastructure. ### | |
### Manually editing the file might lead your Rudder ### | |
### infrastructure to change back the server's ### | |
### configuration and/or to raise a compliance alert. ### | |
############################################################# | |
" | |
location => start, | |
insert_type => "preserve_block"; | |
} | |
# | |
# Select files older than X months | |
# | |
body file_select rudder_common_months_old(months) | |
{ | |
mtime => irange(0,ago(0,"${months}",0,0,0,0)); | |
file_result => "mtime"; | |
} | |
# | |
# Select files older than X days | |
# | |
body file_select rudder_common_days_old(days) | |
{ | |
mtime => irange(0,ago(0,0,"${days}",0,0,0)); | |
file_result => "mtime"; | |
} | |
# | |
# Select files older than X hours | |
# | |
body file_select rudder_common_hours_old(hours) | |
{ | |
mtime => irange(0,ago(0,0,0,"${hours}",0,0)); | |
file_result => "mtime"; | |
} | |
# | |
# Select files older than X minutes | |
# | |
body file_select rudder_common_minutes_old(minutes) | |
{ | |
mtime => irange(0,ago(0,0,0,0,"${minutes}",0)); | |
file_result => "mtime"; | |
} | |
################################################ | |
# Reporting bundles | |
################################################ | |
# | |
# Create and send a report to the server | |
# This bundle takes 6 parameters : | |
# technique_name : the name of the technique, human readable | |
# status : the status of the Component, among the following values | |
# result_success | |
# result_error | |
# result_repaired | |
# log_repaired (for logging only) | |
# log_warn (for logging only) | |
# log_info (for logging only) | |
# log_debug (for logging only) | |
# log_trace (for logging only) | |
# identifier : the identifier of the current Rule and Directive | |
# component_name : the name of the component within the Technique | |
# component_key : the value of the component reference variable (or None if undefined) | |
# message : An explanation message understandable by a human | |
# | |
bundle agent rudder_common_report(technique_name, status, identifier, component_name, component_key, message) | |
{ | |
reports: | |
cfengine_3:: | |
"@@${technique_name}@@${status}@@${identifier}@@${component_name}@@${component_key}@@${g.execRun}##${g.uuid}@#${message}"; | |
} | |
# | |
# Automatically create reports based on existing classes starting by | |
# class_prefix (as defined by the body classes rudder_common_classes) | |
# Takes 6 parameters | |
# technique_name : the name of the technique, human readable | |
# class_prefix : the prefix of a set of classes to reporting on (suffixes with "kept", "repaired" or "error") | |
# identifier : the identifier of the current Rule and Directive | |
# component_name : the name of the component within the Technique | |
# component_key : the value of the component reference variable (None if it does not exists) | |
# message_prefix : The begining of an explanation message understandable by a human | |
# | |
bundle agent rudder_common_reports_generic(technique_name, class_prefix, identifier, component_name, component_key, message_prefix) | |
{ | |
methods: | |
"success" | |
usebundle => rudder_common_report("${technique_name}", "result_success", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was correct"), | |
ifvarclass => "${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; | |
"repaired" | |
usebundle => rudder_common_report("${technique_name}", "result_repaired", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was repaired"), | |
ifvarclass => "${class_prefix}_repaired.!${class_prefix}_error"; | |
"error" | |
usebundle => rudder_common_report("${technique_name}", "result_error", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} could not be repaired"), | |
ifvarclass => "${class_prefix}_error"; | |
} | |
############################################################################ | |
# Copyright (C) Cfengine AS | |
# | |
# This program is free software; you can redistribute it and/or modify it | |
# under the terms of the GNU Lesser General Public License LGPL as published by the | |
# Free Software Foundation; version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# To the extent this program is licensed as part of the Enterprise | |
# versions of Cfengine, the applicable Commerical Open Source License | |
# (COSL) may apply to this file if you as a licensee so wish it. See | |
# included file COSL.txt. | |
########################################################################### | |
# | |
# Cfengine Community Open Promise-Body Library | |
# | |
# This initiative started by Cfengine promotes a | |
# standardized set of names and promise specifications | |
# for template functionality within Cfengine 3. | |
# | |
# The aim is to promote an industry standard for | |
# naming of configuration patterns, leading to a | |
# de facto middleware of standardized syntax. | |
# | |
# Names should be intuitive and parameters should be | |
# minimal to assist readability and comprehensibility. | |
# Contributions to this file are voluntarily given to | |
# the cfengine community, and are moderated by Cfengine. | |
# No liability or warranty for misuse is implied. | |
# | |
# If you add to this file, please try to make the | |
# contributions "self-documenting". Comments made | |
# after the bundle/body statement are retained in | |
# the online docs | |
# | |
# For Cfengine Core: 3.5.0 and older | |
################################################### | |
# If you find Cfengine useful, please consider # | |
# purchasing a commercial version of the software.# | |
################################################### | |
################################################### | |
# edit_line bundles | |
################################################### | |
bundle edit_line insert_lines(lines) | |
{ | |
insert_lines: | |
"$(lines)" | |
comment => "Append lines if they don't exist"; | |
} | |
## | |
bundle edit_line insert_file(templatefile) | |
{ | |
insert_lines: | |
"$(templatefile)" | |
comment => "Insert the template file into the file being edited", | |
insert_type => "file"; | |
} | |
## | |
bundle edit_line comment_lines_matching(regex,comment) | |
# Comment lines of a file matching a regex | |
{ | |
replace_patterns: | |
"^($(regex))$" | |
replace_with => comment("$(comment)"), | |
comment => "Search and replace string"; | |
} | |
## | |
bundle edit_line uncomment_lines_matching(regex,comment) | |
# Uncomment lines of a file where the regex matches | |
# the text after the comment string | |
{ | |
replace_patterns: | |
"^$(comment)\s?($(regex))$" | |
replace_with => uncomment, | |
comment => "Uncomment lines matching a regular expression"; | |
} | |
## | |
bundle edit_line comment_lines_containing(regex,comment) | |
# Comment lines of a file containing a regex | |
{ | |
replace_patterns: | |
"^((?!$(comment)).*$(regex).*)$" | |
replace_with => comment("$(comment)"), | |
comment => "Comment out lines in a file"; | |
} | |
## | |
bundle edit_line uncomment_lines_containing(regex,comment) | |
# Uncomment lines of a file where the regex matches | |
# the text after the comment string | |
{ | |
replace_patterns: | |
"^$(comment)\s?(.*$(regex).*)$" | |
replace_with => uncomment, | |
comment => "Uncomment a line containing a fragment"; | |
} | |
## | |
bundle edit_line delete_lines_matching(regex) | |
{ | |
delete_lines: | |
"$(regex)" | |
comment => "Delete lines matching regular expressions"; | |
} | |
## | |
bundle edit_line warn_lines_matching(regex) | |
{ | |
delete_lines: | |
"$(regex)" | |
comment => "Warn about lines in a file", | |
action => warn_only; | |
} | |
## | |
bundle edit_line append_if_no_line(str) | |
{ | |
insert_lines: | |
"$(str)" | |
comment => "Append a line to the file if it doesn't already exist"; | |
} | |
## | |
bundle edit_line append_if_no_lines(list) | |
{ | |
insert_lines: | |
"$(list)" | |
comment => "Append lines to the file if they don't already exist"; | |
} | |
## | |
bundle edit_line replace_line_end(start,end) | |
# | |
# Lines starting with "$(start)" will get the ending given in "$(end)", | |
# whitespaces will be left unmodified. | |
# For example, replace_line_end("ftp", "2121/tcp") would replace | |
# "ftp 21/tcp" | |
# with | |
# "ftp 2121/tcp" | |
{ | |
field_edits: | |
"\s*$(start)\s.*" | |
comment => "Replace lines with $(this.start) and $(this.end)", | |
edit_field => line("(^|\s)$(start)\s*", "2", "$(end)","set"); | |
} | |
## | |
bundle edit_line append_to_line_end(start,end) | |
# | |
# Lines starting with "$(start)" and not ending with "$(end)" | |
# will get appended with "$(end)", whitespaces will be left unmodified. | |
# For example, append_to_line_end("kernel", "vga=791") would replace | |
# "kernel /boot/vmlinuz root=/dev/sda7" | |
# with | |
# "kernel /boot/vmlinuz root=/dev/sda7 resume=/dev/sda9 vga=791" | |
# | |
# WARNING: Be careful not to have multiple promises matching the same line, | |
# which would result in the line growing indefinetively. | |
{ | |
field_edits: | |
"\s*$(start)\s.*" | |
comment => "Append lines with $(this.start) and $(this.end)", | |
edit_field => line("(^|\s)$(start)\s*", "2", "$(end)","append"); | |
} | |
## | |
bundle edit_line regex_replace(find,replace) | |
# You can think of this like a PCRE powered sed. | |
# Find exactly a regular expression and replace exactly the match with a string. | |
{ | |
replace_patterns: | |
"$(find)" | |
replace_with => value("$(replace)"), | |
comment => "Search and replace string"; | |
} | |
## | |
bundle edit_line resolvconf(search,list) | |
# search is the search domains with space | |
# list is an slist of nameserver addresses | |
{ | |
delete_lines: | |
"search.*" comment => "Reset search lines from resolver"; | |
"nameserver.*" comment => "Reset nameservers in resolver"; | |
insert_lines: | |
"search $(search)" comment => "Add search domains to resolver"; | |
"nameserver $(list)" comment => "Add name servers to resolver"; | |
} | |
## | |
bundle edit_line manage_variable_values_ini(tab, sectionName) | |
# Sets the RHS of configuration items in the file of the form | |
# LHS=RHS | |
# If the line is commented out with #, it gets uncommented first. | |
# Adds a new line if none exists. | |
# Removes any variable value pairs not defined for the ini section | |
# The argument is an associative array containing tab[SectionName][LHS]="RHS" | |
# don't change value when the RHS is dontchange | |
# Based on set_variable_values_ini | |
# Added delete lines section to empty out undefined variable values for INI section | |
# CAUTION : for it to work nicely, you should use Cfengine with the commit n°3229 | |
# otherwise you may risk a segfault | |
# | |
# If you are running 3.2.1 or earlier or more specifically git commit # or | |
# earlier you can use this to work around the segfault bug. | |
# vars: | |
# "$(file)" | |
# edit_line => append_if_no_line("[#EOF#]"), | |
# create => "true", | |
# comment => "Work around bug<bug#here> where eof did not mean end | |
# of section and thus cannot select a region. This promise | |
# should be placed before your call to this bundle"; | |
# "$(file)" | |
# edit_line => manage_variable_values_ini("context.array", "SectionName"), | |
# create => "true", | |
# comment => "Set the variale values only in the specified ini region"; | |
# | |
{ | |
vars: | |
"index" slist => getindices("$(tab)[$(sectionName)]"); | |
# Be careful if the index string contains funny chars | |
"cindex[$(index)]" string => canonify("$(index)"); | |
classes: | |
"edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])","dontchange"), | |
comment => "Create conditions to make changes"; | |
field_edits: | |
# If the line is there, but commented out, first uncomment it | |
"#+\s*$(index)\s*=.*" | |
select_region => INI_section("$(sectionName)"), | |
edit_field => col("=","1","$(index)","set"), | |
ifvarclass => "edit_$(cindex[$(index)])"; | |
# match a line starting like the key something | |
"$(index)\s*=.*" | |
edit_field => col("=","2","$($(tab)[$(sectionName)][$(index)])","set"), | |
select_region => INI_section("$(sectionName)"), | |
classes => if_ok("manage_variable_values_ini_not_$(cindex[$(index)])"), | |
ifvarclass => "edit_$(cindex[$(index)])"; | |
delete_lines: | |
".*" | |
select_region => INI_section("$(sectionName)"), | |
comment => "Remove all entries in the region so there are no extra entries"; | |
insert_lines: | |
"[$(sectionName)]" | |
location => start, | |
comment => "Insert lines"; | |
"$(index)=$($(tab)[$(sectionName)][$(index)])" | |
select_region => INI_section("$(sectionName)"), | |
ifvarclass => "!manage_variable_values_ini_not_$(cindex[$(index)]).edit_$(cindex[$(index)])"; | |
} | |
## | |
bundle edit_line set_variable_values_ini(tab, sectionName) | |
# Sets the RHS of configuration items in the file of the form | |
# LHS=RHS | |
# If the line is commented out with #, it gets uncommented first. | |
# Adds a new line if none exists. | |
# The argument is an associative array containing tab[SectionName][LHS]="RHS" | |
# don't change value when the RHS is dontchange | |
# Based on set_variable_values from cfengine_stdlib.cf, modified to | |
# use section to define were to write, and to handle commented-out lines. | |
# CAUTION : for it to work nicely, you should use Cfengine with the commit n°3229 | |
# otherwise you may risk a segfault | |
# | |
# If you are running 3.2.1 or earlier or more specifically git commit # or | |
# earlier you can use this to work around the segfault bug. | |
# vars: | |
# "$(file)" | |
# edit_line => append_if_no_line("[#EOF#]"), | |
# create => "true", | |
# comment => "Work around bug<bug#here> where eof did not mean end | |
# of section and thus cannot select a region. This promise | |
# should be placed before your call to this bundle"; | |
# "$(file)" | |
# edit_line => set_variable_values_ini("context.array", "SectionName"), | |
# create => "true", | |
# comment => "Set the variale values only in the specified ini region"; | |
# | |
{ | |
vars: | |
"index" slist => getindices("$(tab)[$(sectionName)]"); | |
# Be careful if the index string contains funny chars | |
"cindex[$(index)]" string => canonify("$(index)"); | |
classes: | |
"edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])","dontchange"), | |
comment => "Create conditions to make changes"; | |
field_edits: | |
# If the line is there, but commented out, first uncomment it | |
"#+\s*$(index)\s*=.*" | |
select_region => INI_section("$(sectionName)"), | |
edit_field => col("=","1","$(index)","set"), | |
ifvarclass => "edit_$(cindex[$(index)])"; | |
# match a line starting like the key something | |
"$(index)\s*=.*" | |
edit_field => col("=","2","$($(tab)[$(sectionName)][$(index)])","set"), | |
select_region => INI_section("$(sectionName)"), | |
classes => if_ok("set_variable_values_ini_not_$(cindex[$(index)])"), | |
ifvarclass => "edit_$(cindex[$(index)])"; | |
insert_lines: | |
"[$(sectionName)]" | |
location => start, | |
comment => "Insert lines"; | |
"$(index)=$($(tab)[$(sectionName)][$(index)])" | |
select_region => INI_section("$(sectionName)"), | |
ifvarclass => "!set_variable_values_ini_not_$(cindex[$(index)]).edit_$(cindex[$(index)])"; | |
} | |
bundle edit_line set_quoted_values(v) | |
{ | |
# Sets the RHS of variables in shell-like files | |
# that is: | |
# LHS="RHS" | |
# Adds a new line if no LHS exists | |
# repairs RHS values if one does exist | |
# If the line is commented out with #, it gets uncommented first. | |
# | |
# To use: | |
# 1) Define an array, where the keys are the LHS and the values are the RHS | |
# "stuff[lhs-1]" string => "rhs1"; | |
# "stuff[lhs-2]" string => "rhs2"; | |
# 2) The parameter passed to the edit_line promise is the fully qualified | |
# name of the array (i.e., "bundlename.stuff") WITHOUT any "$" or "@" | |
vars: | |
"index" slist => getindices("$(v)"); | |
# Be careful if the index string contains funny chars | |
"cindex[$(index)]" string => canonify("$(index)"); | |
field_edits: | |
# If the line is there, but commented out, first uncomment it | |
"#+\s*$(index)\s*=.*" | |
edit_field => col("=","1","$(index)","set"); | |
# match a line starting like the key = something | |
"\s*$(index)\s*=.*" | |
edit_field => col("=","2",'"$($(v)[$(index)])"',"set"), | |
classes => if_ok("$(cindex[$(index)])_in_file"), | |
comment => "Match a line starting like key = something"; | |
insert_lines: | |
'$(index)="$($(v)[$(index)])"' | |
comment => "Insert a variable definition", | |
ifvarclass => "!$(cindex[$(index)])_in_file"; | |
} | |
## | |
bundle edit_line set_variable_values(v) | |
# Sets the RHS of variables in the file of the form | |
# LHS = RHS | |
# Adds a new line if no LHS exists, repairs RHS values if one does exist | |
# | |
# To use: | |
# 1) Define an array, where the keys are the LHS and the values are the RHS | |
# "stuff[lhs-1]" string => "rhs1"; | |
# "stuff[lhs-2]" string => "rhs2"; | |
# 2) The parameter passed to the edit_line promise is the fully qualified | |
# name of the array (i.e., "bundlename.stuff") WITHOUT any "$" or "@" | |
{ | |
vars: | |
"index" slist => getindices("$(v)"); | |
# Be careful if the index string contains funny chars | |
"cindex[$(index)]" string => canonify("$(index)"); | |
"cv" string => canonify("$(v)"); | |
field_edits: | |
# match a line starting like the key = something | |
"\s*$(index)\s*=.*" | |
edit_field => col("=","2","$($(v)[$(index)])","set"), | |
classes => if_ok("$(cv)_$(cindex[$(index)])_in_file"), | |
comment => "Match a line starting like key = something"; | |
insert_lines: | |
"$(index)=$($(v)[$(index)])" | |
comment => "Insert a variable definition", | |
ifvarclass => "!$(cv)_$(cindex[$(index)])_in_file"; | |
} | |
bundle edit_line set_config_values(v) | |
# Sets the RHS of configuration items in the file of the form | |
# LHS RHS | |
# If the line is commented out with #, it gets uncommented first. | |
# Adds a new line if none exists. | |
# The argument is the fully-qualified name of an associative array containing v[LHS]="rhs" | |
{ | |
vars: | |
"index" slist => getindices("$(v)"); | |
# Be careful if the index string contains funny chars | |
"cindex[$(index)]" string => canonify("$(index)"); | |
replace_patterns: | |
# If the line is there, maybe commented out, uncomment and replace with | |
# the correct value | |
"^\s*($(index)\s+(?!$($(v)[$(index)])$).*|# ?$(index)\s+.*)$" | |
comment => "Correct the value", | |
replace_with => value("$(index) $($(v)[$(index)])"), | |
classes => always("replace_attempted_$(cindex[$(index)])"); | |
insert_lines: | |
"$(index) $($(v)[$(index)])" | |
ifvarclass => "replace_attempted_$(cindex[$(index)])"; | |
} | |
bundle edit_line set_config_values_matching(v,pat) | |
# Sets the RHS of configuration items in the file of the form | |
# LHS RHS | |
# If the line is commented out with #, it gets uncommented first. | |
# Adds a new line if none exists. | |
# Only elements of "v" that match the regex "pat" are used | |
# The argument is the fully-qualified name of an associative array containing v[LHS]="rhs" | |
{ | |
vars: | |
"allparams" slist => getindices("$(v)"); | |
"index" slist => grep("$(pat)", "allparams"); | |
# Be careful if the index string contains funny chars | |
"cindex[$(index)]" string => canonify("$(index)"); | |
replace_patterns: | |
# If the line is there, maybe commented out, uncomment and replace with | |
# the correct value | |
"^\s*($(index)\s+(?!$($(v)[$(index)])).*|# ?$(index)\s+.*)$" | |
comment => "Correct the value", | |
replace_with => value("$(index) $($(v)[$(index)])"), | |
classes => always("replace_attempted_$(cindex[$(index)])"); | |
insert_lines: | |
"$(index) $($(v)[$(index)])" | |
ifvarclass => "replace_attempted_$(cindex[$(index)])"; | |
} | |
## | |
bundle edit_line maintain_key_values(v,sep) | |
# Contributed by David Lee | |
# Purpose: Sets the RHS of configuration items with an giving separator | |
{ | |
vars: | |
"index" slist => getindices("$(v)"); | |
# Be careful if the index string contains funny chars | |
"cindex[$(index)]" string => canonify("$(index)"); | |
# Matching pattern for line (basically key-and-separator) | |
"keypat[$(index)]" string => "\s*$(index)\s*$(sep)\s*"; | |
# Values may contain regexps. Escape them for replace_pattern matching. | |
"ve[$(index)]" string => escape("$($(v)[$(index)])"); | |
classes: | |
"$(cindex[$(index)])_key_in_file" | |
comment => "Dynamic Class created if patterns matching", | |
expression => regline("^$(keypat[$(index)]).*", "$(edit.filename)"); | |
replace_patterns: | |
# For convergence need to use negative lookahead on value: | |
# "key sep (?!value).*" | |
"^($(keypat[$(index)]))(?!$(ve[$(index)])$).*" | |
comment => "Replace definition of $(index)", | |
replace_with => value("$(match.1)$($(v)[$(index)])"); | |
insert_lines: | |
"$(index)$(sep)$($(v)[$(index)])" | |
comment => "Insert definition of $(index)", | |
ifvarclass => "!$(cindex[$(index)])_key_in_file"; | |
} | |
## | |
bundle edit_line append_users_starting(v) | |
# For adding to /etc/passwd or etc/shadow, needs | |
# an array v[username] string => "line..." | |
{ | |
vars: | |
"index" slist => getindices("$(v)"); | |
classes: | |
"add_$(index)" not => userexists("$(index)"), | |
comment => "Class created if user does not exist"; | |
insert_lines: | |
"$($(v)[$(index)])" | |
comment => "Append users into a password file format", | |
ifvarclass => "add_$(index)"; | |
} | |
## | |
bundle edit_line append_groups_starting(v) | |
# For adding groups to /etc/group, needs | |
# an array v[groupname] string => "line..." | |
{ | |
vars: | |
"index" slist => getindices("$(v)"); | |
classes: | |
"add_$(index)" not => groupexists("$(index)"), | |
comment => "Class created if group does not exist"; | |
insert_lines: | |
"$($(v)[$(index)])" | |
comment => "Append users into a group file format", | |
ifvarclass => "add_$(index)"; | |
} | |
## | |
bundle edit_line set_colon_field(key,field,val) | |
# Set the value of field number "field" of the | |
# line whose first field is "key", in a colon-separated file. | |
{ | |
field_edits: | |
"$(key):.*" | |
comment => "Edit a colon-separated file, using the first field as a key", | |
edit_field => col(":","$(field)","$(val)","set"); | |
} | |
## | |
bundle edit_line set_user_field(user,field,val) | |
# Set the value of field number "field" in | |
# a :-field formatted file like /etc/passwd | |
{ | |
field_edits: | |
"$(user):.*" | |
comment => "Edit a user attribute in the password file", | |
edit_field => col(":","$(field)","$(val)","set"); | |
} | |
## | |
bundle edit_line append_user_field(group,field,allusers) | |
# For adding users to to a file like /etc/group | |
# at field position "field", comma separated subfields | |
{ | |
vars: | |
"val" slist => { @(allusers) }; | |
field_edits: | |
"$(group):.*" | |
comment => "Append users into a password file format", | |
edit_field => col(":","$(field)","$(val)","alphanum"); | |
} | |
## | |
bundle edit_line expand_template(templatefile) | |
# Read in the named text file and expand $(var) | |
# inside the file | |
{ | |
insert_lines: | |
"$(templatefile)" | |
insert_type => "file", | |
comment => "Expand variables in the template file", | |
expand_scalars => "true"; | |
} | |
bundle edit_line replace_or_add(pattern,line) | |
# Replace a pattern in a file with a single line. | |
# If the pattern is not found, add the line to the file. | |
# The pattern must match the whole line (it is automatically | |
# anchored to the start and end of the line) to avoid | |
# ambiguity. | |
{ | |
vars: | |
"cline" string => canonify("$(line)"); | |
"eline" string => escape("$(line)"); | |
replace_patterns: | |
"^(?!$(eline)$)$(pattern)$" | |
comment => "Replace a pattern here", | |
replace_with => value("$(line)"), | |
classes => always("replace_done_$(cline)"); | |
insert_lines: | |
"$(line)" | |
ifvarclass => "replace_done_$(cline)"; | |
} | |
## | |
bundle agent cronjob(commands,user,hours,mins) | |
# For adding lines to crontab for a user | |
# methods: | |
# "cron" usebundle => cronjob("/bin/ls","mark","*","5,10"); | |
{ | |
vars: | |
SuSE:: | |
"crontab" string => "/var/spool/cron/tabs"; | |
redhat|fedora:: | |
"crontab" string => "/var/spool/cron"; | |
freebsd:: | |
"crontab" string => "/var/cron/tabs"; | |
!(SuSE|redhat|fedora|freebsd):: | |
"crontab" string => "/var/spool/cron/crontabs"; | |
files: | |
!windows:: | |
"$(crontab)/$(user)" | |
comment => "A user's regular batch jobs are added to this file", | |
create => "true", | |
edit_line => append_if_no_line("$(mins) $(hours) * * * $(commands)"), | |
perms => mo("600","$(user)"), | |
classes => if_repaired("changed_crontab"); | |
processes: | |
changed_crontab:: | |
"cron" | |
comment => "Most crons need to be huped after file changes", | |
signals => { "hup" }; | |
} | |
##------------------------------------------------------- | |
## editing bodies | |
##------------------------------------------------------- | |
body edit_field quoted_var(newval,method) | |
{ | |
field_separator => "\""; | |
select_field => "2"; | |
value_separator => " "; | |
field_value => "$(newval)"; | |
field_operation => "$(method)"; | |
extend_fields => "false"; | |
allow_blank_fields => "true"; | |
} | |
## | |
body edit_field col(split,col,newval,method) | |
{ | |
field_separator => "$(split)"; | |
select_field => "$(col)"; | |
value_separator => ","; | |
field_value => "$(newval)"; | |
field_operation => "$(method)"; | |
extend_fields => "true"; | |
allow_blank_fields => "true"; | |
} | |
## | |
body edit_field line(split,col,newval,method) | |
{ | |
field_separator => "$(split)"; | |
select_field => "$(col)"; | |
value_separator => " "; | |
field_value => "$(newval)"; | |
field_operation => "$(method)"; | |
extend_fields => "true"; | |
allow_blank_fields => "true"; | |
} | |
## | |
body replace_with value(x) | |
{ | |
replace_value => "$(x)"; | |
occurrences => "all"; | |
} | |
## | |
body select_region INI_section(x) | |
{ | |
select_start => "\[$(x)\]\s*"; | |
select_end => "\[.*\]\s*"; | |
} | |
##------------------------------------------------------- | |
## edit_defaults | |
##------------------------------------------------------- | |
body edit_defaults std_defs | |
{ | |
empty_file_before_editing => "false"; | |
edit_backup => "false"; | |
#max_file_size => "300000"; | |
} | |
## | |
body edit_defaults empty | |
{ | |
empty_file_before_editing => "true"; | |
edit_backup => "false"; | |
#max_file_size => "300000"; | |
} | |
## | |
body edit_defaults no_backup | |
{ | |
edit_backup => "false"; | |
} | |
## | |
body edit_defaults backup_timestamp | |
{ | |
empty_file_before_editing => "false"; | |
edit_backup => "timestamp"; | |
#max_file_size => "300000"; | |
} | |
##------------------------------------------------------- | |
## location | |
##------------------------------------------------------- | |
body location start | |
{ | |
before_after => "before"; | |
} | |
## | |
body location after(str) | |
{ | |
before_after => "after"; | |
select_line_matching => "$(str)"; | |
} | |
## | |
body location before(str) | |
{ | |
before_after => "before"; | |
select_line_matching => "$(str)"; | |
} | |
##------------------------------------------------------- | |
## replace_with | |
##------------------------------------------------------- | |
## | |
body replace_with comment(c) | |
{ | |
replace_value => "$(c) $(match.1)"; | |
occurrences => "all"; | |
} | |
## | |
body replace_with uncomment | |
{ | |
replace_value => "$(match.1)"; | |
occurrences => "all"; | |
} | |
#################################################### | |
## agent bodyparts | |
#################################################### | |
##------------------------------------------------------- | |
## action | |
##------------------------------------------------------- | |
body action if_elapsed(x) | |
{ | |
ifelapsed => "$(x)"; | |
expireafter => "$(x)"; | |
} | |
## | |
body action if_elapsed_day | |
{ | |
ifelapsed => "1440"; # 60 x 24 | |
expireafter => "1400"; | |
} | |
## | |
body action measure_performance(x) | |
{ | |
measurement_class => "Detect changes in $(this.promiser)"; | |
ifelapsed => "$(x)"; | |
expireafter => "$(x)"; | |
} | |
## | |
body action warn_only | |
{ | |
action_policy => "warn"; | |
ifelapsed => "60"; | |
} | |
## | |
body action bg(elapsed,expire) | |
{ | |
ifelapsed => "$(elapsed)"; | |
expireafter => "$(expire)"; | |
background => "true"; | |
} | |
## | |
body action ifwin_bg | |
{ | |
windows:: | |
background => "true"; | |
} | |
## | |
body action immediate | |
{ | |
ifelapsed => "0"; | |
} | |
## | |
body action policy(p) | |
{ | |
action_policy => "$(p)"; | |
} | |
## | |
# Log a message to log=[/file|stdout] | |
body action log_repaired(log,message) | |
{ | |
log_string => "$(sys.date), $(message)"; | |
log_repaired => "$(log)"; | |
} | |
### | |
body action log_verbose | |
{ | |
log_level => "verbose"; | |
} | |
##------------------------------------------------------- | |
## contain | |
##------------------------------------------------------- | |
body contain silent | |
{ | |
no_output => "true"; | |
} | |
## | |
body contain in_dir(s) | |
{ | |
chdir => "$(s)"; | |
} | |
## | |
body contain in_dir_shell(s) | |
{ | |
chdir => "$(s)"; | |
useshell => "true"; # canonical "useshell" but this is backwards-compatible | |
} | |
## | |
body contain silent_in_dir(s) | |
{ | |
chdir => "$(s)"; | |
no_output => "true"; | |
} | |
## | |
body contain in_shell | |
{ | |
useshell => "true"; # canonical "useshell" but this is backwards-compatible | |
} | |
## | |
body contain in_shell_bg | |
{ | |
useshell => "true"; # canonical "useshell" but this is backwards-compatible | |
} | |
## | |
body contain in_shell_and_silent | |
{ | |
useshell => "true"; # canonical "useshell" but this is backwards-compatible | |
no_output => "true"; | |
} | |
## | |
body contain in_dir_shell_and_silent(dir) | |
{ | |
useshell => "true"; # canonical "useshell" but this is backwards-compatible | |
no_output => "true"; | |
chdir => "$(dir)"; | |
} | |
## | |
body contain setuid(x) | |
{ | |
exec_owner => "$(x)"; | |
useshell => "false"; # canonical "noshell" but this is backwards-compatible | |
} | |
## | |
body contain setuid_sh(x) | |
{ | |
exec_owner => "$(x)"; | |
useshell => "true"; # canonical "useshell" but this is backwards-compatible | |
} | |
## | |
body contain setuidgid_sh(owner,group) | |
{ | |
exec_owner => "$(owner)"; | |
exec_group => "$(group)"; | |
useshell => "true"; # canonical "useshell" but this is backwards-compatible | |
} | |
## | |
body contain jail(owner,root,dir) | |
{ | |
exec_owner => "$(owner)"; | |
useshell => "true"; # canonical "useshell" but this is backwards-compatible | |
chdir => "$(dir)"; | |
chroot => "$(root)"; | |
} | |
## | |
body contain setuid_umask(uid, umask) | |
################################################### | |
# | Files | Directories # | |
################################################### | |
# Umask | Octal Symbolic | Octal Symbolic # | |
########+#####################+###################+ | |
# 000 | 666 (rw-rw-rw-) | 777 (rwxrwxrwx) | |
# 002 | 664 (rw-rw-r--) | 775 (rwxrwxr-x) | |
# 022 | 644 (rw-r--r--) | 755 (rwxr-xr-x) | |
# 027 | 640 (rw-r-----) | 750 (rwxr-x---) | |
# 077 | 600 (rw-------) | 700 (rwx------) | |
# 277 | 400 (r--------) | 500 (r-x------) | |
{ | |
exec_owner => "$(uid)"; | |
umask => "$(umask)"; | |
} | |
##------------------------------------------------------- | |
## classes | |
##------------------------------------------------------- | |
body classes if_repaired(x) | |
{ | |
promise_repaired => { "$(x)" }; | |
} | |
## | |
body classes if_else(yes,no) | |
{ | |
promise_kept => { "$(yes)" }; | |
promise_repaired => { "$(yes)" }; | |
repair_failed => { "$(no)" }; | |
repair_denied => { "$(no)" }; | |
repair_timeout => { "$(no)" }; | |
} | |
## | |
body classes cf2_if_else(yes,no) | |
# meant to match cf2 semantics | |
{ | |
promise_repaired => { "$(yes)" }; | |
repair_failed => { "$(no)" }; | |
repair_denied => { "$(no)" }; | |
repair_timeout => { "$(no)" }; | |
} | |
## | |
body classes if_notkept(x) | |
{ | |
repair_failed => { "$(x)" }; | |
repair_denied => { "$(x)" }; | |
repair_timeout => { "$(x)" }; | |
} | |
## | |
body classes if_ok(x) | |
{ | |
promise_repaired => { "$(x)" }; | |
promise_kept => { "$(x)" }; | |
} | |
## | |
body classes if_ok_cancel(x) | |
{ | |
cancel_repaired => { "$(x)" }; | |
cancel_kept => { "$(x)" }; | |
} | |
## | |
body classes cmd_repair(code,cl) | |
{ | |
repaired_returncodes => { "$(code)" }; | |
promise_repaired => { "$(cl)" }; | |
} | |
body classes classes_generic(x) | |
# Define x prefixed/suffixed with promise outcome | |
{ | |
promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" }; | |
repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; | |
repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; | |
repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; | |
promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_not_repaired", "$(x)_reached" }; | |
} | |
##------------------------------------------------------- | |
## Persistent classes | |
##------------------------------------------------------- | |
body classes state_repaired(x) | |
{ | |
promise_repaired => { "$(x)" }; | |
persist_time => "10"; | |
} | |
## | |
body classes enumerate(x) | |
# | |
# This is used by commercial editions to count | |
# instances of jobs in a cluster | |
# | |
{ | |
promise_repaired => { "mXC_$(x)" }; | |
promise_kept => { "mXC_$(x)" }; | |
persist_time => "15"; | |
} | |
## | |
body classes always(x) | |
# Define a class no matter what the outcome of the promise is | |
{ | |
promise_repaired => { "$(x)" }; | |
promise_kept => { "$(x)" }; | |
repair_failed => { "$(x)" }; | |
repair_denied => { "$(x)" }; | |
repair_timeout => { "$(x)" }; | |
} | |
################################################### | |
# agent bundles | |
################################################### | |
##.................................................. | |
## files promises | |
##.................................................. | |
# this is a workaround for the issue that recurse_with_base precludes | |
# a file from being deleted | |
bundle agent rm_rf(name) | |
{ | |
classes: | |
"isdir" expression => isdir($(name)); | |
files: | |
isdir:: | |
"$(name)" | |
file_select => all, | |
depth_search => recurse_with_base(999), | |
delete => tidy; | |
!isdir:: | |
"$(name)" delete => tidy; | |
} | |
##------------------------------------------------------- | |
## copy_from | |
##------------------------------------------------------- | |
body copy_from secure_cp(from,server) | |
{ | |
source => "$(from)"; | |
servers => { "$(server)" }; | |
compare => "digest"; | |
encrypt => "true"; | |
verify => "true"; | |
} | |
## | |
body copy_from remote_cp(from,server) | |
{ | |
servers => { "$(server)" }; | |
source => "$(from)"; | |
compare => "mtime"; | |
} | |
## | |
body copy_from remote_dcp(from,server) | |
{ | |
servers => { "$(server)" }; | |
source => "$(from)"; | |
compare => "digest"; | |
} | |
## | |
body copy_from local_cp(from) | |
{ | |
source => "$(from)"; | |
} | |
## | |
body copy_from local_dcp(from) | |
{ | |
source => "$(from)"; | |
compare => "digest"; | |
} | |
## | |
body copy_from perms_cp(from) | |
{ | |
source => "$(from)"; | |
preserve => "true"; | |
} | |
body copy_from backup_local_cp(from) | |
# Local copy, keeping a backup of old versions | |
{ | |
source => "$(from)"; | |
copy_backup => "timestamp"; | |
} | |
## | |
# Copy only if the file does not already exist, i.e. seed the placement | |
body copy_from seed_cp(from) | |
{ | |
source => "$(from)"; | |
compare => "exists"; | |
} | |
## | |
body copy_from sync_cp(from,server) | |
{ | |
servers => { "$(server)" }; | |
source => "$(from)"; | |
purge => "true"; | |
preserve => "true"; | |
type_check => "false"; | |
} | |
## | |
body copy_from no_backup_cp(from) | |
{ | |
source => "$(from)"; | |
copy_backup => "false"; | |
} | |
## | |
body copy_from no_backup_dcp(from) | |
{ | |
source => "$(from)"; | |
copy_backup => "false"; | |
compare => "digest"; | |
} | |
## | |
body copy_from no_backup_rcp(from,server) | |
{ | |
servers => { "$(server)" }; | |
source => "$(from)"; | |
compare => "mtime"; | |
copy_backup => "false"; | |
} | |
##------------------------------------------------------- | |
## link_from | |
##------------------------------------------------------- | |
body link_from ln_s(x) | |
{ | |
link_type => "symlink"; | |
source => "$(x)"; | |
when_no_source => "force"; | |
} | |
## | |
body link_from linkchildren(tofile) | |
{ | |
source => "$(tofile)"; | |
link_type => "symlink"; | |
when_no_source => "force"; | |
link_children => "true"; | |
when_linking_children => "if_no_such_file"; # "override_file"; | |
} | |
##------------------------------------------------------- | |
## perms | |
##------------------------------------------------------- | |
body perms m(mode) | |
{ | |
mode => "$(mode)"; | |
} | |
## | |
body perms mo(mode,user) | |
{ | |
owners => { "$(user)" }; | |
mode => "$(mode)"; | |
} | |
## | |
body perms mog(mode,user,group) | |
{ | |
owners => { "$(user)" }; | |
groups => { "$(group)" }; | |
mode => "$(mode)"; | |
} | |
## | |
body perms og(u,g) | |
{ | |
owners => { "$(u)" }; | |
groups => { "$(g)" }; | |
} | |
## | |
body perms owner(user) | |
{ | |
owners => { "$(user)" }; | |
} | |
##------------------------------------------------------- | |
## ACLS (extended Unix perms) | |
##------------------------------------------------------- | |
body acl access_generic(acl) | |
# default/inherited ACLs are left unchanged, | |
# applicable for both files and directories on all platforms | |
{ | |
acl_method => "overwrite"; | |
aces => { "@(acl)" }; | |
windows:: | |
acl_type => "ntfs"; | |
!windows:: | |
acl_type => "posix"; | |
} | |
## | |
body acl ntfs(acl) | |
{ | |
acl_type => "ntfs"; | |
acl_method => "overwrite"; | |
aces => { "@(acl)" }; | |
} | |
## | |
body acl strict | |
# NOTE: May need to take ownership of file/dir | |
# to be sure no-one else is allowed access | |
{ | |
acl_method => "overwrite"; | |
windows:: | |
aces => { "user:Administrator:rwx" }; | |
!windows:: | |
aces => { "user:root:rwx" }; | |
} | |
##------------------------------------------------------- | |
## depth_search | |
##------------------------------------------------------- | |
body depth_search recurse(d) | |
{ | |
depth => "$(d)"; | |
xdev => "true"; | |
} | |
## | |
body depth_search recurse_ignore(d,list) | |
{ | |
depth => "$(d)"; | |
exclude_dirs => { @(list) }; | |
} | |
## | |
body depth_search include_base | |
{ | |
include_basedir => "true"; | |
} | |
body depth_search recurse_with_base(d) | |
{ | |
depth => "$(d)"; | |
xdev => "true"; | |
include_basedir => "true"; | |
} | |
##------------------------------------------------------- | |
## delete | |
##------------------------------------------------------- | |
body delete tidy | |
{ | |
dirlinks => "delete"; | |
rmdirs => "true"; | |
} | |
##------------------------------------------------------- | |
## rename | |
##------------------------------------------------------- | |
body rename disable | |
{ | |
disable => "true"; | |
} | |
## | |
body rename rotate(level) | |
{ | |
rotate => "$(level)"; | |
} | |
## | |
body rename to(file) | |
{ | |
newname => "$(file)"; | |
} | |
##------------------------------------------------------- | |
## file_select | |
##------------------------------------------------------- | |
body file_select name_age(name,days) | |
{ | |
leaf_name => { "$(name)" }; | |
mtime => irange(0,ago(0,0,"$(days)",0,0,0)); | |
file_result => "mtime.leaf_name"; | |
} | |
## | |
body file_select days_old(days) | |
{ | |
mtime => irange(0,ago(0,0,"$(days)",0,0,0)); | |
file_result => "mtime"; | |
} | |
## | |
body file_select size_range(from,to) | |
{ | |
search_size => irange("$(from)","$(to)"); | |
file_result => "size"; | |
} | |
## | |
body file_select exclude(name) | |
{ | |
leaf_name => { "$(name)"}; | |
file_result => "!leaf_name"; | |
} | |
## | |
body file_select plain | |
{ | |
file_types => { "plain" }; | |
file_result => "file_types"; | |
} | |
body file_select dirs | |
{ | |
file_types => { "dir" }; | |
file_result => "file_types"; | |
} | |
## | |
body file_select by_name(names) | |
{ | |
leaf_name => { @(names)}; | |
file_result => "leaf_name"; | |
} | |
## | |
body file_select ex_list(names) | |
{ | |
leaf_name => { @(names)}; | |
file_result => "!leaf_name"; | |
} | |
## | |
body file_select all | |
{ | |
leaf_name => { ".*" }; | |
file_result => "leaf_name"; | |
} | |
## | |
body file_select older_than(years, months, days, hours, minutes, seconds) | |
# Generic older_than selection body, aimed to have a common definition handy | |
# for every case possible. | |
{ | |
mtime => irange(0,ago("$(years)","$(months)","$(days)","$(hours)","$(minutes)","$(seconds)")); | |
file_result => "mtime"; | |
} | |
## | |
body file_select filetype_older_than(filetype, days) | |
# Select files of specified type older than specified number of days | |
# Note: This body only takes a single filetype, see filetypes_older_than | |
# if you want to select more than one type of file | |
{ | |
file_types => { "$(filetype)" }; | |
mtime => irange(0,ago(0,0,"$(days)",0,0,0)); | |
file_result => "file_types.mtime"; | |
} | |
## | |
body file_select filetypes_older_than(filetypes, days) | |
# Select files of specified type older than specified number of days | |
# Note: This body only takes a list of filetypes | |
{ | |
file_types => { @(filetypes) }; | |
mtime => irange(0,ago(0,0,"$(days)",0,0,0)); | |
file_result => "file_types.mtime"; | |
} | |
##------------------------------------------------------- | |
## changes | |
##------------------------------------------------------- | |
body changes detect_all_change | |
# This is fierce, and will cost disk cycles | |
{ | |
hash => "best"; | |
report_changes => "all"; | |
update_hashes => "yes"; | |
} | |
## | |
body changes detect_all_change_using(hash) | |
# Detect all changes using a configurable hashing algorithm | |
# for times when you care about both content and file stats e.g. mtime | |
# hash - supported hashing algorithm (md5, sha1, sha224, sha256, sha384, | |
# sha512, best) | |
{ | |
hash => "$(hash)"; | |
report_changes => "all"; | |
update_hashes => "yes"; | |
} | |
## | |
body changes detect_content | |
# This is a cheaper alternative | |
{ | |
hash => "md5"; | |
report_changes => "content"; | |
update_hashes => "yes"; | |
} | |
## | |
body changes detect_content_using(hash) | |
# Detect content changes using a configurable hashing algorithm | |
# for times when you only care about content, not file stats e.g. mtime | |
# hash - supported hashing algorithm (md5, sha1, sha224, sha256, sha384, | |
# sha512, best) | |
{ | |
hash => "$(hash)"; | |
report_changes => "content"; | |
update_hashes => "yes"; | |
} | |
## | |
body changes noupdate | |
# Use on (small) files that should never change | |
{ | |
hash => "sha256"; | |
report_changes => "content"; | |
update_hashes => "no"; | |
} | |
## | |
body changes diff | |
# Generates diff report (Nova and above) | |
{ | |
hash => "sha256"; | |
report_changes => "content"; | |
report_diffs => "true"; | |
update_hashes => "yes"; | |
} | |
## | |
body changes all_changes | |
# Generates diff report (Nova and above) | |
{ | |
hash => "sha256"; | |
report_changes => "all"; | |
report_diffs => "true"; | |
update_hashes => "yes"; | |
} | |
## | |
body changes diff_noupdate | |
{ | |
hash => "sha256"; | |
report_changes => "content"; | |
report_diffs => "true"; | |
update_hashes => "no"; | |
} | |
##-------------------------------------------------------------- | |
## Packages promises | |
##-------------------------------------------------------------- | |
body package_method zypper | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; | |
# set it to "0" to avoid caching of list during upgrade | |
package_list_update_ifelapsed => "240"; | |
package_patch_list_command => "/usr/bin/zypper patches"; | |
package_installed_regex => "i.*"; | |
package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_patch_installed_regex => ".*Installed.*|.*Not Applicable.*"; | |
package_patch_name_regex => "[^|]+\|\s+([^\s]+).*"; | |
package_patch_version_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_name_convention => "$(name)"; | |
package_add_command => "/usr/bin/zypper --non-interactive install"; | |
package_delete_command => "/usr/bin/zypper --non-interactive remove --force-resolution"; | |
package_update_command => "/usr/bin/zypper --non-interactive update"; | |
package_patch_command => "/usr/bin/zypper --non-interactive patch$"; # $ means no args | |
package_verify_command => "/usr/bin/zypper --non-interactive verify$"; | |
} | |
## | |
bundle common debian_knowledge | |
{ | |
vars: | |
"apt_prefix" string => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C PATH=/bin:/sbin/:/usr/bin:/usr/sbin"; | |
"call_dpkg" string => "$(apt_prefix) $(paths.path[dpkg])"; | |
"call_apt_get" string => "$(apt_prefix) $(paths.path[apt_get])"; | |
"call_aptitude" string => "$(apt_prefix) $(paths.path[aptitude])"; | |
"dpkg_options" string => "-o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef"; | |
} | |
body package_method apt | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/dpkg -l"; | |
package_list_name_regex => ".i\s+([^\s:]+).*"; | |
package_list_version_regex => ".i\s+[^\s]+\s+([^\s]+).*"; | |
package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed | |
package_name_convention => "$(name)"; | |
# set it to "0" to avoid caching of list during upgrade | |
package_list_update_ifelapsed => "240"; | |
have_aptitude:: | |
package_add_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --assume-yes install"; | |
package_list_update_command => "/usr/bin/aptitude update"; | |
package_delete_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --assume-yes -q remove"; | |
package_update_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --assume-yes install"; | |
package_patch_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --assume-yes install"; | |
package_verify_command => "/usr/bin/aptitude show"; | |
package_noverify_regex => "(State: not installed|E: Unable to locate package .*)"; | |
!have_aptitude:: | |
package_add_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --yes install"; | |
package_list_update_command => "/usr/bin/apt-get update"; | |
package_delete_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --yes -q remove"; | |
package_update_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --yes install"; | |
package_patch_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --yes install"; | |
package_verify_command => "/usr/bin/dpkg -s"; | |
package_noverify_returncode => "1"; | |
} | |
## | |
body package_method dpkg_version(repo) | |
{ | |
package_changes => "individual"; | |
package_list_command => "/usr/bin/dpkg -l"; | |
# set it to "0" to avoid caching of list during upgrade | |
package_list_update_ifelapsed => "240"; | |
package_list_name_regex => ".i\s+([^\s:]+).*"; | |
package_list_version_regex => ".i\s+[^\s]+\s+([^\s]+).*"; | |
package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed | |
package_file_repositories => { "$(repo)" }; | |
debian.x86_64:: | |
package_name_convention => "$(name)_$(version)_amd64.deb"; | |
debian.i686:: | |
package_name_convention => "$(name)_$(version)_i386.deb"; | |
debian:: | |
package_add_command => "/usr/bin/dpkg --install"; | |
package_delete_command => "/usr/bin/dpkg --purge"; | |
package_update_command => "/usr/bin/dpkg --install"; | |
package_patch_command => "/usr/bin/dpkg --install"; | |
} | |
## | |
body package_method rpm_version(repo) | |
{ | |
package_changes => "individual"; | |
package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; | |
# set it to "0" to avoid caching of list during upgrade | |
package_list_update_ifelapsed => "240"; | |
package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s|]+).*"; | |
package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s|]+).*"; | |
package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_installed_regex => "i.*"; | |
package_file_repositories => { "$(repo)" }; | |
package_name_convention => "$(name)-$(version).$(arch).rpm"; | |
package_add_command => "/bin/rpm -ivh "; | |
package_update_command => "/bin/rpm -Uvh "; | |
package_patch_command => "/bin/rpm -Uvh "; | |
package_delete_command => "/bin/rpm -e --nodeps"; | |
package_noverify_regex => ".*[^\s].*"; | |
} | |
## | |
body package_method windows_feature | |
{ | |
package_changes => "individual"; | |
package_name_convention => "$(name)"; | |
package_delete_convention => "$(name)"; | |
package_installed_regex => ".*"; | |
package_list_name_regex => "(.*)"; | |
package_list_version_regex => "(.*)"; # FIXME: the listing does not give version, so takes name for version too now | |
package_add_command => "$(sys.winsysdir)\WindowsPowerShell\v1.0\powershell.exe -Command \"Import-Module ServerManager; Add-WindowsFeature -Name\""; | |
package_delete_command => "$(sys.winsysdir)\WindowsPowerShell\v1.0\powershell.exe -Command \"Import-Module ServerManager; Remove-WindowsFeature -confirm:$false -Name\""; | |
package_list_command => "$(sys.winsysdir)\WindowsPowerShell\v1.0\powershell.exe -Command \"Import-Module ServerManager; Get-WindowsFeature | where {$_.installed -eq $True} |foreach {$_.Name}\""; | |
} | |
## | |
body package_method msi_implicit(repo) | |
# Use whole file name as promiser, e.g. "7-Zip-4.50-x86_64.msi", | |
# the name, version and arch is then deduced from the promiser | |
{ | |
package_changes => "individual"; | |
package_file_repositories => { "$(repo)" }; | |
package_installed_regex => ".*"; | |
package_name_convention => "$(name)-$(version)-$(arch).msi"; | |
package_delete_convention => "$(firstrepo)$(name)-$(version)-$(arch).msi"; | |
package_name_regex => "^(\S+)-(\d+\.?)+"; | |
package_version_regex => "^\S+-((\d+\.?)+)"; | |
package_arch_regex => "^\S+-[\d\.]+-(.*).msi"; | |
package_add_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; | |
package_update_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; | |
package_delete_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /x"; | |
} | |
## | |
body package_method msi_explicit(repo) | |
# use software name as promiser, e.g. "7-Zip", and explicitly | |
# specify any package_version and package_arch | |
{ | |
package_changes => "individual"; | |
package_file_repositories => { "$(repo)" }; | |
package_installed_regex => ".*"; | |
package_name_convention => "$(name)-$(version)-$(arch).msi"; | |
package_delete_convention => "$(firstrepo)$(name)-$(version)-$(arch).msi"; | |
package_add_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; | |
package_update_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; | |
package_delete_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /x"; | |
} | |
## | |
body package_method yum | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/yum list installed"; | |
package_patch_list_command => "/usr/bin/yum check-update"; | |
# Remember to escape special characters like | | |
package_list_name_regex => "([^.]+).*"; | |
package_list_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_list_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_installed_regex => ".*(installed|\s+@).*"; | |
package_name_convention => "$(name).$(arch)"; | |
package_delete_convention => "${name}"; | |
# set it to "0" to avoid caching of list during upgrade | |
package_list_update_ifelapsed => "240"; | |
package_patch_installed_regex => "^[^*]\s.*"; | |
package_patch_name_regex => "([^.]+).*"; | |
package_patch_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_patch_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_add_command => "/usr/bin/yum -y install"; | |
package_update_command => "/usr/bin/yum -y update"; | |
package_patch_command => "/usr/bin/yum -y update"; | |
package_delete_command => "/bin/rpm -e --nodeps"; | |
package_verify_command => "/bin/rpm -V"; | |
} | |
## | |
body package_method yum_rpm | |
# Contributed by Trond Hasle Amundsen | |
# More efficient package method for RedHat - uses rpm to list instead of yum | |
# Notes: | |
# - using $(name).$(arch) instead of $(name) for package_name_convention | |
# causes uninstallation to fail. | |
# - using allmatches to remove for all architectures | |
# | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'"; | |
package_patch_list_command => "/usr/bin/yum check-update"; | |
package_list_name_regex => "^(\S+?)\s\S+?\s\S+$"; | |
package_list_version_regex => "^\S+?\s(\S+?)\s\S+$"; | |
package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$"; | |
package_installed_regex => ".*"; | |
package_name_convention => "$(name)"; | |
package_patch_installed_regex => "^[^*]\s.*"; | |
package_patch_name_regex => "([^.]+).*"; | |
package_patch_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_patch_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_add_command => "/usr/bin/yum -y install"; | |
package_update_command => "/usr/bin/yum -y update"; | |
package_patch_command => "/usr/bin/yum -y update"; | |
package_delete_command => "/bin/rpm -e --nodeps --allmatches"; | |
package_verify_command => "/bin/rpm -V"; | |
} | |
## | |
body package_method yum_group | |
# Makes use of the "groups of packages" feature of Yum possible. (yum groupinstall, groupremove) | |
# | |
# Groups must be specified by their groupids, available through yum grouplist -v (between parentheses) | |
# $ yum grouplist -v|grep Networking|head -n 1 | |
# Networking Tools (network-tools) <--- network-tools is the groupid | |
# | |
# Policies examples: | |
# | |
# -Install "web-server" group: | |
# ---------------------------- | |
# | |
# packages: | |
# "web-server" | |
# package_policy => "add", | |
# package_method => yum_group; | |
# | |
# -Remove "debugging" and "php" groups: | |
# ------------------------------------- | |
# | |
# vars: | |
# "groups" slist => { "debugging", "php" }; | |
# | |
# packages: | |
# "$(groups)" | |
# package_policy => "delete", | |
# package_method => yum_group; | |
# | |
{ | |
package_add_command => "/usr/bin/yum groupinstall -y"; | |
package_changes => "bulk"; | |
package_delete_command => "/usr/bin/yum groupremove -y"; | |
package_delete_convention => "$(name)"; | |
package_installed_regex => "^i.*"; | |
# Generate a dpkg -l like listing, "i" means installed, "a" available, and a dummy version 1 | |
package_list_command => | |
"/usr/bin/yum grouplist -v|awk '$0 ~ /^Done$/ {next} {sub(/.*\(/, \"\");sub(/\).*/, \"\")} /Available/ {h=\"a\";next} /Installed/ {h=\"i\";next} h==\"i\" || h==\"a\" {print h\" \"$0\" 1\"}'"; | |
package_list_name_regex => "a|i ([^\s]+) 1"; | |
package_list_update_command => "/usr/bin/yum --quiet check-update"; | |
package_list_update_ifelapsed => "240"; | |
package_list_version_regex => "(1)"; | |
package_name_convention => "$(name)"; | |
package_name_regex => "(.*)"; | |
package_noverify_returncode => "0"; | |
package_update_command => "/usr/bin/yum groupupdate"; | |
# grep -x to only get full line matching | |
package_verify_command => "/usr/bin/yum grouplist -v|awk '$0 ~ /^Done$/ {next} {sub(/.*\(/, \"\");sub(/\).*/, \"\")} /Available/ {h=\"a\";next} /Installed/ {h=\"i\";next} h==\"i\"|grep -qx"; | |
} | |
## | |
body package_method rpm_filebased(path) | |
# Contributed by Aleksey Tsalolikhin. Written on 29-Feb-2012. | |
# Based on yum_rpm body in COPBL by Trond Hasle Amundsen. | |
# Purpose: install packages from local filesystem-based package repository. | |
# Note: Specify the path to the local package repository in the argument. | |
# Example of how to use it: | |
# | |
# {{{ | |
# packages: | |
# "epel-release" | |
# package_policy => "add", | |
# package_version => "5-4", | |
# package_architectures => { "noarch" }, | |
# package_method => rpm_filebased("/repo/RPMs"); | |
# }}} | |
{ | |
package_file_repositories => { "$(path)" }; | |
# the above is an addition to Trond's yum_rpm body | |
package_add_command => "/bin/rpm -ihv "; | |
# The above is a change from Trond's yum_rpm body, this makes the commands rpm only. | |
# The reason I changed the install command from yum to rpm is yum will be default | |
# refuse to install the epel-release RPM as it does not have the EPEL GPG key, | |
# but rpm goes ahead and installs the epel-release RPM and the EPEL GPG key. | |
package_name_convention => "$(name)-$(version).$(arch).rpm"; | |
# The above is a change from Tron's yum_rpm body. When package_file_repositories is in play, | |
# package_name_convention has to match the file name, not the package name, per the | |
# CFEngine 3 Reference Manual | |
# The rest is unchanged from Trond's yum_rpm body | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'"; | |
package_list_name_regex => "^(\S+?)\s\S+?\s\S+$"; | |
package_list_version_regex => "^\S+?\s(\S+?)\s\S+$"; | |
package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$"; | |
package_installed_regex => ".*"; | |
package_delete_command => "/bin/rpm -e --allmatches"; | |
package_verify_command => "/bin/rpm -V"; | |
} | |
## | |
# OpenSolaris based systems (Solaris 11, Illumos, etc) use the much better | |
# Image Package System. | |
body package_method ips { | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/pkg list -v --no-refresh"; | |
package_list_name_regex => "pkg://.+?/([^\s]+)@.*$"; | |
package_list_version_regex => "[^\s]+@([^\s]+).*"; | |
package_installed_regex => ".*(i..)"; # all reported are installed | |
# set it to "0" to avoid caching of list during upgrade | |
package_list_update_ifelapsed => "240"; | |
package_add_command => "/usr/bin/pkg install --accept "; | |
package_list_update_command => "/usr/bin/pkg refresh --full"; | |
package_delete_command => "/usr/bin/pkg uninstall"; | |
package_update_command => "/usr/bin/pkg install --accept"; | |
package_patch_command => "/usr/bin/pkg install --accept"; | |
package_verify_command => "/usr/bin/pkg list -a -v --no-refresh"; | |
package_noverify_regex => "(.*---|pkg list: no packages matching .* installed)"; | |
} | |
## | |
# SmartOS (solaris 10 fork by Joyent) uses pkgin | |
body package_method smartos | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/opt/local/bin/pkgin list"; | |
package_list_name_regex => "(.*)\-[0-9]+.*"; | |
package_list_version_regex => ".*\-([0-9][^\s]+).*"; | |
package_installed_regex => ".*"; # all reported are installed | |
package_list_update_command => "/opt/local/bin/pkgin -y update"; | |
package_list_update_ifelapsed => "240"; | |
package_add_command => "/opt/local/bin/pkgin -y install"; | |
package_delete_command => "/opt/local/bin/pkgin -y remove"; | |
package_update_command => "/opt/local/bin/pkgin upgrade"; | |
} | |
# OpenCSW (Solaris software packages) | |
body package_method opencsw | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/opt/csw/bin/pkgutil -c"; | |
package_list_name_regex => "CSW(.*?)\s.*"; | |
package_list_version_regex => ".*?\s+(.*),.*"; | |
package_installed_regex => ".*"; # all reported are installed | |
package_list_update_command => "/opt/csw/bin/pkgutil -U"; | |
package_list_update_ifelapsed => "240"; | |
package_add_command => "/opt/csw/bin/pkgutil -yi"; | |
package_delete_command => "/opt/csw/bin/pkgutil -yr"; | |
package_update_command => "/opt/csw/bin/pkgutil -yu"; | |
} | |
# The older solaris package system is poorly designed, with too many different | |
# names to track. See the example in tests/units/unit_package_solaris.cf | |
# to see how to use this | |
body package_method solaris (pkgname, spoolfile, adminfile) | |
{ | |
package_changes => "individual"; | |
package_list_command => "/usr/bin/pkginfo -l"; | |
package_multiline_start => "\s*PKGINST:\s+[^\s]+.*"; | |
package_list_name_regex => "\s*PKGINST:\s+([^\s]+).*"; | |
package_list_version_regex => "\s*VERSION:\s+([^\s]+).*"; | |
package_list_arch_regex => "\s*ARCH:\s+([^\s]+)"; | |
package_installed_regex => "\s*STATUS:\s*(completely|partially)\s+installed.*"; | |
package_name_convention => "$(name)"; | |
package_add_command => "/usr/sbin/pkgadd -n -a /tmp/$(adminfile) -d /tmp/$(spoolfile)"; | |
package_delete_command => "/usr/sbin/pkgrm -n -a /tmp/$(adminfile)"; | |
} | |
## | |
# | |
# The following bundle is part of a package setup for solaris, see unit examples | |
# | |
bundle edit_line create_solaris_admin_file | |
{ | |
insert_lines: | |
"mail= | |
instance=unique | |
partial=nocheck | |
runlevel=nocheck | |
idepend=nocheck | |
rdepend=nocheck | |
space=nocheck | |
setuid=nocheck | |
conflict=nocheck | |
action=nocheck | |
networktimeout=60 | |
networkretries=3 | |
authentication=quit | |
keystore=/var/sadm/security | |
proxy= | |
basedir=default" | |
comment => "Insert contents of Solaris admin file (automatically install packages)"; | |
} | |
## | |
body package_method freebsd | |
{ | |
package_changes => "individual"; | |
# Could use rpm for this | |
package_list_command => "/usr/sbin/pkg_info"; | |
# Remember to escape special characters like | | |
package_list_name_regex => "([^\s]+)-.*"; | |
package_list_version_regex => "[^\s]+-([^\s]+).*"; | |
package_name_regex => "([^\s]+)-.*"; | |
package_version_regex => "[^\s]+-([^\s]+).*"; | |
package_installed_regex => ".*"; | |
package_name_convention => "$(name)-$(version)"; | |
package_add_command => "/usr/sbin/pkg_add -r"; | |
package_delete_command => "/usr/sbin/pkg_delete"; | |
} | |
body package_method freebsd_portmaster | |
{ | |
package_changes => "individual"; | |
package_list_command => "/usr/sbin/pkg_info"; | |
package_list_name_regex => "([^\s]+)-.*"; | |
package_list_version_regex => "[^\s]+-([^\s]+).*"; | |
package_installed_regex => ".*"; | |
package_name_convention => "$(name)"; | |
package_delete_convention => "$(name)-$(version)"; | |
package_file_repositories => { | |
"/usr/ports/accessibility/", | |
"/usr/port/arabic/", | |
"/usr/ports/archivers/", | |
"/usr/ports/astro/", | |
"/usr/ports/audio/", | |
"/usr/ports/benchmarks/", | |
"/usr/ports/biology/", | |
"/usr/ports/cad/", | |
"/usr/ports/chinese/", | |
"/usr/ports/comms/", | |
"/usr/ports/converters/", | |
"/usr/ports/databases/", | |
"/usr/ports/deskutils/", | |
"/usr/ports/devel/", | |
"/usr/ports/dns/", | |
"/usr/ports/editors/", | |
"/usr/ports/emulators/", | |
"/usr/ports/finance/", | |
"/usr/ports/french/", | |
"/usr/ports/ftp/", | |
"/usr/ports/games/", | |
"/usr/ports/german/", | |
"/usr/ports/graphics/", | |
"/usr/ports/hebrew/", | |
"/usr/ports/hungarian/", | |
"/usr/ports/irc/", | |
"/usr/ports/japanese/", | |
"/usr/ports/java/", | |
"/usr/ports/korean/", | |
"/usr/ports/lang/", | |
"/usr/ports/mail/", | |
"/usr/ports/math/", | |
"/usr/ports/mbone/", | |
"/usr/ports/misc/", | |
"/usr/ports/multimedia/", | |
"/usr/ports/net/", | |
"/usr/ports/net-im/", | |
"/usr/ports/net-mgmt/", | |
"/usr/ports/net-p2p/", | |
"/usr/ports/news/", | |
"/usr/ports/packages/", | |
"/usr/ports/palm/", | |
"/usr/ports/polish/", | |
"/usr/ports/ports-mgmt/", | |
"/usr/ports/portuguese/", | |
"/usr/ports/print/", | |
"/usr/ports/russian/", | |
"/usr/ports/science/", | |
"/usr/ports/security/", | |
"/usr/ports/shells/", | |
"/usr/ports/sysutils/", | |
"/usr/ports/textproc/", | |
"/usr/ports/ukrainian/", | |
"/usr/ports/vietnamese/", | |
"/usr/ports/www/", | |
"/usr/ports/x11/", | |
"/usr/ports/x11-clocks/", | |
"/usr/ports/x11-drivers/", | |
"/usr/ports/x11-fm/", | |
"/usr/ports/x11-fonts/", | |
"/usr/ports/x11-servers/", | |
"/usr/ports/x11-themes/", | |
"/usr/ports/x11-toolkits/", | |
"/usr/ports/x11-wm/", | |
}; | |
package_add_command => "/usr/local/sbin/portmaster -D -G --no-confirm"; | |
package_update_command => "/usr/local/sbin/portmaster -D -G --no-confirm"; | |
package_delete_command => "/usr/local/sbin/portmaster --no-confirm -e"; | |
} | |
## | |
body package_method alpinelinux | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/sbin/apk info -v"; | |
package_list_name_regex => "([^\s]+)-.*"; | |
package_list_version_regex => "[^\s]+-([^\s]+).*"; | |
package_name_regex => ".*"; | |
package_installed_regex => ".*"; | |
package_name_convention => "$(name)"; | |
package_add_command => "/sbin/apk add"; | |
package_delete_command => "/sbin/apk del"; | |
} | |
## | |
body package_method emerge | |
{ | |
package_changes => "individual"; | |
package_list_command => "/bin/sh -c '/bin/ls -d /var/db/pkg/*/* | cut -c 13-'"; | |
package_list_name_regex => ".*/([^\s]+)-\d.*"; | |
package_list_version_regex => ".*/[^\s]+-(\d.*)"; | |
package_installed_regex => ".*"; # all reported are installed | |
package_name_convention => "$(name)"; | |
package_list_update_command => "/bin/true"; # I prefer manual syncing | |
#package_list_update_command => "/usr/bin/emerge --sync"; # if you like automatic | |
package_list_update_ifelapsed => "240"; # should happen every 4 hours | |
package_add_command => "/usr/bin/emerge -q --quiet-build"; | |
package_delete_command => "/usr/bin/emerge --depclean"; | |
package_update_command => "/usr/bin/emerge --update"; | |
package_patch_command => "/usr/bin/emerge --update"; | |
package_verify_command => "/usr/bin/emerge -s"; | |
package_noverify_regex => ".*(Not Installed|Applications found : 0).*"; | |
} | |
## | |
body package_method pacman | |
{ | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/pacman -Q"; | |
# set it to "0" to avoid caching of list during upgrade | |
package_list_update_ifelapsed => "240"; | |
package_list_name_regex => "(.*)\s+.*"; | |
package_list_version_regex => ".*\s+(.*)"; | |
package_installed_regex => ".*"; | |
package_name_convention => "$(name)"; | |
package_add_command => "/usr/bin/pacman -S --noconfirm --noprogressbar --needed"; | |
package_delete_command => "/usr/bin/pacman -Rs --noconfirm"; | |
package_update_command => "/usr/bin/pacman -S --noconfirm --noprogressbar --needed"; | |
} | |
## | |
# Single bundle for all the similar managers simplifies promises | |
body package_method generic | |
{ | |
SuSE:: | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; | |
package_patch_list_command => "/usr/bin/zypper patches"; | |
package_installed_regex => "i.*"; | |
package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_patch_installed_regex => ".*Installed.*|.*Not Applicable.*"; | |
package_patch_name_regex => "[^|]+\|\s+([^\s]+).*"; | |
package_patch_version_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; | |
package_name_convention => "$(name)"; | |
package_add_command => "/usr/bin/zypper --non-interactive install"; | |
package_delete_command => "/usr/bin/zypper --non-interactive remove --force-resolution"; | |
package_update_command => "/usr/bin/zypper --non-interactive update"; | |
package_patch_command => "/usr/bin/zypper --non-interactive patch$"; # $ means no args | |
package_verify_command => "/usr/bin/zypper --non-interactive verify$"; | |
redhat:: | |
package_changes => "bulk"; | |
package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'"; | |
package_patch_list_command => "/usr/bin/yum check-update"; | |
package_list_name_regex => "^(\S+?)\s\S+?\s\S+$"; | |
package_list_version_regex => "^\S+?\s(\S+?)\s\S+$"; | |
package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$"; | |
package_installed_regex => ".*"; | |
package_name_convention => "$(name)"; | |
package_list_update_ifelapsed => "0"; # sometimes, caching is pretty disturbing | |
package_patch_installed_regex => "^[^*]\s.*"; | |
package_patch_name_regex => "([^.]+).*"; | |
package_patch_version_regex => "[^\s]\s+([^\s]+).*"; | |
package_patch_arch_regex => "[^.]+\.([^\s]+).*"; | |
package_add_command => "/usr/bin/yum -y install"; | |
package_update_command => "/usr/bin/yum -y update"; | |
package_patch_command => "/usr/bin/yum -y update"; | |
package_delete_command => "/bin/rpm -e --nodeps --allmatches"; | |
package_verify_command => "/bin/rpm -V"; | |
# package_changes => "bulk"; | |
# package_list_command => "/usr/bin/yum list installed"; | |
# package_patch_list_command => "/usr/bin/yum check-update"; | |
# package_list_name_regex => "([^.]+).*"; | |
# package_list_version_regex => "[^\s]\s+([^\s]+).*"; | |
# package_list_arch_regex => "[^.]+\.([^\s]+).*"; | |
# package_installed_regex => ".*(installed|\s+@).*"; | |
# package_name_convention => "$(name).$(arch)"; | |
# package_list_update_ifelapsed => "240"; | |
# package_patch_installed_regex => "^[^*]\s.*"; | |
# package_patch_name_regex => "([^.]+).*"; | |
# package_patch_version_regex => "[^\s]\s+([^\s]+).*"; | |
# package_patch_arch_regex => "[^.]+\.([^\s]+).*"; | |
# package_add_command => "/usr/bin/yum -y install"; | |
# package_delete_command => "/bin/rpm -e --nodeps"; | |
# package_verify_command => "/bin/rpm -V"; | |
debian:: | |
package_changes => "bulk"; | |
package_list_command => "/usr/bin/dpkg -l"; | |
package_list_name_regex => ".i\s+([^\s:]+).*"; | |
package_list_version_regex => ".i\s+[^\s]+\s+([^\s]+).*"; | |
package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed | |
package_name_convention => "$(name)"; | |
package_list_update_ifelapsed => "240"; # 4 hours | |
debian.have_aptitude:: | |
package_add_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --assume-yes install"; | |
package_list_update_command => "/usr/bin/aptitude update"; | |
package_delete_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --assume-yes remove"; | |
package_update_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --assume-yes install"; | |
package_patch_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/aptitude -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --assume-yes install"; | |
package_verify_command => "/usr/bin/aptitude show"; | |
package_noverify_regex => "(State: not installed|E: Unable to locate package .*)"; | |
debian.!have_aptitude:: | |
package_add_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --yes install"; | |
package_list_update_command => "/usr/bin/apt-get update"; | |
package_delete_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --yes remove"; | |
package_update_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --yes install"; | |
package_patch_command => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C /usr/bin/apt-get -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --yes install"; | |
package_verify_command => "/usr/bin/dpkg -s"; | |
package_noverify_returncode => "1"; | |
freebsd:: | |
package_changes => "individual"; | |
package_list_command => "/usr/sbin/pkg_info"; | |
package_list_name_regex => "([^\s]+)-.*"; | |
package_list_version_regex => "[^\s]+-([^\s]+).*"; | |
package_name_regex => "([^\s]+)-.*"; | |
package_version_regex => "[^\s]+-([^\s]+).*"; | |
package_installed_regex => ".*"; | |
package_name_convention => "$(name)-$(version)"; | |
package_add_command => "/usr/sbin/pkg_add -r"; | |
package_delete_command => "/usr/sbin/pkg_delete"; | |
gentoo:: | |
package_changes => "individual"; | |
package_list_command => "/bin/sh -c '/bin/ls -d /var/db/pkg/*/* | cut -c 13-'"; | |
package_list_name_regex => ".*/([^\s]+)-\d.*"; | |
package_list_version_regex => ".*/[^\s]+-(\d.*)"; | |
package_installed_regex => ".*"; # all reported are installed | |
package_name_convention => "$(name)"; | |
package_list_update_command => "/bin/true"; # I prefer manual syncing | |
#package_list_update_command => "/usr/bin/emerge --sync"; # if you like automatic | |
package_list_update_ifelapsed => "240"; # should happen every 4 hours | |
package_add_command => "/usr/bin/emerge -q --quiet-build"; | |
package_delete_command => "/usr/bin/emerge --depclean"; | |
package_update_command => "/usr/bin/emerge --update"; | |
package_patch_command => "/usr/bin/emerge --update"; | |
package_verify_command => "/usr/bin/emerge -s"; | |
package_noverify_regex => ".*(Not Installed|Applications found : 0).*"; | |
} | |
## | |
##------------------------------------------------------- | |
## storage promises | |
##------------------------------------------------------- | |
body volume min_free_space(free) | |
{ | |
check_foreign => "false"; | |
freespace => "$(free)"; | |
sensible_size => "10000"; | |
sensible_count => "2"; | |
} | |
## | |
body mount nfs(server,source) | |
{ | |
mount_type => "nfs"; | |
mount_source => "$(source)"; | |
mount_server => "$(server)"; | |
edit_fstab => "true"; | |
} | |
## | |
body mount nfs_p(server,source,perm) | |
{ | |
mount_type => "nfs"; | |
mount_source => "$(source)"; | |
mount_server => "$(server)"; | |
mount_options => {"$(perm)"}; | |
edit_fstab => "true"; | |
} | |
## | |
body mount unmount | |
{ | |
mount_type => "nfs"; | |
edit_fstab => "true"; | |
unmount => "true"; | |
} | |
##------------------------------------------------------- | |
## process promises | |
##------------------------------------------------------- | |
body process_select exclude_procs(x) | |
{ | |
command => "$(x)"; | |
process_result => "!command"; | |
} | |
## | |
body process_select days_older_than(d) | |
{ | |
stime_range => irange(ago(0,0,"$(d)",0,0,0),now); | |
process_result => "stime"; | |
} | |
## | |
body process_count any_count(cl) | |
{ | |
match_range => "0,0"; | |
out_of_range_define => { "$(cl)" }; | |
} | |
## | |
body process_count check_range(name,lower,upper) | |
{ | |
match_range => irange("$(lower)","$(upper)"); | |
out_of_range_define => { "$(name)_out_of_range" }; | |
} | |
##------------------------------------------------------- | |
## service promises | |
##------------------------------------------------------- | |
body service_method bootstart | |
{ | |
service_autostart_policy => "boot_time"; | |
service_dependence_chain => "start_parent_services"; | |
windows:: | |
service_type => "windows"; | |
} | |
## | |
body service_method force_deps | |
{ | |
service_dependence_chain => "all_related"; | |
windows:: | |
service_type => "windows"; | |
} | |
## | |
bundle agent standard_services(service,state) | |
{ | |
# DATA, | |
vars: | |
any:: | |
"stakeholders[cfengine3]" slist => { "cfengine_in" }; | |
"stakeholders[acpid]" slist => { "cpu", "cpu0", "cpu1", "cpu2", "cpu3" }; | |
"stakeholders[mongod]" slist => { "mongo_in" }; | |
"stakeholders[postfix]" slist => { "smtp_in" }; | |
"stakeholders[sendmail]" slist => { "smtp_in" }; | |
"stakeholders[www]" slist => { "www_in", "wwws_in", "www_alt_in" }; | |
"stakeholders[ssh]" slist => { "ssh_in" }; | |
"stakeholders[mysql]" slist => { "mysql_in" }; | |
"stakeholders[nfs]" slist => { "nfsd_in" }; | |
"stakeholders[syslog]" slist => { "syslog" }; | |
"stakeholders[rsyslog]" slist => { "syslog" }; | |
"stakeholders[tomcat5]" slist => { "www_alt_in" }; | |
"stakeholders[tomcat6]" slist => { "www_alt_in" }; | |
linux:: | |
"startcommand[acpid]" string => "/etc/init.d/acpid start"; | |
"restartcommand[acpid]" string => "/etc/init.d/acpid restart"; | |
"reloadcommand[acpid]" string => "/etc/init.d/acpid reload"; | |
"stopcommand[acpid]" string => "/etc/init.d/acpid stop"; | |
"pattern[acpid]" string => ".*acpid.*"; | |
"startcommand[cfengine3]" string => "/etc/init.d/cfengine3 start"; | |
"restartcommand[cfengine3]" string => "/etc/init.d/cfengine3 restart"; | |
"reloadcommand[cfengine3]" string => "/etc/init.d/cfengine3 reload"; | |
"stopcommand[cfengine3]" string => "/etc/init.d/cfengine3 stop"; | |
"pattern[cfengine3]" string => ".*cf-execd.*"; | |
"startcommand[fancontrol]" string => "/etc/init.d/fancontrol start"; | |
"restartcommand[fancontrol]" string => "/etc/init.d/fancontrol restart"; | |
"reloadcommand[fancontrol]" string => "/etc/init.d/fancontrol reload"; | |
"stopcommand[fancontrol]" string => "/etc/init.d/fancontrol stop"; | |
"pattern[fancontrol]" string => ".*fancontrol.*"; | |
"startcommand[hddtemp]" string => "/etc/init.d/hddtemp start"; | |
"restartcommand[hddtemp]" string => "/etc/init.d/hddtemp restart"; | |
"reloadcommand[hddtemp]" string => "/etc/init.d/hddtemp reload"; | |
"stopcommand[hddtemp]" string => "/etc/init.d/hddtemp stop"; | |
"pattern[hddtemp]" string => ".*hddtemp.*"; | |
"startcommand[irqbalance]" string => "/etc/init.d/irqbalance start"; | |
"restartcommand[irqbalance]" string => "/etc/init.d/irqbalance restart"; | |
"reloadcommand[irqbalance]" string => "/etc/init.d/irqbalance reload"; | |
"stopcommand[irqbalance]" string => "/etc/init.d/irqbalance stop"; | |
"pattern[irqbalance]" string => ".*irqbalance.*"; | |
"startcommand[lm-sensor]" string => "/etc/init.d/lm-sensor start"; | |
"restartcommand[lm-sensor]" string => "/etc/init.d/lm-sensor restart"; | |
"reloadcommand[lm-sensor]" string => "/etc/init.d/lm-sensor reload"; | |
"stopcommand[lm-sensor]" string => "/etc/init.d/lm-sensor stop"; | |
"pattern[lm-sensor]" string => ".*psensor.*"; | |
"startcommand[mongod]" string => "/etc/init.d/mongod start"; | |
"restartcommand[mongod]" string => "/etc/init.d/mongod restart"; | |
"reloadcommand[mongod]" string => "/etc/init.d/mongod reload"; | |
"stopcommand[mongod]" string => "/etc/init.d/mongod stop"; | |
"pattern[mongod]" string => ".*mongod.*"; | |
"startcommand[openvpn]" string => "/etc/init.d/openvpn start"; | |
"restartcommand[openvpn]" string => "/etc/init.d/openvpn restart"; | |
"reloadcommand[openvpn]" string => "/etc/init.d/openvpn reload"; | |
"stopcommand[openvpn]" string => "/etc/init.d/openvpn stop"; | |
"pattern[openvpn]" string => ".*openvpn.*"; | |
"startcommand[postfix]" string => "/etc/init.d/postfix start"; | |
"restartcommand[postfix]" string => "/etc/init.d/postfix restart"; | |
"reloadcommand[postfix]" string => "/etc/init.d/postfix reload"; | |
"stopcommand[postfix]" string => "/etc/init.d/postfix stop"; | |
"pattern[postfix]" string => ".*postfix.*"; | |
"startcommand[rsync]" string => "/etc/init.d/rsync start"; | |
"restartcommand[rsync]" string => "/etc/init.d/rsync restart"; | |
"reloadcommand[rsync]" string => "/etc/init.d/rsync reload"; | |
"stopcommand[rsync]" string => "/etc/init.d/rsync stop"; | |
"pattern[rsync]" string => ".*rsync.*"; | |
"startcommand[rsyslog]" string => "/etc/init.d/rsyslog start"; | |
"restartcommand[rsyslog]" string => "/etc/init.d/rsyslog restart"; | |
"reloadcommand[rsyslog]" string => "/etc/init.d/rsyslog reload"; | |
"stopcommand[rsyslog]" string => "/etc/init.d/rsyslog stop"; | |
"pattern[rsyslog]" string => ".*rsyslogd.*"; | |
"startcommand[sendmail]" string => "/etc/init.d/sendmail start"; | |
"restartcommand[sendmail]" string => "/etc/init.d/sendmail restart"; | |
"reloadcommand[sendmail]" string => "/etc/init.d/sendmail reload"; | |
"stopcommand[sendmail]" string => "/etc/init.d/sendmail stop"; | |
"pattern[sendmail]" string => ".*sendmail.*"; | |
"startcommand[tomcat5]" string => "/etc/init.d/tomcat5 start"; | |
"restartcommand[tomcat5]" string => "/etc/init.d/tomcat5 restart"; | |
"reloadcommand[tomcat5]" string => "/etc/init.d/tomcat5 reload"; | |
"stopcommand[tomcat5]" string => "/etc/init.d/tomcat5 stop"; | |
"pattern[tomcat5]" string => ".*tomcat5.*"; | |
"startcommand[tomcat6]" string => "/etc/init.d/tomcat6 start"; | |
"restartcommand[tomcat6]" string => "/etc/init.d/tomcat6 restart"; | |
"reloadcommand[tomcat6]" string => "/etc/init.d/tomcat6 reload"; | |
"stopcommand[tomcat6]" string => "/etc/init.d/tomcat6 stop"; | |
"pattern[tomcat6]" string => ".*tomcat6.*"; | |
"startcommand[varnish]" string => "/etc/init.d/varnish start"; | |
"restartcommand[varnish]" string => "/etc/init.d/varnish restart"; | |
"reloadcommand[varnish]" string => "/etc/init.d/varnish reload"; | |
"stopcommand[varnish]" string => "/etc/init.d/varnish stop"; | |
"pattern[varnish]" string => ".*varnish.*"; | |
"startcommand[wpa_supplicant]" string => "/etc/init.d/wpa_supplicant start"; | |
"restartcommand[wpa_supplicant]" string => "/etc/init.d/wpa_supplicant restart"; | |
"reloadcommand[wpa_supplicant]" string => "/etc/init.d/wpa_supplicant reload"; | |
"stopcommand[wpa_supplicant]" string => "/etc/init.d/wpa_supplicant stop"; | |
"pattern[wpa_supplicant]" string => ".*wpa_supplicant.*"; | |
SuSE|suse:: | |
"startcommand[mysql]" string => "/etc/init.d/mysqld start"; | |
"restartcommand[mysql]" string => "/etc/init.d/mysqld restart"; | |
"reloadcommand[mysql]" string => "/etc/init.d/mysqld reload"; | |
"stopcommand[mysql]" string => "/etc/init.d/mysqld stop"; | |
"pattern[mysql]" string => ".*mysqld.*"; | |
"startcommand[www]" string => "/etc/init.d/apache2 start"; | |
"restartcommand[www]" string => "/etc/init.d/apache2 restart"; | |
"reloadcommand[www]" string => "/etc/init.d/apache2 reload"; | |
"stopcommand[www]" string => "/etc/init.d/apache2 stop"; | |
"pattern[www]" string => ".*apache2.*"; | |
"startcommand[ssh]" string => "/etc/init.d/sshd start"; | |
"restartcommand[ssh]" string => "/etc/init.d/sshd restart"; | |
"reloadcommand[ssh]" string => "/etc/init.d/sshd reload"; | |
"stopcommand[ssh]" string => "/etc/init.d/sshd stop"; | |
"pattern[ssh]" string => ".*sshd.*"; | |
redhat:: | |
"startcommand[anacron]" string => "/etc/init.d/anacron start"; | |
"restartcommand[anacron]" string => "/etc/init.d/anacron restart"; | |
"reloadcommand[anacron]" string => "/etc/init.d/anacron reload"; | |
"stopcommand[anacron]" string => "/etc/init.d/anacron stop"; | |
"pattern[anacron]" string => ".*anacron.*"; | |
"startcommand[atd]" string => "/etc/init.d/atd start"; | |
"restartcommand[atd]" string => "/etc/init.d/atd restart"; | |
"reloadcommand[atd]" string => "/etc/init.d/atd reload"; | |
"stopcommand[atd]" string => "/etc/init.d/atd stop"; | |
"pattern[atd]" string => ".*sbin/atd.*"; | |
"startcommand[auditd]" string => "/etc/init.d/auditd start"; | |
"restartcommand[auditd]" string => "/etc/init.d/auditd restart"; | |
"reloadcommand[auditd]" string => "/etc/init.d/auditd reload"; | |
"stopcommand[auditd]" string => "/etc/init.d/auditd stop"; | |
"pattern[auditd]" string => ".*auditd$"; | |
"startcommand[autofs]" string => "/etc/init.d/autofs start"; | |
"restartcommand[autofs]" string => "/etc/init.d/autofs restart"; | |
"reloadcommand[autofs]" string => "/etc/init.d/autofs reload"; | |
"stopcommand[autofs]" string => "/etc/init.d/autofs stop"; | |
"pattern[autofs]" string => ".*automount.*"; | |
"startcommand[bluetoothd]" string => "/etc/init.d/bluetooth start"; | |
"restartcommand[bluetoothd]" string => "/etc/init.d/bluetooth restart"; | |
"reloadcommand[bluetoothd]" string => "/etc/init.d/bluetooth reload"; | |
"stopcommand[bluetoothd]" string => "/etc/init.d/bluetooth stop"; | |
"pattern[bluetoothd]" string => ".*hcid.*"; | |
"startcommand[capi]" string => "/etc/init.d/capi start"; | |
"restartcommand[capi]" string => "/etc/init.d/capi restart"; | |
"reloadcommand[capi]" string => "/etc/init.d/capi reload"; | |
"stopcommand[capi]" string => "/etc/init.d/capi stop"; | |
"pattern[capi]" string => ".*capiinit.*"; | |
"startcommand[conman]" string => "/etc/init.d/conman start"; | |
"restartcommand[conman]" string => "/etc/init.d/conman restart"; | |
"reloadcommand[conman]" string => "/etc/init.d/conman reload"; | |
"stopcommand[conman]" string => "/etc/init.d/conman stop"; | |
"pattern[conman]" string => ".*conmand.*"; | |
"startcommand[cpuspeed]" string => "/etc/init.d/cpuspeed start"; | |
"restartcommand[cpuspeed]" string => "/etc/init.d/cpuspeed restart"; | |
"reloadcommand[cpuspeed]" string => "/etc/init.d/cpuspeed reload"; | |
"stopcommand[cpuspeed]" string => "/etc/init.d/cpuspeed stop"; | |
"pattern[cpuspeed]" string => ".*cpuspeed.*"; | |
"startcommand[crond]" string => "/etc/init.d/crond start"; | |
"restartcommand[crond]" string => "/etc/init.d/crond restart"; | |
"reloadcommand[crond]" string => "/etc/init.d/crond reload"; | |
"stopcommand[crond]" string => "/etc/init.d/crond stop"; | |
"pattern[crond]" string => ".*crond.*"; | |
"startcommand[dc_client]" string => "/etc/init.d/dc_client start"; | |
"restartcommand[dc_client]" string => "/etc/init.d/dc_client restart"; | |
"reloadcommand[dc_client]" string => "/etc/init.d/dc_client reload"; | |
"stopcommand[dc_client]" string => "/etc/init.d/dc_client stop"; | |
"pattern[dc_client]" string => ".*dc_client.*"; | |
"startcommand[dc_server]" string => "/etc/init.d/dc_server start"; | |
"restartcommand[dc_server]" string => "/etc/init.d/dc_server restart"; | |
"reloadcommand[dc_server]" string => "/etc/init.d/dc_server reload"; | |
"stopcommand[dc_server]" string => "/etc/init.d/dc_server stop"; | |
"pattern[dc_server]" string => ".*dc_server.*"; | |
"startcommand[dnsmasq]" string => "/etc/init.d/dnsmasq start"; | |
"restartcommand[dnsmasq]" string => "/etc/init.d/dnsmasq restart"; | |
"reloadcommand[dnsmasq]" string => "/etc/init.d/dnsmasq reload"; | |
"stopcommand[dnsmasq]" string => "/etc/init.d/dnsmasq stop"; | |
"pattern[dnsmasq]" string => ".*dnsmasq.*"; | |
"startcommand[dund]" string => "/etc/init.d/dund start"; | |
"restartcommand[dund]" string => "/etc/init.d/dund restart"; | |
"reloadcommand[dund]" string => "/etc/init.d/dund reload"; | |
"stopcommand[dund]" string => "/etc/init.d/dund stop"; | |
"pattern[dund]" string => ".*dund.*"; | |
"startcommand[gpm]" string => "/etc/init.d/gpm start"; | |
"restartcommand[gpm]" string => "/etc/init.d/gpm restart"; | |
"reloadcommand[gpm]" string => "/etc/init.d/gpm reload"; | |
"stopcommand[gpm]" string => "/etc/init.d/gpm stop"; | |
"pattern[gpm]" string => ".*gpm.*"; | |
"startcommand[haldaemon]" string => "/etc/init.d/haldaemon start"; | |
"restartcommand[haldaemon]" string => "/etc/init.d/haldaemon restart"; | |
"reloadcommand[haldaemon]" string => "/etc/init.d/haldaemon reload"; | |
"stopcommand[haldaemon]" string => "/etc/init.d/haldaemon stop"; | |
"pattern[haldaemon]" string => ".*hald.*"; | |
"startcommand[hidd]" string => "/etc/init.d/hidd start"; | |
"restartcommand[hidd]" string => "/etc/init.d/hidd restart"; | |
"reloadcommand[hidd]" string => "/etc/init.d/hidd reload"; | |
"stopcommand[hidd]" string => "/etc/init.d/hidd stop"; | |
"pattern[hidd]" string => ".*hidd.*"; | |
# "startcommand[ip6tables]" string => "/etc/init.d/ip6tables start"; | |
# "restartcommand[ip6tables]" string => "/etc/init.d/ip6tables restart"; | |
# "reloadcommand[ip6tables]" string => "/etc/init.d/ip6tables reload"; | |
# "stopcommand[ip6tables]" string => "/etc/init.d/ip6tables stop"; | |
# "pattern[ip6tables]" string => ".*ip6tables.*"; | |
# "startcommand[iptables]" string => "/etc/init.d/iptables start"; | |
# "restartcommand[iptables]" string => "/etc/init.d/iptables restart"; | |
# "reloadcommand[iptables]" string => "/etc/init.d/iptables reload"; | |
# "stopcommand[iptables]" string => "/etc/init.d/iptables stop"; | |
# "pattern[iptables]" string => ".*iptables.*"; | |
"startcommand[irda]" string => "/etc/init.d/irda start"; | |
"restartcommand[irda]" string => "/etc/init.d/irda restart"; | |
"reloadcommand[irda]" string => "/etc/init.d/irda reload"; | |
"stopcommand[irda]" string => "/etc/init.d/irda stop"; | |
"pattern[irda]" string => ".*irattach.*"; | |
"startcommand[iscsid]" string => "/etc/init.d/iscsid start"; | |
"restartcommand[iscsid]" string => "/etc/init.d/iscsid restart"; | |
"reloadcommand[iscsid]" string => "/etc/init.d/iscsid reload"; | |
"stopcommand[iscsid]" string => "/etc/init.d/iscsid stop"; | |
"pattern[iscsid]" string => ".*iscsid.*"; | |
"startcommand[isdn]" string => "/etc/init.d/isdn start"; | |
"restartcommand[isdn]" string => "/etc/init.d/isdn restart"; | |
"reloadcommand[isdn]" string => "/etc/init.d/isdn reload"; | |
"stopcommand[isdn]" string => "/etc/init.d/isdn stop"; | |
"pattern[isdn]" string => ".*isdnlog.*"; | |
"startcommand[lvm2-monitor]" string => "/etc/init.d/lvm2-monitor start"; | |
"restartcommand[lvm2-monitor]" string => "/etc/init.d/lvm2-monitor restart"; | |
"reloadcommand[lvm2-monitor]" string => "/etc/init.d/lvm2-monitor reload"; | |
"stopcommand[lvm2-monitor]" string => "/etc/init.d/lvm2-monitor stop"; | |
"pattern[lvm2-monitor]" string => ".*vgchange.*"; | |
"startcommand[mcstrans]" string => "/etc/init.d/mcstrans start"; | |
"restartcommand[mcstrans]" string => "/etc/init.d/mcstrans restart"; | |
"reloadcommand[mcstrans]" string => "/etc/init.d/mcstrans reload"; | |
"stopcommand[mcstrans]" string => "/etc/init.d/mcstrans stop"; | |
"pattern[mcstrans]" string => ".*mcstransd.*"; | |
"startcommand[mdmonitor]" string => "/etc/init.d/mdmonitor start"; | |
"restartcommand[mdmonitor]" string => "/etc/init.d/mdmonitor restart"; | |
"reloadcommand[mdmonitor]" string => "/etc/init.d/mdmonitor reload"; | |
"stopcommand[mdmonitor]" string => "/etc/init.d/mdmonitor stop"; | |
"pattern[mdmonitor]" string => ".*mdadm.*"; | |
"startcommand[mdmpd]" string => "/etc/init.d/mdmpd start"; | |
"restartcommand[mdmpd]" string => "/etc/init.d/mdmpd restart"; | |
"reloadcommand[mdmpd]" string => "/etc/init.d/mdmpd reload"; | |
"stopcommand[mdmpd]" string => "/etc/init.d/mdmpd stop"; | |
"pattern[mdmpd]" string => ".*mdmpd.*"; | |
"startcommand[messagebus]" string => "/etc/init.d/messagebus start"; | |
"restartcommand[messagebus]" string => "/etc/init.d/messagebus restart"; | |
"reloadcommand[messagebus]" string => "/etc/init.d/messagebus reload"; | |
"stopcommand[messagebus]" string => "/etc/init.d/messagebus stop"; | |
"pattern[messagebus]" string => ".*dbus-daemon.*"; | |
"startcommand[microcode_ctl]" string => "/etc/init.d/microcode_ctl start"; | |
"restartcommand[microcode_ctl]" string => "/etc/init.d/microcode_ctl restart"; | |
"reloadcommand[microcode_ctl]" string => "/etc/init.d/microcode_ctl reload"; | |
"stopcommand[microcode_ctl]" string => "/etc/init.d/microcode_ctl stop"; | |
"pattern[microcode_ctl]" string => ".*microcode_ctl.*"; | |
"startcommand[multipathd]" string => "/etc/init.d/multipathd start"; | |
"restartcommand[multipathd]" string => "/etc/init.d/multipathd restart"; | |
"reloadcommand[multipathd]" string => "/etc/init.d/multipathd reload"; | |
"stopcommand[multipathd]" string => "/etc/init.d/multipathd stop"; | |
"pattern[multipathd]" string => ".*multipathd.*"; | |
"startcommand[mysql]" string => "/etc/init.d/mysqld start"; | |
"restartcommand[mysql]" string => "/etc/init.d/mysqld restart"; | |
"reloadcommand[mysql]" string => "/etc/init.d/mysqld reload"; | |
"stopcommand[mysql]" string => "/etc/init.d/mysqld stop"; | |
"pattern[mysql]" string => ".*mysqld.*"; | |
"startcommand[netplugd]" string => "/etc/init.d/netplugd start"; | |
"restartcommand[netplugd]" string => "/etc/init.d/netplugd restart"; | |
"reloadcommand[netplugd]" string => "/etc/init.d/netplugd reload"; | |
"stopcommand[netplugd]" string => "/etc/init.d/netplugd stop"; | |
"pattern[netplugd]" string => ".*netplugd.*"; | |
"startcommand[NetworkManager]" string => "/etc/init.d/NetworkManager start"; | |
"restartcommand[NetworkManager]" string => "/etc/init.d/NetworkManager restart"; | |
"reloadcommand[NetworkManager]" string => "/etc/init.d/NetworkManager reload"; | |
"stopcommand[NetworkManager]" string => "/etc/init.d/NetworkManager stop"; | |
"pattern[NetworkManager]" string => ".*NetworkManager.*"; | |
"startcommand[nfs]" string => "/etc/init.d/nfs start"; | |
"restartcommand[nfs]" string => "/etc/init.d/nfs restart"; | |
"reloadcommand[nfs]" string => "/etc/init.d/nfs reload"; | |
"stopcommand[nfs]" string => "/etc/init.d/nfs stop"; | |
"pattern[nfs]" string => ".*nfsd.*"; | |
"startcommand[nfslock]" string => "/etc/init.d/nfslock start"; | |
"restartcommand[nfslock]" string => "/etc/init.d/nfslock restart"; | |
"reloadcommand[nfslock]" string => "/etc/init.d/nfslock reload"; | |
"stopcommand[nfslock]" string => "/etc/init.d/nfslock stop"; | |
"pattern[nfslock]" string => ".*rpc.statd.*"; | |
"startcommand[nscd]" string => "/etc/init.d/nscd start"; | |
"restartcommand[nscd]" string => "/etc/init.d/nscd restart"; | |
"reloadcommand[nscd]" string => "/etc/init.d/nscd reload"; | |
"stopcommand[nscd]" string => "/etc/init.d/nscd stop"; | |
"pattern[nscd]" string => ".*nscd.*"; | |
"startcommand[oddjobd]" string => "/etc/init.d/oddjobd start"; | |
"restartcommand[oddjobd]" string => "/etc/init.d/oddjobd restart"; | |
"reloadcommand[oddjobd]" string => "/etc/init.d/oddjobd reload"; | |
"stopcommand[oddjobd]" string => "/etc/init.d/oddjobd stop"; | |
"pattern[oddjobd]" string => ".*oddjobd.*"; | |
"startcommand[pand]" string => "/etc/init.d/pand start"; | |
"restartcommand[pand]" string => "/etc/init.d/pand restart"; | |
"reloadcommand[pand]" string => "/etc/init.d/pand reload"; | |
"stopcommand[pand]" string => "/etc/init.d/pand stop"; | |
"pattern[pand]" string => ".*pand.*"; | |
"startcommand[pcscd]" string => "/etc/init.d/pcscd start"; | |
"restartcommand[pcscd]" string => "/etc/init.d/pcscd restart"; | |
"reloadcommand[pcscd]" string => "/etc/init.d/pcscd reload"; | |
"stopcommand[pcscd]" string => "/etc/init.d/pcscd stop"; | |
"pattern[pcscd]" string => ".*pcscd.*"; | |
"startcommand[portmap]" string => "/etc/init.d/portmap start"; | |
"restartcommand[portmap]" string => "/etc/init.d/portmap restart"; | |
"reloadcommand[portmap]" string => "/etc/init.d/portmap reload"; | |
"stopcommand[portmap]" string => "/etc/init.d/portmap stop"; | |
"pattern[portmap]" string => ".*portmap.*"; | |
"startcommand[postgresql]" string => "/etc/init.d/postgresql start"; | |
"restartcommand[postgresql]" string => "/etc/init.d/postgresql restart"; | |
"reloadcommand[postgresql]" string => "/etc/init.d/postgresql reload"; | |
"stopcommand[postgresql]" string => "/etc/init.d/postgresql stop"; | |
"pattern[postgresql]" string => ".*postmaster.*"; | |
"startcommand[rdisc]" string => "/etc/init.d/rdisc start"; | |
"restartcommand[rdisc]" string => "/etc/init.d/rdisc restart"; | |
"reloadcommand[rdisc]" string => "/etc/init.d/rdisc reload"; | |
"stopcommand[rdisc]" string => "/etc/init.d/rdisc stop"; | |
"pattern[rdisc]" string => ".*rdisc.*"; | |
"startcommand[rdisc]" string => "/etc/init.d/rdisc start"; | |
"restartcommand[rdisc]" string => "/etc/init.d/rdisc restart"; | |
"reloadcommand[rdisc]" string => "/etc/init.d/rdisc reload"; | |
"stopcommand[rdisc]" string => "/etc/init.d/rdisc stop"; | |
"pattern[rdisc]" string => ".*rdisc.*"; | |
"startcommand[readahead_early]" string => "/etc/init.d/readahead_early start"; | |
"restartcommand[readahead_early]" string => "/etc/init.d/readahead_early restart"; | |
"reloadcommand[readahead_early]" string => "/etc/init.d/readahead_early reload"; | |
"stopcommand[readahead_early]" string => "/etc/init.d/readahead_early stop"; | |
"pattern[readahead_early]" string => ".*readahead.*early.*"; | |
"startcommand[readahead_later]" string => "/etc/init.d/readahead_later start"; | |
"restartcommand[readahead_later]" string => "/etc/init.d/readahead_later restart"; | |
"reloadcommand[readahead_later]" string => "/etc/init.d/readahead_later reload"; | |
"stopcommand[readahead_later]" string => "/etc/init.d/readahead_later stop"; | |
"pattern[readahead_later]" string => ".*readahead.*later.*"; | |
"startcommand[restorecond]" string => "/etc/init.d/restorecond start"; | |
"restartcommand[restorecond]" string => "/etc/init.d/restorecond restart"; | |
"reloadcommand[restorecond]" string => "/etc/init.d/restorecond reload"; | |
"stopcommand[restorecond]" string => "/etc/init.d/restorecond stop"; | |
"pattern[restorecond]" string => ".*restorecond.*"; | |
"startcommand[rpcgssd]" string => "/etc/init.d/rpcgssd start"; | |
"restartcommand[rpcgssd]" string => "/etc/init.d/rpcgssd restart"; | |
"reloadcommand[rpcgssd]" string => "/etc/init.d/rpcgssd reload"; | |
"stopcommand[rpcgssd]" string => "/etc/init.d/rpcgssd stop"; | |
"pattern[rpcgssd]" string => ".*rpc.gssd.*"; | |
"startcommand[rpcidmapd]" string => "/etc/init.d/rpcidmapd start"; | |
"restartcommand[rpcidmapd]" string => "/etc/init.d/rpcidmapd restart"; | |
"reloadcommand[rpcidmapd]" string => "/etc/init.d/rpcidmapd reload"; | |
"stopcommand[rpcidmapd]" string => "/etc/init.d/rpcidmapd stop"; | |
"pattern[rpcidmapd]" string => ".*rpc.idmapd.*"; | |
"startcommand[rpcsvcgssd]" string => "/etc/init.d/rpcsvcgssd start"; | |
"restartcommand[rpcsvcgssd]" string => "/etc/init.d/rpcsvcgssd restart"; | |
"reloadcommand[rpcsvcgssd]" string => "/etc/init.d/rpcsvcgssd reload"; | |
"stopcommand[rpcsvcgssd]" string => "/etc/init.d/rpcsvcgssd stop"; | |
"pattern[rpcsvcgssd]" string => ".*rpc.svcgssd.*"; | |
"startcommand[saslauthd]" string => "/etc/init.d/saslauthd start"; | |
"restartcommand[saslauthd]" string => "/etc/init.d/saslauthd restart"; | |
"reloadcommand[saslauthd]" string => "/etc/init.d/saslauthd reload"; | |
"stopcommand[saslauthd]" string => "/etc/init.d/saslauthd stop"; | |
"pattern[saslauthd]" string => ".*saslauthd.*"; | |
"startcommand[smartd]" string => "/etc/init.d/smartd start"; | |
"restartcommand[smartd]" string => "/etc/init.d/smartd restart"; | |
"reloadcommand[smartd]" string => "/etc/init.d/smartd reload"; | |
"stopcommand[smartd]" string => "/etc/init.d/smartd stop"; | |
"pattern[smartd]" string => ".*smartd.*"; | |
"startcommand[svnserve]" string => "/etc/init.d/svnserve start"; | |
"restartcommand[svnserve]" string => "/etc/init.d/svnserve restart"; | |
"reloadcommand[svnserve]" string => "/etc/init.d/svnserve reload"; | |
"stopcommand[svnserve]" string => "/etc/init.d/svnserve stop"; | |
"pattern[svnserve]" string => ".*svnserve.*"; | |
"startcommand[syslog]" string => "/etc/init.d/syslog start"; | |
"restartcommand[syslog]" string => "/etc/init.d/syslog restart"; | |
"reloadcommand[syslog]" string => "/etc/init.d/syslog reload"; | |
"stopcommand[syslog]" string => "/etc/init.d/syslog stop"; | |
"pattern[syslog]" string => ".*syslogd.*"; | |
"startcommand[tcsd]" string => "/etc/init.d/tcsd start"; | |
"restartcommand[tcsd]" string => "/etc/init.d/tcsd restart"; | |
"reloadcommand[tcsd]" string => "/etc/init.d/tcsd reload"; | |
"stopcommand[tcsd]" string => "/etc/init.d/tcsd stop"; | |
"pattern[tcsd]" string => ".*tcsd.*"; | |
"startcommand[www]" string => "/etc/init.d/httpd start"; | |
"restartcommand[www]" string => "/etc/init.d/httpd restart"; | |
"reloadcommand[www]" string => "/etc/init.d/httpd reload"; | |
"stopcommand[www]" string => "/etc/init.d/httpd stop"; | |
"pattern[www]" string => ".*httpd.*"; | |
"startcommand[xfs]" string => "/etc/init.d/xfs start"; | |
"restartcommand[xfs]" string => "/etc/init.d/xfs restart"; | |
"reloadcommand[xfs]" string => "/etc/init.d/xfs reload"; | |
"stopcommand[xfs]" string => "/etc/init.d/xfs stop"; | |
"pattern[xfs]" string => ".*xfs.*"; | |
"startcommand[ypbind]" string => "/etc/init.d/ypbind start"; | |
"restartcommand[ypbind]" string => "/etc/init.d/ypbind restart"; | |
"reloadcommand[ypbind]" string => "/etc/init.d/ypbind reload"; | |
"stopcommand[ypbind]" string => "/etc/init.d/ypbind stop"; | |
"pattern[ypbind]" string => ".*ypbind.*"; | |
"startcommand[yum-updatesd]" string => "/etc/init.d/yum-updatesd start"; | |
"restartcommand[yum-updatesd]" string => "/etc/init.d/yum-updatesd restart"; | |
"reloadcommand[yum-updatesd]" string => "/etc/init.d/yum-updatesd reload"; | |
"stopcommand[yum-updatesd]" string => "/etc/init.d/yum-updatesd stop"; | |
"pattern[yum-updatesd]" string => ".*yum-updatesd.*"; | |
"startcommand[ssh]" string => "/etc/init.d/sshd start"; | |
"restartcommand[ssh]" string => "/etc/init.d/sshd restart"; | |
"reloadcommand[ssh]" string => "/etc/init.d/sshd reload"; | |
"stopcommand[ssh]" string => "/etc/init.d/sshd stop"; | |
"pattern[ssh]" string => ".*sshd.*"; | |
debian|ubuntu:: | |
"startcommand[atd]" string => "/etc/init.d/atd start"; | |
"restartcommand[atd]" string => "/etc/init.d/atd restart"; | |
"reloadcommand[atd]" string => "/etc/init.d/atd reload"; | |
"stopcommand[atd]" string => "/etc/init.d/atd stop"; | |
"pattern[atd]" string => "atd.*"; | |
"startcommand[bluetoothd]" string => "/etc/init.d/bluetoothd start"; | |
"restartcommand[bluetoothd]" string => "/etc/init.d/bluetoothd restart"; | |
"reloadcommand[bluetoothd]" string => "/etc/init.d/bluetoothd reload"; | |
"stopcommand[bluetoothd]" string => "/etc/init.d/bluetoothd stop"; | |
"pattern[bluetoothd]" string => ".*bluetoothd.*"; | |
"startcommand[bootlogd]" string => "/etc/init.d/bootlogd start"; | |
"restartcommand[bootlogd]" string => "/etc/init.d/bootlogd restart"; | |
"reloadcommand[bootlogd]" string => "/etc/init.d/bootlogd reload"; | |
"stopcommand[bootlogd]" string => "/etc/init.d/bootlogd stop"; | |
"pattern[bootlogd]" string => ".*bootlogd.*"; | |
"startcommand[crond]" string => "/etc/init.d/cron start"; | |
"restartcommand[crond]" string => "/etc/init.d/cron restart"; | |
"reloadcommand[crond]" string => "/etc/init.d/cron reload"; | |
"stopcommand[crond]" string => "/etc/init.d/cron stop"; | |
"pattern[crond]" string => ".*cron.*"; | |
"startcommand[kerneloops]" string => "/etc/init.d/kerneloops start"; | |
"restartcommand[kerneloops]" string => "/etc/init.d/kerneloops restart"; | |
"reloadcommand[kerneloops]" string => "/etc/init.d/kerneloops reload"; | |
"stopcommand[kerneloops]" string => "/etc/init.d/kerneloops stop"; | |
"pattern[kerneloops]" string => ".*kerneloops.*"; | |
"startcommand[mysql]" string => "/etc/init.d/mysql start"; | |
"restartcommand[mysql]" string => "/etc/init.d/mysql restart"; | |
"reloadcommand[mysql]" string => "/etc/init.d/mysql reload"; | |
"stopcommand[mysql]" string => "/etc/init.d/mysql stop"; | |
"pattern[mysql]" string => ".*mysqld.*"; | |
"startcommand[NetworkManager]" string => "/etc/init.d/network-manager start"; | |
"restartcommand[NetworkManager]" string => "/etc/init.d/network-manager restart"; | |
"reloadcommand[NetworkManager]" string => "/etc/init.d/network-manager reload"; | |
"stopcommand[NetworkManager]" string => "/etc/init.d/network-manager stop"; | |
"pattern[NetworkManager]" string => ".*NetworkManager.*"; | |
"startcommand[ondemand]" string => "/etc/init.d/ondemand start"; | |
"restartcommand[ondemand]" string => "/etc/init.d/ondemand restart"; | |
"reloadcommand[ondemand]" string => "/etc/init.d/ondemand reload"; | |
"stopcommand[ondemand]" string => "/etc/init.d/ondemand stop"; | |
"pattern[ondemand]" string => ".*ondemand.*"; | |
"startcommand[plymouth]" string => "/etc/init.d/plymouthd start"; | |
"restartcommand[plymouth]" string => "/etc/init.d/plymouthd restart"; | |
"reloadcommand[plymouth]" string => "/etc/init.d/plymouthd reload"; | |
"stopcommand[plymouth]" string => "/etc/init.d/plymouthd stop"; | |
"pattern[plymouth]" string => ".*plymouthd.*"; | |
"startcommand[postgresql84]" string => "/etc/init.d/postgresql-8.4 start"; | |
"restartcommand[postgresql84]" string => "/etc/init.d/postgresql-8.4 restart"; | |
"reloadcommand[postgresql84]" string => "/etc/init.d/postgresql-8.4 reload"; | |
"stopcommand[postgresql84]" string => "/etc/init.d/postgresql-8.4 stop"; | |
"pattern[postgresql84]" string => ".*postgresql.*"; | |
"startcommand[postgresql91]" string => "/etc/init.d/postgresql-9.1 start"; | |
"restartcommand[postgresql91]" string => "/etc/init.d/postgresql-9.1 restart"; | |
"reloadcommand[postgresql91]" string => "/etc/init.d/postgresql-9.1 reload"; | |
"stopcommand[postgresql91]" string => "/etc/init.d/postgresql-9.1 stop"; | |
"pattern[postgresql91]" string => ".*postgresql.*"; | |
"startcommand[saned]" string => "/etc/init.d/saned start"; | |
"restartcommand[saned]" string => "/etc/init.d/saned restart"; | |
"reloadcommand[saned]" string => "/etc/init.d/saned reload"; | |
"stopcommand[saned]" string => "/etc/init.d/saned stop"; | |
"pattern[saned]" string => ".*saned.*"; | |
"startcommand[udev]" string => "/etc/init.d/udev start"; | |
"restartcommand[udev]" string => "/etc/init.d/udev restart"; | |
"reloadcommand[udev]" string => "/etc/init.d/udev reload"; | |
"stopcommand[udev]" string => "/etc/init.d/udev stop"; | |
"pattern[udev]" string => ".*udev.*"; | |
"startcommand[udevmonitor]" string => "/etc/init.d/udevmonitor start"; | |
"restartcommand[udevmonitor]" string => "/etc/init.d/udevmonitor restart"; | |
"reloadcommand[udevmonitor]" string => "/etc/init.d/udevmonitor reload"; | |
"stopcommand[udevmonitor]" string => "/etc/init.d/udevmonitor stop"; | |
"pattern[udevmonitor]" string => ".*udevadm.*monitor.*"; | |
"startcommand[www]" string => "/etc/init.d/apache2 start"; | |
"restartcommand[www]" string => "/etc/init.d/apache2 restart"; | |
"reloadcommand[www]" string => "/etc/init.d/apache2 reload"; | |
"stopcommand[www]" string => "/etc/init.d/apache2 stop"; | |
"pattern[www]" string => ".*apache2.*"; | |
"startcommand[ssh]" string => "/etc/init.d/ssh start"; | |
"restartcommand[ssh]" string => "/etc/init.d/ssh restart"; | |
"reloadcommand[ssh]" string => "/etc/init.d/ssh reload"; | |
"stopcommand[ssh]" string => "/etc/init.d/ssh stop"; | |
"pattern[ssh]" string => ".*sshd.*"; | |
# METHODS that implement these ............................................ | |
classes: | |
"start" expression => strcmp("start","$(state)"), | |
comment => "Check if to start a service"; | |
"restart" expression => strcmp("restart","$(state)"), | |
comment => "Check if to restart a service"; | |
"reload" expression => strcmp("reload","$(state)"), | |
comment => "Check if to reload a service"; | |
"stop" expression => strcmp("stop","$(state)"), | |
comment => "Check if to stop a service"; | |
# Do we want to include the packages here too? | |
processes: | |
start:: | |
"$(pattern[$(service)])" -> { "@(stakeholders[$(service)])" } | |
comment => "Verify that the service appears in the process table", | |
restart_class => "start_$(service)"; | |
stop:: | |
"$(pattern[$(service)])" -> { "@(stakeholders[$(service)])" } | |
comment => "Verify that the service does not appear in the process", | |
process_stop => "$(stopcommand[$(service)])", | |
signals => { "term", "kill"}; | |
commands: | |
"$(startcommand[$(service)])" -> { "@(stakeholders[$(service)])" } | |
comment => "Execute command to start the $(service) service", | |
ifvarclass => canonify("start_$(service)"); | |
restart:: | |
"$(restartcommand[$(service)])" -> { "@(stakeholders[$(service)])" } | |
comment => "Execute command to restart the $(service) service"; | |
reload:: | |
"$(reloadcommand[$(service)])" -> { "@(stakeholders[$(service)])" } | |
comment => "Execute command to reload the $(service) service"; | |
} | |
##------------------------------------------------------- | |
## database promises | |
##------------------------------------------------------- | |
body database_server local_mysql(username, password) | |
{ | |
db_server_owner => "$(username)"; | |
db_server_password => "$(password)"; | |
db_server_host => "localhost"; | |
db_server_type => "mysql"; | |
db_server_connection_db => "mysql"; | |
} | |
## | |
body database_server local_postgresql(username, password) | |
{ | |
db_server_owner => "$(username)"; | |
db_server_password => "$(password)"; | |
db_server_host => "localhost"; | |
db_server_type => "postgres"; | |
db_server_connection_db => "postgres"; | |
} | |
##------------------------------------------------------- | |
## guest_environment promises | |
##------------------------------------------------------- | |
body environment_resources kvm(name, arch, cpu_count, mem_kb, disk_file) | |
{ | |
env_spec => | |
"<domain type='kvm'> | |
<name>$(name)</name> | |
<memory>$(mem_kb)</memory> | |
<currentMemory>$(mem_kb)</currentMemory> | |
<vcpu>$(cpu_count)</vcpu> | |
<os> | |
<type arch='$(arch)'>hvm</type> | |
</os> | |
<features> | |
<acpi/> | |
<apic/> | |
<pae/> | |
</features> | |
<on_poweroff>destroy</on_poweroff> | |
<on_reboot>restart</on_reboot> | |
<on_crash>restart</on_crash> | |
<devices> | |
<emulator>/usr/bin/kvm</emulator> | |
<disk type='file' device='disk'> | |
<source file='$(disk_file)'/> | |
<target dev='vda' bus='virtio'/> | |
</disk> | |
<interface type='network'> | |
<source network='default'/> | |
</interface> | |
<input type='mouse' bus='ps2'/> | |
<graphics type='vnc' port='-1' autoport='yes'/> | |
</devices> | |
</domain>"; | |
} | |
#################################################### | |
## monitor bodyparts | |
#################################################### | |
body match_value scan_log(line) | |
{ | |
select_line_matching => "$(line)"; | |
track_growing_file => "true"; | |
} | |
## | |
body match_value scan_changing_file(line) | |
{ | |
select_line_matching => "$(line)"; | |
track_growing_file => "false"; | |
} | |
## | |
body match_value single_value(regex) | |
{ | |
select_line_matching => "$(regex)"; | |
extraction_regex => "($(regex))"; | |
} | |
## | |
body match_value line_match_value(line_match, extract_regex) | |
{ | |
select_line_matching => "$(line_match)"; | |
extraction_regex => "$(extract_regex)"; | |
} | |
## | |
body action sample_rate(x) | |
{ | |
ifelapsed => "$(x)"; | |
expireafter => "10"; | |
} | |
bundle common paths | |
# In addition to defining common paths, this bundle also defines context | |
# classes for paths that are defined (_stdlib_has_path_xxx) and paths that | |
# exist (_stdlib_path_exists_xxx) | |
{ | |
vars: | |
# | |
# Common full pathname of commands for OS | |
# | |
any:: | |
"path[getfacl]" string => "/usr/bin/getfacl"; | |
aix:: | |
"path[awk]" string => "/usr/bin/awk"; | |
"path[bc]" string => "/usr/bin/bc"; | |
"path[cat]" string => "/bin/cat"; | |
"path[cksum]" string => "/usr/bin/cksum"; | |
"path[crontabs]" string => "/var/spool/cron/crontabs"; | |
"path[cut]" string => "/usr/bin/cut"; | |
"path[dc]" string => "/usr/bin/dc"; | |
"path[df]" string => "/usr/bin/df"; | |
"path[diff]" string => "/usr/bin/diff"; | |
"path[dig]" string => "/usr/bin/dig"; | |
"path[echo]" string => "/usr/bin/echo"; | |
"path[egrep]" string => "/usr/bin/egrep"; | |
"path[find]" string => "/usr/bin/find"; | |
"path[grep]" string => "/usr/bin/grep"; | |
"path[ls]" string => "/usr/bin/ls"; | |
"path[netstat]" string => "/usr/bin/netstat"; | |
"path[ping]" string => "/usr/bin/ping"; | |
"path[perl]" string => "/usr/bin/perl"; | |
"path[printf]" string => "/usr/bin/printf"; | |
"path[sed]" string => "/usr/bin/sed"; | |
"path[sort]" string => "/usr/bin/sort"; | |
"path[tr]" string => "/usr/bin/tr"; | |
freebsd|netbsd:: | |
"path[awk]" string => "/usr/bin/awk"; | |
"path[bc]" string => "/usr/bin/bc"; | |
"path[cat]" string => "/bin/cat"; | |
"path[cksum]" string => "/usr/bin/cksum"; | |
"path[crontabs]" string => "/var/cron/tabs"; | |
"path[cut]" string => "/usr/bin/cut"; | |
"path[dc]" string => "/usr/bin/dc"; | |
"path[df]" string => "/bin/df"; | |
"path[diff]" string => "/usr/bin/diff"; | |
"path[dig]" string => "/usr/bin/dig"; | |
"path[echo]" string => "/bin/echo"; | |
"path[egrep]" string => "/usr/bin/egrep"; | |
"path[find]" string => "/usr/bin/find"; | |
"path[grep]" string => "/usr/bin/grep"; | |
"path[ls]" string => "/bin/ls"; | |
"path[netstat]" string => "/usr/bin/netstat"; | |
"path[ping]" string => "/usr/bin/ping"; | |
"path[perl]" string => "/usr/bin/perl"; | |
"path[printf]" string => "/usr/bin/printf"; | |
"path[sed]" string => "/usr/bin/sed"; | |
"path[sort]" string => "/usr/bin/sort"; | |
"path[tr]" string => "/usr/bin/tr"; | |
openbsd:: | |
"path[awk]" string => "/usr/bin/awk"; | |
"path[bc]" string => "/usr/bin/bc"; | |
"path[cat]" string => "/bin/cat"; | |
"path[cksum]" string => "/bin/cksum"; | |
"path[crontabs]" string => "/var/cron/tabs"; | |
"path[cut]" string => "/usr/bin/cut"; | |
"path[dc]" string => "/usr/bin/dc"; | |
"path[df]" string => "/bin/df"; | |
"path[diff]" string => "/usr/bin/diff"; | |
"path[dig]" string => "/usr/sbin/dig"; | |
"path[echo]" string => "/bin/echo"; | |
"path[egrep]" string => "/usr/bin/egrep"; | |
"path[find]" string => "/usr/bin/find"; | |
"path[grep]" string => "/usr/bin/grep"; | |
"path[ls]" string => "/bin/ls"; | |
"path[netstat]" string => "/usr/bin/netstat"; | |
"path[ping]" string => "/usr/bin/ping"; | |
"path[perl]" string => "/usr/bin/perl"; | |
"path[printf]" string => "/usr/bin/printf"; | |
"path[sed]" string => "/usr/bin/sed"; | |
"path[sort]" string => "/usr/bin/sort"; | |
"path[tr]" string => "/usr/bin/tr"; | |
solaris:: | |
"path[awk]" string => "/usr/bin/awk"; | |
"path[bc]" string => "/usr/bin/bc"; | |
"path[cat]" string => "/usr/bin/cat"; | |
"path[cksum]" string => "/usr/bin/cksum"; | |
"path[crontabs]" string => "/var/spool/cron/crontabs"; | |
"path[cut]" string => "/usr/bin/cut"; | |
"path[dc]" string => "/usr/bin/dc"; | |
"path[df]" string => "/usr/bin/df"; | |
"path[diff]" string => "/usr/bin/diff"; | |
"path[dig]" string => "/usr/sbin/dig"; | |
"path[echo]" string => "/usr/bin/echo"; | |
"path[egrep]" string => "/usr/bin/egrep"; | |
"path[find]" string => "/usr/bin/find"; | |
"path[grep]" string => "/usr/bin/grep"; | |
"path[ls]" string => "/usr/bin/ls"; | |
"path[netstat]" string => "/usr/bin/netstat"; | |
"path[ping]" string => "/usr/bin/ping"; | |
"path[perl]" string => "/usr/bin/perl"; | |
"path[printf]" string => "/usr/bin/printf"; | |
"path[sed]" string => "/usr/bin/sed"; | |
"path[sort]" string => "/usr/bin/sort"; | |
"path[tr]" string => "/usr/bin/tr"; | |
# | |
"path[svcs]" string => "/usr/bin/svcs"; | |
"path[svcadm]" string => "/usr/sbin/svcadm"; | |
redhat:: | |
"path[awk]" string => "/bin/awk"; | |
"path[bc]" string => "/usr/bin/bc"; | |
"path[cat]" string => "/bin/cat"; | |
"path[cksum]" string => "/usr/bin/cksum"; | |
"path[createrepo]" string => "/usr/bin/createrepo"; | |
"path[crontab]" string => "/usr/bin/crontab"; | |
"path[crontabs]" string => "/var/spool/cron"; | |
"path[cut]" string => "/bin/cut"; | |
"path[dc]" string => "/usr/bin/dc"; | |
"path[df]" string => "/bin/df"; | |
"path[diff]" string => "/usr/bin/diff"; | |
"path[dig]" string => "/usr/bin/dig"; | |
"path[domainname]" string => "/bin/domainname"; | |
"path[echo]" string => "/bin/echo"; | |
"path[egrep]" string => "/bin/egrep"; | |
"path[find]" string => "/usr/bin/find"; | |
"path[grep]" string => "/bin/grep"; | |
"path[hostname]" string => "/bin/hostname"; | |
"path[init]" string => "/sbin/init"; | |
"path[iptables]" string => "/sbin/iptables"; | |
"path[iptables_save]" string => "/sbin/iptables-save"; | |
"path[ls]" string => "/bin/ls"; | |
"path[netstat]" string => "/bin/netstat"; | |
"path[ping]" string => "/usr/bin/ping"; | |
"path[perl]" string => "/usr/bin/perl"; | |
"path[printf]" string => "/usr/bin/printf"; | |
"path[sed]" string => "/bin/sed"; | |
"path[sort]" string => "/bin/sort"; | |
"path[sysctl]" string => "/sbin/sysctl"; | |
"path[test]" string => "/usr/bin/test"; | |
"path[tr]" string => "/usr/bin/tr"; | |
# | |
"path[chkconfig]" string => "/sbin/chkconfig"; | |
"path[groupadd]" string => "/usr/sbin/groupadd"; | |
"path[groupdel]" string => "/usr/sbin/groupdel"; | |
"path[ifconfig]" string => "/sbin/ifconfig"; | |
"path[ip]" string => "/sbin/ip"; | |
"path[rpm]" string => "/bin/rpm"; | |
"path[service]" string => "/sbin/service"; | |
"path[svc]" string => "/sbin/service"; | |
"path[useradd]" string => "/usr/sbin/useradd"; | |
"path[userdel]" string => "/usr/sbin/userdel"; | |
"path[yum]" string => "/usr/bin/yum"; | |
debian:: | |
"path[awk]" string => "/usr/bin/awk"; | |
"path[bc]" string => "/usr/bin/bc"; | |
"path[cat]" string => "/bin/cat"; | |
"path[chkconfig]" string => "/sbin/chkconfig"; | |
"path[cksum]" string => "/usr/bin/cksum"; | |
"path[createrepo]" string => "/usr/bin/createrepo"; | |
"path[crontab]" string => "/usr/bin/crontab"; | |
"path[crontabs]" string => "/var/spool/cron/crontabs"; | |
"path[cut]" string => "/usr/bin/cut"; | |
"path[dc]" string => "/usr/bin/dc"; | |
"path[df]" string => "/bin/df"; | |
"path[diff]" string => "/usr/bin/diff"; | |
"path[dig]" string => "/usr/bin/dig"; | |
"path[dmidecode]" string => "/usr/sbin/dmidecode"; | |
"path[domainname]" string => "/bin/domainname"; | |
"path[echo]" string => "/bin/echo"; | |
"path[egrep]" string => "/bin/egrep"; | |
"path[find]" string => "/usr/bin/find"; | |
"path[grep]" string => "/bin/grep"; | |
"path[hostname]" string => "/bin/hostname"; | |
"path[ls]" string => "/bin/ls"; | |
"path[init]" string => "/sbin/init"; | |
"path[iptables]" string => "/sbin/iptables"; | |
"path[iptables_save]" string => "/sbin/iptables-save"; | |
"path[netstat]" string => "/bin/netstat"; | |
"path[ping]" string => "/bin/ping"; | |
"path[perl]" string => "/usr/bin/perl"; | |
"path[printf]" string => "/usr/bin/printf"; | |
"path[sed]" string => "/bin/sed"; | |
"path[sort]" string => "/usr/bin/sort"; | |
"path[sysctl]" string => "/sbin/sysctl"; | |
"path[test]" string => "/usr/bin/test"; | |
"path[tr]" string => "/usr/bin/tr"; | |
# | |
"path[apt_cache]" string => "/usr/bin/apt-cache"; | |
"path[apt_config]" string => "/usr/bin/apt-config"; | |
"path[apt_get]" string => "/usr/bin/apt-get"; | |
"path[apt_key]" string => "/usr/bin/apt-key"; | |
"path[aptitude]" string => "/usr/bin/aptitude"; | |
"path[dpkg]" string => "/usr/bin/dpkg"; | |
"path[groupadd]" string => "/usr/sbin/groupadd"; | |
"path[ifconfig]" string => "/sbin/ifconfig"; | |
"path[ip]" string => "/sbin/ip"; | |
"path[service]" string => "/usr/sbin/service"; | |
"path[svc]" string => "/usr/sbin/service"; | |
"path[update_alternatives]" string => "/usr/bin/update-alternatives"; | |
"path[update_rc_d]" string => "/usr/sbin/update-rc.d"; | |
"path[useradd]" string => "/usr/sbin/useradd"; | |
any:: | |
"all_paths" slist => getindices("path"); | |
"$(all_paths)" string => "$(path[$(all_paths)])"; | |
classes: | |
"_stdlib_has_path_$(all_paths)" | |
expression => isvariable("$(all_paths)"), | |
comment => "It's useful to know if a given path is defined"; | |
"_stdlib_path_exists_$(all_paths)" | |
expression => fileexists("$(path[$(all_paths)])"), | |
comment => "It's useful to know if $(all_paths) exists on the filesystem as defined"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
# | |
# Define what an agent has to do when it updates | |
# its promises | |
# | |
#simple copy method | |
body copy_from remote(server, path) | |
{ | |
servers => { | |
"${server}" | |
}; | |
encrypt => "true"; | |
trustkey => "true"; | |
source => "${path}"; | |
compare => "digest"; | |
preserve => "false"; #preserver permissions | |
verify => "true"; | |
purge => "true"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
#simple copy method, unencrypted | |
body copy_from remote_unsecured(server, path) | |
{ | |
servers => { | |
"${server}" | |
}; | |
encrypt => "false"; | |
trustkey => "true"; | |
source => "${path}"; | |
compare => "mtime"; | |
preserve => "true"; #preserver permissions | |
verify => "true"; | |
purge => "true"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
body copy_from copy_digest_without_perms(from) | |
{ | |
source => "${from}"; | |
copy_backup => "false"; | |
preserve => "false"; | |
compare => "digest"; | |
purge => "true"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
body copy_from remote_unsecured_without_perms(server, path) | |
{ | |
servers => { | |
"${server}" | |
}; | |
encrypt => "false"; | |
trustkey => "true"; | |
source => "${path}"; | |
compare => "digest"; | |
preserve => "false"; | |
verify => "true"; | |
purge => "true"; | |
community_edition:: | |
portnumber => "5309"; | |
} | |
bundle common server_info | |
{ | |
vars: | |
any:: | |
"policy_files" string => "/var/rudder/share/${g.uuid}"; #directory where to look for promises in the server for that client | |
policy_server:: | |
"cfserved" string => "%%POLICY_SERVER_HOSTNAME%%"; | |
!policy_server:: | |
"policy_server_file" | |
string => translatepath("${sys.workdir}/policy_server.dat"), | |
comment => "Path to file containing address to policy server"; | |
"cfserved" string => readfile("${policy_server_file}", 2048); | |
} | |
# The update is now split in two parts | |
# - the action part, only launched during failsafe | |
# it copies files, restarts deamons, defines persistent classes | |
# - the report part, not done during failsafe but during regular run | |
# note that if in verbose_mode, then the reporting will be done | |
# as well during failsafe | |
# | |
# Since the defined class are persistent, the classes are still | |
# available during the "normal" agent execution, for reporting | |
bundle agent update | |
{ | |
methods: | |
failsafe:: | |
"update" usebundle => update_action; | |
(!failsafe|verbose_mode):: | |
"report" usebundle => update_reports; | |
reports: | |
# We want to have always reports if something goes bad | |
rudder_promises_generated_error|no_update:: | |
"********************************************************************************* | |
* rudder-agent could not get an updated configuration from the policy server. * | |
* This can be caused by a network issue, an unavailable server, or if this * | |
* node was deleted from the Rudder root server. * | |
* Any existing configuration policy will continue to be applied without change. * | |
*********************************************************************************" | |
action => immediate; | |
} | |
bundle agent update_action | |
{ | |
vars: | |
"client_inputs" string => "${sys.workdir}/inputs"; #where to put the files on the client when downloaded | |
"file_to_check_update" string => "rudder_promises_generated"; | |
nova_edition:: | |
"server_inputs" string => "${server_info.policy_files}/rules/cfengine-nova"; #actual directory with promises | |
community_edition:: | |
"server_inputs" string => "${server_info.policy_files}/rules/cfengine-community"; #actual directory with promises | |
files: | |
any:: | |
"${g.rudder_ncf}/." | |
create => "true", | |
comment => "Make sure the ncf directory exists"; | |
root_server:: | |
"${g.rudder_ncf}/common" | |
copy_from => copy_digest_without_perms("${g.rudder_ncf_origin_common}"), | |
depth_search => recurse_ignore("inf", @{g.excludedreps}), | |
perms => u_mog("644", "root", "root"), | |
action => immediate, | |
classes => success("rudder_ncf_common_updated", "rudder_ncf_common_update_error", "rudder_ncf_common_updated_ok"), | |
comment => "Update the common Rudder ncf instance"; | |
"${g.rudder_ncf}/local" | |
copy_from => copy_digest_without_perms("${g.rudder_ncf_origin_local}"), | |
depth_search => recurse_ignore("inf", @{g.excludedreps}), | |
perms => u_mog("644", "root", "root"), | |
action => immediate, | |
classes => success("rudder_ncf_local_updated", "rudder_ncf_local_update_error", "rudder_ncf_local_updated_ok"), | |
comment => "Update the local Rudder ncf instance"; | |
!root_server:: | |
"${g.rudder_ncf}/common" | |
copy_from => remote_unsecured_without_perms("${server_info.cfserved}", "${g.rudder_ncf_origin_common}"), | |
depth_search => recurse_ignore("inf", @{g.excludedreps}), | |
perms => u_mog("644", "root", "root"), | |
action => immediate, | |
classes => success("rudder_ncf_common_updated", "rudder_ncf_common_update_error", "rudder_ncf_common_updated_ok"), | |
comment => "Update the common Rudder ncf instance"; | |
"${g.rudder_ncf}/local" | |
copy_from => remote_unsecured_without_perms("${server_info.cfserved}", "${g.rudder_ncf_origin_local}"), | |
depth_search => recurse_ignore("inf", @{g.excludedreps}), | |
perms => u_mog("644", "root", "root"), | |
action => immediate, | |
classes => success("rudder_ncf_local_updated", "rudder_ncf_local_update_error", "rudder_ncf_local_updated_ok"), | |
comment => "Update the local Rudder ncf instance"; | |
"${client_inputs}/${file_to_check_update}" | |
copy_from => remote("${server_info.cfserved}","${server_inputs}/${file_to_check_update}"), | |
action => immediate, | |
classes => success("rudder_promises_generated_repaired", "rudder_promises_generated_error", "rudder_promises_generated_ok"); | |
# The defined class are persistent, so if they are already set, promises has already been updated | |
# a short while ago | |
rudder_promises_generated_repaired.!root_server:: | |
"${client_inputs}" | |
copy_from => remote("${server_info.cfserved}","${server_inputs}"), | |
depth_search => recurse("inf"), | |
action => immediate, | |
classes => success("config", "no_update", "config_ok"); | |
root_server|(rudder_promises_generated_ok|(rudder_promises_generated_repaired.(config|config_ok)).!no_update.!rudder_promises_generated_error):: | |
# Every time we check update inputs successfully (already up to date or | |
# updated), touch a file to let other promises know we are doing ok | |
"${sys.workdir}/last_successful_inputs_update" | |
touch => "true"; | |
# Copy the tools only if the file rudder_tools_updated is not up to date | |
any:: | |
"${g.rudder_tools_updated}" | |
copy_from => remote_unsecured("${server_info.cfserved}", "${g.rudder_tools_updated_origin}"), | |
action => immediate, | |
classes => success("rudder_tools_updated_repaired", "rudder_tools_updated_error", "rudder_tools_updated_kept"), | |
comment => "Check if we need to update the tools"; | |
# We copy only if we have the class rudder_tools_updated_repaired | |
rudder_tools_updated_repaired:: | |
"${g.rudder_tools}" | |
copy_from => remote_unsecured("${server_info.cfserved}", "${g.rudder_tools_origin}"), | |
depth_search => recurse_ignore("inf", @{g.excludedreps}), | |
action => immediate, | |
classes => success("rudder_tools_updated", "rudder_tools_update_error", "rudder_tools_updated_ok"); | |
processes: | |
config.!windows:: | |
"cf-serverd" restart_class => "start_server"; | |
config.!windows:: | |
"cf-execd" restart_class => "start_exec"; | |
commands: | |
start_exec.!windows:: | |
"${sys.cf_execd}" | |
action => u_ifwin_bg, | |
classes => outcome("executor"); | |
start_exec.cygwin:: | |
"${sys.cf_execd}" | |
action => u_ifwin_bg, | |
classes => outcome("executor"); | |
start_server:: | |
"${sys.cf_serverd}" | |
action => u_ifwin_bg, | |
classes => outcome("server"); | |
######################################################### | |
reports: | |
server_ok:: | |
"@@Common@@log_repaired@@&TRACKINGKEY&@@Update@@None@@${g.execRun}##${g.uuid}@#Started the server (cf-serverd)"; | |
executor_ok:: | |
"@@Common@@log_repaired@@&TRACKINGKEY&@@Update@@None@@${g.execRun}##${g.uuid}@#Started the scheduler (cf-execd)"; | |
} | |
# This bundle is responsible for the reporting of what happened in the update | |
# It can work because the classes defined during the update are persistent, so | |
# the classes are available for the next 4 minutes | |
bundle agent update_reports | |
{ | |
reports: | |
server_ok:: | |
"@@Common@@log_repaired@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Started the server (cf-serverd)"; | |
executor_ok:: | |
"@@Common@@log_repaired@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Started the scheduler (cf-execd)"; | |
no_update:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Cannot update node's policy (CFEngine promises)"; | |
rudder_tools_update_error:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Cannot update Rudder tools"; | |
rudder_ncf_common_update_error:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Cannot update common Rudder ncf instance"; | |
rudder_ncf_local_update_error:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Cannot update local Rudder ncf instance"; | |
rudder_promises_generated_error:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Cannot update node's policy"; | |
(rudder_promises_generated_ok|(rudder_tools_updated_ok.rudder_ncf_common_updated_ok.rudder_ncf_local_updated_ok.config_ok)).!(rudder_promises_generated_repaired|rudder_promises_generated_error|rudder_tools_updated|rudder_tools_update_error|rudder_ncf_common_updated|rudder_ncf_common_update_error|rudder_ncf_local_updated|rudder_ncf_local_update_error|config|no_update):: | |
"@@Common@@result_success@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Rudder policy, tools and ncf instance are already up to date. No action required."; | |
rudder_tools_updated:: | |
"@@Common@@log_repaired@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Rudder tools updated"; | |
rudder_ncf_common_updated:: | |
"@@Common@@log_repaired@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Rudder ncf common instance updated"; | |
rudder_ncf_local_updated:: | |
"@@Common@@log_repaired@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Rudder ncf local instance updated"; | |
config:: | |
"@@Common@@log_repaired@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Node's policy (CFEngine promises) updated"; | |
rudder_promises_generated_repaired|config|rudder_tools_updated|rudder_ncf_common_updated|rudder_ncf_local_updated|server_ok|executor_ok:: | |
"@@Common@@result_repaired@@hasPolicyServer-root@@common-root@@00@@Update@@None@@${g.execRun}##${g.uuid}@#Policy or dependencies were updated or CFEngine service restarted"; | |
} | |
############################################ | |
body classes outcome(x) | |
{ | |
promise_repaired => {"${x}_ok"}; | |
} | |
############################################ | |
body action u_background | |
{ | |
background => "true"; | |
} | |
############################################ | |
body classes success(if, else, kept) | |
{ | |
promise_kept => { "${kept}" }; | |
promise_repaired => {"${if}"}; | |
repair_failed => { "${else}" }; | |
repair_denied => { "${else}" }; | |
repair_timeout => { "${else}" }; | |
# persist for 4 minutes so that it wont overlap with the next | |
# execution in 5 minutes | |
persist_time => "4"; | |
} | |
############################################ | |
body action u_ifwin_bg | |
{ | |
windows:: | |
background => "true"; | |
} | |
body service_method u_bootstart | |
{ | |
service_autostart_policy => "boot_time"; | |
} | |
body perms u_mog(mode,user,group) | |
{ | |
owners => { "${user}" }; | |
groups => { "${group}" }; | |
mode => "${mode}"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent internal_security | |
{ | |
vars: | |
!windows:: | |
"mode" string => "600"; | |
"user" string => "root"; | |
"group" string => "0"; | |
#windows:: | |
# "mode" string => "755"; | |
# "user" string => "Administrator"; | |
# "group" string => "Administrators"; | |
files: | |
!windows:: | |
"${g.rudder_var}/cfengine-community/inputs" | |
depth_search => recurse("inf"), | |
perms => mog("${mode}", "${user}", "${group}"), | |
classes => kept_if_else("security_sanitization_ok", "security_sanitization_repaired", "security_sanitization_failed"); | |
"${g.rudder_var}/cfengine-community/inputs" | |
perms => mog("${mode}", "${user}", "${group}"), | |
classes => kept_if_else("security_sanitization_ok", "security_sanitization_repaired", "security_sanitization_failed"); | |
"${g.rudder_var}/cfengine-community/ppkeys" | |
depth_search => recurse("inf"), | |
perms => mog("${mode}", "${user}", "${group}"), | |
classes => kept_if_else("security_sanitization_ok", "security_sanitization_repaired", "security_sanitization_failed"); | |
"${g.rudder_var}/cfengine-community/ppkeys" | |
perms => mog("${mode}", "${user}", "${group}"), | |
classes => kept_if_else("security_sanitization_ok", "security_sanitization_repaired", "security_sanitization_failed"); | |
reports: | |
security_sanitization_ok.!security_sanitization_repaired:: | |
"@@Common@@result_success@@hasPolicyServer-root@@common-root@@00@@Security parameters@@None@@${g.execRun}##${g.uuid}@#The internal environment security is acceptable"; | |
security_sanitization_repaired:: | |
"@@Common@@result_repaired@@hasPolicyServer-root@@common-root@@00@@Security parameters@@None@@${g.execRun}##${g.uuid}@#Some internal security parameters were adjusted"; | |
security_sanitization_failed:: | |
"@@Common@@result_error@@hasPolicyServer-root@@common-root@@00@@Security parameters@@None@@${g.execRun}##${g.uuid}@#The internal environment security is NOT acceptable!"; | |
windows:: | |
"@@Common@@result_success@@hasPolicyServer-root@@common-root@@00@@Security parameters@@None@@${g.execRun}##${g.uuid}@#No internal security parameters defined for Windows OSes yet"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
bundle agent process_matching | |
{ | |
vars: | |
# This deliberately excludes cf-execd which is handled separately below | |
"cf_components" slist => { "cf-key", | |
# "cf-monitord", Disabled | |
"cf-promises", | |
"cf-runagent", "cf-serverd" }; | |
windows:: | |
"stop_signal" string => "kill"; | |
!windows:: | |
"stop_signal" string => "term"; | |
classes: | |
"restart_cf" expression => "Hr05.Min00_05"; | |
files: | |
!windows.!android:: | |
# This is to cleanup /etc/crontab from pre-2.5 usage | |
# and initial promises before 2.7 | |
"${g.crontab}" | |
create => "true", | |
edit_defaults => noempty_backup, | |
edit_line => cron_cleanup; | |
# Temporary cron file added by rudder-agent postinst to prevent from UUID removal. | |
# When this promise will be generated, this cron will be useless then removed. | |
# (see http://www.rudder-project.org/redmine/issues/3925 and http://www.rudder-project.org/redmine/issues/3930). | |
"/etc/cron.d/rudder-agent-uuid" delete => tidy; | |
community_edition.!aix:: | |
"/etc/cron.d/rudder-agent" | |
create => "true", | |
perms => mog("644", "root", "root"), | |
edit_defaults => empty_backup, | |
edit_line => expand_template("${sys.workdir}/inputs/common/cron/rudder_agent_community_cron"); | |
aix:: | |
"/var/spool/cron/crontabs/root" | |
create => "true", | |
perms => mog("600", "root", "cron"), | |
edit_line => insert_lines("0,5,10,15,20,25,30,35,40,45,50,55 * * * * if [ -x /opt/rudder/bin/check-rudder-agent ]; then /opt/rudder/bin/check-rudder-agent; fi"), | |
classes => rudder_common_classes("rudder_aix_crontab_insertion"), | |
comment => "Insert an AIX-compatible user crontab to run /opt/rudder/bin/check-rudder-agent"; | |
processes: | |
windows:: | |
# Always stop cf-monitord | |
"${g.escaped_workdir}\/bin\/cf-monitord" signals => { "${stop_signal}" }; | |
!windows:: | |
# Always stop cf-monitord | |
"${sys.workdir}/bin/cf-monitord" signals => { "${stop_signal}" }; | |
restart_cf.!policy_server:: | |
"${cf_components}" signals => { "${stop_signal}" }; | |
# Policy servers have both Nova and Community, don't blindly kill the wrong processes | |
restart_cf.policy_server:: | |
"${sys.workdir}/bin/${cf_components}" signals => { "${stop_signal}" }; | |
restart_cf.!windows:: | |
"${sys.workdir}/bin/cf-execd" signals => { "${stop_signal}" }; | |
# Note: cron will get restarted automatically by init (respawn directive in inittab) | |
aix.rudder_aix_crontab_insertion:: | |
"^/usr/sbin/cron" signals => { "${stop_signal}" }; | |
commands: | |
restart_cf.!windows:: | |
"${sys.cf_serverd}"; | |
"${sys.cf_execd}"; | |
reports: | |
restart_cf:: | |
"Reloaded configuration of all Cfengine components"; | |
} | |
# This is to cleanup /etc/crontab from pre-2.5 usage | |
# and initial promises before 2.7 | |
bundle edit_line cron_cleanup | |
{ | |
# Remove old lines to replace them with new version | |
delete_lines: | |
"0,5,10,15,20,25,30,35,40,45,50,55 \* \* \* \* root if \[ \`ps -efww \| grep cf-execd \| grep \"/var/cfengine/bin/cf-execd\" \| grep -v grep \| wc -l\` -eq 0 \]; then /var/cfengine/bin/cf-execd; fi"; | |
"0,5,10,15,20,25,30,35,40,45,50,55 \* \* \* \* root if \[ \`ps -efww \| grep cf-execd \| grep \"/var/rudder/cfengine-community/bin/cf-execd\" \| grep -v grep \| wc -l\` -eq 0 \]; then /var/rudder/cfengine-community/bin/cf-execd; fi"; | |
"0,5,10,15,20,25,30,35,40,45,50,55 \* \* \* \* root if \[ ! -e /opt/rudder/etc/disable-agent -a \`ps -efww \| grep cf-execd \| grep \"/var/rudder/cfengine-community/bin/cf-execd\" \| grep -v grep \| wc -l\` -eq 0 \]; then /var/rudder/cfengine-community/bin/cf-execd; fi"; | |
"0,5,10,15,20,25,30,35,40,45,50,55 \* \* \* \* root if \[ ! -e /opt/rudder/etc/disable-agent -a \`ps -efww \| grep cf-execd \| grep \"/var/cfengine/bin/cf-execd\" \| grep -v grep \| wc -l\` -eq 0 \]; then /var/cfengine/bin/cf-execd; fi"; | |
"0,5,10,15,20,25,30,35,40,45,50,55 \* \* \* \* root if \[ ! -e /opt/rudder/etc/disable-agent -a \`ps -efww \| grep cf-execd \| grep \"/var/cfengine/bin/cf-execd\" \| grep -v grep \| wc -l\` -eq 0 \]; then /var/cfengine/bin/cf-agent -f failsafe.cf \&\& /var/cfengine/bin/cf-agent; fi"; | |
"0,5,10,15,20,25,30,35,40,45,50,55 \* \* \* \* root if \[ ! -e /opt/rudder/etc/disable-agent -a \`ps -efww \| grep cf-execd \| grep \"/var/rudder/cfengine-community/bin/cf-execd\" \| grep -v grep \| wc -l\` -eq 0 \]; then /var/rudder/cfengine-community/bin/cf-agent -f failsafe.cf \&\& /var/rudder/cfengine-community/bin/cf-agent; fi"; | |
"0,5,10,15,20,25,30,35,40,45,50,55 \* \* \* \* root if \[ ! -e /opt/rudder/etc/disable-agent -a \`ps -efww \| grep -E \"\(cf-execd\|cf-agent\)\" \| grep -E \"/var/cfengine/bin/\(cf-execd\|cf-agent\)\" \| grep -v grep \| wc -l\` -eq 0 ]; then /var/cfengine/bin/cf-agent -f failsafe.cf \&\& /var/cfengine/bin/cf-agent; fi"; | |
"0,5,10,15,20,25,30,35,40,45,50,55 \* \* \* \* root if \[ ! -e /opt/rudder/etc/disable-agent -a \`ps -efww \| grep -E \"\(cf-execd\|cf-agent\)\" \| grep -E \"/var/rudder/cfengine-community/bin/\(cf-execd\|cf-agent\)\" \| grep -v grep \| wc -l\` -eq 0 ]; then /var/rudder/cfengine-community/bin/cf-agent -f failsafe.cf \&\& /var/rudder/cfengine-community/bin/cf-agent; fi"; | |
# Remove entry with wrong escapements from /etc/crontab | |
"0,5,10,15,20,25,30,35,40,45,50,55 \* \* \* \* root if \[ ! -e /opt/rudder/etc/disable-agent -a \`ps -efww \| grep -E \"\(cf-execd\|cf-agent\)\" \| grep -E \"/var/rudder/cfengine-community/bin/\(cf-execd\|cf-agent\)\" \| grep -v grep \| wc -l\` -eq 0 ]; then /var/rudder/cfengine-community/bin/cf-agent -f failsafe.cf \\\&\\\& /var/rudder/cfengine-community/bin/cf-agent; fi"; | |
} | |
##################################################################################### | |
# Copyright 2011 Normation SAS | |
##################################################################################### | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, Version 3. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# | |
##################################################################################### | |
####################################################### | |
# | |
# Server specific configuration | |
# | |
####################################################### | |
bundle server access_rules | |
{ | |
# Access rules are only defined on a policy server. Standard nodes should not share any files. | |
access: | |
policy_server:: | |
"${def.dir_masterfiles}" | |
handle => "grant_access_policy", | |
comment => "Grant access to the policy updates", | |
maproot => { @{def.acl} }, | |
admit => { @{def.acl} }; | |
"${g.rudder_tools}" | |
maproot => { @{def.acl} }, | |
admit => { @{def.acl} }; | |
"${g.rudder_ncf_origin_common}" | |
maproot => { @{def.acl} }, | |
admit => { @{def.acl} }; | |
"${g.rudder_ncf_origin_local}" | |
maproot => { @{def.acl} }, | |
admit => { @{def.acl} }; | |
"/var/rudder/share/root/" | |
maproot => { host2ip("${server_info.cfserved}"), escape("${server_info.cfserved}") }, | |
admit => { host2ip("${server_info.cfserved}"), escape("${server_info.cfserved}") }; | |
# the policy server must have access to the cfengine folder | |
"${sys.workdir}" | |
maproot => { host2ip("${server_info.cfserved}"), escape("${server_info.cfserved}") }, | |
admit => { host2ip("${server_info.cfserved}"), escape("${server_info.cfserved}") }; | |
roles: | |
# Allow user root to set any class | |
".*" authorize => { "root" }; | |
} | |
bundle common def | |
{ | |
vars: | |
"policy_server_file" string => translatepath("${sys.workdir}/policy_server.dat"), | |
comment => "Path to file containing address to policy server"; | |
"policy_server" string => readfile("${policy_server_file}", 2048), | |
comment => "IP address or hostname to locate your policy host."; | |
"dir_masterfiles" string => translatepath("${sys.workdir}/masterfiles"); | |
# List here the IP masks that we grant access to on the server | |
policy_server:: | |
"acl" slist => { | |
'%%POLICY_SERVER_ALLOWED_NETWORKS%%' | |
}; | |
!policy_server:: | |
"acl" slist => { | |
"${def.policy_server}" | |
}; | |
} | |
body server control | |
{ | |
trustkeysfrom => { | |
"127.0.0.0/8" , "::1", | |
@{def.acl} , | |
host2ip("${server_info.cfserved}"), "${server_info.cfserved}" | |
}; #trustkey allows the exchange of keys | |
allowconnects => { | |
@{def.acl} , | |
host2ip("${server_info.cfserved}"), "${server_info.cfserved}" | |
}; | |
maxconnections => "1000"; | |
logallconnections => "true"; | |
cfruncommand => "${sys.workdir}/bin/cf-agent -f failsafe.cf && ${sys.workdir}/bin/cf-agent"; | |
allowusers => { "root" }; | |
skipverify => { "127.0.0.0/8" , "::1", @{def.acl} }; | |
community_edition:: | |
port => "5309"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment