Test Failed
Push — develop ( 55b248...7d9761 )
by Tony
21:25
created

RRD::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * RRD.php
4
 *
5
 * Fetch data from RRD files
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * @package    LibreNMS
21
 * @link       http://librenms.org
22
 * @copyright  2016 Tony Murray
23
 * @author     Tony Murray <[email protected]>
24
 */
25
26
namespace App\Data;
27
28
use App\Exceptions\UnsupportedOutputFormatException;
29
use App\Models\Device;
30
use Settings;
31
use Symfony\Component\Process\Exception\ProcessFailedException;
32
use Symfony\Component\Process\Process;
33
34
abstract class RRD implements Source
35
{
36
    /** @var array Array of formats this RRD Source supports */
37
    protected $supported_formats = [];
38
39
    /** @var string Holds the rrdtool command that will be run */
40
    protected $command;
41
42
    /**
43
     * RRD constructor.
44
     *
45
     * @param $args
46
     */
47
    public function __construct($args)
48
    {
49
        $this->command = $this->buildCommand($args);
50
    }
51
52
    /**
53
     * Run rrdtool and return the output
54
     *
55
     * @return string
56
     */
57
    protected function run()
58
    {
59
        $process = new Process($this->command);
60
        $process->run();
61
        if (!$process->isSuccessful()) {
62
            throw new ProcessFailedException($process);
63
        }
64
        return $process->getOutput();
65
    }
66
67
    /**
68
     * Check if the requested format is supported
69
     *
70
     * @param $format
71
     * @return bool
72
     */
73
    protected function isFormatSupported($format)
74
    {
75
        return in_array($format, $this->supported_formats);
76
    }
77
78
    /**
79
     * Throw an exception if the requested format isn't supported
80
     *
81
     * @param $format
82
     * @throws UnsupportedOutputFormatException
83
     */
84
    protected function checkFormatSupported($format)
85
    {
86
        if (!$this->isFormatSupported($format)) {
87
            throw new UnsupportedOutputFormatException("Format ($format) is not supported by the chosen data source ".get_class($this));
88
        }
89
    }
90
91
92
    /**
93
     * Generate an rrdtool command with the supplied arguments
94
     *
95
     * @param string $args rrdtool arguments
96
     * @return string
97
     */
98
    private function buildCommand($args)
99
    {
100
        $rrd_cmd = Settings::get('rrdtool').' ';
101
102
        // if using rrdcached append --daemon and replace rrd_dir with rrdcached if it is set
103
        if (Settings::has('rrdcached')) {
104
            if (Settings::has('rrdcached_dir')) {
105
                $rrdcached_dir = Settings::get('rrdcached_dir');
106
                if ($rrdcached_dir !== false) {
107
                    $rrd_dir = Settings::get('rrd_dir');
108
                    $args = str_replace(array($rrd_dir.'/', $rrd_dir), './'.$rrdcached_dir.'/', $args);
109
                }
110
            }
111
            $rrdcached = Settings::get('rrdcached');
112
            $rrd_cmd .= "--daemon $rrdcached ";
113
        }
114
        return $rrd_cmd.$args;
115
    }
116
117
    /**
118
     * Generates a filename based on the hostname (or IP) and some extra items
119
     *
120
     * @param Device $device Device
121
     * @param array|string $extra Components of RRD filename - will be separated with "-", or a pre-formed rrdname
122
     * @param string $extension File extension (default is .rrd)
123
     * @return string the name of the rrd file for $host's $extra component
124
     */
125
    public static function getFileName($device, $extra, $extension = '.rrd')
126
    {
127
        $filename = safename(is_array($extra) ? implode("-", $extra) : $extra);
128
        return implode("/", array(Settings::get('rrd_dir'), $device->hostname, $filename.$extension));
129
    }
130
131
    /**
132
     * Get the name of this ports rrd file
133
     *
134
     * @param $port_id
135
     * @param string $suffix
136
     * @return string
137
     */
138
    public static function getPortName($port_id, $suffix = '')
139
    {
140
        if (!empty($suffix)) {
141
            $suffix = '-'.$suffix;
142
        }
143
144
        return "port-id$port_id$suffix";
145
    }
146
147
    /**
148
     * Get the full rrd path to this port on this device
149
     *
150
     * @param Device $device
151
     * @param $port_id
152
     * @param string $suffix
153
     * @return string
154
     */
155
    public static function getPortFileName($device, $port_id, $suffix = '')
156
    {
157
        return self::getFileName($device, self::getPortName($port_id, $suffix));
158
    }
159
160
    /**
161
     * Escapes strings for rrdtool
162
     *
163
     * @param string $string the string to escape
164
     * @param integer $length if passed, string will be padded and trimmed to exactly this length (after rrdtool unescapes it)
165
     * @return string
166
     */
167
    public static function escape($string, $length = null)
168
    {
169
        $result = shorten_interface_type($string);
170
        $result = str_replace("'", '', $result);            # remove quotes
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
171
        $result = str_replace('%', '%%', $result);          # double percent signs
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
172
        if (is_numeric($length) && strlen($string) > $length) {
173
            $extra = substr_count($string, ':', 0, $length);
174
            $result = substr(str_pad($result, $length), 0, ($length + $extra));
175
            if ($extra > 0) {
176
                $result = substr($result, 0, (-1 * $extra));
177
            }
178
        }
179
180
        $result = str_replace(':', '\:', $result);          # escape colons
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
181
        return $result.' ';
182
    }
183
}
184