예제 #1
0
 /**
  * Mass update hosts
  *
  * @param _array $hosts multidimensional array with Hosts data
  * @param array $hosts['hosts'] Array of Host objects to update
  * @param string $hosts['fields']['host'] Host name.
  * @param array $hosts['fields']['groupids'] HostGroup IDs add Host to.
  * @param int $hosts['fields']['port'] Port. OPTIONAL
  * @param int $hosts['fields']['status'] Host Status. OPTIONAL
  * @param int $hosts['fields']['useip'] Use IP. OPTIONAL
  * @param string $hosts['fields']['dns'] DNS. OPTIONAL
  * @param string $hosts['fields']['ip'] IP. OPTIONAL
  * @param int $hosts['fields']['proxy_hostid'] Proxy Host ID. OPTIONAL
  * @param int $hosts['fields']['useipmi'] Use IPMI. OPTIONAL
  * @param string $hosts['fields']['ipmi_ip'] IPMAI IP. OPTIONAL
  * @param int $hosts['fields']['ipmi_port'] IPMI port. OPTIONAL
  * @param int $hosts['fields']['ipmi_authtype'] IPMI authentication type. OPTIONAL
  * @param int $hosts['fields']['ipmi_privilege'] IPMI privilege. OPTIONAL
  * @param string $hosts['fields']['ipmi_username'] IPMI username. OPTIONAL
  * @param string $hosts['fields']['ipmi_password'] IPMI password. OPTIONAL
  * @return boolean
  */
 public static function massUpdate($data)
 {
     $hosts = zbx_toArray($data['hosts']);
     $hostids = zbx_objectValues($hosts, 'hostid');
     try {
         self::BeginTransaction(__METHOD__);
         $options = array('hostids' => $hostids, 'editable' => 1, 'output' => API_OUTPUT_EXTEND, 'preservekeys' => 1);
         $upd_hosts = self::get($options);
         foreach ($hosts as $hnum => $host) {
             if (!isset($upd_hosts[$host['hostid']])) {
                 self::exception(ZBX_API_ERROR_PERMISSIONS, S_NO_PERMISSION);
             }
         }
         // CHECK IF HOSTS HAVE AT LEAST 1 GROUP {{{
         if (isset($data['groups']) && empty($data['groups'])) {
             self::exception(ZBX_API_ERROR_PARAMETERS, 'No groups for hosts');
         }
         // }}} CHECK IF HOSTS HAVE AT LEAST 1 GROUP
         // UPDATE HOSTS PROPERTIES {{{
         if (isset($data['host'])) {
             if (count($hosts) > 1) {
                 self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot mass update host name');
             }
             $cur_host = reset($hosts);
             $options = array('filter' => array('host' => $cur_host['host']), 'output' => API_OUTPUT_SHORTEN, 'editable' => 1, 'nopermissions' => 1);
             $host_exists = self::get($options);
             $host_exist = reset($host_exists);
             if ($host_exist && $host_exist['hostid'] != $cur_host['hostid']) {
                 self::exception(ZBX_API_ERROR_PARAMETERS, S_HOST . ' [ ' . $data['host'] . ' ] ' . S_ALREADY_EXISTS_SMALL);
             }
             //can't add host with the same name as existing template
             if (CTemplate::exists(array('host' => $cur_host['host']))) {
                 self::exception(ZBX_API_ERROR_PARAMETERS, S_TEMPLATE . ' [ ' . $cur_host['host'] . ' ] ' . S_ALREADY_EXISTS_SMALL);
             }
         }
         if (isset($data['host']) && !preg_match('/^' . ZBX_PREG_HOST_FORMAT . '$/i', $data['host'])) {
             self::exception(ZBX_API_ERROR_PARAMETERS, 'Incorrect characters used for Hostname [ ' . $data['host'] . ' ]');
         }
         if (isset($data['dns']) && !empty($data['dns']) && !preg_match('/^' . ZBX_PREG_DNS_FORMAT . '$/i', $data['dns'])) {
             self::exception(ZBX_API_ERROR_PARAMETERS, 'Incorrect characters used for DNS [ ' . $data['dns'] . ' ]');
         }
         $sql_set = array();
         if (isset($data['proxy_hostid'])) {
             $sql_set[] = 'proxy_hostid=' . $data['proxy_hostid'];
         }
         if (isset($data['host'])) {
             $sql_set[] = 'host=' . zbx_dbstr($data['host']);
         }
         if (isset($data['port'])) {
             $sql_set[] = 'port=' . $data['port'];
         }
         if (isset($data['status'])) {
             $sql_set[] = 'status=' . $data['status'];
         }
         if (isset($data['useip'])) {
             $sql_set[] = 'useip=' . $data['useip'];
         }
         if (isset($data['dns'])) {
             $sql_set[] = 'dns=' . zbx_dbstr($data['dns']);
         }
         if (isset($data['ip'])) {
             $sql_set[] = 'ip=' . zbx_dbstr($data['ip']);
         }
         if (isset($data['useipmi'])) {
             $sql_set[] = 'useipmi=' . $data['useipmi'];
         }
         if (isset($data['ipmi_port'])) {
             $sql_set[] = 'ipmi_port=' . $data['ipmi_port'];
         }
         if (isset($data['ipmi_authtype'])) {
             $sql_set[] = 'ipmi_authtype=' . $data['ipmi_authtype'];
         }
         if (isset($data['ipmi_privilege'])) {
             $sql_set[] = 'ipmi_privilege=' . $data['ipmi_privilege'];
         }
         if (isset($data['ipmi_username'])) {
             $sql_set[] = 'ipmi_username='******'ipmi_username']);
         }
         if (isset($data['ipmi_password'])) {
             $sql_set[] = 'ipmi_password='******'ipmi_password']);
         }
         if (isset($data['ipmi_ip'])) {
             $sql_set[] = 'ipmi_ip=' . zbx_dbstr($data['ipmi_ip']);
         }
         if (!empty($sql_set)) {
             $sql = 'UPDATE hosts SET ' . implode(', ', $sql_set) . ' WHERE ' . DBcondition('hostid', $hostids);
             $result = DBexecute($sql);
             if (isset($data['status'])) {
                 update_host_status($hostids, $data['status']);
             }
         }
         // }}} UPDATE HOSTS PROPERTIES
         // UPDATE HOSTGROUPS LINKAGE {{{
         if (isset($data['groups']) && !is_null($data['groups'])) {
             $data['groups'] = zbx_toArray($data['groups']);
             $host_groups = CHostGroup::get(array('hostids' => $hostids));
             $host_groupids = zbx_objectValues($host_groups, 'groupid');
             $new_groupids = zbx_objectValues($data['groups'], 'groupid');
             $groups_to_add = array_diff($new_groupids, $host_groupids);
             if (!empty($groups_to_add)) {
                 $result = self::massAdd(array('hosts' => $hosts, 'groups' => zbx_toObject($groups_to_add, 'groupid')));
                 if (!$result) {
                     self::exception(ZBX_API_ERROR_PARAMETERS, 'Can\'t add group');
                 }
             }
             $groupids_to_del = array_diff($host_groupids, $new_groupids);
             if (!empty($groupids_to_del)) {
                 $result = self::massRemove(array('hostids' => $hostids, 'groupids' => $groupids_to_del));
                 if (!$result) {
                     self::exception(ZBX_API_ERROR_PARAMETERS, 'Can\'t remove group');
                 }
             }
         }
         // }}} UPDATE HOSTGROUPS LINKAGE
         $data['templates_clear'] = isset($data['templates_clear']) ? zbx_toArray($data['templates_clear']) : array();
         $cleared_templateids = array();
         foreach ($hostids as $hostid) {
             foreach ($data['templates_clear'] as $tpl) {
                 $result = unlink_template($hostid, $tpl['templateid'], false);
                 if (!$result) {
                     self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot unlink template [ ' . $tpl['templateid'] . ' ]');
                 }
                 $cleared_templateids[] = $tpl['templateid'];
             }
         }
         // UPDATE TEMPLATE LINKAGE {{{
         if (isset($data['templates']) && !is_null($data['templates'])) {
             $opt = array('hostids' => $hostids, 'output' => API_OUTPUT_SHORTEN, 'preservekeys' => true);
             $host_templates = CTemplate::get($opt);
             $host_templateids = array_keys($host_templates);
             $new_templateids = zbx_objectValues($data['templates'], 'templateid');
             $templates_to_del = array_diff($host_templateids, $new_templateids);
             $templates_to_del = array_diff($templates_to_del, $cleared_templateids);
             if (!empty($templates_to_del)) {
                 $result = self::massRemove(array('hostids' => $hostids, 'templateids' => $templates_to_del));
                 if (!$result) {
                     self::exception(ZBX_API_ERROR_PARAMETERS, S_CANNOT_UNLINK_TEMPLATE);
                 }
             }
             $result = self::massAdd(array('hosts' => $hosts, 'templates' => $data['templates']));
             if (!$result) {
                 self::exception(ZBX_API_ERROR_PARAMETERS, S_CANNOT_LINK_TEMPLATE);
             }
         }
         // }}} UPDATE TEMPLATE LINKAGE
         // UPDATE MACROS {{{
         if (isset($data['macros']) && !is_null($data['macros'])) {
             $macrosToAdd = zbx_toHash($data['macros'], 'macro');
             $hostMacros = CUserMacro::get(array('hostids' => $hostids, 'output' => API_OUTPUT_EXTEND));
             $hostMacros = zbx_toHash($hostMacros, 'macro');
             // Delete
             $macrosToDelete = array();
             foreach ($hostMacros as $hmnum => $hmacro) {
                 if (!isset($macrosToAdd[$hmacro['macro']])) {
                     $macrosToDelete[] = $hmacro['macro'];
                 }
             }
             // Update
             $macrosToUpdate = array();
             foreach ($macrosToAdd as $nhmnum => $nhmacro) {
                 if (isset($hostMacros[$nhmacro['macro']])) {
                     $macrosToUpdate[] = $nhmacro;
                     unset($macrosToAdd[$nhmnum]);
                 }
             }
             //----
             if (!empty($macrosToDelete)) {
                 $result = self::massRemove(array('hostids' => $hostids, 'macros' => $macrosToDelete));
                 if (!$result) {
                     self::exception(ZBX_API_ERROR_PARAMETERS, 'Can\'t remove macro');
                 }
             }
             if (!empty($macrosToUpdate)) {
                 $result = CUsermacro::massUpdate(array('hosts' => $hosts, 'macros' => $macrosToUpdate));
                 if (!$result) {
                     self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot update macro');
                 }
             }
             if (!empty($macrosToAdd)) {
                 $result = self::massAdd(array('hosts' => $hosts, 'macros' => $macrosToAdd));
                 if (!$result) {
                     self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot add macro');
                 }
             }
         }
         // }}} UPDATE MACROS
         // PROFILE {{{
         if (isset($data['profile']) && !is_null($data['profile'])) {
             if (empty($data['profile'])) {
                 $sql = 'DELETE FROM hosts_profiles WHERE ' . DBcondition('hostid', $hostids);
                 if (!DBexecute($sql)) {
                     self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot delete profile');
                 }
             } else {
                 $existing_profiles = array();
                 $existing_profiles_db = DBselect('SELECT hostid FROM hosts_profiles WHERE ' . DBcondition('hostid', $hostids));
                 while ($existing_profile = DBfetch($existing_profiles_db)) {
                     $existing_profiles[] = $existing_profile['hostid'];
                 }
                 $hostids_without_profile = array_diff($hostids, $existing_profiles);
                 $fields = array_keys($data['profile']);
                 $fields = implode(', ', $fields);
                 $values = array_map('zbx_dbstr', $data['profile']);
                 $values = implode(', ', $values);
                 foreach ($hostids_without_profile as $hostid) {
                     $sql = 'INSERT INTO hosts_profiles (hostid, ' . $fields . ') VALUES (' . $hostid . ', ' . $values . ')';
                     if (!DBexecute($sql)) {
                         self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot create profile');
                     }
                 }
                 if (!empty($existing_profiles)) {
                     $host_profile_fields = array('devicetype', 'name', 'os', 'serialno', 'tag', 'macaddress', 'hardware', 'software', 'contact', 'location', 'notes');
                     $sql_set = array();
                     foreach ($host_profile_fields as $field) {
                         if (isset($data['profile'][$field])) {
                             $sql_set[] = $field . '=' . zbx_dbstr($data['profile'][$field]);
                         }
                     }
                     $sql = 'UPDATE hosts_profiles SET ' . implode(', ', $sql_set) . ' WHERE ' . DBcondition('hostid', $existing_profiles);
                     if (!DBexecute($sql)) {
                         self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot update profile');
                     }
                 }
             }
         }
         // }}} PROFILE
         // EXTENDED PROFILE {{{
         if (isset($data['extendedProfile']) && !is_null($data['extendedProfile'])) {
             if (empty($data['extendedProfile'])) {
                 $sql = 'DELETE FROM hosts_profiles_ext WHERE ' . DBcondition('hostid', $hostids);
                 if (!DBexecute($sql)) {
                     self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot delete extended profile');
                 }
             } else {
                 $existing_profiles = array();
                 $existing_profiles_db = DBselect('SELECT hostid FROM hosts_profiles_ext WHERE ' . DBcondition('hostid', $hostids));
                 while ($existing_profile = DBfetch($existing_profiles_db)) {
                     $existing_profiles[] = $existing_profile['hostid'];
                 }
                 $hostids_without_profile = array_diff($hostids, $existing_profiles);
                 $fields = array_keys($data['extendedProfile']);
                 $fields = implode(', ', $fields);
                 $values = array_map('zbx_dbstr', $data['extendedProfile']);
                 $values = implode(', ', $values);
                 foreach ($hostids_without_profile as $hostid) {
                     $sql = 'INSERT INTO hosts_profiles_ext (hostid, ' . $fields . ') VALUES (' . $hostid . ', ' . $values . ')';
                     if (!DBexecute($sql)) {
                         self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot create extended profile');
                     }
                 }
                 if (!empty($existing_profiles)) {
                     $host_profile_ext_fields = array('device_alias', 'device_type', 'device_chassis', 'device_os', 'device_os_short', 'device_hw_arch', 'device_serial', 'device_model', 'device_tag', 'device_vendor', 'device_contract', 'device_who', 'device_status', 'device_app_01', 'device_app_02', 'device_app_03', 'device_app_04', 'device_app_05', 'device_url_1', 'device_url_2', 'device_url_3', 'device_networks', 'device_notes', 'device_hardware', 'device_software', 'ip_subnet_mask', 'ip_router', 'ip_macaddress', 'oob_ip', 'oob_subnet_mask', 'oob_router', 'date_hw_buy', 'date_hw_install', 'date_hw_expiry', 'date_hw_decomm', 'site_street_1', 'site_street_2', 'site_street_3', 'site_city', 'site_state', 'site_country', 'site_zip', 'site_rack', 'site_notes', 'poc_1_name', 'poc_1_email', 'poc_1_phone_1', 'poc_1_phone_2', 'poc_1_cell', 'poc_1_screen', 'poc_1_notes', 'poc_2_name', 'poc_2_email', 'poc_2_phone_1', 'poc_2_phone_2', 'poc_2_cell', 'poc_2_screen', 'poc_2_notes');
                     $sql_set = array();
                     foreach ($host_profile_ext_fields as $field) {
                         if (isset($data['extendedProfile'][$field])) {
                             $sql_set[] = $field . '=' . zbx_dbstr($data['extendedProfile'][$field]);
                         }
                     }
                     $sql = 'UPDATE hosts_profiles_ext SET ' . implode(', ', $sql_set) . ' WHERE ' . DBcondition('hostid', $existing_profiles);
                     if (!DBexecute($sql)) {
                         self::exception(ZBX_API_ERROR_PARAMETERS, 'Cannot update extended profile');
                     }
                 }
             }
         }
         // }}} EXTENDED PROFILE
         self::EndTransaction(true, __METHOD__);
         return array('hostids' => $hostids);
     } catch (APIException $e) {
         self::EndTransaction(false, __METHOD__);
         $error = $e->getErrors();
         $error = reset($error);
         self::setError(__METHOD__, $e->getCode(), $error);
         return false;
     }
 }
예제 #2
0
 public static function parseMain($rules)
 {
     $triggers_for_dependencies = array();
     try {
         if (isset($rules['host']['exist']) || isset($rules['host']['missed'])) {
             $xpath = new DOMXPath(self::$xml);
             $hosts = $xpath->query('hosts/host');
             foreach ($hosts as $hnum => $host) {
                 $host_db = self::mapXML2arr($host, XML_TAG_HOST);
                 if (!isset($host_db['status'])) {
                     $host_db['status'] = HOST_STATUS_TEMPLATE;
                 }
                 $current_host = $host_db['status'] == HOST_STATUS_TEMPLATE ? CTemplate::exists($host_db) : CHost::exists($host_db);
                 if (!$current_host && !isset($rules['host']['missed'])) {
                     info('Host [' . $host_db['host'] . '] skipped - user rule');
                     continue;
                     // break if update nonexist
                 }
                 if ($current_host && !isset($rules['host']['exist'])) {
                     info('Host [' . $host_db['host'] . '] skipped - user rule');
                     continue;
                     // break if not update exist
                 }
                 if (isset($host_db['proxy_hostid'])) {
                     $proxy_exists = CProxy::get(array('proxyids' => $host_db['proxy_hostid']));
                     if (empty($proxy_exists)) {
                         $host_db['proxy_hostid'] = 0;
                     }
                 }
                 if ($current_host) {
                     $options = array('filter' => array('host' => $host_db['host']), 'output' => API_OUTPUT_EXTEND, 'editable' => 1);
                     if ($host_db['status'] == HOST_STATUS_TEMPLATE) {
                         $current_host = CTemplate::get($options);
                     } else {
                         $current_host = CHost::get($options);
                     }
                     if (empty($current_host)) {
                         throw new APIException(1, 'No permission for host [' . $host_db['host'] . ']');
                     } else {
                         $current_host = reset($current_host);
                     }
                 }
                 // HOST GROUPS {{{
                 $groups = $xpath->query('groups/group', $host);
                 $host_db['groups'] = array();
                 $groups_to_parse = array();
                 foreach ($groups as $gnum => $group) {
                     $groups_to_parse[] = array('name' => $group->nodeValue);
                 }
                 if (empty($groups_to_parse)) {
                     $groups_to_parse[] = array('name' => ZBX_DEFAULT_IMPORT_HOST_GROUP);
                 }
                 foreach ($groups_to_parse as $group) {
                     $current_group = CHostGroup::exists($group);
                     if ($current_group) {
                         $options = array('filter' => $group, 'output' => API_OUTPUT_EXTEND, 'editable' => 1);
                         $current_group = CHostGroup::get($options);
                         if (empty($current_group)) {
                             throw new APIException(1, 'No permissions for group ' . $group['name']);
                         }
                         $host_db['groups'][] = reset($current_group);
                     } else {
                         $result = CHostGroup::create($group);
                         if (!$result) {
                             throw new APIException(1, CHostGroup::resetErrors());
                         }
                         $options = array('groupids' => $result['groupids'], 'output' => API_OUTPUT_EXTEND);
                         $new_group = CHostgroup::get($options);
                         $host_db['groups'][] = reset($new_group);
                     }
                 }
                 // }}} HOST GROUPS
                 // MACROS
                 $macros = $xpath->query('macros/macro', $host);
                 $host_db['macros'] = array();
                 if ($macros->length > 0) {
                     foreach ($macros as $macro) {
                         $host_db['macros'][] = self::mapXML2arr($macro, XML_TAG_MACRO);
                     }
                 }
                 // }}} MACROS
                 // TEMPLATES {{{
                 if (isset($rules['template']['exist'])) {
                     $templates = $xpath->query('templates/template', $host);
                     $host_db['templates'] = array();
                     foreach ($templates as $tnum => $template) {
                         $options = array('filter' => array('host' => $template->nodeValue), 'output' => API_OUTPUT_EXTEND, 'editable' => 1);
                         $current_template = CTemplate::get($options);
                         if (empty($current_template)) {
                             throw new APIException(1, 'No permission for Template [' . $template->nodeValue . ']');
                         }
                         $current_template = reset($current_template);
                         if (!$current_template && !isset($rules['template']['missed'])) {
                             info('Template [' . $template->nodeValue . '] skipped - user rule');
                             continue;
                             // break if update nonexist
                         }
                         if ($current_template && !isset($rules['template']['exist'])) {
                             info('Template [' . $template->nodeValue . '] skipped - user rule');
                             continue;
                             // break if not update exist
                         }
                         $host_db['templates'][] = $current_template;
                     }
                 }
                 // }}} TEMPLATES
                 // HOSTS
                 if ($current_host && isset($rules['host']['exist'])) {
                     if ($host_db['status'] == HOST_STATUS_TEMPLATE) {
                         $host_db['templateid'] = $current_host['hostid'];
                         $result = CTemplate::update($host_db);
                         if (!$result) {
                             throw new APIException(1, CTemplate::resetErrors());
                         }
                         $options = array('templateids' => $result['templateids'], 'output' => API_OUTPUT_EXTEND);
                         $current_host = CTemplate::get($options);
                     } else {
                         $host_db['hostid'] = $current_host['hostid'];
                         $result = CHost::update($host_db);
                         if (!$result) {
                             throw new APIException(1, CHost::resetErrors());
                         }
                         $options = array('hostids' => $result['hostids'], 'output' => API_OUTPUT_EXTEND);
                         $current_host = CHost::get($options);
                     }
                     if ($current_host === false) {
                         throw new APIException(1, $host_db['status'] == HOST_STATUS_TEMPLATE ? CTemplate::resetErrors() : CHost::resetErrors());
                     }
                 }
                 if (!$current_host && isset($rules['host']['missed'])) {
                     if ($host_db['status'] == HOST_STATUS_TEMPLATE) {
                         $result = CTemplate::create($host_db);
                         if (!$result) {
                             throw new APIException(1, CTemplate::resetErrors());
                         }
                         $options = array('templateids' => $result['templateids'], 'output' => API_OUTPUT_EXTEND);
                         $current_host = CTemplate::get($options);
                     } else {
                         $result = CHost::create($host_db);
                         if (!$result) {
                             throw new APIException(1, CHost::resetErrors());
                         }
                         $options = array('hostids' => $result['hostids'], 'output' => API_OUTPUT_EXTEND);
                         $current_host = CHost::get($options);
                     }
                 }
                 $current_host = reset($current_host);
                 // HOST PROFILES {{{
                 $profile_node = $xpath->query('host_profile/*', $host);
                 if ($profile_node->length > 0) {
                     $profile = array();
                     foreach ($profile_node as $num => $field) {
                         $profile[$field->nodeName] = $field->nodeValue;
                     }
                     delete_host_profile($current_host['hostid']);
                     add_host_profile($current_host['hostid'], $profile['devicetype'], $profile['name'], $profile['os'], $profile['serialno'], $profile['tag'], $profile['macaddress'], $profile['hardware'], $profile['software'], $profile['contact'], $profile['location'], $profile['notes']);
                 }
                 $profile_ext_node = $xpath->query('host_profiles_ext/*', $host);
                 if ($profile_ext_node->length > 0) {
                     $profile_ext = array();
                     foreach ($profile_ext_node as $num => $field) {
                         $profile_ext[$field->nodeName] = $field->nodeValue;
                     }
                     delete_host_profile_ext($current_host['hostid']);
                     add_host_profile_ext($current_host['hostid'], $profile_ext);
                 }
                 // }}} HOST PROFILES
                 // ITEMS {{{
                 if (isset($rules['item']['exist']) || isset($rules['item']['missed'])) {
                     $items = $xpath->query('items/item', $host);
                     foreach ($items as $inum => $item) {
                         $item_db = self::mapXML2arr($item, XML_TAG_ITEM);
                         $item_db['hostid'] = $current_host['hostid'];
                         if ($current_item = CItem::exists($item_db)) {
                             $options = array('filter' => array('hostid' => $item_db['hostid'], 'key_' => $item_db['key_']), 'webitems' => 1, 'output' => API_OUTPUT_EXTEND, 'editable' => 1);
                             $current_item = CItem::get($options);
                             if (empty($current_item)) {
                                 throw new APIException(1, 'No permission for Item [' . $item_db['key_'] . ']');
                             }
                             $current_item = reset($current_item);
                         }
                         if (!$current_item && !isset($rules['item']['missed'])) {
                             info('Item [' . $item_db['key_'] . '] skipped - user rule');
                             continue;
                             // break if not update exist
                         }
                         if ($current_item && !isset($rules['item']['exist'])) {
                             info('Item [' . $item_db['key_'] . '] skipped - user rule');
                             continue;
                             // break if not update exist
                         }
                         // ITEM APPLICATIONS {{{
                         $applications = $xpath->query('applications/application', $item);
                         $item_applications = array();
                         $applications_to_add = array();
                         foreach ($applications as $application) {
                             $application_db = array('name' => $application->nodeValue, 'hostid' => $current_host['hostid']);
                             if ($current_application = CApplication::exists($application_db)) {
                                 $current_application = CApplication::get(array('filter' => $application_db, 'output' => API_OUTPUT_EXTEND));
                                 if (empty($current_application)) {
                                     throw new APIException(1, 'No permission for Application [' . $application_db['name'] . ']');
                                 }
                             }
                             if ($current_application) {
                                 $item_applications = array_merge($item_applications, $current_application);
                             } else {
                                 $applications_to_add[] = $application_db;
                             }
                         }
                         if (!empty($applications_to_add)) {
                             $result = CApplication::create($applications_to_add);
                             if (!$result) {
                                 throw new APIException(1, CApplication::resetErrors());
                             }
                             $options = array('applicationids' => $result['applicationids'], 'output' => API_OUTPUT_EXTEND);
                             $new_applications = CApplication::get($options);
                             $item_applications = array_merge($item_applications, $new_applications);
                         }
                         // }}} ITEM APPLICATIONS
                         if ($current_item && isset($rules['item']['exist'])) {
                             $item_db['itemid'] = $current_item['itemid'];
                             $result = CItem::update($item_db);
                             if (!$result) {
                                 throw new APIException(1, CItem::resetErrors());
                             }
                             $options = array('itemids' => $result['itemids'], 'webitems' => 1, 'output' => API_OUTPUT_EXTEND);
                             $current_item = CItem::get($options);
                         }
                         if (!$current_item && isset($rules['item']['missed'])) {
                             $result = CItem::create($item_db);
                             if (!$result) {
                                 throw new APIException(1, CItem::resetErrors());
                             }
                             $options = array('itemids' => $result['itemids'], 'webitems' => 1, 'output' => API_OUTPUT_EXTEND);
                             $current_item = CItem::get($options);
                         }
                         $r = CApplication::massAdd(array('applications' => $item_applications, 'items' => $current_item));
                         if ($r === false) {
                             throw new APIException(1, CApplication::resetErrors());
                         }
                     }
                 }
                 // }}} ITEMS
                 // TRIGGERS {{{
                 if (isset($rules['trigger']['exist']) || isset($rules['trigger']['missed'])) {
                     $triggers = $xpath->query('triggers/trigger', $host);
                     $triggers_to_add = array();
                     $triggers_to_upd = array();
                     foreach ($triggers as $trigger) {
                         $trigger_db = self::mapXML2arr($trigger, XML_TAG_TRIGGER);
                         $trigger_db['expression'] = str_replace('{{HOSTNAME}:', '{' . $host_db['host'] . ':', $trigger_db['expression']);
                         $trigger_db['hostid'] = $current_host['hostid'];
                         if ($current_trigger = CTrigger::exists($trigger_db)) {
                             $ctriggers = CTrigger::get(array('filter' => array('description' => $trigger_db['description']), 'hostids' => $current_host['hostid'], 'output' => API_OUTPUT_EXTEND, 'editable' => 1));
                             $current_trigger = false;
                             foreach ($ctriggers as $tnum => $ct) {
                                 $tmp_exp = explode_exp($ct['expression'], false);
                                 if (strcmp($trigger_db['expression'], $tmp_exp) == 0) {
                                     $current_trigger = $ct;
                                     break;
                                 }
                             }
                             if (!$current_trigger) {
                                 throw new APIException(1, 'No permission for Trigger [' . $trigger_db['description'] . ']');
                             }
                         }
                         if (!$current_trigger && !isset($rules['trigger']['missed'])) {
                             info('Trigger [' . $trigger_db['description'] . '] skipped - user rule');
                             continue;
                             // break if not update exist
                         }
                         if ($current_trigger && !isset($rules['trigger']['exist'])) {
                             info('Trigger [' . $trigger_db['description'] . '] skipped - user rule');
                             continue;
                             // break if not update exist
                         }
                         if ($current_trigger && isset($rules['trigger']['exist'])) {
                             $trigger_db['triggerid'] = $current_trigger['triggerid'];
                             $triggers_to_upd[] = $trigger_db;
                         }
                         if (!$current_trigger && isset($rules['trigger']['missed'])) {
                             $triggers_to_add[] = $trigger_db;
                         }
                     }
                     if (!empty($triggers_to_upd)) {
                         $result = CTrigger::update($triggers_to_upd);
                         if (!$result) {
                             throw new APIException(1, CTrigger::resetErrors());
                         }
                         $options = array('triggerids' => $result['triggerids'], 'output' => API_OUTPUT_EXTEND);
                         $r = CTrigger::get($options);
                         $triggers_for_dependencies = array_merge($triggers_for_dependencies, $r);
                     }
                     if (!empty($triggers_to_add)) {
                         $result = CTrigger::create($triggers_to_add);
                         if (!$result) {
                             throw new APIException(1, CTrigger::resetErrors());
                         }
                         $options = array('triggerids' => $result['triggerids'], 'output' => API_OUTPUT_EXTEND);
                         $r = CTrigger::get($options);
                         $triggers_for_dependencies = array_merge($triggers_for_dependencies, $r);
                     }
                 }
                 // }}} TRIGGERS
                 // GRAPHS {{{
                 if (isset($rules['graph']['exist']) || isset($rules['graph']['missed'])) {
                     $graphs = $xpath->query('graphs/graph', $host);
                     $graphs_to_add = array();
                     $graphs_to_upd = array();
                     foreach ($graphs as $gnum => $graph) {
                         // GRAPH ITEMS {{{
                         $gitems = $xpath->query('graph_elements/graph_element', $graph);
                         $graph_hostids = array();
                         $graph_items = array();
                         foreach ($gitems as $ginum => $gitem) {
                             $gitem_db = self::mapXML2arr($gitem, XML_TAG_GRAPH_ELEMENT);
                             $data = explode(':', $gitem_db['host_key_']);
                             $gitem_host = array_shift($data);
                             $gitem_db['host'] = $gitem_host == '{HOSTNAME}' ? $host_db['host'] : $gitem_host;
                             $gitem_db['key_'] = implode(':', $data);
                             if ($current_item = CItem::exists($gitem_db)) {
                                 $current_item = CItem::get(array('filter' => array('key_' => $gitem_db['key_']), 'webitems' => 1, 'host' => $gitem_db['host'], 'output' => API_OUTPUT_EXTEND, 'editable' => 1));
                                 if (empty($current_item)) {
                                     throw new APIException(1, 'No permission for Item [' . $gitem_db['key_'] . ']');
                                 }
                                 $current_item = reset($current_item);
                                 $graph_hostids[] = $current_item['hostid'];
                                 $gitem_db['itemid'] = $current_item['itemid'];
                                 $graph_items[] = $gitem_db;
                             } else {
                                 throw new APIException(1, 'Item [' . $gitem_db['host_key_'] . '] does not exists');
                             }
                         }
                         // }}} GRAPH ITEMS
                         $graph_db = self::mapXML2arr($graph, XML_TAG_GRAPH);
                         $graph_db['hostids'] = $graph_hostids;
                         if ($current_graph = CGraph::exists($graph_db)) {
                             $current_graph = CGraph::get(array('filter' => array('name' => $graph_db['name']), 'hostids' => $graph_db['hostids'], 'output' => API_OUTPUT_EXTEND, 'editable' => 1));
                             if (empty($current_graph)) {
                                 throw new APIException(1, 'No permission for Graph [' . $graph_db['name'] . ']');
                             }
                             $current_graph = reset($current_graph);
                         }
                         if (!$current_graph && !isset($rules['graph']['missed'])) {
                             info('Graph [' . $graph_db['name'] . '] skipped - user rule');
                             continue;
                             // break if not update exist
                         }
                         if ($current_graph && !isset($rules['graph']['exist'])) {
                             info('Graph [' . $graph_db['name'] . '] skipped - user rule');
                             continue;
                             // break if not update exist
                         }
                         if ($graph_db['ymin_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) {
                             $item_data = explode(':', $graph_db['ymin_item_key'], 2);
                             if (count($item_data) < 2) {
                                 throw new APIException(1, 'Incorrect y min item for graph [' . $graph_db['name'] . ']');
                             }
                             if (!($item = get_item_by_key($item_data[1], $item_data[0]))) {
                                 throw new APIException(1, 'Missing item [' . $graph_db['ymin_item_key'] . '] for host [' . $host_db['host'] . ']');
                             }
                             $graph_db['ymin_itemid'] = $item['itemid'];
                         }
                         if ($graph_db['ymax_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) {
                             $item_data = explode(':', $graph_db['ymax_item_key'], 2);
                             if (count($item_data) < 2) {
                                 throw new APIException(1, 'Incorrect y max item for graph [' . $graph_db['name'] . ']');
                             }
                             if (!($item = get_item_by_key($item_data[1], $item_data[0]))) {
                                 throw new APIException(1, 'Missing item [' . $graph_db['ymax_item_key'] . '] for host [' . $host_db['host'] . ']');
                             }
                             $graph_db['ymax_itemid'] = $item['itemid'];
                         }
                         $graph_db['gitems'] = $graph_items;
                         if ($current_graph) {
                             $graph_db['graphid'] = $current_graph['graphid'];
                             $graphs_to_upd[] = $graph_db;
                         } else {
                             $graphs_to_add[] = $graph_db;
                         }
                     }
                     if (!empty($graphs_to_add)) {
                         $r = CGraph::create($graphs_to_add);
                         if ($r === false) {
                             throw new APIException(1, CGraph::resetErrors());
                         }
                     }
                     if (!empty($graphs_to_upd)) {
                         $r = CGraph::update($graphs_to_upd);
                         if ($r === false) {
                             throw new APIException(1, CGraph::resetErrors());
                         }
                     }
                 }
             }
             // DEPENDENCIES
             $dependencies = $xpath->query('dependencies/dependency');
             if ($dependencies->length > 0) {
                 $triggers_for_dependencies = zbx_objectValues($triggers_for_dependencies, 'triggerid');
                 $triggers_for_dependencies = array_flip($triggers_for_dependencies);
                 foreach ($dependencies as $dependency) {
                     $triggers_to_add_dep = array();
                     $trigger_description = $dependency->getAttribute('description');
                     $current_triggerid = get_trigger_by_description($trigger_description);
                     // sdi('<b><u>Trigger Description: </u></b>'.$trigger_description.' | <b>Current_triggerid: </b>'. $current_triggerid['triggerid']);
                     if ($current_triggerid && isset($triggers_for_dependencies[$current_triggerid['triggerid']])) {
                         $depends_on_list = $xpath->query('depends', $dependency);
                         foreach ($depends_on_list as $depends_on) {
                             $depends_triggerid = get_trigger_by_description($depends_on->nodeValue);
                             // sdi('<b>depends on description: </b>'.$depends_on->nodeValue.' | <b>depends_triggerid: </b>'. $depends_triggerid['triggerid']);
                             if ($depends_triggerid['triggerid']) {
                                 $triggers_to_add_dep[] = $depends_triggerid['triggerid'];
                             }
                         }
                         $r = update_trigger($current_triggerid['triggerid'], null, $current_triggerid['description'], null, null, null, null, null, $triggers_to_add_dep, null);
                         if ($r === false) {
                             throw new APIException();
                         }
                     }
                 }
             }
         }
         return true;
     } catch (APIException $e) {
         error($e->getErrors());
         return false;
     }
 }