Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
8350a0d
Merge pull request #2 from bdelano/bdedit
bdelano Nov 16, 2018
f22f0dd
updates readme
bdelano Nov 16, 2018
ee213c7
updates readme
bdelano Nov 16, 2018
75426d6
adds module paths
bdelano Nov 16, 2018
b6bef4b
updates readme
bdelano Nov 16, 2018
ae138d6
updates readme
bdelano Nov 16, 2018
50a046f
cleans up argument input
bdelano Nov 16, 2018
3ea1806
adds additional interface details and does some cleanup
bdelano Nov 19, 2018
5fd365f
adds mgmt ip lookup
bdelano Nov 21, 2018
70ecbd9
changes ipddress to array instead of the mess it was
bdelano Nov 21, 2018
29e0fb0
adds module to build object from rancid directories
bdelano Nov 23, 2018
dc0fe44
various bug fixes
bdelano Nov 23, 2018
a093bd6
updates README
bdelano Nov 24, 2018
213162c
cleans up some minor issues
bdelano Nov 28, 2018
09c6065
adds interfaces back to force10
bdelano Nov 29, 2018
4f81d4e
adds vlan information
bdelano Dec 5, 2018
f3fea6f
adds patch information
bdelano Dec 5, 2018
1df10dc
adds opengear template
bdelano Dec 5, 2018
3a2bde0
fixes software version capture
bdelano Dec 5, 2018
646a5f3
removes die on no matching vendor
bdelano Dec 5, 2018
afbd408
removes suffix from patch
bdelano Dec 5, 2018
6d2ba66
removes comma, easier than fixing other things
bdelano Dec 5, 2018
c3d5a0a
adds support for multiple patches
bdelano Dec 5, 2018
bb4c023
fixes missing software versions
bdelano Dec 5, 2018
7878326
adds interface vlan number to vlan list
bdelano Dec 13, 2018
831ea98
rebuilds how nat information is captured
bdelano Dec 17, 2018
27d26f7
fixes issues with vlan grouping
bdelano Dec 18, 2018
0c02273
fixes vlan bugs and adds console port
bdelano Jan 16, 2019
1a1ccf3
fixes more bugs with vlan parsing
bdelano Jan 16, 2019
74ae33f
changes default device type names
bdelano Jan 31, 2019
97f16c4
fixes bug with vlan allocations
bdelano Jan 31, 2019
a9a4586
fixes issue with stale configs getting checked
bdelano Feb 19, 2019
2e7be24
another tweak to the interface:vlan capture
bdelano Feb 19, 2019
c9f6b40
adds Arbor support
bdelano Feb 19, 2019
8f367fc
changes interface format to match netbox name
bdelano Feb 19, 2019
5a30df8
adds Arbor support
bdelano Feb 19, 2019
804a480
adds tacacs,snmp,syslog info
bdelano Apr 23, 2019
1a3386b
adds check for tacacs accounting
bdelano May 14, 2019
3f35d64
fixes issues with snmp remote ip capture
bdelano May 20, 2019
03f8ab3
fixes stupid bug caused by using stupid global vars in packages, need…
bdelano Jun 29, 2019
c885a0e
gets changes in line with local
bdelano Sep 18, 2019
952ea4c
adds additional device role regex
bdelano Sep 18, 2019
88f8828
removes global variables
bdelano Sep 19, 2019
405623e
updates opengear config
bdelano Jun 17, 2020
2a92b46
various changes to clean up information
bdelano Oct 8, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions Arbor.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package CFG2JSON::Arbor;
use strict;
use NetAddr::IP;
use Data::Dumper;
my $gbics;

sub new{
$gbics=();
my $class = shift;
my $args = { @_ };
my $config=$args->{config};
my $dev=getinfo($config);
#print Dumper $gbics;
my $interfaces=getinterfaces($config);
#my $interfaces={};
$dev->{interfaces}=$interfaces;
my $self = bless {device=>$dev}, $class;
}

