Ask Your Question

How do I resolve a file reference via Ruby in a custom module

asked 2017-09-13 08:28:44 -0600

srpecnik gravatar image

Hi everyone, I have what I think should be a simple question, but for the life of me just can't find a solution. Hoping you can help, here goes...

I'm trying to build a custom module that makes a couple of quick REST calls (I know, kind of "unpuppety"). I've got everything up and running, except for I can't figure out how to read the contents of a "puppetted" file reference from Ruby. In the below resource declaration, I have hardcoded the location of a file that lives inside of my module. This works just fine for my testing, but is not adequate when run on my server.

elasticsearch_template { 'analytic_template':
  ensure     => present,
  servername => 'localhost',
  port       => '9201',
  ssl        => false,
  content    => 'C:\Users\specnik\repos\elasticsearch\files\template_1.json'
  # content    => 'puppet:///modules/elasticsearch/template_1.json',

What I think best practice would be is to reference a file from within a module like I have in the commented line above. The question is, with that type of reference, how do I read the file from Ruby? Right now I am using the following, which works for the hard coded file reference only:[:content])

Surely there must be an API to sort this kind of thing out?? Has anybody come across this type of thing before and could point me to a solution? Oh, and the reason I am not using an existing elasticsearch module is because I am spinning up a container with elasticsearch and not trying to install directly on the machine.

Thanks! Scott

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2017-09-15 15:05:23 -0600

DarylW gravatar image

If you are trying to do rest calls, and use that information as part of something on your system, you may want to implement our own custom types and providers

There is an interesting example from Gareth Rushgrove where he has custom types generated off of the Kubernettes swagger files, and uses that to construct his own resources for managing kubernettes clusters

In your case, it may also work to either get the information you need via a custom fact on the instance, or have a custom hiera backend which will allow you to get the information you need that way. You may be specifically interested in the following

Hiera backends are Puppet functions

In this version of Hiera, a backend is simply a custom Puppet function that accepts a particular set of arguments and whose return value obeys a particular format. The function can do whatever is necessary to locate its data.

A backend function can use the modern Ruby functions API or the Puppet language. (They can’t use the legacy Ruby functions API.) Among other things, this means you can use different versions of a Hiera backend in different environments, and you can distribute Hiera backends in Puppet modules.

This is a simpler interface than in previous versions of Hiera, where custom backends were globally-loaded Ruby classes that had to define particular methods.

edit flag offensive delete link more


Thanks! I was actually in the midst if implementing a custom mod, which is where this question came from. Here is what I ended up with:

srpecnik gravatar imagesrpecnik ( 2017-09-15 19:27:01 -0600 )edit

Note: use of hiera is not available when applying a catalog

Henrik Lindberg gravatar imageHenrik Lindberg ( 2017-09-16 05:49:11 -0600 )edit

answered 2017-09-13 18:30:43 -0600

srpecnik gravatar image

So after a night of sleep I think i've answered my own question. Seems I was over thinking the problem. Why not just use a file resource in the first place :)

file { '/home/pvadmin/analytics/analytics_mapping.json':
    ensure  => present,
    path    => '/home/pvadmin/analytics/analytics_mapping.json',
    content => file('profile/analytics_mapping.json'),
    owner   => 'pvadmin',
    group   => 'pvadmin',
    mode    => '0755',
    require => File['/home/pvadmin/analytics'],
    notify  => Docker::Run['analytics'],

elasticsearch_template { 'analytic_template':
    ensure     => present,
    servername => 'localhost',
    port       => '9201',
    ssl        => false,
    content    => '/home/pvadmin/analytics/analytics_mapping.json',
    require    => Exec['waitForContainerToStart'],

Doh! OK, so I have a solution but now I am curious, is it possible to do what I was attempting? Does the File resource use internal APIs that aren't accessible to public extenders?


edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2017-09-13 08:26:15 -0600

Seen: 109 times

Last updated: Sep 15 '17