i am getting aq funny error, i think its from this code
bundle agent init
{
files:
"/var/cfengine/billing/$(main.peers)/$(main.year)-$(main.month)"
edit_line => insert_line( '{ "some-data": "$(peers)" }' ),
create => "true";
}
bundle edit_line insert_line( line )
{
insert_lines:
"$(line)";
}
bundle agent main
{
vars:
"peers" slist => { "one", "two" };
"year" string => strftime( localtime, "%Y", now() );
"month" string => strftime( localtime, "%m", now() );
"invoices[$(peers)]"
string => format( "%S", readdata("/var/cfengine/billing/$(peers)/$(year)-$(month)", "auto") ),
if => fileexists( "/var/cfengine/billing/$(peers)/$(year)-$(month)" );
}
error: format() didn't have enough parameters
I think the error with format()
is that it is not a collecting function.
Also, I don’t think that you have to stuff JSON strings into classic arrays in
order to be able to iterate and process them. The meta
attribute combined with
=variablesmatching()= or =variablesmatching_as_data()= can be useful to pull
together various data containers.
Here I switched from a classic array to individual data containers for each data file. Each variable is tagged with invoice so that they can all be collected together into a unified data container.
bundle agent init
{
files:
"/var/cfengine/billing/$(main.peers)/$(main.year)-$(main.month)"
edit_line => insert_line( '{ "some-data": "$(main.peers)" }' ),
create => "true";
}
bundle edit_line insert_line( line )
{
insert_lines:
"$(line)";
}
bundle agent main
{
vars:
"peers" slist => { "one", "two" };
"year" string => strftime( localtime, "%Y", now() );
"month" string => strftime( localtime, "%m", now() );
"invoices_$(peers)"
meta => { invoice },
data => readdata("/var/cfengine/billing/$(peers)/$(year)-$(month)", "JSON"),
if => fileexists( "/var/cfengine/billing/$(peers)/$(year)-$(month)" );
"unified_invoices"
data => variablesmatching_as_data( ".*", # Variables with any name, in any bundle, in any namespace
"invoice"); # Tagged with invoice
reports:
"CFEngine $(sys.cf_version)";
}
[root@hub ~]# cf-agent -KIf ./t.cf --show-evaluated-vars=main R: CFEngine 3.12.2 Variable name Variable value Meta tags default:main.invoices_one {"some-data":"one"} source=promise,invoice default:main.invoices_two {"some-data":"two"} source=promise,invoice default:main.month 07 source=promise default:main.peers {"one","two"} source=promise default:main.unified_invoices {"default:main.invoices_one":{"some-data":"one"},"default:main.invoices_two":{"some-data":"two"}} source=promise default:main.year 2019 source=promise default:sys.domain example.com source=agent
See CFE-3105 for issue tracking adding collecting behavior to the format()
function.
Example showing format should take functions that return data.
bundle agent main
{
vars:
"peers" slist => { "one", "two" };
"year" string => strftime( localtime, "%Y", now() );
"month" string => strftime( localtime, "%m", now() );
"$(peers)" data => '{ "some-data": "$(peers)" }';
"WORKS[$(peers)]"
string => format( "%S", "$(peers)" );
"ERRORS[$(peers)]"
string => format( "%S", parsejson( '{ "some-data": "$(peers)" }' ) );
}
error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters error: format() didn't have enough parameters Variable name Variable value Meta tags default:main.WORKS[one] {\"some-data\":\"one\"} source=promise default:main.WORKS[two] {\"some-data\":\"two\"} source=promise default:main.month 07 source=promise default:main.one {"some-data":"one"} source=promise default:main.peers {"one","two"} source=promise default:main.two {"some-data":"two"} source=promise default:main.year 2019 source=promise default:maintain_key_values_meta.tags {"deprecated=3.6.0","deprecation-reason=Generic reimplementation","replaced-by=set_line_based"} source=promise
Ok, but what if $(peers) contains characters that are not valid in variable names?
Then you need to make a canonified map that you can use for iteration.
bundle agent init
{
files:
"/var/cfengine/billing/$(main.peers)/$(main.year)-$(main.month)"
edit_line => insert_line( '{ "some-data": "$(main.peers)" }' ),
create => "true";
}
bundle edit_line insert_line( line )
{
insert_lines:
"$(line)";
}
bundle agent main
{
vars:
"peers" slist => { "one-crap", "two.balls" };
"cmap_peers[$(peers)]" string => canonify( $(peers) );
"year" string => strftime( localtime, "%Y", now() );
"month" string => strftime( localtime, "%m", now() );
"invoices_$(cmap_peers[$(peers)])"
meta => { invoice },
data => readdata("/var/cfengine/billing/$(peers)/$(year)-$(month)", "JSON"),
if => fileexists( "/var/cfengine/billing/$(peers)/$(year)-$(month)" );
"unified_invoices"
data => variablesmatching_as_data( ".*", # Variables with any name, in any bundle, in any namespace
"invoice"); # Tagged with invoice
reports:
"CFEngine $(sys.cf_version)";
}