Ask Your Question
0

merging arrays with the same key

asked 2016-09-29 08:58:54 -0500

gilbo gravatar image

Heya - i've got these in hiera:

profiles::apache::vhosts::vhostsappcommon :
  -  
    docroot: /a/path
    docroot_owner : a user
    docroot_group : a group
    docroot_mode : 'a mode'
    log_level: debug
    ip_based: true
    headers :
      - unset somethingspecific

and:

profiles::apache::vhosts::vhostscommon:
  -
    options : ['FollowSymLinks','MultiViews']
    headers:
      - unset something
      - edit somethingelse
      - always append something
      - set somethingelse
      - set somethingmore
    request_headers:
      - set blah
      - set blah blah
    ssl_protocol : -all +TLSv1.2

now i need to merge these two things to make one default apache config. The question is how do i merge these 2 things successfully so that the nested hash requestheaders includes all values from both arrays. All the merges i've tried so far ditches everything in favour of the right most array's requestheaders values, as per deep_merge's documentation.

Thanks!

edit retag flag offensive close merge delete

4 Answers

Sort by » oldest newest most voted
0

answered 2016-09-29 12:55:13 -0500

lupin gravatar image

updated 2016-09-29 12:55:48 -0500

Did you test it with hiera_array?

edit flag offensive delete link more
0

answered 2016-09-30 06:38:39 -0500

DarylW gravatar image

https://docs.puppet.com/hiera/3.2/loo...

Merge behaviors

There are three merge behaviors available.
•The default native type is described above under “Native Merging.”
•The deep type is largely useless and should be avoided.
•The deeper type does a recursive merge, behaving as most users expect.

In a deeper hash merge, Hiera recursively merges keys and values in each source hash. For each key, if the value is:

However (just above that)

Limitations:
•This currently only works with the yaml and json backends.
•You must install the deep_merge Ruby gem for deep merges to work. If it isn’t available, Hiera falls back to the default native merge behavior. If you’re using Puppet Server, you’ll need to use the puppetserver gem command to install the gem.
•This configuration is global, not per-lookup.

So. for deep/deeper merge to work, you must have the deep_merge rubygem installed, otherwise it just falls back to the 'native' behavior (which you are seeing). You want the 'deeper merge' behavior (as the above quote says, it does a recursive merge, behaving as most users expect)

Hope that helps!

edit flag offensive delete link more
0

answered 2016-09-30 05:25:45 -0500

gilbo gravatar image

updated 2016-09-30 07:38:27 -0500

Hi yes a puppetserver gem list on all my compile masters lists deep_merge. also my hiera config file on all masters states merge behaviour as deeper. I really think I'm running into this caviet (from the documentation you linked me to)

•…an array and exists in two or more source hashes, the values from each source are merged into a single array and de-duplicated (but not automatically flattened, as in an array merge lookup).

as I think request_headers is being interpreted as an array as it's got [] chars round it when I do a notice on the variable ive read it into. I've absolutely no idea how to form it into a nested hash within the hash.

edit flag offensive delete link more

Comments

The only thing that I could think for you to do is to do some sort of hiera_array call specifically for the headers, and then add the arrays together yourself to build a new hash. It seems like a lot of work.. I wonder if there are any issues on the deep_merge gem around merging arrays?

DarylW gravatar imageDarylW ( 2016-09-30 09:12:07 -0500 )edit
0

answered 2016-09-30 05:33:05 -0500

Emerson Prado gravatar image

I used stdlib concat function with good results for merging arrays. But you seem to need to merge hashes, not arrays, correct? If that's the case, merge or deep_merge seem good solutions, also from stdlib. BTW, I think stdlib is a "must-have". Best regards, Emerson

edit flag offensive delete link more

Comments

heya - yes we've got the latest and greatest stdlib installed - and no, the notation above definitely returns the hieras as arrays. I have used merge and deep_merge, but the sticking point is when we get to the headers bit, as they're duplicate keys only one of them "wins", but I want all values.

gilbo gravatar imagegilbo ( 2016-09-30 05:47:19 -0500 )edit

Well, I understand a hash can't have more than one value for a given key, so I guess the solution would be to use a hash as the value for said key in Hiera, then join using **deep merge**, which will then merge all items for the outer hash's key. The example in the stlib page says it all.

Emerson Prado gravatar imageEmerson Prado ( 2016-10-01 10:57:23 -0500 )edit

Your Answer

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

Add Answer

Question Tools

Stats

Asked: 2016-09-29 08:58:54 -0500

Seen: 328 times

Last updated: Sep 30 '16