############################################################################### # # update.cf - Executed prior to promises.cf through cf-execd # ############################################################################### body common control { version => "1-UPDATE"; # normal ordering says vars run before classes in the same bundle, so # force class definition before the update() bundle is run bundlesequence => { "update_classes", "update" }; } ############################################################################# body agent control { ifelapsed => "1"; skipidentify => "false"; } ############################################################################# bundle common update_classes { classes: any:: "has_cfengine_environment_file" expression => fileexists("$(sys.workdir)/cfengine_environment"), comment => "Define has_cfengine_environment_file if $(sys.workdir)/cfengine_environment exists"; "has_policy_servers_dat_file" comment => "Define has_policy_servers_dat_file if $(sys.workdir)/policy_servers.dat exists", expression => fileexists("$(sys.workdir)/policy_servers.dat"); "has_policy_servers_dat_file" comment => "Define has_policy_servers_dat_file if $(sys.workdir)/policy_servers.dat exists", expression => fileexists("$(sys.workdir)/policy_servers.dat"); } bundle agent update { vars: any:: "seed" string => strftime("gmtime", "%Y%m%d%H%M", "$(sys.systime)"); redhat:: "logger" string => "/usr/bin/logger"; SLES:: "logger" string => "/bin/logger"; !has_cfengine_environment_file:: "cfengine_environment" string => "deploy/aitcfe/branch/prod", comment => "If has_cfengine_environment_file is not set, default to prod"; has_cfengine_environment_file:: "cfengine_environment" string => readfile("$(sys.workdir)/cfengine_environment", 128), comment => "If has_cfengine_environment_file IS set, set cfengine_environment to the contents of that file, up to the first 128 bytes"; !has_policy_servers_dat_file:: "policyhosts_preshuffle" comment => "Define policyhosts to the default value if has_policy_servers_dat_file is not defined", slist => { "smith.ait.psu.edu", "wesson.offsite.psu.edu" }; has_policy_servers_dat_file:: "policyhosts_preshuffle" comment => "Define policyhosts according to the contents of $(sys.workdir)/policy_servers.dat", slist => readstringlist("$(sys.workdir)/policy_servers.dat", "#.*", "[\n]", 10, 512); any:: "inputs_dir" string => translatepath("$(sys.workdir)/inputs"), comment => "Directory containing Cfengine policies", handle => "update_vars_inputs_dir"; "bin_dir" string => translatepath("$(sys.workdir)/bin"), comment => "Directory containing Cfengine binaries", handle => "update_vars_inputs_bin"; "modules_dir" string => translatepath("$(sys.workdir)/modules"), comment => "Directory containing CFEngine modules", handle => "update_vars_modules_dir"; "ppkeys_dir" string => translatepath("$(sys.workdir)/ppkeys"), comment => "Path to public key file", handle => "update_vars_ppkeys_dir"; "ppkeys_file" string => translatepath("$(ppkeys_dir)/localhost.pub"), comment => "Path to public key file", handle => "update_vars_ppkeys_file"; "file_check" string => translatepath("$(inputs_dir)/promises.cf"), comment => "Path to a policy file", handle => "update_vars_file_check"; "master_location" string => "/var/cfengine/masterfiles", comment => "The master cfengine policy directory on the policy host", handle => "update_vars_master_location"; # shuffle policyhosts "policyhosts" comment => "Shuffled copy of policyhosts_preshuffle. This is what copy_from attributes should reference.", slist => shuffle("policyhosts_preshuffle", "$(sys.fqhost).$(seed)"); "policyhosts_string" comment => "Collapsed copy of policyhosts", string => join(", ", "policyhosts"); files: any:: "$(sys.workdir)" comment => "Ensure permissions on $(inputs_dir)", perms => m_u_g("0755", "root", "root"), file_select => dir, action => fix_and_log; "$(bin_dir)" comment => "Ensure permissions on $(bin_dir)", perms => m_u_g("0755", "root", "root"), file_select => dir, action => fix_and_log; "$(ppkeys_dir)" comment => "Ensure permissions on $(ppkeys_dir)", perms => m_u_g("0700", "root", "root"), file_select => dir, action => fix_and_log; "$(inputs_dir)/controls" comment => "Watch for changes to $(this.promiser), and define restart_cfengine if the contents of those files change.", changes => detect_content, depth_search => recurse("2"), action => fix_and_log, classes => if_repaired("restart_cfengine"); "$(inputs_dir)" comment => "Remotely copy $(policyhosts):$(master_location)/$(cfengine_environment)/inputs to $(inputs_dir)", perms => m_u_g("0440", "root", "root"), copy_from => remote_copy("$(master_location)/$(cfengine_environment)/inputs", "@(policyhosts)"), depth_search => recurse("10"), action => fix_and_log; commands: cfengine.linux:: "$(logger) -i -t cf-agent 'CFEngine file=update.cf version=$(sys.cf_version) env=$(cfengine_environment) policyhosts=$(policyhosts_string)'" contain => in_shell; redhat.restart_cfengine:: "/sbin/service cfengine3 restart >/dev/null" comment => "Restart cfengine because restart_cfengine was defined", contain => in_shell, action => fix_and_log; reports: verbose:: "policyhosts = @(policyhosts)"; "Shuffled policyhosts = $(policyhosts_string)"; "cfengine_environment = $(cfengine_environment)"; "cfengine_private_environment = $(cfengine_private_environment)"; } ## ## select promise bodies from COPBL, and some custom ones ## body perms m_u_g(m,u,g) { mode => "$(m)"; owners => { "$(u)" }; groups => { "$(g)" }; } body action fix_and_log { ifelapsed => "1"; action_policy => "fix"; log_level => "inform"; } body copy_from remote_copy(sourcedir, sourceservers) { source => "$(sourcedir)"; servers => { "smith.ait.psu.edu", "wesson.offsite.psu.edu" }; copy_backup => "false"; purge => "true"; trustkey => "false"; compare => "digest"; encrypt => "false"; verify => "true"; } body depth_search recurse(d) { depth => "$(d)"; xdev => "true"; } body depth_search avoid_inputs_recurse(d) { depth => "$(d)"; exclude_dirs => {"/var/cfengine/inputs", "/var/cfengine/state" }; } body file_select plain { file_types => { "plain" }; file_result => "file_types"; } body file_select dir { file_types => { "dir" }; file_result => "file_types"; } body classes if_repaired(x) { promise_repaired => { "$(x)" }; } body contain in_shell { useshell => "true"; exec_timeout => "30"; } body changes detect_content { hash => "md5"; report_changes => "content"; update_hashes => "yes"; }