If you use Cisco networking gear, you might be familiar with CDP.
CDP is a Cisco proprietary protocol that issues packets from a Cisco switch
to all attached devices.
When you're on a Cisco device, you can detect neighboring switches and routers
and what port they're plugged in to using CDP.
There's also a Linux tool called cdpr which will briefly listen on a
port for CDP
packets from the switch. (http://www.monkeymental.com/)
I just use the stock Ubuntu package and it works like a champ.
example output:
# cdpr -d eth0
cdpr - Cisco Discovery Protocol Reporter
Version 2.2.1
Copyright (c) 2002-2006 - MonkeyMental.com
Using Device: eth0
Waiting for CDP advertisement:
(default config is to transmit CDP packets every 60 seconds)
Device ID
value: switchZZ.foo.com
Addresses
value: 10.20.22.6
Port ID
value: GigabitEthernet0/6
What's great here, is that cdpr is telling me what switch the host is
plugged in to,
and what port on that switch.
The cdpr package also has options for reporting to a central server,
but that's what I use puppet for, right?
So I just cron a nightly cdpr run. (not that I move ports that often,
but it's a simple thing to grab from time to time),
and then I wrote a facter fact to roll these stats back up in to the
puppet yaml.
I'm not a ruby master, but the following did the trick:
------------------------------------------
# Facter fact to read output from cdpr and report back values
require 'facter'
cdprfile = '/tmp/cdpr.out'
f = File.new(cdprfile)
parseme = f.read.gsub(/\n/,' ')
f.close
switch = parseme.gsub(/.*Device ID\s+value:\s+(\S+)\s.*/,'\1')
port = parseme.gsub(/.*Port ID\s+value:\s+(\S+)\s.*/,'\1')
if switch.length > 40
switch = ''
end
if port.length > 40
port = ''
end
# Debug
#print "Switch:\t", switch, "\n"
#print "Port:\t", port, "\n"
Facter.add("cdp_device") do
setcode do
switch
end
end
Facter.add("cdp_port") do
setcode do
port
end
end
------------------------------------------
So after I add this fact to fact sync with puppet I can just walk my
yaml and get a mapping
of server to switch ports..
Over-simplified walk example:
# grep cdp /var/lib/puppet/yaml/node/*
/var/lib/puppet/yaml/node/widgetXX.foo.com.yaml: cdp_port: GigabitEthernet0/9
/var/lib/puppet/yaml/node/widgetXX.foo.com.yaml: cdp_device: switch25-1.foo.com
/var/lib/puppet/yaml/node/widgetYY.foo.com.yaml: cdp_port: GigabitEthernet0/33
/var/lib/puppet/yaml/node/widgetYY.foo.com.yaml: cdp_device: switch22-1.foo.com
I hope some other network/sysadmin types find this useful.
Cheers,
Joel
Netomata Config Generator (NCG) creates complete, ready-to-install config files for network devices and services from a common lightweight model of your network. Because these config files are generated programmatically (rather than by hand), and generated from a shared model (rather than being managed separately for each device or service), they are more likely to be consistent and complete, which makes your network more reliable, easier to troubleshoot, and easier to expand in both size and functionality.
The inputs to NCG are a model describing your network (neto and neto_table files), and templates (ncg files) for the config files of the various devices (routers, swiches, load balancers, firewalls, etc.) and services (SNMP, DNS, DHCP, etc.) that you want to generate config files for. From these inputs, NCG produces complete, consistent, ready-to-install config files for those devices and services.