<%doc> Web interface for device discovery and updates % % <%attr> title => 'Update Device' section => 'Management' % % <%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 => 1 $subs_inherit => 1 $pretend => undef $user => $ui->get_current_user($r) % % %###################################################################### %# %# Initialization %# %###################################################################### <%init> my $DEBUG = 0; my $manager = $ui->get_permission_manager($r); unless ( $manager && $manager->can($user, 'access_admin_section', 'updatedevice.html:new') ){ $m->comp('/generic/error.mhtml', error => "You do not have permission to add new devices"); } 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; 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; # Make sure we don't have a device by this name already if ( my $o = Device->search(name=>$host)->first ){ $argv{device} = $o->id; } 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{contacts} = $contacts || ""; $argv{owner} = $owner; $argv{used_by} = $used_by; $argv{add_subnets} = $add_subnets; $argv{subs_inherit} = $subs_inherit; $argv{site} = $site; 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"); } %###################################################################### %# %# User Interface %# %######################################################################
Device: <% $host %>
%if ( $action eq "discover" ){ % my @allcls = ContactList->retrieve_all; <& /generic/attribute_table.mhtml, field_headers=>["Description"], data=>[ $info->{sysdescription} ] &>
% my (@field_headers, @cell_data) = (); % if ( ! $argv{device} ){ # We're inserting a Device for the first time % % push( @field_headers, "Owner:" ); <&| "/generic/HERE.mhtml" &> [new] % push( @cell_data, $_ ); % push( @field_headers, "Used by:" ); <&| "/generic/HERE.mhtml" &> [new] % push( @cell_data, $_ ); % push( @field_headers, "Site:" ); <&| "/generic/HERE.mhtml" &> [new] % push( @cell_data, $_ ); % push( @field_headers, "Contacts:" ); <&| "/generic/HERE.mhtml" &> Select all that apply % push( @cell_data, $_ ); %################################################################ %# The following block only applies to routers %################################################################ % if ( $info->{ipforwarding} ){ % push( @field_headers, "Add new Subnets (if any)?:" ); <&| "/generic/HERE.mhtml" &> % if ( Netdot->config->get('ADDSUBNETS') ){ % }else{ % } % push( @cell_data, $_ ); % push( @field_headers, "Should new subnets
inherit device owner/user?:" ); <&| "/generic/HERE.mhtml" &> % if ( Netdot->config->get('SUBNET_INHERIT_DEV_INFO') ){ % }else{ % } % push( @cell_data, $_ ); % } % }else{ # We're updating an existing Device %################################################################### %# Ask if changes should not be committed to the DB %################################################################### % push( @field_headers, "Dry Run?:" ); <&| "/generic/HERE.mhtml" &> (Show operations and roll back DB changes) % push( @cell_data, $_ ); % } # endif !$argv{device} <& /generic/attribute_table.mhtml, field_headers=>\@field_headers, data=>\@cell_data &>
 
%}elsif ( $action eq "update" ){ % ########################################################################## % # We filter out the log output to get only lines belonging to this device % # This is because some other process might be logging to this same logger % ########################################################################## % my $log = $logstr->string() ; % my @lines = split /\n/, $log; % my @output = grep /$fqdn/, @lines; % if ( @output ){
%          foreach my $line ( @output ){
<% $line %>
%          }
           

% } [Go to <% $fqdn %>] % }
<%cleanup> if ( defined $logstr ){ Log::Log4perl->eradicate_appender('updatedevice.html') }