%doc> Web interface for device discovery and updates %doc> % % <%attr> title => 'Update Device' section => 'Management' %attr> % % <%args> $action $device => undef $host => undef $version => undef $comstr => undef $other_comstr => undef $sec_name => undef $sec_level => undef $auth_proto => undef $auth_pass => undef $priv_proto => undef $priv_pass => undef $id => undef $sid => undef $insert => undef $owner => undef $used_by => undef $site => undef $contacts => undef $add_subnets => 0 $subs_inherit => 0 $pretend => undef %args> % % %###################################################################### %# %# Initialization %# %###################################################################### <%init> my $DEBUG = 0; my $o; my $fqdn; my %argv; my $session; my $guessed_user_ent; my $guessed_site; my $guessed_cl; my $info; my $default_owner; my $default_cl; my $logstr; my $dev_exists_notice; print "ARGS contains:
", Dumper(%ARGS), "" if $DEBUG; if( $action eq "discover" && ! $sid ) { eval { $session = $ui->mk_session(); }; if ( my $e = $@ ){ $m->comp('/generic/error.mhtml', error => $e); } } if( $sid ) { eval { $session = $ui->get_session($sid); }; if ( my $e = $@ ){ $m->comp('/generic/error.mhtml', error => $ui->error); } } if ( $action eq "discover" ){ if ( $device ){ # We got a device id, so we're most likely updating my $o = Device->retrieve($device); unless ( $o ){ $m->comp('/generic/error.mhtml', error=>"Could not retrieve Device id: $device"); } $argv{device} = $device; $argv{name} = $o->fqdn; # Fetch SNMP info eval { $info = $o->get_snmp_info(); }; if ( my $e = $@ ){ $m->comp('/generic/error.mhtml', error=>$e); } } elsif ( $host ){ $host =~ s/\s*//g; $argv{version} = $version; if ( $version == 3 ){ foreach my $key ( qw(sec_name sec_level auth_proto auth_pass priv_proto priv_pass) ){ $argv{$key} = $ARGS{$key} if defined $ARGS{$key}; } }else{ # Give preference to the community being passed if ( $comstr eq "Other" ){ $argv{communities} = [$other_comstr] if defined $other_comstr; }else{ $argv{communities} = [$comstr] if defined $comstr; } } # Fetch SNMP info eval { $info = Device->get_snmp_info(host=>$host, %argv); }; if ( my $e = $@ ){ $m->comp('/generic/error.mhtml', error=>$e); } print "info contains:
", Dumper(%$info), "" if $DEBUG; # Check for duplicates # Make sure we don't have a device by this name already if ( my $o = Device->search(name=>$host)->first ){ $argv{device} = $o->id; } # Serial Number + Product elsif( $info->{serialnumber} ){ my %search_args = (serialnumber=>$info->{serialnumber}); if ( $info->{sysobjectid} && (my $product = Product->search(sysobjectid=>$info->{sysobjectid})->first) ){ $search_args{product} = $product; } if ( my $other = Device->search(%search_args)->first ){ $dev_exists_notice = sprintf("At least one other device with this S/N: %s already exists: %s", $other->serialnumber, $other->get_label); if ( Netdot->config->get('ENFORCE_DEVICE_UNIQUENESS') ){ $m->comp('/generic/error.mhtml', error=>$dev_exists_notice); } } } # Base MAC elsif( !$dev_exists_notice && $info->{physaddr} ){ if ( my $physaddr = PhysAddr->search(address=>$info->{physaddr})->first ){ if ( my $other = Device->search(physaddr=>$physaddr)->first ){ $dev_exists_notice = sprintf("At least one other device with this MAC: %s already exists: %s", $physaddr->address, $other->get_label); if ( Netdot->config->get('ENFORCE_DEVICE_UNIQUENESS') ){ $m->comp('/generic/error.mhtml', error=>$dev_exists_notice); } } } } if ( !$argv{device} ) { # Looks like we have to create a new device $argv{name} = $host; # Try to guess the user entity based on the subnet # Note that we're using the first IP address found # So it might not be totally accurate, especially for # routers. LOOP: foreach my $int ( keys %{ $info->{interface} } ){ foreach my $ip ( keys %{ $info->{interface}->{$int}->{ips} } ){ my $mask = $info->{interface}->{$int}->{ips}->{$ip}->{mask}; if ( my $subnetaddr = Ipblock->get_subnet_addr(address=>$ip, prefix=>$mask) ){ if ( my $subnet = Ipblock->search(address=>$subnetaddr)->first ){ if ( my $user_ent = $subnet->used_by ){ $guessed_user_ent = $user_ent; if ( my $cl = $user_ent->contactlist ){ $guessed_cl = $cl->id; }if ( my @entsites = $user_ent->sites ){ $guessed_site = $entsites[0]->site; } last LOOP; #just grab the first one } } } } } # Get the default owner entity from config my $config_owner = Netdot->config->get('DEFAULT_DEV_OWNER'); $default_owner = Entity->search(name=>$config_owner)->first; # If we could not determine it before, # try to guess site based on SNMP location if ( ! $guessed_site ){ if ( my $loc = $info->{syslocation} ){ if ( my $site = Site->search_like(name=>"%$loc%")->first ){ $guessed_site = $site; } } } # Get the default contactlist from config my $config_cl = $ui->config->get('DEFAULT_CONTACTLIST'); $default_cl = ContactList->search(name=>$config_cl)->first; } }else{ $m->comp('/generic/error.mhtml', error => "Discovery needs either device id or hostname"); } # Now store the SNMP info in the session $argv{info} = $info; $session->{argv} = \%argv; }elsif ( $action eq "update" ){ # Add a string log appender # Notice that we intentionally "eradicate" the appender and make sure the string # is not being used (wasting memory) except when this component is called. # We look it up before creating it in case this process ended abruptly earlier. if ( $logstr = Log::Log4perl::appender_by_name('updatedevice.html') ){ Log::Log4perl->eradicate_appender('updatedevice.html'); } $logstr = Netdot::Util::Log->new_appender('String', name=>'updatedevice.html'); my $logger = Netdot->log->get_logger('Netdot::Model::Device'); $logger->add_appender($logstr); my $dns_logger = Netdot->log->get_logger('Netdot::Model::DNS'); $dns_logger->add_appender($logstr); my $ip_logger = Netdot->log->get_logger('Netdot::Model::Ipblock'); $ip_logger->add_appender($logstr); %argv = %{$session->{argv}}; print "argv contains:
", Dumper(%argv), "" if $DEBUG; if ( exists $argv{device} ){ unless ( $o = Device->retrieve($argv{device}) ){ $m->comp('/generic/error.mhtml', error=>"Could not retrieve Device id: $device"); } my %uargs = (info=>$argv{info}, do_info=>1); unless( $uargs{name} = $argv{name} ){ $uargs{name} = $o->fqdn; } $uargs{pretend} = 1 if $pretend; eval { #we use discover here because it will correct the RR for us (if it needs correcting), #if the device has moved it calls snmp_update anyway, so its #really not that different than before. $o = Device->discover(%uargs); }; if ( my $e = $@ ){ $m->comp('/generic/error.mhtml', error=>$e); } }else{ $argv{name} = $host || ""; $argv{owner} = $owner || 0; $argv{used_by} = $used_by || 0; $argv{site} = $site || 0; $argv{contacts} = $contacts || ""; $argv{add_subnets} = $add_subnets; $argv{subs_inherit} = $subs_inherit; eval { $o = Device->discover(%argv); }; if ( my $e = $@ ){ $m->comp('/generic/error.mhtml', error=>$e); } } $fqdn = $o->fqdn; }#endif update else{ $m->comp('/generic/error.mhtml', error => "Unknown action: $action"); } %init> %###################################################################### %# %# User Interface %# %######################################################################
% foreach my $line ( @output ){ <% $line %> % }