Last active
December 11, 2015 04:39
-
-
Save jeremyschulman/4546586 to your computer and use it in GitHub Desktop.
Simple demonstration of "walking LLDP" in a Junos network to create a connection map
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'highline/import' | |
require 'net/netconf/jnpr' | |
start_at = ARGV[0] || begin | |
puts "You need to specify a starting target ip/host" | |
exit 1 | |
end | |
my_username = ENV["USER"] | |
puts "login: #{my_username}" | |
my_password = ask("password: "){|a| a.echo = false} | |
class ScannerLLDP | |
attr_reader :network_lldp, :devices_ip, :devices_nc | |
def initialize( name, password ) | |
@network_lldp = {} | |
@devices_nc = {} | |
@devices_ip = {} | |
@visit_list = [] | |
@login = {} | |
@login[:username] = name | |
@login[:password] = password | |
end | |
def lldp_visit( target_ip ) | |
@login[:target] = target_ip | |
puts "Connecting to #{target_ip} ..." | |
dev = Netconf::SSH.new( @login ) | |
dev.open | |
# record where I am now | |
my_lldp = dev.rpc.get_lldp_local_info | |
my_lldp_name = my_lldp.xpath('lldp-local-system-name').text | |
@devices_nc[my_lldp_name] = dev | |
@devices_ip[my_lldp_name] = target_ip | |
puts "Connected to #{my_lldp_name}" | |
my_cnx_grid = [] | |
# find the places I need to visit | |
nei_nbs = dev.rpc.get_lldp_neighbors_information | |
nei_nbs = nei_nbs.xpath('lldp-neighbor-information') | |
nei_ports = nei_nbs.xpath('lldp-local-interface | lldp-local-port-id') | |
nei_ports.each do |nei| | |
if_name = nei.text | |
# get details on the specific interface | |
rsp = dev.rpc.command "show lldp neighbors interface #{if_name}" | |
if_nei = rsp.xpath('lldp-neighbor-information') | |
rmt_sysname = if_nei.xpath('lldp-remote-system-name').text | |
rmt_ip = if_nei.xpath('lldp-remote-management-address').text | |
puts "found #{rmt_sysname}" | |
my_cnx_grid << { :ifd => if_name, :rmtsys => rmt_sysname } | |
unless @devices_ip[rmt_sysname] | |
puts "--> ADDING #{rmt_sysname}" | |
@devices_ip[rmt_sysname] = rmt_ip | |
@visit_list << rmt_sysname | |
end | |
end | |
@network_lldp[my_lldp_name] = my_cnx_grid | |
dev.close | |
end # lldp_visit | |
def startat( target_ip ) | |
while target_ip | |
lldp_visit( target_ip ) | |
target_ip = @devices_ip[@visit_list.pop] | |
end | |
end | |
def devices | |
@devices_nc.keys | |
end | |
def ncopen( name ) | |
unless ncdev = @devices_nc[name] | |
puts "Invalid name: #{name}" | |
end | |
ncdev.open | |
ncdev | |
end | |
end #class | |
scanner = ScannerLLDP.new( my_username, my_password ) | |
scanner.startat start_at | |
# At this point you can examine the network connectivity | |
# by looking at scanner.network_lldp. | |
# You can connect to any device using scanner.ncopen <name-learned-via-LLDP> | |
# and then perform any RPC as normally done using the NETCONF gem | |
# see https://www.github.com/Juniper-Workflow/net-netconf for more details |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[2] pry(main)> scanner.network_lldp | |
=> {"EX4200-153"=> | |
[{:ifd=>"xe-1/1/1.0", :rmtsys=>"MX240-R132-re0"}, | |
{:ifd=>"xe-0/1/0.0", :rmtsys=>"MX240-R130-re0"}], | |
"MX240-R130-re0"=> | |
[{:ifd=>"xe-2/1/2", :rmtsys=>"EX4200-153"}, | |
{:ifd=>"xe-2/0/2", :rmtsys=>"MX240-R178"}, | |
{:ifd=>"xe-2/0/3", :rmtsys=>"MX240-R176-re0"}, | |
{:ifd=>"xe-2/1/0", :rmtsys=>"MX240-R176-re0"}, | |
{:ifd=>"xe-2/0/0", :rmtsys=>"MX240-R132-re0"}, | |
{:ifd=>"xe-2/0/1", :rmtsys=>"MX240-R132-re0"}], | |
"MX240-R176-re0"=> | |
[{:ifd=>"xe-2/1/0", :rmtsys=>"MX480-R244"}, | |
{:ifd=>"xe-2/1/1", :rmtsys=>"EX4200-139"}, | |
{:ifd=>"xe-2/0/0", :rmtsys=>"MX240-R132-re0"}, | |
{:ifd=>"xe-2/0/1", :rmtsys=>"MX240-R132-re0"}, | |
{:ifd=>"xe-2/0/2", :rmtsys=>"MX240-R130-re0"}, | |
{:ifd=>"xe-2/0/3", :rmtsys=>"MX240-R130-re0"}], | |
"EX4200-139"=>[{:ifd=>"xe-1/1/0.0", :rmtsys=>"MX240-R176-re0"}], | |
"MX480-R244"=>[{:ifd=>"xe-5/0/1", :rmtsys=>"MX240-R176-re0"}], | |
"MX240-R178"=>[{:ifd=>"xe-2/0/0", :rmtsys=>"MX240-R130-re0"}], | |
"MX240-R132-re0"=> | |
[{:ifd=>"xe-2/1/0", :rmtsys=>"EX4200-153"}, | |
{:ifd=>"xe-2/0/2", :rmtsys=>"MX240-R176-re0"}, | |
{:ifd=>"xe-2/0/3", :rmtsys=>"MX240-R176-re0"}, | |
{:ifd=>"xe-2/0/0", :rmtsys=>"MX240-R130-re0"}, | |
{:ifd=>"xe-2/0/1", :rmtsys=>"MX240-R130-re0"}]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment