Nick
2011-Jan-10 11:01 UTC
[Puppet Users] is it possible to access resource definitions from ERB templates?
Puppet''s template() function has the potential to be a rather excellent way to generate configuration files, so I wondered if it would be able to generate something non-trivial, like a set of Shorewall configuration files. I should note, I have seen the Shorewall example from the puppet "patterns" pages, and others based on it [1]. These work by generating lots of fragments of files in /var/lib/puppet/modules/shorewall, with names prefixed by some index number, and finally sorting and concatenating them together, interleaved with various headers and footers. This isn''t ideal when, like the zones file, there can be sections defined in some hierarchy. It also seems to be extremely slow to run (at least for me - it takes long enough to make some tea *and* drink it). But having tried to implement a version which uses a template (in v0.25.4), I can''t see a way to do it without resorting to some variation of file concatenation, because the structure of resources defined in a puppet manifest is not fully exposed to the templates (that I can see). What I would like to do in general, for example, is to define some resources in a class like this: define somesystem::section { # This is a placeholder, it doesn''t do anything # besides represent a section in the generated config file } define somesystem::item($name) { # ditto } class somesystem::defaults { # this could define any default configuration data, e.g.: section {"common": item {"base": name => "/etc/somesystem"} } } node "mynode" { class somesystem::my_config inherits somesystem::defaults { # This can extend (or override) the default config data section {"animals": item {"dog": name => ''fido''}; item {"cat": name => ''fluffy''}; } section {"vegetables": item {"potato": name => ''spud''}; } } } Then, using a template like this example: <config> <!-- boilerplate --> <%# (note that the resources would ideally be iterated in the order they appear in the manifest, by default) %> <% scope.class.resources(''section'').each do |section| -%> <Section id="<%= section.title %>"> <% section.resources(''item'').each do |item| -%> <item type="<%= item.title %>"><%= item.name %></item> <% end -%> </Section> <% end %> </config> ...we might generate something like this: <config> <!-- boilerplate --> <Section id="common"> <item type="base">/var/somesystem</item> </Section> <Section id="animals"> <item type="dog">fido</item> <item type="cat">fluffy</item> </Section> <Section id="vegetables"> <item type="dog">fido</item> <item type="cat">fluffy</item> </Section> </config> I would guess there is a way to access the manifest''s syntax tree from within the template via the .scope method, but it doesn''t seem to be fully supported or encouraged. [4] On the other hand, if Puppet had some sort of DOM accessible to templates, this could be made to work, and Puppet would have a very general and powerful way to generate all sorts of content from resources defined in manifests. I''d like to ask: - Does this seem a worthy and achievable aim in general? - Is there some way I could achieve this now, preferably in 0.25.x? I would guess that the only way is to write a Provider, or to somehow implement a (client-side?) ERB template which uses the YAML in /var/lib/puppet/state/localconfig.yaml as context, neither of which I know how to do currently. Advice and pointers would be very welcome. Thanks, Nick 1. These shorewall modules all seem to be essentially the same: http://projects.puppetlabs.com/projects/puppet/wiki/Aqueos_Shorewall_Patterns https://github.com/camptocamp/puppet-shorewall git://labs.riseup.net/module_shorewall 2. The above depend on this, or something equivalent: git://git.black.co.at/module-common 3. "plugins loaded into memory on the server (e.g., functions) do not correctly work in environments [on 0.25.x]" http://groups.google.com/group/puppet-dev/browse_thread/thread/d39e2db23a7f65b8 4. A similar idea to mine is discussed here: http://www.mail-archive.com/puppet-users@googlegroups.com/msg06883.html -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
João Matos
2013-Jun-19 13:59 UTC
[Puppet Users] Re: is it possible to access resource definitions from ERB templates?
Did you get anything like what you mentioned to work? I had this very same idea, but I can''t find any documentation on accessing the list of instantiated resources from a template. On Monday, January 10, 2011 11:01:17 AM UTC, Nick wrote:> > Puppet''s template() function has the potential to be a rather excellent > way to > generate configuration files, so I wondered if it would be able to generate > something non-trivial, like a set of Shorewall configuration files. > > I should note, I have seen the Shorewall example from the puppet "patterns" > pages, and others based on it [1]. These work by generating lots of > fragments > of files in /var/lib/puppet/modules/shorewall, with names prefixed by some > index > number, and finally sorting and concatenating them together, interleaved > with > various headers and footers. This isn''t ideal when, like the zones file, > there > can be sections defined in some hierarchy. It also seems to be extremely > slow > to run (at least for me - it takes long enough to make some tea *and* > drink it). > > But having tried to implement a version which uses a template (in > v0.25.4), I > can''t see a way to do it without resorting to some variation of file > concatenation, because the structure of resources defined in a puppet > manifest > is not fully exposed to the templates (that I can see). > > > What I would like to do in general, for example, is to define some > resources in > a class like this: > > define somesystem::section { > # This is a placeholder, it doesn''t do anything > # besides represent a section in the generated config file > } > > define somesystem::item($name) { > # ditto > } > > class somesystem::defaults { > # this could define any default configuration data, e.g.: > > section {"common": > item {"base": name => "/etc/somesystem"} > } > } > > > node "mynode" { > > class somesystem::my_config inherits somesystem::defaults { > # This can extend (or override) the default config data > > section {"animals": > item {"dog": name => ''fido''}; > item {"cat": name => ''fluffy''}; > } > > section {"vegetables": > item {"potato": name => ''spud''}; > } > } > } > > Then, using a template like this example: > > <config> <!-- boilerplate --> > > <%# (note that the resources would ideally be iterated > in the order they appear in the manifest, by default) %> > > <% scope.class.resources(''section'').each do |section| -%> > <Section id="<%= section.title %>"> > <% section.resources(''item'').each do |item| -%> > <item type="<%= item.title %>"><%= item.name %></item> > <% end -%> > </Section> > <% end %> > > </config> > > ...we might generate something like this: > > <config> <!-- boilerplate --> > > <Section id="common"> > <item type="base">/var/somesystem</item> > </Section> > > <Section id="animals"> > <item type="dog">fido</item> > <item type="cat">fluffy</item> > </Section> > > <Section id="vegetables"> > <item type="dog">fido</item> > <item type="cat">fluffy</item> > </Section> > > </config> > > I would guess there is a way to access the manifest''s syntax tree from > within > the template via the .scope method, but it doesn''t seem to be fully > supported or > encouraged. [4] > > On the other hand, if Puppet had some sort of DOM accessible to templates, > this > could be made to work, and Puppet would have a very general and powerful > way to > generate all sorts of content from resources defined in manifests. > > I''d like to ask: > > - Does this seem a worthy and achievable aim in general? > - Is there some way I could achieve this now, preferably in 0.25.x? > > I would guess that the only way is to write a Provider, or to somehow > implement > a (client-side?) ERB template which uses the YAML in > /var/lib/puppet/state/localconfig.yaml as context, neither of which I know > how > to do currently. Advice and pointers would be very welcome. > > Thanks, > > Nick > > > 1. These shorewall modules all seem to be essentially the same: > > http://projects.puppetlabs.com/projects/puppet/wiki/Aqueos_Shorewall_Patterns > https://github.com/camptocamp/puppet-shorewall > git://labs.riseup.net/module_shorewall > > 2. The above depend on this, or something equivalent: > git://git.black.co.at/module-common > > 3. "plugins loaded into memory on the server (e.g., functions) do not > correctly work in environments [on 0.25.x]" > > http://groups.google.com/group/puppet-dev/browse_thread/thread/d39e2db23a7f65b8 > > 4. A similar idea to mine is discussed here: > http://www.mail-archive.com/puppet-users@googlegroups.com/msg06883.html > >-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users. For more options, visit https://groups.google.com/groups/opt_out.