On Monday, August 20, 2012 11:32:46 AM UTC-5, dkw wrote: > > Hi John: > > Thanks for your comments and instruction. More inline... > > On Fri, Aug 17, 2012 at 02:36:13PM -0700, jcbollinger wrote: > > > # cat common.yaml > > > --- > > > searchdomain : 'example.com' > > > ssh_auth : ldap > > > servers : > > > server-a : > > > sshd_auth: "local" > > > ClientAliveInterval: "nil" > > > ClientAliveCountMax: "nil" > > > server-b : > > > sshd_auth: "local" > > > ClientAliveInterval: "nil" > > > ClientAliveCountMax: "nil" > > > server-c : > > > sshd_auth: "ldap" > > > ClientAliveInterval: "nil" > > > ClientAliveCountMax: "nil" > > > server-d : > > > sshd_auth: "ldap" > > > ClientAliveInterval: "10" > > > ClientAliveCountMax: "3" > > > > > > > > [...] > > > > > > > > > > # cat Inuit.pp > > > class user { > > > $sshd_hash = hiera(servers) > > > create_resources('sshd_lookup', $sshd_hash) > > > > > > > In answer to your first question, about declaring only an sshd_lookup > > resource for server-a, you apparently have a key misunderstanding about > > create_resources(). That function creates one resource of the specified > > type for *each* top-level key in the provided hash. The keys are used > as > > the resource titles, and the values are hashes of parameter key/value > pairs > > for the corresponding resource instance. > > > > If you only want an sshd_lookup resource for server-a, then either you > must > > feed it a hash containing only an entry for server-a, or else you must > > declare the sshd_lookup in the conventional way. For example, instead > of > > the create_resources() call above, use: > > > > $server_a_params = $sshd_hash['server-a'] > > sshd_lookup { 'server-a': > > sshd_auth => $server_a_params['sshd_auth'], > > ClientAliveInterval => > $server_a_params['ClientAliveInterval'], > > ClientAliveCountMax => $server_a_params['ClientAliveCountMax'] > > } > > > I would like to use a hash in conventional way, however, I can't get > that data from a YAML file with puppet DSL, so I understand.
The "conventional way" is to use a standard resource declaration instead of create_resources(). I guess you really mean you want to use create_resources() to declare only one resource. As I described before, to achieve that the hash paramerter you pass to create_resources() must be contain a single key ("server-a") whose associated value is a hash associating each non-default parameter with its assigned value. If your data are structured appropriately for then you can get the needed hash directly or nearly directly from hiera. In particular, the ordinary hiera() function will return a hash if that's the type of value associated with the requested key. If you want each node to have its own sshd-auth info, and no node needs to have any of the others' info, then your data are structured sub-optimally. Node-specific data for different nodes should not generally be co-mingled, nor mixed with shared data. You already have a node-specific level in your hierarchy, so put the needed data there. You could continue to structure it as a hash mapped to a single key, but I would consider just raising the inner keys to the top level, and then using an ordinary resource declaration instead of create_resources(). Any way around, you certainly can build hashes in Puppet DSL, including with use of data obtained via hiera. For example, to obtain the hash you want from the data structure you already have, you should be able to do something like this: $sshd_lookup_data = { "${hostname}" => $sshd_hash["${hostname}"] } > Should > I try go down the road of using ruby DSL and a init.rb for my > manifest, so I can lookup $hostname from client node directly from > the YAML? The goal is to get all configuration data from one YAML > file or database, abstracting the modules/manifest code. > You do not need Ruby DSL to achieve your stated aim, and you should avoid Ruby DSL wherever you don't need it. Hiera can do this job for you, or if you need something custom then I would suggest writing a custom Puppet function (in Ruby) instead of switching to Ruby DSL. I am confused, however. You say that you want all the data in a single file, yet you declare two levels in your Hiera hierarchy, one of them defined per-hostname. Do you just mean you want this particular data all in one file? (Why?) I think it will help you to decouple data source from data usage in your mind. That will align your thinking better with Hiera, as such decoupling / abstraction is the most fundamental aspect of what Hiera does for you in practice. So no, you don't need your manifest to read data from a YAML file; instead, you need it to declare resources of particular types (e.g. Sshd_lookup) based on external data structured in some particular way. As a separate question, you need to configure Hiera and the data sources on which it will rely to define the needed data with the appropriate structure. Moreover, it is usually better to choose data structure based on the needs of your manifests where that is feasible, rather than deciding data structure a priori and having to develop manifests that are adapted for it. Either approach is doable, but usually it is easier to adapt the data structure to the needs of the manifests than the other way around. > > > > > Alternatively, you could construct a single-entry hash of hashes of the > > correct form for create_resources(); I leave that as an exercise. > > I did get a single YAML hash of hashes to work using hiera and > create_resources, where the common.yaml file took over if a $name.yaml > (or $hostname.yaml) file didn't exist. That is not my requirement, > unfortunately. I want to stuff all my server host information into > the hash of hashes inside the YAML file, with the $hostname being > the key. > See above. > > > > > > > > > > > } > > > > > > define sshd_lookup ( $sshd_auth, $ClientAliveInterval, > > > $ClientAliveCountMax, > > > $server_role, $location ) { > > > > > > $data = hiera_hash('servers') > > > $sshd_type = $data[$hostname]['sshd_auth'] > > > > > > > There, you are looking up an entry in the hash by the $hostname of the > > client for which you are compiling the catalog. For any given node, > that > > will result in the same piece of data for every sshd_lookup instance. > > > > If you want the value appropriate for the current resource instance then > > you can either add $sshd_type to the parameter list (since you are > > otherwise just re-reading the same data that you passed to > > create_resources()), or else use $name or $title (they are equivalent in > > this context) to look up the desired entry in the outer hash. ($name > and > > $title in a type definition refer to the title of the resource > instance). > > Can you please illustrate looking up the desired entry in the outer > hash? I have tried many ways and failed in all of them. This is > probably the best way to do it. I will illustrate that momentarily. I suggest, however, that the best way to do it is almost certainly the other alternative I suggested; i.e. something like this: define sshd_lookup ( $sshd_auth, $ClientAliveInterval, $ClientAliveCountMax, $server_role, $location, $sshd_type ) { notice ("setting sshd_type: $sshd_type" ) } I'm rather surprised you're not doing that already. Supposing that there is some reason you haven't told us why you want to look up the data directly in the hash that was already loaded, here is how you would do it: define sshd_lookup ( $sshd_auth, $ClientAliveInterval, $ClientAliveCountMax, $server_role, $location ) { # ensure class User is loaded because we # want to use one of its variables include 'user' $sshd_type = $user::data[$name]['sshd_type'] notice ("setting sshd_type: $sshd_type" ) } > It's data is derived from hiera > and create_resource? > > Though inefficient and maybe not scalable depending on how big the > hash becomes, I tried a conditional based on $name given the results > of all the keys returned from create_resources and it works as I > want it to: > > class user { > $sshd_hash = hiera(servers) > create_resources('sshd_lookup', $sshd_hash) > } > > define sshd_lookup ( $sshd_auth, $ClientAliveInterval, > $ClientAliveCountMax, > $server_role, $location ) { > > $data = hiera_hash('servers') > $sshd_type = $data[$name]['sshd_auth'] > > if $hostname == $name { > > notice "my name is $name" > notice ("setting name: $name" ) > notice ("setting hostname: $hostname" ) > notice ("setting sshd_type: $sshd_type" ) > > # add machine logic > #if ($sshd_type = ldap) { > # include ldap > #} > > #if ${clientaliverinterval} != nil { > #augeas { "clientinterval_modify": > #context => "/files/etc/ssh/sshd_config", > #changes => "set > ClientAliveInterval=${clientaliverinterval}"; > #} > } > > } > > Note that your conditional is absolutely pointless as far as the manifests you have presented to us go. You already know that the condition will always be satisfied if you declare only the one Sshd_lookup instance you want for a given node, because that's the way you have structured the definition and its data. Furthermore, you may be approaching this altogether the wrong way. If it is part of the nature of sshd_lookup that no node will ever need to declare more than one instance, then sshd_lookup should probably be a class instead of a definition: class sshd_lookup { $all_data = hiera_hash('servers') $node_data = $all_data[$hostname] $sshd_auth = $node_data['sshd_auth'] $ClientAliveInterval = $node_data['ClientAliveInterval'] $ClientAliveCountMax = $node_data['ClientAliveCountMax'] $server_role = $node_data['server_role'] $location = $node_data['location'] $sshd_type = $data[$hostname]['sshd_auth'] # ... } All things considered, I think you should take a step back and look at the bigger picture. You seem to be getting mired in the details. I'm not sure whether you inherited this from someone else, whether you have requirements you're not telling us about, or what, but your overall design doesn't seem all that solid. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/BgWWfncIiF8J. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.