openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Status.class.php (5882B)


      1 <?php
      2 
      3 namespace cms\status;
      4 
      5 use BadMethodCallException;
      6 use cms\action\RequestParams;
      7 use cms\base\Configuration;
      8 use cms\base\DB;
      9 use cms\base\DefaultConfig;
     10 use cms\base\Startup;
     11 use cms\Dispatcher;
     12 use cms\update\Update;
     13 use configuration\Config;
     14 use configuration\ConfigurationLoader;
     15 use database\Database;
     16 use Exception;
     17 use util\Http;
     18 use logger\Logger;
     19 use \util\exception\ObjectNotFoundException;
     20 use util\exception\UIException;
     21 use util\exception\SecurityException;
     22 use util\json\JSON;
     23 use util\Session;
     24 use util\XML;
     25 use util\YAML;
     26 
     27 /**
     28  * Actuator.
     29  */
     30 class Status
     31 {
     32 	/**
     33      * Getting the state
     34      */
     35     public static function execute()
     36     {
     37 		$cmd     = $_SERVER['QUERY_STRING'];
     38 		$data    = [];
     39 		$success = false;
     40 
     41 		switch( $cmd ) {
     42 			case '':
     43 			case 'health':
     44 			case 'status':
     45 			case 'state':
     46 
     47 				$data['state'] = 'UP';
     48 				$success = true;
     49 				break;
     50 
     51 			case 'db':
     52 			case 'database':
     53 
     54 				$config = new Config( self::getConfiguration() );
     55 				$databases = [];
     56 				foreach( $config->subset('database')->subsets() as $dbName => $dbConfig ) {
     57 
     58 					if (!$dbConfig->is('enabled', true)) {
     59 						$dbState = [
     60 							'state'   => 'DISABLED',
     61 						];
     62 
     63 					} else {
     64 
     65 						try {
     66 							$db = new Database($dbConfig->subset('read')->getConfig() + $dbConfig->getConfig());
     67 
     68 							$update = new Update();
     69 
     70 							if	( $update->isUpdateRequired( $db ) )
     71 								$dbState = [
     72 									'state'   => 'UP',
     73 								];
     74 							else
     75 								$dbState = [
     76 									'state'   => 'DOWN',
     77 									'message' => 'NEEDS UPGRADE',
     78 								];
     79 
     80 							$db->disconnect();
     81 
     82 						} catch (\Exception $e) {
     83 							$dbState = [
     84 								'state' => 'DOWN',
     85 								'message' => $e->getMessage(),
     86 							];
     87 						}
     88 
     89 					}
     90 
     91 					$databases[$dbName] = $dbState;
     92 				}
     93 
     94 				$data['databases'] = $databases;
     95 				$success = true;
     96 				break;
     97 
     98 			case 'upgrade':
     99 			case 'update':
    100 			case 'install':
    101 
    102 				$config = new Config( self::getConfiguration() );
    103 				$databases = [];
    104 				foreach( $config->subset('database')->subsets() as $dbName => $dbConfig ) {
    105 
    106 					$dbState = [];
    107 
    108 					if (!$dbConfig->is('enabled', true)) {
    109 						$dbState = [
    110 							'state'   => 'DISABLED',
    111 						];
    112 
    113 					} else {
    114 
    115 						try {
    116 							$adminDb = new Database($dbConfig->subset('admin')->getConfig() + $dbConfig->getConfig());
    117 							$adminDb->id = $dbName;
    118 
    119 							$updater = new Update();
    120 
    121 							if   ( ! $updater->isUpdateRequired( $adminDb ) ) {
    122 								$dbState = [
    123 									'state' => 'UP',
    124 								];
    125 							}
    126 							else {
    127 
    128 								if (!$dbConfig->is('auto_update', true))
    129 									$dbState = [
    130 										'state'   => 'DOWN',
    131 										'message' => 'DB Update required, but auto-update is disabled. ' . Startup::TITLE . " " . Startup::VERSION . " needs DB-version " . Update::SUPPORTED_VERSION
    132 										];
    133 								else {
    134 									$updater->update($adminDb);
    135 
    136 									// Try to close the PDO connection. PDO doc:
    137 									// To close the connection, you need to destroy the object by ensuring that all
    138 									// remaining references to it are deleted—you do this by assigning NULL to the variable that holds the object.
    139 									// If you don't do this explicitly, PHP will automatically close the connection when your script ends.
    140 									$adminDb = null;
    141 									unset($adminDb);
    142 
    143 									$dbState = [
    144 										'state'   => 'UP',
    145 										'message' => 'Updated',
    146 									];
    147 								}
    148 							}
    149 
    150 
    151 						} catch (\Exception $e) {
    152 							$dbState = [
    153 								'state' => 'DOWN',
    154 								'message' => $e->getMessage(),
    155 							];
    156 						}
    157 
    158 					}
    159 
    160 					$databases[$dbName] = $dbState;
    161 				}
    162 
    163 				$data['databases'] = $databases;
    164 				$success = true;
    165 				break;
    166 
    167 			case 'info':
    168 				$data = [
    169 					'version' => Startup::VERSION,
    170 					'date' => Startup::DATE,
    171 					'name' => Startup::TITLE,
    172 					'api'  => Startup::API_LEVEL,
    173 				];
    174 				$success = true;
    175 				break;
    176 
    177 			case 'system':
    178 				$data = [
    179 					'interpreter' => PHP_VERSION,
    180 					'os'          => PHP_OS,
    181 					'usage' => getrusage(),
    182 					'memory' => [
    183 						'allocated' => memory_get_usage(true),
    184 						'used'      => memory_get_usage(),
    185 						'peak_allocated' => memory_get_peak_usage(true),
    186 						'peak_used'      => memory_get_peak_usage(),
    187 
    188 					],
    189 				];
    190 				$success = true;
    191 				break;
    192 
    193 			case 'env':
    194 			case 'environment':
    195 				if   ( version_compare(PHP_VERSION,'7.1','>=') )
    196 					$data['environment'] = getenv(); // since PHP 7.1
    197 				$success = true;
    198 				break;
    199 
    200 			case 'server':
    201 				$data['server'] = $_SERVER;
    202 				$success = true;
    203 				break;
    204 
    205 			case 'extensions':
    206 					$data['extensions'] = get_loaded_extensions();
    207 				$success = true;
    208 				break;
    209 
    210 			case 'config':
    211 			case 'configuration':
    212 
    213 				$data['configuration'] = self::getConfiguration();
    214 				$success = true;
    215 
    216 				break;
    217 
    218 			default:
    219 		}
    220 
    221 		// Be safe! We must clear secret values.
    222 		array_walk_recursive($data, function(&$value,$key) {
    223 			if   ( stripos($key,'secret'  ) !== FALSE ||
    224 				   stripos($key,'password') !== FALSE ||
    225 				   stripos($key,'pass'    ) !== FALSE    )
    226 				$value = '**********';
    227 		});
    228 
    229 
    230 		header('Content-Type: application/json; charset=UTF-8');
    231 		$output = JSON::encode($data);
    232 
    233         if (!headers_sent()) {
    234             // HTTP Spec:
    235             // "Applications SHOULD use this field to indicate the transfer-length of the
    236         	//  message-body, unless this is prohibited by the rules in section 4.4."
    237             //
    238             // And the overhead of 'Transfer-Encoding: chunked' is eliminated...
    239 			header('HTTP/1.0 ' . ($success ? '200 OK' : '503 Internal Server Error') );
    240             header('Content-Length: ' . strlen($output));
    241 
    242 		}
    243 
    244 		echo $output;
    245     }
    246 
    247 
    248     private static function getConfiguration() {
    249 		$configFile = getenv( 'CMS_CONFIG_FILE' );
    250 		if   ( ! $configFile )
    251 			$configFile = Startup::DEFAULT_CONFIG_FILE;
    252 
    253 		$configLoader = new ConfigurationLoader( $configFile );
    254 		return  $configLoader->load();
    255 	}
    256 }