How to return default hash keys in hiera_hash() call?
You need the hash merge
function from the stdlib module.
merge
: Merges two or more hashes together and returns the resulting hash.Example:
$hash1 = {'one' => 1, 'two' => 2} $hash2 = {'two' => 'dos', 'three' => 'tres'} $merged_hash = merge($hash1, $hash2) # The resulting hash is equivalent to: # $merged_hash = {'one' => 1, 'two' => 'dos', 'three' => 'tres'}
When there is a duplicate key, the key in the rightmost hash "wins."
So in your case
$test = merge( $test_default, hiera_hash(test, {}) )
Note 1
You should use hiera_hash
only if you need to deep-merge hashes from multiple hierarchy layers. I suppose with your approach, you do want that.
Note 2
A flat list of keys is usually easier to handle, and it is also the only way to leverage automatic class parameter lookup. It is a safe practice to adhere to the standard data layout.
Yes, there can be performance implications.
Related videos on Youtube
Comments
-
Simon over 1 year
In an attempt to clean up my client's Hiera data for Puppet, and drastically reduce the number of Hiera calls in the Puppet manifests, I'm changing constructs like
some_name::key1: a_value_1 some_name::key2: a_value_2 [...] some_name::keyX: a_value_X
into
some_name: key1: a_value_1 key2: a_value_2 [...] keyX: a_value_X
So that instead of having X
hiera()
calls, I have only onehiera_hash()
call. This works perfectly until you run into a situation like this:# some_manifest.pp hiera(some_name::key1, default_value_1) hiera(some_name::key2, default_value_2) [...] hiera(some_name::keyX, default_value_X)
The problem here is that I can't find a way to provide default values for all keys in a clean and concise way.
hiera_hash(key_to_be_searched, default_hash)
returns the value ofdefault_hash
ifkey_to_be_searched
isn't found in it's hierarchy. But you can't make it check if a hash (found in the hierarchy) contains (at least) all keys defined indefault_hash
.For example, if I have this bit of hiera data:
test: foo: bar bar: baz
Together with this bit of DSL:
$test_default = { foo => '1', bar => '2', baz => 'foo', } $test = hiera_hash(test, $test_default)
I would expect (or rather, want)
$test
to contain:foo => 'bar', bar => 'baz', baz => 'foo',
But, as far as I can tell, that's not a possibility. What Puppet returns in this example is this:
foo => 'bar', bar => 'baz',
Is there anyone here who has a solution to this problem? In the current environment I estimate the number of Hiera calls in a Puppet run to be reduced anywhere between five- and ten-fold by restructuring the data in the way I want to. It also makes for way cleaner code.
-
c4f4t0r about 9 yearsi'm using something like this and i don't have any problem "hiera_hash('useradmins',{}), i'm using an empty hash as default value and it works, why you say doesn't work?
-
Simon about 9 yearsI didn't say it doesn't work. I'm saying it doesn't do what I want it to do. I want to be able to provide default keys which should always be in the hash even if not defined in the hierarchy. I need this functionality in order to condense the X
hiera()
calls into onehiera_hash()
call, but see no way to actually provide the functionality. Right now the default hash gets returned only if the key I search for is not found in the hierarchy, I want all keys defined in the default hash to be present in the returned hash. -
c4f4t0r about 9 yearsbut you are telling to hiera to looking for test and not count the keys, now i understand what you want, if you find the way :) let me know.
-
-
Simon about 9 yearsThanks for your answer! I do think you switched the array order in the example though. Since the right-most array always wins, I want the data coming from the hiera call to be the rightmost, no?
-
Felix Frank about 9 yearsAbsolutely - my bad. Will update to use the correct merge call.