1

could you please help me. I'm getting dict from hiera in puppet manifest and then trying to filter them and pass in a python script as args. But don't know how to do it.

My hiera:

myclass::server_conf:
 'first_serv':
   'serv_name': 'testname'
   'serv_hostname': 'testhost'
   'test_url': 'test@url.com'
 'second_serv':
   'serv_name': 'testname2'
   'serv_hostname': 'testhost2'
   'test_url': 'test@url.com2'

My puppet manifest(i'm getting hash from values in hiera):

 $server_conf = hiera_hash('myclass::server_conf', {})

As result of this i had:

{\"first_serv\"=>{\"serv_name\"=>\"testname\", \"serv_hostname\"=>\"testhost\", \"test_url\"=>\"test@url.com\"}, \"second_serv\"=>{\"serv_name\"=>\"serv2\", \"serv_name\"=>\"testname2\", \"serv_hostname\"=>\"testhost2\", \"test_url\"=>\"test@url.com2\"}}

Then i want to select from this list only values:

'testname' 'testhost' 'test@url.com' 'testname2' 'testhost2' 'test@url.com2'

I'm trying to do it using map function:

$transforrmed_data = map(server_conf) |$key,$value| { $value }

And getting error:

Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Could not match |$key,$value| at /manifests/server.pp:26 on node test.node

How can i solve this problem? Also I need to transfer to one more variable 'testname2' 'testhost2' 'test@url.com2' and pass it to exec command resource.

Thank you!

aRTURIUS
  • 1,230
  • 2
  • 13
  • 31

1 Answers1

4

It looks like there is a pretty good example of this on the Ask PuppetLabs forum: Iterate nested hash from hiera in manifest.

The solution makes use of a defined type which runs your exec. Then just iterate over your hash automatically with create_resources(), which converts a hash into a set of resources and adds them to the catalog. This function makes it easy to create many resources from a Hiera data-source at once instead of having to write your own looping function. It is best used with defined types, as they can be implemented many different times.

I've adapted their example for your purposes:

define run_my_exec($serv_name, $serv_hostname, $test_url) {
  notify { "$serv_name": }
}

$server_conf = hiera_hash('myclass::server_conf', {})
create_resources( run_my_exec, $server_conf )

Also, using an exec in puppet is a code smell. Not that it's always bad, but often it's the least elegant way to solve the problem. For instance, is this exec configuring your server? If so, perhaps using a template to write the configuration file would be better. Here's another perspective on execs from the puppet docs for that type:

A caution: There’s a widespread tendency to use collections of execs to manage resources that aren’t covered by an existing resource type. This works fine for simple tasks, but once your exec pile gets complex enough that you really have to think to understand what’s happening, you should consider developing a custom resource type instead, as it will be much more predictable and maintainable.

Dan Bowling
  • 1,205
  • 1
  • 15
  • 41
  • I need to use exec command to run python script(which creates some configurations on the server using api): python python.py $serv_name $serv_hostname $test_url . Would I be able to run it for the first_serv and second_serv by runing create_resources? – aRTURIUS Jan 24 '16 at 21:16
  • Yes. I'll edit my answer to be more clear about it, but the the create_resource() function iterates over the hash and creates a new instance of the resource with the keys/values inside that hash. So, the example code I gave you will run notify() and output testname and testname2. – Dan Bowling Jan 25 '16 at 17:03
  • I this case i have error: Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Duplicate declaration: Exec[server_config] is already declared in file /etc/puppet/modules/server/master.pp:355; cannot redeclare at /etc/puppet/modules/server/master.pp:355 on node – aRTURIUS Jan 26 '16 at 12:33
  • That's because the name of the exec must be unique every time it is run. Use $name inside its name, that should pull in the key for the hash it's iterating over. – Dan Bowling Jan 26 '16 at 15:33
  • I do not quite understand about the "Use $name inside its name" what do you mean under it? – aRTURIUS Jan 26 '16 at 17:34
  • I have added 2 keys $name in 'first_serv' and 'second_serv' and put key $name instead of exec name ? is it correct? Thank you! – aRTURIUS Jan 26 '16 at 18:19
  • When you create a resource (such as exec, file, user, package, whatever) it's name (or title) must be unique. So, package{"My Package Title": ensure => present} is an example. That title in there must be unique, it can never be declared a second time. It's hard to explain this in the comment box without formatting, could you ask another question on SO and just leave a comment with a link to that? I'll answer that with a fuller explanation. It will be better for the community too, since this is really a separate issue. – Dan Bowling Jan 26 '16 at 18:25