#!/usr/bin/perl use strict; use warnings; use Getopt::Long qw(:config no_ignore_case bundling); my %opts = ( no_changed => 0, no_unreach => 0, no_failed => 0, ); my $usage = < 0 --no-unreachable|-u don't show where unreachable > 0 --no-failed|-f don't show where failed > 0 EOT GetOptions( "no-changed|c" => \$opts{no_changed}, "no-unreachable|u" => \$opts{no_unreach}, "no-failed|f" => \$opts{no_failed}, "help|h" => sub {print $usage; exit 0} ) or die $usage; my $play = 'n/a'; my $play_printed = 0; my $section = 'n/a'; my $section_printed = 0; my $recap = 'n/a'; my $recap_found = 0; my $recap_printed = 0; while (my $line = ) { if ($line =~ /^PLAY RECAP \**/) { $recap_found = 1; $recap = $line; last; } elsif ($line =~ /^PLAY /) { $play = $line; $play_printed = 0; $section = 'n/a'; $section_printed = 0; } elsif ($line =~ /^(TASK|RUNNING HANDLER) /) { $section = $line; $section_printed = 0; } elsif ($line =~ /^(ok|skipping|included): /) { # skip } elsif ($line !~ /\S/) { # skip } else { if (!$play_printed) { print "\n", $play; $play_printed = 1; } if (!$section_printed) { print "\n", $section; $section_printed = 1; } print $line; } } if (!$recap_found) { die "\nNo 'PLAY RECAP' found or not an ansible-playbook's output.\n"; } while (my $line = ) { next if $line !~ /\S/; if ($line =~ /:\s+ok=\d+\s+changed=(\d+)\s+unreachable=(\d+)\s+failed=(\d+)/) { my ($changed, $unreachable, $failed) = ($1, $2, $3); my $ok = 1; if ($changed and !$opts{no_changed}) { $ok = 0; } if ($unreachable and !$opts{no_unreach}) { $ok = 0; } if ($failed and !$opts{no_failed}) { $ok = 0; } next if $ok; } if (!$recap_printed) { print "\n\n$recap\n"; $recap_printed = 1; } print $line; } # vim: set tabstop=4 shiftwidth=4 expandtab smarttab: