diff --git a/tree/20_cfe_basics/log_rudder.cf b/tree/20_cfe_basics/log_rudder.cf index d044e8cbd..b1b1f8ab1 100644 --- a/tree/20_cfe_basics/log_rudder.cf +++ b/tree/20_cfe_basics/log_rudder.cf @@ -16,6 +16,7 @@ # ##################################################################################### + # @name Log for Rudder # @description Logging output for Rudder reports # @@ -35,7 +36,7 @@ bundle agent log_rudder(message, class_parameter, old_class_prefix, class_prefix "c_old_class_prefix" string => canonify("${old_class_prefix}"); # When ${class_prefix} itself contains ${class_prefix}, it uses the previous value when calling - # rudder_common_reports_generic. We reset it at the beginning of the bundle execution + # _rudder_common_reports_generic. We reset it at the beginning of the bundle execution # to be able to test if class_prefix is actually defined. "c_class_prefix" string => ""; "c_class_prefix" string => canonify("${class_prefix}"); @@ -64,11 +65,11 @@ bundle agent log_rudder(message, class_parameter, old_class_prefix, class_prefix methods: !use_class_prefix:: - "report" usebundle => rudder_common_reports_generic("${report_data.technique_name}", "${c_old_class_prefix}", "${report_data.identifier}", "${report_data.component_name}", "${component_key}", "${message}"), + "report" usebundle => _rudder_common_reports_generic("${report_data.technique_name}", "${c_old_class_prefix}", "${report_data.identifier}", "${report_data.component_name}", "${component_key}", "${message}"), classes => classes_generic("logger_rudder_${c_old_class_prefix}"); use_class_prefix:: - "report" usebundle => rudder_common_reports_generic("${report_data.technique_name}", "${c_class_prefix}", "${report_data.identifier}", "${report_data.component_name}", "${component_key}", "${message}"), + "report" usebundle => _rudder_common_reports_generic("${report_data.technique_name}", "${c_class_prefix}", "${report_data.identifier}", "${report_data.component_name}", "${component_key}", "${message}"), classes => classes_generic("logger_rudder_${c_class_prefix}"); reports: @@ -77,6 +78,143 @@ bundle agent log_rudder(message, class_parameter, old_class_prefix, class_prefix "${configuration.info}: Class prefix is too long - fallbacking to old_class_prefix ${old_class_prefix} for reporting"; } +# bundle backported from rudder (prefixed with _ to avoid conflicts) +# all this would be removed when we put this file back to rudder +# +# +# Create and send a report to the server +# This bundle takes 7 parameters : +# technique_name : the name of the technique, human readable +# class_prefix : the class_prefix (to ensure reports) +# 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 +# Warning, any modification here should also be ported to _rudder_common_report_hooks +bundle agent _rudder_common_report(technique_name, class_prefix, status, identifier, component_name, component_key, message) +{ + # We cannot allow for empty component_name + defaults: + "component_name" string => "None", if_match_regex => ""; + + classes: + changes_only:: + "send_reports" or => { + strcmp("${status}", "result_error") , + strcmp("${status}", "result_repaired") , + strcmp("${status}", "log_warn") , + strcmp("${status}", "log_repaired") , + strcmp("${status}", "audit_noncompliant") , + strcmp("${status}", "audit_error") , + }; + + methods: + # If we need to send a report, make sure we have sent the "StartRun" message first + send_reports.!start_run_message_sent:: + "Send start message" + usebundle => _startExecution("${identifier}"), + action => immediate_ignore_dry_run; + + reports: + !changes_only|send_reports:: + "@@${technique_name}@@${status}@@${identifier}@@${component_name}@@${component_key}@@${g.execRun}##${g.uuid}@#${message}" + comment => "Sending report from class_prefix ${class_prefix}"; +} + +# +# 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 beginning of an explanation message understandable by a human +# +# Warning, any modification here should also be ported to _rudder_common_generic_hooks +bundle agent _rudder_common_reports_generic(technique_name, class_prefix, identifier, component_name, component_key, message_prefix) +{ + methods: + + # We cannot allow for empty component_name + defaults: + "component_name" string => "None", if_match_regex => ""; + + classes: + "report" expression => "${report_data.should_report}"; + + methods: + + # This case should NEVER happen. If it ever happens, it is a bug in CFEngine or ncf that lead to changing something in dry-run mode. + # Hence, as we are facing a severe bug and we want to avoid changing more things, we define an abort class after displaying an error message . + "abort" usebundle => _abort("repaired_during_dryrun", "Repaired previous component while in dry-run mode, this is a bug. Aborting immediately."), + action => immediate_ignore_dry_run, + ifvarclass => "(dry_run|global_dry_run).${class_prefix}_repaired"; + + !report:: + "na" + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "log_info", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable"), + ifvarclass => "${class_prefix}_noop.!${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; + + "success" + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "log_info", "${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}", "${class_prefix}", "log_repaired", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was repaired"), + ifvarclass => "${class_prefix}_repaired.!${class_prefix}_error"; + + "error" + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "log_warn", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} could not be repaired"), + ifvarclass => "${class_prefix}_error"; + + + report.!(dry_run|global_dry_run):: + "na" + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "result_na", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable"), + ifvarclass => "${class_prefix}_noop.!${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; + + "success" + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "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}", "${class_prefix}", "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}", "${class_prefix}", "result_error", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} could not be repaired"), + ifvarclass => "${class_prefix}_error"; + + report.(dry_run|global_dry_run):: + "na" + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "audit_na", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable"), + ifvarclass => "${class_prefix}_noop.!${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; + + "success" + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "audit_compliant", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was correct"), + ifvarclass => "${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; + + "noncompliant" + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "audit_noncompliant", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not correct"), + ifvarclass => "${class_prefix}_error.!${class_prefix}_repaired"; + + "unexpected error" + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "audit_error", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was repaired but should have been run in dry-run mode"), + ifvarclass => "${class_prefix}_repaired"; +} + + ###################################################################### ##### Reporting for the pre/post hooks ##### These methods should not be used for normal generic method usage @@ -86,7 +224,7 @@ bundle agent log_rudder(message, class_parameter, old_class_prefix, class_prefix # # Automatically create reports based on existing classes starting by # class_prefix (as defined by the body classes rudder_common_classes) -# Difference with rudder_common_reports_generic : it remaps _repaired +# Difference with _rudder_common_reports_generic : it remaps _repaired # to _audit_compliant in audit mode # Takes 7 parameters # technique_name : the name of the technique, human readable @@ -94,7 +232,7 @@ bundle agent log_rudder(message, class_parameter, old_class_prefix, class_prefix # 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 +# message_prefix : The beginning of an explanation message understandable by a human # enforce_mode : Define the mode of reporting: enforce or audit # bundle agent _rudder_common_reports_generic_hooks(technique_name, class_prefix, identifier, component_name, component_key, message_prefix, enforce_mode) @@ -109,32 +247,32 @@ bundle agent _rudder_common_reports_generic_hooks(technique_name, class_prefix, methods: is_enforce:: "na" - usebundle => rudder_common_report("${technique_name}", "${class_prefix}", "result_na", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable"), + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "result_na", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable"), ifvarclass => "${class_prefix}_noop.!${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; "success" - usebundle => rudder_common_report("${technique_name}", "${class_prefix}", "result_success", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was correct"), + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "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}", "${class_prefix}", "result_repaired", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was repaired"), + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "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}", "${class_prefix}", "result_error", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} could not be repaired"), + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "result_error", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} could not be repaired"), ifvarclass => "${class_prefix}_error"; !is_enforce:: "na" - usebundle => rudder_common_report("${technique_name}", "${class_prefix}", "audit_na", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable"), + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "audit_na", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable"), ifvarclass => "${class_prefix}_noop.!${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; "success" - usebundle => rudder_common_report("${technique_name}", "${class_prefix}", "audit_compliant", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was correct"), + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "audit_compliant", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was correct"), ifvarclass => "(${class_prefix}_kept|${class_prefix}_repaired).!${class_prefix}_error"; "noncompliant" - usebundle => rudder_common_report("${technique_name}", "${class_prefix}", "audit_noncompliant", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not correct"), + usebundle => _rudder_common_report("${technique_name}", "${class_prefix}", "audit_noncompliant", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not correct"), ifvarclass => "${class_prefix}_error"; } @@ -205,7 +343,7 @@ bundle agent _rudder_common_report_hooks(technique_name, status, identifier, com # If we need to send a report, make sure we have sent the "StartRun" message first pass2.send_reports.!start_run_message_sent:: "Send start message" - usebundle => startExecution, + usebundle => _startExecution("${identifier}"), action => immediate_ignore_dry_run; reports: @@ -213,41 +351,6 @@ bundle agent _rudder_common_report_hooks(technique_name, status, identifier, com "@@${technique_name}@@${resulting_status}@@${identifier}@@${component_name}@@${component_key}@@${g.execRun}##${g.uuid}@#${message}"; } - -bundle agent startExecution -{ - vars: - second_pass:: # This is necessary to work around a CFEngine bug that causes this to be defined all the time - # Define a global class to show we have sent a "StartRun" report - "dummy_string" string => "dummy_content", - classes => always("start_run_message_sent"); - - classes: - # Dummy class to work around a CFEngine bug - "second_pass" expression => "any"; - - reports: - cfengine_3:: - # Send the report and define a persistant class to store the last "heartbeat" time - "@@Common@@control@@rudder@@run@@0@@start@@${g.rudder_node_config_id}@@${g.execRun}##${g.uuid}@#Start execution" - classes => rudder_always_classes_persist("heartbeat_sent", "${g.heartbeat_interval}"); -} - -bundle agent endExecution -{ - reports: - start_run_message_sent:: - "@@Common@@control@@rudder@@run@@0@@end@@${g.rudder_node_config_id}@@${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 was deleted from the Rudder root server. * -* Any existing configuration policy will continue to be applied without change. * -*********************************************************************************"; -} - # # Define the current Technique we are doing report on # Must be called before the reporting @@ -292,9 +395,19 @@ bundle agent enable_reporting { "report_data.should_report" string => "true"; } + + + +##################################################################### + + + + + + # # Automatically defines classes bases on a given prefix -# The classes are defined based on the romises outcome +# The classes are defined based on the promises outcome # body classes rudder_common_classes(prefix) { @@ -336,6 +449,12 @@ body classes rudder_always_classes_persist(always, persist) persist_time => "${persist}"; } +# DEPRECATED - for compatibility +body classes _rudder_always_classes_persist(always, persist) +{ + inherit_from => rudder_always_classes_persist("${always}", "${persist}") +} + ################################################ # Reporting bundles ################################################ @@ -365,13 +484,6 @@ bundle agent rudder_common_report(technique_name, status, identifier, component_ "report" usebundle => rudder_common_report_index("${technique_name}", "${status}", "${identifier}", "${component_name}", "${component_key}", "${message}", ""); } -# DEPRECATED - for compatibility -bundle agent _rudder_common_report(technique_name, status, identifier, component_name, component_key, message) -{ - methods: - "report" usebundle => rudder_common_report_index("${technique_name}", "${status}", "${identifier}", "${component_name}", "${component_key}", "${message}", ""); -} - # # Create and send a report to the server # This bundle takes 7 parameters : @@ -393,7 +505,6 @@ bundle agent _rudder_common_report(technique_name, status, identifier, component # index : the current index, that will distinguish two identical reports and ensure they are both sent bundle agent rudder_common_report_index(technique_name, status, identifier, component_name, component_key, message, index) { - vars: !(dry_run|global_dry_run):: "new_status" string => "${status}"; @@ -405,11 +516,8 @@ bundle agent rudder_common_report_index(technique_name, status, identifier, comp strcmp("${status}", "result_repaired"), "audit_error", strcmp("${status}", "result_error"), "audit_noncompliant", "${status}"); - # We cannot allow for empty component_name - defaults: - "component_name" string => "None", if_match_regex => ""; - classes: + "pass2" expression => "pass1"; "pass1" expression => "any"; @@ -448,6 +556,7 @@ bundle agent rudder_common_report_index(technique_name, status, identifier, comp comment => "Reporting for ${technique_name} message ${message} for index ${index}"; } + # # Automatically create reports based on existing classes starting by # class_prefix (as defined by the body classes rudder_common_classes) @@ -466,14 +575,6 @@ bundle agent rudder_common_reports_generic(technique_name, class_prefix, identif usebundle => rudder_common_reports_generic_index("${technique_name}", "${class_prefix}", "${identifier}", "${component_name}", "${component_key}", "${message_prefix}", ""); } -# DEPRECATED - for compatibility -bundle agent _rudder_common_reports_generic(technique_name, class_prefix, identifier, component_name, component_key, message_prefix) -{ - methods: - "report" - usebundle => rudder_common_reports_generic_index("${technique_name}", "${class_prefix}", "${identifier}", "${component_name}", "${component_key}", "${message_prefix}", ""); -} - # # Automatically create reports based on existing classes starting by # class_prefix (as defined by the body classes rudder_common_classes) @@ -488,12 +589,6 @@ bundle agent _rudder_common_reports_generic(technique_name, class_prefix, identi # bundle agent rudder_common_reports_generic_index(technique_name, class_prefix, identifier, component_name, component_key, message_prefix, index) { - # We cannot allow for empty component_name - defaults: - "component_name" string => "None", if_match_regex => ""; - - classes: - "report" expression => "${report_data.should_report}"; methods: # This case should NEVER happen. If it ever happens, it is a bug in CFEngine or ncf that lead to changing something in dry-run mode. @@ -502,25 +597,7 @@ bundle agent rudder_common_reports_generic_index(technique_name, class_prefix, i action => immediate, ifvarclass => "(dry_run|global_dry_run).${class_prefix}_repaired"; - !report:: - "na" - usebundle => rudder_common_report_index("${technique_name}", "${class_prefix}", "log_info", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable", "${index}"), - ifvarclass => "${class_prefix}_noop.!${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; - - "success" - usebundle => rudder_common_report_index("${technique_name}", "${class_prefix}", "log_info", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was correct", "${index}"), - ifvarclass => "${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; - - "repaired" - usebundle => rudder_common_report_index("${technique_name}", "${class_prefix}", "log_repaired", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was repaired", "${index}"), - ifvarclass => "${class_prefix}_repaired.!${class_prefix}_error"; - - "error" - usebundle => rudder_common_report_index("${technique_name}", "${class_prefix}", "log_warn", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} could not be repaired", "${index}"), - ifvarclass => "${class_prefix}_error"; - - - report.!(dry_run|global_dry_run):: + !(dry_run|global_dry_run):: "na" usebundle => rudder_common_report_index("${technique_name}", "result_na", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable", "${index}"), ifvarclass => "${class_prefix}_noop.!${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; @@ -537,7 +614,7 @@ bundle agent rudder_common_reports_generic_index(technique_name, class_prefix, i usebundle => rudder_common_report_index("${technique_name}", "result_error", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} could not be repaired", "${index}"), ifvarclass => "${class_prefix}_error"; - report.(dry_run|global_dry_run):: + dry_run|global_dry_run:: "na" usebundle => rudder_common_report_index("${technique_name}", "audit_na", "${identifier}", "${component_name}", "${component_key}", "${message_prefix} was not applicable", "${index}"), ifvarclass => "${class_prefix}_noop.!${class_prefix}_kept.!${class_prefix}_repaired.!${class_prefix}_error"; @@ -556,3 +633,43 @@ bundle agent rudder_common_reports_generic_index(technique_name, class_prefix, i } +bundle agent startExecution +{ + vars: + second_pass:: # This is necessary to work around a CFEngine bug that causes this to be defined all the time + # Define a global class to show we have sent a "StartRun" report + "dummy_string" string => "dummy_content", + classes => always("start_run_message_sent"); + + classes: + # Dummy class to work around a CFEngine bug + "second_pass" expression => "any"; + + reports: + cfengine_3:: + # Send the report and define a persistent class to store the last "heartbeat" time + "@@Common@@control@@rudder@@run@@0@@start@@${g.rudder_node_config_id}@@${g.execRun}##${g.uuid}@#Start execution" + classes => rudder_always_classes_persist("heartbeat_sent", "${g.heartbeat_interval}"); +} + +# DEPRECATED - for compatibility +bundle agent _startExecution(identifier) +{ + methods: + "any" usebundle => startExecution; +} + +bundle agent endExecution +{ + reports: + start_run_message_sent:: + "@@Common@@control@@rudder@@run@@0@@end@@${g.rudder_node_config_id}@@${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 was deleted from the Rudder root server. * +* Any existing configuration policy will continue to be applied without change. * +*********************************************************************************"; +} \ No newline at end of file