sub getinfo{
my @config=split("\n",$_[0]);
my $obj={};
for(@config){
$obj->{model}=$1 if $_=~/# System Board Model: (.*)/i;
$obj->{version}=$1 if $_=~/# Version: Peakflow SP (.*)/i;
$obj->{serial}=$1 if $_=~/# Chassis Serial Number: (.*)/i;
$obj->{processor}=$1 if $_=~/# Processor: (.*)/i;
if($_=~/# (Slot [\d]+): (.*?): (.*)/i){
my $slot=lc($1);
my $key=lc($2);
my $val=lc($3);
$key=~s/serial number/serial/;
$key=~s/model/part_id/;
$slot=~s/\s+//;
if($key=~/firmware|type/){
$obj->{slots}{$slot}{description}=$obj->{slots}{$slot}{description}." $val";
}else{
$obj->{slots}{$slot}{$key}=$val;
}
$obj->{slots}{$slot}{name}=$slot;
#$obj->{slots}{$slot}{manufacturer}='arbor';
}elsif($_=~/# Memory Device: ([\d]+.*)\s(DIM.*)/i){
$obj->{dimms}{$2}{description}=$1;
$obj->{dimms}{$2}{name}=$2;
#$obj->{memory}{$2}{manufacturer}='arbor';
}
}
$obj->{model}=$obj->{slots}{slot1}{model} if $obj->{slots} && $obj->{model} eq 'Not Specified';
return $obj;
}

sub getinterfaces{
my ($intchunk,$ints);
for(split("\n",$_[0])){
$intchunk.=$1."<nl>" if $_=~/^#INT:(.*)/i;
}
$intchunk=~s/\s+(eth|tms|mgt)/<interface>$1/g;
my @i_arr=split(/<interface>/,$intchunk);
shift @i_arr;
for(@i_arr){
my @intinfo=split("<nl>",$_);
my $intbase=shift @intinfo;
#print "intbase:$intbase \n";
my ($int,$inttype,$status,$mtu)=($1,$3,$4,$5) if $intbase=~/((eth|tms|mgt)[\d\.]+)\s(.*), Interface is (.*), mtu ([\d]+)/i;
$inttype=~s/\s+//g;
$ints->{$int}{mtu}=$mtu;
$ints->{$int}{status}=$status;
if($int=~/.*\..*/){
$ints->{$int}{formfactor}='virtual';
}else{
$ints->{$int}{formfactor}=getFF($inttype);
}
for(@intinfo){
$ints->{$int}{localmac}=lc($1) if $_=~/.*Hardware: ([\w\:]+)/;
if($_=~/Inet: ([\d\.]+) netmask ([\d\.]+) .*/){
my ($ip,$bits)=_getCIDR($1,$2);
push(@{$ints->{$int}{ipaddress}},{ip=>$ip,bits=>$bits,type=>'interface',version=>'4'}) if $ip ne '0.0.0.0';
}elsif($_=~/Inet6: (.*) prefixlen ([\d]+)/){
push(@{$ints->{$int}{ipaddress}},{ip=>$1,bits=>$2,type=>'interface',version=>'6'});
}
}
}
return $ints;
}
sub getFF{
my $ff->{TenGigabitEthernet}='SFP+10G-SR';
$ff->{TenGigabitFiber}='SFP+10G-SR';
$ff->{GigabitFiber}='SFP1000BASE-SX';
$ff->{GigabitEthernet}='10/100/1000BASETX';
return $ff->{$_[0]};
}

sub _getCIDR{
my ($ip,$mask)=@_;
my $ninet = new NetAddr::IP "$ip $mask";
my $bits=$ninet->masklen;
return ($ip,$bits);
}

1
147 changes: 141 additions & 6 deletions Arista.pm
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package Arista;
package CFG2JSON::Arista;
use strict;
use Data::Dumper;
my $modules;

sub new{
my ($class,$args)=@_;
$modules=();
my $class = shift;
my $args = { @_ };
my $config=$args->{config};
$modules=buildModuleHash($config);
addGBICS() if $modules->{mods};
my $dev=getinfo($config);
my $interfaces=getinterfaces($config);
#my $interfaces={};
$dev->{interfaces}=$interfaces;
$dev->{modules}=$modules->{mods};
my $self = bless {device=>$dev}, $class;
}

Expand All @@ -18,34 +25,162 @@ sub getinfo{
$obj->{serial}=$1 if $_=~/!Serial number:\s+(.*)/i;
$obj->{model}=$1 if $_=~/!Model: Arista\s+(.*)/i;
$obj->{version}=$1 if $_=~/!Software image version:\s+(.*)/i;
$obj->{taaccounting}=$1 if $_=~/aaa accounting commands (.*)/i;
push(@{$obj->{syslog}},$2) if $_=~/logging( vrf MGMT)? host ([\d\.]+)/i;
push(@{$obj->{snmp}},$1) if $_=~/snmp-server host ([\d\.]+)( vrf MGMT)? version/i;
push(@{$obj->{tacacs}},$1) if $_=~/!tacacs-server host ([\d\.]+)/i;
if($_=~/!(.*)\.swix\s+([\d\.\/]+)\\\s+([\w]+),\s([\w]+)\s+.*/i){
my $patch;
$patch->{file}=$1;
$patch->{version}=$2;
$patch->{status}=$3.'-'.$4;
push(@{$obj->{patch}},$patch);
}
}
return $obj;
}

sub buildModuleHash{
my $c = shift;
$c =~ s/\n/<nl>/g;
my $ret;
for(split(/!System has/,$c)){
if($_=~/.*(transceiver slots)|(card slots)/){
for(split(/<nl>/,$_)){
if($_=~/!\s+([\d\/]+.*)/){
my @list=split(/\s+/,$1);
if($list[1] eq 'Not'){
$ret->{gbics}->{$list[0]}{vendor}='none';
$ret->{gbics}->{$list[0]}{model}='none';
$ret->{gbics}->{$list[0]}{serial}='none';
}else{
$ret->{gbics}->{$list[0]}{description}='vendor:'.$list[1];
$ret->{gbics}->{$list[0]}{part_id}=$list[-3];
$ret->{gbics}->{$list[0]}{serial}=$list[-2];
$ret->{gbics}->{$list[0]}{name}=$list[0];
}
}elsif($_=~/!\s+(Linecard([\d]+).*)/){
my $lcn=$2;
my @list=split(/\s+/,$1);
if($list[1] ne 'Not'){
$ret->{mods}->{$list[0]}{cardname}=$list[0];
$ret->{mods}->{$list[0]}{cardnumber}=$lcn;
$ret->{mods}->{$list[0]}{model}=$list[1];
$ret->{mods}->{$list[0]}{partnumber}=$list[1];
$ret->{mods}->{$list[0]}{version}=$list[2];
$ret->{mods}->{$list[0]}{serial}=$list[3];
$ret->{mods}->{$list[0]}{vendor}='Arista';
$ret->{mods}->{$list[0]}{devicerole}='LineCard';
}
}
}
}
}
return $ret;
}

sub addGBICS{
my $c = shift;
for my $m (keys %{$modules->{mods}}){
my $card=$modules->{mods}{$m}->{cardnumber};;
for my $gb (keys %{$modules->{gbics}}){
my @gbns=split('/',$gb);
if($card eq $gbns[0] && $modules->{gbics}{$gb}{serial} ne 'none'){
my $gbic=$modules->{gbics}{$gb};
$gbic->{port}=$gb;
$modules->{mods}{$m}{gbics}{$gb}=$gbic;
}
}
}
}

sub getinterfaces{
my $c = shift;
my $ints;
$c =~ s/\n/<nl>/g;
$c =~ s/\n/<nl>/ig;
$c =~ s/\s+!//ig;
$c =~ s/([\w])!/$1/ig;
my @ints_arr=split("!",$c);
shift @ints_arr;
for(@ints_arr){
my $int=$_;
if(lc($int)=~/<nl>interface\s+([fskpmvlgibrtortchanel\d\-\/\.]+[\d])\s?<nl>\s?(.*)/ig){
if($int=~/<nl>interface\s+([fskpmvlgibrtortchanel\d\-\/\.]+[\d])\s?<nl>\s?(.*)/ig){
my $i=$1;
my $rc=$2;
$ints->{$i}{rawconfig}=$rc;
push(@{$ints->{$i}{vlans}},$1) if $i=~/Vlan([\d]+)/;
if($i=~/(Vlan|Loop)/i){
$ints->{$i}{formfactor}='virtual';
}elsif($i=~/port-/i){
$ints->{$i}{formfactor}='lag';
}elsif($i=~/.*\.[\d]+$/){
#print "match:$i\n";
$ints->{$i}{formfactor}='virtual';
}else{
my $bi=$i;
$bi=~s/Ethernet//;
$bi=~s/\/1$//;
#print "i:$i bi:$bi\n";
if($modules->{gbics}->{$bi}{model}){
$ints->{$i}{formfactor}=$modules->{gbics}->{$bi}{model};
$ints->{$i}{serial}=$modules->{gbics}->{$bi}{serial};
}elsif($i=~/management/){
$ints->{$i}{formfactor}='1000BaseTX';
}else{
$ints->{$i}{formfactor}='physical';
}
}
$ints->{$i}{mtu}='1500';
$rc=~s/!<nl>router$//i;
for(split/<nl>/,$rc){
my $l=$_;
$ints->{$i}{description}=$1 if $l=~/\s+description\s([!\"\'():,\@.&\w\s\/\-]+).*$/i;
$ints->{$i}{ipaddress}=$1 if $l=~/\s+ip\saddress\s([.\d]+\/[\d]+).*$/i;
push(@{$ints->{$i}{ipaddress}},{ip=>$1,bits=>$2,type=>'interface',version=>'4'}) if $l=~/\s+ip\saddress\s([\d]+\..*)\/([\d]+)$/;
$ints->{$i}{vrf}=$1 if $l=~/\s+vrf forwarding (.*)/i;
$ints->{$i}{mtu}=$1 if $l=~/\s+mtu\s([\d]+)/i;
if($l=~/encapsulation dot1q vlan ([\d]+)/i){
push(@{$ints->{$i}{vlans}},$1);
$ints->{$i}{mode}='sub';
}
if($l =~ m/\s+switchport\saccess\svlan\s([\d]+.*)$/){
push(@{$ints->{$i}{vlans}},$1);
$ints->{$i}{mode}='access';
}
if($l =~ /\sswitchport\strunk\sallowed\svlan\s(add\s)?([-,\d.*]+)$/){
$ints->{$i}=addGroups($ints->{$i},$2);
$ints->{$i}{mode}='tagged';
}
if($l=~/\s+channel-group\s([\d]+)\smode active/){
$ints->{$i}{parent}='Port-Channel'.$1;
push(@{$ints->{'Port-Channel'.$1}{children}},$i);
}
}
}
}
$ints->{console}{formfactor}='NONE';
return $ints;
}

sub addGroups{
my ($int,$info)=@_;
my @p_arr;
for(split(/,/,$info)){
my $pn=$_;
if($pn=~/([\d]+\/)?([\d]+)-([\d]+\/)?([\d]+)/){
my $i1s=$1;
my $i1p=$2;
my $i2s=$3;
my $i2p=$4;
for($i1p...$i2p){
my $p=$i1s.'/'.$_;
$p=$_ if !$i1s;
push(@{$int->{vlans}},$_)
}
}else{
push(@{$int->{vlans}},$pn)
}
}
return $ints
return $int;
}

1
31 changes: 31 additions & 0 deletions BuildList.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package CFG2JSON::BuildList;
use strict;
use FindBin;
use lib $FindBin::Bin;
use File::Slurp;

sub new{
my ($class,$args) = @_;
my ($devlist,$sitelist)=_buildList($args->{rancidpath},$args->{custhash});
$args->{devlist}=$devlist;
$args->{sitelist}=$sitelist;
my $self = bless $args , $class;
}

sub _buildList{
my ($path,$custhash)=@_;
my ($devlist,$sitelist);
for(split("\n",`ls -1 $path`)){
my $site=$_;
my $cust='default';
$cust=$custhash->{$site} if $custhash->{$site};
push(@{$sitelist->{$cust}},{sitename=>$site,rancidpath=>$path});
for(split("\n",`cat $path/$_/router.db`)){
my $hn=lc($1) if $_=~/(.*?);.*/i;
push(@{$devlist->{$cust}},{sitename=>$site,rancidpath=>$path,hostname=>$hn})
}
}
return ($devlist,$sitelist);
}

1;
Loading