diff --git a/tests/acceptance/30_generic_methods/variable_dict_merge.cf b/tests/acceptance/30_generic_methods/variable_dict_merge.cf new file mode 100644 index 000000000..8c7e18b23 --- /dev/null +++ b/tests/acceptance/30_generic_methods/variable_dict_merge.cf @@ -0,0 +1,66 @@ +####################################################### +# +# Create a dict variable by merging two other variables +# +####################################################### + +bundle common acc_path +{ + vars: + "root" string => getenv("NCF_TESTS_ACCEPTANCE", 1024); +} + +body common control +{ + inputs => { "${acc_path.root}/default.cf.sub", "${acc_path.root}/default_ncf.cf.sub", "@{ncf_inputs.default_files}" }; + bundlesequence => { configuration, default("${this.promise_filename}") }; + version => "1.0"; +} + +####################################################### + +bundle agent init +{ + vars: + + "dict1" data => parsejson('{ "key1": "value1", "key2": "value2", "key3": { "keyx": "valuex" }, "key4": [ "valuey" ] }'); + "dict2" data => parsejson('{ "key1": "value1bis", "key4": "value4" }'); + "ref" string => '{ + "key1": "value1bis", + "key2": "value2", + "key3": { + "keyx": "valuex" + }, + "key4": "value4" +}'; + +} + +####################################################### + +bundle agent test +{ + methods: + "ph3" usebundle => variable_dict_merge("prefix", "var3", "init.dict1", "init.dict2"); +} + +####################################################### + +bundle agent check +{ + vars: + "result" string => storejson("prefix.var3"); + + classes: + + "ok_class" expression => "variable_dict_merge_var3_kept.!variable_dict_merge_var3_repaired.!variable_dict_merge_var3_error"; + "ok_value" expression => strcmp("${result}", "${init.ref}"); + + "ok" expression => "ok_class.ok_value"; + + reports: + ok:: + "$(this.promise_filename) Pass"; + !ok:: + "$(this.promise_filename) FAIL"; +} diff --git a/tree/30_generic_methods/variable_dict_merge.cf b/tree/30_generic_methods/variable_dict_merge.cf new file mode 100644 index 000000000..b647712da --- /dev/null +++ b/tree/30_generic_methods/variable_dict_merge.cf @@ -0,0 +1,97 @@ +##################################################################################### +# Copyright 2017 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 . +# +##################################################################################### + +# @name Variable dict merge +# @description Define a variable resulting of the merge of two other variables +# @documentation To use the generated variable, you must use the form `${variable_prefix.variable_name[key]}` with each name replaced with the parameters of this method. +# +# The resulting variable will be the merge of the two parameters, which means it is built by: +# +# * Taking the content of the first variable +# * Adding the content of the second variable, and replace the kays that were already there +# +# It is only a one-level merge, and the value of the first-lvel key will be completely replaced by the merge. +# +#### Usage +# +# If you have a `prefix.variable1` variable defined by: +# +# ```json +# { "key1": "value1", "key2": "value2", "key3": { "keyx": "valuex" } } +# ``` +# +# And a `prefix.variable2` variable defined by: +# +# ```json +# { "key1": "different", "key3": "value3", "key4": "value4" } +# ``` +# +# And that you use: +# +# ``` +# variablr_dict_merge("prefix", "variable3, "prefix.variable1", "prefix.variable2") +# ``` +# +# You will get a `prefix.variable3` variable containing: +# +# ```json +# { +# "key1": "different", +# "key2": "value2", +# "key3": "value3", +# "key4": "value4" +# } +# ``` +# +# @parameter variable_prefix The prefix of the variable name +# @parameter variable_name The variable to define, the full name will be variable_prefix.variable_name +# @parameter first_variable The first variable, that will be overriden if necessary (in the form variable_prefix.variable_name) +# @parameter second_variable The second variable, that will override the first if necessary (in the form variable_prefix.variable_name) +# +# @agent_version >=3.6 +# +# @class_prefix variable_dict_merge +# @class_parameter variable_name + +bundle agent variable_dict_merge(variable_prefix, variable_name, first_variable, second_variable) +{ + vars: + "old_class_prefix" string => canonify("variable_dict_merge_${variable_name}"); + "promisers" slist => { @{this.callers_promisers}, cf_null }, policy => "ifdefined"; + "class_prefix" string => canonify(join("_", "promisers")); + "args" slist => { "${variable_prefix}", "${variable_name}", "${first_variable}", "${second_variable}" }; + + # define the variable within the variable_prefix namespace + "${variable_prefix}.${variable_name}" data => mergedata("${first_variable}", "${second_variable}"); + + classes: + "variable_defined" expression => isvariable("${variable_prefix}.${variable_name}"); + + methods: + !variable_defined:: + "error" usebundle => _classes_failure("${old_class_prefix}"); + "error" usebundle => _classes_failure("${class_prefix}"); + + variable_defined:: + "success" usebundle => _classes_success("${old_class_prefix}"); + "success" usebundle => _classes_success("${class_prefix}"); + + any:: + "report" + usebundle => _log("Set the dict ${variable_prefix}.${variable_name} to the content of the merge of ${first_variable} and ${second_variable}", "${old_class_prefix}", "${class_prefix}", @{args}); +}