refactor!: Restructure grapqhl-schema to better align with clean code and project structure principles
This commit is contained in:
parent
47640ff13e
commit
a89c3eeea7
21 changed files with 648 additions and 1847 deletions
12
codegen.ts
12
codegen.ts
|
|
@ -2,16 +2,16 @@ import type {CodegenConfig} from '@graphql-codegen/cli';
|
||||||
|
|
||||||
const config: CodegenConfig = {
|
const config: CodegenConfig = {
|
||||||
overwrite: true,
|
overwrite: true,
|
||||||
schema: './schema.graphql',
|
schema: 'src/schema/*.graphql',
|
||||||
generates: {
|
generates: {
|
||||||
"src/generated/graphql.ts": {
|
"src/schema/generated/graphql.ts": {
|
||||||
plugins: ["typescript", "typescript-resolvers"],
|
plugins: ["typescript", "typescript-resolvers"],
|
||||||
config: {
|
config: {
|
||||||
enumValues: {
|
enumValues: {
|
||||||
DeviceCommunicationType: "../model/model_enum_values.js#DeviceCommunicationType",
|
DeviceCommunicationType: "../../model/model_enum_values.js#DeviceCommunicationType",
|
||||||
StorageItemType: "../model/model_enum_values.js#StorageItemType",
|
StorageItemType: "../../model/model_enum_values.js#StorageItemType",
|
||||||
DeviceStatus: "../model/model_enum_values.js#DeviceStatus",
|
DeviceStatus: "../../model/model_enum_values.js#DeviceStatus",
|
||||||
Permission: "../model/model_enum_values.js#Permission",
|
Permission: "../../model/model_enum_values.js#Permission",
|
||||||
},
|
},
|
||||||
declarationKind: 'interface'
|
declarationKind: 'interface'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
624
schema.graphql
624
schema.graphql
|
|
@ -1,624 +0,0 @@
|
||||||
# Scalars resolved by package "graphql-scalars"
|
|
||||||
scalar DateTime
|
|
||||||
scalar Time
|
|
||||||
scalar JSONObject
|
|
||||||
|
|
||||||
# Schema definitions go here
|
|
||||||
type Query {
|
|
||||||
"Get api (build) version"
|
|
||||||
apiVersion: String!
|
|
||||||
"Get zabbix version"
|
|
||||||
zabbixVersion: String
|
|
||||||
"""
|
|
||||||
Login to zabbix - provided for debugging and testing purpose. The result of the login operation is
|
|
||||||
authentication token returned may be passed as
|
|
||||||
header 'zabbix-auth-token' for authenticating future API requests.
|
|
||||||
As an alternative to the cookie 'zbx_session' may be set which is automatically set after login to
|
|
||||||
the cockpit - this is the standard way to authenticate api calls initiated by the cockpit frontend
|
|
||||||
because the frontend is always embedded into the Zabbix portal which is only accessible after logging in and
|
|
||||||
obtainind the zbx_session - cookie.
|
|
||||||
"""
|
|
||||||
login(username: String!, password: String!): String
|
|
||||||
|
|
||||||
"""
|
|
||||||
Logout from zabbix - provided for debugging and testing purpose. This invalidates the token received by the login
|
|
||||||
operation. Returns true on success
|
|
||||||
"""
|
|
||||||
logout: Boolean
|
|
||||||
|
|
||||||
"""
|
|
||||||
Get all hosts + corresponding items. If with_items==true only hosts with attached items are delivered
|
|
||||||
name_pattern: If provided this will perform a LIKE "%…%" search on the name attribute within the database.
|
|
||||||
|
|
||||||
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
|
||||||
"""
|
|
||||||
allHosts(name_pattern: String = "", filter_host: String = null, hostids: Int,
|
|
||||||
groupids:[Int!] = null, with_items: Boolean = false, tag_deviceType:[String]=[], tag_hostType:[String!]): [Host]
|
|
||||||
|
|
||||||
"""
|
|
||||||
Get all host groups.
|
|
||||||
If with_hosts==true only groups with attached hosts are delivered.
|
|
||||||
|
|
||||||
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
|
||||||
"""
|
|
||||||
allHostGroups(search_name: String, with_hosts: Boolean = true): [HostGroup]
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Get all locations used by hosts.
|
|
||||||
distinct_by_name=true means that the result is filtered for distinct names (default)
|
|
||||||
name_pattern: If provided this will perform a Regex search on the name attribute within the database.
|
|
||||||
|
|
||||||
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
|
||||||
"""
|
|
||||||
locations(name_pattern: String = "", distinct_by_name: Boolean = true, templateids:[String] = null): [Location]
|
|
||||||
|
|
||||||
"""
|
|
||||||
Export history from Zabbix items
|
|
||||||
|
|
||||||
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
|
||||||
"""
|
|
||||||
exportHostValueHistory(
|
|
||||||
"(Optional) list of hostnames to be included in the result"
|
|
||||||
host_filter: [String!],
|
|
||||||
"(Optional) list of item keys to be included in the result"
|
|
||||||
itemKey_filter: [String!],
|
|
||||||
"""
|
|
||||||
(Optional) timestamp of earliest value"""
|
|
||||||
time_from: DateTime,
|
|
||||||
"""(Optional) timestamp of last value """
|
|
||||||
time_until: DateTime,
|
|
||||||
"""Results are sorted by timestamps - ascending or descending order may be specified
|
|
||||||
using this parameter"""
|
|
||||||
sortOrder: SortOrder=desc,
|
|
||||||
"""
|
|
||||||
Maximum number of records to be delivered. Hint: This might be useful, because the
|
|
||||||
current version of Zabbix delivers a 500 - error in case of requesting too much data
|
|
||||||
"""
|
|
||||||
limit: Int
|
|
||||||
"""
|
|
||||||
As values are stored in different data structures depending on their type
|
|
||||||
the type information must be specified in advance, although
|
|
||||||
each value (also if number) is converted into a string afterwards
|
|
||||||
"""
|
|
||||||
type: StorageItemType = FLOAT
|
|
||||||
|
|
||||||
):HistoryExportResponse
|
|
||||||
|
|
||||||
"""
|
|
||||||
Return all user permissions. If objectNames is provided return only the permissions related to the objects within
|
|
||||||
the objectNames - list
|
|
||||||
"""
|
|
||||||
userPermissions(objectNames: [String!]): [UserPermission!]
|
|
||||||
|
|
||||||
"""
|
|
||||||
Return true if and only if the current user (identified by token / cookie)
|
|
||||||
has all requested permissions (minimum - if READ is requested and the user has READ_WRITE
|
|
||||||
the response will be true)
|
|
||||||
"""
|
|
||||||
hasPermissions(permissions: [PermissionRequest!]!): Boolean
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
name_pattern: If provided this will perform a LIKE "%…%" search on the name attribute within the database.
|
|
||||||
exclude_groups_pattern: Regex allowing to exclude all matching hostgroups from group permissions
|
|
||||||
"""
|
|
||||||
exportUserRights(name_pattern: String = "" exclude_hostgroups_pattern: String = ""): UserRights
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserRights {
|
|
||||||
userGroups: [UserGroup!]
|
|
||||||
userRoles: [UserRole!]
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserRole {
|
|
||||||
roleid: Int!
|
|
||||||
name: String
|
|
||||||
type: Int
|
|
||||||
readonly: Int
|
|
||||||
rules: UserRoleRules
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserRoleRules {
|
|
||||||
ui: [UserRoleRule!]
|
|
||||||
ui_default_access: Int
|
|
||||||
modules:[UserRoleModule!]
|
|
||||||
modules_default_access: Int
|
|
||||||
api_access: Int
|
|
||||||
api_mode: Int
|
|
||||||
api: [String!]
|
|
||||||
actions: [UserRoleRule!]
|
|
||||||
actions_default_access: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserRoleRule {
|
|
||||||
name: String
|
|
||||||
status: Int
|
|
||||||
}
|
|
||||||
type UserRoleModule {
|
|
||||||
moduleid: String
|
|
||||||
status: Int
|
|
||||||
id: String
|
|
||||||
relative_path: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserGroup {
|
|
||||||
usrgrpid: Int!
|
|
||||||
name: String!
|
|
||||||
gui_access: Int
|
|
||||||
users_status: Int
|
|
||||||
hostgroup_rights: [ZabbixGroupRight!]
|
|
||||||
templategroup_rights: [ZabbixGroupRight!]
|
|
||||||
}
|
|
||||||
|
|
||||||
type ZabbixGroupRight {
|
|
||||||
id: Int!
|
|
||||||
uuid: String
|
|
||||||
name: String
|
|
||||||
permission: Permission
|
|
||||||
}
|
|
||||||
|
|
||||||
########################################################
|
|
||||||
# User permissions
|
|
||||||
########################################################
|
|
||||||
|
|
||||||
input PermissionRequest {
|
|
||||||
permission: Permission!,
|
|
||||||
"""
|
|
||||||
objectName maps to name / path suffix of the template group representing the permission in Zabbix:
|
|
||||||
Permissions/{objectName}
|
|
||||||
"""
|
|
||||||
objectName: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
READ, READ_WRITE or DENY:
|
|
||||||
describes the rights related to an objectName
|
|
||||||
There is no EXECUTE or anything else in Zabbix,
|
|
||||||
i.e. objectName - Tree has to be designed accordingly in order to represent the perform actions.
|
|
||||||
|
|
||||||
E.g.
|
|
||||||
|
|
||||||
Let's assume a button called "button1", used in application "app1", having a label which shows "do something". Instead of model the action "do something" the idea is
|
|
||||||
to model the effect of this action - do something will result in a status change. Let's further assume that the button will only
|
|
||||||
be displayed if the user is allowed to see the current status.
|
|
||||||
|
|
||||||
Permissions/app1/button1/status
|
|
||||||
|
|
||||||
The following PermissionRequests would be used by the frontend:
|
|
||||||
|
|
||||||
1. Should the button (and its status) be displayed at all?
|
|
||||||
button1.displayed = hasPermissions(
|
|
||||||
{
|
|
||||||
objectName: "app1/button1/status"
|
|
||||||
permission: READ
|
|
||||||
})
|
|
||||||
2. Should the user be able to press the button (enabled)?
|
|
||||||
button1.displayed = hasPermissions(
|
|
||||||
{
|
|
||||||
objectName: "app1/button1/status"
|
|
||||||
permission: READ_WRITE
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
Usage Example for this pattern: Activation/Deactivation of a control program - the button
|
|
||||||
shows the possible action. If the program is active it shows "Deactivate". If the program is inactive it shows "Activate".
|
|
||||||
From this label the user learns something about the current state - therefore the status - read - permission is needed in order
|
|
||||||
to display the button at all. The status write permission is needed in order to enable the button (i.e. allow the user to press it).
|
|
||||||
in order to model the permissions to press / see a button "button1" belonging to application "app1"
|
|
||||||
the following template group could be modelled in Zabbix
|
|
||||||
"""
|
|
||||||
enum Permission {
|
|
||||||
"""
|
|
||||||
DENY superseeds anything else - i.e. if in Zabbix there is a DENY and READ at the same time the result will be DENY
|
|
||||||
"""
|
|
||||||
DENY
|
|
||||||
"""
|
|
||||||
READ superseeds READ_WRITE - i.e. if in Zabbix there is a READ_WRITE and READ at the same time the resulting permission
|
|
||||||
level will be READ
|
|
||||||
"""
|
|
||||||
READ
|
|
||||||
"""
|
|
||||||
READ_WRITE implies the READ permission. Do not set both READ and READ_WRITE at the same time if you want to achieve
|
|
||||||
READ + WRITE permission, because in this case READ will superseed the READ_WRITE and the resulting permission level will be READ
|
|
||||||
"""
|
|
||||||
READ_WRITE
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserPermission {
|
|
||||||
permission: Permission!,
|
|
||||||
"""
|
|
||||||
objectName maps to name / path suffix of the template group representing the permission in Zabbix:
|
|
||||||
Permissions/{objectName}
|
|
||||||
"""
|
|
||||||
objectName: String!
|
|
||||||
}
|
|
||||||
########################################################
|
|
||||||
# Values
|
|
||||||
########################################################
|
|
||||||
|
|
||||||
enum StorageItemType {
|
|
||||||
FLOAT
|
|
||||||
INT
|
|
||||||
TEXT
|
|
||||||
}
|
|
||||||
|
|
||||||
type HistoryExportResponse {
|
|
||||||
result: [JSONObject!]
|
|
||||||
error: ApiError
|
|
||||||
}
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
type Mutation {
|
|
||||||
|
|
||||||
"""
|
|
||||||
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
|
||||||
"""
|
|
||||||
createHost(host: String!, hostgroupids:[Int!]!, templateids: [Int!]!,
|
|
||||||
location: LocationInput): ZabbixCreateResponse
|
|
||||||
|
|
||||||
"""
|
|
||||||
(Mass) Import zabbix groups
|
|
||||||
and assign them to the corresponding hosts by groupid or groupName.
|
|
||||||
|
|
||||||
Return value: If no error occurs a groupid be returned for each created group,
|
|
||||||
otherwise the return object will contain an error message
|
|
||||||
|
|
||||||
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
|
||||||
"""
|
|
||||||
importHostGroups(hostGroups: [CreateHostGroup!]!):[CreateHostGroupResponse!]
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
(Mass) Import hosts and assign them to host groups by groupid or groupName.
|
|
||||||
|
|
||||||
Return value: If no error occurs a hostid will be returned for each created host,
|
|
||||||
otherwise the return object will contain an error message.
|
|
||||||
|
|
||||||
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
|
||||||
"""
|
|
||||||
importHosts(hosts: [CreateHost!]!):[CreateHostResponse!]
|
|
||||||
|
|
||||||
importUserRights(input: UserRightsInput!, dryRun: Boolean! = true): ImportUserRightsResult
|
|
||||||
}
|
|
||||||
|
|
||||||
input UserRightsInput {
|
|
||||||
userRoles: [UserRoleInput!]
|
|
||||||
userGroups: [UserGroupInput!]
|
|
||||||
}
|
|
||||||
|
|
||||||
input UserRoleInput {
|
|
||||||
name: String
|
|
||||||
type: Int
|
|
||||||
readonly: Int
|
|
||||||
rules: UserRoleRulesInput
|
|
||||||
}
|
|
||||||
|
|
||||||
input UserRoleRulesInput {
|
|
||||||
ui: [UserRoleRuleInput!]
|
|
||||||
ui_default_access: Int
|
|
||||||
modules:[UserRoleModuleInput!]
|
|
||||||
modules_default_access: Int
|
|
||||||
api_access: Int
|
|
||||||
api_mode: Int
|
|
||||||
api: [String!]
|
|
||||||
actions: [UserRoleRuleInput!]
|
|
||||||
actions_default_access: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
input UserRoleRuleInput {
|
|
||||||
name: String
|
|
||||||
status: Int
|
|
||||||
}
|
|
||||||
input UserRoleModuleInput {
|
|
||||||
moduleid: String
|
|
||||||
status: Int
|
|
||||||
id: String
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
input UserGroupInput {
|
|
||||||
name: String!
|
|
||||||
gui_access: Int
|
|
||||||
users_status: Int
|
|
||||||
hostgroup_rights: [ZabbixGroupRightInput!]
|
|
||||||
templategroup_rights: [ZabbixGroupRightInput!]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
input ZabbixGroupRightInput {
|
|
||||||
uuid: String
|
|
||||||
"""
|
|
||||||
name may optionally be specified for documentation purpose,
|
|
||||||
but the master for setting the user right is the uuid.
|
|
||||||
If a uuid is found and the corresponding group
|
|
||||||
has a deviating name this will be documented within a message
|
|
||||||
with errorcode = 0 (OK) but the permission will be set (
|
|
||||||
the reason is that names for groups may deviate between several
|
|
||||||
instances of the control center although the semantic is the same -
|
|
||||||
while the semantic is identified by uuid.
|
|
||||||
"""
|
|
||||||
name: String
|
|
||||||
permission: Permission
|
|
||||||
}
|
|
||||||
|
|
||||||
type ImportUserRightsResult {
|
|
||||||
userRoles: [ImportUserRightResult!]
|
|
||||||
userGroups: [ImportUserRightResult!]
|
|
||||||
}
|
|
||||||
type ImportUserRightResult {
|
|
||||||
id: String
|
|
||||||
name: String
|
|
||||||
message: String
|
|
||||||
errors: [ApiError!]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Hint: WGS84[dd.ddddd] coordinates are used
|
|
||||||
"""
|
|
||||||
interface GpsPosition {
|
|
||||||
latitude: Float
|
|
||||||
longitude: Float
|
|
||||||
}
|
|
||||||
#########################################
|
|
||||||
|
|
||||||
type HostGroup {
|
|
||||||
groupid: ID!
|
|
||||||
name: String
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Host {
|
|
||||||
hostid: ID!
|
|
||||||
"""
|
|
||||||
The host field contains the "hostname" in Zabbix
|
|
||||||
"""
|
|
||||||
host: String!
|
|
||||||
deviceType: String
|
|
||||||
hostgroups: [HostGroup!]
|
|
||||||
name: String
|
|
||||||
tags: JSONObject
|
|
||||||
}
|
|
||||||
|
|
||||||
type ZabbixItem {
|
|
||||||
itemid: Int!
|
|
||||||
name: String!
|
|
||||||
key_: String!
|
|
||||||
hostid: Int
|
|
||||||
lastclock: Int
|
|
||||||
lastvalue: String
|
|
||||||
value_type: Int!
|
|
||||||
attributeName: String
|
|
||||||
deviceType: String
|
|
||||||
topicType:String
|
|
||||||
status: DeviceStatus
|
|
||||||
type: DeviceCommunicationType
|
|
||||||
hosts: [Host]
|
|
||||||
}
|
|
||||||
|
|
||||||
type ZabbixHost implements Host {
|
|
||||||
hostid: ID!
|
|
||||||
host: String!
|
|
||||||
deviceType: String
|
|
||||||
hostgroups: [HostGroup!]
|
|
||||||
name: String
|
|
||||||
tags: JSONObject
|
|
||||||
|
|
||||||
|
|
||||||
items: [ZabbixItem!]
|
|
||||||
inventory: Inventory
|
|
||||||
parentTemplates: [Template!]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
(IoT / Edge - ) Devices are hosts having a state containing the "output" / the business data which is exposed
|
|
||||||
besides monitoring information.
|
|
||||||
"""
|
|
||||||
interface Device implements Host {
|
|
||||||
hostid: ID!
|
|
||||||
"""
|
|
||||||
Per convention a uuid is used as hostname to identify devices if they do not have a unique hostname
|
|
||||||
"""
|
|
||||||
host: String!
|
|
||||||
deviceType: String
|
|
||||||
hostgroups: [HostGroup!]
|
|
||||||
name: String
|
|
||||||
tags: JSONObject
|
|
||||||
state: DeviceState
|
|
||||||
}
|
|
||||||
type OperationalDeviceData {
|
|
||||||
temperature: Float
|
|
||||||
voltage: Float
|
|
||||||
signalstrength: Float
|
|
||||||
location: Location
|
|
||||||
timestamp: DateTime
|
|
||||||
error: [ErrorPayload!]
|
|
||||||
}
|
|
||||||
interface DeviceState {
|
|
||||||
operational: OperationalDeviceData
|
|
||||||
}
|
|
||||||
|
|
||||||
# Generic IoT devices with "generic" current state - mapping all "values"
|
|
||||||
type GenericDeviceState implements DeviceState {
|
|
||||||
operational: OperationalDeviceData
|
|
||||||
current: JSONObject
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Device represents generic IoT / Edge - devices providing their state as generic "state.current" - JSON Object
|
|
||||||
"""
|
|
||||||
type GenericDevice implements Host & Device {
|
|
||||||
hostid: ID!
|
|
||||||
"""
|
|
||||||
Per convention a uuid is used as hostname to identify devices if they do not have a unique hostname
|
|
||||||
"""
|
|
||||||
host: String!
|
|
||||||
deviceType: String
|
|
||||||
hostgroups: [HostGroup!]
|
|
||||||
name: String
|
|
||||||
tags: JSONObject
|
|
||||||
state: GenericDeviceState
|
|
||||||
}
|
|
||||||
|
|
||||||
type ErrorPayload {
|
|
||||||
code: Int!
|
|
||||||
message: String
|
|
||||||
additionalInfo: JSONObject
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SensorValueType {
|
|
||||||
NUMERIC # 0 - numeric float;
|
|
||||||
CHARACTER # 1 - character;
|
|
||||||
LOG # 2 - log;
|
|
||||||
NUMERIC_UNSIGNED # 3 - numeric unsigned;
|
|
||||||
TEXT # 4 - text;
|
|
||||||
}
|
|
||||||
|
|
||||||
type ZabbixCreateResponse {
|
|
||||||
hostids: [Int]
|
|
||||||
itemids: [Int]
|
|
||||||
error: ApiError
|
|
||||||
}
|
|
||||||
|
|
||||||
input LocationInput {
|
|
||||||
name: String
|
|
||||||
location_lat: String
|
|
||||||
location_lon: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Template {
|
|
||||||
templateid: String!
|
|
||||||
name: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Inventory {
|
|
||||||
location: Location
|
|
||||||
}
|
|
||||||
|
|
||||||
type Location implements GpsPosition {
|
|
||||||
name: String
|
|
||||||
latitude: Float
|
|
||||||
longitude: Float
|
|
||||||
}
|
|
||||||
|
|
||||||
enum DeviceStatus {
|
|
||||||
ENABLED
|
|
||||||
DISABLED
|
|
||||||
}
|
|
||||||
|
|
||||||
enum DeviceCommunicationType {
|
|
||||||
ZABBIX_AGENT
|
|
||||||
ZABBIX_AGENT_ACTIVE
|
|
||||||
ZABBIX_TRAP
|
|
||||||
ZABBIX_INTERNAL_ITEM
|
|
||||||
SIMPLE_CHECK
|
|
||||||
DEPENDANT_ITEM
|
|
||||||
SIMULATOR_CALCULATED
|
|
||||||
SIMULATOR_JAVASCRIPT
|
|
||||||
HTTP_AGENT
|
|
||||||
IPMI_AGENT
|
|
||||||
JMX_AGENT
|
|
||||||
SNMP_AGENT
|
|
||||||
SNMP_TRAP
|
|
||||||
DATABASE_MONITOR
|
|
||||||
}
|
|
||||||
|
|
||||||
type Item {
|
|
||||||
itemid: Int
|
|
||||||
hostid: Int
|
|
||||||
name: String!
|
|
||||||
key_: String
|
|
||||||
attributeName: String
|
|
||||||
deviceType: String
|
|
||||||
topicType:String
|
|
||||||
status: DeviceStatus
|
|
||||||
type: DeviceCommunicationType
|
|
||||||
hosts: [Host]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
####################################################################
|
|
||||||
# Input types used for importXXX - and storeXXX - Mutations
|
|
||||||
####################################################################
|
|
||||||
|
|
||||||
input CreateHostGroup {
|
|
||||||
"""
|
|
||||||
Name of the host group
|
|
||||||
"""
|
|
||||||
groupName: String!
|
|
||||||
"""
|
|
||||||
Internally used unique id
|
|
||||||
(will be assigned by Zabbix if empty)
|
|
||||||
"""
|
|
||||||
uuid: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateHostGroupResponse {
|
|
||||||
groupName: String!
|
|
||||||
groupid: Int
|
|
||||||
message: String
|
|
||||||
error: ApiError
|
|
||||||
}
|
|
||||||
|
|
||||||
type HostTypeMeta {
|
|
||||||
deviceType: String
|
|
||||||
deviceTypeDescription: String
|
|
||||||
}
|
|
||||||
|
|
||||||
input CreateHost {
|
|
||||||
deviceKey: String!
|
|
||||||
"""
|
|
||||||
Optional display name of the device (must be unique if provided - default is to set display name to deviceKey)
|
|
||||||
"""
|
|
||||||
name: String
|
|
||||||
deviceType: String!
|
|
||||||
"""
|
|
||||||
groupNames is used to assign the created object
|
|
||||||
to a host group. It is mandatory but
|
|
||||||
can also be blank. This is usefull in case of
|
|
||||||
passing a groupid instead which is
|
|
||||||
the zabbix internal key for storing the group.
|
|
||||||
If a groupid is provided the passed groupName is ignored
|
|
||||||
"""
|
|
||||||
groupNames: [String!]!
|
|
||||||
"""
|
|
||||||
Optionally the internal groupids can be passed - in this case the
|
|
||||||
groupName is ignored
|
|
||||||
"""
|
|
||||||
groupids: [Int]
|
|
||||||
location: LocationInput
|
|
||||||
}
|
|
||||||
type CreateHostResponse {
|
|
||||||
deviceKey: String!
|
|
||||||
hostid: String
|
|
||||||
message: String
|
|
||||||
error: ApiError
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Error {
|
|
||||||
code: Int
|
|
||||||
message: String
|
|
||||||
data: JSONObject
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApiError implements Error {
|
|
||||||
code: Int
|
|
||||||
message: String
|
|
||||||
data: JSONObject
|
|
||||||
path: String
|
|
||||||
args: JSONObject
|
|
||||||
}
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
# General purpose types + enums
|
|
||||||
############################################################################
|
|
||||||
enum SortOrder {
|
|
||||||
"Deliver values in ascending order"
|
|
||||||
asc
|
|
||||||
"Deliver values in descending order"
|
|
||||||
desc
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import {isObjectType} from "graphql";
|
import {isObjectType} from "graphql";
|
||||||
import {logger} from "../logging/logger.js";
|
import {logger} from "../logging/logger.js";
|
||||||
|
import {Device, Host} from "../schema/generated/graphql";
|
||||||
|
|
||||||
|
export const isDevice = (value: Host): value is Device => !!(value as Device).deviceType;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
As a default all . - seperators within a key shall be replaced by a Capital letter of the following word
|
As a default all . - seperators within a key shall be replaced by a Capital letter of the following word
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ import {
|
||||||
QueryHasPermissionsArgs,
|
QueryHasPermissionsArgs,
|
||||||
QueryUserPermissionsArgs,
|
QueryUserPermissionsArgs,
|
||||||
Resolvers,
|
Resolvers,
|
||||||
StorageItemType, Host, QueryExportHostValueHistoryArgs,
|
StorageItemType, Host, QueryExportHostValueHistoryArgs, Device,
|
||||||
} from "../generated/graphql.js";
|
} from "../schema/generated/graphql.js";
|
||||||
|
|
||||||
import {HostImporter} from "../execution/host_importer";
|
import {HostImporter} from "../execution/host_importer";
|
||||||
import {HostValueExporter} from "../execution/host_exporter";
|
import {HostValueExporter} from "../execution/host_exporter";
|
||||||
|
|
@ -34,6 +34,7 @@ import {
|
||||||
} from "../datasources/zabbix-userroles.js";
|
} from "../datasources/zabbix-userroles.js";
|
||||||
import {ZABBIX_EDGE_DEVICE_BASE_GROUP, zabbixAPI} from "../datasources/zabbix-api";
|
import {ZABBIX_EDGE_DEVICE_BASE_GROUP, zabbixAPI} from "../datasources/zabbix-api";
|
||||||
import {GraphQLInterfaceType, GraphQLList} from "graphql/type";
|
import {GraphQLInterfaceType, GraphQLList} from "graphql/type";
|
||||||
|
import {isDevice} from "./resolver_helpers";
|
||||||
|
|
||||||
|
|
||||||
export function createResolvers(): Resolvers {
|
export function createResolvers(): Resolvers {
|
||||||
|
|
@ -160,9 +161,12 @@ export function createResolvers(): Resolvers {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
__resolveType: function (host: Host, _context, info ): string {
|
__resolveType: function (host: Host, _context, info ): string {
|
||||||
|
|
||||||
const deviceType = host.deviceType ?? "";
|
if (!isDevice(host)) {
|
||||||
|
logger.info(`checking host ${host.name} for deviceType - no device type found, returning as ZabbixHost`);
|
||||||
|
|
||||||
if (deviceType) {
|
return "ZabbixHost";
|
||||||
|
}
|
||||||
|
const deviceType = host.deviceType!;
|
||||||
logger.info(`checking host ${host.name} for deviceType - found ${deviceType}`);
|
logger.info(`checking host ${host.name} for deviceType - found ${deviceType}`);
|
||||||
let interfaceType: GraphQLInterfaceType = (info.returnType instanceof GraphQLList ?
|
let interfaceType: GraphQLInterfaceType = (info.returnType instanceof GraphQLList ?
|
||||||
info.returnType.ofType : info.returnType) as GraphQLInterfaceType
|
info.returnType.ofType : info.returnType) as GraphQLInterfaceType
|
||||||
|
|
@ -171,12 +175,6 @@ export function createResolvers(): Resolvers {
|
||||||
}
|
}
|
||||||
return "GenericDevice"
|
return "GenericDevice"
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`checking host ${host.name} for deviceType - no device type found, returning as ZabbixHost`);
|
|
||||||
return "ZabbixHost"; // Return "generic" device host as a default if no templates are assigned
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
Inventory: {
|
Inventory: {
|
||||||
|
|
@ -239,13 +237,6 @@ export function createResolvers(): Resolvers {
|
||||||
DISABLED: DeviceStatus.DISABLED
|
DISABLED: DeviceStatus.DISABLED
|
||||||
},
|
},
|
||||||
|
|
||||||
SensorValueType: {
|
|
||||||
NUMERIC: 0,
|
|
||||||
CHARACTER: 1,
|
|
||||||
LOG: 2,
|
|
||||||
NUMERIC_UNSIGNED: 3,
|
|
||||||
TEXT: 4
|
|
||||||
},
|
|
||||||
StorageItemType: {
|
StorageItemType: {
|
||||||
TEXT: StorageItemType.Text,
|
TEXT: StorageItemType.Text,
|
||||||
FLOAT: StorageItemType.Float,
|
FLOAT: StorageItemType.Float,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {ZabbixAPI} from "./zabbix-api.js";
|
import {ZabbixAPI} from "./zabbix-api.js";
|
||||||
import {ApiError, SortOrder, StorageItemType} from "../generated/graphql.js";
|
import {ApiError, SortOrder, StorageItemType} from "../schema/generated/graphql.js";
|
||||||
import {ZabbixCreateOrUpdateStorageItemRequest} from "./zabbix-items.js";
|
import {ZabbixCreateOrUpdateStorageItemRequest} from "./zabbix-items.js";
|
||||||
import {ZabbixForceCacheReloadRequest} from "./zabbix-script.js";
|
import {ZabbixForceCacheReloadRequest} from "./zabbix-script.js";
|
||||||
import {logger} from "../logging/logger.js";
|
import {logger} from "../logging/logger.js";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {isZabbixErrorResult, ParsedArgs, ZabbixParams, ZabbixRequest} from "./zabbix-request.js";
|
import {isZabbixErrorResult, ParsedArgs, ZabbixParams, ZabbixRequest} from "./zabbix-request.js";
|
||||||
import {Permission} from "../generated/graphql.js";
|
import {Permission} from "../schema/generated/graphql.js";
|
||||||
import {
|
import {
|
||||||
FIND_ZABBIX_EDGE_DEVICE_BASE_GROUP_PREFIX,
|
FIND_ZABBIX_EDGE_DEVICE_BASE_GROUP_PREFIX,
|
||||||
ZABBIX_EDGE_DEVICE_BASE_GROUP,
|
ZABBIX_EDGE_DEVICE_BASE_GROUP,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {Host, ZabbixHost} from "../generated/graphql.js";
|
import {CreateHostResponse, Host, ZabbixHost} from "../schema/generated/graphql.js";
|
||||||
import {ZabbixAPI} from "./zabbix-api.js";
|
import {ZabbixAPI} from "./zabbix-api.js";
|
||||||
import {
|
import {
|
||||||
isZabbixErrorResult,
|
isZabbixErrorResult,
|
||||||
|
|
@ -8,8 +8,7 @@ import {
|
||||||
ZabbixRequest,
|
ZabbixRequest,
|
||||||
ZabbixResult
|
ZabbixResult
|
||||||
} from "./zabbix-request.js";
|
} from "./zabbix-request.js";
|
||||||
import {QueryZabbixItemResponse} from "./zabbix-items.js";
|
import {ZabbixHistoryGetParams, ZabbixQueryHistoryRequest} from "./zabbix-history.js";
|
||||||
import {ZabbixExportValue, ZabbixHistoryGetParams, ZabbixQueryHistoryRequest} from "./zabbix-history.js";
|
|
||||||
|
|
||||||
|
|
||||||
export class ZabbixQueryHostsGenericRequest<T extends ZabbixResult> extends ZabbixRequest<T> {
|
export class ZabbixQueryHostsGenericRequest<T extends ZabbixResult> extends ZabbixRequest<T> {
|
||||||
|
|
@ -244,9 +243,7 @@ class ZabbixCreateHostParams implements ZabbixParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class ZabbixCreateHostRequest extends ZabbixRequest<{
|
export class ZabbixCreateHostRequest extends ZabbixRequest<CreateHostResponse> {
|
||||||
hostids: number[]
|
|
||||||
}> {
|
|
||||||
constructor(authToken?: string | null, cookie?: string) {
|
constructor(authToken?: string | null, cookie?: string) {
|
||||||
super("host.create", authToken, cookie);
|
super("host.create", authToken, cookie);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import {ParsedArgs, ZabbixParams, ZabbixRequest, ZabbixResult, ZabbixValueType} from "./zabbix-request.js";
|
import {ParsedArgs, ZabbixParams, ZabbixRequest, ZabbixResult, ZabbixValueType} from "./zabbix-request.js";
|
||||||
|
import {ZabbixItem} from "../schema/generated/graphql";
|
||||||
|
|
||||||
export class ZabbixQueryItemsMetaRequest extends ZabbixRequest<any> {
|
export class ZabbixQueryItemsMetaRequest extends ZabbixRequest<any> {
|
||||||
createZabbixParams(args?: ParsedArgs) {
|
createZabbixParams(args?: ParsedArgs) {
|
||||||
|
|
@ -13,27 +14,8 @@ export class ZabbixQueryItemsMetaRequest extends ZabbixRequest<any> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type QueryZabbixItemResponse = {
|
|
||||||
value_type: string;
|
|
||||||
itemid: string,
|
|
||||||
name: string,
|
|
||||||
status?: string,
|
|
||||||
key_?: string,
|
|
||||||
lastvalue: string | null
|
|
||||||
lastclock: string | null
|
|
||||||
tags?: {
|
|
||||||
tag: string,
|
|
||||||
value: string
|
|
||||||
}[]
|
|
||||||
hosts?: {
|
|
||||||
hostid: number,
|
|
||||||
host: string,
|
|
||||||
templateid?: number,
|
|
||||||
name: string
|
|
||||||
}[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ZabbixQueryItemsRequest extends ZabbixRequest<QueryZabbixItemResponse[]> {
|
export class ZabbixQueryItemsRequest extends ZabbixRequest<ZabbixItem[]> {
|
||||||
constructor(authToken?: string | null, cookie?: string) {
|
constructor(authToken?: string | null, cookie?: string) {
|
||||||
super("item.get", authToken, cookie);
|
super("item.get", authToken, cookie);
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +48,7 @@ export class ZabbixQueryItemsRequest extends ZabbixRequest<QueryZabbixItemRespon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class ZabbixQueryItemsByIdRequest extends ZabbixRequest<QueryZabbixItemResponse[]> {
|
export class ZabbixQueryItemsByIdRequest extends ZabbixRequest<ZabbixItem[]> {
|
||||||
constructor(authToken?: string | null, cookie?: string) {
|
constructor(authToken?: string | null, cookie?: string) {
|
||||||
super("item.get.itembyid", authToken, cookie);
|
super("item.get.itembyid", authToken, cookie);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {ParsedArgs, ZabbixParams, ZabbixRequest} from "./zabbix-request.js";
|
import {ParsedArgs, ZabbixParams, ZabbixRequest} from "./zabbix-request.js";
|
||||||
import {UserRoleModule} from "../generated/graphql.js";
|
import {UserRoleModule} from "../schema/generated/graphql.js";
|
||||||
|
|
||||||
export class ZabbixQueryModulesRequest extends ZabbixRequest<UserRoleModule[]> {
|
export class ZabbixQueryModulesRequest extends ZabbixRequest<UserRoleModule[]> {
|
||||||
constructor(authToken?: string | null, cookie?: string | null) {
|
constructor(authToken?: string | null, cookie?: string | null) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {ApiError, InputMaybe, QueryHasPermissionsArgs, UserPermission} from "../generated/graphql.js";
|
import {ApiError, InputMaybe, QueryHasPermissionsArgs, UserPermission} from "../schema/generated/graphql.js";
|
||||||
import {ZabbixAPI} from "./zabbix-api.js";
|
import {ZabbixAPI} from "./zabbix-api.js";
|
||||||
import {ApiErrorCode, Permission, PermissionNumber} from "../model/model_enum_values.js";
|
import {ApiErrorCode, Permission, PermissionNumber} from "../model/model_enum_values.js";
|
||||||
import {logger} from "../logging/logger.js";
|
import {logger} from "../logging/logger.js";
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import {
|
||||||
UserGroupInput,
|
UserGroupInput,
|
||||||
ZabbixGroupRight,
|
ZabbixGroupRight,
|
||||||
ZabbixGroupRightInput
|
ZabbixGroupRightInput
|
||||||
} from "../generated/graphql.js";
|
} from "../schema/generated/graphql.js";
|
||||||
import {ZabbixAPI} from "./zabbix-api.js";
|
import {ZabbixAPI} from "./zabbix-api.js";
|
||||||
import {ZabbixQueryTemplateGroupRequest, ZabbixQueryTemplateGroupResponse} from "./zabbix-templates.js";
|
import {ZabbixQueryTemplateGroupRequest, ZabbixQueryTemplateGroupResponse} from "./zabbix-templates.js";
|
||||||
import {ZabbixQueryHostgroupsRequest, ZabbixQueryHostgroupsResult} from "./zabbix-hostgroups.js";
|
import {ZabbixQueryHostgroupsRequest, ZabbixQueryHostgroupsResult} from "./zabbix-hostgroups.js";
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import {
|
||||||
ZabbixRequest,
|
ZabbixRequest,
|
||||||
ZabbixResult
|
ZabbixResult
|
||||||
} from "./zabbix-request.js";
|
} from "./zabbix-request.js";
|
||||||
import {ApiError, ImportUserRightResult, UserRole, UserRoleInput, UserRoleModule} from "../generated/graphql.js";
|
import {ApiError, ImportUserRightResult, UserRole, UserRoleInput, UserRoleModule} from "../schema/generated/graphql.js";
|
||||||
import {ZabbixAPI} from "./zabbix-api.js";
|
import {ZabbixAPI} from "./zabbix-api.js";
|
||||||
import {ZabbixQueryModulesRequest} from "./zabbix-module.js";
|
import {ZabbixQueryModulesRequest} from "./zabbix-module.js";
|
||||||
import {ApiErrorCode} from "../model/model_enum_values.js";
|
import {ApiErrorCode} from "../model/model_enum_values.js";
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import {
|
import {
|
||||||
ApiError,
|
ApiError,
|
||||||
HistoryExportResponse, QueryExportHostValueHistoryArgs,
|
GenericResponse, QueryExportHostValueHistoryArgs,
|
||||||
StorageItemType
|
StorageItemType, ZabbixItem
|
||||||
} from "../generated/graphql.js";
|
} from "../schema/generated/graphql.js";
|
||||||
import {ApiErrorCode, ApiErrorMessage} from "../model/model_enum_values.js";
|
import {ApiErrorCode, ApiErrorMessage} from "../model/model_enum_values.js";
|
||||||
|
|
||||||
import {QueryZabbixItemResponse, ZabbixQueryItemsRequest} from "../datasources/zabbix-items.js";
|
import {ZabbixQueryItemsRequest} from "../datasources/zabbix-items.js";
|
||||||
import {isZabbixErrorResult, ParsedArgs, ZabbixErrorResult} from "../datasources/zabbix-request.js";
|
import {isZabbixErrorResult, ParsedArgs, ZabbixErrorResult} from "../datasources/zabbix-request.js";
|
||||||
import {ZabbixHistoryGetParams, ZabbixQueryHistoryRequest} from "../datasources/zabbix-history.js";
|
import {ZabbixHistoryGetParams, ZabbixQueryHistoryRequest} from "../datasources/zabbix-history.js";
|
||||||
import {zabbixAPI} from "../datasources/zabbix-api";
|
import {zabbixAPI} from "../datasources/zabbix-api";
|
||||||
|
|
@ -20,7 +20,7 @@ type ItemMapResponse = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HostValueExporter {
|
export class HostValueExporter {
|
||||||
static async exportHistory(args: QueryExportHostValueHistoryArgs, zabbixAuthToken?: string, cookie?: string): Promise<HistoryExportResponse> {
|
static async exportHistory(args: QueryExportHostValueHistoryArgs, zabbixAuthToken?: string, cookie?: string): Promise<GenericResponse> {
|
||||||
let itemMapResponse: ItemMapResponse = await HostValueExporter.queryItemsForFilterArgs(args, zabbixAuthToken, cookie);
|
let itemMapResponse: ItemMapResponse = await HostValueExporter.queryItemsForFilterArgs(args, zabbixAuthToken, cookie);
|
||||||
if (itemMapResponse.error || !itemMapResponse.items) {
|
if (itemMapResponse.error || !itemMapResponse.items) {
|
||||||
return {
|
return {
|
||||||
|
|
@ -77,7 +77,7 @@ export class HostValueExporter {
|
||||||
let hostFilter = args.host_filter
|
let hostFilter = args.host_filter
|
||||||
let itemKeyFilter = args.itemKey_filter
|
let itemKeyFilter = args.itemKey_filter
|
||||||
|
|
||||||
let items: QueryZabbixItemResponse[] | ZabbixErrorResult = await new ZabbixQueryItemsRequest(zabbixAuthToken, cookie)
|
let items: ZabbixItem[] | ZabbixErrorResult = await new ZabbixQueryItemsRequest(zabbixAuthToken, cookie)
|
||||||
.executeRequestReturnError(zabbixAPI, new ParsedArgs(
|
.executeRequestReturnError(zabbixAPI, new ParsedArgs(
|
||||||
{
|
{
|
||||||
filter: {
|
filter: {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import {
|
import {
|
||||||
CreateHost,
|
CreateHost,
|
||||||
CreateHostResponse,
|
CreateHostGroup,
|
||||||
CreateHostGroupResponse,
|
CreateHostGroupResponse,
|
||||||
InputMaybe,CreateHostGroup
|
ImportHostResponse,
|
||||||
} from "../generated/graphql.js";
|
InputMaybe
|
||||||
|
} from "../schema/generated/graphql.js";
|
||||||
import {logger} from "../logging/logger.js";
|
import {logger} from "../logging/logger.js";
|
||||||
import {ZabbixQueryTemplatesRequest} from "../datasources/zabbix-templates.js";
|
import {ZabbixQueryTemplatesRequest} from "../datasources/zabbix-templates.js";
|
||||||
import {isZabbixErrorResult, ParsedArgs, ZabbixErrorResult} from "../datasources/zabbix-request.js";
|
import {isZabbixErrorResult, ParsedArgs, ZabbixErrorResult} from "../datasources/zabbix-request.js";
|
||||||
|
|
@ -89,7 +90,7 @@ export class HostImporter {
|
||||||
if (!hosts) {
|
if (!hosts) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
let result: CreateHostResponse[] = []
|
let result: ImportHostResponse[] = []
|
||||||
for (let device of hosts) {
|
for (let device of hosts) {
|
||||||
let groupids = device.groupids
|
let groupids = device.groupids
|
||||||
if (!groupids) {
|
if (!groupids) {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
110
src/schema/api_commons.graphql
Normal file
110
src/schema/api_commons.graphql
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
########################################################
|
||||||
|
# Request/response
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
type GenericResponse {
|
||||||
|
result: [JSONObject!]
|
||||||
|
error: ApiError
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiError implements Error {
|
||||||
|
code: Int
|
||||||
|
message: String
|
||||||
|
data: JSONObject
|
||||||
|
path: String
|
||||||
|
args: JSONObject
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Error {
|
||||||
|
code: Int
|
||||||
|
message: String
|
||||||
|
data: JSONObject
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
# User permissions
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
input PermissionRequest {
|
||||||
|
permission: Permission!,
|
||||||
|
"""
|
||||||
|
objectName maps to name / path suffix of the template group representing the permission in Zabbix:
|
||||||
|
Permissions/{objectName}
|
||||||
|
"""
|
||||||
|
objectName: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
READ, READ_WRITE or DENY:
|
||||||
|
describes the rights related to an objectName
|
||||||
|
There is no EXECUTE or anything else in Zabbix,
|
||||||
|
i.e. objectName - Tree has to be designed accordingly in order to represent the perform actions.
|
||||||
|
|
||||||
|
E.g.
|
||||||
|
|
||||||
|
Let's assume a button called "button1", used in application "app1", having a label which shows "do something". Instead of model the action "do something" the idea is
|
||||||
|
to model the effect of this action - do something will result in a status change. Let's further assume that the button will only
|
||||||
|
be displayed if the user is allowed to see the current status.
|
||||||
|
|
||||||
|
Permissions/app1/button1/status
|
||||||
|
|
||||||
|
The following PermissionRequests would be used by the frontend:
|
||||||
|
|
||||||
|
1. Should the button (and its status) be displayed at all?
|
||||||
|
button1.displayed = hasPermissions(
|
||||||
|
{
|
||||||
|
objectName: "app1/button1/status"
|
||||||
|
permission: READ
|
||||||
|
})
|
||||||
|
2. Should the user be able to press the button (enabled)?
|
||||||
|
button1.displayed = hasPermissions(
|
||||||
|
{
|
||||||
|
objectName: "app1/button1/status"
|
||||||
|
permission: READ_WRITE
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
Usage Example for this pattern: Activation/Deactivation of a control program - the button
|
||||||
|
shows the possible action. If the program is active it shows "Deactivate". If the program is inactive it shows "Activate".
|
||||||
|
From this label the user learns something about the current state - therefore the status - read - permission is needed in order
|
||||||
|
to display the button at all. The status write permission is needed in order to enable the button (i.e. allow the user to press it).
|
||||||
|
in order to model the permissions to press / see a button "button1" belonging to application "app1"
|
||||||
|
the following template group could be modelled in Zabbix
|
||||||
|
"""
|
||||||
|
enum Permission {
|
||||||
|
"""
|
||||||
|
DENY superseeds anything else - i.e. if in Zabbix there is a DENY and READ at the same time the result will be DENY
|
||||||
|
"""
|
||||||
|
DENY
|
||||||
|
"""
|
||||||
|
READ superseeds READ_WRITE - i.e. if in Zabbix there is a READ_WRITE and READ at the same time the resulting permission
|
||||||
|
level will be READ
|
||||||
|
"""
|
||||||
|
READ
|
||||||
|
"""
|
||||||
|
READ_WRITE implies the READ permission. Do not set both READ and READ_WRITE at the same time if you want to achieve
|
||||||
|
READ + WRITE permission, because in this case READ will superseed the READ_WRITE and the resulting permission level will be READ
|
||||||
|
"""
|
||||||
|
READ_WRITE
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserPermission {
|
||||||
|
permission: Permission!,
|
||||||
|
"""
|
||||||
|
objectName maps to name / path suffix of the template group representing the permission in Zabbix:
|
||||||
|
Permissions/{objectName}
|
||||||
|
"""
|
||||||
|
objectName: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# General purpose types + enums
|
||||||
|
############################################################################
|
||||||
|
enum SortOrder {
|
||||||
|
"Deliver values in ascending order"
|
||||||
|
asc
|
||||||
|
"Deliver values in descending order"
|
||||||
|
desc
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"""
|
"""
|
||||||
Represents a message containing information about a specific device and its associated data value.
|
Represents a message containing information about a specific device and its associated data value.
|
||||||
The class is designed to be extended by other classes that define more structured or specialized types
|
The interface is designed to be extended by other types that define more structured or specialized types
|
||||||
of device value messages.
|
of device value messages.
|
||||||
"""
|
"""
|
||||||
interface DeviceValueMessage {
|
interface DeviceValueMessage {
|
||||||
58
src/schema/devices.graphql
Normal file
58
src/schema/devices.graphql
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
|
||||||
|
"""
|
||||||
|
(IoT / Edge - ) Devices are hosts having a state containing the "output" / the business data which is exposed
|
||||||
|
besides monitoring information.
|
||||||
|
"""
|
||||||
|
interface Device implements Host {
|
||||||
|
hostid: ID!
|
||||||
|
"""
|
||||||
|
Per convention a uuid is used as hostname to identify devices if they do not have a unique hostname
|
||||||
|
"""
|
||||||
|
host: String!
|
||||||
|
deviceType: String
|
||||||
|
hostgroups: [HostGroup!]
|
||||||
|
name: String
|
||||||
|
tags: JSONObject
|
||||||
|
state: DeviceState
|
||||||
|
}
|
||||||
|
type OperationalDeviceData {
|
||||||
|
temperature: Float
|
||||||
|
voltage: Float
|
||||||
|
signalstrength: Float
|
||||||
|
location: Location
|
||||||
|
timestamp: DateTime
|
||||||
|
error: [ErrorPayload!]
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorPayload {
|
||||||
|
code: Int!
|
||||||
|
message: String
|
||||||
|
additionalInfo: JSONObject
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DeviceState {
|
||||||
|
operational: OperationalDeviceData
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generic IoT devices with "generic" current state - mapping all "values"
|
||||||
|
type GenericDeviceState implements DeviceState {
|
||||||
|
operational: OperationalDeviceData
|
||||||
|
current: JSONObject
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Device represents generic IoT / Edge - devices providing their state as generic "state.current" - JSON Object
|
||||||
|
"""
|
||||||
|
type GenericDevice implements Host & Device {
|
||||||
|
hostid: ID!
|
||||||
|
"""
|
||||||
|
Per convention a uuid is used as hostname to identify devices if they do not have a unique hostname
|
||||||
|
"""
|
||||||
|
host: String!
|
||||||
|
deviceType: String
|
||||||
|
hostgroups: [HostGroup!]
|
||||||
|
name: String
|
||||||
|
tags: JSONObject
|
||||||
|
state: GenericDeviceState
|
||||||
|
}
|
||||||
171
src/schema/mutations.graphql
Normal file
171
src/schema/mutations.graphql
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
type Mutation {
|
||||||
|
|
||||||
|
"""
|
||||||
|
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
||||||
|
"""
|
||||||
|
createHost(host: String!, hostgroupids:[Int!]!, templateids: [Int!]!,
|
||||||
|
location: LocationInput): CreateHostResponse
|
||||||
|
|
||||||
|
"""
|
||||||
|
(Mass) Import zabbix groups
|
||||||
|
and assign them to the corresponding hosts by groupid or groupName.
|
||||||
|
|
||||||
|
Return value: If no error occurs a groupid be returned for each created group,
|
||||||
|
otherwise the return object will contain an error message
|
||||||
|
|
||||||
|
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
||||||
|
"""
|
||||||
|
importHostGroups(hostGroups: [CreateHostGroup!]!):[CreateHostGroupResponse!]
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
(Mass) Import hosts and assign them to host groups by groupid or groupName.
|
||||||
|
|
||||||
|
Return value: If no error occurs a hostid will be returned for each created host,
|
||||||
|
otherwise the return object will contain an error message.
|
||||||
|
|
||||||
|
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
||||||
|
"""
|
||||||
|
importHosts(hosts: [CreateHost!]!):[ImportHostResponse!]
|
||||||
|
|
||||||
|
importUserRights(input: UserRightsInput!, dryRun: Boolean! = true): ImportUserRightsResult
|
||||||
|
}
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Input types used for importXXX - and storeXXX - Mutations
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
input CreateHostGroup {
|
||||||
|
"""
|
||||||
|
Name of the host group
|
||||||
|
"""
|
||||||
|
groupName: String!
|
||||||
|
"""
|
||||||
|
Internally used unique id
|
||||||
|
(will be assigned by Zabbix if empty)
|
||||||
|
"""
|
||||||
|
uuid: String
|
||||||
|
}
|
||||||
|
type ImportHostResponse {
|
||||||
|
deviceKey: String!
|
||||||
|
hostid: String
|
||||||
|
message: String
|
||||||
|
error: ApiError
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type CreateHostGroupResponse {
|
||||||
|
groupName: String!
|
||||||
|
groupid: Int
|
||||||
|
message: String
|
||||||
|
error: ApiError
|
||||||
|
}
|
||||||
|
|
||||||
|
input CreateHost {
|
||||||
|
deviceKey: String!
|
||||||
|
"""
|
||||||
|
Optional display name of the device (must be unique if provided - default is to set display name to deviceKey)
|
||||||
|
"""
|
||||||
|
name: String
|
||||||
|
deviceType: String!
|
||||||
|
"""
|
||||||
|
groupNames is used to assign the created object
|
||||||
|
to a host group. It is mandatory but
|
||||||
|
can also be blank. This is usefull in case of
|
||||||
|
passing a groupid instead which is
|
||||||
|
the zabbix internal key for storing the group.
|
||||||
|
If a groupid is provided the passed groupName is ignored
|
||||||
|
"""
|
||||||
|
groupNames: [String!]!
|
||||||
|
"""
|
||||||
|
Optionally the internal groupids can be passed - in this case the
|
||||||
|
groupName is ignored
|
||||||
|
"""
|
||||||
|
groupids: [Int]
|
||||||
|
location: LocationInput
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateHostResponse {
|
||||||
|
hostids: [Int]
|
||||||
|
itemids: [Int]
|
||||||
|
error: ApiError
|
||||||
|
}
|
||||||
|
input LocationInput {
|
||||||
|
name: String
|
||||||
|
location_lat: String
|
||||||
|
location_lon: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Permission related input
|
||||||
|
#######################################
|
||||||
|
input UserRightsInput {
|
||||||
|
userRoles: [UserRoleInput!]
|
||||||
|
userGroups: [UserGroupInput!]
|
||||||
|
}
|
||||||
|
|
||||||
|
input UserRoleInput {
|
||||||
|
name: String
|
||||||
|
type: Int
|
||||||
|
readonly: Int
|
||||||
|
rules: UserRoleRulesInput
|
||||||
|
}
|
||||||
|
|
||||||
|
input UserRoleRulesInput {
|
||||||
|
ui: [UserRoleRuleInput!]
|
||||||
|
ui_default_access: Int
|
||||||
|
modules:[UserRoleModuleInput!]
|
||||||
|
modules_default_access: Int
|
||||||
|
api_access: Int
|
||||||
|
api_mode: Int
|
||||||
|
api: [String!]
|
||||||
|
actions: [UserRoleRuleInput!]
|
||||||
|
actions_default_access: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
input UserRoleRuleInput {
|
||||||
|
name: String
|
||||||
|
status: Int
|
||||||
|
}
|
||||||
|
input UserRoleModuleInput {
|
||||||
|
moduleid: String
|
||||||
|
status: Int
|
||||||
|
id: String
|
||||||
|
}
|
||||||
|
|
||||||
|
input UserGroupInput {
|
||||||
|
name: String!
|
||||||
|
gui_access: Int
|
||||||
|
users_status: Int
|
||||||
|
hostgroup_rights: [ZabbixGroupRightInput!]
|
||||||
|
templategroup_rights: [ZabbixGroupRightInput!]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input ZabbixGroupRightInput {
|
||||||
|
uuid: String
|
||||||
|
"""
|
||||||
|
name may optionally be specified for documentation purpose,
|
||||||
|
but the master for setting the user right is the uuid.
|
||||||
|
If a uuid is found and the corresponding group
|
||||||
|
has a deviating name this will be documented within a message
|
||||||
|
with errorcode = 0 (OK) but the permission will be set (
|
||||||
|
the reason is that names for groups may deviate between several
|
||||||
|
instances of the control center although the semantic is the same -
|
||||||
|
while the semantic is identified by uuid.
|
||||||
|
"""
|
||||||
|
name: String
|
||||||
|
permission: Permission
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImportUserRightsResult {
|
||||||
|
userRoles: [ImportUserRightResult!]
|
||||||
|
userGroups: [ImportUserRightResult!]
|
||||||
|
}
|
||||||
|
type ImportUserRightResult {
|
||||||
|
id: String
|
||||||
|
name: String
|
||||||
|
message: String
|
||||||
|
errors: [ApiError!]
|
||||||
|
}
|
||||||
|
|
||||||
107
src/schema/queries.graphql
Normal file
107
src/schema/queries.graphql
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
# Scalars resolved by package "graphql-scalars"
|
||||||
|
scalar DateTime
|
||||||
|
scalar Time
|
||||||
|
scalar JSONObject
|
||||||
|
|
||||||
|
type Query {
|
||||||
|
"Get api (build) version"
|
||||||
|
apiVersion: String!
|
||||||
|
"Get zabbix version"
|
||||||
|
zabbixVersion: String
|
||||||
|
"""
|
||||||
|
Login to zabbix - provided for debugging and testing purpose. The result of the login operation is
|
||||||
|
authentication token returned may be passed as
|
||||||
|
header 'zabbix-auth-token' for authenticating future API requests.
|
||||||
|
As an alternative to the cookie 'zbx_session' may be set which is automatically set after login to
|
||||||
|
the cockpit - this is the standard way to authenticate api calls initiated by the cockpit frontend
|
||||||
|
because the frontend is always embedded into the Zabbix portal which is only accessible after logging in and
|
||||||
|
obtainind the zbx_session - cookie.
|
||||||
|
"""
|
||||||
|
login(username: String!, password: String!): String
|
||||||
|
|
||||||
|
"""
|
||||||
|
Logout from zabbix - provided for debugging and testing purpose. This invalidates the token received by the login
|
||||||
|
operation. Returns true on success
|
||||||
|
"""
|
||||||
|
logout: Boolean
|
||||||
|
|
||||||
|
"""
|
||||||
|
Get all hosts + corresponding items. If with_items==true only hosts with attached items are delivered
|
||||||
|
name_pattern: If provided this will perform a LIKE "%…%" search on the name attribute within the database.
|
||||||
|
|
||||||
|
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
||||||
|
"""
|
||||||
|
allHosts(name_pattern: String = "", filter_host: String = null, hostids: Int,
|
||||||
|
groupids:[Int!] = null, with_items: Boolean = false, tag_deviceType:[String]=[], tag_hostType:[String!]): [Host]
|
||||||
|
|
||||||
|
"""
|
||||||
|
Get all host groups.
|
||||||
|
If with_hosts==true only groups with attached hosts are delivered.
|
||||||
|
|
||||||
|
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
||||||
|
"""
|
||||||
|
allHostGroups(search_name: String, with_hosts: Boolean = true): [HostGroup]
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Get all locations used by hosts.
|
||||||
|
distinct_by_name=true means that the result is filtered for distinct names (default)
|
||||||
|
name_pattern: If provided this will perform a Regex search on the name attribute within the database.
|
||||||
|
|
||||||
|
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
||||||
|
"""
|
||||||
|
locations(name_pattern: String = "", distinct_by_name: Boolean = true, templateids:[String] = null): [Location]
|
||||||
|
|
||||||
|
"""
|
||||||
|
Export history from Zabbix items
|
||||||
|
|
||||||
|
Authentication: By zbx_session - cookie or zabbix-auth-token - header
|
||||||
|
"""
|
||||||
|
exportHostValueHistory(
|
||||||
|
"(Optional) list of hostnames to be included in the result"
|
||||||
|
host_filter: [String!],
|
||||||
|
"(Optional) list of item keys to be included in the result"
|
||||||
|
itemKey_filter: [String!],
|
||||||
|
"""
|
||||||
|
(Optional) timestamp of earliest value"""
|
||||||
|
time_from: DateTime,
|
||||||
|
"""(Optional) timestamp of last value """
|
||||||
|
time_until: DateTime,
|
||||||
|
"""Results are sorted by timestamps - ascending or descending order may be specified
|
||||||
|
using this parameter"""
|
||||||
|
sortOrder: SortOrder=desc,
|
||||||
|
"""
|
||||||
|
Maximum number of records to be delivered. Hint: This might be useful, because the
|
||||||
|
current version of Zabbix delivers a 500 - error in case of requesting too much data
|
||||||
|
"""
|
||||||
|
limit: Int
|
||||||
|
"""
|
||||||
|
As values are stored in different data structures depending on their type
|
||||||
|
the type information must be specified in advance, although
|
||||||
|
each value (also if number) is converted into a string afterwards
|
||||||
|
"""
|
||||||
|
type: StorageItemType = FLOAT
|
||||||
|
|
||||||
|
):GenericResponse
|
||||||
|
|
||||||
|
"""
|
||||||
|
Return all user permissions. If objectNames is provided return only the permissions related to the objects within
|
||||||
|
the objectNames - list
|
||||||
|
"""
|
||||||
|
userPermissions(objectNames: [String!]): [UserPermission!]
|
||||||
|
|
||||||
|
"""
|
||||||
|
Return true if and only if the current user (identified by token / cookie)
|
||||||
|
has all requested permissions (minimum - if READ is requested and the user has READ_WRITE
|
||||||
|
the response will be true)
|
||||||
|
"""
|
||||||
|
hasPermissions(permissions: [PermissionRequest!]!): Boolean
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
name_pattern: If provided this will perform a LIKE "%…%" search on the name attribute within the database.
|
||||||
|
exclude_groups_pattern: Regex allowing to exclude all matching hostgroups from group permissions
|
||||||
|
"""
|
||||||
|
exportUserRights(name_pattern: String = "" exclude_hostgroups_pattern: String = ""): UserRights
|
||||||
|
}
|
||||||
|
|
||||||
155
src/schema/zabbix.graphql
Normal file
155
src/schema/zabbix.graphql
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
###################################
|
||||||
|
# Hosts, items + groups, templates
|
||||||
|
###################################
|
||||||
|
|
||||||
|
type HostGroup {
|
||||||
|
groupid: ID!
|
||||||
|
name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Host {
|
||||||
|
hostid: ID!
|
||||||
|
"""
|
||||||
|
The host field contains the "hostname" in Zabbix
|
||||||
|
"""
|
||||||
|
host: String!
|
||||||
|
hostgroups: [HostGroup!]
|
||||||
|
name: String
|
||||||
|
tags: JSONObject
|
||||||
|
}
|
||||||
|
|
||||||
|
type ZabbixItem {
|
||||||
|
itemid: Int!
|
||||||
|
name: String!
|
||||||
|
key_: String!
|
||||||
|
hostid: Int
|
||||||
|
lastclock: Int
|
||||||
|
lastvalue: String
|
||||||
|
value_type: Int!
|
||||||
|
attributeName: String
|
||||||
|
status: DeviceStatus
|
||||||
|
type: DeviceCommunicationType
|
||||||
|
hosts: [Host!]
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DeviceCommunicationType {
|
||||||
|
ZABBIX_AGENT
|
||||||
|
ZABBIX_AGENT_ACTIVE
|
||||||
|
ZABBIX_TRAP
|
||||||
|
ZABBIX_INTERNAL_ITEM
|
||||||
|
SIMPLE_CHECK
|
||||||
|
DEPENDANT_ITEM
|
||||||
|
SIMULATOR_CALCULATED
|
||||||
|
SIMULATOR_JAVASCRIPT
|
||||||
|
HTTP_AGENT
|
||||||
|
IPMI_AGENT
|
||||||
|
JMX_AGENT
|
||||||
|
SNMP_AGENT
|
||||||
|
SNMP_TRAP
|
||||||
|
DATABASE_MONITOR
|
||||||
|
}
|
||||||
|
|
||||||
|
type ZabbixHost implements Host {
|
||||||
|
hostid: ID!
|
||||||
|
host: String!
|
||||||
|
hostgroups: [HostGroup!]
|
||||||
|
name: String
|
||||||
|
tags: JSONObject
|
||||||
|
|
||||||
|
|
||||||
|
items: [ZabbixItem!]
|
||||||
|
inventory: Inventory
|
||||||
|
parentTemplates: [Template!]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Template {
|
||||||
|
templateid: String!
|
||||||
|
name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type Inventory {
|
||||||
|
location: Location
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
Hint: WGS84[dd.ddddd] coordinates are used
|
||||||
|
"""
|
||||||
|
interface GpsPosition {
|
||||||
|
latitude: Float
|
||||||
|
longitude: Float
|
||||||
|
}
|
||||||
|
type Location implements GpsPosition {
|
||||||
|
name: String
|
||||||
|
latitude: Float
|
||||||
|
longitude: Float
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DeviceStatus {
|
||||||
|
ENABLED
|
||||||
|
DISABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
# History / Values
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
enum StorageItemType {
|
||||||
|
FLOAT
|
||||||
|
INT
|
||||||
|
TEXT
|
||||||
|
}
|
||||||
|
############################
|
||||||
|
# Permissions
|
||||||
|
############################
|
||||||
|
type UserRights {
|
||||||
|
userGroups: [UserGroup!]
|
||||||
|
userRoles: [UserRole!]
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserRole {
|
||||||
|
roleid: Int!
|
||||||
|
name: String
|
||||||
|
type: Int
|
||||||
|
readonly: Int
|
||||||
|
rules: UserRoleRules
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserRoleRules {
|
||||||
|
ui: [UserRoleRule!]
|
||||||
|
ui_default_access: Int
|
||||||
|
modules:[UserRoleModule!]
|
||||||
|
modules_default_access: Int
|
||||||
|
api_access: Int
|
||||||
|
api_mode: Int
|
||||||
|
api: [String!]
|
||||||
|
actions: [UserRoleRule!]
|
||||||
|
actions_default_access: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserRoleRule {
|
||||||
|
name: String
|
||||||
|
status: Int
|
||||||
|
}
|
||||||
|
type UserRoleModule {
|
||||||
|
moduleid: String
|
||||||
|
status: Int
|
||||||
|
id: String
|
||||||
|
relative_path: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserGroup {
|
||||||
|
usrgrpid: Int!
|
||||||
|
name: String!
|
||||||
|
gui_access: Int
|
||||||
|
users_status: Int
|
||||||
|
hostgroup_rights: [ZabbixGroupRight!]
|
||||||
|
templategroup_rights: [ZabbixGroupRight!]
|
||||||
|
}
|
||||||
|
|
||||||
|
type ZabbixGroupRight {
|
||||||
|
id: Int!
|
||||||
|
uuid: String
|
||||||
|
name: String
|
||||||
|
permission: Permission
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue