Project

General

Profile

« Previous | Next » 

Revision b5c19bee

Added by Félix DALLIDET over 6 years ago

Fixes #11142: filetemplate technique posthook

View differences:

techniques/fileDistribution/fileTemplate/1.0/fileTemplate.st
#Post hook command
&FILE_TEMPLATE_TEMPLATE_POST_HOOK_COMMAND: {command |"posthook[&i&]" string => "&command&";}&
#Post hook persistence
&FILE_TEMPLATE_PERSISTENT_POST_HOOK: {persistence | "persist[&i&]" string => "&persistence&";}&
#Index
"index" slist => getindices("dst");
#Name of the template, from its location
"name[${index}]" string => lastnode("${src[${index}]}", "/");
#canonified names for reporting
#Canonified names for reporting
"src_canon[${index}]" string => canonify("${relative_src}/${src[${index}]}");
"dst_canon[${index}]" string => canonify("${dst[${index}]}");
"temp_canon[${index}]" string => canonify("${temp}/${name[${index}]}");
"temp_dir_canon" string => canonify("${temp}");
"posthook_canon[${index}]" string => canonify("${posthook[${index}]}");
#Cancel persistent classes
"cancel" string => "cancel persistence",
classes => cancel_all_classes("posthook_rerun_${index}"),
ifvarclass => "command_execution_${posthook_canon[${index}]}_ok";
classes:
"pass3" expression => "pass2";
"pass2" expression => "pass1";
......
"posthook_specified_${index}" not => strcmp("${posthook[${index}]}", "");
"file_modified_${index}" expression =>"permissions_${dst_canon[${index}]}_repaired|file_from_template_${dst_canon[${index}]}_repaired";
"posthook_launch_${index}" expression =>"posthook_specified_${index}.file_modified_${index}";
"posthook_not_launch_${index}" expression =>"posthook_specified_${index}.!(file_modified_${index})";
"posthook_persistent_${index}" expression => strcmp("${persist[${index}]}", "true");
#Check if the posthook is persistent and in error, set up a class for 10000 minutes => about 1 week
"posthook_rerun_${index}" expression => "posthook_persistent_${index}.command_execution_${posthook_canon[${index}]}_failed",
scope => "namespace",
persistence => "10000";
methods:
#Ensure the templates are in a safe place
......
usebundle => command_execution(
"${posthook[${index}]}"
),
ifvarclass => "posthook_launch_${index}";
ifvarclass => "posthook_launch_${index}|posthook_rerun_${index}";
################################################################################
# REPORTING #
......
#Case with execution
"any" usebundle => rudder_common_reports_generic("fileTemplate", "command_execution_${posthook_canon[${index}]}", "${trackingkey[${index}]}", "Posthook", "${dst[${index}]}", "The command ${posthook[${index}]} from postHook execution "),
ifvarclass => "posthook_launch_${index}";
ifvarclass => "command_execution_${posthook_canon[${index}]}_reached";
#Case without execution
"report_${index}" usebundle => rudder_common_report("fileTemplate", "result_na", "${trackingkey[${index}]}", "Posthook", "${dst[${index}]}", "No post-modification needed to run"),
ifvarclass => "!file_modified_${index}.posthook_specified_${index}";
ifvarclass => "!file_modified_${index}.posthook_specified_${index}.!command_execution_${posthook_canon[${index}]}_reached";
#Case where no posthook set
......
"report_hook_${index}" usebundle => rudder_common_report("fileTemplate", "result_na", "${trackingkey[${index}]}", "Posthook", "${dst[${index}]}", "No post-modification set to run"),
ifvarclass => "!posthook_specified_${index}";
}
techniques/fileDistribution/fileTemplate/1.0/metadata.xml
</CONSTRAINT>
</INPUT>
<SELECT1>
<NAME>FILE_TEMPLATE_PERSISTENT_POST_HOOK</NAME>
<DESCRIPTION>Retry hook on error</DESCRIPTION>
<ITEM>
<VALUE>true</VALUE>
<LABEL>Yes</LABEL>
</ITEM>
<ITEM>
<VALUE>false</VALUE>
<LABEL>False</LABEL>
</ITEM>
<CONSTRAINT>
<DEFAULT>true</DEFAULT>
<MAYBEEMPTY>false</MAYBEEMPTY>
</CONSTRAINT>
</SELECT1>
<SECTION name="Expand template" multivalued="false" component="true" componentKey="FILE_TEMPLATE_AGENT_DESTINATION_PATH">
</SECTION>
......
</SECTION>
</SECTIONS>
</TECHNIQUE>
techniques/fileDistribution/fileTemplate/1.0/tests/loadVars.json
{
"displayName": "Variable (string)",
"enabled": true,
"longDescription": "",
"parameters": {
"section": {
"name": "sections",
"sections": [
{
"section": {
"name": "Variable definition",
"vars": [
{
"var": {
"name": "GENERIC_VARIABLE_CONTENT",
"value": "Alice"
}
},
{
"var": {
"name": "GENERIC_VARIABLE_NAME",
"value": "nom1"
}
}
]
}
},
{
"section": {
"name": "Variable definition",
"vars": [
{
"var": {
"name": "GENERIC_VARIABLE_CONTENT",
"value": "1 chemin de la rue"
}
},
{
"var": {
"name": "GENERIC_VARIABLE_NAME",
"value": "adresse1"
}
}
]
}
},
{
"section": {
"name": "Variable definition",
"vars": [
{
"var": {
"name": "GENERIC_VARIABLE_CONTENT",
"value": "Bob"
}
},
{
"var": {
"name": "GENERIC_VARIABLE_NAME",
"value": "nom2"
}
}
]
}
}
]
}
},
"shortDescription": "",
"techniqueName": "genericVariableDefinition",
"techniqueVersion": "2.0"
}
techniques/fileDistribution/fileTemplate/1.0/tests/template1
{{{vars.generic_variable_definition.nom1}}} habite {{{vars.generic_variable_definition.adresse1}}}
techniques/fileDistribution/fileTemplate/1.0/tests/test_error_fileTemplate/test_error_fileTemplate.cf
#!/usr/local/bin/ncf -f
bundle agent init {
vars:
"gen_files" slist => {"test1.conf", "test2.conf", "posthooktest", "persistentPosthooktest"};
"src_files" slist => {"template1", "_tmp_test2_conf.tpl"};
"other_files" slist => {"/tmp/toRepairPosthook"};
methods:
"any" usebundle => file_remove("/tmp/${gen_files}");
"any" usebundle => file_remove("/var/rudder/templates/${src_files}");
"any" usebundle => file_remove("${other_files}");
}
techniques/fileDistribution/fileTemplate/1.0/tests/test_error_fileTemplate/test_error_fileTemplate.json
{
"displayName": "File content (from remote template) (1,1) (3,1)",
"enabled": true,
"longDescription": "",
"parameters": {
"section": {
"name": "sections",
"sections": [
{
"section": {
"name": "Apply template",
"sections": [
{
"section": {
"name": "Load Template from a file or text input",
"sections": [
{
"section": {
"name": "Expand template"
}
},
{
"section": {
"name": "Posthook"
}
},
{
"section": {
"name": "Put permissions"
}
},
{
"section": {
"name": "Templates directory permissions"
}
},
{
"section": {
"name": "Templates location"
}
}
],
"vars": [
{
"var": {
"name": "FILE_TEMPLATE_AGENT_DESTINATION_PATH",
"value": "/tmp/test3.conf"
}
},
{
"var": {
"name": "FILE_TEMPLATE_GROUP_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERMISSIONS",
"value": "700"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERSISTENT_POST_HOOK",
"value": "false"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_OR_NOT",
"value": "File"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_TEMPLATE",
"value": ""
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE",
"value": "notAFile"
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_POST_HOOK_COMMAND",
"value": ""
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_TYPE",
"value": "mustache"
}
}
]
}
}
]
}
}
]
}
},
"shortDescription": "",
"techniqueName": "fileTemplate",
"techniqueVersion": "1.0"
}
techniques/fileDistribution/fileTemplate/1.0/tests/test_error_fileTemplate/test_error_fileTemplate.metadata
[{
"inits": ["test_error_fileTemplate.cf"],
"directives": ["test_error_fileTemplate.json", "loadVars.json"],
"checks": ["test_error_fileTemplate.rb"],
"sharedFiles":["template1"],
"compliance": 66.67
}]
techniques/fileDistribution/fileTemplate/1.0/tests/test_error_fileTemplate/test_error_fileTemplate.rb
require "spec_helper"
# Test with an inexistent template file, should failed
describe file("/var/rudder/tmp/templates") do
it { should be_directory }
it { should be_mode 750 }
it { should be_owned_by "root" }
end
describe file("/tmp/test3.conf") do
it { should_not exist }
end
describe command("rudder agent run -r") do
its(:stdout) { should match /^R: @@fileTemplate@@result_error@@.*?@@.*?@@.*?@@Load Template from a file or text input@@\/tmp\/test3.conf@@.*?The copy of the file.*?from the policy server to .*? could not be repaired$/m}
end
techniques/fileDistribution/fileTemplate/1.0/tests/test_fileTemplate/test_fileTemplate.json
{
"displayName": "File content (from remote template) (1,1) (3,1)",
"enabled": true,
"longDescription": "",
"parameters": {
"section": {
"name": "sections",
"sections": [
{
"section": {
"name": "Apply template",
"sections": [
{
"section": {
"name": "Load Template from a file or text input",
"sections": [
{
"section": {
"name": "Expand template"
}
},
{
"section": {
"name": "Posthook"
}
},
{
"section": {
"name": "Put permissions"
}
},
{
"section": {
"name": "Templates directory permissions"
}
},
{
"section": {
"name": "Templates location"
}
}
],
"vars": [
{
"var": {
"name": "FILE_TEMPLATE_AGENT_DESTINATION_PATH",
"value": "/tmp/test2.conf"
}
},
{
"var": {
"name": "FILE_TEMPLATE_GROUP_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERMISSIONS",
"value": "770"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERSISTENT_POST_HOOK",
"value": "false"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_OR_NOT",
"value": "Raw"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_TEMPLATE",
"value": "{{{vars.generic_variable_definition.nom1}}} et {{{vars.generic_variable_definition.nom2}}} habitent {{{vars.generic_variable_definition.adresse1}}}"
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE",
"value": ""
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_POST_HOOK_COMMAND",
"value": ""
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_TYPE",
"value": "mustache"
}
}
]
}
}
]
}
},
{
"section": {
"name": "Apply template",
"sections": [
{
"section": {
"name": "Load Template from a file or text input",
"sections": [
{
"section": {
"name": "Expand template"
}
},
{
"section": {
"name": "Posthook"
}
},
{
"section": {
"name": "Put permissions"
}
},
{
"section": {
"name": "Templates directory permissions"
}
},
{
"section": {
"name": "Templates location"
}
}
],
"vars": [
{
"var": {
"name": "FILE_TEMPLATE_AGENT_DESTINATION_PATH",
"value": "/tmp/test1.conf"
}
},
{
"var": {
"name": "FILE_TEMPLATE_GROUP_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERMISSIONS",
"value": "700"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERSISTENT_POST_HOOK",
"value": "false"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_OR_NOT",
"value": "File"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_TEMPLATE",
"value": ""
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE",
"value": "template1"
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_POST_HOOK_COMMAND",
"value": ""
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_TYPE",
"value": "mustache"
}
}
]
}
}
]
}
}
]
}
},
"shortDescription": "",
"techniqueName": "fileTemplate",
"techniqueVersion": "1.0"
}
techniques/fileDistribution/fileTemplate/1.0/tests/test_fileTemplate/test_fileTemplate.metadata
[{
"inits": [],
"directives": ["test_fileTemplate.json", "loadVars.json"],
"checks": ["test_fileTemplate.rb"],
"sharedFiles":["template1"],
"compliance": 100
}]
techniques/fileDistribution/fileTemplate/1.0/tests/test_fileTemplate/test_fileTemplate.rb
require "spec_helper"
describe file("/var/rudder/tmp/templates") do
it { should be_directory }
it { should be_mode 750 }
it { should be_owned_by "root" }
end
describe file("/var/rudder/tmp/templates/template1") do
it {should be_file}
its(:content) { should match /{{{vars.generic_variable_definition.nom1}}} habite {{{vars.generic_variable_definition.adresse1}}}/ }
end
describe file("/var/rudder/tmp/templates/_tmp_test2_conf.tpl") do
it {should be_file}
its(:content) { should match /{{{vars.generic_variable_definition.nom1}}} et {{{vars.generic_variable_definition.nom2}}} habitent {{{vars.generic_variable_definition.adresse1}}}/ }
end
describe file("/tmp/test1.conf") do
it { should be_file }
it { should be_mode 700 }
it { should be_owned_by "root" }
its(:content) { should match /Alice habite 1 chemin de la rue/}
end
describe file("/tmp/test2.conf") do
it { should be_file }
it { should be_mode 770 }
it { should be_owned_by "root" }
its(:content) { should match /Alice et Bob habitent 1 chemin de la rue/}
end
describe command("rm -f -R /tmp/toRepairPosthook") do
end
describe command("rm -f /tmp/test1.conf") do
end
describe command("rm -f /tmp/posthookTest") do
end
describe command("rm -f /tmp/persistentPosthooktest") do
end
describe command("rm -f /var/rudder/tmp/templates/*") do
end
techniques/fileDistribution/fileTemplate/1.0/tests/test_posthook/test_posthook.cf
#!/usr/local/bin/ncf -f
bundle agent init {
vars:
"gen_files" slist => {"test1.conf", "test2.conf", "posthooktest", "persistentPosthooktest"};
"src_files" slist => {"template1", "_tmp_test2_conf.tpl"};
"other_files" slist => {"/tmp/toRepairPosthook"};
methods:
"any" usebundle => file_remove("/tmp/${gen_files}");
"any" usebundle => file_remove("/var/rudder/templates/${src_files}");
"any" usebundle => file_remove("${other_files}");
}
techniques/fileDistribution/fileTemplate/1.0/tests/test_posthook/test_posthook.json
{
"displayName": "File content (from remote template) (1,1) (3,1)",
"enabled": true,
"longDescription": "",
"parameters": {
"section": {
"name": "sections",
"sections": [
{
"section": {
"name": "Apply template",
"sections": [
{
"section": {
"name": "Load Template from a file or text input",
"sections": [
{
"section": {
"name": "Expand template"
}
},
{
"section": {
"name": "Posthook"
}
},
{
"section": {
"name": "Put permissions"
}
},
{
"section": {
"name": "Templates directory permissions"
}
},
{
"section": {
"name": "Templates location"
}
}
],
"vars": [
{
"var": {
"name": "FILE_TEMPLATE_AGENT_DESTINATION_PATH",
"value": "/tmp/posthookTest"
}
},
{
"var": {
"name": "FILE_TEMPLATE_GROUP_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERMISSIONS",
"value": "700"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERSISTENT_POST_HOOK",
"value": "false"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_OR_NOT",
"value": "File"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_TEMPLATE",
"value": ""
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE",
"value": "template1"
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_POST_HOOK_COMMAND",
"value": "/bin/true"
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_TYPE",
"value": "mustache"
}
}
]
}
}
]
}
},
{
"section": {
"name": "Apply template",
"sections": [
{
"section": {
"name": "Load Template from a file or text input",
"sections": [
{
"section": {
"name": "Expand template"
}
},
{
"section": {
"name": "Posthook"
}
},
{
"section": {
"name": "Put permissions"
}
},
{
"section": {
"name": "Templates directory permissions"
}
},
{
"section": {
"name": "Templates location"
}
}
],
"vars": [
{
"var": {
"name": "FILE_TEMPLATE_AGENT_DESTINATION_PATH",
"value": "/tmp/persistentPosthooktest"
}
},
{
"var": {
"name": "FILE_TEMPLATE_GROUP_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_OWNER",
"value": "root"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERMISSIONS",
"value": "700"
}
},
{
"var": {
"name": "FILE_TEMPLATE_PERSISTENT_POST_HOOK",
"value": "true"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_OR_NOT",
"value": "File"
}
},
{
"var": {
"name": "FILE_TEMPLATE_RAW_TEMPLATE",
"value": ""
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE",
"value": "template1"
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_POST_HOOK_COMMAND",
"value": "/bin/ls /tmp/toRepairPosthook"
}
},
{
"var": {
"name": "FILE_TEMPLATE_TEMPLATE_TYPE",
"value": "mustache"
}
}
]
}
}
]
}
}
]
}
},
"shortDescription": "",
"techniqueName": "fileTemplate",
"techniqueVersion": "1.0"
}
techniques/fileDistribution/fileTemplate/1.0/tests/test_posthook/test_posthook.metadata
[{
"inits": ["test_posthook.cf"],
"directives": ["test_posthook.json", "loadVars.json"],
"checks": ["test_posthook.rb"],
"sharedFiles":["template1"],
"compliance": 100
}]
techniques/fileDistribution/fileTemplate/1.0/tests/test_posthook/test_posthook.rb
require "spec_helper"
# First run is done by technique scenario => persistent posthook launched
describe command("rudder agent run -r") do
its(:stdout) { should match /^R: @@fileTemplate@@result_na@@.*?@@.*?@@.*?@@Posthook@@\/tmp\/posthookTest@@.*?No post-modification needed to run$/m}
its(:stdout) { should match /^R: @@fileTemplate@@result_error@@.*?@@.*?@@.*?@@Posthook@@\/tmp\/persistentPosthooktest@@.*?The command .*?from postHook execution could not be repaired$/m}
end
# Force the execution of the posthook
describe command("rm -f /tmp/posthookTest /tmp/persistentPosthookTest") do
end
describe command("rudder agent run -r") do
its(:stdout) { should match /^R: @@fileTemplate@@result_repaired@@.*?@@.*?@@.*?@@Posthook@@\/tmp\/posthookTest@@.*?The command .*?from postHook execution was repaired$/m}
its(:stdout) { should match /^R: @@fileTemplate@@result_error@@.*?@@.*?@@.*?@@Posthook@@\/tmp\/persistentPosthooktest@@.*?The command .*?from postHook execution could not be repaired$/m}
end
# We retry to ensure that the persistent one continues
describe command("rudder agent run -r") do
its(:stdout) { should match /^R: @@fileTemplate@@result_na@@.*?@@.*?@@.*?@@Posthook@@\/tmp\/posthookTest@@.*?No post-modification needed to run$/m}
its(:stdout) { should match /^R: @@fileTemplate@@result_error@@.*?@@.*?@@.*?@@Posthook@@\/tmp\/persistentPosthooktest@@.*?The command .*?from postHook execution could not be repaired$/m}
end
# Resolution of the persistent posthook
describe command("mkdir /tmp/toRepairPosthook; rudder agent run -r") do
its(:stdout) { should match /^R: @@fileTemplate@@result_na@@.*?@@.*?@@.*?@@Posthook@@\/tmp\/posthookTest@@.*?No post-modification needed to run$/m}
its(:stdout) { should match /^R: @@fileTemplate@@result_repaired@@.*?@@.*?@@.*?@@Posthook@@\/tmp\/persistentPosthooktest@@.*?The command .*?from postHook execution was repaired$/m}
end
describe command("rm -rf /tmp/toRepairPosthook") do
end

Also available in: Unified diff