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 22/** 23 * Check if user has read permissions for host groups. 24 * 25 * @param array $groupids 26 * 27 * @return bool 28 */ 29function isReadableHostGroups(array $groupids) { 30 return count($groupids) == API::HostGroup()->get([ 31 'countOutput' => true, 32 'groupids' => $groupids 33 ]); 34} 35 36/** 37 * Check if user has write permissions for host groups. 38 * 39 * @param array $groupids 40 * 41 * @return bool 42 */ 43function isWritableHostGroups(array $groupids) { 44 return count($groupids) == API::HostGroup()->get([ 45 'countOutput' => true, 46 'groupids' => $groupids, 47 'editable' => true 48 ]); 49} 50 51/** 52 * Returns list of child groups for host group with given name. 53 * 54 * @param string $name Host group name. 55 */ 56function getChildGroupIds($name) { 57 $parent = $name.'/'; 58 $len = strlen($parent); 59 60 $groups = API::HostGroup()->get([ 61 'output' => ['groupid', 'name'], 62 'search' => ['name' => $parent], 63 'startSearch' => true 64 ]); 65 66 $child_groupids = []; 67 foreach ($groups as $group) { 68 if (substr($group['name'], 0, $len) === $parent) { 69 $child_groupids[] = $group['groupid']; 70 } 71 } 72 73 return $child_groupids; 74} 75 76/** 77 * Apply host group rights to all subgroups. 78 * 79 * @param string $groupid Host group ID. 80 * @param string $name Host group name. 81 */ 82function inheritPermissions($groupid, $name) { 83 $child_groupids = getChildGroupIds($name); 84 85 if (!$child_groupids) { 86 return; 87 } 88 89 $usrgrps = API::UserGroup()->get([ 90 'output' => ['usrgrpid'], 91 'selectRights' => ['id', 'permission'] 92 ]); 93 94 $upd_usrgrps = []; 95 96 foreach ($usrgrps as $usrgrp) { 97 $rights = zbx_toHash($usrgrp['rights'], 'id'); 98 99 if (array_key_exists($groupid, $rights)) { 100 foreach ($child_groupids as $child_groupid) { 101 $rights[$child_groupid] = [ 102 'id' => $child_groupid, 103 'permission' => $rights[$groupid]['permission'] 104 ]; 105 } 106 } 107 else { 108 foreach ($child_groupids as $child_groupid) { 109 unset($rights[$child_groupid]); 110 } 111 } 112 113 $rights = array_values($rights); 114 115 if ($usrgrp['rights'] !== $rights) { 116 $upd_usrgrps[] = [ 117 'usrgrpid' => $usrgrp['usrgrpid'], 118 'rights' => $rights 119 ]; 120 } 121 } 122 123 if ($upd_usrgrps) { 124 API::UserGroup()->update($upd_usrgrps); 125 } 126} 127 128/** 129 * Add subgroups with tag filters inherited from main host group ($groupid) to all user groups in which tag filters for 130 * particular group are created. 131 * 132 * @param string $groupid Host group ID. 133 * @param string $name Host group name. 134 */ 135function inheritTagFilters($groupid, $name) { 136 $child_groupids = getChildGroupIds($name); 137 138 if (!$child_groupids) { 139 return; 140 } 141 142 $usrgrps = API::UserGroup()->get([ 143 'output' => ['usrgrpid'], 144 'selectTagFilters' => ['groupid', 'tag', 'value'] 145 ]); 146 147 $upd_usrgrps = []; 148 149 foreach ($usrgrps as $usrgrp) { 150 $tag_filters = []; 151 152 foreach ($usrgrp['tag_filters'] as $tag_filter) { 153 $tag_filters[$tag_filter['groupid']][] = [ 154 'tag' => $tag_filter['tag'], 155 'value' => $tag_filter['value'] 156 ]; 157 } 158 159 if (array_key_exists($groupid, $tag_filters)) { 160 foreach ($child_groupids as $child_groupid) { 161 $tag_filters[$child_groupid] = $tag_filters[$groupid]; 162 } 163 } 164 else { 165 foreach ($child_groupids as $child_groupid) { 166 unset($tag_filters[$child_groupid]); 167 } 168 } 169 170 $upd_tag_filters = []; 171 172 foreach ($tag_filters as $tag_filter_groupid => $tags) { 173 foreach ($tags as $tag) { 174 $upd_tag_filters[] = ['groupid' => (string) $tag_filter_groupid] + $tag; 175 } 176 } 177 178 if ($usrgrp['tag_filters'] !== $upd_tag_filters) { 179 $upd_usrgrps[] = [ 180 'usrgrpid' => $usrgrp['usrgrpid'], 181 'tag_filters' => $upd_tag_filters 182 ]; 183 } 184 } 185 186 if ($upd_usrgrps) { 187 API::UserGroup()->update($upd_usrgrps); 188 } 189} 190 191/** 192 * Get sub-groups of selected host groups. 193 * 194 * @param array $groupids 195 * @param array $ms_groups [OUT] the list of groups for multiselect 196 * 197 * @return array 198 */ 199function getSubGroups(array $groupids, array &$ms_groups = null) { 200 $db_groups = $groupids 201 ? API::HostGroup()->get([ 202 'output' => ['groupid', 'name'], 203 'groupids' => $groupids, 204 'preservekeys' => true 205 ]) 206 : []; 207 208 if ($ms_groups !== null) { 209 $ms_groups = CArrayHelper::renameObjectsKeys($db_groups, ['groupid' => 'id']); 210 } 211 212 $db_groups_names = []; 213 214 foreach ($db_groups as $db_group) { 215 $db_groups_names[] = $db_group['name'].'/'; 216 } 217 218 if ($db_groups_names) { 219 $child_groups = API::HostGroup()->get([ 220 'output' => ['groupid'], 221 'search' => ['name' => $db_groups_names], 222 'searchByAny' => true, 223 'startSearch' => true 224 ]); 225 226 foreach ($child_groups as $child_group) { 227 $groupids[] = $child_group['groupid']; 228 } 229 } 230 231 return $groupids; 232} 233 234/* 235 * Creates a hintbox suitable for Problem hosts widget. 236 * 237 * @param array $hosts Array of problematic hosts. 238 * @param array $data Array of host data, filter settings and 239 * severity configuration. 240 * @param array $data['config'] Severities configuration array. 241 * @param array $data['filter']['severities'] Array of severities. 242 * @param string $data['hosts_data'][<hostid>]['host'] Host name. 243 * @param int $data['hosts_data'][<hostid>]['severities'][<severity>] Severity count. 244 * @param CUrl $url URL that leads to problems view having hostid 245 * in its filter. 246 * 247 * @return CTableInfo 248 */ 249function makeProblemHostsHintBox(array $hosts, array $data, CUrl $url) { 250 // Set trigger severities as table header, ordered starting from highest severity. 251 $header = [_('Host')]; 252 253 foreach (range(TRIGGER_SEVERITY_COUNT - 1, TRIGGER_SEVERITY_NOT_CLASSIFIED) as $severity) { 254 if (in_array($severity, $data['filter']['severities'])) { 255 $header[] = getSeverityName($severity, $data['config']); 256 } 257 } 258 259 $maintenanceids = []; 260 foreach ($data['hosts_data'] as $host) { 261 if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { 262 $maintenanceids[$host['maintenanceid']] = true; 263 } 264 } 265 266 $db_maintenances = $maintenanceids 267 ? API::Maintenance()->get([ 268 'output' => ['name', 'description'], 269 'maintenanceids' => array_keys($maintenanceids), 270 'preservekeys' => true 271 ]) 272 : []; 273 274 $table_inf = (new CTableInfo())->setHeader($header); 275 276 $popup_rows = 0; 277 278 foreach ($hosts as $hostid => $host) { 279 $host_data = $data['hosts_data'][$hostid]; 280 $url->setArgument('filter_hostids', [$hostid]); 281 $host_name = new CLink($host_data['host'], $url->getUrl()); 282 283 if ($host_data['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { 284 if (array_key_exists($host_data['maintenanceid'], $db_maintenances)) { 285 $maintenance = $db_maintenances[$host_data['maintenanceid']]; 286 $maintenance_icon = makeMaintenanceIcon($host_data['maintenance_type'], $maintenance['name'], 287 $maintenance['description'] 288 ); 289 } 290 else { 291 $maintenance_icon = makeMaintenanceIcon($host_data['maintenance_type'], _('Inaccessible maintenance'), 292 '' 293 ); 294 } 295 296 $host_name = [$host_name, $maintenance_icon]; 297 } 298 299 $row = new CRow((new CCol($host_name))->addClass(ZBX_STYLE_NOWRAP)); 300 301 foreach (range(TRIGGER_SEVERITY_COUNT - 1, TRIGGER_SEVERITY_NOT_CLASSIFIED) as $severity) { 302 if (in_array($severity, $data['filter']['severities'])) { 303 $row->addItem( 304 ($host_data['severities'][$severity] != 0) 305 ? (new CCol($host_data['severities'][$severity]))->addClass(getSeverityStyle($severity)) 306 : '' 307 ); 308 } 309 } 310 311 $table_inf->addRow($row); 312 313 if (++$popup_rows == ZBX_WIDGET_ROWS) { 314 break; 315 } 316 } 317 318 return $table_inf; 319} 320 321/** 322 * Enriches host groups array by parent groups. 323 * 324 * @param array $groups 325 * @param string $groups[<groupid>]['groupid'] 326 * @param string $groups[<groupid>]['name'] 327 * @param array $options HostGroup API call parameters. 328 * 329 * @return array 330 */ 331function enrichParentGroups(array $groups, array $options = []) { 332 $parents = []; 333 foreach ($groups as $group) { 334 $parent = explode('/', $group['name']); 335 while (array_pop($parent) && $parent) { 336 $parents[implode('/', $parent)] = true; 337 } 338 } 339 340 if ($parents) { 341 foreach ($groups as $group) { 342 if (array_key_exists($group['name'], $parents)) { 343 unset($parents[$group['name']]); 344 } 345 } 346 } 347 348 if ($parents) { 349 if (!array_key_exists('output', $options)) { 350 $options['output'] = ['groupid', 'name']; 351 } 352 353 if (!array_key_exists('filter', $options)) { 354 $options['filter'] = []; 355 } 356 357 $options['filter']['name'] = array_keys($parents); 358 359 $options['preservekeys'] = true; 360 $groups += API::HostGroup()->get($options); 361 } 362 363 return $groups; 364} 365