Skip to content
This repository has been archived by the owner on Jan 15, 2025. It is now read-only.

Better error handling for proxy access mode #33

Merged
merged 1 commit into from
Apr 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ enableLink | **Optional.** Enable/disable graph with a rendered URL to t
datasource | **Required.** Type of the Grafana datasource (`influxdb`, `graphite` or `pnp`). Defaults to `influxdb`.
defaultdashboard | **Required.** Name of the default dashboard which will be shown for unconfigured graphs. **Important: `panelID` must be set to `1`!** Defaults to `icinga2-default`.
defaultdashboardstore | **Optional.** Grafana backend (file or database). Defaults to `Database`.
accessmode | **Optional.** Controlls if module proxies all graphs or user loads graphs directly. Direct access speeds up page load, needs `auth.anonymous` enabled in Grafana. Defaults to `proxy`.
accessmode | **Optional.** Controls whether graphs are fetched with curl (`proxy`) or are embedded (`direct`). Direct access is faster and needs `auth.anonymous` enabled in Grafana. Defaults to `proxy`.


Example:
Expand Down
49 changes: 32 additions & 17 deletions library/Grafana/ProvidedHook/Grapher.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
use Icinga\Application\Icinga;
use Icinga\Application\Config;
use Icinga\Exception\ConfigurationError;
use Exception;
use Icinga\Application\Hook\GrapherHook;
use Icinga\Module\Monitoring\Object\MonitoredObject;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Web\Url;
use Icinga\Web\View;
use Icinga\Module\Grafana\Util;

class Grapher extends GrapherHook
{
Expand Down Expand Up @@ -83,12 +85,12 @@ protected function init()
{
if($this->password != null)
{
$this->auth = $this->username.":".$this->password."@";
$this->auth = $this->username.":".$this->password;
}
else
{
$this->auth = $this->username."@";
}
{
$this->auth = $this->username;
}
}
else
{
Expand Down Expand Up @@ -177,22 +179,35 @@ private function getPreviewImage($serviceName, $hostName)

// fetch image with curl
$curl_handle = curl_init();
curl_setopt($curl_handle,CURLOPT_URL,$pngUrl);
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl_handle,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($curl_handle,CURLOPT_TIMEOUT,5);
curl_setopt($curl_handle, CURLOPT_USERPWD, "$this->auth");
curl_setopt($curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
$imgBinary = curl_exec($curl_handle);
if(curl_error($curl_handle))
{
return 'Graph currently unavailable: :' . curl_error($curl_handle);
$curl_opts = array(
CURLOPT_URL => $pngUrl,
CURLOPT_CONNECTTIMEOUT => 2,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false, //TODO: config option
CURLOPT_TIMEOUT => 5, //TODO: config option
CURLOPT_USERPWD => "$this->auth",
CURLOPT_HTTPAUTH, CURLAUTH_ANY
);

curl_setopt_array($curl_handle, $curl_opts);

$res = curl_exec($curl_handle);

if ($res === false) {
return "<b>Graph currently unavailable: Curl error: ' . curl_error($curl_handle)</b>";
}
curl_close($curl_handle);

$statusCode = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE);

if ($statusCode > 299) {
$error = @json_decode($res);
return "<b>Cannot fetch Grafana graph: ". Util::httpStatusCodeToString($statusCode) .
" ($statusCode)</b>: " . (property_exists($error, 'message') ? $error->message : "");
}

curl_close($curl_handle);

$img = 'data:image/png;base64,'.base64_encode($imgBinary);
$img = 'data:image/png;base64,'.base64_encode($res);
$imghtml = '<img src="%s" alt="%s" width="%d" height="%d" />';
return sprintf(
$imghtml,
Expand Down
59 changes: 59 additions & 0 deletions library/Grafana/Util.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace Icinga\Module\Grafana;

class Util
{

public static function httpStatusCodetoString($code = 0)
{
$statuscodes = array(
'100' => 'Continue',
'101' => 'Switching Protocols',
'200' => 'OK',
'201' => 'Created',
'202' => 'Accepted',
'203' => 'Non-Authoritative Information',
'204' => 'No Content',
'205' => 'Reset Content',
'206' => 'Partial Content',
'300' => 'Multiple Choices',
'302' => 'Found',
'303' => 'See Other',
'304' => 'Not Modified',
'305' => 'Use Proxy',
'400' => 'Bad Request',
'401' => 'Unauthorized',
'402' => 'Payment Required',
'403' => 'Forbidden',
'404' => 'Not Found',
'405' => 'Method Not Allowed',
'406' => 'Not Acceptable',
'407' => 'Proxy Authentication Required',
'408' => 'Request Timeout',
'409' => 'Conflict',
'410' => 'Gone',
'411' => 'Length Required',
'412' => 'Precondition Failed',
'413' => 'Request Entity Too Large',
'414' => 'Request-URI Too Long',
'415' => 'Unsupported Media Type',
'416' => 'Requested Range Not Satisfiable',
'417' => 'Expectation Failed',
'500' => 'Internal Server Error',
'501' => 'Not Implemented',
'502' => 'Bad Gateway',
'503' => 'Service Unavailable',
'504' => 'Gateway Timeout',
'505' => 'HTTP Version Not Supported'
);

$code = (string)$code;

if(array_key_exists($code, $statuscodes)) {
return $statuscodes[$code];
} else {
return $code;
}
}
}