feat: improve Zabbix multi-version compatibility and introduce local development environment
This update enhances compatibility across multiple Zabbix versions and introduces tools for easier local development and testing. Key improvements and verified version support: - Verified Zabbix version support: 6.2, 6.4, 7.0, and 7.4. - Version-specific feature handling: - `history.push` is enabled only for Zabbix 7.0+; older versions skip it with a clear error or notice. - Conditional JSON-RPC authentication: the `auth` field is automatically added to the request body for versions older than 6.4. - Implemented static Zabbix version caching in the datasource to minimize redundant API calls. - Query optimization refinements: - Added mapping for implied fields (e.g., `state` -> `items`, `deviceType` -> `tags`). - Automatically prune unnecessary Zabbix parameters (like `selectItems` or `selectTags`) when not requested. - Local development environment: - Added a new `zabbix-local` Docker Compose profile that includes PostgreSQL, Zabbix Server, and Zabbix Web. - Supports testing different versions by passing the `ZABBIX_VERSION` environment variable (e.g., 6.2, 6.4, 7.0, 7.4). - Provided a sample environment file at `samples/zabbix-local.env`. - Documentation and Roadmap: - Updated README with a comprehensive version compatibility matrix and local environment instructions. - Created a new guide: `docs/howtos/local_development.md`. - Updated maintenance guides and added "Local Development Environment" as an achieved milestone in the roadmap. - Test suite enhancements: - Improved Smoketest and RegressionTest executors with more reliable resource cleanup and error reporting. - Made tests version-aware to prevent failures on older Zabbix instances. BREAKING CHANGE: Dropped Zabbix 6.0 specific workarounds; the minimum supported version is now 6.2.
This commit is contained in:
parent
7c2dee2b6c
commit
fb5e9cbe81
36 changed files with 470 additions and 172 deletions
|
|
@ -17,8 +17,9 @@ import {
|
|||
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 {ZabbixQueryHostgroupsRequest, ZabbixQueryHostgroupsResult} from "./zabbix-hostgroups.js";
|
||||
import {GroupHelper, ZabbixQueryHostgroupsRequest, ZabbixQueryHostgroupsResult} from "./zabbix-hostgroups.js";
|
||||
import {ApiErrorCode} from "../model/model_enum_values.js";
|
||||
|
||||
|
||||
|
|
@ -153,19 +154,22 @@ export class ZabbixImportUserGroupsRequest
|
|||
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 params = new ZabbixCreateOrUpdateParams({
|
||||
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,
|
||||
}, args?.dryRun)
|
||||
};
|
||||
|
||||
let params = new ZabbixCreateOrUpdateParams(paramsObj, args?.dryRun)
|
||||
let result = await createGroupRequest.executeRequestReturnError(zabbixAPI, params);
|
||||
if (isZabbixErrorResult(result)) {
|
||||
|
||||
|
|
@ -214,30 +218,36 @@ export class ZabbixImportUserGroupsRequest
|
|||
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) {
|
||||
result.push(
|
||||
{
|
||||
id: Number(hostgroup.groupid),
|
||||
permission: hostgroup_right.permission,
|
||||
}
|
||||
)
|
||||
success = true;
|
||||
if (hostgroup.uuid && hostgroup_right.uuid && hostgroup.uuid === hostgroup_right.uuid) {
|
||||
matchedId = Number(hostgroup.groupid);
|
||||
matchedName = hostgroup.name;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (success && hostgroup_right.name && hostgroup_right.name != matchedName) {
|
||||
errors.push(
|
||||
|
||||
if (success) {
|
||||
result.push(
|
||||
{
|
||||
code: ApiErrorCode.OK,
|
||||
message: `WARNING: Hostgroup found and permissions set, but target name=${matchedName} does not match`,
|
||||
data: hostgroup_right,
|
||||
id: matchedId!,
|
||||
permission: hostgroup_right.permission,
|
||||
}
|
||||
)
|
||||
}
|
||||
if (!success) {
|
||||
|
||||
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,
|
||||
|
|
@ -262,29 +272,36 @@ export class ZabbixImportUserGroupsRequest
|
|||
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) {
|
||||
result.push(
|
||||
{
|
||||
id: Number(templategroup.groupid),
|
||||
permission: templategroup_right.permission,
|
||||
}
|
||||
)
|
||||
if (templategroup.uuid && templategroup_right.uuid && templategroup.uuid === templategroup_right.uuid) {
|
||||
matchedId = Number(templategroup.groupid);
|
||||
matchedName = templategroup.name;
|
||||
success = true;
|
||||
matchedName = templategroup.name
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (success && templategroup_right.name && templategroup_right.name != matchedName) {
|
||||
errors.push(
|
||||
|
||||
if (success) {
|
||||
result.push(
|
||||
{
|
||||
code: ApiErrorCode.OK,
|
||||
message: `WARNING: Templategroup found and permissions set, but target name=${matchedName} does not match`,
|
||||
data: templategroup_right,
|
||||
id: matchedId!,
|
||||
permission: templategroup_right.permission,
|
||||
}
|
||||
)
|
||||
}
|
||||
if (!success) {
|
||||
|
||||
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,
|
||||
|
|
@ -317,6 +334,10 @@ export class ZabbixPropagateHostGroupsRequest extends ZabbixRequest<ZabbixCreate
|
|||
super("hostgroup.propagate", authToken, cookie);
|
||||
}
|
||||
|
||||
async prepare(zabbixAPI: ZabbixAPI, args?: ZabbixPropagateHostGroupsParams): Promise<ZabbixCreateUserGroupResponse | ZabbixErrorResult | undefined> {
|
||||
return super.prepare(zabbixAPI, args);
|
||||
}
|
||||
|
||||
createZabbixParams(args?: ZabbixPropagateHostGroupsParams): ZabbixParams {
|
||||
return {
|
||||
groups: [...new Set(args?.groups || [])].map(value => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue