Listing 2 config2db
#!/usr/bin/perl
use strict;
use warnings;
use lib 'scripts';
use IO::File;
use NetAddr::IP;
use Cisco::Reconfig;
use MyConfigCDBI;
$|++;
sub version_file { my $f = shift; $f =~ s/\.config$/\.version/; $f }
sub get_version
{
my $fh = new IO::File $_[0];
my $version; # The output of show version
my $class;
unless ($fh)
{
warn "Failed to open version file $_[0]: $!\n";
return (map { 'Could not read version file' } 1 .. 3);
}
do { local $/ = undef; $version = <$fh>; };
close $fh;
my $sw = ($version =~ m/^(.+Software .+ Version .+)$/m)[0]
|| 'Cannot find software version';
my $hw = ($version =~
m/^(cisco .+ (processor .+|bytes of memory\.?))$/mi)[0]
|| 'Cannot find hardware version';
my $sn = ($version =~ m/processor board ID (\w+( \([^\)]+\))?)/mi)[0]
|| 'Cannot find serial number';
if ($version =~ m/cisco\s(Cat6k-|WS-C(29|3[57]|40))/)
{ $class = 'switch' }
elsif ($version =~ /cisco\s(2[56]\d\d|18\d\d
|WS-C65\d\d|17\d\d|CISCO76\d\d)\s/ix)
{ $class = 'router' }
elsif ($version =~ /cisco\sAIR-AP/)
{ $class = 'access-point' }
return ($sw, $hw, $sn, $class);
}
sub get_base_info
{
my %k = map { $_ => $_[0]->get($_) }
('hostname', 'snmp-server contact', 'snmp-server location');
return map { $k{$_} =~ s/^$_\s+//; chomp($k{$_}); $k{$_} } sort keys %k;
}
sub get_interfaces
{
my $config = shift;
my @ifs = ();
for my $if ($config->get('interface')->all())
{
my @container = (($if->text =~ m/interface (\S+)/)[0]);
next unless $container[0];
my $desc = ($if->get('description')->text =~ m/description (.+)$/)[0];
push @container, $desc;
for my $addr ($if->get('ip address'))
{
next if $addr->text =~ m/no ip address/;
next unless $addr->text;
my ($ip, $mask, $class) =
$addr->text =~ m/ip address (\S+) (\S+)\s*(secondary)?/;
$class ||= 'primary';
my $i = NetAddr::IP->new($ip, $mask);
next unless $i;
push @container, [ $i, $class ];
}
push @ifs, \@container;
}
return @ifs;
}
MyConfig::CDBI->connection('dbi:SQLite:dbname=config.db');
for my $c (@ARGV)
{
my $config = readconfig($c);
my ($dev, $loc, $ctc) = get_base_info($config);
if (not defined $dev)
{
warn "$c does not define a device host name\n";
next;
}
my $vc = version_file($c);
my ($sw, $hw, $sn, $cl) = get_version($vc);
# Populate our devices table
my $device = MyConfig::CDBI::Device->find_or_create(
device => $dev,
location => $loc,
contact => $ctc,
serial => $sn,
hardware => $hw,
software => $sw,
class => $cl
);
# Extract the interfaces from the configuration
for my $if (get_interfaces($config))
{
my $ifname = lc shift @$if;
my $desc = shift @$if;
print "$c $device $ifname\n";
my $interface = MyConfig::CDBI::Interface->find_or_create(
interface => $ifname,
device => $dev,
description => $desc
);
for my $ip (@$if)
{
my $subnet = MyConfig::CDBI::Subnet->find_or_create(
cidr => $ip->[0]->network->cidr,
first => scalar $ip->[0]->network->numeric,
last => scalar $ip->[0]->broadcast->numeric,
);
my $address = MyConfig::CDBI::Address->find_or_create(
ip => scalar $ip->[0]->numeric,
interface => lc $interface->interface,
device => $device->device,
cidr => $subnet->cidr,
type => $ip->[1],
);
}
}
} |