270 lines
7.5 KiB
Perl
270 lines
7.5 KiB
Perl
# --
|
|
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
|
# --
|
|
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
|
# the enclosed file COPYING for license information (GPL). If you
|
|
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
|
# --
|
|
|
|
package Kernel::System::Ticket::Event::Icinga2Acknowledge;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Kernel::System::VariableCheck qw(:all);
|
|
|
|
our @ObjectDependencies = (
|
|
'Kernel::Config',
|
|
'Kernel::System::Log',
|
|
'Kernel::System::Ticket',
|
|
'Kernel::System::User',
|
|
'Kernel::System::JSON',
|
|
);
|
|
|
|
use LWP::UserAgent;
|
|
use IO::Socket::SSL;
|
|
use URI::Escape qw();
|
|
|
|
sub new {
|
|
my ( $Type, %Param ) = @_;
|
|
|
|
# Allocate new hash for object.
|
|
my $Self = {};
|
|
bless( $Self, $Type );
|
|
|
|
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
|
|
|
# Get correct FreeFields.
|
|
$Self->{Fhost} = $ConfigObject->Get('Icinga2::Acknowledge::FreeField::Host');
|
|
$Self->{Fservice} = $ConfigObject->Get('Icinga2::Acknowledge::FreeField::Service');
|
|
|
|
return $Self;
|
|
}
|
|
|
|
sub Run {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
for my $Needed (qw(Data Event Config)) {
|
|
if ( !$Param{$Needed} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Needed!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( !$Param{Data}->{TicketID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => 'Need Data->{TicketID}!',
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
# Check if acknowledge is active.
|
|
my $Enabled = $Kernel::OM->Get('Kernel::Config')->Get('Icinga2::Acknowledge::Enabled');
|
|
|
|
return 1 if !$Enabled;
|
|
|
|
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
|
|
|
# Check if it's a Icinga2 related ticket.
|
|
my %Ticket = $TicketObject->TicketGet(
|
|
TicketID => $Param{Data}->{TicketID},
|
|
DynamicFields => 1,
|
|
);
|
|
if ( !$Ticket{ $Self->{Fhost} } ) {
|
|
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'debug',
|
|
Message => 'No Icinga2 Ticket!',
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
|
|
# Check if it's an acknowledge.
|
|
return 1 if $Ticket{Lock} ne 'lock';
|
|
|
|
# Agent lookup.
|
|
my %User = $Kernel::OM->Get('Kernel::System::User')->GetUserData(
|
|
UserID => $Param{UserID},
|
|
Cached => 1,
|
|
);
|
|
|
|
my $Return = $Self->_HTTP(
|
|
Ticket => \%Ticket,
|
|
User => \%User,
|
|
);
|
|
|
|
if ($Return) {
|
|
|
|
$TicketObject->HistoryAdd(
|
|
TicketID => $Param{Data}->{TicketID},
|
|
HistoryType => 'Misc',
|
|
Name => 'Sent Acknowledge to Icinga2.',
|
|
CreateUserID => $Param{UserID},
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
else {
|
|
|
|
$TicketObject->HistoryAdd(
|
|
TicketID => $Param{Data}->{TicketID},
|
|
HistoryType => 'Misc',
|
|
Name => 'Was not able to send Acknowledge to Icinga2.',
|
|
CreateUserID => $Param{UserID},
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
sub _HTTP {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
for my $Needed (qw(Ticket User)) {
|
|
if ( !$Param{$Needed} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Needed!",
|
|
);
|
|
|
|
return;
|
|
}
|
|
}
|
|
my %Ticket = %{ $Param{Ticket} };
|
|
my %UserData = %{ $Param{User} };
|
|
|
|
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
|
|
|
my $URL = $ConfigObject->Get('Icinga2::Acknowledge::HTTP::URL');
|
|
my $User = $ConfigObject->Get('Icinga2::Acknowledge::HTTP::User');
|
|
my $Pw = $ConfigObject->Get('Icinga2::Acknowledge::HTTP::Password');
|
|
my $Author = $ConfigObject->Get('Icinga2::Acknowledge::Author');
|
|
my $Comment = $ConfigObject->Get('Icinga2::Acknowledge::Comment');
|
|
my $Sticky = $ConfigObject->Get('Icinga2::Acknowledge::Sticky');
|
|
my $Notify = $ConfigObject->Get('Icinga2::Acknowledge::Notify');
|
|
my $Expiry;
|
|
|
|
if ( $Ticket{ $Self->{Fservice} } !~ /^host$/i ) {
|
|
|
|
my $Filter = sprintf(
|
|
'match("%s",host.name)&&match("%s",service.name)',
|
|
$Ticket{ $Self->{Fhost} },
|
|
$Ticket{ $Self->{Fservice} }
|
|
);
|
|
$URL .= sprintf( "?type=Service&filter=%s", URI::Escape::uri_escape($Filter) );
|
|
}
|
|
else {
|
|
|
|
my $Filter = sprintf( 'match("%s",host.name)', $Ticket{ $Self->{Fhost} } );
|
|
$URL .= sprintf( "?type=Host&filter=%s", URI::Escape::uri_escape($Filter) );
|
|
}
|
|
|
|
if ( !IsStringWithData($Author) ) {
|
|
|
|
$Author = $UserData{UserFullname};
|
|
}
|
|
|
|
# Replace ticket tags.
|
|
TICKET:
|
|
for my $Key ( sort keys %Ticket ) {
|
|
next TICKET if !defined $Ticket{$Key};
|
|
|
|
# URLencode values.
|
|
$Ticket{$Key} = URI::Escape::uri_escape_utf8( $Ticket{$Key} );
|
|
$Comment =~ s/<$Key>/$Ticket{$Key}/g;
|
|
}
|
|
|
|
# replace config tags
|
|
$Comment =~ s{<CONFIG_(.+?)>}{$Kernel::OM->Get('Kernel::Config')->Get($1)}egx;
|
|
|
|
# get json object
|
|
my $JSONObject = $Kernel::OM->Get('Kernel::System::JSON');
|
|
|
|
my %Icinga2Param = (
|
|
'author' => $Author,
|
|
'comment' => "$Comment",
|
|
'sticky' => $Sticky == 1 ? $JSONObject->True() : $JSONObject->False(),
|
|
'notify' => $Notify == 1 ? $JSONObject->True() : $JSONObject->False(),
|
|
);
|
|
if ($Expiry) {
|
|
|
|
$Icinga2Param{'expiry'} = $Expiry;
|
|
}
|
|
my $Json = $JSONObject->Encode( Data => \%Icinga2Param );
|
|
|
|
my $UserAgent = LWP::UserAgent->new(
|
|
timeout => 30,
|
|
ssl_opts => {
|
|
verify_hostname => 0,
|
|
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
|
|
}
|
|
);
|
|
my $Request = HTTP::Request->new( POST => $URL );
|
|
$Request->authorization_basic( $User, $Pw );
|
|
$Request->header( 'Accept' => 'application/json' );
|
|
$Request->content($Json);
|
|
my $Response = $UserAgent->request($Request);
|
|
if ( !$Response->is_success() ) {
|
|
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Can't request $URL: " . $Response->status_line(),
|
|
);
|
|
|
|
return;
|
|
}
|
|
else {
|
|
|
|
my $ResponseString = $Response->decoded_content();
|
|
if ($ResponseString) {
|
|
|
|
my $ResponseJSON = $JSONObject->Decode(
|
|
Data => $ResponseString
|
|
);
|
|
|
|
if ( !IsHashRefWithData($ResponseJSON) ) {
|
|
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => sprintf(
|
|
"Error sending ack to Icinga2. Fail to decode json (http %s): %s",
|
|
$Response->status_line(),
|
|
$ResponseString
|
|
),
|
|
);
|
|
return;
|
|
}
|
|
|
|
my $Results = $ResponseJSON->{results};
|
|
if (
|
|
$ResponseJSON
|
|
&& IsArrayRefWithData($Results)
|
|
&& IsHashRefWithData( $Results->[0] )
|
|
&& $Results->[0]->{status}
|
|
&& $Results->[0]->{code} > 299
|
|
)
|
|
{
|
|
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => sprintf(
|
|
"Error sending ack to Icinga2: %s (%s)",
|
|
$Response->status_line(),
|
|
$Results->[0]->{status}
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
1;
|