Search code examples
puppet

Inserting a string into a file with Puppet with iteration


I'm running a .each iteration with Puppet:

$extensions_list = ["RT::Extension::ActivityReports",
                    "RT::Extension::JSGantt",
                   ]
$extensions_list.each |$extls| {
  cpan { $extls:
    ensure  => present,
    require => Class['::cpan'],
  }
}

As you can see I'm just installing two Perl modules with a cpan module from Puppet Forge. This part works just as expected.

What I would like to happen is each time a new Perl module is installed in this way it will be added to added to the config line of RT (Request Tracker). That file lives here:

/opt/rt4/etc/RT_SiteConfig.pm

and the format of the line is:

Plugins('RT::MODULE::ONE RT::MODULE::TWO');

So, in the end I would like it to look like this:

Plugins('RT::Extension::ActivityReports RT::Extension::JSGantt');

Having Puppet add each new module in turn to that line as they are installed. As in if I decided to install RT::Authen::ExternalAuth a month from now I can just add it to my above iteration and after Puppet runs this:

Plugins('RT::Extension::ActivityReports RT::Extension::JSGantt');

would become this:

Plugins('RT::Extension::ActivityReports RT::Extension::JSGantt RT::Authen::ExternalAuth');

With no other intervention on my part then to add it to the iteration statement.


Solution

  • Assuming that you don't have any other Puppet code managing /opt/rt4/etc/RT_SiteConfig.pm, then you have a few options for making sure that you have the correct Plugins line in that file.

    If you only want to manage just that one line then I would recommend using join and a file_line resource from stdlib.

    For example:

    include stdlib
    
    $ext_string = join($extensions_list, ' ')
    
    file_line { 'rt extensions':
      ensure => present,
      path   => '/opt/rt4/etc/RT_SiteConfig.pm',
      line   => "Plugins('${ext_string}');",
      match  => '^\s*Plugins\(',
    }
    

    This will add a line containing the list of plugins and will replace any existing plugin line.

    If there are several settings that you want to manage then it might make sense to just templatize the entire file. In that case you could simply have the line

    Plugins('<%= @extensions_list.join(' ') %>');
    

    in your template.