1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **/
19
20 #include "common.h"
21
22 #include "db.h"
23 #include "log.h"
24 #include "dbcache.h"
25 #include "zbxserver.h"
26
27 typedef struct
28 {
29 zbx_uint64_t itemid;
30 zbx_uint64_t valuemapid;
31 zbx_uint64_t interfaceid;
32 zbx_uint64_t templateid;
33 char *name;
34 char *key;
35 char *delay_flex;
36 char *trapper_hosts;
37 char *units;
38 char *formula;
39 char *logtimefmt;
40 char *params;
41 char *ipmi_sensor;
42 char *snmp_community;
43 char *snmp_oid;
44 char *snmpv3_securityname;
45 char *snmpv3_authpassphrase;
46 char *snmpv3_privpassphrase;
47 char *snmpv3_contextname;
48 char *username;
49 char *password;
50 char *publickey;
51 char *privatekey;
52 char *description;
53 char *lifetime;
54 char *port;
55 int delay;
56 int history;
57 int trends;
58 unsigned char type;
59 unsigned char value_type;
60 unsigned char data_type;
61 unsigned char status;
62 unsigned char multiplier;
63 unsigned char delta;
64 unsigned char snmpv3_securitylevel;
65 unsigned char snmpv3_authprotocol;
66 unsigned char snmpv3_privprotocol;
67 unsigned char authtype;
68 unsigned char flags;
69 unsigned char inventory_link;
70 unsigned char evaltype;
71 }
72 zbx_template_item_t;
73
74 /* lld rule condition */
75 typedef struct
76 {
77 zbx_uint64_t item_conditionid;
78 char *macro;
79 char *value;
80 unsigned char operator;
81 }
82 zbx_lld_rule_condition_t;
83
84 /* lld rule */
85 typedef struct
86 {
87 /* discovery rule source id */
88 zbx_uint64_t templateid;
89 /* discovery rule source conditions */
90 zbx_vector_ptr_t conditions;
91
92 /* discovery rule destination id */
93 zbx_uint64_t itemid;
94 /* the starting id to be used for destination condition ids */
95 zbx_uint64_t conditionid;
96 /* discovery rule destination condition ids */
97 zbx_vector_uint64_t conditionids;
98 }
99 zbx_lld_rule_map_t;
100
101 /* auxiliary function for DBcopy_template_items() */
DBget_interfaces_by_hostid(zbx_uint64_t hostid,zbx_uint64_t * interfaceids)102 static void DBget_interfaces_by_hostid(zbx_uint64_t hostid, zbx_uint64_t *interfaceids)
103 {
104 DB_RESULT result;
105 DB_ROW row;
106 unsigned char type;
107
108 result = DBselect(
109 "select type,interfaceid"
110 " from interface"
111 " where hostid=" ZBX_FS_UI64
112 " and type in (%d,%d,%d,%d)"
113 " and main=1",
114 hostid, INTERFACE_TYPE_AGENT, INTERFACE_TYPE_SNMP, INTERFACE_TYPE_IPMI, INTERFACE_TYPE_JMX);
115
116 while (NULL != (row = DBfetch(result)))
117 {
118 ZBX_STR2UCHAR(type, row[0]);
119 ZBX_STR2UINT64(interfaceids[type - 1], row[1]);
120 }
121 DBfree_result(result);
122 }
123
124 /******************************************************************************
125 * *
126 * Function: get_template_items *
127 * *
128 * Purpose: read template items from database *
129 * *
130 * Parameters: hostid - [IN] host id *
131 * templateids - [IN] array of template IDs *
132 * items - [OUT] the item data *
133 * *
134 * Comments: The itemid and key are set depending on whether the item exists *
135 * for the specified host. *
136 * If item exists itemid will be set to its itemid and key will be *
137 * set to NULL. *
138 * If item does not exist, itemid will be set to 0 and key will be *
139 * set to item key. *
140 * *
141 ******************************************************************************/
get_template_items(zbx_uint64_t hostid,const zbx_vector_uint64_t * templateids,zbx_vector_ptr_t * items)142 static void get_template_items(zbx_uint64_t hostid, const zbx_vector_uint64_t *templateids, zbx_vector_ptr_t *items)
143 {
144 DB_RESULT result;
145 DB_ROW row;
146 char *sql = NULL;
147 size_t sql_alloc = 0, sql_offset = 0, i;
148 unsigned char interface_type;
149 zbx_template_item_t *item;
150 zbx_uint64_t interfaceids[4];
151
152 memset(&interfaceids, 0, sizeof(interfaceids));
153 DBget_interfaces_by_hostid(hostid, interfaceids);
154
155 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
156 "select ti.itemid,ti.name,ti.key_,ti.type,ti.value_type,ti.data_type,ti.delay,ti.delay_flex,"
157 "ti.history,ti.trends,ti.status,ti.trapper_hosts,ti.units,ti.multiplier,ti.delta,"
158 "ti.formula,ti.logtimefmt,ti.valuemapid,ti.params,ti.ipmi_sensor,ti.snmp_community,"
159 "ti.snmp_oid,ti.snmpv3_securityname,ti.snmpv3_securitylevel,ti.snmpv3_authprotocol,"
160 "ti.snmpv3_authpassphrase,ti.snmpv3_privprotocol,ti.snmpv3_privpassphrase,ti.authtype,"
161 "ti.username,ti.password,ti.publickey,ti.privatekey,ti.flags,ti.description,"
162 "ti.inventory_link,ti.lifetime,ti.snmpv3_contextname,hi.itemid,ti.evaltype,ti.port"
163 " from items ti"
164 " left join items hi on hi.key_=ti.key_"
165 " and hi.hostid=" ZBX_FS_UI64
166 " where",
167 hostid);
168 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "ti.hostid", templateids->values, templateids->values_num);
169
170 result = DBselect("%s", sql);
171
172 while (NULL != (row = DBfetch(result)))
173 {
174 item = zbx_malloc(NULL, sizeof(zbx_template_item_t));
175
176 ZBX_STR2UINT64(item->templateid, row[0]);
177 ZBX_STR2UCHAR(item->type, row[3]);
178 ZBX_STR2UCHAR(item->value_type, row[4]);
179 ZBX_STR2UCHAR(item->data_type, row[5]);
180 item->delay = atoi(row[6]);
181 item->history = atoi(row[8]);
182 item->trends = atoi(row[9]);
183 ZBX_STR2UCHAR(item->status, row[10]);
184 ZBX_STR2UCHAR(item->multiplier, row[13]);
185 ZBX_STR2UCHAR(item->delta, row[14]);
186 ZBX_DBROW2UINT64(item->valuemapid, row[17]);
187 ZBX_STR2UCHAR(item->snmpv3_securitylevel, row[23]);
188 ZBX_STR2UCHAR(item->snmpv3_authprotocol, row[24]);
189 ZBX_STR2UCHAR(item->snmpv3_privprotocol, row[26]);
190 ZBX_STR2UCHAR(item->authtype, row[28]);
191 ZBX_STR2UCHAR(item->flags, row[33]);
192 ZBX_STR2UCHAR(item->inventory_link, row[35]);
193 ZBX_STR2UCHAR(item->evaltype, row[39]);
194
195 switch (interface_type = get_interface_type_by_item_type(item->type))
196 {
197 case INTERFACE_TYPE_UNKNOWN:
198 item->interfaceid = 0;
199 break;
200 case INTERFACE_TYPE_ANY:
201 for (i = 0; INTERFACE_TYPE_COUNT > i; i++)
202 {
203 if (0 != interfaceids[INTERFACE_TYPE_PRIORITY[i] - 1])
204 break;
205 }
206 item->interfaceid = interfaceids[INTERFACE_TYPE_PRIORITY[i] - 1];
207 break;
208 default:
209 item->interfaceid = interfaceids[interface_type - 1];
210 }
211
212 item->name = zbx_strdup(NULL, row[1]);
213 item->delay_flex = zbx_strdup(NULL, row[7]);
214 item->trapper_hosts = zbx_strdup(NULL, row[11]);
215 item->units = zbx_strdup(NULL, row[12]);
216 item->formula = zbx_strdup(NULL, row[15]);
217 item->logtimefmt = zbx_strdup(NULL, row[16]);
218 item->params = zbx_strdup(NULL, row[18]);
219 item->ipmi_sensor = zbx_strdup(NULL, row[19]);
220 item->snmp_community = zbx_strdup(NULL, row[20]);
221 item->snmp_oid = zbx_strdup(NULL, row[21]);
222 item->snmpv3_securityname = zbx_strdup(NULL, row[22]);
223 item->snmpv3_authpassphrase = zbx_strdup(NULL, row[25]);
224 item->snmpv3_privpassphrase = zbx_strdup(NULL, row[27]);
225 item->username = zbx_strdup(NULL, row[29]);
226 item->password = zbx_strdup(NULL, row[30]);
227 item->publickey = zbx_strdup(NULL, row[31]);
228 item->privatekey = zbx_strdup(NULL, row[32]);
229 item->description = zbx_strdup(NULL, row[34]);
230 item->lifetime = zbx_strdup(NULL, row[36]);
231 item->snmpv3_contextname = zbx_strdup(NULL, row[37]);
232 item->port = zbx_strdup(NULL, row[40]);
233
234 if (SUCCEED != DBis_null(row[38]))
235 {
236 item->key = NULL;
237 ZBX_STR2UINT64(item->itemid, row[38]);
238 }
239 else
240 {
241 item->key = zbx_strdup(NULL, row[2]);
242 item->itemid = 0;
243 }
244
245 zbx_vector_ptr_append(items, item);
246 }
247 DBfree_result(result);
248
249 zbx_free(sql);
250
251 zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
252 }
253
254 /******************************************************************************
255 * *
256 * Function: get_template_lld_rule_map *
257 * *
258 * Purpose: reads template lld rule conditions and host lld_rule identifiers *
259 * from database *
260 * *
261 * Parameters: items - [IN] the host items including lld rules *
262 * rules - [OUT] the ldd rule mapping *
263 * *
264 ******************************************************************************/
get_template_lld_rule_map(const zbx_vector_ptr_t * items,zbx_vector_ptr_t * rules)265 static void get_template_lld_rule_map(const zbx_vector_ptr_t *items, zbx_vector_ptr_t *rules)
266 {
267 zbx_template_item_t *item;
268 zbx_lld_rule_map_t *rule;
269 zbx_lld_rule_condition_t *condition;
270 int i, index;
271 zbx_vector_uint64_t itemids;
272 DB_RESULT result;
273 DB_ROW row;
274 char *sql = NULL;
275 size_t sql_alloc = 0, sql_offset = 0;
276 zbx_uint64_t itemid, item_conditionid;
277
278 zbx_vector_uint64_create(&itemids);
279
280 /* prepare discovery rules */
281 for (i = 0; i < items->values_num; i++)
282 {
283 item = items->values[i];
284
285 if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags))
286 continue;
287
288 rule = zbx_malloc(NULL, sizeof(zbx_lld_rule_map_t));
289
290 rule->itemid = item->itemid;
291 rule->templateid = item->templateid;
292 rule->conditionid = 0;
293 zbx_vector_uint64_create(&rule->conditionids);
294 zbx_vector_ptr_create(&rule->conditions);
295
296 zbx_vector_ptr_append(rules, rule);
297
298 if (0 != rule->itemid)
299 zbx_vector_uint64_append(&itemids, rule->itemid);
300 zbx_vector_uint64_append(&itemids, rule->templateid);
301 }
302
303 if (0 != itemids.values_num)
304 {
305 zbx_vector_ptr_sort(rules, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
306 zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
307
308 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
309 "select item_conditionid,itemid,operator,macro,value from item_condition where");
310 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num);
311
312 result = DBselect("%s", sql);
313
314 while (NULL != (row = DBfetch(result)))
315 {
316 ZBX_STR2UINT64(itemid, row[1]);
317
318 index = zbx_vector_ptr_bsearch(rules, &itemid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
319
320 if (FAIL != index)
321 {
322 /* read template lld conditions */
323
324 rule = (zbx_lld_rule_map_t *)rules->values[index];
325
326 condition = zbx_malloc(NULL, sizeof(zbx_lld_rule_condition_t));
327
328 ZBX_STR2UINT64(condition->item_conditionid, row[0]);
329 ZBX_STR2UCHAR(condition->operator, row[2]);
330 condition->macro = zbx_strdup(NULL, row[3]);
331 condition->value = zbx_strdup(NULL, row[4]);
332
333 zbx_vector_ptr_append(&rule->conditions, condition);
334 }
335 else
336 {
337 /* read host lld conditions identifiers */
338
339 for (i = 0; i < rules->values_num; i++)
340 {
341 rule = (zbx_lld_rule_map_t *)rules->values[i];
342
343 if (itemid != rule->itemid)
344 continue;
345
346 ZBX_STR2UINT64(item_conditionid, row[0]);
347 zbx_vector_uint64_append(&rule->conditionids, item_conditionid);
348
349 break;
350 }
351
352 if (i == rules->values_num)
353 THIS_SHOULD_NEVER_HAPPEN;
354 }
355 }
356 DBfree_result(result);
357
358 zbx_free(sql);
359 }
360
361 zbx_vector_uint64_destroy(&itemids);
362 }
363
364 /******************************************************************************
365 * *
366 * Function: calculate_template_lld_rule_conditionids *
367 * *
368 * Purpose: calculate identifiers for new item conditions *
369 * *
370 * Parameters: rules - [IN] the ldd rule mapping *
371 * *
372 * Return value: The number of new item conditions to be inserted. *
373 * *
374 ******************************************************************************/
calculate_template_lld_rule_conditionids(zbx_vector_ptr_t * rules)375 static int calculate_template_lld_rule_conditionids(zbx_vector_ptr_t *rules)
376 {
377 zbx_lld_rule_map_t *rule;
378 int i, conditions_num = 0;
379 zbx_uint64_t conditionid;
380
381 /* calculate the number of new conditions to be inserted */
382 for (i = 0; i < rules->values_num; i++)
383 {
384 rule = rules->values[i];
385
386 if (rule->conditions.values_num > rule->conditionids.values_num)
387 conditions_num += rule->conditions.values_num - rule->conditionids.values_num;
388 }
389
390 /* reserve ids for the new conditions to be inserted and assign to lld rules */
391 if (0 == conditions_num)
392 goto out;
393
394 conditionid = DBget_maxid_num("item_condition", conditions_num);
395
396 for (i = 0; i < rules->values_num; i++)
397 {
398 rule = rules->values[i];
399
400 if (rule->conditions.values_num <= rule->conditionids.values_num)
401 continue;
402
403 rule->conditionid = conditionid;
404 conditionid += rule->conditions.values_num - rule->conditionids.values_num;
405 }
406 out:
407 return conditions_num;
408 }
409
410 /******************************************************************************
411 * *
412 * Function: update_template_lld_rule_formulas *
413 * *
414 * Purpose: translate template item condition identifiers in expression type *
415 * discovery rule formulas to refer the host item condition *
416 * identifiers instead. *
417 * *
418 * Parameters: items - [IN] the template items *
419 * rules - [IN] the ldd rule mapping *
420 * *
421 ******************************************************************************/
update_template_lld_rule_formulas(zbx_vector_ptr_t * items,zbx_vector_ptr_t * rules)422 static void update_template_lld_rule_formulas(zbx_vector_ptr_t *items, zbx_vector_ptr_t *rules)
423 {
424 zbx_lld_rule_map_t *rule;
425 int i, j, index;
426 char *formula;
427 zbx_uint64_t conditionid;
428
429 for (i = 0; i < items->values_num; i++)
430 {
431 zbx_template_item_t *item = items->values[i];
432
433 if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags) || CONDITION_EVAL_TYPE_EXPRESSION != item->evaltype)
434 continue;
435
436 index = zbx_vector_ptr_bsearch(rules, &item->templateid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
437
438 if (FAIL == index)
439 {
440 THIS_SHOULD_NEVER_HAPPEN;
441 continue;
442 }
443
444 rule = rules->values[index];
445
446 formula = zbx_strdup(NULL, item->formula);
447
448 conditionid = rule->conditionid;
449
450 for (j = 0; j < rule->conditions.values_num; j++)
451 {
452 zbx_uint64_t id;
453 char srcid[64], dstid[64], *ptr;
454 size_t pos = 0, len;
455
456 zbx_lld_rule_condition_t *condition = rule->conditions.values[j];
457
458 if (j < rule->conditionids.values_num)
459 id = rule->conditionids.values[j];
460 else
461 id = conditionid++;
462
463 zbx_snprintf(srcid, sizeof(srcid), "{" ZBX_FS_UI64 "}", condition->item_conditionid);
464 zbx_snprintf(dstid, sizeof(dstid), "{" ZBX_FS_UI64 "}", id);
465
466 len = strlen(srcid);
467
468 while (NULL != (ptr = strstr(formula + pos, srcid)))
469 {
470 pos = ptr - formula + len - 1;
471 zbx_replace_string(&formula, ptr - formula, &pos, dstid);
472 }
473 }
474
475 zbx_free(item->formula);
476 item->formula = formula;
477 }
478 }
479
480 /******************************************************************************
481 * *
482 * Function: save_template_items *
483 * *
484 * Purpose: saves template items to the target host in database *
485 * *
486 * Parameters: hostid - [IN] the target host *
487 * items - [IN] the template items *
488 * rules - [IN] the ldd rule mapping *
489 * *
490 ******************************************************************************/
save_template_items(zbx_uint64_t hostid,zbx_vector_ptr_t * items)491 void save_template_items(zbx_uint64_t hostid, zbx_vector_ptr_t *items)
492 {
493 char *sql = NULL;
494 size_t sql_alloc = 16 * ZBX_KIBIBYTE, sql_offset = 0;
495 int new_items = items->values_num, i;
496 zbx_uint64_t itemid;
497 zbx_db_insert_t db_insert;
498
499 sql = zbx_malloc(sql, sql_alloc);
500
501 DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
502
503 for (i = 0; i < items->values_num; i++)
504 {
505 char *name_esc, *delay_flex_esc, *trapper_hosts_esc, *units_esc, *formula_esc,
506 *logtimefmt_esc, *params_esc, *ipmi_sensor_esc, *snmp_community_esc,
507 *snmp_oid_esc, *snmpv3_securityname_esc, *snmpv3_authpassphrase_esc,
508 *snmpv3_privpassphrase_esc, *username_esc, *password_esc, *publickey_esc,
509 *privatekey_esc, *description_esc, *lifetime_esc, *snmpv3_contextname_esc,
510 *port_esc;
511 zbx_template_item_t *item = items->values[i];
512
513 /* skip new items */
514 if (NULL != item->key)
515 continue;
516
517 name_esc = DBdyn_escape_string(item->name);
518 delay_flex_esc = DBdyn_escape_string(item->delay_flex);
519 trapper_hosts_esc = DBdyn_escape_string(item->trapper_hosts);
520 units_esc = DBdyn_escape_string(item->units);
521 formula_esc = DBdyn_escape_string(item->formula);
522 logtimefmt_esc = DBdyn_escape_string(item->logtimefmt);
523 params_esc = DBdyn_escape_string(item->params);
524 ipmi_sensor_esc = DBdyn_escape_string(item->ipmi_sensor);
525 snmp_community_esc = DBdyn_escape_string(item->snmp_community);
526 snmp_oid_esc = DBdyn_escape_string(item->snmp_oid);
527 snmpv3_securityname_esc = DBdyn_escape_string(item->snmpv3_securityname);
528 snmpv3_authpassphrase_esc = DBdyn_escape_string(item->snmpv3_authpassphrase);
529 snmpv3_privpassphrase_esc = DBdyn_escape_string(item->snmpv3_privpassphrase);
530 username_esc = DBdyn_escape_string(item->username);
531 password_esc = DBdyn_escape_string(item->password);
532 publickey_esc = DBdyn_escape_string(item->publickey);
533 privatekey_esc = DBdyn_escape_string(item->privatekey);
534 description_esc = DBdyn_escape_string(item->description);
535 lifetime_esc = DBdyn_escape_string(item->lifetime);
536 snmpv3_contextname_esc = DBdyn_escape_string(item->snmpv3_contextname);
537 port_esc = DBdyn_escape_string(item->port);
538
539 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
540 "update items"
541 " set name='%s',"
542 "type=%d,"
543 "value_type=%d,"
544 "data_type=%d,"
545 "delay=%d,"
546 "delay_flex='%s',"
547 "history=%d,"
548 "trends=%d,"
549 "status=%d,"
550 "trapper_hosts='%s',"
551 "units='%s',"
552 "multiplier=%d,"
553 "delta=%d,"
554 "formula='%s',"
555 "logtimefmt='%s',"
556 "valuemapid=%s,"
557 "params='%s',"
558 "ipmi_sensor='%s',"
559 "snmp_community='%s',"
560 "snmp_oid='%s',"
561 "snmpv3_securityname='%s',"
562 "snmpv3_securitylevel=%d,"
563 "snmpv3_authprotocol=%d,"
564 "snmpv3_authpassphrase='%s',"
565 "snmpv3_privprotocol=%d,"
566 "snmpv3_privpassphrase='%s',"
567 "snmpv3_contextname='%s',"
568 "authtype=%d,"
569 "username='%s',"
570 "password='%s',"
571 "publickey='%s',"
572 "privatekey='%s',"
573 "templateid=" ZBX_FS_UI64 ","
574 "flags=%d,"
575 "description='%s',"
576 "inventory_link=%d,"
577 "interfaceid=%s,"
578 "lifetime='%s',"
579 "evaltype=%d,"
580 "port='%s'"
581 " where itemid=" ZBX_FS_UI64 ";\n",
582 name_esc, (int)item->type, (int)item->value_type,
583 (int)item->data_type, item->delay, delay_flex_esc,
584 item->history, item->trends, (int)item->status, trapper_hosts_esc,
585 units_esc, (int)item->multiplier, (int)item->delta, formula_esc,
586 logtimefmt_esc, DBsql_id_ins(item->valuemapid), params_esc,
587 ipmi_sensor_esc, snmp_community_esc, snmp_oid_esc,
588 snmpv3_securityname_esc, (int)item->snmpv3_securitylevel,
589 (int)item->snmpv3_authprotocol, snmpv3_authpassphrase_esc,
590 (int)item->snmpv3_privprotocol, snmpv3_privpassphrase_esc,
591 snmpv3_contextname_esc, (int)item->authtype, username_esc,
592 password_esc, publickey_esc, privatekey_esc,
593 item->templateid, (int)item->flags, description_esc,
594 (int)item->inventory_link, DBsql_id_ins(item->interfaceid),
595 lifetime_esc, (int)item->evaltype, port_esc, item->itemid);
596
597 new_items--;
598
599 zbx_free(port_esc);
600 zbx_free(snmpv3_contextname_esc);
601 zbx_free(lifetime_esc);
602 zbx_free(description_esc);
603 zbx_free(privatekey_esc);
604 zbx_free(publickey_esc);
605 zbx_free(password_esc);
606 zbx_free(username_esc);
607 zbx_free(snmpv3_privpassphrase_esc);
608 zbx_free(snmpv3_authpassphrase_esc);
609 zbx_free(snmpv3_securityname_esc);
610 zbx_free(snmp_oid_esc);
611 zbx_free(snmp_community_esc);
612 zbx_free(ipmi_sensor_esc);
613 zbx_free(params_esc);
614 zbx_free(logtimefmt_esc);
615 zbx_free(formula_esc);
616 zbx_free(units_esc);
617 zbx_free(trapper_hosts_esc);
618 zbx_free(delay_flex_esc);
619 zbx_free(name_esc);
620 }
621
622 DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
623
624 if (16 < sql_offset)
625 DBexecute("%s", sql);
626
627 zbx_free(sql);
628
629 if (0 == new_items)
630 return;
631
632 itemid = DBget_maxid_num("items", new_items);
633
634 zbx_db_insert_prepare(&db_insert, "items", "itemid", "name", "key_", "hostid", "type", "value_type",
635 "data_type", "delay", "delay_flex", "history", "trends", "status", "trapper_hosts", "units",
636 "multiplier", "delta", "formula", "logtimefmt", "valuemapid", "params", "ipmi_sensor",
637 "snmp_community", "snmp_oid", "snmpv3_securityname", "snmpv3_securitylevel",
638 "snmpv3_authprotocol", "snmpv3_authpassphrase", "snmpv3_privprotocol", "snmpv3_privpassphrase",
639 "authtype", "username", "password", "publickey", "privatekey", "templateid", "flags",
640 "description", "inventory_link", "interfaceid", "lifetime", "snmpv3_contextname", "evaltype",
641 "port", NULL);
642
643 for (i = 0; i < items->values_num; i++)
644 {
645 zbx_template_item_t *item = items->values[i];
646
647 /* skip existing items */
648 if (NULL == item->key)
649 continue;
650
651 zbx_db_insert_add_values(&db_insert, itemid, item->name, item->key, hostid, (int)item->type,
652 (int)item->value_type, (int)item->data_type, item->delay, item->delay_flex,
653 item->history, item->trends, (int)item->status, item->trapper_hosts, item->units,
654 (int)item->multiplier, (int)item->delta, item->formula, item->logtimefmt,
655 item->valuemapid, item->params, item->ipmi_sensor, item->snmp_community, item->snmp_oid,
656 item->snmpv3_securityname, (int)item->snmpv3_securitylevel,
657 (int)item->snmpv3_authprotocol, item->snmpv3_authpassphrase,
658 (int)item->snmpv3_privprotocol, item->snmpv3_privpassphrase, (int)item->authtype,
659 item->username, item->password, item->publickey, item->privatekey, item->templateid,
660 (int)item->flags, item->description, (int)item->inventory_link, item->interfaceid,
661 item->lifetime, item->snmpv3_contextname, (int)item->evaltype, item->port);
662
663 item->itemid = itemid++;
664 }
665
666 zbx_db_insert_execute(&db_insert);
667 zbx_db_insert_clean(&db_insert);
668 }
669
670 /******************************************************************************
671 * *
672 * Function: save_template_lld_rules *
673 * *
674 * Purpose: saves template lld rule item conditions to the target host in *
675 * database *
676 * *
677 * Parameters: items - [IN] the template items *
678 * rules - [IN] the ldd rule mapping *
679 * new_conditions - [IN] the number of new item conditions to *
680 * be inserted *
681 * *
682 ******************************************************************************/
save_template_lld_rules(zbx_vector_ptr_t * items,zbx_vector_ptr_t * rules,int new_conditions)683 static void save_template_lld_rules(zbx_vector_ptr_t *items, zbx_vector_ptr_t *rules, int new_conditions)
684 {
685 char *macro_esc, *value_esc;
686 int i, j, index;
687 zbx_db_insert_t db_insert;
688 zbx_lld_rule_map_t *rule;
689 zbx_lld_rule_condition_t *condition;
690 char *sql = NULL;
691 size_t sql_alloc = 0, sql_offset = 0;
692 zbx_vector_uint64_t item_conditionids;
693
694 if (0 == rules->values_num)
695 return;
696
697 zbx_vector_uint64_create(&item_conditionids);
698
699 if (0 != new_conditions)
700 {
701 zbx_db_insert_prepare(&db_insert, "item_condition", "item_conditionid", "itemid", "operator", "macro",
702 "value", NULL);
703
704 /* insert lld rule conditions for new items */
705 for (i = 0; i < items->values_num; i++)
706 {
707 zbx_template_item_t *item = items->values[i];
708
709 if (NULL == item->key)
710 continue;
711
712 if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags))
713 continue;
714
715 index = zbx_vector_ptr_bsearch(rules, &item->templateid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
716
717 if (FAIL == index)
718 {
719 THIS_SHOULD_NEVER_HAPPEN;
720 continue;
721 }
722
723 rule = rules->values[index];
724
725 for (j = 0; j < rule->conditions.values_num; j++)
726 {
727 condition = rule->conditions.values[j];
728
729 zbx_db_insert_add_values(&db_insert, rule->conditionid++, item->itemid,
730 (int)condition->operator, condition->macro, condition->value);
731 }
732 }
733 }
734
735 DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
736
737 /* update lld rule conditions for existing items */
738 for (i = 0; i < rules->values_num; i++)
739 {
740 rule = rules->values[i];
741
742 /* skip lld rules of new items */
743 if (0 == rule->itemid)
744 continue;
745
746 index = MIN(rule->conditions.values_num, rule->conditionids.values_num);
747
748 /* update intersecting rule conditions */
749 for (j = 0; j < index; j++)
750 {
751 condition = rule->conditions.values[j];
752
753 macro_esc = DBdyn_escape_string(condition->macro);
754 value_esc = DBdyn_escape_string(condition->value);
755
756 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update item_condition"
757 " set operator=%d,macro='%s',value='%s'"
758 " where item_conditionid=" ZBX_FS_UI64 ";\n",
759 (int)condition->operator, macro_esc, value_esc, rule->conditionids.values[j]);
760
761 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
762
763 zbx_free(value_esc);
764 zbx_free(macro_esc);
765 }
766
767 /* delete removed rule conditions */
768 for (j = index; j < rule->conditionids.values_num; j++)
769 zbx_vector_uint64_append(&item_conditionids, rule->conditionids.values[j]);
770
771 /* insert new rule conditions */
772 for (j = index; j < rule->conditions.values_num; j++)
773 {
774 condition = rule->conditions.values[j];
775
776 zbx_db_insert_add_values(&db_insert, rule->conditionid++, rule->itemid,
777 (int)condition->operator, condition->macro, condition->value);
778 }
779 }
780
781 /* delete removed item conditions */
782 if (0 != item_conditionids.values_num)
783 {
784 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from item_condition where");
785 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "item_conditionid", item_conditionids.values,
786 item_conditionids.values_num);
787 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
788 }
789
790 DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
791
792 if (16 < sql_offset)
793 DBexecute("%s", sql);
794
795 if (0 != new_conditions)
796 {
797 zbx_db_insert_execute(&db_insert);
798 zbx_db_insert_clean(&db_insert);
799 }
800
801 zbx_free(sql);
802 zbx_vector_uint64_destroy(&item_conditionids);
803 }
804
805 /******************************************************************************
806 * *
807 * Function: save_template_item_applications *
808 * *
809 * Purpose: saves new item applications links in database *
810 * *
811 * Parameters: items - [IN] the template items *
812 * *
813 ******************************************************************************/
save_template_item_applications(zbx_vector_ptr_t * items)814 void save_template_item_applications(zbx_vector_ptr_t *items)
815 {
816 typedef struct
817 {
818 zbx_uint64_t itemid;
819 zbx_uint64_t applicationid;
820 }
821 zbx_itemapp_t;
822
823 DB_RESULT result;
824 DB_ROW row;
825 char *sql = NULL;
826 size_t sql_alloc = 0, sql_offset = 0;
827 zbx_vector_uint64_t itemids;
828 zbx_vector_ptr_t itemapps;
829 zbx_itemapp_t *itemapp;
830 int i;
831 zbx_db_insert_t db_insert;
832
833 zbx_vector_ptr_create(&itemapps);
834 zbx_vector_uint64_create(&itemids);
835
836 for (i = 0; i < items->values_num; i++)
837 {
838 zbx_template_item_t *item = items->values[i];
839
840 zbx_vector_uint64_append(&itemids, item->itemid);
841 }
842
843 zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
844
845 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
846 "select hi.itemid,ha.applicationid"
847 " from items_applications tia"
848 " join items hi on hi.templateid=tia.itemid"
849 " and");
850 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hi.itemid", itemids.values, itemids.values_num);
851 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
852 " join application_template hat on hat.templateid=tia.applicationid"
853 " join applications ha on ha.applicationid=hat.applicationid"
854 " and ha.hostid=hi.hostid"
855 " left join items_applications hia on hia.applicationid=ha.applicationid"
856 " and hia.itemid=hi.itemid"
857 " where hia.itemappid is null");
858
859 result = DBselect("%s", sql);
860
861 while (NULL != (row = DBfetch(result)))
862 {
863 itemapp = zbx_malloc(NULL, sizeof(zbx_itemapp_t));
864
865 ZBX_STR2UINT64(itemapp->itemid, row[0]);
866 ZBX_STR2UINT64(itemapp->applicationid, row[1]);
867
868 zbx_vector_ptr_append(&itemapps, itemapp);
869 }
870 DBfree_result(result);
871
872 if (0 == itemapps.values_num)
873 goto out;
874
875 zbx_db_insert_prepare(&db_insert, "items_applications", "itemappid", "itemid", "applicationid", NULL);
876
877 for (i = 0; i < itemapps.values_num; i++)
878 {
879 itemapp = itemapps.values[i];
880
881 zbx_db_insert_add_values(&db_insert, __UINT64_C(0), itemapp->itemid, itemapp->applicationid);
882 }
883
884 zbx_db_insert_autoincrement(&db_insert, "itemappid");
885 zbx_db_insert_execute(&db_insert);
886 zbx_db_insert_clean(&db_insert);
887 out:
888 zbx_free(sql);
889
890 zbx_vector_uint64_destroy(&itemids);
891
892 zbx_vector_ptr_clear_ext(&itemapps, zbx_ptr_free);
893 zbx_vector_ptr_destroy(&itemapps);
894 }
895
896 /******************************************************************************
897 * *
898 * Function: save_template_discovery_prototypes *
899 * *
900 * Purpose: saves host item prototypes in database *
901 * *
902 * Parameters: hostid - [IN] the target host *
903 * items - [IN] the template items *
904 * *
905 ******************************************************************************/
save_template_discovery_prototypes(zbx_uint64_t hostid,zbx_vector_ptr_t * items)906 void save_template_discovery_prototypes(zbx_uint64_t hostid, zbx_vector_ptr_t *items)
907 {
908 typedef struct
909 {
910 zbx_uint64_t itemid;
911 zbx_uint64_t parent_itemid;
912 }
913 zbx_proto_t;
914
915 DB_RESULT result;
916 DB_ROW row;
917 char *sql = NULL;
918 size_t sql_alloc = 0, sql_offset = 0;
919 zbx_vector_uint64_t itemids;
920 zbx_vector_ptr_t prototypes;
921 zbx_proto_t *proto;
922 int i;
923 zbx_db_insert_t db_insert;
924
925 zbx_vector_ptr_create(&prototypes);
926 zbx_vector_uint64_create(&itemids);
927
928 for (i = 0; i < items->values_num; i++)
929 {
930 zbx_template_item_t *item = items->values[i];
931
932 /* process only new prototype items */
933 if (NULL == item->key || 0 == (ZBX_FLAG_DISCOVERY_PROTOTYPE & item->flags))
934 continue;
935
936 zbx_vector_uint64_append(&itemids, item->itemid);
937 }
938
939 if (0 == itemids.values_num)
940 goto out;
941
942 zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
943
944 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
945 "select i.itemid,r.itemid"
946 " from items i,item_discovery id,items r"
947 " where i.templateid=id.itemid"
948 " and id.parent_itemid=r.templateid"
949 " and r.hostid=" ZBX_FS_UI64
950 " and",
951 hostid);
952 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "i.itemid", itemids.values, itemids.values_num);
953
954 result = DBselect("%s", sql);
955
956 while (NULL != (row = DBfetch(result)))
957 {
958 proto = zbx_malloc(NULL, sizeof(zbx_proto_t));
959
960 ZBX_STR2UINT64(proto->itemid, row[0]);
961 ZBX_STR2UINT64(proto->parent_itemid, row[1]);
962
963 zbx_vector_ptr_append(&prototypes, proto);
964 }
965 DBfree_result(result);
966
967 if (0 == prototypes.values_num)
968 goto out;
969
970 zbx_db_insert_prepare(&db_insert, "item_discovery", "itemdiscoveryid", "itemid",
971 "parent_itemid", NULL);
972
973 for (i = 0; i < prototypes.values_num; i++)
974 {
975 proto = prototypes.values[i];
976
977 zbx_db_insert_add_values(&db_insert, __UINT64_C(0), proto->itemid, proto->parent_itemid);
978 }
979
980 zbx_db_insert_autoincrement(&db_insert, "itemdiscoveryid");
981 zbx_db_insert_execute(&db_insert);
982 zbx_db_insert_clean(&db_insert);
983 out:
984 zbx_free(sql);
985
986 zbx_vector_uint64_destroy(&itemids);
987
988 zbx_vector_ptr_clear_ext(&prototypes, zbx_ptr_free);
989 zbx_vector_ptr_destroy(&prototypes);
990 }
991
992 /******************************************************************************
993 * *
994 * Function: free_template_item *
995 * *
996 * Purpose: frees template item *
997 * *
998 * Parameters: item - [IN] the template item *
999 * *
1000 ******************************************************************************/
free_template_item(zbx_template_item_t * item)1001 void free_template_item(zbx_template_item_t *item)
1002 {
1003 zbx_free(item->port);
1004 zbx_free(item->snmpv3_contextname);
1005 zbx_free(item->lifetime);
1006 zbx_free(item->description);
1007 zbx_free(item->privatekey);
1008 zbx_free(item->publickey);
1009 zbx_free(item->password);
1010 zbx_free(item->username);
1011 zbx_free(item->snmpv3_privpassphrase);
1012 zbx_free(item->snmpv3_authpassphrase);
1013 zbx_free(item->snmpv3_securityname);
1014 zbx_free(item->snmp_oid);
1015 zbx_free(item->snmp_community);
1016 zbx_free(item->ipmi_sensor);
1017 zbx_free(item->params);
1018 zbx_free(item->logtimefmt);
1019 zbx_free(item->formula);
1020 zbx_free(item->units);
1021 zbx_free(item->trapper_hosts);
1022 zbx_free(item->delay_flex);
1023 zbx_free(item->name);
1024 zbx_free(item->key);
1025
1026 zbx_free(item);
1027 }
1028
1029 /******************************************************************************
1030 * *
1031 * Function: free_lld_rule_condition *
1032 * *
1033 * Purpose: frees lld rule condition *
1034 * *
1035 * Parameters: item - [IN] the lld rule condition *
1036 * *
1037 ******************************************************************************/
free_lld_rule_condition(zbx_lld_rule_condition_t * condition)1038 void free_lld_rule_condition(zbx_lld_rule_condition_t *condition)
1039 {
1040 zbx_free(condition->macro);
1041 zbx_free(condition->value);
1042 zbx_free(condition);
1043 }
1044
1045 /******************************************************************************
1046 * *
1047 * Function: free_lld_rule_map *
1048 * *
1049 * Purpose: frees lld rule mapping *
1050 * *
1051 * Parameters: item - [IN] the lld rule mapping *
1052 * *
1053 ******************************************************************************/
free_lld_rule_map(zbx_lld_rule_map_t * rule)1054 void free_lld_rule_map(zbx_lld_rule_map_t *rule)
1055 {
1056 zbx_vector_ptr_clear_ext(&rule->conditions, (zbx_clean_func_t)free_lld_rule_condition);
1057 zbx_vector_ptr_destroy(&rule->conditions);
1058
1059 zbx_vector_uint64_destroy(&rule->conditionids);
1060
1061 zbx_free(rule);
1062 }
1063
1064 /******************************************************************************
1065 * *
1066 * Function: DBcopy_template_items *
1067 * *
1068 * Purpose: copy template items to host *
1069 * *
1070 * Parameters: hostid - [IN] host id *
1071 * templateids - [IN] array of template IDs *
1072 * *
1073 ******************************************************************************/
DBcopy_template_items(zbx_uint64_t hostid,const zbx_vector_uint64_t * templateids)1074 void DBcopy_template_items(zbx_uint64_t hostid, const zbx_vector_uint64_t *templateids)
1075 {
1076 const char *__function_name = "DBcopy_template_items";
1077
1078 zbx_vector_ptr_t items, lld_rules;
1079 int new_conditions = 0;
1080
1081 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
1082
1083 zbx_vector_ptr_create(&items);
1084 zbx_vector_ptr_create(&lld_rules);
1085
1086 get_template_items(hostid, templateids, &items);
1087
1088 if (0 == items.values_num)
1089 goto out;
1090
1091 get_template_lld_rule_map(&items, &lld_rules);
1092
1093 new_conditions = calculate_template_lld_rule_conditionids(&lld_rules);
1094 update_template_lld_rule_formulas(&items, &lld_rules);
1095
1096 save_template_items(hostid, &items);
1097 save_template_lld_rules(&items, &lld_rules, new_conditions);
1098 save_template_item_applications(&items);
1099 save_template_discovery_prototypes(hostid, &items);
1100 out:
1101 zbx_vector_ptr_clear_ext(&lld_rules, (zbx_clean_func_t)free_lld_rule_map);
1102 zbx_vector_ptr_destroy(&lld_rules);
1103
1104 zbx_vector_ptr_clear_ext(&items, (zbx_clean_func_t)free_template_item);
1105 zbx_vector_ptr_destroy(&items);
1106
1107 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
1108 }
1109