user3017717
user3017717

Reputation: 11

Create XML based on puppet templates with correct custom values?

In a database config setup I have 20 something XML files with the database connection information.

They have all exactly the same content except the connection information that is different. I have to use these XML files for five different environments, so instead of updating them manually I was hoping there was a good way to update their content with puppet, as I use this to set up the rest of the environment:

<config-property-setting name="DatabaseName"></config-property-setting>
<config-property-setting name="Password"></config-property-setting>
<config-property-setting name="UserName"></config-property-setting>
<config-property-setting name="ServerName"></config-property-setting>
<config-property-setting name="DriverType"></config-property-setting>
<config-property-setting name="MaxStatements"></config-property-setting>
<config-property-setting name="NetworkProtocol"></config-property-setting>
<config-property-setting name="PortNumber"></config-property-setting>
<config-property-setting name="LoginTimeout"></config-property-setting>

These are the values needed to be changed for each XML file.

Is there a good way to have a config file where the values for these files are entered and then, through templates, are pushed out as the correct configured and named XML files?

Upvotes: 1

Views: 1534

Answers (2)

bartavelle
bartavelle

Reputation: 917

The most elegant way to do that in pure puppet is probably by using Hiera and an Erb template.

First of all, make sure that your hiera.yaml contains a hierarchy appropriate for your use case. For example, if the distinct environments are in distinct domains (but it might be more common to use the environment variable) :

:hierarchy:
  - "%{module_name}/%{::fqdn}"
  - "%{module_name}/%{::domain}"
  - "%{module_name}/global"
  - "global"

Then you can store the various configuration values just as @mudasobwa suggested, for example in hieradata/xmlmodule/domain1.internal :

:properties:
  :DatabaseName : 'name'
  :Password : 'pwd'
  :UserName : 'user'
  :ServerName : 'server'
  :DriverType : 'mysql'
  :MaxStatements : 30
  :NetworkProtocol : 'udp'
  :PortNumber : 1234
  :LoginTimeout : 60

Then it's as simple as :

$properties = hiera('properties')
file { '/where/the/xml/fileS/goes.xml':
    content => template('template.xml.erb');
}

And you get the values you need in the properties hash :

<config-property-setting name="DatabaseName">
    <%=properties['DatabaseName']%>
</config-property-setting>
<config-property-setting name="Password">
    <%=properties['Password']%>
</config-property-setting>
...

Upvotes: 1

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121020

I would use pure ruby for that. First of all, create YAML config file:

:properties:
  :DatabaseName : 'name'
  :Password : 'pwd'
  :UserName : 'user'
  :ServerName : 'server'
  :DriverType : 'mysql'
  :MaxStatements : 30
  :NetworkProtocol : 'udp'
  :PortNumber : 1234
  :LoginTimeout : 60

Then use this ruby code to produce what you need:

require 'yaml'
cfg = YAML.load_file 'cfg.yml'
xml = cfg[:properties].map { |k, v|
  "<config-property-setting name='#{k}'>#{v}</config-property-setting>"  
}.join("\n")

And, finally, inject these values into xml config templates (there must be a placeholder within xml configs to denote the place for proper values, e. g. if you want to insert them right after the root node <root>):

xml_config_files.each { |file|
  File.write(file, File.read(f).gsub /<root>/m, "<root>\n#{xml}\n")
}

Hope it helps.

Upvotes: 0

Related Questions