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

Reply via email to