Templates with multiple changes

28 views
Skip to first unread message

bofh...@gmail.com

unread,
Nov 11, 2016, 6:13:49 PM11/11/16
to help-cfengine
Hi all,

I feel I am close to a solution but the last part is just out of my reach.
I want to template a file that has multiple items changing.  Can this be done?  This is going to contain a pile of hosts so a "hard coded" template isn't an option.


Current Promise:
bundle agent template
{
  vars:
      "servers[host0]"   string => "000";
      "servers[host1]"   string => "001";
      "server_num"       slist  => { "$(servers[host0])", "$(servers[host1])" };

  files:
      "/tmp/testfile"
      create           => "true",
      edit_defaults    => empty,
      template_method  => "mustache",
      edit_template    => "/tmp/src/file";
}



Template file (solve for XXXXX)
{{#vars.template.server_num}}
          Line 1: host_number = {{{.}}}
          Line 2: Host_name = XXXXX  (should be host0 the the next batch host1....)
          Line 3: String of data

{{/vars.template.server_num}}


Desired Output:
Line 1: host_number = 000
Line 2: Host_name = host0
Line 3: String of data

Line 1: host_number = 001
Line 2: Host_name = host1
Line 3: String of data



Thank you in advance,
Robin

Ted Zlatanov

unread,
Nov 14, 2016, 10:55:35 AM11/14/16
to help-c...@googlegroups.com
On Fri, 11 Nov 2016 15:13:48 -0800 (PST) bofh...@gmail.com wrote:

b> *Template file (solve for XXXXX)*{{#vars.template.server_num}}
b> Line 1: host_number = {{{.}}}
b> Line 2: Host_name = XXXXX (should be host0 the the next batch
b> host1....)
b> Line 3: String of data

b> {{/vars.template.server_num}}

b> *Desired Output:*Line 1: host_number = 000
b> Line 2: Host_name = host0
b> Line 3: String of data

b> Line 1: host_number = 001
b> Line 2: Host_name = host1
b> Line 3: String of data

I've looked at this several times and can't figure out what you're
after, sorry. It's especially unclear if you want this output in two
files or in the same file.

If you're mapping hostnames to pieces of data, you could do

vars: "hostdata" data => '{ "host1": { "key": "v1" }, "host2": { "key": "v2" } }';

and then iterate over the hosts to extract the value for that key. If
that data model fits your needs, can you explain again what your desired
output is?

Ted

bofh...@gmail.com

unread,
Nov 14, 2016, 3:16:29 PM11/14/16
to help-cfengine
Sorry for the confusion of not explaining in full.

I am trying to generate a single file for our LDAP setup (/etc/openldap/slapd.conf).  In this file there is a section that has the synrepl configs for each host.  I need to capture both the rid= and provider= lines but everything else in the block of text is the same.  The amount of hosts keeps growing and I want to generate the file instead of hand editing which is what we do today.  We have already had issues with bad edits.  I think your statement about mapping hostdata to pieces of data is what I need.  I am still new to CFEngine but I keep plugging away at it. The help I have received from this group (and you) is greatly appreciated.

Here is a sample of the blocks I want to manage.
synscrepl
   rid=001
   provider=ldap://SERVER_A:389/
   bindmethod=simple
   starttls=critical
   schemachecking=on
   type=refreshAndPersist
   retry="60,+"

syncrepl
   rid=002
   provider=ldap://SERVER_B:389/
   bindmethod=simple
   starttls=critical
   schemachecking=on
   type=refreshAndPersist
   retry="60,+"

syncrepl
   rid=003
   provider=ldap://SERVER_C:389/
   bindmethod=simple
   starttls=critical
   schemachecking=on
   type=refreshAndPersist
   retry="60,+"
........

Ted Zlatanov

unread,
Nov 15, 2016, 2:38:37 PM11/15/16
to help-c...@googlegroups.com
If I understand correctly, you want this data model and corresponding
template. Although I'm using string_mustache() to keep the example
simple, the same thing works when the template is in a .mustache file.

`-top-` is the top-level object for iteration. That's a CFEngine
extension so you won't find it in other Mustache implementations.

HTH
Ted

#+begin_src cfengine3
bundle agent main
{
vars:
"servers" data => '[
{ rid: "001", hostport: "SERVER_A:389" },
{ rid: "002", hostport: "SERVER_B:389" },
{ rid: "003", hostport: "SERVER_C:389" },
{ rid: "004", hostport: "SERVER_D:3890" },
]';
"output" string => string_mustache('
{{#-top-}}
synscrepl
rid={{{ rid }}}
provider=ldap://{{{ hostport }}}/
bindmethod=simple
starttls=critical
schemachecking=on
type=refreshAndPersist
retry="60,+"

{{/-top-}}', servers);

reports:
"$(this.bundle): output = $(output)";

}
#+end_src

Output:

#+begin_src text
R: main: output =
synscrepl
rid=001
provider=ldap://SERVER_A:389/
bindmethod=simple
starttls=critical
schemachecking=on
type=refreshAndPersist
retry="60,+"

synscrepl
rid=002
provider=ldap://SERVER_B:389/
bindmethod=simple
starttls=critical
schemachecking=on
type=refreshAndPersist
retry="60,+"

synscrepl
rid=003
provider=ldap://SERVER_C:389/
bindmethod=simple
starttls=critical
schemachecking=on
type=refreshAndPersist
retry="60,+"

synscrepl
rid=004
provider=ldap://SERVER_D:3890/
bindmethod=simple
starttls=critical
schemachecking=on
type=refreshAndPersist
retry="60,+"
#+end_src

bofh...@gmail.com

unread,
Nov 15, 2016, 5:32:01 PM11/15/16
to help-cfengine
Thank you so much.  Feels like drinking from a fire hose at times but you guys are really helping me along. 





On Friday, November 11, 2016 at 4:13:49 PM UTC-7, bofh...@gmail.com wrote:
Reply all
Reply to author
Forward
0 new messages