CFEngine: new maparray() function
  2013-04-08

From an array and a string template, maparray() will generate a slist of strings expanded from the template, with the possibility for each array element, to use its key and its value(s).

Example reproduced below:

body common control
{
      bundlesequence => { run };
}

bundle agent run
{
  vars:
      "todo[1]" string => "2";
      "todo[one]" string => "two";
      "todo[3999]" slist => { "big", "small" };
      "map" slist => maparray("yes $(this.k) $(this.v)", "todo");

  reports:
    cfengine::
      "Hello $(map)";
}

Output:

R: Hello yes 1 2
R: Hello yes one two
R: Hello yes 3999 big
R: Hello yes 3999 small

Here is another example based on DNS entries:

body common control {
  bundlesequence => { "dns" };
}

bundle agent dns {

 vars:

  "cluster_ipv4[proc1]"   string  =>  "10.0.0.1";
  "cluster_ipv4[proc2]"   string  =>  "10.0.0.2";
  "cluster_ipv4[proc3]"   string  =>  "10.0.0.3";

  "cluster_ipv6[proc1]"   string  =>  "2001:500:88:200::10";
  "cluster_ipv6[proc2]"   string  =>  "2001:500:88:200::20";
  "cluster_ipv6[proc3]"   string  =>  "2001:500:88:200::30";

  "web_servers[www]"      slist    =>  { "10.0.8.1", "10.0.8.2", "10.0.8.3"};

  "cluster_A"       slist   =>  maparray("$(this.k) IN A $(this.v)", "cluster_ipv4");
  "cluster_AAAA"    slist   =>  maparray("$(this.k) IN AAAA $(this.v)", "cluster_ipv6");
  "www_A"           slist   =>  maparray("$(this.k) IN A $(this.v)", "web_servers");

 reports:
  "$(cluster_A)";

  "$(cluster_AAAA)";

  "$(www_A)";
}

Output:

Running full policy integrity checks
R: proc3 IN A 10.0.0.3
R: proc2 IN A 10.0.0.2
R: proc1 IN A 10.0.0.1
R: proc3 IN AAAA 2001:500:88:200::30
R: proc1 IN AAAA 2001:500:88:200::10
R: proc2 IN AAAA 2001:500:88:200::20
R: www IN A 10.0.8.1
R: www IN A 10.0.8.2
R: www IN A 10.0.8.3

Round-robin DNS is used on the www server (several A entries)