• Publicidad

Problema de intermitencia con módulo Net::Telnet::Cisco

Aquí encontrarás todo lo que sea específicamente acerca de módulos de Perl. Ya sea que estás compartiendo tu módulo, un manual o simplemente tienes una duda acerca de alguno.

Problema de intermitencia con módulo Net::Telnet::Cisco

Notapor jero2528 » 2016-03-30 15:31 @688

Saludos Perleros.

Tengo inconvenientes con la ejecución de un script en Perl que ejecuta tres comandos sobre equipos Cisco, los cuales dependen uno del otro, de manera que si el comando 1, no se ejecuta, no se puede seguir ya que el comando 2 se arma de acuerdo a la salida generada por el primero; de igual forma sucede con el tercer comando.

El problema es que algunas veces el script se ejecuta de forma correcta y otras veces se detiene ya que alguno de los comandos ejecutados no genera la salida que se espera. ¿Por qué sucede esto? ¿Cómo puedo resolver este inconveniente?

La salida del script cuando se ejecuta sin problemas es la siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. [root@miserver ~]# /usr/local/scripts/findipservicescisco.pl
  2. Wed Mar 30 19:22:28 UTC 2016
  3. C1 show ip route 190.60.215.408
  4. C2: show ip route 190.60.124.190
  5. C3 show run inter GigabitEthernet0/1.6087
  6. (190.60.215.408,65661,COMPANY,29)
  7. update subnets set serviceid = 65661, Customer = 'COMPANY' where subnet = 3191658288 and mask = 29
  8. Wed Mar 30 19:22:30 UTC 2016
  9. [root@miserver ~]#
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

¡Qué alegría que funcionara! :D Pero luego borré los datos que actualiza el script en la base de datos para volver a ejecutar lo mismo y la salida es la siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. [root@miserver ~]# /usr/local/scripts/findipservicescisco.pl
  2. Wed Mar 30 19:26:50 UTC 2016
  3. C1 show ip route 190.60.215.408
  4. C2: show ip route 190.60.124.190
  5. Wed Mar 30 19:26:52 UTC 2016
  6. [root@miserver ~]#
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Es decir: que la salida del comando 2 (C2) no fue la esperada para poder ejecutar el Comando 3.

He probado indicando el timeout a la ejecución de los comandos, he usado las opciones de print() y wait_for() pero el resultado es el mismo siempre y no solo me ha ocurrido en este script sino en algunos otros.

Comparto el código para que por favor alguien me ayude a resolver este lío:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. @conn1 = conectar_telnet_cisco( $IPDEVICE, $userbackupsdefault, $passbackupsdefault );
  2. if ( ( $conn1[0] ) ) {
  3.     $mensajeerror = "Equipo=$DEVICE, IP=$IPDEVICE, Descripcion=$conn1[0]\n";
  4. }
  5. else {
  6.     $query01
  7.         = "select id, subnet, mask from subnets where serviceId is null and mastersubnetid not in (0, 1, 2, 3, 4) and subnet=3191658288 group by subnet";
  8.     $r_query01 = $mysql_glpi01->selectall_arrayref("$query01");
  9.     foreach $row_r_query01 (@$r_query01) {
  10.         ( $id, $ip, $mask ) = @$row_r_query01;
  11.         $idFather = &findFather($id);
  12.  
  13.         #print "Father: $idFather\n";
  14.         if ( $idFather == 1 ) {
  15.             $ip      = `php /usr/local/scripts/ip2long.php $ip long2ip`;
  16.             $command = "show ip route $ip";
  17.             print "C1 $command \n";
  18.             $ipnextjump = "";
  19.             @out = $conn1[1]->cmd( String => "$command\n", Timeout => 10 );
  20.             for my $salida (@out) {
  21.                 if ( $salida =~ /\*\s+((?:\d+\.){3}\d+)/i ) {
  22.                     $ipnextjump = $1;
  23.                 }
  24.             }
  25.             $interface = "";
  26.             if ( $ipnextjump =~ /(?:\d+\.){3}\d+/ ) {
  27.                 $commandnext = "show ip route $ipnextjump";
  28.                 print "C2: $commandnext \n";
  29.                 @out = $conn1[1]->cmd( String => "$commandnext\n", Timeout => 10 );
  30.                 for my $salida (@out) {
  31.                     if ( $salida =~ /\*.+?via\s+(\w+\/\d+\.\d+)/i ) {
  32.                         $interface = $1;
  33.                     }
  34.                 }
  35.             }
  36.             if ( $interface =~ /\w+\/\d+\.\d+/ ) {
  37.                 $commandDesc = "show run inter $interface";
  38.                 print "C3 $commandDesc \n";
  39.                 @out = $conn1[1]->cmd( String => "$commandDesc\n", Timeout => 10 );
  40.                 for my $salida (@out) {
  41.                     if ( $salida =~ /description\s+(\d+(?:\*\d+)?)/i ) {
  42.                         ( $servicio, $subservicio ) = split( /\*/, $1 );
  43.                         unless ($subservicio) { $subservicio = 0; }
  44.                         $cliente = &getClient($servicio);
  45.                         print "($ip,$servicio,$cliente,$mask) \n";
  46.                         &updateService( $ip, $servicio, $cliente, $mask );
  47.                         &insertLog( $ip, $servicio, $mask );
  48.  
  49.                         #&insertStaticIp($dataS[$i]{'ipservicio'}, $servicio, $subservicio, $dataS[$i]{'maskservicio'}, $dataS[$i]{'interface'});
  50.                     }
  51.                 }
  52.             }
  53.         }
  54.     }
  55. }
  56. cerrar_telnet_cisco( $conn1[1] );
  57.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


