1<?php 2/* 3** Zabbix 4** Copyright (C) 2001-2021 Zabbix SIA 5** 6** This program is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2 of the License, or 9** (at your option) any later version. 10** 11** This program is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with this program; if not, write to the Free Software 18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19**/ 20 21 22require_once dirname(__FILE__).'/include/config.inc.php'; 23require_once dirname(__FILE__).'/include/hosts.inc.php'; 24require_once dirname(__FILE__).'/include/maintenances.inc.php'; 25require_once dirname(__FILE__).'/include/forms.inc.php'; 26 27$page['title'] = _('Configuration of maintenance periods'); 28$page['file'] = 'maintenance.php'; 29$page['scripts'] = ['class.cviewswitcher.js', 'class.calendar.js', 'multiselect.js']; 30 31require_once dirname(__FILE__).'/include/page_header.php'; 32 33// VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION 34$fields = [ 35 'hostids' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 36 'groupids' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 37 // maintenance 38 'maintenanceid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, 'isset({form}) && {form} == "update"'], 39 'maintenanceids' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, null], 40 'mname' => [T_ZBX_STR, O_OPT, null, NOT_EMPTY, 'isset({add}) || isset({update})', _('Name')], 41 'maintenance_type' => [T_ZBX_INT, O_OPT, null, null, 'isset({add}) || isset({update})'], 42 'description' => [T_ZBX_STR, O_OPT, null, null, 'isset({add}) || isset({update})'], 43 'active_since' => [T_ZBX_ABS_TIME, O_OPT, null, NOT_EMPTY, 44 'isset({add}) || isset({update})', _('Active since') 45 ], 46 'active_till' => [T_ZBX_ABS_TIME, O_OPT, null, NOT_EMPTY, 47 'isset({add}) || isset({update})', _('Active till') 48 ], 49 'timeperiods' => [T_ZBX_STR, O_OPT, null, null, null], 50 'tags_evaltype' => [T_ZBX_INT, O_OPT, null, null, null], 51 'tags' => [T_ZBX_STR, O_OPT, null, null, null], 52 // actions 53 'action' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, IN('"maintenance.massdelete"'), null], 54 'add' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 55 'update' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 56 'clone' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 57 'delete' => [T_ZBX_STR, O_OPT, P_SYS|P_ACT, null, null], 58 'cancel' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 59 // form 60 'form' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 61 'form_refresh' => [T_ZBX_INT, O_OPT, null, null, null], 62 // filter 63 'filter_set' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 64 'filter_rst' => [T_ZBX_STR, O_OPT, P_SYS, null, null], 65 'filter_name' => [T_ZBX_STR, O_OPT, null, null, null], 66 'filter_status' => [T_ZBX_INT, O_OPT, null, IN([-1, MAINTENANCE_STATUS_ACTIVE, MAINTENANCE_STATUS_APPROACH, MAINTENANCE_STATUS_EXPIRED]), null], 67 'filter_groups' => [T_ZBX_INT, O_OPT, null, DB_ID, null], 68 // sort and sortorder 69 'sort' => [T_ZBX_STR, O_OPT, P_SYS, 70 IN('"active_since","active_till","maintenance_type","name"'), 71 null 72 ], 73 'sortorder' => [T_ZBX_STR, O_OPT, P_SYS, IN('"'.ZBX_SORT_DOWN.'","'.ZBX_SORT_UP.'"'), 74 null 75 ] 76]; 77 78check_fields($fields); 79 80/* 81 * Permissions 82 */ 83if (isset($_REQUEST['maintenanceid'])) { 84 $dbMaintenance = API::Maintenance()->get([ 85 'output' => API_OUTPUT_EXTEND, 86 'selectTimeperiods' => API_OUTPUT_EXTEND, 87 'selectTags' => API_OUTPUT_EXTEND, 88 'editable' => true, 89 'maintenanceids' => getRequest('maintenanceid') 90 ]); 91 if (empty($dbMaintenance)) { 92 access_deny(); 93 } 94} 95if (hasRequest('action') && (!hasRequest('maintenanceids') || !is_array(getRequest('maintenanceids')))) { 96 access_deny(); 97} 98 99/* 100 * Actions 101 */ 102if (isset($_REQUEST['clone']) && isset($_REQUEST['maintenanceid'])) { 103 unset($_REQUEST['maintenanceid']); 104 $_REQUEST['form'] = 'clone'; 105} 106elseif (hasRequest('add') || hasRequest('update')) { 107 if (hasRequest('update')) { 108 $messageSuccess = _('Maintenance updated'); 109 $messageFailed = _('Cannot update maintenance'); 110 } 111 else { 112 $messageSuccess = _('Maintenance added'); 113 $messageFailed = _('Cannot add maintenance'); 114 } 115 116 $result = true; 117 $absolute_time_parser = new CAbsoluteTimeParser(); 118 119 $absolute_time_parser->parse(getRequest('active_since')); 120 $active_since_date = $absolute_time_parser->getDateTime(true); 121 122 $absolute_time_parser->parse(getRequest('active_till')); 123 $active_till_date = $absolute_time_parser->getDateTime(true); 124 125 if (!validateDateInterval($active_since_date->format('Y'), $active_since_date->format('m'), 126 $active_since_date->format('d'))) { 127 info(_s('"%1$s" must be between 1970.01.01 and 2038.01.18.', _('Active since'))); 128 $result = false; 129 } 130 131 if (!validateDateInterval($active_till_date->format('Y'), $active_till_date->format('m'), 132 $active_till_date->format('d'))) { 133 info(_s('"%1$s" must be between 1970.01.01 and 2038.01.18.', _('Active till'))); 134 $result = false; 135 } 136 137 if ($result) { 138 $timeperiods = getRequest('timeperiods', []); 139 140 foreach ($timeperiods as &$timeperiod) { 141 if ($timeperiod['timeperiod_type'] == TIMEPERIOD_TYPE_ONETIME) { 142 $absolute_time_parser->parse($timeperiod['start_date']); 143 $timeperiod['start_date'] = $absolute_time_parser 144 ->getDateTime(true) 145 ->getTimestamp(); 146 } 147 } 148 unset($timeperiod); 149 150 $maintenance = [ 151 'name' => $_REQUEST['mname'], 152 'maintenance_type' => getRequest('maintenance_type'), 153 'description' => getRequest('description'), 154 'active_since' => $active_since_date->getTimestamp(), 155 'active_till' => $active_till_date->getTimestamp(), 156 'timeperiods' => $timeperiods, 157 'hostids' => getRequest('hostids', []), 158 'groupids' => getRequest('groupids', []) 159 ]; 160 161 if ($maintenance['maintenance_type'] != MAINTENANCE_TYPE_NODATA) { 162 $maintenance += [ 163 'tags_evaltype' => getRequest('tags_evaltype', MAINTENANCE_TAG_EVAL_TYPE_AND_OR), 164 'tags' => getRequest('tags', []) 165 ]; 166 167 foreach ($maintenance['tags'] as $tnum => $tag) { 168 if ($tag['tag'] === '' && $tag['value'] === '') { 169 unset($maintenance['tags'][$tnum]); 170 } 171 } 172 } 173 174 if (isset($_REQUEST['maintenanceid'])) { 175 $maintenance['maintenanceid'] = $_REQUEST['maintenanceid']; 176 $result = API::Maintenance()->update($maintenance); 177 } 178 else { 179 $result = API::Maintenance()->create($maintenance); 180 } 181 } 182 183 if ($result) { 184 unset($_REQUEST['form']); 185 uncheckTableRows(); 186 } 187 188 show_messages($result, $messageSuccess, $messageFailed); 189} 190elseif (hasRequest('delete') || getRequest('action', '') == 'maintenance.massdelete') { 191 $maintenanceids = getRequest('maintenanceid', []); 192 if (hasRequest('maintenanceids')) { 193 $maintenanceids = getRequest('maintenanceids'); 194 } 195 196 zbx_value2array($maintenanceids); 197 198 $result = API::Maintenance()->delete($maintenanceids); 199 if ($result) { 200 unset($_REQUEST['form'], $_REQUEST['maintenanceid']); 201 uncheckTableRows(); 202 } 203 else { 204 $maintenances = API::Maintenance()->get([ 205 'maintenanceids' => getRequest('maintenanceids'), 206 'output' => [], 207 'editable' => true 208 ]); 209 uncheckTableRows(null, zbx_objectValues($maintenances, 'maintenanceid')); 210 } 211 212 show_messages($result, _('Maintenance deleted'), _('Cannot delete maintenance')); 213} 214 215/* 216 * Display 217 */ 218$data = [ 219 'form' => getRequest('form') 220]; 221 222if (!empty($data['form'])) { 223 $data['maintenanceid'] = getRequest('maintenanceid'); 224 $data['form_refresh'] = getRequest('form_refresh', 0); 225 226 if (isset($data['maintenanceid']) && !hasRequest('form_refresh')) { 227 $dbMaintenance = reset($dbMaintenance); 228 $data['mname'] = $dbMaintenance['name']; 229 $data['maintenance_type'] = $dbMaintenance['maintenance_type']; 230 $data['active_since'] = date(ZBX_DATE_TIME, $dbMaintenance['active_since']); 231 $data['active_till'] = date(ZBX_DATE_TIME, $dbMaintenance['active_till']); 232 $data['description'] = $dbMaintenance['description']; 233 234 // time periods 235 $data['timeperiods'] = $dbMaintenance['timeperiods']; 236 CArrayHelper::sort($data['timeperiods'], ['timeperiod_type', 'start_date']); 237 238 foreach ($data['timeperiods'] as &$timeperiod) { 239 $timeperiod['start_date'] = date(ZBX_DATE_TIME, $timeperiod['start_date']); 240 } 241 unset($timeperiod); 242 243 // get hosts 244 $db_hosts = API::Host()->get([ 245 'output' => ['hostid', 'name'], 246 'maintenanceids' => $data['maintenanceid'], 247 'editable' => true 248 ]); 249 250 // get groups 251 $db_groups = API::HostGroup()->get([ 252 'output' => ['groupid', 'name'], 253 'maintenanceids' => $data['maintenanceid'], 254 'editable' => true 255 ]); 256 257 // tags 258 $data['tags_evaltype'] = $dbMaintenance['tags_evaltype']; 259 $data['tags'] = $dbMaintenance['tags']; 260 CArrayHelper::sort($data['tags'], ['tag', 'value']); 261 } 262 else { 263 $data += [ 264 'mname' => getRequest('mname', ''), 265 'maintenance_type' => getRequest('maintenance_type', 0), 266 'active_since' => getRequest('active_since', date(ZBX_DATE_TIME, strtotime('today'))), 267 'active_till' => getRequest('active_till', date(ZBX_DATE_TIME, strtotime('tomorrow'))), 268 'description' => getRequest('description', ''), 269 'timeperiods' => getRequest('timeperiods', []), 270 'tags_evaltype' => getRequest('tags_evaltype', MAINTENANCE_TAG_EVAL_TYPE_AND_OR), 271 'tags' => getRequest('tags', []) 272 ]; 273 274 $hostids = getRequest('hostids', []); 275 $groupids = getRequest('groupids', []); 276 277 $db_hosts = $hostids 278 ? API::Host()->get([ 279 'output' => ['hostid', 'name'], 280 'hostids' => $hostids, 281 'editable' => true 282 ]) 283 : []; 284 285 $db_groups = $groupids 286 ? API::HostGroup()->get([ 287 'output' => ['groupid', 'name'], 288 'groupids' => $groupids, 289 'editable' => true 290 ]) 291 : []; 292 } 293 294 $data['hosts_ms'] = CArrayHelper::renameObjectsKeys($db_hosts, ['hostid' => 'id']); 295 CArrayHelper::sort($data['hosts_ms'], ['name']); 296 297 $data['groups_ms'] = CArrayHelper::renameObjectsKeys($db_groups, ['groupid' => 'id']); 298 CArrayHelper::sort($data['groups_ms'], ['name']); 299 300 // render view 301 echo (new CView('configuration.maintenance.edit', $data))->getOutput(); 302} 303else { 304 // get maintenances 305 $sortField = getRequest('sort', CProfile::get('web.'.$page['file'].'.sort', 'name')); 306 $sortOrder = getRequest('sortorder', CProfile::get('web.'.$page['file'].'.sortorder', ZBX_SORT_UP)); 307 308 CProfile::update('web.'.$page['file'].'.sort', $sortField, PROFILE_TYPE_STR); 309 CProfile::update('web.'.$page['file'].'.sortorder', $sortOrder, PROFILE_TYPE_STR); 310 311 // filter 312 if (hasRequest('filter_set')) { 313 CProfile::update('web.maintenance.filter_name', getRequest('filter_name', ''), PROFILE_TYPE_STR); 314 CProfile::update('web.maintenance.filter_status', getRequest('filter_status', -1), PROFILE_TYPE_INT); 315 CProfile::updateArray('web.maintenance.filter_groups', getRequest('filter_groups', []), PROFILE_TYPE_ID); 316 } 317 elseif (hasRequest('filter_rst')) { 318 CProfile::delete('web.maintenance.filter_name'); 319 CProfile::delete('web.maintenance.filter_status'); 320 CProfile::deleteIdx('web.maintenance.filter_groups'); 321 } 322 323 $filter = [ 324 'name' => CProfile::get('web.maintenance.filter_name', ''), 325 'status' => CProfile::get('web.maintenance.filter_status', -1), 326 'groups' => CProfile::getArray('web.maintenance.filter_groups', []) 327 ]; 328 329 // Get host groups. 330 $filter['groups'] = $filter['groups'] 331 ? CArrayHelper::renameObjectsKeys(API::HostGroup()->get([ 332 'output' => ['groupid', 'name'], 333 'groupids' => $filter['groups'], 334 'editable' => true, 335 'preservekeys' => true 336 ]), ['groupid' => 'id']) 337 : []; 338 339 $filter_groupids = $filter['groups'] ? array_keys($filter['groups']) : null; 340 if ($filter_groupids) { 341 $filter_groupids = getSubGroups($filter_groupids); 342 } 343 344 $config = select_config(); 345 346 $data = [ 347 'sort' => $sortField, 348 'sortorder' => $sortOrder, 349 'filter' => $filter, 350 'profileIdx' => 'web.maintenance.filter', 351 'active_tab' => CProfile::get('web.maintenance.filter.active', 1) 352 ]; 353 354 // Get list of maintenances. 355 $options = [ 356 'output' => ['maintenanceid', 'name', 'maintenance_type', 'active_since', 'active_till', 'description'], 357 'search' => [ 358 'name' => ($filter['name'] === '') ? null : $filter['name'] 359 ], 360 'groupids' => $filter_groupids, 361 'editable' => true, 362 'sortfield' => $sortField, 363 'sortorder' => $sortOrder, 364 'limit' => $config['search_limit'] + 1 365 ]; 366 367 $data['maintenances'] = API::Maintenance()->get($options); 368 369 foreach ($data['maintenances'] as $key => $maintenance) { 370 if ($maintenance['active_till'] < time()) { 371 $data['maintenances'][$key]['status'] = MAINTENANCE_STATUS_EXPIRED; 372 } 373 elseif ($maintenance['active_since'] > time()) { 374 $data['maintenances'][$key]['status'] = MAINTENANCE_STATUS_APPROACH; 375 } 376 else { 377 $data['maintenances'][$key]['status'] = MAINTENANCE_STATUS_ACTIVE; 378 } 379 } 380 381 // filter by status 382 if ($filter['status'] != -1) { 383 foreach ($data['maintenances'] as $key => $maintenance) { 384 if ($data['maintenances'][$key]['status'] != $filter['status']) { 385 unset($data['maintenances'][$key]); 386 } 387 } 388 } 389 390 order_result($data['maintenances'], $sortField, $sortOrder); 391 392 // pager 393 if (hasRequest('page')) { 394 $page_num = getRequest('page'); 395 } 396 elseif (isRequestMethod('get') && !hasRequest('cancel')) { 397 $page_num = 1; 398 } 399 else { 400 $page_num = CPagerHelper::loadPage($page['file']); 401 } 402 403 CPagerHelper::savePage($page['file'], $page_num); 404 405 $data['paging'] = CPagerHelper::paginate($page_num, $data['maintenances'], $sortOrder, new CUrl('maintenance.php')); 406 407 // render view 408 echo (new CView('configuration.maintenance.list', $data))->getOutput(); 409} 410 411require_once dirname(__FILE__).'/include/page_footer.php'; 412