Browse Source

implement inspect and onu command

alakiza 2 years ago
parent
commit
3b2fd7a01b
5 changed files with 453 additions and 3 deletions
  1. 150 3
      modules/commands.pm
  2. 96 0
      modules/inspect_bdcom.pm
  3. 80 0
      modules/inspect_cdata.pm
  4. 70 0
      modules/onu_bdcom.pm
  5. 57 0
      modules/onu_cdata.pm

+ 150 - 3
modules/commands.pm

@@ -5,6 +5,10 @@ use Mojo::AsyncAwait;
 use Data::Dumper;
 use purge_cdata;
 use purge_bdcom;
+use inspect_bdcom;
+use inspect_cdata;
+use onu_bdcom;
+use onu_cdata;
 
 our $client;
 
@@ -17,9 +21,121 @@ sub command_help
   my $chatid = shift;
   my $rest = shift;
   
-  notify($chatid, "<b>/purge</b> <i>ip-адрес-устройства номер-дерева</i> - Очистить дерево PON", $rest);
+  notify($chatid, 
+"<b>/purge </b> <i>ip-адрес-устройства номер-дерева</i> - Очистить дерево PON
+<b>/inspect</b> <i>ip-адрес-устройства номер-дерева</i> - Информация об ONU на дереве
+<b>/onu</b> <i>ip-адрес-устройства номер-дерева</i> - Краткая информация ONU на дереве", $rest);
 }
 
+# inspect 172.25.7.1 2 - посмотреть информацию об ONU на дереве 2 устройства 172.25.7.1
+async command_inspect => sub
+{
+  my $cmd = shift;
+  my $args = shift;
+  my $chatid = shift;
+  my $rest = shift;
+
+  my $ip = $args->[0];
+  my $tree = $args->[1];
+
+  return notify($chatid, "Не указан IP-адрес") unless $ip;
+  return notify($chatid, "Не указан номер дерева") unless $tree;
+
+  return notify($chatid, "Неправильный IP-адрес: $ip") unless is_valid_ip($ip);
+
+  my $res;
+  eval {
+    $res = await $client->get_p("device", "/pon?query=ip=\"$ip\"");
+  };
+  return notify($chatid, "Ошибка: " . parse_error($@)) if $@;
+  return notify($chatid, "Устройство с ip=$ip не найдено") if @$res<1;
+  
+  my $dev = $res->[0];
+
+  my $sub;  
+  if ($dev->{type} =~ /^BDCOM/)
+  {
+    $sub = reference("inspect_bdcom");
+  }
+  elsif ($dev->{type} =~ /^C-DATA/)
+  {
+    $sub = reference("inspect_cdata");
+  }
+
+  return notify($chatid, "Неправильный номер дерева: $tree") unless is_valid_tree($dev->{type}, $tree);
+  
+  return notify($chatid, "Устройство $ip '$dev->{name}' неизвестного типа $dev->{type}") unless $sub;
+  
+#  notify($chatid, "Смотрю дерево $tree на устройстве $ip '$dev->{name}'");
+
+  my $text;
+  eval {
+    $text = await $sub->($ip, $dev->{login}, $dev->{password}, $tree);
+  };
+  
+  return notify($chatid, "$ip '$dev->{name}': $@") if $@;
+  
+  notify($chatid, "$ip '$dev->{name}' дерево $tree
+<code>$text</code>");
+
+};
+
+# onu 172.25.7.1 2 - получить короткую информацию об ONU на дереве 2 устройства 172.25.7.1
+async command_onu => sub
+{
+  my $cmd = shift;
+  my $args = shift;
+  my $chatid = shift;
+  my $rest = shift;
+
+  my $ip = $args->[0];
+  my $tree = $args->[1];
+
+  return notify($chatid, "Не указан IP-адрес") unless $ip;
+  return notify($chatid, "Не указан номер дерева") unless $tree;
+
+  return notify($chatid, "Неправильный IP-адрес: $ip") unless is_valid_ip($ip);
+
+  my $res;
+  eval {
+    $res = await $client->get_p("device", "/pon?query=ip=\"$ip\"");
+  };
+  return notify($chatid, "Ошибка: " . parse_error($@)) if $@;
+  return notify($chatid, "Устройство с ip=$ip не найдено") if @$res<1;
+  
+  my $dev = $res->[0];
+
+  my $sub;  
+  if ($dev->{type} =~ /^BDCOM/)
+  {
+    $sub = reference("onu_bdcom");
+  }
+  elsif ($dev->{type} =~ /^C-DATA/)
+  {
+    $sub = reference("onu_cdata");
+  }
+
+  return notify($chatid, "Неправильный номер дерева: $tree") unless is_valid_tree($dev->{type}, $tree);
+  
+  return notify($chatid, "Устройство $ip '$dev->{name}' неизвестного типа $dev->{type}") unless $sub;
+  
+#  notify($chatid, "Смотрю дерево $tree на устройстве $ip '$dev->{name}'");
+
+  my $text;
+  eval {
+    $text = await $sub->($ip, $dev->{login}, $dev->{password}, $tree);
+  };
+  
+  return notify($chatid, "$ip '$dev->{name}': $@") if $@;
+  
+  notify($chatid, "$ip '$dev->{name}' дерево $tree
+<code>$text</code>");
+
+};
+
+
+
+
 # purge 172.1.1.1 2 - почистить дерево 2 на ПОН
 async command_purge => sub
 {
@@ -35,8 +151,7 @@ async command_purge => sub
   return notify($chatid, "Не указан номер дерева") unless $tree;
 
   return notify($chatid, "Неправильный IP-адрес: $ip") unless is_valid_ip($ip);
-  return notify($chatid, "Неправильный номер дерева: $tree") unless $tree =~ /^\d+$/;
-
+  
   my $res;
   eval {
     $res = await $client->get_p("device", "/pon?query=ip=\"$ip\"");
@@ -55,6 +170,8 @@ async command_purge => sub
   {
     $sub = reference("purge_cdata");
   }
+
+  return notify($chatid, "Неправильный номер дерева: $tree") unless is_valid_tree($dev->{type}, $tree);
   
   return notify($chatid, "Устройство $ip '$dev->{name}' неизвестного типа $dev->{type}") unless $sub;
   
@@ -77,6 +194,36 @@ sub is_valid_ip
   return $_[0] =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
 }
 
+sub get_tree_count
+{
+    my $devtype = shift;
+    if ($devtype =~ /^BDCOM P3608/) {
+        return 8;
+    } elsif ($devtype =~ /^BDCOM P3600-08/) {
+        return 8;
+    } elsif ($devtype =~ /^BDCOM P3616/) {
+        return 16;
+    } elsif ($devtype =~ /^BDCOM P3310/) {
+        return 4;
+    } elsif ($devtype =~ /^C-DATA FD1208/) {
+        return 8;
+    } elsif ($devtype =~ /^C-DATA FD1216/) {
+        return 16;
+    }
+
+    return 0;
+}
+
+sub is_valid_tree
+{
+    my $devtype = shift;
+    my $tree_num = shift;
+
+    my $tree_count = get_tree_count($devtype);
+
+    return ($tree_num <= $tree_count)&&($tree_num > 0);
+}
+
 sub parse_error
 {
   my $e = shift;

+ 96 - 0
modules/inspect_bdcom.pm

@@ -0,0 +1,96 @@
+use Modern::Perl;
+use utf8;
+
+use telnet;
+
+sub extract_onu_num {
+    my $onu_name = shift;
+
+    $onu_name =~ m|EPON0/\d+:(\d+)|;
+
+    return $1;
+};
+
+sub extract_onu_info {
+    my @lines = @_;
+
+    return map([substr($_, 0, 11), split(' ', substr($_, 12, -1))], @lines[3..@lines-3]);
+};
+
+async inspect_bdcom => sub
+{
+    my $ip = shift;
+    my $login = shift;
+    my $password = shift;
+    my $tree = shift;
+  
+  ############################
+  
+    my $t = new telnet($ip);
+#  $t->debug(1);
+
+    await $t->connect;
+
+    await $t->reply(qr/Username:/, $login);
+    await $t->reply(qr/Password:/, $password);
+
+    my @greeting = await $t->waitfor(qr/>/);
+    my $version = "C";
+
+    for (@greeting)
+    {
+        $version = $1 if /Welcome to BDCOM P3310(\w)/;
+    }
+
+    $t->print("enable");
+
+    my @next = await $t->waitfor(qr/#|password:/);
+
+    if (grep {$_ =~ /password:/} @next)
+    {
+        $t->print($password);
+        await $t->waitfor(qr/#/);
+    }
+
+    $t->prompt(qr/#/);
+  
+    await $t->cmd("terminal length 0");
+    await $t->cmd("terminal width 200");
+  
+  #######################
+  
+    my @inactive_onu = await $t->cmd("show epon inactive-onu interface ePON 0/$tree");
+    $inactive_onu[0] =~ m|Interface EPON0/\d+ has bound (\d+)|;
+    my $inactive_count = $1 || "?";
+
+    $t->prompt(qr/#/);
+
+    my @active_onu = await $t->cmd("show epon active-onu interface ePON 0/$tree");
+    $active_onu[0] =~ m|Interface EPON0/\d+ has bound (\d+)|;
+    my $active_count = $1 || "?";
+
+    my $total_count = $active_count + $inactive_count;
+
+    $t->close;
+
+    my $res = "Всего: $total_count
+Количество активных ONU: $active_count
+Количество неактивных ONU: $inactive_count
+\n";
+
+    my @in_onu_info = extract_onu_info(@inactive_onu);
+    my @compact_in_onu_info = map( [extract_onu_num(@$_[0]), @$_[1]], @in_onu_info );
+    @compact_in_onu_info = map( join(" ", @$_), @compact_in_onu_info);
+
+    my @a_onu_info = extract_onu_info(@active_onu);
+    my @compact_a_onu_info = map( [extract_onu_num(@$_[0]), @$_[1]], @a_onu_info );
+    @compact_a_onu_info = map( join(" ", @$_), @compact_a_onu_info);
+
+    $res = $res . "Неактивные ONU:\n" . join("\n", @compact_in_onu_info) . "\n\n";
+
+    $res = $res . "Активные ONU:\n" . join("\n", @compact_a_onu_info);
+
+    return $res;
+};
+
+1;

+ 80 - 0
modules/inspect_cdata.pm

@@ -0,0 +1,80 @@
+use Modern::Perl;
+use utf8;
+
+use telnet;
+
+sub extract_onu_info {
+    my @lines = @_;
+
+    my @onu_info = @lines[6..@lines-5];
+
+    return map([ split(' ', $_) ], @onu_info );
+};
+
+async inspect_cdata => sub
+{
+    my $ip = shift;
+    my $login = shift;
+    my $password = shift;
+    my $tree = shift;
+  
+    my $t = new telnet($ip);
+    $t->debug(1);
+
+    await $t->connect;
+
+    await $t->reply(qr/User name:/, $login);
+    await $t->reply(qr/User password:/, $password);
+  
+    $t->print("enable");
+    await $t->waitfor("#");
+    $t->prompt(qr/#\s?$/);
+  
+    await $t->cmd("config");
+    await $t->cmd("vty output show-all");
+  
+    $t->print("interface epon 0/0");
+    $t->prompt(qr/#\s?$/);
+    my @lines = await $t->cmd("show ont info $tree all");
+  
+#    say Dumper @lines;
+#    say Dumper @lines[2];
+
+    my $onu_count_line = @lines[@lines-3];
+
+    $onu_count_line =~ m|Total: (\d+), online (\d+)|;
+    my $total_onu_cnt   = $1;
+    my $online_onu_cnt  = $2;
+    my $offline_onu_cnt = $total_onu_cnt - $online_onu_cnt;
+
+    $t->close;
+
+    if (@lines[2] =~ /Error/) {
+        $total_onu_cnt   = 0;
+        $online_onu_cnt  = 0;
+        $offline_onu_cnt = 0;
+    }
+
+    my @onu_info = extract_onu_info(@lines);
+
+#    say Dumper @onu_info;
+
+    my @online_onu = grep { @$_[5] =~ "online" }  @onu_info;
+    @online_onu = map join(' ', @$_[2,3]), @online_onu;
+
+    my @offline_onu = grep { @$_[5] =~ "offline" }  @onu_info;
+    @offline_onu = map join(' ', @$_[2,3]), @offline_onu;
+
+    my $res = "Всего: $total_onu_cnt
+Количество активных ONU: $online_onu_cnt
+Количество неактивных ONU: $offline_onu_cnt
+\n";
+
+    $res = $res . "Неактивные ONU:\n" . join("\n", @offline_onu) . "\n\n" if $offline_onu_cnt;
+
+    $res = $res . "Активные ONU:\n" . join("\n", @online_onu) if $online_onu_cnt;
+
+    return $res;
+};
+
+1;

+ 70 - 0
modules/onu_bdcom.pm

@@ -0,0 +1,70 @@
+use Modern::Perl;
+use utf8;
+
+use telnet;
+
+async onu_bdcom => sub
+{
+    my $ip = shift;
+    my $login = shift;
+    my $password = shift;
+    my $tree = shift;
+  
+  ############################
+  
+    my $t = new telnet($ip);
+#  $t->debug(1);
+
+    await $t->connect;
+
+    await $t->reply(qr/Username:/, $login);
+    await $t->reply(qr/Password:/, $password);
+
+    my @greeting = await $t->waitfor(qr/>/);
+    my $version = "C";
+
+    for (@greeting)
+    {
+        $version = $1 if /Welcome to BDCOM P3310(\w)/;
+    }
+
+    $t->print("enable");
+
+    my @next = await $t->waitfor(qr/#|password:/);
+
+    if (grep {$_ =~ /password:/} @next)
+    {
+        $t->print($password);
+        await $t->waitfor(qr/#/);
+    }
+
+    $t->prompt(qr/#/);
+  
+    await $t->cmd("terminal length 0");
+    await $t->cmd("terminal width 200");
+  
+  #######################
+  
+    my @inactive_onu = await $t->cmd("show epon inactive-onu interface ePON 0/$tree");
+    $inactive_onu[0] =~ m|Interface EPON0/\d+ has bound (\d+)|;
+    my $inactive_count = $1 || "?";
+
+    $t->prompt(qr/#/);
+
+    my @active_onu = await $t->cmd("show epon active-onu interface ePON 0/$tree");
+    $active_onu[0] =~ m|Interface EPON0/\d+ has bound (\d+)|;
+    my $active_count = $1 || "?";
+
+    my $total_count = $active_count + $inactive_count;
+
+    $t->close;
+
+    my $res = "Всего: $total_count
+Количество активных ONU: $active_count
+Количество неактивных ONU: $inactive_count
+\n";
+
+    return $res;
+};
+
+1;

+ 57 - 0
modules/onu_cdata.pm

@@ -0,0 +1,57 @@
+use Modern::Perl;
+use utf8;
+
+use telnet;
+
+async onu_cdata => sub
+{
+    my $ip = shift;
+    my $login = shift;
+    my $password = shift;
+    my $tree = shift;
+  
+    my $t = new telnet($ip);
+    $t->debug(1);
+
+    await $t->connect;
+
+    await $t->reply(qr/User name:/, $login);
+    await $t->reply(qr/User password:/, $password);
+  
+    $t->print("enable");
+    await $t->waitfor("#");
+    $t->prompt(qr/#\s?$/);
+  
+    await $t->cmd("config");
+    await $t->cmd("vty output show-all");
+  
+    $t->print("interface epon 0/0");
+    $t->prompt(qr/#\s?$/);
+    my @lines = await $t->cmd("show ont info $tree all");
+  
+    #say Dumper @lines;
+
+    my $onu_count_line = @lines[@lines-3];
+
+    $onu_count_line =~ m|Total: (\d+), online (\d+)|;
+    my $total_onu_cnt   = $1;
+    my $online_onu_cnt  = $2;
+    my $offline_onu_cnt = $total_onu_cnt - $online_onu_cnt;
+
+    $t->close;
+
+    if (@lines[2] =~ /Error/) {
+        $total_onu_cnt   = 0;
+        $online_onu_cnt  = 0;
+        $offline_onu_cnt = 0;
+    }
+
+    my $res = "Всего: $total_onu_cnt
+Количество активных ONU: $online_onu_cnt
+Количество неактивных ONU: $offline_onu_cnt
+\n";
+
+    return $res;
+};
+
+1;