# Zabbix GraphQL API A GraphQL wrapper for the Zabbix API that provides enhanced mass import/export operations, hierarchical host group management, and dynamic schema extensibility. Built with Apollo Server, TypeScript, and ES modules. ## ๐Ÿš€ Features - **GraphQL Interface**: Modern GraphQL API wrapping Zabbix functionality - *Reference*: `schema/queries.graphql`, `schema/mutations.graphql`, `src/api/start.ts` - **Hierarchical Data Mapping**: Automatic mapping of Zabbix items/tags to nested GraphQL objects - *Reference*: `src/api/resolver_helpers.ts`, `schema/device_value_commons.graphql`, `docs/sample_all_devices_query.graphql` - **Mass Operations**: Import/export capabilities for hosts, templates, and user rights - *Reference*: `schema/mutations.graphql` (importHosts, importTemplates, importUserRights, etc.), `docs/sample_import_*.graphql` - **Dynamic Schema Extension**: Extend the schema without code changes using environment variables - *Reference*: `src/api/schema.ts`, `schema/extensions/`, `src/common_utils.ts` (ADDITIONAL_SCHEMAS, ADDITIONAL_RESOLVERS) - **Permission System**: Role-based access control using Zabbix template groups - *Reference*: `schema/api_commons.graphql` (Permission enum, PermissionRequest), `src/api/resolvers.ts` (hasPermissions, userPermissions), `docs/sample_import_permissions_template_groups_mutation.graphql` - **Real-time Subscriptions**: WebSocket support for GraphQL subscriptions (infrastructure implemented) - *Reference*: `src/api/start.ts` (WebSocketServer integration with `graphql-ws`), `AGENTS.md` (mentions WebSocket support), `package.json` (graphql-ws, subscriptions dependencies) - **Type Safety**: Full TypeScript support with generated types - *Reference*: `codegen.ts`, `src/schema/generated/graphql.ts`, `tsconfig.json`, `package.json` (devDependencies for GraphQL Codegen) ## ๐Ÿ“‹ Prerequisites Before you begin, ensure you have met the following requirements: - **Node.js** >= 18.x (tested with v21.5.0) - **NPM** >= 8.x - **Zabbix Server** with API access - **Zabbix Super Admin Token** (for full functionality) ## ๐Ÿ› ๏ธ Installation ### Clone the repository ```bash git clone https://github.com/your-repo/zabbix-graphql-api.git cd zabbix-graphql-api ``` ### Install dependencies ```bash npm install ``` ## โš™๏ธ Configuration ### Environment Variables Create a `.env` file in the project root with the following variables: ```bash # Zabbix connection ZABBIX_BASE_URL=http://your-zabbix-server/zabbix ZABBIX_AUTH_TOKEN=your-super-admin-token ZABBIX_AUTH_TOKEN_FOR_REQUESTS=your-super-admin-token # Optional configuration ZABBIX_EDGE_DEVICE_BASE_GROUP=Roadwork ZABBIX_ROADWORK_BASE_GROUP=Roadwork ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX=Permissions SCHEMA_PATH=./schema/ # Dynamic schema extension (optional) ADDITIONAL_SCHEMAS=./schema/extensions/display_devices.graphql,./schema/extensions/location_tracker_devices.graphql ADDITIONAL_RESOLVERS=SinglePanelDevice,FourPanelDevice,DistanceTrackerDevice # Logging LOG_LEVELS=info ``` ### Environment Variable Details | Variable | Description | Default | |----------|-------------|---------| | `ZABBIX_BASE_URL` | URL to your Zabbix server (include `/zabbix` path) | - | | `ZABBIX_AUTH_TOKEN` | Zabbix Super Admin API token | - | | `ZABBIX_AUTH_TOKEN_FOR_REQUESTS` | Token used for automated requests | - | | `ZABBIX_EDGE_DEVICE_BASE_GROUP` | Base group for edge devices | - | | `ZABBIX_ROADWORK_BASE_GROUP` | Base group for roadwork devices | - | | `ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX` | Prefix for permission template groups | `Permissions` | | `SCHEMA_PATH` | Path to schema files | `./schema/` | | `ADDITIONAL_SCHEMAS` | Comma-separated list of additional schema files | - | | `ADDITIONAL_RESOLVERS` | Comma-separated list of resolver types to generate | - | | `LOG_LEVELS` | Log level configuration | - | ## โ–ถ๏ธ Running the Application ### Development Mode ```bash # Start with hot reloading npm run start ``` The GraphQL API will be available at `http://localhost:4000/` ### Production Build ```bash # Compile TypeScript npm run compile # Run production build npm run prod ``` ### Available Scripts | Script | Description | |--------|-------------| | `npm run start` | Start development server with hot reload | | `npm run compile` | Compile TypeScript to JavaScript | | `npm run prod` | Run production build | | `npm run test` | Run tests | | `npm run codegen` | Generate TypeScript types from GraphQL schema | | `npm run nodemon` | Alternative development runner | ## ๐Ÿณ Docker Deployment ### Using Pre-built Images The application can be deployed using Docker: ```bash # Build the image docker build -t zabbix-graphql-api . # Run the container docker run -d \ --name zabbix-graphql \ -p 4000:4000 \ -e ZABBIX_BASE_URL=http://your-zabbix-server/zabbix \ -e ZABBIX_AUTH_TOKEN=your-super-admin-token \ zabbix-graphql-api ``` ### Building Your Own Image ```bash # Build with custom API version docker build --build-arg API_VERSION=v1.0.0 -t zabbix-graphql-api . # Run with environment file docker run -d \ --name zabbix-graphql \ -p 4000:4000 \ --env-file .env \ zabbix-graphql-api ``` ## ๐Ÿ” Roles and Permissions Extension The API implements a permission system using Zabbix template groups: ### Permission Template Groups - Template groups with prefix `Permissions/` (configurable via `ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX`) are used for permissions - Users gain permissions by being assigned to user groups that have access to these permission template groups ### Available Permissions The system supports three permission levels defined in `schema/api_commons.graphql`: - `DENY`: Explicitly denies access (supersedes other permissions) - `READ`: Allows viewing/reading access - `READ_WRITE`: Allows both reading and writing (implies READ permission) ### Permission Object Names Permission object names map to Zabbix template group paths: `Permissions/{objectName}` ### GraphQL Permission Queries ```graphql # Check if current user has specific permissions query HasPermissions { hasPermissions(permissions: [ { objectName: "hosts", permission: READ }, { objectName: "templates", permission: READ_WRITE } ]) } # Get all user permissions query GetUserPermissions { userPermissions(objectNames: ["hosts", "templates"]) } ``` ### Setting Up Permissions 1. Create template groups with the prefix `Permissions/` (e.g., `Permissions/hosts`, `Permissions/templates`) 2. Assign these template groups to user groups in Zabbix with appropriate permission levels 3. Users in those user groups will inherit the permissions ### Detailed Permission Usage Examples For comprehensive examples of permission usage patterns, see `schema/api_commons.graphql` which contains detailed documentation in the `PermissionRequest` input type comments, including real-world examples of how to model permissions for buttons, status controls, and application features. See also `docs/sample_import_permissions_template_groups_mutation.graphql` for examples of importing permission template groups. ## ๐Ÿ“Š Schema and Schema Extension ### Main Schema Structure The GraphQL schema is located in the `schema/` directory and consists of: - `queries.graphql` - Query definitions (see detailed documentation in file comments) - `mutations.graphql` - Mutation definitions (see detailed documentation in file comments) - `devices.graphql` - Device-related types (see detailed documentation in file comments) - `zabbix.graphql` - Zabbix-specific types (see detailed documentation in file comments) - `device_value_commons.graphql` - Common value types (see detailed documentation in file comments) - `api_commons.graphql` - Common API types and permission system (see detailed documentation in file comments) - `extensions/` - Custom device type extensions For comprehensive understanding of each operation, read the detailed comments in the respective schema files. ### Dynamic Schema Extension Extend the schema without code changes using environment variables: ```bash ADDITIONAL_SCHEMAS=./schema/extensions/display_devices.graphql,./schema/extensions/location_tracker_devices.graphql ADDITIONAL_RESOLVERS=SinglePanelDevice,FourPanelDevice,DistanceTrackerDevice ``` This enables runtime schema extension for custom device types without modifying the core code. ### Sample Operations For practical examples of schema usage, see the sample files in the `docs/` directory: - `docs/sample_all_devices_query.graphql` - Example of querying all devices - `docs/sample_import_templates_mutation.graphql` - Example of importing templates - `docs/sample_import_host_groups_mutation.graphql` - Example of importing host groups ## ๐Ÿ—‚๏ธ Hierarchical Data Mapping The API automatically maps Zabbix items to nested GraphQL objects using the `createHierarchicalValueFieldResolver` function: - Zabbix item key `state.current.values.temperature` โ†’ GraphQL `{ state: { current: { values: { temperature } } } }` - Type hints: `json_`, `str_`, `bool_`, `float_` prefixes for value conversion - Automatic resolution of hierarchical structures from flat Zabbix item keys The `createHierarchicalValueFieldResolver` function (found in `src/api/resolver_helpers.ts`) dynamically creates resolvers that map Zabbix items or tags to hierarchical GraphQL structures. It uses field names and Zabbix item keys (dot-separated) to automatically resolve nested objects, eliminating the need for manual resolver definitions for each hierarchical field. For detailed information about the mapping mechanism and type hinting, see the comments in `schema/device_value_commons.graphql` and `src/api/resolver_helpers.ts`. See `docs/sample_all_devices_query.graphql` for examples of how hierarchical data appears in query results. ## ๐Ÿท๏ธ Zabbix Tags Usage Zabbix tags are used for: - Device classification (`deviceType` tag) - Host categorization (`hostType` tag) - Custom metadata storage - Permission assignment through template groups For detailed information about tag usage and available tag types, see the comments in `schema/devices.graphql` and `schema/zabbix.graphql`. See `docs/sample_all_hosts_query.graphql` and `docs/sample_all_devices_query.graphql` for examples of how tags appear in query results. ## ๐Ÿงช Testing Run the test suite: ```bash npm test ``` The testing strategy includes: - Unit tests with mocked Zabbix API responses - Integration tests with real GraphQL operations - Permission system validation - Import/export functionality testing ## ๐Ÿ“– Detailed Documentation Through Comments This project uses extensive inline documentation in the form of comments within the GraphQL schema files and documentation samples. For the most comprehensive understanding of the API, its capabilities, and usage patterns, read the detailed comments in: - `schema/queries.graphql` - Complete documentation of all query operations - `schema/mutations.graphql` - Complete documentation of all mutation operations with usage examples - `schema/api_commons.graphql` - Detailed explanation of the permission system with real-world usage examples - `docs/*.graphql` - Practical examples of all operations with sample variables and expected outcomes The comments in these files contain real-world usage examples, implementation notes, and detailed explanations that go beyond what's covered in this README. ## ๐Ÿ“– Example: Extending Schema with Distance Tracker Device ### Zabbix-Side Configuration Before extending the schema, you need to configure Zabbix appropriately: #### 1. Host Configuration in Zabbix - Create a host in Zabbix with the tag `deviceType` set to `distance-tracker` - Add items to the host with hierarchical keys that match your GraphQL fields: - `distance.current` (for the `distance` field) - `battery.level` (for the `batteryLevel` field) - `status.lastSeen` (for the `lastSeen` field) - `location.latitude` and `location.longitude` (for the `location` object) #### 2. Item Key Naming Convention The API automatically maps dotted item keys to nested GraphQL objects: - Zabbix item key `distance.current` โ†’ GraphQL `{ distance }` - Zabbix item key `battery.level` โ†’ GraphQL `{ batteryLevel }` - Zabbix item key `location.latitude` โ†’ GraphQL `{ location: { location_lat } }` ### Schema Extension Steps #### 1. Create Schema Extension Create `schema/extensions/distance_tracker_device.graphql`: ```graphql type DistanceTrackerDevice { id: String name: String location: Location distance: Float batteryLevel: Float lastSeen: DateTime } ``` #### 2. Configure Environment Variables ```bash ADDITIONAL_SCHEMAS=./schema/extensions/distance_tracker_device.graphql ADDITIONAL_RESOLVERS=DistanceTrackerDevice ``` #### 3. Import Template via GraphQL Mutation Instead of manually creating items in Zabbix, you can import a complete template using the GraphQL API: ```graphql mutation ImportDistanceTrackerTemplate($templates: [CreateTemplate!]!) { importTemplates(templates: $templates) { host templateid message error { message code data } } } ``` Variables: ```json { "templates": [ { "host": "DISTANCE_TRACKER", "name": "Distance Tracker Device Template", "groupNames": ["Templates/Roadwork/Devices"], "tags": [ { "tag": "deviceType", "value": "DistanceTrackerDevice" } ], "items": [ { "name": "Distance Current Value", "type": 0, "key": "distance.current", "value_type": 0, "history": "7d", "units": "m" }, { "name": "Battery Level", "type": 0, "key": "battery.level", "value_type": 0, "history": "7d", "units": "%" }, { "name": "Last Seen Timestamp", "type": 0, "key": "status.lastSeen", "value_type": 4, "history": "30d" }, { "name": "Location Latitude", "type": 0, "key": "location.latitude", "value_type": 0, "history": "30d", "units": "deg" }, { "name": "Location Longitude", "type": 0, "key": "location.longitude", "value_type": 0, "history": "30d", "units": "deg" } ] } ] } ``` This creates a template in Zabbix with all the required items that map to your GraphQL fields. #### 4. Link Hosts to the Template After importing the template, link your hosts to it in Zabbix or via the importHosts mutation: ```graphql mutation ImportHosts($hosts: [CreateHost!]!) { importHosts(hosts: $hosts) { deviceKey hostid message error { message code data } } } ``` Variables: ```json { "hosts": [ { "deviceKey": "DistanceTracker001", "name": "Distance Tracker 001", "deviceType": "distance-tracker", "groupNames": ["Roadwork/Devices"], "templateids": [12345] // Use the templateid returned from importTemplates } ] } ``` #### 5. Use in Queries Once the template and host are set up in Zabbix, query the data via GraphQL: ```graphql query GetDistanceTrackers { allDevices(tag_deviceType: ["distance-tracker"]) { ... on DistanceTrackerDevice { id name location { name location_lat location_lon } distance batteryLevel lastSeen } } } ``` #### 6. Expected Response Structure Based on the Zabbix configuration above, the API will return: ```json { "data": { "allDevices": [ { "id": "12345", "name": "Distance Tracker 001", "location": { "name": "Main Office", "location_lat": "37.7749", "location_lon": "-122.4194" }, "distance": 42.5, "batteryLevel": 87.2, "lastSeen": "2023-10-15T10:30:00Z" } ] } } ``` ## ๐Ÿค Contributing 1. Fork the repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request ## ๐Ÿ“„ License This project is licensed under the AGPL-3.0 License - see the [LICENSE](LICENSE) file for details. ## ๐Ÿ“š Schema and Documentation ### Schema Files as Documentation The schema files in the `schema/` directory serve as both API definition and documentation. Each type, field, and operation includes detailed comments explaining usage, parameters, and examples. For comprehensive understanding of the API, read the comments in: - `schema/queries.graphql` - Query operations with detailed parameter descriptions - `schema/mutations.graphql` - Mutation operations with input type documentation - `schema/api_commons.graphql` - Common types and permission system documentation - `schema/devices.graphql` - Device-related types and hierarchies - `schema/zabbix.graphql` - Zabbix-specific mappings and types ### Documentation Files The `docs/` directory contains sample GraphQL queries and mutations that demonstrate how to use the API: - `sample_all_*.graphql` - Sample queries for retrieving hosts, devices, templates, and groups - `sample_import_*.graphql` - Sample mutations for importing various Zabbix entities - `sample_delete_*.graphql` - Sample mutations for deleting templates and template groups - `sample_export_*.graphql` - Sample queries for exporting user rights and other data - `VCR - Technical product information.pdf` - Technical documentation for specific implementations Of particular interest: - `sample_import_distance_tracker_template.graphql` - Complete example of importing a template for distance tracker devices - `sample_import_user_rights_mutation.graphql` - Example of importing user permissions - `sample_import_permissions_template_groups_mutation.graphql` - Example of importing permission template groups ### Reading Comments for Detailed Documentation For detailed documentation with usage examples and implementation notes, read the comments in the schema and documentation files. The project creator has embedded extensive documentation as comments in the GraphQL schema files, which provide real-world usage examples and implementation guidance that complement this README. ## ๐Ÿ†˜ Support For support, please open an issue in the GitHub repository. ## ๐Ÿ”„ API Version Current API version: ${API_VERSION:-"Not set"}