array( 'filter' => FILTER_VALIDATE_INT, 'pageset' => true, 'default' => '-1' ), 'paged' => array( 'filter' => FILTER_VALIDATE_INT, 'default' => '1' ), 'host_status' => array( 'filter' => FILTER_VALIDATE_INT, 'pageset' => true, 'default' => '-1' ), 'host_template_id' => array( 'filter' => FILTER_VALIDATE_INT, 'pageset' => true, 'default' => '-1' ), 'filterd' => array( 'filter' => FILTER_CALLBACK, 'pageset' => true, 'default' => '', 'options' => array('options' => 'sanitize_search_string') ), 'sort_column' => array( 'filter' => FILTER_CALLBACK, 'default' => 'description', 'options' => array('options' => 'sanitize_search_string') ), 'sort_direction' => array( 'filter' => FILTER_CALLBACK, 'default' => 'ASC', 'options' => array('options' => 'sanitize_search_string') ), 'has_graphs' => array( 'filter' => FILTER_VALIDATE_REGEXP, 'options' => array('options' => array('regexp' => '(true|false)')), 'pageset' => true, 'default' => 'true' ) ); validate_store_request_vars($filters, 'sess_auto'); /* ================= input validation ================= */ /* if the number of rows is -1, set it to the default */ if (get_request_var('rowsd') == -1) { $rows = read_config_option('num_rows_table'); }else{ $rows = get_request_var('rowsd'); } if ((!empty($_SESSION['sess_automation_host_status'])) && (!isempty_request_var('host_status'))) { if ($_SESSION['sess_automation_host_status'] != get_request_var('host_status')) { set_request_var('paged', '1'); } } ?>
| '> | '> | '> |
'; print_r($item); print ''; $operation = ($item['operation'] != 0) ? $automation_oper{$item['operation']} : ' '; form_alternate_row(); $form_data = '
'; print_r($item); print ''; $field_name = ($item['field'] === AUTOMATION_TREE_ITEM_TYPE_STRING) ? $automation_tree_header_types[AUTOMATION_TREE_ITEM_TYPE_STRING] : $item['field']; form_alternate_row(); $form_data = '
'; print $sql_query; print''; cacti_log(__FUNCTION__ . ' returns: ' . $sql_query, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); return $sql_query; } function build_matching_objects_filter($rule_id, $rule_type) { cacti_log(__FUNCTION__ . " called rule id: $rule_id", false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); $sql_filter = ''; /* create an SQL which queries all host related tables in a huge join * this way, we may add any where clause that might be added via * 'Matching Device' match */ $sql = "SELECT * FROM automation_match_rule_items WHERE rule_id=$rule_id AND rule_type=$rule_type ORDER BY sequence"; $rule_items = db_fetch_assoc($sql); #print '
Items: $sql'; if (sizeof($rule_items)) { # $sql_order = build_sort_order($xml_array['index_order_type'], 'automation_host'); # $sql_query = build_data_query_sql($rule); $sql_filter = build_rule_item_filter($rule_items); # print 'SQL Query: ' . $sql_query . '
'; print_r($rule_items); print '
'; print_r($fields); print ''; # remove unwanted entries $fields = array_minus($fields, $excluded_fields); # now reformat entries for use with draw_edit_form if (sizeof($fields)) { foreach ($fields as $key => $value) { switch($table) { case 'graph_templates_graph': $table = 'gtg'; break; case 'host': $table = 'h'; break; case 'host_template': $table = 'ht'; break; case 'graph_templates': $table = 'gt'; break; } # we want to know later which table was selected $new_key = $table . '.' . $key; # give the user a hint abou the data type of the column $new_fields[$new_key] = strtoupper($table) . ': ' . $key . ' - ' . $value; } } return $new_fields; } /* * get_field_names * @arg $snmp_query_id snmp query id * return all field names for that snmp query, taken from snmp_cache */ function get_field_names($snmp_query_id) { cacti_log(__FUNCTION__ . " called: $snmp_query_id", false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* get the unique field values from the database */ $sql = 'SELECT DISTINCT field_name FROM host_snmp_cache WHERE snmp_query_id=' . $snmp_query_id; $field_names = db_fetch_assoc($sql); return db_fetch_assoc($sql); } function array_to_list($array, $sql_column) { /* if the last item is null; pop it off */ if ((empty($array{count($array)-1})) && (sizeof($array) > 1)) { array_pop($array); } if (count($array) > 0) { $sql = '('; for ($i=0;($i
'; print_r($query_fields); print ''; } elseif ($automation_rule['leaf_type'] == TREE_ITEM_TYPE_GRAPH) { $title = 'Graph Match Rule'; $tables = array ('host', 'host_templates'); # add some more filter columns for a GRAPH match $query_fields += get_query_fields('graph_templates', array('id', 'hash')); $query_fields += array('gtg.title' => 'GTG: title - varchar(255)'); $query_fields += array('gtg.title_cache' => 'GTG: title_cache - varchar(255)'); #print '
'; print_r($query_fields); print ''; } $_fields_rule_item_edit['field']['array'] = $query_fields; $module = 'automation_tree_rules.php'; break; case AUTOMATION_RULE_TYPE_TREE_ACTION: $item_table = 'automation_tree_rule_items'; $sql_and = ''; $automation_rule = db_fetch_row_prepared('SELECT * FROM automation_tree_rules WHERE id = ?', array($rule_id)); $_fields_rule_item_edit = $fields_automation_tree_rule_item_edit; $query_fields = get_query_fields('host_template', array('id', 'hash')); $query_fields += get_query_fields('host', array('id', 'host_template_id')); /* list of allowed header types depends on rule leaf_type * e.g. for a Device Rule, only Device-related header types make sense */ if ($automation_rule['leaf_type'] == TREE_ITEM_TYPE_HOST) { $title = 'Create Tree Rule (Device)'; $tables = array ('host', 'host_templates'); #print '
'; print_r($query_fields); print ''; } elseif ($automation_rule['leaf_type'] == TREE_ITEM_TYPE_GRAPH) { $title = 'Create Tree Rule (Graph)'; $tables = array ('host', 'host_templates'); # add some more filter columns for a GRAPH match $query_fields += get_query_fields('graph_templates', array('id', 'hash')); $query_fields += array('gtg.title' => 'GTG: title - varchar(255)'); $query_fields += array('gtg.title_cache' => 'GTG: title_cache - varchar(255)'); #print '
'; print_r($query_fields); print ''; } $_fields_rule_item_edit['field']['array'] = $query_fields; $module = 'automation_tree_rules.php'; break; } if (!empty($rule_item_id)) { $automation_item = db_fetch_row("SELECT * FROM $item_table WHERE id=$rule_item_id $sql_and"); $header_label = __('Rule Item [edit rule item for %s: %s]', $title, $automation_rule['name']); }else{ $header_label = __('Rule Item [new rule item for %s: %s]', $title, $automation_rule['name']); $automation_item = array(); $automation_item['sequence'] = get_sequence('', 'sequence', $item_table, 'rule_id=' . $rule_id . $sql_and); } form_start($module, 'form_automation_global_item_edit'); html_start_box($header_label, '100%', '', '3', 'center', ''); draw_edit_form( array( 'config' => array('no_form_tag' => true), 'fields' => inject_form_variables($_fields_rule_item_edit, (isset($automation_item) ? $automation_item : array()), (isset($automation_rule) ? $automation_rule : array())) ) ); html_end_box(); } /** * hook executed for a graph template * @param $host_id - the host to perform automation on * @param $graph_template_id - the graph_template_id to perform automation on */ function automation_hook_graph_template($host_id, $graph_template_id) { global $config; if (read_config_option('automation_graphs_enabled') == '') { cacti_log(__FUNCTION__ . ' Host[' . $host_id . '] - skipped: Graph Creation Switch is: ' . (read_config_option('automation_graphs_enabled') == '' ? 'off' : 'on') . ' graph template: ' . $graph_template_id, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); return; } automation_execute_graph_template($host_id, $graph_template_id); } /** * hook executed for a new device on a tree * @param $data - data passed from hook */ function automation_hook_device_create_tree($data) { global $config; cacti_log(__FUNCTION__ . ' called: ' . serialize($data), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); if (read_config_option('automation_tree_enabled') == '') { cacti_log(__FUNCTION__ . ' Host[' . $data['id'] . '] - skipped: Tree Creation Switch is: ' . (read_config_option('automation_tree_enabled') == '' ? 'off' : 'on'), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); return; } automation_execute_device_create_tree($data); /* make sure, the next plugin gets required $data */ return($data); } /** * hook executed for a new graph on a tree * @param $data - data passed from hook */ function automation_hook_graph_create_tree($data) { global $config; cacti_log(__FUNCTION__ . ' called: ' . serialize($data), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); if (read_config_option('automation_tree_enabled') == '') { cacti_log(__FUNCTION__ . ' Graph[' . $data['id'] . '] - skipped: Tree Creation Switch is: ' . (read_config_option('automation_tree_enabled') == '' ? 'off' : 'on'), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); return; } automation_execute_graph_create_tree($data); /* make sure, the next plugin gets required $data */ return($data); } /** * run rules for a data query * @param $data - data passed from hook */ function automation_execute_data_query($host_id, $snmp_query_id) { global $config; cacti_log(__FUNCTION__ . ' Host[' . $host_id . "] - start - data query: $snmp_query_id", false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); # get all related rules for that data query that are enabled $sql = "SELECT agr.id, agr.name, agr.snmp_query_id, agr.graph_type_id FROM automation_graph_rules AS agr WHERE snmp_query_id=$snmp_query_id AND enabled='on'"; $rules = db_fetch_assoc($sql); cacti_log(__FUNCTION__ . ' Host[' . $host_id . "] - sql: $sql - found: " . sizeof($rules), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); if (!sizeof($rules)) return; # now walk all rules and create graphs if (sizeof($rules)) { foreach ($rules as $rule) { cacti_log(__FUNCTION__ . ' Host[' . $host_id . '] - rule=' . $rule['id'] . ' name: ' . $rule['name'], false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* build magic query, for matching hosts JOIN tables host and host_template */ $sql_query = 'SELECT h.id AS host_id, h.hostname, h.description, ht.name AS host_template_name FROM host AS h LEFT JOIN host_template AS ht ON h.host_template_id=ht.id'; /* get the WHERE clause for matching hosts */ $sql_filter = build_matching_objects_filter($rule['id'], AUTOMATION_RULE_TYPE_GRAPH_MATCH); /* now we build up a new query for counting the rows */ $rows_query = $sql_query . ' WHERE (' . $sql_filter . ') AND h.id=' . $host_id; $hosts = db_fetch_assoc($rows_query); cacti_log(__FUNCTION__ . ' Host[' . $host_id . "] - create sql: $rows_query matches:" . sizeof($hosts), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); if (!sizeof($hosts)) { continue; } create_dq_graphs($host_id, $snmp_query_id, $rule); } } } /** * run rules for a graph template * @param $data - data passed from hook */ function automation_execute_graph_template($host_id, $graph_template_id) { global $config; include_once($config['base_path'] . '/lib/template.php'); include_once($config['base_path'] . '/lib/api_automation_tools.php'); include_once($config['base_path'] . '/lib/utility.php'); $dataSourceId = ''; $function = 'Function[' . __FUNCTION__ . ']'; cacti_log(__FUNCTION__ . ' called: Host[' . $host_id . '] - graph template: ' . $graph_template_id, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); # are there any input fields? if ($graph_template_id > 0) { $input_fields = getInputFields($graph_template_id); if (sizeof($input_fields)) { # do nothing for such graph templates return; } } # graph already present? $existsAlready = db_fetch_cell_prepared('SELECT id FROM graph_local WHERE graph_template_id = ? AND host_id = ?', array($graph_template_id, $host_id)); if ((isset($existsAlready)) && ($existsAlready > 0)) { $dataSourceId = db_fetch_cell_prepared('SELECT data_template_rrd.local_data_id FROM graph_templates_item, data_template_rrd WHERE graph_templates_item.local_graph_id = ? AND graph_templates_item.task_item_id = data_template_rrd.id LIMIT 1', array($existsAlready)); cacti_log('NOTE: ' . $function . ' Host[' . $host_id . "] Graph - Already Exists - graph-id: ($existsAlready) - data-source-id: ($dataSourceId)", false, 'AUTOM8'); return; }else{ # input fields are not supported $suggested_values = array(); $returnArray = create_complete_graph_from_template($graph_template_id, $host_id, '', $suggested_values); $dataSourceId = ''; if (sizeof($returnArray)) { if (isset($returnArray['local_data_id'])) { foreach($returnArray['local_data_id'] as $item) { push_out_host($host_id, $item); if (strlen($dataSourceId)) { $dataSourceId .= ', ' . $item; }else{ $dataSourceId = $item; } } cacti_log('Host[' . $host_id . '] Graph Added - graph-id: (' . $returnArray['local_graph_id'] . ") - data-source-ids: ($dataSourceId)", false, 'AUTOM8'); } } else { cacti_log('Host[' . $host_id . '] ERROR: graph-id: (' . $returnArray['local_graph_id'] . ') without data sources', false, 'AUTOM8'); } } } /** * run rules for a new device in a tree * @param $data - data passed from hook */ function automation_execute_device_create_tree($host_id) { global $config; /* the $data array holds all information about the host we're just working on * even if we selected multiple hosts, the calling code will scan through the list * so we only have a single host here */ cacti_log(__FUNCTION__ . " Host[$host_id] called", false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* * find all active Tree Rules * checking whether a specific rule matches the selected host * has to be done later */ $sql = "SELECT atr.id, atr.name, atr.tree_id, atr.tree_item_id, atr.leaf_type, atr.host_grouping_type FROM automation_tree_rules AS atr WHERE enabled='on' AND leaf_type=" . TREE_ITEM_TYPE_HOST; $rules = db_fetch_assoc($sql); cacti_log(__FUNCTION__ . " Host[$host_id], matching rule sql: $sql matches: " . sizeof($rules), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* now walk all rules */ if (sizeof($rules)) { foreach ($rules as $rule) { cacti_log(__FUNCTION__ . " Host[$host_id], active rule: " . $rule['id'] . ' name: ' . $rule['name'] . ' type: ' . $rule['leaf_type'], false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* does the rule apply to the current host? * test 'eligible objects' rule items */ $matches = get_matching_hosts($rule, AUTOMATION_RULE_TYPE_TREE_MATCH, 'h.id=' . $host_id); cacti_log(__FUNCTION__ . " Host[$host_id], matching hosts: " . serialize($matches), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* if the rule produces a match, we will have to create all required tree nodes */ if (sizeof($matches)) { /* create the bunch of header nodes */ $parent = create_all_header_nodes($host_id, $rule); cacti_log(__FUNCTION__ . " Host[$host_id], parent: " . $parent, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* now that all rule items have been executed, add the item itself */ $node = create_device_node($host_id, $parent, $rule); cacti_log(__FUNCTION__ . " Host[$host_id], node: " . $node, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); } } } } /** * run rules for a new graph on a tree * @param $data - data passed from hook */ function automation_execute_graph_create_tree($graph_id) { global $config; /* the $data array holds all information about the graph we're just working on * even if we selected multiple graphs, the calling code will scan through the list * so we only have a single graph here */ cacti_log(__FUNCTION__ . ' Graph[' . $graph_id . '] called', false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* * find all active Tree Rules * checking whether a specific rule matches the selected graph * has to be done later */ $sql = "SELECT atr.id, atr.name, atr.tree_id, atr.tree_item_id, atr.leaf_type, atr.host_grouping_type FROM automation_tree_rules AS atr WHERE enabled='on' AND leaf_type=" . TREE_ITEM_TYPE_GRAPH; $rules = db_fetch_assoc($sql); cacti_log(__FUNCTION__ . ' Graph[' . $graph_id . "], Matching rule sql: $sql matches: " . sizeof($rules), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* now walk all rules */ if (sizeof($rules)) { foreach ($rules as $rule) { cacti_log(__FUNCTION__ . ' Graph[' . $graph_id . '], active rule: ' . $rule['id'] . ' name: ' . $rule['name'] . ' type: ' . $rule['leaf_type'], false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* does this rule apply to the current graph? * test 'eligible objects' rule items */ $matches = get_matching_graphs($rule, AUTOMATION_RULE_TYPE_TREE_MATCH, 'graph_local.id=' . $graph_id); cacti_log(__FUNCTION__ . ' Graph[' . $graph_id . '], Matching graphs: ' . serialize($matches), false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* if the rule produces a match, we will have to create all required tree nodes */ if (sizeof($matches)) { /* create the bunch of header nodes */ $parent = create_all_header_nodes($graph_id, $rule); cacti_log(__FUNCTION__ . ' Graph[' . $graph_id . '], Parent: ' . $parent, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* now that all rule items have been executed, add the item itself */ $node = create_graph_node($graph_id, $parent, $rule); cacti_log(__FUNCTION__ . ' Graph[' . $graph_id . '], Node: ' . $node, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); } } } } /** * create all graphs for a data query * @param int $host_id - host id * @param int $snmp_query_id - snmp query id * @param array $rule - matching rule */ function create_dq_graphs($host_id, $snmp_query_id, $rule) { global $config, $automation_op_array, $automation_oper; include_once($config['base_path'] . '/lib/template.php'); cacti_log(__FUNCTION__ . ' Host[' . $host_id . "] - snmp query: $snmp_query_id - rule: " . $rule['name'], false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); $function = 'Function[' . __FUNCTION__ . ']'; $snmp_query_array = array(); $snmp_query_array['snmp_query_id'] = $rule['snmp_query_id']; $snmp_query_array['snmp_index_on'] = get_best_data_query_index_type($host_id, $rule['snmp_query_id']); $snmp_query_array['snmp_query_graph_id'] = $rule['graph_type_id']; # get all rule items $automation_rule_items = db_fetch_assoc_prepared('SELECT * FROM automation_graph_rule_items AS agri WHERE rule_id = ? ORDER BY sequence', array($rule['id'])); # and all matching snmp_indices from snmp_cache /* get the unique field values from the database */ $field_names = db_fetch_assoc_prepared('SELECT DISTINCT field_name FROM host_snmp_cache AS hsc WHERE snmp_query_id= ?', array($snmp_query_id)); #print '
Field Names: $sql'; /* build magic query */ $sql_query = 'SELECT host_id, snmp_query_id, snmp_index'; $num_visible_fields = sizeof($field_names); $i = 0; if (sizeof($field_names) > 0) { foreach($field_names as $column) { $field_name = $column['field_name']; $sql_query .= ", MAX(CASE WHEN field_name ='$field_name' THEN field_value ELSE NULL END) AS '$field_name'"; $i++; } } $sql_query .= ' FROM host_snmp_cache AS hsc WHERE snmp_query_id=' . $snmp_query_id . ' AND host_id=' . $host_id . ' GROUP BY snmp_query_id, snmp_index'; # $sql_filter = ''; # if(sizeof($automation_rule_items)) { # $sql_filter = ' WHERE'; # foreach($automation_rule_items as $automation_rule_item) { # # AND|OR # if ($automation_rule_item['operation'] != AUTOMATION_OPER_NULL) { # $sql_filter .= ' ' . $automation_oper[$automation_rule_item['operation']]; # } # # right bracket ')' does not come with a field # if ($automation_rule_item['operation'] == AUTOMATION_OPER_RIGHT_BRACKET) { # continue; # } # # field name # if ($automation_rule_item['field'] != '') { # $sql_filter .= (' a.' . $automation_rule_item['field']); # # # $sql_filter .= ' ' . $automation_op_array['op'][$automation_rule_item['operator']] . ' '; # if ($automation_op_array['binary'][$automation_rule_item['operator']]) { # $sql_filter .= (''' . $automation_op_array['pre'][$automation_rule_item['operator']] . mysql_real_escape_string($automation_rule_item['pattern']) . $automation_op_array['post'][$automation_rule_item['operator']] . '''); # } # } # } # } $sql_filter = build_rule_item_filter($automation_rule_items, ' a.'); if (sizeof($sql_filter)) $sql_filter = ' WHERE' . $sql_filter; /* add the additional filter settings to the original data query. IMO it's better for the MySQL server to use the original one as an subquery which requires MySQL v4.1(?) or higher */ $sql_query = 'SELECT * FROM (' . $sql_query . ") as a $sql_filter"; /* fetch snmp indices */ # print $sql_query . '\n'; $snmp_query_indexes = db_fetch_assoc($sql_query); # now create the graphs if (sizeof($snmp_query_indexes)) { $graph_template_id = db_fetch_cell_prepared('SELECT graph_template_id FROM snmp_query_graph WHERE id = ?', array($rule['graph_type_id'])); cacti_log(__FUNCTION__ . ' Host[' . $host_id . "] - graph template: $graph_template_id", false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); foreach ($snmp_query_indexes as $snmp_index) { $snmp_query_array['snmp_index'] = $snmp_index['snmp_index']; cacti_log(__FUNCTION__ . ' Host[' . $host_id . '] - checking index: ' . $snmp_index['snmp_index'], false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); $existsAlready = db_fetch_cell_prepared('SELECT DISTINCT dl.id FROM data_local AS dl LEFT JOIN data_template_data AS dtd ON dl.id=dtd.local_data_id LEFT JOIN data_input_data AS did ON dtd.id=did.data_template_data_id LEFT JOIN data_input_fields AS dif ON did.data_input_field_id=dif.id LEFT JOIN snmp_query_graph AS sqg ON did.value=sqg.id WHERE dif.type_code="output_type" AND sqg.id = ? AND dl.host_id = ? AND dl.snmp_query_id = ? AND dl.snmp_index = ?', array($rule['graph_type_id'], $host_id, $rule['snmp_query_id'], $snmp_query_array['snmp_index'])); if (isset($existsAlready) && $existsAlready > 0) { cacti_log('NOTE: ' . $function . ' Host[' . $host_id . "] Graph - Already Exists - DS[$existsAlready]", false, 'AUTOM8'); continue; } $myempty = array(); /* Suggested Values are not been implemented */ $return_array = create_complete_graph_from_template($graph_template_id, $host_id, $snmp_query_array, $myempty); if (sizeof($return_array) && array_key_exists('local_graph_id', $return_array) && array_key_exists('local_data_id', $return_array)) { $data_source_id = db_fetch_cell_prepared('SELECT data_template_rrd.local_data_id FROM graph_templates_item, data_template_rrd WHERE graph_templates_item.local_graph_id = ? AND graph_templates_item.task_item_id = data_template_rrd.id LIMIT 1', array($return_array['local_graph_id'])); foreach($return_array['local_data_id'] as $item) { push_out_host($host_id, $item); if (strlen($data_source_id)) { $data_source_id .= ', ' . $item; }else{ $data_source_id = $item; } } cacti_log('NOTE: ' . $function . ' Host[' . $host_id . '] Graph Added - graph-id: (' . $return_array['local_graph_id'] . ") - data-source-ids: ($data_source_id)", false, 'AUTOM8'); } else { cacti_log('WARNING: ' . $function . ' Host[' . $host_id . '] Graph Not Added', false, 'AUTOM8'); } } } } /* create_all_header_nodes - walk across all tree rule items * - get all related rule items * - take header type into account * - create (multiple) header nodes * * @arg $item_id id of the host/graph we're working on * @arg $rule the rule we're working on * returns the last tree item that was hooked into the tree */ function create_all_header_nodes ($item_id, $rule) { global $config, $automation_tree_header_types; # get all related rules that are enabled $tree_items = db_fetch_assoc_prepared('SELECT * FROM automation_tree_rule_items AS atri WHERE atri.rule_id = ? ORDER BY sequence', array($rule['id'])); cacti_log(__FUNCTION__ . " called: Item $item_id matches: " . sizeof($tree_items) . ' items', false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); /* start at the given tree item * it may be worth verifying existance of this entry * in case it was selected once but then deleted */ $parent_tree_item_id = $rule['tree_item_id']; # now walk all rules and create tree nodes if (sizeof($tree_items)) { /* build magic query, * for matching hosts JOIN tables host and host_template */ if ($rule['leaf_type'] == TREE_ITEM_TYPE_HOST) { $sql_tables = 'FROM host AS h LEFT JOIN host_template AS ht ON h.host_template_id=ht.id '; $sql_where = 'WHERE h.id='. $item_id . ' '; } elseif ($rule['leaf_type'] == TREE_ITEM_TYPE_GRAPH) { /* graphs require a different set of tables to be joined */ $sql_tables = 'FROM host AS h LEFT JOIN host_template AS ht ON h.host_template_id=ht.id LEFT JOIN graph_local AS gl ON h.id=gl.host_id LEFT JOIN graph_templates AS gt ON gl.graph_template_id=gt.id LEFT JOIN graph_templates_graph AS gtg ON gl.id=gtg.local_graph_id '; $sql_where = 'WHERE gl.id=' . $item_id . ' '; } /* get the WHERE clause for matching hosts */ $sql_filter = build_matching_objects_filter($rule['id'], AUTOMATION_RULE_TYPE_TREE_MATCH); foreach ($tree_items as $tree_item) { if ($tree_item['field'] === AUTOMATION_TREE_ITEM_TYPE_STRING) { # for a fixed string, use the given text $sql = ''; $target = $automation_tree_header_types[AUTOMATION_TREE_ITEM_TYPE_STRING]; } else { $sql_field = $tree_item['field'] . ' AS source '; /* now we build up a new query for counting the rows */ $sql = 'SELECT ' . $sql_field . $sql_tables . $sql_where . ' AND (' . $sql_filter . ')'; $target = db_fetch_cell($sql); } cacti_log(__FUNCTION__ . " Item $item_id - sql: $sql matches: " . $target, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); $parent_tree_item_id = create_multi_header_node($target, $rule, $tree_item, $parent_tree_item_id); } } return $parent_tree_item_id; } /* create_multi_header_node - work on a single header item * - evaluate replacement rule * - this may return an array of new header items * - walk that array to create all header items for this single rule item * @arg $target string (name) of the object; e.g. ht.name * @arg $rule rule * @arg $tree_item rule item; replacement_pattern may result in multi-line replacement * @arg $parent_tree_item_id parent tree item id * returns id of the header that was hooked in */ function create_multi_header_node($object, $rule, $tree_item, $parent_tree_item_id){ global $config; cacti_log(__FUNCTION__ . " - object: '" . $object . "', Header: '" . $tree_item['search_pattern'] . "', parent: " . $parent_tree_item_id, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); if ($tree_item['field'] === AUTOMATION_TREE_ITEM_TYPE_STRING) { $parent_tree_item_id = create_header_node($tree_item['search_pattern'], $rule, $tree_item, $parent_tree_item_id); cacti_log(__FUNCTION__ . " called - object: '" . $object . "', Header: '" . $tree_item['search_pattern'] . "', hooked at: " . $parent_tree_item_id, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); } else { $replacement = automation_string_replace($tree_item['search_pattern'], $tree_item['replace_pattern'], $object); /* build multiline
'; print_r($field_names); print '
'; print_r($replacement); print ''; for ($j=0; sizeof($replacement); $j++) { $title = array_shift($replacement); $parent_tree_item_id = create_header_node($title, $rule, $tree_item, $parent_tree_item_id); cacti_log(__FUNCTION__ . " - object: '" . $object . "', Header: '" . $title . "', hooked at: " . $parent_tree_item_id, false, 'AUTOM8 TRACE', POLLER_VERBOSITY_HIGH); } } return $parent_tree_item_id; } /** * create a single tree header node * @param string $title - graph title * @param array $rule - rule * @param array $item - item * @param int $parent_tree_item_id - parent item id * @return int - id of new item */ function create_header_node($title, $rule, $item, $parent_tree_item_id) { global $config; include_once($config['base_path'] . '/lib/api_tree.php'); $id = 0; # create a new entry $local_graph_id = 0; # headers don't need no graph_id $host_id = 0; # or a host_id $propagate = ($item['propagate_changes'] != ''); $function = 'Function[' . __FUNCTION__ . ']'; if (api_tree_branch_exists($rule['tree_id'], $parent_tree_item_id, $title)) { $new_item = api_tree_get_branch_id($rule['tree_id'], $parent_tree_item_id, $title); cacti_log('NOTE: ' . $function . ' Parent[' . $parent_tree_item_id . '] Tree Item - Already Exists', false, 'AUTOM8'); }else{ $new_item = api_tree_item_save($id, $rule['tree_id'], TREE_ITEM_TYPE_HEADER, $parent_tree_item_id, $title, $local_graph_id, $host_id, $rule['host_grouping_type'], $item['sort_type'], $propagate); if (isset($new_item) && $new_item > 0) { cacti_log('NOTE: ' . $function . ' Parent[' . $parent_tree_item_id . '] Tree Item - Added - id: (' . $new_item . ') Title: (' .$title . ')', false, 'AUTOM8'); } else { cacti_log('WARNING: ' . $function . ' Parent[' . $parent_tree_item_id . '] Tree Item - Not Added', false, 'AUTOM8'); } } return $new_item; } /** * add a device to the tree * @param int $host_id - host id * @param int $parent - parent id * @param array $rule - rule * @return int - id of new item */ function create_device_node($host_id, $parent, $rule) { global $config; include_once($config['base_path'] . '/lib/api_tree.php'); $id = 0; # create a new entry $local_graph_id = 0; # hosts don't need no graph_id $title = ''; # nor a title $sort_type = 0; # nor a sort type $propagate = false; # nor a propagation flag $function = 'Function[' . __FUNCTION__ . ']'; if (api_tree_host_exists($rule['tree_id'], $parent, $host_id)) { $new_item = db_fetch_cell_prepared('SELECT id FROM graph_tree_items WHERE host_id = ? AND parent = ? AND graph_tree_id = ?', array($host_id, $parent, $rule['tree_id'])); cacti_log('NOTE: ' . $function . ' Host[' . $host_id . '] Tree Item - Already Exists', false, 'AUTOM8'); }else{ $new_item = api_tree_item_save($id, $rule['tree_id'], TREE_ITEM_TYPE_HOST, $parent, $title, $local_graph_id, $host_id, $rule['host_grouping_type'], $sort_type, $propagate); if (isset($new_item) && $new_item > 0) { cacti_log('NOTE: ' . $function . ' Host[' . $host_id . '] Tree Item - Added - id: (' . $new_item . ')', false, 'AUTOM8'); } else { cacti_log('WARNING: ' . $function . ' Host[' . $host_id . '] Tree Item - Not Added', false, 'AUTOM8'); } } return $new_item; } /** * add a device to the tree * @param int $graph_id - graph id * @param int $parent - parent id * @param array $rule - rule * @return int - id of new item */ function create_graph_node($graph_id, $parent, $rule) { global $config; include_once($config['base_path'] . '/lib/api_tree.php'); $id = 0; # create a new entry $host_id = 0; # graphs don't need no host_id $title = ''; # nor a title $sort_type = 0; # nor a sort type $propagate = false; # nor a propagation flag $function = 'Function[' . __FUNCTION__ . ']'; if (api_tree_graph_exists($rule['tree_id'], $parent, $graph_id)) { $new_item = db_fetch_cell_prepared('SELECT id FROM graph_tree_items WHERE local_graph_id = ? AND parent = ? AND graph_tree_id = ?', array($graph_id, $parent, $rule['tree_id'])); cacti_log('WARNING: ' . $function . ' Graph[' . $graph_id . '] Tree Item - Already Exists', false, 'AUTOM8'); }else{ $new_item = api_tree_item_save($id, $rule['tree_id'], TREE_ITEM_TYPE_GRAPH, $parent, $title, $graph_id, $host_id, $rule['host_grouping_type'], $sort_type, $propagate); if (isset($new_item) && $new_item > 0) { cacti_log('NOTE: ' . $function . ' Graph[' . $graph_id . '] Tree Item - Added - id: (' . $new_item . ')', false, 'AUTOM8'); } else { cacti_log('WARNING: ' . $function . ' Graph[' . $graph_id . '] Tree Item - Not Added', false, 'AUTOM8'); } } return $new_item; } function automation_poller_bottom () { global $config; $command_string = trim(read_config_option('path_php_binary')); // If its not set, just assume its in the path if (trim($command_string) == '') { $command_string = 'php'; } $extra_args = ' -q ' . $config['base_path'] . '/poller_automation.php -M'; exec_background($command_string, $extra_args); } function automation_add_device ($device, $web = false) { global $plugins, $config; $template_id = $device['host_template']; $snmp_sysName = preg_split('/[\s.]+/', $device['snmp_sysName'], -1, PREG_SPLIT_NO_EMPTY); $description = (isset($snmp_sysName[0]) != '' ? $snmp_sysName[0] : ($device['hostname'] == '' ? $device['ip'] : $device['hostname'])); $ip = $device['ip']; $community = $device['community']; $snmp_ver = $device['snmp_version']; $snmp_username = $device['snmp_username']; $snmp_password = $device['snmp_password']; $snmp_port = $device['snmp_port']; $snmp_timeout = isset($device['snmp_timeout']) ? $device['snmp_timeout']:read_config_option('snmp_timeout'); $disable = ''; $availability_method = isset($device['availability_method']) ? $device['availability_method']:read_config_option('availability_method'); $ping_method = isset($device['ping_method']) ? $device['ping_method']:read_config_option('ping_method'); $ping_port = isset($device['ping_port']) ? $device['ping_port']:read_config_option('ping_port'); $ping_timeout = isset($device['ping_timeout']) ? $device['ping_timeout']:read_config_option('ping_timeout'); $ping_retries = isset($device['ping_retries']) ? $device['ping_retries']:read_config_option('ping_retries'); $notes = isset($device['notes']) ? $device['notes']:'Added by Discovery Plugin'; $snmp_auth_protocol = $device['snmp_auth_protocol']; $snmp_priv_passphrase = $device['snmp_priv_passphrase']; $snmp_priv_protocol = $device['snmp_priv_protocol']; $snmp_context = $device['snmp_context']; $snmp_engine_id = $device['snmp_engine_id']; $device_threads = isset($device['device_threads']) ? $device['device_threads']:1; $max_oids = isset($device['max_oids']) ? $device['max_oids']:10; automation_debug(' - Adding Device'); $host_id = api_device_save('0', $template_id, $description, $ip, $community, $snmp_ver, $snmp_username, $snmp_password, $snmp_port, $snmp_timeout, $disable, $availability_method, $ping_method, $ping_port, $ping_timeout, $ping_retries, $notes, $snmp_auth_protocol, $snmp_priv_passphrase, $snmp_priv_protocol, $snmp_context, $snmp_engine_id, $max_oids, $device_threads); if ($host_id) { if (!$web) { automation_debug(' - Success'); } /* Use the thold plugin if it exists */ if (api_plugin_is_enabled('thold')) { if (!$web) { automation_debug(" Creating Thresholds\n"); } if (file_exists($config['base_path'] . '/plugins/thold/thold-functions.php')) { include_once($config['base_path'] . '/plugins/thold/thold-functions.php'); autocreate($host_id); } else if (file_exists($config['base_path'] . '/plugins/thold/thold_functions.php')) { include_once($config['base_path'] . '/plugins/thold/thold_functions.php'); autocreate($host_id); } } db_execute_prepared('DELETE FROM automation_devices WHERE ip = ? LIMIT 1', array($ip)); }else{ if (!$web) { automation_debug(' - Failed'); } } return $host_id; } function automation_add_tree ($host_id, $tree) { automation_debug(" Adding to tree\n"); if ($tree > 1000000) { $tree_id = $tree - 1000000; $parent = 0; } else { $tree_item = db_fetch_row_prepared('SELECT * FROM graph_tree_items WHERE id = ?', array($tree)); if (!isset($tree_item['graph_tree_id'])) return; $tree_id = $tree_item['graph_tree_id']; $parent = $tree; } $nodeId = api_tree_item_save(0, $tree_id, 3, $parent, '', 0, $host_id, 1, 1, false); } function automation_find_os($sysDescr, $sysObject, $sysName) { $sql_where = ''; $sql_where .= $sysDescr != '' ? 'WHERE (sysDescr="" OR "' . $sysDescr . '" RLIKE sysDescr OR sysDescr LIKE "%' . $sysDescr . '%")':''; $sql_where .= $sysObject != '' ? ($sql_where != '' ? ' AND':'WHERE') . ' (sysOid="" OR "' . $sysObject . '" RLIKE sysOid OR sysOid LIKE "%' . $sysObject . '%")':''; $sql_where .= $sysName != '' ? ($sql_where != '' ? ' AND':'WHERE') . ' (sysName="" OR "' . $sysName . '" RLIKE sysName OR sysName LIKE "%' . $sysName . '%")':''; $result = db_fetch_row("SELECT at.*,ht.name FROM automation_templates AS at INNER JOIN host_template AS ht ON ht.id=at.host_template $sql_where ORDER BY sequence LIMIT 1"); if (sizeof($result)) { return $result; }else{ return false; } } function automation_debug($text) { global $debug; static $message = ''; if ($debug) { print $text; if (strstr($text, "\n") !== false) { cacti_log(trim($message . $text), false, "AUTOM8"); $message = ''; }else{ $message .= $text; } } } function automation_calculate_start($networks, $position) { if (!isset($networks[$position])) return false; $h = trim($networks[$position]); // 10.1.0.1 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $h)) { return $h; } // 10.1.0.* if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.\*$/", $h)) { return substr($h,0,-1) . "1"; } // 10.1.*.1 if (preg_match("/^([0-9]{1,3}\.[0-9]{1,3}\.)\*(\.[0-9]{1,3})$/", $h, $matches)) { return $matches[1] . "1" . $matches[2]; } // 10.1.0.0/24 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.0\/[0-9]{1,2}$/", $h)) { preg_match_all("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\./", $h, $matches); return $matches[0][0] . "1"; } // 10.1.0./24 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.\/[0-9]{1,2}$/", $h)) { preg_match_all("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\./", $h, $matches); return $matches[0][0] . "1"; } // 10.1.0/24 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}$/", $h)) { preg_match_all("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/", $h, $matches); return $matches[0][0] . ".1"; } // 10.1.0.172/24 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}$/", $h)) { preg_match_all("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/", $h, $matches); return $matches[0][0]; } // 10.1.0.0/255.255.255.0 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.0\/255\.255\.[0-9]{1,3}\.0$/", $h)) { preg_match_all("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\./", $h, $matches); return $matches[0][0] . "1"; } // 10.1.0.19/255.255.255.240 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/255\.255\.255\.[0-9]{1,3}\$/", $h)) { preg_match_all("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/", $h, $matches); return $matches[0][0]; } // 10.1.0.19-10.1.0.27 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}-[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\$/", $h)) { preg_match_all("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}-/", $h, $matches); return substr($matches[0][0], 0, -1); } automation_debug(" Could not calculate starting address!\n"); return false; } function automation_calculate_total_ips($networks, $position) { if (!isset($networks[$position])) return false; $h = trim($networks[$position]); // 10.1.0.1 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $h)) { return 1; } // 10.1.0.* if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.\*$/", $h)) { return "254"; } // 10.1.*.1 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.\*\.[0-9]{1,3}$/", $h)) { return "254"; } // 10.1.0.0/24 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.0\/[0-9]{1,2}$/", $h)) { preg_match_all("/\/[0-9]{1,2}$/", $h, $matches); $subnet = substr($matches[0][0], 1); $total = 1; for ($x = 0; $x < (32-$subnet); $x++) { $total = $total * 2; } return $total-2; } // 10.1.0./24 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.\/[0-9]{1,2}$/", $h)) { preg_match_all("/\/[0-9]{1,2}$/", $h, $matches); $subnet = substr($matches[0][0], 1); $total = 1; for ($x = 0; $x < (32-$subnet); $x++) { $total = $total * 2; } return $total-2; } // 10.1.0/24 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}$/", $h)) { preg_match_all("/\/[0-9]{1,2}$/", $h, $matches); $subnet = substr($matches[0][0], 1); $total = 1; for ($x = 0; $x < (32-$subnet); $x++) { $total = $total * 2; } return $total-2; } // 10.1.0.172/24 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{1,2}$/", $h)) { preg_match_all("/\/[0-9]{1,2}$/", $h, $matches); $subnet = substr($matches[0][0], 1); $total = 1; for ($x = 0; $x < (32-$subnet); $x++) { $total = $total * 2; } return $total-2; } // 10.1.0.0/255.255.255.0 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.0\/255\.255\.[0-9]{1,3}\.0$/", $h)) { preg_match_all("/[0-9]{1,3}.0$/", $h, $matches); $subnet = substr($matches[0][0], 0, -2); return ((256 - $subnet)*256) - 2; } // 10.1.0.19/255.255.255.240 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/255\.255\.255\.[0-9]{1,3}\$/", $h)) { preg_match_all("/\.[0-9]{1,3}$/", $h, $matches); $subnet = substr($matches[0][0], 1); return (256 - $subnet)-1; } // 10.1.0.19-10.1.0.27 if (preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}-[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\$/", $h)) { preg_match_all("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}-/", $h, $matches); preg_match_all("/-[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $h, $matches2); $start = substr($matches[0][0], 0, -1); $end = substr($matches2[0][0], 1); $starta = explode('.', $start); $enda = explode('.', $end); $start = ($starta[0] * 16777216) + ($starta[1] * 65536) + ($starta[2] * 256) + $starta[3]; $end = ($enda[0] * 16777216) + ($enda[1] * 65536) + ($enda[2] * 256) + $enda[3]; return $end - $start + 1; } automation_debug(" Could not calculate total IPs!\n"); return false; } function automation_get_next_host ($start, $total, $count, $networks, $position) { if (!isset($networks[$position])) return false; $h = trim($networks[$position]); if ($count == $total || $total < 1) return false; if (preg_match("/^([0-9]{1,3}\.[0-9]{1,3}\.)\*(\.[0-9]{1,3})$/", $h, $matches)) { // 10.1.*.1 return $matches[1] . ++$count . $matches[2]; } else { // other cases $ip = explode('.', $start); $y = 16777216; for ($x = 0; $x < 4; $x++) { $ip[$x] += intval($count/$y); $count -= ((intval($count/$y))*256); $y = $y / 256; if ($ip[$x] == 256 && $x > 0) { $ip[$x] = 0; $ip[$x-1] += 1; } } return implode('.',$ip); } } function automation_primeIPAddressTable($network_id) { $subNets = db_fetch_cell_prepared('SELECT subnet_range FROM automation_networks WHERE id = ?', array($network_id)); $subNets = explode(',', trim($subNets)); $total = 0; if (sizeof($subNets)) { foreach($subNets as $position => $subNet) { $count = 1; $sql = array(); $subNetTotal = automation_calculate_total_ips($subNets, $position); $total += $subNetTotal; $start = automation_calculate_start($subNets, $position); if ($start != '') { $sql[] = "('$start', '', $network_id, '0', '0', '0')"; } while ($count < $subNetTotal) { $ip = automation_get_next_host($start, $subNetTotal, $count, $subNets, $position); $count++; if ($ip != '') { $sql[] = "('$ip', '', $network_id, '0', '0', '0')"; } if ($count % 1000 == 0) { db_execute("INSERT INTO automation_ips (ip_address, hostname, network_id, pid, status, thread) VALUES " . implode(',', $sql)); $sql = array(); } } if (sizeof($sql)) { db_execute("INSERT INTO automation_ips (ip_address, hostname, network_id, pid, status, thread) VALUES " . implode(',', $sql)); } } } automation_debug("A Total of $total IP Addresses Primed\n"); } function automation_valid_snmp_device (&$device) { global $snmp_logging; /* initialize variable */ $host_up = FALSE; $snmp_logging = false; $device["snmp_status"] = HOST_DOWN; $device["ping_status"] = 0; /* force php to return numeric oid's */ cacti_oid_numeric_format(); $snmp_items = db_fetch_assoc_prepared('SELECT * FROM automation_snmp_items WHERE snmp_id = ? ORDER BY sequence ASC', array($device['snmp_id'])); if (sizeof($snmp_items)) { automation_debug(', SNMP:'); foreach($snmp_items as $item) { // general options $device['snmp_version'] = $item['snmp_version']; $device['snmp_port'] = $item['snmp_port']; $device['snmp_timeout'] = $item['snmp_timeout']; $device['snmp_retries'] = $item['snmp_retries']; // snmp v1/v2 options $device['snmp_readstring'] = $item['snmp_readstring']; // snmp v3 options $device['snmp_username'] = $item['snmp_username']; $device['snmp_password'] = $item['snmp_password']; $device['snmp_auth_protocol'] = $item['snmp_auth_protocol']; $device['snmp_priv_passphrase'] = $item['snmp_priv_passphrase']; $device['snmp_priv_protocol'] = $item['snmp_priv_protocol']; $device['snmp_context'] = $item['snmp_context']; $device['snmp_engine_id'] = $item['snmp_engine_id']; $device['max_oids'] = $item['max_oids']; $session = cacti_snmp_session($device['hostname'], $device['snmp_readstring'], $device['snmp_version'], $device['snmp_username'], $device['snmp_password'], $device['snmp_auth_protocol'], $device['snmp_priv_passphrase'], $device['snmp_priv_protocol'], $device['snmp_context'], $device['snmp_engine_id'], $device['snmp_port'], $device['snmp_timeout'], $device['snmp_retries'], $device['max_oids']); if ($session !== false) { /* Community string is not used for v3 */ $snmp_sysObjectID = cacti_snmp_session_get($session, '.1.3.6.1.2.1.1.2.0'); if ($snmp_sysObjectID != 'U') { $snmp_sysObjectID = str_replace('enterprises', '.1.3.6.1.4.1', $snmp_sysObjectID); $snmp_sysObjectID = str_replace('OID: ', '', $snmp_sysObjectID); $snmp_sysObjectID = str_replace('.iso', '.1', $snmp_sysObjectID); if ((strlen($snmp_sysObjectID)) && (!substr_count($snmp_sysObjectID, 'No Such Object')) && (!substr_count($snmp_sysObjectID, 'Error In'))) { $snmp_sysObjectID = trim(str_replace('"', '', $snmp_sysObjectID)); $device['snmp_status'] = HOST_UP; $host_up = TRUE; break; } } } if ($host_up == TRUE) { break; } } } if ($host_up) { $device['snmp_sysObjectID'] = $snmp_sysObjectID; $device['community'] = $device['snmp_readstring']; /* get system name */ $snmp_sysName = cacti_snmp_session_get($session, '.1.3.6.1.2.1.1.5.0'); if (strlen($snmp_sysName)) { $snmp_sysName = trim(strtr($snmp_sysName,"\""," ")); $device["snmp_sysName"] = $snmp_sysName; } /* get system location */ $snmp_sysLocation = cacti_snmp_session_get($session, '.1.3.6.1.2.1.1.6.0'); if (strlen($snmp_sysLocation)) { $snmp_sysLocation = trim(strtr($snmp_sysLocation,"\""," ")); $device["snmp_sysLocation"] = $snmp_sysLocation; } /* get system contact */ $snmp_sysContact = cacti_snmp_session_get($session, '.1.3.6.1.2.1.1.4.0'); if (strlen($snmp_sysContact)) { $snmp_sysContact = trim(strtr($snmp_sysContact,"\""," ")); $device["snmp_sysContact"] = $snmp_sysContact; } /* get system description */ $snmp_sysDescr = cacti_snmp_session_get($session, '.1.3.6.1.2.1.1.1.0'); if (strlen($snmp_sysDescr)) { $snmp_sysDescr = trim(strtr($snmp_sysDescr,"\""," ")); $device["snmp_sysDescr"] = $snmp_sysDescr; } /* get system uptime */ $snmp_sysUptime = cacti_snmp_session_get($session, '.1.3.6.1.2.1.1.3.0'); if (strlen($snmp_sysUptime)) { $snmp_sysUptime = trim(strtr($snmp_sysUptime,"\""," ")); $device["snmp_sysUptime"] = $snmp_sysUptime; } $session->close(); }else{ automation_debug(' No response'); } return $host_up; } /* gethostbyaddr_wtimeout - This function provides a good method of performing a rapid lookup of a DNS entry for a host so long as you don't have to look far. */ function automation_get_dns_from_ip($ip, $dns, $timeout = 1000) { /* random transaction number (for routers etc to get the reply back) */ $data = rand(10, 99); /* trim it to 2 bytes */ $data = substr($data, 0, 2); /* create request header */ $data .= "\1\0\0\1\0\0\0\0\0\0"; /* split IP into octets */ $octets = explode(".", $ip); /* perform a quick error check */ if (count($octets) != 4) return "ERROR"; /* needs a byte to indicate the length of each segment of the request */ for ($x=3; $x>=0; $x--) { switch (strlen($octets[$x])) { case 1: // 1 byte long segment $data .= "\1"; break; case 2: // 2 byte long segment $data .= "\2"; break; case 3: // 3 byte long segment $data .= "\3"; break; default: // segment is too big, invalid IP return "ERROR"; } /* and the segment itself */ $data .= $octets[$x]; } /* and the final bit of the request */ $data .= "\7in-addr\4arpa\0\0\x0C\0\1"; /* create UDP socket */ $handle = @fsockopen("udp://$dns", 53); @stream_set_timeout($handle, floor($timeout/1000), ($timeout*1000)%1000000); @stream_set_blocking($handle, 1); /* send our request (and store request size so we can cheat later) */ $requestsize = @fwrite($handle, $data); /* get the response */ $response = @fread($handle, 1000); /* check to see if it timed out */ $info = @stream_get_meta_data($handle); /* close the socket */ @fclose($handle); if ($info["timed_out"]) { return "timed_out"; } /* more error handling */ if ($response == "") { return $ip; } /* parse the response and find the response type */ $type = @unpack("s", substr($response, $requestsize+2)); if (isset($type[1]) && $type[1] == 0x0C00) { /* set up our variables */ $host = ""; $len = 0; /* set our pointer at the beginning of the hostname uses the request size from earlier rather than work it out. */ $position = $requestsize + 12; /* reconstruct the hostname */ do { /* get segment size */ $len = unpack("c", substr($response, $position)); /* null terminated string, so length 0 = finished */ if ($len[1] == 0) { /* return the hostname, without the trailing '.' */ return strtoupper(substr($host, 0, strlen($host) -1)); } /* add the next segment to our host */ $host .= substr($response, $position+1, $len[1]) . "."; /* move pointer on to the next segment */ $position += $len[1] + 1; } while ($len != 0); /* error - return the hostname we constructed (without the . on the end) */ return strtoupper($ip); } /* error - return the hostname */ return strtoupper($ip); } function api_automation_is_time_to_start($network_id) { $net = db_fetch_row_prepared('SELECT * FROM automation_networks WHERE id = ?', array($network_id)); switch($net['sched_type']) { case '1': return false; break; case '2': $recur = $net['recur_every'] * 86400; // days $start = strtotime($net['start_at']); $next = strtotime($net['next_start']); $now = time(); if ($net['next_start'] == '0000-00-00 00:00:00') { if ($now > $start) { while($now > $start) { $start += $recur; } db_execute_prepared('UPDATE automation_networks SET next_start = ? WHERE id = ?', array(date('Y-m-d H:i', $start), $network_id)); return true; break; } }else{ if ($now > $next) { while($now > $next) { $next += $recur; } db_execute_prepared('UPDATE automation_networks SET next_start = ? WHERE id = ?', array(date('Y-m-d H:i', $next), $network_id)); return true; } } return false; break; case '3': $recur = $net['recur_every'] * 86400 * 7; // weeks $start = strtotime($net['start_at']); $next = strtotime($net['next_start']); $now = time(); $days = explode(',', $net['day_of_week']); $day = 86400; $week = 86400 * 7; if ($net['next_start'] == '0000-00-00 00:00:00') { if ($now > $start) { while(true) { $start += $day; $cur_day = date('w', $start) + 1; $key = array_search($cur_day, $days, false); if ($key !== false && $key >= 0) { break; } } db_execute_prepared('UPDATE automation_networks SET next_start = ? WHERE id = ?', array(date('Y-m-d H:i', $start), $network_id)); return true; } }else{ if ($now > $next) { while(true) { $next += $day; $cur_day = date('w', $next) + 1; $key = array_search($cur_day, $days, false); if ($key !== false && $key >= 0) { if ($key == 0) { $next += $recur - $week; } break; } } db_execute_prepared('UPDATE automation_networks SET next_start = ? WHERE id = ?', array(date('Y-m-d H:i', $next), $network_id)); return true; } } return false; break; case '4': $start = strtotime($net['start_at']); $next = strtotime($net['next_start']); $now = time(); $months = explode(',', $net['month']); $days = explode(',', $net['day_of_month']); $day = 86400; // See if the last day of the month is selected $last = array_search('32', $days); if ($last !== false && $last > 0) { $last = true; }else{ $last = false; } if ($net['next_start'] == '0000-00-00 00:00:00') { if ($now > $start) { while(true) { $start += $day; $month_of_year = date('n', $start); $day_of_month = date('j', $start); $chdays = $days; if ($last) { $chdays[] = date('j', strtotime('last day', $start)); } $key = array_search($month_of_year, $months); if ($key !== false && $key >= 0) { $key = array_search($day_of_month, $chdays); if ($key !== false && $key >= 0) { break; } } } db_execute_prepared('UPDATE automation_networks SET next_start = ? WHERE id = ?', array(date('Y-m-d H:i', $start), $network_id)); return true; } }else{ if ($now > $next) { while(true) { $next += $day; $month_of_year = date('n', $next); $day_of_month = date('j', $next); $chdays = $days; if ($last) { $chdays[] = date('j', strtotime('last day', $next)); } $key = array_search($month_of_year, $months); if ($key !== false && $key >= 0) { $key = array_search($day_of_month, $chdays); if ($key !== false && $key >= 0) { break; } } } db_execute_prepared('UPDATE automation_networks SET next_start = ? WHERE id = ?', array(date('Y-m-d H:i', $next), $network_id)); return true; } } return false; break; case '5': $start = strtotime($net['start_at']); $next = strtotime($net['next_start']); $now = time(); $months = explode(',', $net['month']); $weeks = explode(',', $net['monthly_week']); $days = explode(',', $net['monthly_day']); $day = 86400; if ($net['next_start'] == '0000-00-00 00:00:00') { if ($now > $start) { while(true) { $start += $day; $month_of_year = date('n', $start); $day_of_month = date('j', $start); $times = array(); $key = array_search($month_of_year, $months); if ($key !== false && $key >= 0) { foreach($weeks as $week) { switch($week) { case '1': $sweek = '1st'; break; case '2': $sweek = '2nd'; break; case '3': $sweek = '3rd'; break; case '4': $sweek = '4th'; break; } foreach($days as $day) { switch($day) { case '1': $sday = 'Sunday'; break; case '2': $sday = 'Monday'; break; case '3': $sday = 'Tuesday'; break; case '4': $sday = 'Wednesday'; break; case '5': $sday = 'Thursday'; break; case '6': $sday = 'Friday'; break; case '7': $sday = 'Saturday'; break; } $time = strtotime("$sweek $sday", $start); $cur_month = date('n', $time); if ($cur_month != $month_of_year) { break 2; } if ($time !== false && $time > 0) { $times[$time] = $time; } } } asort($times); foreach($times as $time) { if ($time > $now) { break; } } } } db_execute_prepared('UPDATE automation_networks SET next_start = ? WHERE id = ?', array(date('Y-m-d H:i', $time), $network_id)); return true; } }else{ if ($now > $next) { while(true) { $next += $day; $month_of_year = date('n', $next); $day_of_month = date('j', $next); $times = array(); $key = array_search($month_of_year, $months); if ($key !== false && $key >= 0) { foreach($weeks as $week) { switch($week) { case '1': $sweek = '1st'; break; case '2': $sweek = '2nd'; break; case '3': $sweek = '3rd'; break; case '4': $sweek = '4th'; break; } foreach($days as $day) { switch($day) { case '1': $sday = 'Sunday'; break; case '2': $sday = 'Monday'; break; case '3': $sday = 'Tuesday'; break; case '4': $sday = 'Wednesday'; break; case '5': $sday = 'Thursday'; break; case '6': $sday = 'Friday'; break; case '7': $sday = 'Saturday'; break; } $time = strtotime("$sweek $sday", $next); $cur_month = date('n', $time); if ($cur_month != $month_of_year) { break 2; } if ($time !== false && $time > 0) { $times[$time] = $time; } } } asort($times); foreach($times as $time) { if ($time > $now) { break; } } } } db_execute_prepared('UPDATE automation_networks SET next_start = ? WHERE id = ?', array(date('Y-m-d H:i', $time), $network_id)); return true; } } return false; break; } } function ping_netbios_name($ip, $timeout_ms = 1000) { $handle = @fsockopen("udp://$ip", 137); if (is_resource($handle)) { stream_set_timeout($handle, floor($timeout_ms/1000), ($timeout_ms*1000)%1000000); stream_set_blocking($handle, 1); $packet = "\x99\x99\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x20\x43\x4b" . str_repeat("\x41", 30) . "\x00\x00\x21\x00\x01"; /* send our request (and store request size so we can cheat later) */ $requestsize = @fwrite($handle, $packet); /* get the response */ $response = @fread($handle, 2048); /* check to see if it timed out */ $info = @stream_get_meta_data($handle); /* close the socket */ fclose($handle); if ($info["timed_out"]) { return false; } if (!isset($response[56])) { return false; } /* parse the response and find the response type */ $names = hexdec(ord($response[56])); if ($names > 0) { $host = ''; for($i=57;$i