use Modern::Perl; use utf8; use telnet; use Mojo::AsyncAwait; use Data::Dumper; sub cdata_extract_onu_info { my @lines = @_; my @onu_info = @lines[6..@lines-5]; return map([ split(' ', $_) ], @onu_info ); }; async cdata_login => sub { my $t = shift; my $login = shift; my $password = shift; 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"); }; async cdata_get_onu_info => sub { my $t = shift; my $tree = shift; await $t->cmd("interface epon 0/0"); my @lines = await $t->cmd("show ont info $tree all"); 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; if ($lines[2] =~ /Error/) { $total_onu_cnt = 0; $online_onu_cnt = 0; $offline_onu_cnt = 0; } await $t->cmd("exit"); my @onu_info = cdata_extract_onu_info(@lines); my @online_onu = grep { @$_[5] =~ "online" } @onu_info; @online_onu = map [@$_[2,3]], @online_onu; my @offline_onu = grep { @$_[5] =~ "offline|powerdown" } @onu_info; @offline_onu = map [@$_[2,3]], @offline_onu; my %res = ( 'total_cnt' => $total_onu_cnt, 'active_cnt' => $online_onu_cnt, 'inactive_cnt' => $offline_onu_cnt, 'active' => [ @online_onu ], 'inactive' => [ @offline_onu ], ); return %res; }; async cdata_inspect => sub { my $ip = shift; my $login = shift; my $password = shift; my $tree = shift; my $t = new telnet($ip); # $t->debug(1); await cdata_login($t, $login, $password); my %onu_info = await cdata_get_onu_info($t, $tree); # say Dumper \%onu_info; $t->close; my $res = "Всего: $onu_info{'total_cnt'} Количество активных ONU: $onu_info{'active_cnt'} Количество неактивных ONU: $onu_info{'inactive_cnt'} \n"; $res = $res . "Неактивные ONU:\n" . join("\n", map( join(" ", @$_), @{$onu_info{'inactive'}} ) ) . "\n\n"; $res = $res . "Активные ONU:\n" . join("\n", map( join(" ", @$_), @{$onu_info{'active'}} ) ); return $res; }; async cdata_onu => sub { my $ip = shift; my $login = shift; my $password = shift; my $tree = shift; my $t = new telnet($ip); # $t->debug(1); await cdata_login($t, $login, $password); my %onu_info = await cdata_get_onu_info($t, $tree); $t->close; my $res = "Всего: $onu_info{'total_cnt'} Количество активных ONU: $onu_info{'active_cnt'} Количество неактивных ONU: $onu_info{'inactive_cnt'} \n"; return $res; }; async cdata_purge => sub { my $ip = shift; my $login = shift; my $password = shift; my $tree = shift; my $save = shift; my $t = new telnet($ip); # $t->debug(1); await cdata_login($t, $login, $password); my %onu_info = await cdata_get_onu_info($t, $tree); if ($onu_info{'inactive_cnt'} == 0) { $t->close; return "Нечего чистить."; } say Dumper \%onu_info; await $t->cmd("interface epon 0/0"); foreach my $i ( @{$onu_info{'inactive'}} ) { say Dumper @$i[0]; my $onu_num = @$i[0]; my @tmp = await $t->cmd("ont delete $tree $onu_num"); say Dumper @tmp; } await $t->cmd("exit"); my @deleted_onu = map( join(" ", @$_), @{$onu_info{'inactive'}}); %onu_info = await cdata_get_onu_info($t, $tree); if ($save) { await $t->cmd("save"); } $t->close; my $res = "Осталось ONU: $onu_info{'total_cnt'}\n"; if ( $onu_info{'active_cnt'} != $onu_info{'total_cnt'} ) { $res = $res . "Общее количество ONU и количество активных ONU не совпадает. Лучше обратиться к Вашему системноу администратору\n"; } $res = $res . "Удалённые ONU:\n" . join("\n", @deleted_onu) if @deleted_onu > 0; return $res; }; 1;