#!/usr/bin/perl

use strict;
use warnings;

=head1 DESCRIPTION

=encoding utf8

    Запустить одну и ту же команду на всех нодах кластера redis. 

    Полезно для:
    массового forget:
    redis-iterate ppcback01f.yandex.ru 6380 cluster forget 10327afa0ab53658d6f0c421c136fa6ffc1e02ff
    массового запроса статуса:
    redis-iterate ppcback01f.yandex.ru 6380 cluster nodes

=cut

use Getopt::Long;

run() unless caller();

sub run
{
    my $opts = parse_options();

    my $nodes_addrs_str=qx!redis-cli -h $opts->{host_to_begin} -p $opts->{port_to_begin} cluster nodes | grep -v handshake| awk '{print \$2}'!;
    my @nodes_addrs = split /\s+/, $nodes_addrs_str;

    for my $addr (@nodes_addrs){
        $addr =~ /^(.*):([^:]+)$/;
        my $host = $1;
        my $port = $2;
        print "\n\nhost $host port $port\n";

        my $cmd = "redis-cli -h $host -p $port @{$opts->{cmd}}";
        print "$cmd\n";
        unless ($opts->{dry_run}){
            my $e = system($cmd);
            print "exit code = $e\n";
        }
    }
}

sub parse_options
{
    my %O;
    GetOptions(
        "h|help" => sub {system("podselect -section NAME -section DESCRIPTION $0 | pod2text"); exit 0;},
        "n|dry-run" => \$O{dry_run},
    ) || die "can't parse options";

    if ( scalar(@ARGV) < 3 ){
        die "too few params; expecting <host> <port> <cmd>; stop\n";
    }

    $O{host_to_begin} = shift @ARGV;
    $O{port_to_begin} = shift @ARGV;

    die "bad host $O{host_to_begin}, stop\n" unless $O{host_to_begin} =~ /^[a-z0-9\.:\-]+$/i;
    die "bad port $O{port_to_begin}, stop\n" unless $O{port_to_begin} =~ /^[0-9]+$/;

    $O{cmd} = [@ARGV];
    die "bad command @{$O{cmd}}, stop\n" if grep { !/^[a-z0-9 ]+$/ } @{$O{cmd}};

    return \%O;
}

