On Monday, July 8, 2013 2:56:07 PM UTC-5, Wil Cooley wrote:
>
> I have a case where I need to somehow access a variable in a defined
> type, which is built from the parameters of the defined type (and
> possibly other sources). As far as I can tell, doing this directly is
> not possible, nor have I found a good way to do so indirectly.
>
Doing this is not possible. You need to choose a different approach.
>
> Here's an example:
>
> # hypothetical 3rd-party or internal module
> define openssl_keypair {
> include openssl_keypair::param
>
> $keyfile = "${openssl_keypair::param::keydir}/${title}.key"
> $certfile = "${openssl_keypair::param::certdir}/${title}.crt"
>
> file { $keyfile: ... }
> file { $certfile: ... }
> ...
> }
>
> # 3rd party: torian/ldap
> class ldap::server::master(..., $ssl_cert, $ssl_key, ...) {
> # $ssl_* used in a template, augeas, etc
> # pretend this class does not include file resources for these
> ...
> }
>
> # 3rd party: puppetlabs/apache
> class apache::vhost(..., $ssl_cert, $ssl_key, ...) {
> # likewise
> ...
> }
>
> Now I want to use these:
>
> modules/profile/manifests/ssl_webserver.pp:
> openssl_keypair { 'foo.example.com': }
> apache::vhost { ...
> ssl_cert => '/etc/pki/tls/...', # Damn, gotta hard-code this
> ssl_cert => '/etc/pki/tls/...',
> }
>
> I think you can see where I'm going with this -- the only way to know
> what the former's $keyfile and $certfile are is to somehow refer to
> these variables but from what I can tell, that is not possible.
>
>
The way to do this in Puppet (and not a bad way in general) is for both of
the resources in question to draw their data from a single, common source,
instead of one of them drawing the data from the other. For example:
define site::secure_vhost (...) {
$cert_name = "vhost_${title}"
$cert = "/path/to/cert/${cert_name}"
openssl_keypair { ${cert_name}: }
apache::vhost { ${title}:
...
ssl_cert => $cert
}
}
There, the site::secure_vhost instance not only serves as the common data
source, but directly feeds the data to each of the component resources. If
the common data source is a class (variable) or external data, then you
also have the alternative of the defined type(s) accessing the data
directly from that source.
In some cases, it makes sense to collapse that model by making one resource
the common data source. Doing that with a defined type as the common
source requires that that defined declare all other defined types that need
the data, passing it to them via their parameters. That's usually suitable
only if the common source is a local custom defined type.
> Does anyone see a good way around it, given the current and planned
> future? I considered that there could be a hash-of-hashes somewhere,
> with the openssl_keypair's $title as key and sub-keys for keyfile,
> certfile, but while looking at the 2.7 language spec:
>
> Significant Bugs: Mutability
>
> Due to a bug in Puppet, hashes are mutable — their contents can be
> changed within a given scope. New elements can be added by assigning a
> value to a previously unused key ($myhash[new_key] = "New value"),
> although existing keys cannot be reassigned.
>
> This behavior is considered a bug; do not use it. It will not be
> removed during the Puppet 2.7 series, but may be removed thereafter
> without a deprecation period.
>
>
> http://docs.puppetlabs.com/puppet/2.7/reference/lang_datatypes.html#significant-bugs-mutability-1
>
>
> This section is absent from the reference for v3, so I presume this
> bug was fixed.
>
You can certainly use a hash of hashes somewhere as your common data
source, as long as you don't count on it being mutable. That is, it must
be fully defined when it is declared; your defined types must not rely on
being able to add anything to it. If you use the data to drive which
vhosts are declared, then it's also fairly DRY.
>
> Any ideas? I can imagine doing something really yucky with a function
> or template.
>
>
You can also do this with external data; via hiera, for instance. That's
its purpose.
> Does anyone else see this as useful? Should I open an FR for it? I did
> not find anything already in existence.
>
>
If by "this" you mean accessing the variables of a defined type instance, I
see only limited utility. Such an approach does not fit well into the
Puppet model because it is inherently parse-order dependent. There are
better ways to accomplish the same objectives.
John
--
You received this message because you are subscribed to the Google Groups
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-users.
For more options, visit https://groups.google.com/groups/opt_out.