De antemano, muchas gracias a cualquiera que me pueda ayudar con este problema. Cada vez es más frecuente y cada día que pasa es un reto poder trabajar con ello. Por cierto, la versión de Perl que uso es: This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi sobre un RedHat 6. Mil gracias :roll: :oops: :shock: :idea:
Última edición por explorer el 2016-03-30 16:15 @719, editado 1 vez en total
Razón: Formateado de código con Perltidy
Saludos,

Jero2528
Avatar de Usuario
jero2528
Perlero nuevo
Perlero nuevo
 
Mensajes: 50
Registrado: 2014-05-14 15:43 @697
Ubicación: Bogota, Colombia

Publicidad

Re: Problema de intermitencia con módulo Net::Telnet::Cisco

Notapor explorer » 2016-03-30 16:53 @745

Algunas cosas se pueden cambiar, pero es cuestión de estilo, no de funcionamiento. Yo no veo errores.

Además, si el comando C2 se ejecuta y devuelve lo esperado, y el programa sigue, entonces el problema no está en nuestro programa, sino cuando llega algo inesperado.

Debes realizar cambios en el programa para que guarde la salida de C2 cuando recibamos algo inesperado (puede ser a un archivo de log, por ejemplo. O un archivo de texto. Algo para que quede constancia de qué ha pasado.

Si el problema es que ocurre un timeout y no recibimos nada, podríamos adoptar la táctica de volver a intentar ejecutar el comando C2, para ver si a la segunda, funciona.

Una vez nos pasó, que los aparatos Cisco se actualizaron, y las respuestas a los comandos podrían demorarse mucho, o lo contrario: que ya no eran capaces de procesar comandos a la misma velocidad que se les dábamos.

Hicimos pruebas con esperas sleep(), y resultó en algunos casos. La solución fue ajustar bien el prompt para que Net::Telnet::Cisco supiera perfectamente cuándo ha terminado de ejecutarse el comando anterior.

Aún así, hubo casos de grandes demoras. La solución fue: en caso de error (no hay respuesta del aparato), hacemos una pequeña espera (de entre unas décimas a unos segundos, y luego volvemos a intentar conectarnos al aparato (a veces incluso rehacer toda la conexión) y volver a ejecutar el comando. Si al cabo de 3 o 5 intentos esto no funciona, pues salimos con error.

Lo importante, es que sepas qué es lo que ha pasado: ¿el comando ha devuelto algo o nada? Y si ha devuelto algo, y no es lo esperado, ¿qué aspecto tiene?

JF
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Módulos

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado