Passed
Push — master ( 300cc7...278791 )
by Patrick
01:59
created

SettingsController::indexAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 54
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 23
nc 1
nop 0
dl 0
loc 54
rs 9.552
c 2
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Icinga\Module\Trapdirector\Controllers;
4
5
use Icinga\Data\ResourceFactory;
6
use Icinga\Web\Url;
7
use Icinga\Application\Icinga;
8
use Icinga\Exception\ProgrammingError;
9
use Icinga\Exception\ConfigurationError;
10
use RunTimeException;
11
use Exception;
12
13
use Icinga\Module\Trapdirector\TrapsController;
14
use Icinga\Module\Trapdirector\Forms\TrapsConfigForm;
15
use Icinga\Module\Trapdirector\Icinga2Api;
16
17
use Trap;
18
19
class SettingsController extends TrapsController
20
{
21
  
22
  /**
23
   * get param dberror or idoerror
24
   * set errorDetected
25
   */
26
  private function get_param()
27
  {
28
      $dberrorMsg=$this->params->get('dberror');
29
      if ($dberrorMsg != '')
30
      {
31
          $this->view->errorDetected=$dberrorMsg;
32
      }
33
      $dberrorMsg=$this->params->get('idodberror');
34
      if ($dberrorMsg != '')
35
      {
36
          $this->view->errorDetected=$dberrorMsg;
37
      }
38
  }
39
  
40
  /**
41
   * Check empty configuration (and create one if needed)
42
   * Setup : configErrorDetected
43
   */
44
  private function check_empty_config()
45
  {
46
      $this->view->configErrorDetected == NULL; // Displayed error on various conifugration errors.
47
      if ($this->Config()->isEmpty() == true)
48
      {
49
          $this->Config()->setSection('config'); // Set base config section.
50
          try
51
          {
52
              $this->Config()->saveIni();
53
              $this->view->configErrorDetected='Configuration is empty : you can run install script with parameters (see Automatic installation below)';
54
              //$emptyConfig=1;
55
          }
56
          catch (Exception $e)
57
          {
58
              $this->view->configErrorDetected=$e->getMessage();
59
          }
60
          
61
      }
62
  }
63
  
64
  /**
65
   * Check database and IDO database
66
   * Setup : 
67
   * db_error : numerical error (trap db) 0=OK
68
   * message : message (trap db)
69
   * ido_db_error : numerical error 0=OK
70
   * ido_message : message
71
   */
72
  private function check_db()
73
  {
74
      $db_message=array( // index => ( message OK, message NOK, optional link if NOK )
75
          0	=>	array('Database configuration OK','',''),
76
          1	=>	array('Database set in config.ini','No database in config.ini',''),
77
          2	=>	array('Database exists in Icingaweb2 config','Database does not exist in Icingaweb2 : ',
78
              Url::fromPath('config/resource')),
79
          3	=>	array('Database credentials OK','Database does not exist/invalid credentials/no schema : ',
80
              Url::fromPath('trapdirector/settings/createschema')),
81
          4	=>	array('Schema is set','Schema is not set for ',
82
              Url::fromPath('trapdirector/settings/createschema')),
83
          5	=>	array('Schema is up to date','Schema is outdated :',
84
              Url::fromPath('trapdirector/settings/updateschema')),
85
      );
86
      
87
      $dberror=$this->getDb(true); // Get DB in test mode
88
      
89
      $this->view->db_error=$dberror[0];
90
      switch ($dberror[0])
91
      {
92
          case 2:
93
          case 4:
94
              $db_message[$dberror[0]][1] .= $dberror[1];
95
              break;
96
          case 3:
97
              $db_message[$dberror[0]][1] .= $dberror[1] . ', Message : ' . $dberror[2];
98
              break;
99
          case 5:
100
              $db_message[$dberror[0]][1] .= ' version '. $dberror[1] . ', version needed : ' .$dberror[2];
101
              break;
102
          case 0:
103
          case 1:
104
              break;
105
          default:
106
              new ProgrammingError('Out of bond result from database test');
107
      }
108
      $this->view->message=$db_message;
109
      
110
      $dberror=$this->getIdoDb(true); // Get IDO DB in test mode
111
      $this->view->ido_db_error=$dberror[0];
112
      $this->view->ido_message='IDO Database : ' . $dberror[1];
113
  }
114
  
115
  /**
116
   * Check API parameters
117
   * Setup : 
118
   * apimessage
119
   */
120
  private function check_api()
121
  {
122
      if ($this->Config()->get('config', 'icingaAPI_host') != '')
123
      {
124
          $apitest=new Icinga2Api($this->Config()->get('config', 'icingaAPI_host'),$this->Config()->get('config', 'icingaAPI_port'));
125
          $apitest->setCredentials($this->Config()->get('config', 'icingaAPI_user'), $this->Config()->get('config', 'icingaAPI_password'));
126
          try {
127
              list($this->view->apimessageError,$this->view->apimessage)=$apitest->test($this->getModuleConfig()::getapiUserPermissions());
128
              //$this->view->apimessageError=false;
129
          } catch (RuntimeException $e) {
130
              $this->view->apimessage='API config : ' . $e->getMessage();
131
              $this->view->apimessageError=true;
132
          }
133
      }
134
      else
135
      {
136
          $this->view->apimessage='API parameters not configured';
137
          $this->view->apimessageError=true;
138
      }
139
  }
140
141
  /**
142
   * Check icingaweb2 etc path
143
   * Setup : 
144
   * icingaEtcWarn : 0 if same than in trap_in.php, 1 if not
145
   * icingaweb2_etc : path 
146
   */
147
  private function check_icingaweb_path()
148
  {
149
      $this->view->icingaEtcWarn=0;
150
      $icingaweb2_etc=$this->Config()->get('config', 'icingaweb2_etc');
151
      if ($icingaweb2_etc != "/etc/icingaweb2/" && $icingaweb2_etc != '')
152
      {
153
          $output=array();
154
          
155
          exec('cat ' . $this->module->getBaseDir() .'/bin/trap_in.php | grep "\$icingaweb2_etc=" ',$output);
156
          
157
          if (! preg_match('#"'. $icingaweb2_etc .'"#',$output[0]))
158
          {
159
              $this->view->icingaEtcWarn=1;
160
              $this->view->icingaweb2_etc=$icingaweb2_etc;
161
          }
162
      }
163
      
164
  }
165
  
166
  /**
167
   * Get db list filtered by $allowed
168
   * @param array $allowed : array of allowed database
169
   * @return array : resource list
170
   */
171
  private function get_db_list($allowed)
172
  {
173
      $resources = array();
174
      foreach (ResourceFactory::getResourceConfigs() as $name => $resource) 
175
      {
176
          if ($resource->get('type') === 'db' && in_array($resource->get('db'), $allowed)) 
177
          {
178
              $resources[$name] = $name;
179
          }
180
      }
181
      return $resources;
182
  }
183
  
184
  /**
185
   * Index of configuration
186
   * Params setup in $this->view :
187
   * errorDetected : if db or ido was detected by another page
188
   * configErrorDetected : error if empty configuration (or error wrting a new one).
189
   * db_error : numerical error (trap db) 0=OK
190
   * message : message (trap db)
191
   * ido_db_error : numerical error 0=OK
192
   * ido_message : message
193
   * apimessage
194
   * icingaEtcWarn : 0 if same than in trap_in.php, 1 if not
195
   * icingaweb2_etc : path 
196
   **/
197
  public function indexAction()
198
  {
199
      
200
    // CHeck permissions : display tests in any case, but no configuration.
201
	$this->view->configPermission=$this->checkModuleConfigPermission(1);
202
	// But check read permission
203
	$this->checkReadPermission();
204
	
205
	$this->view->tabs = $this->Module()->getConfigTabs()->activate('config');
206
	
207
	// Get message : sent on configuration problems detected by controllers
208
    $this->get_param();
209
    
210
    // Test if configuration exists, if not create for installer script
211
	$this->check_empty_config();
212
213
	// Test Database
214
    $this->check_db();
215
	
216
	//********* Test API
217
    $this->check_api();
218
	
219
	//*********** Test snmptrapd alive and options
220
	list ($this->view->snmptrapdError, $this->view->snmptrapdMessage) = $this->checkSnmpTrapd();
221
222
	// List DB in $ressources
223
	$resources = $this->get_db_list(array('mysql', 'pgsql')); 
224
225
	// Check standard Icingaweb2 path
226
	$this->check_icingaweb_path();
227
	
228
	// Setup path for mini documentation
229
	$this->view->traps_in_config= PHP_BINARY . ' ' . $this->Module()->getBaseDir() . '/bin/trap_in.php';
230
	
231
	$this->view->installer= $this->Module()->getBaseDir() . '/bin/installer.sh '
232
	    . ' -c all ' 
233
	    . ' -d ' . $this->Module()->getBaseDir()
234
	    . ' -p ' . PHP_BINARY
235
	    . ' -a ' . exec('whoami')
236
	    . ' -w ' . Icinga::app()->getConfigDir();
237
	        
238
	// ******************* configuration form setup*******************
239
	$this->view->form = $form = new TrapsConfigForm();
240
	
241
	// set default paths;
242
	$this->view->form->setPaths($this->Module()->getBaseDir(),Icinga::app()->getConfigDir());
243
	
244
	// set default ido database
245
	$this->view->form->setDefaultIDODB($this->Config()->module('monitoring','backends')->get('icinga','resource'));
246
	
247
	// Make form handle request.
248
	$form->setIniConfig($this->Config())
249
		->setDBList($resources)
250
		->handleRequest();
251
        
252
  }
253
254
  public function createschemaAction()
255
  {
256
	$this->checkModuleConfigPermission();
257
	$this->getTabs()->add('create_schema',array(
258
		'active'	=> true,
259
		'label'		=> $this->translate('Create Schema'),
260
		'url'		=> Url::fromRequest()
261
	));
262
	// check if needed
263
	
264
	$dberror=$this->getDb(true); // Get DB in test mode
265
	
266
	if ($dberror[0] == 0)
267
	{
268
		printf('Schema already exists');
269
	}
270
	else
271
	{
272
		printf('Creating schema : <br>');
273
274
		// Get module database name
275
		$dbName=$this->Config()->get('config', 'database');
276
277
		try {
278
		  $dbResource = ResourceFactory::getResourceConfig($dbName);
279
		  $dbType=$dbResource->get('db');
280
		  switch ($dbType) {
281
		      case 'mysql':
282
		          $dbFileExt='sql';
283
		          break;
284
		      case 'pgsql':
285
		          $dbFileExt='pgsql';
286
		          break;
287
		      default:
288
		          throw new ConfigurationError('Unsuported database : '.$dbType);
289
		  }
290
		} catch (ConfigurationError $e )
291
		{
292
		    printf("Database configuration error : %s",$e->getMessage());
293
		    return;
294
		}
295
		printf('<pre>');
296
		require_once $this->Module()->getBaseDir() .'/bin/trap_class.php';
297
		
298
		$icingaweb2_etc=$this->Config()->get('config', 'icingaweb2_etc');
299
		$debug_level=4;
300
		$Trap = new Trap($icingaweb2_etc);
301
		$Trap->setLogging($debug_level,'display');
302
		
303
		$prefix=$this->Config()->get('config', 'database_prefix');
304
		// schema file : <path>/SQL/schema_v<verion>.<dbtype>
305
		$schema=$this->Module()->getBaseDir() . 
306
		'/SQL/schema_v'. $this->getModuleConfig()->getDbCurVersion() . '.' . $dbFileExt;
307
		
308
		$Trap->trapsDB->create_schema($schema,$prefix);
309
		echo '</pre>';
310
	}
311
	echo '<br><br>Return to <a href="' . Url::fromPath('trapdirector/settings') .'" class="link-button icon-wrench"> settings page </a>';
312
  }
313
314
  public function updateschemaAction()
315
  {
316
	  $this->checkModuleConfigPermission();
317
    	$this->getTabs()->add('get',array(
318
    		'active'	=> true,
319
    		'label'		=> $this->translate('Update Schema'),
320
    		'url'		=> Url::fromRequest()
321
    	));
322
	  // check if needed
323
	  
324
	  $dberror=$this->getDb(true); // Get DB in test mode
325
	  
326
	  echo 'Return to <a href="' . Url::fromPath('trapdirector/settings') .'" class="link-button icon-wrench"> settings page </a><br><br>';
327
	  
328
	  if ($dberror[0] == 0)
329
	  {
330
	      echo 'Schema already exists and is up to date<br>';
331
	      return;
332
	  }
333
	  if ($dberror[0] != 5)
334
	  {
335
	      echo 'Database does not exists or is not setup correctly<br>';
336
	      return;
337
	  }
338
      // setup
339
	  require_once($this->Module()->getBaseDir() .'/bin/trap_class.php');
340
	  $icingaweb2_etc=$this->Config()->get('config', 'icingaweb2_etc');
341
	  $debug_level=4;
342
	  $Trap = new Trap($icingaweb2_etc);
343
	  
344
	  
345
	  $prefix=$this->Config()->get('config', 'database_prefix');
346
	  $updateSchema=$this->Module()->getBaseDir() . '/SQL/';
347
	  
348
	  $target_version=$dberror[2];
349
	  
350
	  if ($this->params->get('msgok') == null) {
351
	      // Check for messages and display if any
352
              echo "Upgrade databse is going to start.<br>Don't forget to backup your database before update<br>";
353
	      $Trap->setLogging(2,'syslog');
354
	      $message = $Trap->trapsDB->update_schema($updateSchema,$target_version,$prefix,true);
355
	      if ($message != '')
356
	      {
357
	          echo 'Note :<br><pre>';
358
	          echo $message;
359
	          echo '</pre>';
360
	          echo '<br>';
361
	          echo '<a  class="link-button" style="font-size:large;font-weight:bold" href="' . Url::fromPath('trapdirector/settings/updateschema') .'?msgok=1">Click here to update</a>';
362
	          echo '<br>';
363
	          return;
364
	      }
365
	  }
366
	  
367
	  $Trap->setLogging($debug_level,'display');
368
	  
369
	  echo 'Updating schema to '. $target_version . ': <br>';
370
	  echo '<pre>';
371
	  	  
372
	  $Trap->trapsDB->update_schema($updateSchema,$target_version,$prefix);
373
	  echo '</pre>';
374
  }  
375
376
  private function checkSnmpTrapd()
377
  {
378
      $psOutput=array();
379
      // First check is someone is listening to port 162. As not root, we can't have pid... 
380
      exec('netstat -an |grep -E "udp.*:162"',$psOutput);
381
      if (count($psOutput) == 0)
382
      {
383
          return array(1,'Port UDP/162 is not open : snmptrapd must not be started');
384
      }
385
      $psOutput=array();
386
      exec('ps fax |grep snmptrapd |grep -v grep',$psOutput);
387
      if (count($psOutput) == 0)
388
      {
389
          return array(1,"UDP/162 : OK, but no snmptrapd process (?)");
390
      }
391
      // Assume there is only one line... TODO : see if there is a better way to do this
392
      $line = preg_replace('/^.*snmptrapd /','',$psOutput[0]);
393
      if (!preg_match('/-n/',$line))
394
          return array(1,'snmptrapd has no -n option : '.$line);
395
      if (!preg_match('/-O[^ ]*n/',$line))
396
          return array(1,'snmptrapd has no -On option : '.$line);
397
      if (!preg_match('/-O[^ ]*e/',$line))
398
          return array(1,'snmptrapd has no -Oe option : '.$line);
399
      
400
      return array(0,'snmptrapd listening to UDP/162, options : '.$line);
401
  }
402
}
403