1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22/**
23 * Import formatter
24 */
25class CImportDataAdapter {
26
27	/**
28	 * @var array configuration import data
29	 */
30	protected $data;
31
32	/**
33	 * Object used for converting older import versions.
34	 *
35	 * @var CConverterChain
36	 */
37	protected $converterChain;
38
39	/**
40	 * Current import version.
41	 *
42	 * @var string
43	 */
44	protected $currentVersion;
45
46	/**
47	 * @param string            $currentVersion     current import version
48	 * @param CConverterChain   $converterChain     object used for converting older import versions
49	 */
50	public function __construct($currentVersion, CConverterChain $converterChain) {
51		$this->currentVersion = $currentVersion;
52		$this->converterChain = $converterChain;
53	}
54
55	/**
56	 * Set the data and initialize the adapter.
57	 *
58	 * @param array $data   import data
59	 */
60	public function load(array $data) {
61		$version = $data['zabbix_export']['version'];
62
63		if ($this->currentVersion != $version) {
64			$data = $this->converterChain->convert($data, $version);
65		}
66
67		$this->data = $data['zabbix_export'];
68	}
69
70	/**
71	 * Get groups from the imported data.
72	 *
73	 * @return array
74	 */
75	public function getGroups() {
76		return array_key_exists('groups', $this->data) ? $this->data['groups'] : [];
77	}
78
79	/**
80	 * Get templates from the imported data.
81	 *
82	 * @return array
83	 */
84	public function getTemplates() {
85		$templates = [];
86
87		if (array_key_exists('templates', $this->data)) {
88			foreach ($this->data['templates'] as $template) {
89				$template = CArrayHelper::renameKeys($template, ['template' => 'host']);
90
91				$templates[] = CArrayHelper::getByKeys($template, [
92					'groups', 'macros', 'templates', 'host', 'status', 'name', 'description'
93				]);
94			}
95		}
96
97		return $templates;
98	}
99
100	/**
101	 * Get hosts from the imported data.
102	 *
103	 * @return array
104	 */
105	public function getHosts() {
106		$hosts = [];
107
108		if (array_key_exists('hosts', $this->data)) {
109			foreach ($this->data['hosts'] as $host) {
110				$host = CArrayHelper::renameKeys($host, ['proxyid' => 'proxy_hostid']);
111
112				if (array_key_exists('interfaces', $host)) {
113					foreach ($host['interfaces'] as $inum => $interface) {
114						if ($interface['type'] != INTERFACE_TYPE_SNMP) {
115							unset($interface['bulk']);
116						}
117
118						$host['interfaces'][$inum] = CArrayHelper::renameKeys($interface, ['default' => 'main']);
119					}
120				}
121
122				if (array_key_exists('inventory', $host)) {
123					if (array_key_exists('inventory_mode', $host['inventory'])) {
124						$host['inventory_mode'] = $host['inventory']['inventory_mode'];
125						unset($host['inventory']['inventory_mode']);
126					}
127					else {
128						$host['inventory_mode'] = HOST_INVENTORY_DISABLED;
129					}
130				}
131
132				$hosts[] = CArrayHelper::getByKeys($host, [
133					'inventory', 'proxy', 'groups', 'templates', 'macros', 'interfaces', 'host', 'status',
134					'description', 'ipmi_authtype', 'ipmi_privilege', 'ipmi_username', 'ipmi_password', 'name',
135					'inventory_mode', 'tls_connect', 'tls_accept', 'tls_issuer', 'tls_subject', 'tls_psk_identity',
136					'tls_psk'
137				]);
138			}
139		}
140
141		return $hosts;
142	}
143
144	/**
145	 * Get applications from the imported data.
146	 *
147	 * @return array
148	 */
149	public function getApplications() {
150		$applications = [];
151
152		if (array_key_exists('hosts', $this->data)) {
153			foreach ($this->data['hosts'] as $host) {
154				if (array_key_exists('applications', $host)) {
155					foreach ($host['applications'] as $application) {
156						$applications[$host['host']][$application['name']] = $application;
157					}
158				}
159			}
160		}
161
162		if (array_key_exists('templates', $this->data)) {
163			foreach ($this->data['templates'] as $template) {
164				if (array_key_exists('applications', $template)) {
165					foreach ($template['applications'] as $application) {
166						$applications[$template['template']][$application['name']] = $application;
167					}
168				}
169			}
170		}
171
172		return $applications;
173	}
174
175	/**
176	 * Get value maps from the imported data.
177	 *
178	 * @return array
179	 */
180	public function getValueMaps() {
181		return array_key_exists('value_maps', $this->data) ? $this->data['value_maps'] : [];
182	}
183
184	/**
185	 * Get items from the imported data.
186	 *
187	 * @return array
188	 */
189	public function getItems() {
190		$items = [];
191
192		if (array_key_exists('hosts', $this->data)) {
193			foreach ($this->data['hosts'] as $host) {
194				if (array_key_exists('items', $host)) {
195					foreach ($host['items'] as $item) {
196						$items[$host['host']][$item['key']] = $this->renameItemFields($item);
197					}
198				}
199			}
200		}
201
202		if (array_key_exists('templates', $this->data)) {
203			foreach ($this->data['templates'] as $template) {
204				if (array_key_exists('items', $template)) {
205					foreach ($template['items'] as $item) {
206						$items[$template['template']][$item['key']] = $this->renameItemFields($item);
207					}
208				}
209			}
210		}
211
212		return $items;
213	}
214
215	/**
216	 * Get discovery rules from the imported data.
217	 *
218	 * @return array
219	 */
220	public function getDiscoveryRules() {
221		$discovery_rules = [];
222
223		if (array_key_exists('hosts', $this->data)) {
224			foreach ($this->data['hosts'] as $host) {
225				if (array_key_exists('discovery_rules', $host)) {
226					foreach ($host['discovery_rules'] as $discovery_rule) {
227						$discovery_rules[$host['host']][$discovery_rule['key']] =
228							$this->formatDiscoveryRule($discovery_rule);
229					}
230				}
231			}
232		}
233
234		if (array_key_exists('templates', $this->data)) {
235			foreach ($this->data['templates'] as $template) {
236				if (array_key_exists('discovery_rules', $template)) {
237					foreach ($template['discovery_rules'] as $discovery_rule) {
238						$discovery_rules[$template['template']][$discovery_rule['key']] =
239							$this->formatDiscoveryRule($discovery_rule);
240					}
241				}
242			}
243		}
244
245		return $discovery_rules;
246	}
247
248	/**
249	 * Get web scenarios from the imported data.
250	 *
251	 * @return array
252	 */
253	public function getHttpTests() {
254		$httptests = [];
255
256		if (array_key_exists('hosts', $this->data)) {
257			foreach ($this->data['hosts'] as $host) {
258				if (array_key_exists('httptests', $host)) {
259					foreach ($host['httptests'] as $httptest) {
260						$httptests[$host['host']][$httptest['name']] = $this->formatHttpTest($httptest);
261					}
262				}
263			}
264		}
265
266		if (array_key_exists('templates', $this->data)) {
267			foreach ($this->data['templates'] as $template) {
268				if (array_key_exists('httptests', $template)) {
269					foreach ($template['httptests'] as $httptest) {
270						$httptests[$template['template']][$httptest['name']] = $this->formatHttpTest($httptest);
271					}
272				}
273			}
274		}
275
276		return $httptests;
277	}
278
279	/**
280	 * Get web scenario steps from the imported data.
281	 *
282	 * @return array
283	 */
284	public function getHttpSteps() {
285		$httpsteps = [];
286
287		if (array_key_exists('hosts', $this->data)) {
288			foreach ($this->data['hosts'] as $host) {
289				if (array_key_exists('httptests', $host)) {
290					foreach ($host['httptests'] as $httptest) {
291						foreach ($httptest['steps'] as $httpstep) {
292							$httpsteps[$host['host']][$httptest['name']][$httpstep['name']] = $httpstep;
293						}
294					}
295				}
296			}
297		}
298
299		if (array_key_exists('templates', $this->data)) {
300			foreach ($this->data['templates'] as $template) {
301				if (array_key_exists('httptests', $template)) {
302					foreach ($template['httptests'] as $httptest) {
303						foreach ($httptest['steps'] as $httpstep) {
304							$httpsteps[$template['template']][$httptest['name']][$httpstep['name']] = $httpstep;
305						}
306					}
307				}
308			}
309		}
310
311		return $httpsteps;
312	}
313
314	/**
315	 * Get graphs from the imported data.
316	 *
317	 * @return array
318	 */
319	public function getGraphs() {
320		$graphs = [];
321
322		if (array_key_exists('graphs', $this->data)) {
323			foreach ($this->data['graphs'] as $graph) {
324				$graphs[] = $this->renameGraphFields($graph);
325			}
326		}
327
328		return $graphs;
329	}
330
331	/**
332	 * Get triggers from the imported data.
333	 *
334	 * @return array
335	 */
336	public function getTriggers() {
337		$triggers = [];
338
339		if (array_key_exists('triggers', $this->data)) {
340			foreach ($this->data['triggers'] as $trigger) {
341				$triggers[] = $this->renameTriggerFields($trigger);
342			}
343		}
344
345		return $triggers;
346	}
347
348	/**
349	 * Get images from the imported data.
350	 *
351	 * @return array
352	 */
353	public function getImages() {
354		$images = [];
355
356		if (array_key_exists('images', $this->data)) {
357			foreach ($this->data['images'] as $image) {
358				$images[] = CArrayHelper::renameKeys($image, ['encodedImage' => 'image']);
359			}
360		}
361
362		return $images;
363	}
364
365	/**
366	 * Get maps from the imported data.
367	 *
368	 * @return array
369	 */
370	public function getMaps() {
371		return array_key_exists('maps', $this->data) ? $this->data['maps'] : [];
372	}
373
374	/**
375	 * Get screens from the imported data.
376	 *
377	 * @return array
378	 */
379	public function getScreens() {
380		$screens = [];
381
382		if (array_key_exists('screens', $this->data)) {
383			foreach ($this->data['screens'] as $screen) {
384				$screens[] = CArrayHelper::renameKeys($screen, ['screen_items' => 'screenitems']);
385			}
386		}
387
388		return $screens;
389	}
390
391	/**
392	 * Get template screens from the imported data.
393	 *
394	 * @return array
395	 */
396	public function getTemplateScreens() {
397		$screens = [];
398
399		if (array_key_exists('templates', $this->data)) {
400			foreach ($this->data['templates'] as $template) {
401				if (array_key_exists('screens', $template)) {
402					foreach ($template['screens'] as $screen) {
403						$screens[$template['template']][$screen['name']] =
404							CArrayHelper::renameKeys($screen, ['screen_items' => 'screenitems']);
405					}
406				}
407			}
408		}
409
410		return $screens;
411	}
412
413	/**
414	 * Format discovery rule.
415	 *
416	 * @param array $discovery_rule
417	 *
418	 * @return array
419	 */
420	protected function formatDiscoveryRule(array $discovery_rule) {
421		$discovery_rule = $this->renameItemFields($discovery_rule);
422
423		foreach ($discovery_rule['item_prototypes'] as &$item_prototype) {
424			$item_prototype = $this->renameItemFields($item_prototype);
425		}
426		unset($item_prototype);
427
428		foreach ($discovery_rule['trigger_prototypes'] as &$trigger_prototype) {
429			$trigger_prototype = $this->renameTriggerFields($trigger_prototype);
430		}
431		unset($trigger_prototype);
432
433		foreach ($discovery_rule['graph_prototypes'] as &$graph_prototype) {
434			$graph_prototype = $this->renameGraphFields($graph_prototype);
435		}
436		unset($graph_prototype);
437
438		return $discovery_rule;
439	}
440
441	/**
442	 * Rename items, discovery rules, item prototypes fields.
443	 *
444	 * @param array $item
445	 *
446	 * @return array
447	 */
448	protected function renameItemFields(array $item) {
449		return CArrayHelper::renameKeys($item, ['key' => 'key_', 'allowed_hosts' => 'trapper_hosts']);
450	}
451
452	/**
453	 * Format web scenario.
454	 *
455	 * @param array $httptest
456	 *
457	 * @return array
458	 */
459	protected function formatHttpTest(array $httptest) {
460		$httptest = $this->renameHttpTestFields($httptest);
461
462		$no = 0;
463		foreach ($httptest['steps'] as &$step) {
464			$step['no'] = ++$no;
465		}
466		unset($step);
467
468		return $httptest;
469	}
470
471	/**
472	 * Rename web scenarios fields.
473	 *
474	 * @param array $httptest
475	 *
476	 * @return array
477	 */
478	protected function renameHttpTestFields(array $httptest) {
479		return CArrayHelper::renameKeys($httptest, ['attempts' => 'retries']);
480	}
481
482	/**
483	 * Rename triggers, trigger prototypes fields.
484	 *
485	 * @param array $trigger
486	 *
487	 * @return array
488	 */
489	protected function renameTriggerFields(array $trigger) {
490		$trigger = CArrayHelper::renameKeys($trigger, ['description' => 'comments']);
491
492		return CArrayHelper::renameKeys($trigger, ['name' => 'description', 'severity' => 'priority']);
493	}
494
495	/**
496	 * Rename graphs, graph prototypes fields.
497	 *
498	 * @param array $graph
499	 *
500	 * @return array
501	 */
502	protected function renameGraphFields(array $graph) {
503		return CArrayHelper::renameKeys($graph, [
504			'type' => 'graphtype',
505			'ymin_type_1' => 'ymin_type',
506			'ymax_type_1' => 'ymax_type',
507			'graph_items' => 'gitems'
508		]);
509	}
510}
511