import { isZabbixErrorResult, ParsedArgs, ZabbixCreateOrUpdateParams, ZabbixCreateOrUpdateRequest, ZabbixErrorResult, ZabbixParams, ZabbixRequest, ZabbixResult } from "./zabbix-request.js"; import { ApiError, ImportUserRightResult, UserGroup, UserGroupInput, ZabbixGroupRight, ZabbixGroupRightInput } from "../schema/generated/graphql.js"; import {ZabbixAPI} from "./zabbix-api.js"; import {logger} from "../logging/logger.js"; import {ZabbixQueryTemplateGroupRequest, ZabbixQueryTemplateGroupResponse} from "./zabbix-templates.js"; import {GroupHelper, ZabbixQueryHostgroupsRequest, ZabbixQueryHostgroupsResult} from "./zabbix-hostgroups.js"; import {ApiErrorCode} from "../model/model_enum_values.js"; abstract class ZabbixPrepareGetTemplatesAndHostgroupsRequest extends ZabbixRequest { protected templategroups: ZabbixQueryTemplateGroupResponse[]; protected hostgroups: ZabbixQueryHostgroupsResult[]; constructor(path: string, authToken?: string | null, cookie?: string) { super(path, authToken, cookie); } async prepare(zabbixAPI: ZabbixAPI, args?: A): Promise { let prepResult = await super.prepare(zabbixAPI, args); if (prepResult) { return prepResult; } let templategroups = await new ZabbixQueryTemplateGroupRequest(this.authToken, this.cookie) .executeRequestReturnError(zabbixAPI); if (isZabbixErrorResult(templategroups)) { this.prepResult = templategroups; return templategroups; } this.templategroups = templategroups; let hostgroups = await new ZabbixQueryHostgroupsRequest(this.authToken, this.cookie) .executeRequestReturnError(zabbixAPI); if (isZabbixErrorResult(hostgroups)) { this.prepResult = hostgroups; return hostgroups; } this.hostgroups = hostgroups; return undefined } } export class ZabbixExportUserGroupArgs extends ParsedArgs { public exclude_hostgroups_pattern?: RegExp | undefined = undefined; constructor(name_pattern?: string | null, exclude_hostgroups_pattern_str?: string | null) { super(name_pattern? {name_pattern: name_pattern} : undefined); if (exclude_hostgroups_pattern_str) { this.exclude_hostgroups_pattern = new RegExp(exclude_hostgroups_pattern_str); } } } export class ZabbixExportUserGroupsRequest extends ZabbixPrepareGetTemplatesAndHostgroupsRequest< UserGroup[], ZabbixExportUserGroupArgs> { constructor(authToken?: string | null, cookie?: string) { super("usergroup.get.withuuids", authToken, cookie); } createZabbixParams(args?: ZabbixExportUserGroupArgs): ZabbixParams { return { ...super.createZabbixParams(args), output: "extend", selectTemplateGroupRights: "extend", selectHostGroupRights: "extend" }; } async executeRequestReturnError(zabbixAPI: ZabbixAPI, args?: ZabbixExportUserGroupArgs): Promise { let result = await super.executeRequestReturnError(zabbixAPI, args); if (!isZabbixErrorResult(result)) { for (let userGroup of result) { for (let template_permission of userGroup.templategroup_rights || []) { for (let templategroup of this.templategroups) { if (templategroup.groupid == template_permission.id.toString()) { template_permission.uuid = templategroup.uuid; template_permission.name = templategroup.name; break; } } } let filtered_hostgroup_permission: ZabbixGroupRight [] = []; for (let hostgroup_permission of userGroup.hostgroup_rights || []) { for (let hostgroup of this.hostgroups) { if (hostgroup.groupid == hostgroup_permission.id.toString()) { hostgroup_permission.uuid = hostgroup.uuid; hostgroup_permission.name = hostgroup.name; break; } } if (!args?.exclude_hostgroups_pattern || !hostgroup_permission.name || !args.exclude_hostgroups_pattern.test(hostgroup_permission.name)) { filtered_hostgroup_permission.push(hostgroup_permission); } } userGroup.hostgroup_rights = filtered_hostgroup_permission; } } return result; } } export class ZabbixQueryUserGroupsRequest extends ZabbixRequest { constructor(authToken?: string | null, cookie?: string | null) { super("usergroup.get", authToken, cookie); } createZabbixParams(args?: ParsedArgs): ZabbixParams { return { ...super.createZabbixParams(args), output: "extend", }; } } export class ZabbixImportUserGroupsParams extends ParsedArgs { constructor(public usergroups: UserGroupInput[], public dryRun = true) { super(); } } export class ZabbixImportUserGroupsRequest extends ZabbixPrepareGetTemplatesAndHostgroupsRequest { constructor(zabbixAuthToken: any, cookie: any) { super("usergroup.create.import", zabbixAuthToken, cookie); } async executeRequestReturnError(zabbixAPI: ZabbixAPI, args?: ZabbixImportUserGroupsParams): Promise { let prepareResult = await this.prepare(zabbixAPI, args); if (prepareResult) { return prepareResult; } let results: ImportUserRightResult[] = []; let hostGroupsToPropagete: number[] = [] let createGroupRequest = new ZabbixCreateOrUpdateRequest< ZabbixCreateUserGroupResponse, ZabbixQueryUserGroupsRequest, ZabbixCreateOrUpdateParams>( "usergroup", "usrgrpid", ZabbixQueryUserGroupsRequest, this.authToken, this.cookie); for (let userGroup of args?.usergroups || []) { let templategroup_rights = this.calc_templategroup_rights(userGroup); let hostgroup_rights = this.calc_hostgroup_rights(userGroup); let errors: ApiError[] = []; let paramsObj: any = { name: userGroup.name, gui_access: userGroup.gui_access, users_status: userGroup.users_status, hostgroup_rights: hostgroup_rights.hostgroup_rights, templategroup_rights: templategroup_rights.templategroup_rights, }; let params = new ZabbixCreateOrUpdateParams(paramsObj, args?.dryRun) let result = await createGroupRequest.executeRequestReturnError(zabbixAPI, params); if (isZabbixErrorResult(result)) { errors.push(result.error); results.push( { name: userGroup.name, errors: errors, message: result.error.message || "Error creating user group", } ) } else { hostGroupsToPropagete.push( ...hostgroup_rights.hostgroup_rights.map( value => value.id)); results.push( { name: userGroup.name, id: result.usrgrpids[0], message: createGroupRequest.message, errors: errors, } ) } errors.push(...templategroup_rights.errors); errors.push(...hostgroup_rights.errors); } // If user groups were imported: Propagate group permissions to group children if (hostGroupsToPropagete.length > 0) { // Propagate group permissions to group children, filter duplicate groupids first await new ZabbixPropagateHostGroupsRequest(this.authToken, this.cookie) .executeRequestThrowError(zabbixAPI, new ZabbixPropagateHostGroupsParams(hostGroupsToPropagete)) } return results; } calc_hostgroup_rights(usergroup: UserGroupInput): { errors: ApiError[], hostgroup_rights: ZabbixGroupRight[] } { let result: ZabbixGroupRight [] = []; let errors: ApiError[] = []; for (let hostgroup_right of usergroup.hostgroup_rights || []) { let success = false; let matchedName = ""; let matchedId: number | undefined = undefined; // Try matching by UUID first for (let hostgroup of this.hostgroups) { if (hostgroup.uuid && hostgroup_right.uuid && hostgroup.uuid === hostgroup_right.uuid) { matchedId = Number(hostgroup.groupid); matchedName = hostgroup.name; success = true; break; } } if (success) { result.push( { id: matchedId!, permission: hostgroup_right.permission, } ) if (hostgroup_right.name && hostgroup_right.name != matchedName) { errors.push( { code: ApiErrorCode.OK, message: `WARNING: Hostgroup found and permissions set, but target name=${matchedName} does not match provided name=${hostgroup_right.name}`, data: hostgroup_right, } ) } } else { errors.push( { code: ApiErrorCode.ZABBIX_HOSTGROUP_NOT_FOUND, message: `Hostgroup with UUID ${hostgroup_right.uuid} not found`, data: hostgroup_right, } ) } } return { hostgroup_rights: result, errors: errors, }; } calc_templategroup_rights(usergroup: UserGroupInput): { errors: ApiError[], templategroup_rights: ZabbixGroupRightInput[] } { let result: ZabbixGroupRight [] = []; let errors: ApiError[] = []; for (let templategroup_right of usergroup.templategroup_rights || []) { let success = false; let matchedName = ""; let matchedId: number | undefined = undefined; // Try matching by UUID first for (let templategroup of this.templategroups) { if (templategroup.uuid && templategroup_right.uuid && templategroup.uuid === templategroup_right.uuid) { matchedId = Number(templategroup.groupid); matchedName = templategroup.name; success = true; break; } } if (success) { result.push( { id: matchedId!, permission: templategroup_right.permission, } ) if (templategroup_right.name && templategroup_right.name != matchedName) { errors.push( { code: ApiErrorCode.OK, message: `WARNING: Templategroup found and permissions set, but target name=${matchedName} does not match provided name=${templategroup_right.name}`, data: templategroup_right, } ) } } else { errors.push( { code: ApiErrorCode.ZABBIX_TEMPLATEGROUP_NOT_FOUND, message: `Templategroup with UUID ${templategroup_right.uuid} not found`, data: templategroup_right, } ) } } return { templategroup_rights: result, errors: errors, }; } } export type ZabbixCreateUserGroupResponse = { usrgrpids: string[]; } class ZabbixPropagateHostGroupsParams extends ParsedArgs { constructor(public groups: number[]) { super(); } } export class ZabbixPropagateHostGroupsRequest extends ZabbixRequest { constructor(authToken?: string | null, cookie?: string | null) { super("hostgroup.propagate", authToken, cookie); } async prepare(zabbixAPI: ZabbixAPI, args?: ZabbixPropagateHostGroupsParams): Promise { return super.prepare(zabbixAPI, args); } createZabbixParams(args?: ZabbixPropagateHostGroupsParams): ZabbixParams { return { groups: [...new Set(args?.groups || [])].map(value => { return { groupid: value } }) || [], permissions: true } } }