234 lines
7.8 KiB
Perl
234 lines
7.8 KiB
Perl
# Automatically enables "strict", "warnings", "utf8" and Perl 5.10 features
|
|
use Mojolicious::Lite;
|
|
use Net::SSH::Perl;
|
|
use Data::Printer;
|
|
use Try::Tiny;
|
|
use File::Slurp qw(:std);
|
|
use JSON;
|
|
|
|
my $config = plugin 'Config';
|
|
# Datei einlesen
|
|
my $fi = read_file( 'sshcron.json', err_mode => "quiet");
|
|
my $daten = [];
|
|
if ( $fi ) {
|
|
$daten = decode_json($fi);
|
|
}
|
|
# Route with placeholder
|
|
get '/' => sub {
|
|
my $c = shift;
|
|
$c->render(template => 'index', da => $daten );
|
|
};
|
|
|
|
# Route with placeholder
|
|
any '/jobs/:new/:server' => {new => '', server => ''} => sub {
|
|
my $c = shift;
|
|
my $j = $c->req->json;
|
|
my $new = $c->stash('new');
|
|
my $server = $c->stash('server');
|
|
|
|
if ( $j->{new} && $j->{server} ) {
|
|
$server = $j->{server};
|
|
$new = $j->{new};
|
|
}
|
|
|
|
my @servers;
|
|
my @neline;
|
|
my %se;
|
|
my @allserver;
|
|
|
|
# bei angabe der richtigen Parameter ...
|
|
if ( $new =~ /upd|del/ && $server ne "" ) {
|
|
for my $old ( @{$daten} ) {
|
|
if ( $server eq 'alle' ) {
|
|
if ( !$se{$old->{server}} ) {
|
|
$se{$old->{server}} = 1;
|
|
push @servers, $old->{server};
|
|
}
|
|
} elsif ( defined $old->{server} && $old->{server} ne $server ) {
|
|
push @neline, $old;
|
|
}
|
|
}
|
|
|
|
if ( $new eq "upd" ) {
|
|
if ( $server ne "alle" ) {
|
|
push @servers, $server;
|
|
}
|
|
|
|
for my $ser ( @servers ) {
|
|
try {
|
|
my $ssh = Net::SSH::Perl->new($ser, options => [ "MACs +hmac-sha1" ]);
|
|
$ssh->login('root', '8-Tung');
|
|
|
|
my($stdout, $stderr, $exit) = $ssh->cmd("grep -rHv '##' '/etc/cron.d'");
|
|
|
|
next if ( defined $stderr );
|
|
for my $text ( split '\n', $stdout ) {
|
|
my @s = split ':', $text;
|
|
|
|
if ( scalar(@s) == 1 || $s[1] =~ /$config->{ignore}/ ) {
|
|
|
|
} else {
|
|
my $status = "Ja";
|
|
if ( $s[1] =~ /^#/ ) {
|
|
$status = "Nein";
|
|
}
|
|
|
|
my @file = split( '/', $s[0]);
|
|
my @j = split( ' ', $s[1]);
|
|
|
|
my $pro = "";
|
|
if (scalar(@j) > 6) {
|
|
|
|
for my $p ( 6 .. scalar(@j)-1 ) {
|
|
if ($p == scalar(@j)-1 ) {
|
|
$pro .= "$j[$p]";
|
|
} else {
|
|
$pro .= "$j[$p] ";
|
|
}
|
|
}
|
|
if (scalar(@s) > 2 ) {
|
|
for my $p ( 2 .. scalar(@s)-1 ) {
|
|
$pro .= ":$s[$p]";
|
|
}
|
|
}
|
|
push @neline, { datei => $file[scalar(@file)-1], user => $j[5], min => $j[0] =~ s/#//r , std => $j[1], day => $j[2], month => $j[3], monthday => $j[4], programm => $pro, server => $ser, status => $status };
|
|
}
|
|
}
|
|
}
|
|
} catch {
|
|
push @neline, { datei => '', user =>'', min => '', std => '', day => '', month => '', monthday => '', programm => 'error', server => $ser, status => '' };
|
|
};
|
|
}
|
|
}
|
|
# schreiben der neuen Daten in JSON Datei
|
|
write_file('sshcron.json', encode_json(\@neline) );
|
|
$daten = \@neline;
|
|
}
|
|
my %s;
|
|
|
|
for my $old ( @{$daten} ) {
|
|
if ( !$s{$old->{server}} ) {
|
|
$s{$old->{server}} = 1;
|
|
push @allserver, $old->{server};
|
|
}
|
|
}
|
|
# p $daten;
|
|
if ( $j->{new} && $j->{server} ) {
|
|
$c->render(json => { rc => 0, msg => 'OK' });
|
|
} else {
|
|
$c->render(template => 'jobs', da => $daten , server => \@allserver);
|
|
}
|
|
};
|
|
|
|
# Start the Mojolicious command system
|
|
app->start;
|
|
__DATA__
|
|
|
|
@@ index.html.ep
|
|
% layout 'index';
|
|
<div class="container-fluid">
|
|
<h3>zeigt, holt Cronjobs aus cron.d</h3>
|
|
<h5>/jobs/:upd|del/:server</h5>
|
|
</div>
|
|
|
|
@@ jobs.html.ep
|
|
% layout 'index';
|
|
<div class="container-fluid">
|
|
|
|
<div class="menu col-6 px-3">
|
|
<select class="form-control-sm server">
|
|
% for my $d ( @$server ) {
|
|
<option value="<%= $d %>"><%= $d %></option>
|
|
% }
|
|
</select>
|
|
<button id="refresh" class="btn btn-secondary fas fa-sync" type="button"></button>
|
|
<button id="del" class="btn bt-sm btn-secondary fas fa-trash" type="button"></button>
|
|
</div>
|
|
|
|
<table id="tbl" class="table table-striped table-bordered table-sm nowrap" style="width:100%">
|
|
<thead>
|
|
<tr>
|
|
<th>activ</th>
|
|
<th>server</th>
|
|
<th>min</th>
|
|
<th>hour</th>
|
|
<th>day</th>
|
|
<th>month</th>
|
|
<th>monthday</th>
|
|
<th>user</th>
|
|
<th>file</th>
|
|
<th>program</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
% for my $d ( @{$da} ) {
|
|
<tr>
|
|
<td><%= $d->{status} %></td>
|
|
<td><%= $d->{server} %></td>
|
|
<td><%= $d->{min} %></td>
|
|
<td><%= $d->{std} %></td>
|
|
<td><%= $d->{day} %></td>
|
|
<td><%= $d->{month} %></td>
|
|
<td><%= $d->{monthday} %></td>
|
|
<td><%= $d->{user} %></td>
|
|
<td><%= $d->{datei} %></td>
|
|
<td><%= $d->{programm} %></td>
|
|
</tr>
|
|
%}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
@@ layouts/index.html.ep
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>MyApp</title>
|
|
% my $htlib = 'omv';
|
|
%= stylesheet "http://$htlib/htlib/bootstrap/4.3.1/css/bootstrap.min.css"
|
|
%= stylesheet "http://$htlib/htlib/fontawesome/5.7.2/css/all.css"
|
|
%= stylesheet "http://$htlib/htlib/jquery-datatables/1.10.19/css/dataTables.bootstrap4.min.css"
|
|
%= stylesheet "http://$htlib/htlib/jquery-datatables/extensions/Scroller/1.5.0/css/scroller.bootstrap4.min.css"
|
|
|
|
<style>
|
|
div.dataTables_wrapper div.dataTables_filter {
|
|
text-align: unset;
|
|
}
|
|
</style>
|
|
|
|
<!-- Jquery / Datatables -->
|
|
%= javascript "http://$htlib/htlib/jquery/jquery-3.3.1.js"
|
|
%= javascript "http://$htlib/htlib/bootstrap/4.3.1/js/bootstrap.bundle.min.js"
|
|
%= javascript "http://$htlib/htlib/jquery-datatables/1.10.19/js/jquery.dataTables.min.js"
|
|
%= javascript "http://$htlib/htlib/jquery-datatables/extensions/Scroller/1.5.0/js/dataTables.scroller.min.js"
|
|
</head>
|
|
<body>
|
|
<%= content %>
|
|
<script>
|
|
$(document).ready(function() {
|
|
$('#tbl').DataTable({
|
|
scrollY: '85vh',
|
|
deferRender: true,
|
|
scroller: true,
|
|
});
|
|
$('#tbl_filter > label').addClass('ml-auto pr-3');
|
|
$('#tbl_filter').addClass('row pt-3');
|
|
$('.menu').prependTo('#tbl_filter')
|
|
|
|
$('#del').on('click', function() {
|
|
var c = confirm('Einträge für Server löschen (JOBs werden NICHT auf dem Server gelöscht)');
|
|
if (c) {
|
|
$.post('/jobs/', JSON.stringify({ new: 'del', server: $('.server option:selected').val() }), function(){
|
|
location.reload();
|
|
} )
|
|
}
|
|
})
|
|
$('#refresh').on('click', function() {
|
|
$.post('/jobs/', JSON.stringify({ new: 'upd', server: $('.server option:selected').val() }), function(){
|
|
location.reload();
|
|
} )
|
|
})
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |