On Friday, February 1, 2013 8:16:12 AM UTC-6, Bernhard Schmidt wrote: > > --- > require 'facter' > require 'facter/util/ip' > > if not FileTest.exists?("/usr/sbin/lldpctl") > nil > end >
That last bit probably doesn't do what you want. That is to say, it evaluates to nil in every case (implicitly when the condition is not satisfied), and has no effect on anything else in the fact implementation. Perhaps you meant to put the rest of the body in an 'else' clause? Or, reverse the sense of the test and put everything else inside the condition? > > config = Hash[] > output = Facter::Util::Resolution.exec("/usr/sbin/lldpctl -f keyvalue") > > if output == "" > nil > end Again, a not-what-you-intended conditional statement. In this case, it's probably altogether unnecessary. > > for line in output.split("\n") do > # Drop Multiline > if line =~ /^lldp/ > key, value = line.split('=') > prefix, int, key2 = key.split('.', 3) > if not config.has_key?(int) > config[int] = Hash[] > end > config[int][key2] = value > end > end > More idiomatic Ruby might be: # This hash automatically creates appropriate new # entries as needed: config = Hash.new { |h, k| h[k] = Hash.new } output.lines.grep(/^lldp/).each do |line| # note the 'chomp': key, value = line.chomp.split('=') prefix, int, key2 = key.split('.', 3) config[int][key2] = value end Other than the "chomp", however, I don't think that will change the results. > for interface in config.keys do > Facter.add("lldp_neighbor_" + Facter::Util::IP.alphafy(interface)) do > setcode do > device = config[interface].fetch('chassis.name', "") > ifdescr = config[interface].fetch('port.descr', "") > ifalias = config[interface].fetch('port.ifalias', "") if device != "" > if ifalias != "" > device + " " + ifalias > else > device + " " + ifdescr > end > end > end > end > end > More idiomatic: config.each_pair do | interface, props | Facter.add("lldp_neighbor_" + Facter::Util::IP.alphafy(interface)) do setcode do device = props.fetch('chassis.name', "") if device != "" # note: although clean and concise, this is not 100% # equivalent to the original if 'port.ifalias' can be present but # empty: device + ' ' + props.fetch('port.ifalias', props['port.descr']) else # default value when device is empty 'no config' end end end end I think that might solve your problem, too. Here's what I think is happening to you: your 'for' loop runs, setting variable 'interface' in turn to each key of the 'config' hash. At each iteration, it creates a block of code that Facter will execute (later) to determine the value of one fact. Ruby blocks are closures, so where yours later reference the value of 'interface' they are getting the then-current value in the context where the block was created. By that time, that's the value after the iteration is done (apparently the last key iterated). I think the rewritten version will solve that problem because at each iteration, the values of the key and (inner) hash are captured as distinct local variables ('interface' and 'props'), very much as if the block passed to 'each_pair' were an independent function. This is a Ruby subtlety, so you have chosen a good example to attempt to expand your understanding of Ruby. 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 puppet-users+unsubscr...@googlegroups.com. To post to this group, send email to puppet-users@googlegroups.com. Visit this group at http://groups.google.com/group/puppet-users?hl=en. For more options, visit https://groups.google.com/groups/opt_out.