����JFIF��x�x����'403WebShell
403Webshell
Server IP : 78.140.185.180  /  Your IP : 18.119.0.207
Web Server : LiteSpeed
System : Linux cpanel13.v.fozzy.com 4.18.0-513.11.1.lve.el8.x86_64 #1 SMP Thu Jan 18 16:21:02 UTC 2024 x86_64
User : builderbox ( 1072)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /lib64/nagios/plugins/extra/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /lib64/nagios/plugins/extra/check_image_version
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use Carp;
use JSON::XS;
use LWP::UserAgent;
use IPC::Run qw(run);
use Getopt::Long;

my ( $opt_c, $opt_h );
my $exitcode = '0';

GetOptions(
    "c|containers=s" => \$opt_c,
    "h|help"         => \$opt_h,
);

if ($opt_h) {
    my $help_text = <<"END";
Usage: $0 -c container1,container2,...

Checks the version for active docker containers and compares them to latest on DockerHub
  -c|--containers     List of local containers and image to check, separated by comma
                      Example: fe1_nginx:stable,dev2_gitlab
                      Default value for image tag is latest
  -h|--help (--help)  Show this help message
END
    say $help_text;
    exit;
}

croak 'List of containers not passed!' if !$opt_c;
my @incidents;

my %containers;

for ( split( ',', $opt_c ) ) {
    $containers{ ( split ':', $_ )[0] } = ( split ':', $_ )[1];
}

my $container_regex = ( join "|", keys %containers );

my @containers = (
  split /\n/,
  run_cmd(
    'docker', 'ps', '--no-trunc',
    '--filter=' . "name=($container_regex)",
    '--format', '{{.Names}}'
  )
);

for my $container (@containers) {
    my $container_info =
      decode_json(
        run_cmd(
          'docker',
          'inspect',
          $container
        )
      )->[0];
    my $container_image = ( split /\:/, $container_info->{Image})[1];
    my $image_info =
      decode_json(
        run_cmd(
          'docker',
          'image',
          'inspect',
          $container_image
        )
      )->[0];
    croak 'Cannot obtain image info!' if !$image_info;
    # we are skipping images that do not have remote digest
    next if !$image_info->{RepoDigests}->[0];
    my $container_name = ( split /\@/, $image_info->{RepoDigests}->[0] )[0];
    # we need array here, because image can be updated without changing tag
    # which changes its sha-digest
    # if we have older image with the same tag, pull new image and restart
    # then RepoDigest will contain multiple images
    # smartmatch does the job and is sufficient enough
    my @container_sha =
      map { ( split /\@/, $_ )[1] } @{ $image_info->{RepoDigests} };
    my $url_prefix = 'https://hub.docker.com/v2/repositories/';
    my $remote_url = $url_prefix . $container_name . '/tags/?page_size=100';
    my $remote_images = send_req($remote_url);
    if (!$remote_images) {
        $remote_url =
          $url_prefix .
          'library/' .
          $container_name .
          '/tags/?page_size=100';
        $remote_images = send_req($remote_url);
    }
    croak 'Cannot obtain remote image info!' if !$remote_images;
    my $tag =
    ( map
      {
        if ( $container =~ /$_/ ) { $containers{$_} }
        else { () } 
      }
      keys %containers
    )[0];
    $tag //= 'latest';
    my $found;
    for my $remote_image_info (@{$remote_images}) {
        next if $remote_image_info->{name} ne $tag;
        $found = '1';
        unless ( grep { $remote_image_info->{digest} eq $_ } @container_sha ) {
            push @incidents, "$container_name:$tag has updates on DockerHub!";
            $exitcode = '2';
        }
    }
    if ( !$found ) {
        my ($current_version) = $image_info->{RepoTags}->[0] =~ /:(.+)$/;
        my @actual_version    = split /\W/, $current_version;
        my $is_num            = sub { $_[0] =~ /^-?[0-9]+$/ };
        my $filter            = sub {
            my $remote_image = $_[0];
            return 0 if grep { $remote_image->{digest} eq $_ } @container_sha;
            my @check_version = split /\W/, $remote_image->{name};
            my $length
              = $#actual_version > $#check_version
              ? $#actual_version
              : $#check_version;
            my $cmp;
            for my $i ( 0 .. $length ) {
                $check_version[$i]  //= -1;
                $actual_version[$i] //= -1;
                return 0
                  if ( $is_num->( $actual_version[$i] )
                    != $is_num->( $check_version[$i] ) );
                next
                  if !$is_num->( $actual_version[$i] )
                  and
                  ( $actual_version[$i] eq $check_version[$i] or return 0 );
                next if $actual_version[$i] == $check_version[$i];
                $cmp = $actual_version[$i] < $check_version[$i]
                  unless defined $cmp;
            }
            return $cmp;
        };
        my @versions = grep { $filter->($_) } @{$remote_images};
        if (@versions) {
            push @incidents,
              "New versions found for $container_name:$current_version";
            push @incidents, $_->{name} for @versions;
            $exitcode = '1';
            $found    = '1';
        }
    }
    if (!$found) {
        push @incidents, "Cannot determine remote digest for $container_name:$tag!";
        $exitcode = '2';
    }
}

@incidents ? say join( "\n", @incidents ) : say 'OK';
exit $exitcode;

# subs
sub run_cmd {
    my @cmd = @_;
    my ( $out, $err );
    run \@cmd, \undef, \$out, \$err;
    chomp $out;
    return $out;
}

sub send_req {
    my $url = shift;
    my $ua  = LWP::UserAgent->new();
    my $response = $ua->get(
      $url, 'Accept' => 'application/json'
    );
    return if !$response->is_success;
    my $content = decode_json( $response->content );
    $content->{results} ? return $content->{results} : return $content;
}

Youez - 2016 - github.com/yon3zu
LinuXploit