Skip to content

Commit

Permalink
Fixes #10079: Add a generic method to merge two dict variables
Browse files Browse the repository at this point in the history
  • Loading branch information
amousset committed Jan 27, 2017
1 parent 15b4a49 commit 6cc23b4
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 0 deletions.
66 changes: 66 additions & 0 deletions tests/acceptance/30_generic_methods/variable_dict_merge.cf
Original file line number Diff line number Diff line change
@@ -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";
}
97 changes: 97 additions & 0 deletions tree/30_generic_methods/variable_dict_merge.cf
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
#
#####################################################################################

# @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, which content will be overriden in the resulting variable if necessary (written in the form variable_prefix.variable_name)
# @parameter second_variable The second variable, which content will override the first in the resulting variable if necessary (written 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});
}

0 comments on commit 6cc23b4

Please sign in to comment.