feat: add template and template group management via GraphQL

- Implemented GraphQL endpoints for importing, querying, and deleting Zabbix templates and template groups. - Added support for full template data import, including items, preprocessing steps, tags, and linked templates. - Implemented dependent item support by deferred creation logic in the template importer. - Added ability to query templates and template groups with name pattern filtering (supporting Zabbix wildcards). - Implemented batch deletion for templates and template groups by ID or name pattern. - Improved error reporting by including detailed Zabbix API error data in GraphQL responses. - Added comprehensive unit and integration tests covering all new functionality. - Provided GraphQL sample queries and mutations in the 'docs' directory for all new endpoints.
This commit is contained in:
Andreas Hilbig 2026-01-24 15:42:13 +01:00
parent e641f8e610
commit a3ed4886a3
22 changed files with 2450 additions and 20 deletions

View file

@ -0,0 +1,18 @@
### Query
Use this query to list all template groups.
```graphql
query AllTemplateGroups($name_pattern: String) {
allTemplateGroups(name_pattern: $name_pattern) {
groupid
name
}
}
```
### Variables
```json
{
"name_pattern": "Templates/Roadwork/*"
}
```

View file

@ -0,0 +1,30 @@
### Mutation
Use this mutation to delete template groups by their numeric IDs or by a name pattern.
```graphql
mutation DeleteTemplateGroups($groupids: [Int!], $name_pattern: String) {
deleteTemplateGroups(groupids: $groupids, name_pattern: $name_pattern) {
id
message
error {
message
code
data
}
}
}
```
### Variables (by ID)
```json
{
"groupids": [201]
}
```
### Variables (by name pattern)
```json
{
"name_pattern": "Templates/Roadwork/%"
}
```

View file

@ -0,0 +1,30 @@
### Mutation
Use this mutation to delete templates by their numeric IDs or by a name pattern.
```graphql
mutation DeleteTemplates($templateids: [Int!], $name_pattern: String) {
deleteTemplates(templateids: $templateids, name_pattern: $name_pattern) {
id
message
error {
message
code
data
}
}
}
```
### Variables (by ID)
```json
{
"templateids": [501]
}
```
### Variables (by name pattern)
```json
{
"name_pattern": "BT_DEVICE_TRACKER%"
}
```

View file

@ -0,0 +1,59 @@
### Mutation
Use this mutation to import template groups.
```graphql
mutation ImportTemplateGroups($templateGroups: [CreateTemplateGroup!]!) {
importTemplateGroups(templateGroups: $templateGroups) {
groupName
groupid
message
error {
message
code
data
}
}
}
```
### Variables
This sample data is based on the `template_groups` from `src/testdata/templates/zbx_default_templates_vcr.yaml`.
```json
{
"templateGroups": [
{
"uuid": "43aab460fe444f18886b19948413b7e3",
"groupName": "Permissions/ConstructionSite"
},
{
"uuid": "376524057e094c07aaa0cf7f524849dc",
"groupName": "Templates/Roadwork/Controller"
},
{
"uuid": "7d83c76454564390bb0e34600780eaec",
"groupName": "Templates/Roadwork/Device-Capabilities"
},
{
"uuid": "48d5d2a18a08448c96a931b63bb2c97d",
"groupName": "Templates/Roadwork/Device-Capabilities/FLASH_ATTACHABLE"
},
{
"uuid": "785986b84892468ea2e92d912747b1d3",
"groupName": "Templates/Roadwork/Device-Capabilities/GEOLOCALIZABLE"
},
{
"uuid": "a4b79479e97a4b48972dcb476d45e55a",
"groupName": "Templates/Roadwork/Device-Capabilities/HAS_OPERATIONAL_DATA"
},
{
"uuid": "3604af8102644bee9dcaf0f9c1ee93a1",
"groupName": "Templates/Roadwork/Devices"
},
{
"uuid": "5ad0bd9e42a4487e869e9e41b38fe553",
"groupName": "Templates/Roadwork/DisplayLibrary"
}
]
}
```

View file

@ -0,0 +1,97 @@
### Mutation
Use this mutation to import templates along with their items, tags, and linked templates.
```graphql
mutation ImportTemplates($templates: [CreateTemplate!]!) {
importTemplates(templates: $templates) {
host
templateid
message
error {
message
code
data
}
}
}
```
### Variables
This sample data is based on the `BT_DEVICE_TRACKER` template from `src/testdata/templates/zbx_default_templates_vcr.yaml`.
```json
{
"templates": [
{
"uuid": "27474f627cb344b782a81c16d7e0c7d1",
"host": "BT_DEVICE_TRACKER",
"name": "BT_DEVICE_TRACKER",
"groupNames": ["Templates/Roadwork/Devices"],
"templates": [
{ "name": "ROADWORK_DEVICE" }
],
"tags": [
{ "tag": "class", "value": "roadwork" },
{ "tag": "deviceType", "value": "bt_device_tracker_generic" }
],
"items": [
{
"uuid": "d4d3ec9f3ca940a39a721b6cfd2f3471",
"name": "location",
"type": 18,
"key": "location",
"value_type": 4,
"history": "2d",
"preprocessing": [
{
"type": 21,
"params": [
"var obj=JSON.parse(value);\n\nif (obj[\"isFiltered\"]) {\n throw \"Result is filtered\";\n return \"filtered\";\n}\n\nreturn value;"
]
},
{
"type": 15,
"params": ["filtered"],
"error_handler": 1
}
],
"master_item": {
"key": "mqtt.trap[deviceValue/location]"
}
},
{
"uuid": "380c4a7d752848cba3b5a59a0f9b13c0",
"name": "MQTT_LOCATION",
"type": 2,
"key": "mqtt.trap[deviceValue/location]",
"value_type": 4,
"history": "0"
}
]
}
]
}
```
### Mapping Reference
When converting from Zabbix YAML/XML exports, use the following numeric mappings for items and preprocessing:
#### Item Type (`type`)
- `2`: ZABBIX_TRAP (TRAP)
- `18`: DEPENDANT_ITEM (DEPENDENT)
- `21`: SIMULATOR_JAVASCRIPT (JAVASCRIPT)
#### Value Type (`value_type`)
- `0`: Float
- `3`: Int (Numeric unsigned)
- `4`: Text
#### Preprocessing Type (`type`)
- `12`: JSONPATH
- `15`: NOT_MATCHES_REGEX
- `21`: JAVASCRIPT
#### Error Handler (`error_handler`)
- `1`: DISCARD_VALUE
- `2`: SET_VALUE
- `3`: SET_ERROR

View file

@ -0,0 +1,18 @@
### Query
Use this query to verify the results of the template import.
```graphql
query GetTemplates($name_pattern: String) {
templates(name_pattern: $name_pattern) {
templateid
name
}
}
```
### Variables
```json
{
"name_pattern": "BT_DEVICE_TRACKER"
}
```