per-agent configuration of batch processors, #71837
[freeside.git] / torrus / perllib / Torrus / SiteConfig.pm
1 #  Copyright (C) 2002  Stanislav Sinyagin
2 #
3 #  This program is free software; you can redistribute it and/or modify
4 #  it under the terms of the GNU General Public License as published by
5 #  the Free Software Foundation; either version 2 of the License, or
6 #  (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software
15 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16
17 # $Id: SiteConfig.pm,v 1.1 2010-12-27 00:03:39 ivan Exp $
18 # Stanislav Sinyagin <ssinyagin@yahoo.com>
19
20 ## %Torrus::Global::treeConfig manipulation
21
22 package Torrus::SiteConfig;
23
24 use Torrus::Log;
25 use strict;
26
27 our %validDaemonNames = ('collector' => 1,
28                          'monitor'   => 1);
29
30 our %mandatoryGraphStyles =
31     (
32      'SingleGraph'     => {'color' => 1, 'line'  => 1},
33      'HWBoundary'     => {'color' => 1, 'line'  => 1},
34      'HWFailure'      => {'color' => 1},
35      'HruleMin'       => {'color' => 1},
36      'HruleNormal'    => {'color' => 1},
37      'HruleMax'       => {'color' => 1},
38      'BpsIn'          => {'color' => 1, 'line'  => 1},
39      'BpsOut'         => {'color' => 1, 'line'  => 1}
40      );
41
42 %Torrus::SiteConfig::validLineStyles =
43     (
44      'LINE1' => 1,
45      'LINE2' => 1,
46      'LINE3' => 1,
47      'AREA'  => 1,
48      'STACK' => 1
49      );
50
51 ## Verify the correctness of %Torrus::Global::treeConfig contents
52
53 sub verify
54 {
55     my $ok = 1;
56     if( not (scalar( keys %Torrus::Global::treeConfig )) )
57     {
58         Error('%Torrus::Global::treeConfig is not defined or empty');
59         $ok = 0;
60     }
61
62     foreach my $tree ( keys %Torrus::Global::treeConfig )
63     {
64         if( $tree !~ /^[a-zA-Z][a-zA-Z0-9_\-]*$/o )
65         {
66             Error("Invalid tree name: " . $tree);
67             $ok = 0;
68             next;
69         }
70
71         if( not $Torrus::Global::treeConfig{$tree}{'description'} )
72         {
73             Error("Missing description for the tree named \"" . $tree . "\"");
74             $ok = 0;
75         }
76
77         my $xmlfiles = $Torrus::Global::treeConfig{$tree}{'xmlfiles'};
78         if( not ref( $xmlfiles ) or not scalar( @{$xmlfiles} ) )
79         {
80             Error("'xmlfiles' array is not defined for the tree named \"" .
81                   $tree . "\"");
82             $ok = 0;
83         }
84         else
85         {
86             foreach my $file ( @{$xmlfiles} )
87             {
88                 $ok = findXMLFile( $file,
89                                    "in the tree named \"" . $tree . "\"" ) ?
90                                        $ok:0;
91             }
92
93             if( ref( $Torrus::Global::treeConfig{$tree}{'run'} ) )
94             {
95                 foreach my $daemon
96                     ( keys %{$Torrus::Global::treeConfig{$tree}{'run'}} )
97                 {
98                     if( not $validDaemonNames{$daemon} )
99                     {
100                         Error("\"" . $daemon . "\" is not a correct daemon " .
101                               "name in the tree named \"" . $tree . "\"");
102                         $ok = 0;
103                     }
104                 }
105             }
106         }
107     }
108
109     foreach my $file ( @Torrus::Global::xmlAlwaysIncludeFirst )
110     {
111         $ok = findXMLFile( $file,
112                            'in @Torrus::Global::xmlAlwaysIncludeFirst' ) ?
113                                $ok:0;
114     }
115     foreach my $file ( @Torrus::Global::xmlAlwaysIncludeLast )
116     {
117         $ok = findXMLFile( $file,
118                            'in @Torrus::Global::xmlAlwaysIncludeLast' ) ?
119                                $ok:0;
120     }
121
122     # Validate the styling profile
123
124     my $file = $Torrus::Global::stylingDir . '/' .
125         $Torrus::Renderer::stylingProfile . '.pl';
126     if( -r $file )
127     {
128         require $file;
129
130         #Color names are always there
131         require $Torrus::Global::stylingDir . '/colornames.pl';
132
133         if( defined($Torrus::Renderer::stylingProfileOverlay) )
134         {
135             my $overlay = $Torrus::Renderer::stylingProfileOverlay;
136             if( -r $overlay )
137             {
138                 require $overlay;
139             }
140             else
141             {
142                 Error('Error reading styling profile overlay from ' .
143                       $overlay . ': File is not readable');
144                 $ok = 0;
145             }
146         }
147
148         my $profile = \%Torrus::Renderer::graphStyles;
149         # Check if mandatory parameters present
150         foreach my $element ( keys %mandatoryGraphStyles )
151         {
152             if( ref( $profile->{$element} ) )
153             {
154                 if( $mandatoryGraphStyles{$element}{'color'}
155                     and not defined( $profile->{$element}{'color'} ) )
156                 {
157                     Error('Mandatory color for ' . $element .
158                           ' is not defined in ' . $file);
159                     $ok = 0;
160                 }
161                 if( $mandatoryGraphStyles{$element}{'line'}
162                     and not defined( $profile->{$element}{'line'} ) )
163                 {
164                     Error('Mandatory line style for ' . $element .
165                           ' is not defined in ' . $file);
166                     $ok = 0;
167                 }
168             }
169             else
170             {
171                 Error('Mandatory styling for ' . $element .
172                       ' is not defined in ' . $file);
173                 $ok = 0;
174             }
175         }
176         # Check validity of all parameters
177         foreach my $element ( keys %{$profile} )
178         {
179             if( defined( $profile->{$element}{'color'} ) )
180             {
181                 my $color = $profile->{$element}{'color'};
182                 my $recursionLimit = 100;
183
184                 while( $color =~ /^\#\#(\S+)$/ )
185                 {
186                     if( $recursionLimit-- <= 0 )
187                     {
188                         Error('Color recursion is too deep');
189                         $ok = 0;
190                     }
191                     else
192                     {
193                         my $colorName = $1;
194                         $color = $profile->{$colorName}{'color'};
195                         if( not defined( $color ) )
196                         {
197                             Error('No color is defined for ' . $colorName);
198                             $ok = 0;
199                         }
200                     }
201                 }
202
203                 if( $color !~ /^\#[0-9a-fA-F]{6}$/ )
204                 {
205                     Error('Invalid color specification for ' . $element .
206                           ' in ' . $file);
207                     $ok = 0;
208                 }
209             }
210             if( defined( $profile->{$element}{'line'} ) )
211             {
212                 if( not $Torrus::SiteConfig::validLineStyles{
213                     $profile->{$element}{'line'}} )
214                 {
215                     Error('Invalid line specification for ' . $element .
216                           ' in ' . $file);
217                     $ok = 0;
218                 }
219             }
220         }
221     }
222     else
223     {
224         Error('Error reading styling profile from ' . $file .
225               ': File is not readable');
226         $ok = 0;
227     }
228
229     return $ok;
230 }
231
232
233 sub findXMLFile
234 {
235     my $file = shift;
236     my $msg = shift;
237
238     my $filename;
239     if( defined( $file ) )
240     {
241         my $found = 0;
242         foreach my $dir ( @Torrus::Global::xmlDirs )
243         {
244             $filename = $dir . '/' . $file;
245             if( -r $filename )
246             {
247                 $found = 1;
248                 last;
249             }
250         }
251         
252         if( not $found )
253         {
254             Error("Cannot find file: " . $file);
255             $filename = undef;
256         }
257     }
258     else
259     {
260         Error("File name undefined " . $msg);
261     }
262     return $filename;
263 }
264
265
266 sub treeExists
267 {
268     my $tree = shift;
269     return defined( $Torrus::Global::treeConfig{$tree} );
270 }
271
272
273 sub listTreeNames
274 {
275     return( sort keys %Torrus::Global::treeConfig );
276 }
277
278
279 sub mayRunCollector
280 {
281     my $tree = shift;
282     my $run = $Torrus::Global::treeConfig{$tree}{'run'}{'collector'};
283     return( defined($run) and $run > 0 );   
284 }
285
286 sub collectorInstances
287 {
288     my $tree = shift;
289     my $run = $Torrus::Global::treeConfig{$tree}{'run'}{'collector'};
290     return( (defined($run) and $run > 1) ? int($run) : 1 ); 
291 }
292
293 sub mayRunMonitor
294 {
295     my $tree = shift;
296     return $Torrus::Global::treeConfig{$tree}{'run'}{'monitor'};
297 }
298
299
300 sub listXmlFiles
301 {
302     my $tree = shift;
303     return @{$Torrus::Global::treeConfig{$tree}{'xmlfiles'}};
304 }
305
306
307 sub treeDescription
308 {
309     my $tree = shift;
310     return $Torrus::Global::treeConfig{$tree}{'description'};
311 }
312
313
314 sub loadStyling
315 {
316     require $Torrus::Global::stylingDir . '/' .
317         $Torrus::Renderer::stylingProfile . '.pl';
318
319     require $Torrus::Global::stylingDir . '/colornames.pl';
320
321     if( defined($Torrus::Renderer::stylingProfileOverlay) )
322     {
323         require $Torrus::Renderer::stylingProfileOverlay;
324     }
325 }
326
327
328 1;
329
330
331 # Local Variables:
332 # mode: perl
333 # indent-tabs-mode: nil
334 # perl-indent-level: 4
335 # End: