On 2014-11-06 15:27, Igor Galić wrote:
Hi folks,
over the last couple of days I've been dabbling with the design
for a new module for Apache httpd: we use our own package & module
currently, which allows for multi-instance configurations, but are
trying to shift towards "standard" Ubuntu 2.4 package (I created a
ppa with a current version:
https://launchpad.net/~apache-helpdesk/+archive/httpd-ppa )
I've been hitting a snag in the design, because httpd and many of
its modules are complex beasts, and I don't want to try and foresee every
single directive someone might want to use in templates / (defined) type / class
but rather have some form of matcher. Since most of the directives follow
simple patterns, I'd like to handle those, and reject everything else -
rather than handling everything explicitly as is the case now.
For a defined type, or a class, we could introduce the special variables
`$_` and `$*` (I'm not happy with those names. They are short, that's nice
but otherwise, they are too Perlesque, and not very speaking)
define httpd::mod (
$ensure = 'enabled',
$instance = 'default',
$* # all others
) {
validate_re($ensure, 'enabled|disabled')
Match {
/_enabled$/ => { validate_bool($_) }
/_path$/ => { validate_absolute_path($_) }
/s$/ => { validate_array($_) }
/_size$/ => { validate_number($_) }
default => { fail("${name} We really don't know what to make of this
directive") }
}
}
alternatively, we could match the front part:
define httpd::directory (
$ensure = 'present',
$instance = 'default',
$*
) {
# …
Match {
/(proxy|ssl|..)_/ => { httpd::mod { $1: ensure => $ensure, instance =>
$instance, $* }
}
}
This is kind of the basic idea, and it's lacking a good way to transform those
matches into actual variables we can access, but I hope you get the basic idea.
The main reason I wish this was supported syntax, is that a
$catch_all_other_settings
hash generally translates poorly through all the layers of
yaml -> ruby -> puppet dsl -> actual config. The chances for very specific
failures
are very high simply because of the amount of layers, each of which can
introduce
their own implementation leak.
Highly welcome your feedback!
Having what is essentially a "call by name" support varargs can be made
by sticking any excess attribute assignments into a hash and assigning
the constructed hash when the resource is instantiated.
In Puppet 4.0 (and in 3.7 with --parser future) you will have the
ability to also type the argument. There is a Struct type that can
validate ha hash with keys where data has different type. It does not
(yet at least) support defining keys with regexps. That could be added.
Later in the 4.x series we plan to introduce the ability to create
complex types and give them names (makes it easier to use complex types).
Also in 3.7 future/4.0 is the ability to use varargs in lambdas using a
splat '*' notation. Currently this implementation does not allow defines
and classes to use varargs. If we do, the syntax will be:
define something ($x, *$y) {}
and if you also add in typing, you get
define something (String $x, Struct[{ a=>Integer, b=>String}] *$y) { }
I can imagine extending the Struct type to allow keys to be regular
expressions, or the Enum type (list of given keys).
Yet more options when we allow creation of arbitrary types (including
non resource types), is to simply pass around an instance of a Struct
(essentially a hash with defined keys / types).
Regards
- henrik
--
Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/
--
You received this message because you are subscribed to the Google Groups "Puppet
Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/puppet-dev/lnaacj%2472u%241%40ger.gmane.org.
For more options, visit https://groups.google.com/d/optout.