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', 'class.tab-indicators.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$allowed_edit = CWebUser::checkAccess(CRoleHelper::ACTIONS_EDIT_MAINTENANCE); 100 101if (!$allowed_edit && hasRequest('form') && getRequest('form') !== 'update') { 102 access_deny(ACCESS_DENY_PAGE); 103} 104 105/* 106 * Actions 107 */ 108if (isset($_REQUEST['clone']) && isset($_REQUEST['maintenanceid'])) { 109 unset($_REQUEST['maintenanceid']); 110 $_REQUEST['form'] = 'clone'; 111} 112elseif (hasRequest('add') || hasRequest('update')) { 113 if (!$allowed_edit) { 114 access_deny(ACCESS_DENY_PAGE); 115 } 116 117 if (hasRequest('update')) { 118 $messageSuccess = _('Maintenance updated'); 119 $messageFailed = _('Cannot update maintenance'); 120 } 121 else { 122 $messageSuccess = _('Maintenance added'); 123 $messageFailed = _('Cannot add maintenance'); 124 } 125 126 $result = true; 127 $absolute_time_parser = new CAbsoluteTimeParser(); 128 129 $absolute_time_parser->parse(getRequest('active_since')); 130 $active_since_date = $absolute_time_parser->getDateTime(true); 131 132 $absolute_time_parser->parse(getRequest('active_till')); 133 $active_till_date = $absolute_time_parser->getDateTime(true); 134 135 if (!validateDateInterval($active_since_date->format('Y'), $active_since_date->format('m'), 136 $active_since_date->format('d'))) { 137 info(_s('"%1$s" must be between 1970.01.01 and 2038.01.18.', _('Active since'))); 138 $result = false; 139 } 140 141 if (!validateDateInterval($active_till_date->format('Y'), $active_till_date->format('m'), 142 $active_till_date->format('d'))) { 143 info(_s('"%1$s" must be between 1970.01.01 and 2038.01.18.', _('Active till'))); 144 $result = false; 145 } 146 147 if ($result) { 148 $timeperiods = getRequest('timeperiods', []); 149 150 foreach ($timeperiods as &$timeperiod) { 151 if ($timeperiod['timeperiod_type'] == TIMEPERIOD_TYPE_ONETIME) { 152 $absolute_time_parser->parse($timeperiod['start_date']); 153 $timeperiod['start_date'] = $absolute_time_parser 154 ->getDateTime(true) 155 ->getTimestamp(); 156 } 157 } 158 unset($timeperiod); 159 160 $maintenance = [ 161 'name' => $_REQUEST['mname'], 162 'maintenance_type' => getRequest('maintenance_type'), 163 'description' => getRequest('description'), 164 'active_since' => $active_since_date->getTimestamp(), 165 'active_till' => $active_till_date->getTimestamp(), 166 'timeperiods' => $timeperiods, 167 'hostids' => getRequest('hostids', []), 168 'groupids' => getRequest('groupids', []) 169 ]; 170 171 if ($maintenance['maintenance_type'] != MAINTENANCE_TYPE_NODATA) { 172 $maintenance += [ 173 'tags_evaltype' => getRequest('tags_evaltype', MAINTENANCE_TAG_EVAL_TYPE_AND_OR), 174 'tags' => getRequest('tags', []) 175 ]; 176 177 foreach ($maintenance['tags'] as $tnum => $tag) { 178 if ($tag['tag'] === '' && $tag['value'] === '') { 179 unset($maintenance['tags'][$tnum]); 180 } 181 } 182 } 183 184 if (isset($_REQUEST['maintenanceid'])) { 185 $maintenance['maintenanceid'] = $_REQUEST['maintenanceid']; 186 $result = API::Maintenance()->update($maintenance); 187 } 188 else { 189 $result = API::Maintenance()->create($maintenance); 190 } 191 } 192 193 if ($result) { 194 unset($_REQUEST['form']); 195 uncheckTableRows(); 196 } 197 198 show_messages($result, $messageSuccess, $messageFailed); 199} 200elseif (hasRequest('delete') || getRequest('action', '') == 'maintenance.massdelete') { 201 if (!$allowed_edit) { 202 access_deny(ACCESS_DENY_PAGE); 203 } 204 205 $maintenanceids = getRequest('maintenanceid', []); 206 if (hasRequest('maintenanceids')) { 207 $maintenanceids = getRequest('maintenanceids'); 208 } 209 210 zbx_value2array($maintenanceids); 211 212 $result = API::Maintenance()->delete($maintenanceids); 213 if ($result) { 214 unset($_REQUEST['form'], $_REQUEST['maintenanceid']); 215 uncheckTableRows(); 216 } 217 else { 218 $maintenances = API::Maintenance()->get([ 219 'maintenanceids' => getRequest('maintenanceids'), 220 'output' => [], 221 'editable' => true 222 ]); 223 uncheckTableRows(null, zbx_objectValues($maintenances, 'maintenanceid')); 224 } 225 226 show_messages($result, _('Maintenance deleted'), _('Cannot delete maintenance')); 227} 228 229/* 230 * Display 231 */ 232$data = [ 233 'form' => getRequest('form'), 234 'allowed_edit' => $allowed_edit 235]; 236 237if (!empty($data['form'])) { 238 $data['maintenanceid'] = getRequest('maintenanceid'); 239 $data['form_refresh'] = getRequest('form_refresh', 0); 240 241 if (isset($data['maintenanceid']) && !hasRequest('form_refresh')) { 242 $dbMaintenance = reset($dbMaintenance); 243 $data['mname'] = $dbMaintenance['name']; 244 $data['maintenance_type'] = $dbMaintenance['maintenance_type']; 245 $data['active_since'] = date(ZBX_DATE_TIME, $dbMaintenance['active_since']); 246 $data['active_till'] = date(ZBX_DATE_TIME, $dbMaintenance['active_till']); 247 $data['description'] = $dbMaintenance['description']; 248 249 // time periods 250 $data['timeperiods'] = $dbMaintenance['timeperiods']; 251 CArrayHelper::sort($data['timeperiods'], ['timeperiod_type', 'start_date']); 252 253 foreach ($data['timeperiods'] as &$timeperiod) { 254 $timeperiod['start_date'] = date(ZBX_DATE_TIME, $timeperiod['start_date']); 255 } 256 unset($timeperiod); 257 258 // get hosts 259 $db_hosts = API::Host()->get([ 260 'output' => ['hostid', 'name'], 261 'maintenanceids' => $data['maintenanceid'], 262 'editable' => true 263 ]); 264 265 // get groups 266 $db_groups = API::HostGroup()->get([ 267 'output' => ['groupid', 'name'], 268 'maintenanceids' => $data['maintenanceid'], 269 'editable' => true 270 ]); 271 272 // tags 273 $data['tags_evaltype'] = $dbMaintenance['tags_evaltype']; 274 $data['tags'] = $dbMaintenance['tags']; 275 CArrayHelper::sort($data['tags'], ['tag', 'value']); 276 } 277 else { 278 $data += [ 279 'mname' => getRequest('mname', ''), 280 'maintenance_type' => getRequest('maintenance_type', 0), 281 'active_since' => getRequest('active_since', date(ZBX_DATE_TIME, strtotime('today'))), 282 'active_till' => getRequest('active_till', date(ZBX_DATE_TIME, strtotime('tomorrow'))), 283 'description' => getRequest('description', ''), 284 'timeperiods' => getRequest('timeperiods', []), 285 'tags_evaltype' => getRequest('tags_evaltype', MAINTENANCE_TAG_EVAL_TYPE_AND_OR), 286 'tags' => getRequest('tags', []) 287 ]; 288 289 $hostids = getRequest('hostids', []); 290 $groupids = getRequest('groupids', []); 291 292 $db_hosts = $hostids 293 ? API::Host()->get([ 294 'output' => ['hostid', 'name'], 295 'hostids' => $hostids, 296 'editable' => true 297 ]) 298 : []; 299 300 $db_groups = $groupids 301 ? API::HostGroup()->get([ 302 'output' => ['groupid', 'name'], 303 'groupids' => $groupids, 304 'editable' => true 305 ]) 306 : []; 307 } 308 309 $data['hosts_ms'] = CArrayHelper::renameObjectsKeys($db_hosts, ['hostid' => 'id']); 310 CArrayHelper::sort($data['hosts_ms'], ['name']); 311 312 $data['groups_ms'] = CArrayHelper::renameObjectsKeys($db_groups, ['groupid' => 'id']); 313 CArrayHelper::sort($data['groups_ms'], ['name']); 314 315 // render view 316 echo (new CView('configuration.maintenance.edit', $data))->getOutput(); 317} 318else { 319 // get maintenances 320 $sortField = getRequest('sort', CProfile::get('web.'.$page['file'].'.sort', 'name')); 321 $sortOrder = getRequest('sortorder', CProfile::get('web.'.$page['file'].'.sortorder', ZBX_SORT_UP)); 322 323 CProfile::update('web.'.$page['file'].'.sort', $sortField, PROFILE_TYPE_STR); 324 CProfile::update('web.'.$page['file'].'.sortorder', $sortOrder, PROFILE_TYPE_STR); 325 326 // filter 327 if (hasRequest('filter_set')) { 328 CProfile::update('web.maintenance.filter_name', getRequest('filter_name', ''), PROFILE_TYPE_STR); 329 CProfile::update('web.maintenance.filter_status', getRequest('filter_status', -1), PROFILE_TYPE_INT); 330 CProfile::updateArray('web.maintenance.filter_groups', getRequest('filter_groups', []), PROFILE_TYPE_ID); 331 } 332 elseif (hasRequest('filter_rst')) { 333 CProfile::delete('web.maintenance.filter_name'); 334 CProfile::delete('web.maintenance.filter_status'); 335 CProfile::deleteIdx('web.maintenance.filter_groups'); 336 } 337 338 $filter = [ 339 'name' => CProfile::get('web.maintenance.filter_name', ''), 340 'status' => CProfile::get('web.maintenance.filter_status', -1), 341 'groups' => CProfile::getArray('web.maintenance.filter_groups', []) 342 ]; 343 344 // Get host groups. 345 $filter['groups'] = $filter['groups'] 346 ? CArrayHelper::renameObjectsKeys(API::HostGroup()->get([ 347 'output' => ['groupid', 'name'], 348 'groupids' => $filter['groups'], 349 'editable' => true, 350 'preservekeys' => true 351 ]), ['groupid' => 'id']) 352 : []; 353 354 $filter_groupids = $filter['groups'] ? array_keys($filter['groups']) : null; 355 if ($filter_groupids) { 356 $filter_groupids = getSubGroups($filter_groupids); 357 } 358 359 $data = [ 360 'sort' => $sortField, 361 'sortorder' => $sortOrder, 362 'filter' => $filter, 363 'profileIdx' => 'web.maintenance.filter', 364 'active_tab' => CProfile::get('web.maintenance.filter.active', 1), 365 'allowed_edit' => $allowed_edit 366 ]; 367 368 // Get list of maintenances. 369 $options = [ 370 'output' => ['maintenanceid', 'name', 'maintenance_type', 'active_since', 'active_till', 'description'], 371 'search' => [ 372 'name' => ($filter['name'] === '') ? null : $filter['name'] 373 ], 374 'groupids' => $filter_groupids, 375 'editable' => true, 376 'sortfield' => $sortField, 377 'sortorder' => $sortOrder, 378 'limit' => CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT) + 1 379 ]; 380 381 $data['maintenances'] = API::Maintenance()->get($options); 382 383 foreach ($data['maintenances'] as $key => $maintenance) { 384 if ($maintenance['active_till'] < time()) { 385 $data['maintenances'][$key]['status'] = MAINTENANCE_STATUS_EXPIRED; 386 } 387 elseif ($maintenance['active_since'] > time()) { 388 $data['maintenances'][$key]['status'] = MAINTENANCE_STATUS_APPROACH; 389 } 390 else { 391 $data['maintenances'][$key]['status'] = MAINTENANCE_STATUS_ACTIVE; 392 } 393 } 394 395 // filter by status 396 if ($filter['status'] != -1) { 397 foreach ($data['maintenances'] as $key => $maintenance) { 398 if ($data['maintenances'][$key]['status'] != $filter['status']) { 399 unset($data['maintenances'][$key]); 400 } 401 } 402 } 403 404 order_result($data['maintenances'], $sortField, $sortOrder); 405 406 // pager 407 if (hasRequest('page')) { 408 $page_num = getRequest('page'); 409 } 410 elseif (isRequestMethod('get') && !hasRequest('cancel')) { 411 $page_num = 1; 412 } 413 else { 414 $page_num = CPagerHelper::loadPage($page['file']); 415 } 416 417 CPagerHelper::savePage($page['file'], $page_num); 418 419 $data['paging'] = CPagerHelper::paginate($page_num, $data['maintenances'], $sortOrder, new CUrl('maintenance.php')); 420 421 // render view 422 echo (new CView('configuration.maintenance.list', $data))->getOutput(); 423} 424 425require_once dirname(__FILE__).'/include/page_footer.php'; 426