Hello,

for the last couple of hours I've been trying to wrap my head around a
problem writing a custom facter plugin and I'm not getting it.

I'm trying to export LLDP neighbors as facter variables. I've already
found https://gist.github.com/1424959 and I'm quite happy with it, so
the issue is not pressing. But I'd like to understand it.

If the neighbor provides an ifAlias (like Cisco) I want to use this,
but if it doesn't I want to use description.

Sidenote: This is my first time with Ruby and it looks quite ugly

First try:
---
require 'facter/util/ip'

Facter::Util::IP.get_interfaces.each do |interface|

  # Make a fact for each detail of each interface.  Yay.
  Facter.add("lldp_neighbor_" + Facter::Util::IP.alphafy(interface)) do
    setcode do
      device = Facter::Util::Resolution.exec("/usr/sbin/lldpctl -f keyvalue " + 
interface + " | grep chassis.name | cut -d '=' -f 2")
      ifdescr = Facter::Util::Resolution.exec("/usr/sbin/lldpctl -f keyvalue " 
+ interface + " | grep port.descr | cut -d '=' -f 2")
      ifalias = Facter::Util::Resolution.exec("/usr/sbin/lldpctl -f keyvalue " 
+ interface + " | grep port.ifalias | cut -d '=' -f 2")
      if device
        if ifalias
          device + " " + ifalias
        else
          device + " "  + ifdescr
        end
      end
    end
  end
end
---

This is highly inefficient, but works

lldp_neighbor_eth0 => swg1-kic B23
lldp_neighbor_eth4 => csr1-kic Gi4/3


Next I wanted to try to parse the whole output to get rid of all the 
spawning

---
require 'facter'
require 'facter/util/ip'

if not FileTest.exists?("/usr/sbin/lldpctl")
  nil
end

config = Hash[]
output = Facter::Util::Resolution.exec("/usr/sbin/lldpctl -f keyvalue")

if output == ""
  nil
end

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

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
---

This errorneously reports the same neighbor for both interfaces

lldp_neighbor_eth0 => csr1-kic Gi4/3
lldp_neighbor_eth4 => csr1-kic Gi4/3

I somehow cannot execute the whole facter plugin using irb, but when I
replace the second part of the script with

---
for interface in config.keys do
  device = config[interface].fetch('chassis.name', "")
  ifdescr = config[interface].fetch('port.descr', "")
  ifalias = config[interface].fetch('port.ifalias', "")
  if device != ""
    if ifalias != ""
      puts interface + " " + device + " " + ifalias
    else
      puts interface + " " + device + " "  + ifdescr
    end
  end
end
---

it does display the right information

eth0 swg1-kic B23
eth4 csr1-kic Gi4/3

Also, if I just open irb and run the first part of the script (the data
collection) the resulting hash looks fine

irb(main):030:0> pp config
{"eth0"=>
  {"via"=>"LLDP",
   "rid"=>"1",
   "age"=>"0 day, 00:51:37",
   "chassis.mac"=>"00:01:e7:df:df:00",
   "chassis.name"=>"swg1-kic",
   "chassis.descr"=>
    "HP J4865A ProCurve Switch 4108GL, revision G.07.109, ROM G.05.02 
(/sw/code/build/gamo(m03))",
   "chassis.mgmt-ip"=>"xxxx",
   "chassis.Bridge.enabled"=>"on",
   "chassis.Router.enabled"=>"off",
   "port.local"=>"47",
   "port.descr"=>"B23"},
 "eth4"=>
  {"via"=>"LLDP",
   "rid"=>"2",
   "age"=>"0 day, 00:47:03",
   "chassis.mac"=>"68:ef:bd:7e:ee:86",
   "chassis.name"=>"csr1-kic",
   "chassis.descr"=>
    "Cisco IOS Software, s72033_rp Software (s72033_rp-ADVIPSERVICESK9_WAN-M), 
Version 12.2(33)SXI2a, RELEASE SOFTWARE (fc2)",
   "chassis.mgmt-ip"=>"xxx.xxx.xxx.xxx",
   "chassis.Bridge.enabled"=>"off",
   "chassis.Router.enabled"=>"on",
   "port.ifalias"=>"Gi4/3",
   "port.descr"=>"Mirror-Port, moni-kic",
   "port.auto-negotiation.supported"=>"no",
   "port.auto-negotiation.enabled"=>"yes",
   "port.auto-negotiation.1000Base-T.hd"=>"no",
   "port.auto-negotiation.1000Base-T.fd"=>"yes",
   "port.auto-negotiation.current"=>"unknown"}}

So something is obviously wrong in my facter part, but I cannot find it. 

I've tried several attempts (like explicitly resetting the variables
in the setcode block), but ...

Help! :-)

Bernhard

-- 
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.


Reply via email to