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 * @param array $options additional API options to select host groups. 197 * 198 * @return array 199 */ 200function getSubGroups(array $groupids, array &$ms_groups = null, array $options = []) { 201 $db_groups = $groupids 202 ? API::HostGroup()->get([ 203 'output' => ['groupid', 'name'], 204 'groupids' => $groupids, 205 'preservekeys' => true 206 ] + $options) 207 : []; 208 209 if ($ms_groups !== null) { 210 $ms_groups = CArrayHelper::renameObjectsKeys($db_groups, ['groupid' => 'id']); 211 } 212 213 $db_groups_names = []; 214 215 foreach ($db_groups as $db_group) { 216 $db_groups_names[] = $db_group['name'].'/'; 217 } 218 219 if ($db_groups_names) { 220 $db_groups += API::HostGroup()->get([ 221 'output' => ['groupid'], 222 'search' => ['name' => $db_groups_names], 223 'searchByAny' => true, 224 'startSearch' => true, 225 'preservekeys' => true 226 ] + $options); 227 } 228 229 return array_keys($db_groups); 230} 231 232/* 233 * Creates a hintbox suitable for Problem hosts widget. 234 * 235 * @param array $hosts Array of problematic hosts. 236 * @param array $data Array of host data, filter settings and 237 * severity configuration. 238 * @param array $data['config'] Severities configuration array. 239 * @param array $data['filter']['severities'] Array of severities. 240 * @param string $data['hosts_data'][<hostid>]['host'] Host name. 241 * @param int $data['hosts_data'][<hostid>]['severities'][<severity>] Severity count. 242 * @param CUrl $url URL that leads to problems view having hostid 243 * in its filter. 244 * 245 * @return CTableInfo 246 */ 247function makeProblemHostsHintBox(array $hosts, array $data, CUrl $url) { 248 // Set trigger severities as table header, ordered starting from highest severity. 249 $header = [_('Host')]; 250 251 foreach (range(TRIGGER_SEVERITY_COUNT - 1, TRIGGER_SEVERITY_NOT_CLASSIFIED) as $severity) { 252 if (in_array($severity, $data['filter']['severities'])) { 253 $header[] = getSeverityName($severity, $data['config']); 254 } 255 } 256 257 $maintenanceids = []; 258 foreach ($data['hosts_data'] as $host) { 259 if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { 260 $maintenanceids[$host['maintenanceid']] = true; 261 } 262 } 263 264 $db_maintenances = $maintenanceids 265 ? API::Maintenance()->get([ 266 'output' => ['name', 'description'], 267 'maintenanceids' => array_keys($maintenanceids), 268 'preservekeys' => true 269 ]) 270 : []; 271 272 $table_inf = (new CTableInfo())->setHeader($header); 273 274 $popup_rows = 0; 275 276 foreach ($hosts as $hostid => $host) { 277 $host_data = $data['hosts_data'][$hostid]; 278 $url->setArgument('filter_hostids', [$hostid]); 279 $host_name = new CLink($host_data['host'], $url->getUrl()); 280 281 if ($host_data['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { 282 if (array_key_exists($host_data['maintenanceid'], $db_maintenances)) { 283 $maintenance = $db_maintenances[$host_data['maintenanceid']]; 284 $maintenance_icon = makeMaintenanceIcon($host_data['maintenance_type'], $maintenance['name'], 285 $maintenance['description'] 286 ); 287 } 288 else { 289 $maintenance_icon = makeMaintenanceIcon($host_data['maintenance_type'], _('Inaccessible maintenance'), 290 '' 291 ); 292 } 293 294 $host_name = [$host_name, $maintenance_icon]; 295 } 296 297 $row = new CRow((new CCol($host_name))->addClass(ZBX_STYLE_NOWRAP)); 298 299 foreach (range(TRIGGER_SEVERITY_COUNT - 1, TRIGGER_SEVERITY_NOT_CLASSIFIED) as $severity) { 300 if (in_array($severity, $data['filter']['severities'])) { 301 $row->addItem( 302 ($host_data['severities'][$severity] != 0) 303 ? (new CCol($host_data['severities'][$severity]))->addClass(getSeverityStyle($severity)) 304 : '' 305 ); 306 } 307 } 308 309 $table_inf->addRow($row); 310 311 if (++$popup_rows == ZBX_WIDGET_ROWS) { 312 break; 313 } 314 } 315 316 return $table_inf; 317} 318 319/** 320 * Enriches host groups array by parent groups. 321 * 322 * @param array $groups 323 * @param string $groups[<groupid>]['groupid'] 324 * @param string $groups[<groupid>]['name'] 325 * 326 * @return array 327 */ 328function enrichParentGroups(array $groups) { 329 $parents = []; 330 foreach ($groups as $group) { 331 $parent = explode('/', $group['name']); 332 while (array_pop($parent) && $parent) { 333 $parents[implode('/', $parent)] = true; 334 } 335 } 336 337 if ($parents) { 338 foreach ($groups as $group) { 339 if (array_key_exists($group['name'], $parents)) { 340 unset($parents[$group['name']]); 341 } 342 } 343 } 344 345 if ($parents) { 346 $groups += API::HostGroup()->get([ 347 'output' => ['groupid', 'name'], 348 'filter' => [ 349 'name' => array_keys($parents) 350 ], 351 'preservekeys' => true 352 ]); 353 } 354 355 return $groups; 356} 357