Forum: CFEngine Help
Subject: Using a bundle to generically fill an associative array
Author: svenXY
Link to topic: https://cfengine.com/forum/read.php?3,23728,23728#msg-23728
Hi again,
My intention is to provide a bundle to generically fill associative arrays from
csv-files. The idea discussed here earlier was to use getfields twice, first to
read the array of headers (a.k.a keys), then to read the line that matches my
search criteria and then make those two into an associative array.
The second step here ist to use usebundle to create arrays that can then be
used outside of the array, but this does not seem to be possible.
I have the following code (pls. forgive the german comments, I hope the
intention becomes clear anyway):
body common control {
version => "0.0.1";
bundlesequence => { "make_arrs" };
}
bundle agent make_arrs {
vars:
"csv_file" string => "/tmp/data.csv";
methods:
"ok" usebundle => arr("${csv_file}", "d1", ";", "host;type;.*",
"${sys.uqhost};.*");
"ok" usebundle => arr("${csv_file}", "d2", ";", "host;type;.*",
"x10001;.*");
reports:
linux::
"d1: ${arr.d1}";
"d2: ${arr.d2}";
}
bundle agent arr(file, myname, delimiter, h_regex, l_regex)
{
# Das Bundle liest die Datei data.csv
# und füllt ein assoz. Array
vars:
"data_file" string => "${file}";
# Daten: Dursucht die Datei nach Zeilen, die mit "${sys.uqhost};.*"
beginnen,
# es kann auch jede andere Regex sein, trennt am ';'
# und füllt das Array arr_data
# lines_data enthält die Zahl der gefundenen Zeilen
"lines_data" int => getfields(
"${l_regex}",
"${data_file}",
"${delimiter}",
"arr_data"
),
comment => "An array containing the host specific data";
# Header: Dursucht die Datei nach Zeilen, die mit "host;type;.*"
beginnen,
# es kann auch jede andere Regex sein, trennt am ';'
# und füllt das Array arr_fields
# lines_data enthält die Zahl der gefundenen Zeilen
"no_h_fields" int => getfields(
"${h_regex}",
"${data_file}",
"${delimiter}",
"arr_fields"
),
comment => "Retrieve an array of fields";
# Da cfengine assoz. Arrays und Arrays weitestgehend gleich
behandelt,
# ist das Ergebnis hier eine Liste der Keys, hier Strings von
Zahlen (1-n):
"h_keys" slist => getindices("h_fields"),
comment => "Make a list from the array";
# Jetzt wird das eingentliche Array gefüllt mit den Werten aus
arr_fields als Schlüsseln
# und den Werten aus arr_data als Werten.
# Ergebnis z.B. ${data} = x10001 usw.
"${myname}[${arr_fields[${h_keys}]}]" string =>
"${arr_data[${h_keys}]}",
comment => "Fill assoc. array with list of keys and
values from the num. array";
}
The csv-file would be something like this:
host;type;stage;in_iface;out_iface;instance;ws_name
host1;pub;prod;10.112.4.11;10.112.8.11;bla;ifasl
myhost;pub;prod;10.112.4.12;10.112.8.12;bla2;fasl2
The result is:
cf3> Promise handle:
cf3> Promise made by: d1: ${arr.d1}
cf3> .........................................................
cf3>
cf3> Report: d1: ${arr.d1}
cf3> R: d1: ${arr.d1}
cf3>
cf3> .........................................................
cf3> Promise handle:
cf3> Promise made by: d2: ${arr.d2}
cf3> .........................................................
cf3>
cf3> Report: d2: ${arr.d2}
cf3> R: d2: ${arr.d2}
Thanks for any comments on this,
Sven
_______________________________________________
Help-cfengine mailing list
[email protected]
https://cfengine.org/mailman/listinfo/help-cfengine