Forum: CFEngine Help
Subject: problem programatically generating arrays from files
Author: svenXY
Link to topic: https://cfengine.com/forum/read.php?3,22966,22966#msg-22966
Hi,
this one is a bit more complicated, but hopefully interesting enough to draw
some attention ;-)
Ultimatively, I want to use it to configure an application for all combinations
of type, environment and version configured for the $(sys.host) automatically.
Given a file with
data.dat:
#############################
### type/env specific ##
#############################
type | env | versions | prefix | is_member
public | prod | 1.1 | prod/ | false
int | prod | 1.1 | int/ | false
public | beta | 1.1,1.2 | beta/ | false
int | beta | 1.1,1.2 | ibeta/ | false
#############################
## host specific ##
#############################
host | type | env | prod_iface
myhost | public | prod | 10.10.5.5
myhost | public | beta | 10.10.5.6
myhost | int | prod | 10.10.5.7
myhost | int | beta | 10.10.5.8
I'd like to fill an associative array (it will be named w[] for shortness) with
key-value pairs from 1) the environmental information and 2) host-specific
information.
I had this working mostly with 3.1.4 but ran into some strange behaviour where
it wouldn't remeber parts of the array, so I decided to hope for improvement on
that area in 3.2.x, but now it is even worse...
However, here's the code:
body common control
{
bundlesequence => { "my_app" };
inputs => { "cfengine_stdlib.cf" };
}
bundle agent my_app
{
vars:
"spl" string => "\s+\|\s+(?!\|)";
"datafile" string => "/path/to/data.dat";
"envs" slist => { "prod", "beta" };
"types" slist => { "public", "int" };
# read type/env data from file into env_${types}_${envs} arrays
"vv_${types}_${envs}" int =>
getfields(
"${types}\s+\|\s+${envs}\s+\|\s+.*","${datafile}","\s+\|\s+(?!\|)","env_${types}_${envs}"
);
# read host data from file into host_${types}_${envs} arrays
"vh_${types}_${envs}" int =>
getfields(
"${sys.host}\s+\|\s+${types}\s+\|\s+${envs}\s+\|\s+.*","${datafile}","\s+\|\s+(?!\|)","host_${types}_${envs}"
);
# retrieve the header lines to make into array-keys later
"no_e_fields" int =>
getfields("type\|env\|.*","${datafile}","\|","efields");
"no_h_fields" int =>
getfields("host${spl}type${spl}env.*","${datafile}","${spl}","hfields");
classes:
"has_${types}_${envs}" expression =>
isgreaterthan("${vh_${types}_${envs}}","0"),
comment => "data found for the host in question";
reports:
linux::
"lines matching ${types}_${envs}: ${vh_${types}_${envs}}";
"class activated: has_${types}_${envs}",
ifvarclass => canonify("has_${types}_${envs}");
methods:
"any" usebundle => make_config("${types}", "${envs}"),
comment => "Installing my_app ${types} in ${envs}",
ifvarclass => canonify("has_${types}_${envs}");
}
bundle agent make_config(type, env)
{
vars:
"mykey" slist => getindices("my_app.efields");
"my_h_key" slist => getindices("my_app.hfields");
### !!!!!! here's the problem - I'm not allowed to do this (it was possible
but did not work properly in 3.1.4 !!!
### what I'm after here is w, w, w,...
"w[$(my_app.hfields[$(my_h_key)])]" string =>
"${my_app.host_${type}_${env}[${my_h_key}]}";
"w[${my_app.efields[${mykey}]}]" string =>
"${my_app.env_${type}_${env}[${mykey}]}";
reports:
linux::
"${w}: installing ${w}-my_app in ${w} in /path/to/app//${w} ${w}";
}
results in:
~/.cfagent/bin/cf-agent -K -f ./test_anon.cf
cf3> ./test_anon.cf:66,46: Too many levels of [] reserved for array use, near
token 'string'
cf3> ./test_anon.cf:66,46: Use of a reserved or illegal variable name
"w[$(my_app.hfields[$(my_h_key)])]" , near token 'string'
cf3> ./test_anon.cf:67,43: Too many levels of [] reserved for array use, near
token 'string'
cf3> ./test_anon.cf:67,43: Use of a reserved or illegal variable name
"w[${my_app.efields[${mykey}]}]" , near token 'string'
I understand that this is some complex construction, but the aim here is to
have a (i.e. 1) extendable simple array to be used in template files.
I'm stuck here, any help/hints/suggestions are greatly appreciated.
Regards,
Sven
_______________________________________________
Help-cfengine mailing list
[email protected]
https://cfengine.org/mailman/listinfo/help-cfengine