for my $cmd (@{$ctxt->{commands}}) { ...
####
use Ops::Exec qw(ops_do_ssh_shell ops_new_context ops_new_cmd);
use Ops::Config qw(ops_get_servers);
my %servers = map { $_ => new_server($_) } ops_get_servers('foo');
my @contexts = map {ops_new_context({
name => $servers{$_}{name},
user => 'foo',
host => $servers{$_}{host},
key => $ENV{HOME} . '/.ssh/id_rsa.foo.prod',
commands => [ ops_new_cmd({ name => 'capacity',
command => 'df -k /home'}),
ops_new_cmd({ name => 'process_type1',
command => 'ps -ef | grep process_type1 | grep -v grep | wc -l'}),
ops_new_cmd({ name => 'process_type2',
command => 'ps -ef | grep process_type2 | grep -v grep | wc -l'})
]
})} sort keys %servers;
for my $ctxt (@contexts) {
if ($local_state->{status} eq 'success') {
my $ctxt_status = ops_do_ssh_shell($ctxt);
for my $cmd_status (@{$ctxt_status->{commands}}) {
if ( $ctxt_status->{success} ) {
$servers{$ctxt_status->{name}}{$cmd_status->{name}} = $cmd_status->{output};
}
else {
$local_state->{status} = 'failure';
$local_state->{stack_trace} = $cmd_status;
}
}
}
}
if ($local_state->{status} eq 'success') {
for my $server (keys %servers) {
$servers{$server}{capacity} = parse_capacity($servers{$server}{capacity});
# further parsing and validation
}
}
# statuses are evaluated to generate warnings and alerts
# texts and emails are sent yadda yadda
####
package Ops::Exec;
use strict;
use warnings;
use Exporter qw(import);
use Data::Dumper;
use Net::OpenSSH;
use Hash::Util qw(lock_ref_keys);
use Clone qw(clone);
our @EXPORT_OK = qw(ops_do_ssh_shell ops_do_ssh_qx ops_new_context ops_new_cmd ops_new_qx_cmd);
use constant SUCCESS => 1;
use constant FAILURE => 0;
sub ops_new_cmd {
my ($init_hash) = @_;
my $new_cmd = {};
lock_ref_keys($new_cmd, qw(name command success output std_err cmd_ret_code cmd_ret_msg));
$new_cmd = clone($init_hash);
$new_cmd->{success} = SUCCESS;
return $new_cmd
}
sub ops_new_context {
my ($init_hash) = @_;
my $new_cmd = {};
lock_ref_keys($new_cmd, qw(name user host key commands success ssh_retcode ssh_retmsg outputs));
$new_cmd = clone($init_hash);
$new_cmd->{success} = SUCCESS;
return $new_cmd
}
sub ops_do_ssh_shell {
my ($ctxt) = @_;
my $ssh;
defined $ctxt->{key} or $ctxt->{key} = $ENV{HOME} . '/.ssh/id_rsa';
if ( $ctxt->{success} ) {
$ssh = Net::OpenSSH->new($ctxt->{host}, user => $ctxt->{user}, key_path => $ctxt->{key});
if ( $ssh->error ) {
$ctxt->{success} = FAILURE;
($ctxt->{ssh_retcode}, $ctxt->{ssh_retmsg}) = (0 + $ssh->error, '' . $ssh->error);
}
}
for my $cmd (@{$ctxt->{commands}}) {
if ( $ctxt->{success} ) {
($cmd->{output}, $cmd->{std_err}) = $ssh->capture2($cmd->{command});
$cmd->{cmd_ret_code} = 0 + $ssh->error;
if ( $cmd->{cmd_ret_code} ) {
$ctxt->{success} = FAILURE;
$ctxt->{cmd_ret_msg} = '' . $ssh->error;
}
chomp $cmd->{output};
chomp $cmd->{std_err};
}
}
return $ctxt;
}
sub ops_new_qx_cmd {
my ($init_hash) = @_;
my $new_cmd = {};
lock_ref_keys($new_cmd, qw(name user host command success output std_err cmd_ret_code cmd_ret_msg ssh_ret_code ssh_ret_msg ssh_cmd_qx));
%$new_cmd = %$init_hash;
$new_cmd->{success} = SUCCESS;
return $new_cmd
}
sub ops_do_ssh_qx {
my ($cmd) = @_;
$cmd->{ssh_cmd_qx} = 'ssh ' . $cmd->{user} . '\@' . $cmd->{host} . ' \'' . $cmd->{command} . '\'' . ' 2>/dev/null';
$cmd->{output} = qx($cmd->{ssh_cmd_qx});
if ( defined $cmd->{output} ) {
$cmd->{cmd_ret_code} = $?;
chomp $cmd->{output};
}
else {
($cmd->{ssh_ret_code}, $cmd->{ssh_ret_msg}) = (0 + $!, '' . $!);
}
return $cmd;
}
"Red Guitar, Three Chords ...";