4

I'm trying to set a crontab's weekday in hiera based on a custom fact and a basic modulo but I can't even figure out if it's possible.

I'd like to do something like:

  cron-job:
    command:  "do something"
    user:    myuser
    hour:    "%{::instance}"
    minute:  "%{::instance}"
    weekday: "%{::instance}" % 7

Can that even be done?

Alex Harvey
  • 14,494
  • 5
  • 61
  • 97
jercra
  • 394
  • 6
  • 18

2 Answers2

4

No, this is not possible. Please keep in mind that the YAML is just data, not code.

Hiera does offer some transformations using Interpolation Tokens, but there are only two functions that you can use with these, no arithmetics.

Felix Frank
  • 8,125
  • 1
  • 23
  • 30
  • Sadly that's what I figured. I also tried to use interpolation to look up from a list but that doesn't work either. Was hoping for something like: weekday: "%hiera('my.lookup.val.)${::instance}" so that the hiera function would lookup my.lookup.val.01 for instance 01 but that doesn't work either. I'll either need to go with instance in my hiera config or use a module I guess. – jercra Mar 02 '15 at 03:04
  • 1
    Do create defined types that accept raw data from hiera as their parameters, and perform the required transformations for you. – Felix Frank Mar 02 '15 at 09:45
  • 1
    Yeah, I do that for a couple of other things. It's a hoop to jump through that I was hoping to avoid. Lookup_cron and Cac_cron here I come. Thank you for the suggestion. – jercra Mar 02 '15 at 14:55
1

I'm not sure I follow the use case, but you could probably get away with using inline_epp or inline_template to make it look like this feature exists.

For example:

# In real usage this would be the result of a hiera lookup
$simple_lookup_result = '9 % 7'
$simple_evaluated = inline_template("<%= ${simple_lookup_result} %>")

exec { 'simple':
  command => "/bin/echo $simple_evaluated",
  logoutput => true,
}

# Again, hiera...
$complex_lookup_result = 'sprintf("The value is %i", 9 % 7)'
$complex_evaluated = inline_template("<%= ${complex_lookup_result} %>")

exec { 'complex':
  command => "/bin/echo $complex_evaluated",
  logoutput => true,
}

And the results:

$ puppet apply eval.pp 
Notice: Compiled catalog for box in environment production in 0.06 seconds
Notice: /Stage[main]/Main/Exec[simple]/returns: 2
Notice: /Stage[main]/Main/Exec[simple]/returns: executed successfully
Notice: /Stage[main]/Main/Exec[complex]/returns: The value is 2
Notice: /Stage[main]/Main/Exec[complex]/returns: executed successfully
Notice: Applied catalog in 0.05 seconds

Keep in mind that Hiera can interpolate variables or Hiera lookups, and lookups can also be done within the code that inline_epp or inline_template will ultimately evaluate.

N.B. that this is an example, and you shouldn't pass Hiera input into a shell command unless you trust your users and really like headaches.

GargantuChet
  • 5,691
  • 1
  • 30
  • 41
  • Interpreting data as code -- what could possibly go wrong? I much prefer the approach Felix presented in a comment on his answer: put the logic in a defined type, whose parameters you populate with the Hiera data. And that's even easier now, in Puppet 5, than it was in the versions available when that answer was written. – John Bollinger Aug 22 '18 at 21:41
  • This came up in the Google results for using formulas in Hiera so I wanted to share the technique. Example use case: say I want to size the swap partition based on a default formula (RHEL's sizing recommendations, for example), but the app groups have their own idea for which formula to use and even what factors to base it on. I couldn't think of a way to fully generalize it while still using Hiera to drive configuration, but am open to suggestions. – GargantuChet Aug 23 '18 at 07:44
  • I'm not hearing anything that couldn't be achieved with data as data (albeit perhaps more of it) and a for-purpose defined type. – John Bollinger Aug 23 '18 at 13:15
  • I'm not sure how you'd set a base-level default and let the various configuration layers override it unless you use Hiera to drive which purpose-defined type is used on a particular host. Certainly this isn't appropriate when you can come up with likely parameters. But I think of Puppet modules as an API and Hiera data as input to that API. Sometimes you really want to take a callback function, instead of telling the consumer to subclass. – GargantuChet Aug 23 '18 at 16:04