feat: implement smoketest and extend host provisioning with template linking

- Add runSmoketest mutation to automate end-to-end verification.

- Add SmoketestExecutor and HostDeleter to support automated testing and cleanup.

- Extend createHost and importHosts to allow linking templates by name or ID.

- Update docs/howtos/cookbook.md with new recipe steps and AI/MCP guidance.

- Update .junie/guidelines.md with new verification and deployment standards.

- Add src/test/template_link.test.ts and update existing tests to cover new functionality.

- Regenerate GraphQL types to match schema updates.
This commit is contained in:
Andreas Hilbig 2026-01-31 11:46:02 +01:00
parent b56255ffaa
commit 67357d0bc3
20 changed files with 690 additions and 50 deletions

View file

@ -0,0 +1,110 @@
import {DeleteResponse} from "../schema/generated/graphql.js";
import {
ZabbixDeleteHostsRequest,
ZabbixQueryHostsGenericRequest,
} from "../datasources/zabbix-hosts.js";
import {
ZabbixDeleteHostGroupsRequest,
ZabbixQueryHostgroupsRequest,
ZabbixQueryHostgroupsParams,
GroupHelper
} from "../datasources/zabbix-hostgroups.js";
import {isZabbixErrorResult, ParsedArgs} from "../datasources/zabbix-request.js";
import {zabbixAPI} from "../datasources/zabbix-api.js";
export class HostDeleter {
public static async deleteHosts(hostids: number[] | null | undefined, name_pattern?: string | null, zabbixAuthToken?: string, cookie?: string): Promise<DeleteResponse[]> {
const result: DeleteResponse[] = [];
let idsToDelete = hostids ? [...hostids] : [];
if (name_pattern) {
const queryResult = await new ZabbixQueryHostsGenericRequest("host.get", zabbixAuthToken, cookie)
.executeRequestReturnError(zabbixAPI, new ParsedArgs({ name_pattern: name_pattern }));
if (!isZabbixErrorResult(queryResult) && Array.isArray(queryResult)) {
const foundIds = queryResult.map((t: any) => Number(t.hostid));
// Merge and deduplicate
idsToDelete = Array.from(new Set([...idsToDelete, ...foundIds]));
}
}
if (idsToDelete.length === 0) {
return [];
}
const deleteResult = await new ZabbixDeleteHostsRequest(zabbixAuthToken, cookie)
.executeRequestReturnError(zabbixAPI, new ParsedArgs(idsToDelete));
if (isZabbixErrorResult(deleteResult)) {
let errorMessage = deleteResult.error.message;
if (deleteResult.error.data) {
errorMessage += " " + (typeof deleteResult.error.data === 'string' ? deleteResult.error.data : JSON.stringify(deleteResult.error.data));
}
for (const id of idsToDelete) {
result.push({
id: id,
message: errorMessage,
error: deleteResult.error
});
}
} else if (deleteResult?.hostids) {
for (const id of idsToDelete) {
result.push({
id: id,
message: `Host ${id} deleted successfully`
});
}
}
return result;
}
public static async deleteHostGroups(groupids: number[] | null | undefined, name_pattern?: string | null, zabbixAuthToken?: string, cookie?: string): Promise<DeleteResponse[]> {
const result: DeleteResponse[] = [];
let idsToDelete = groupids ? [...groupids] : [];
if (name_pattern) {
const queryResult = await new ZabbixQueryHostgroupsRequest(zabbixAuthToken, cookie)
.executeRequestReturnError(zabbixAPI, new ZabbixQueryHostgroupsParams({
filter_name: GroupHelper.groupFullName(name_pattern)
}));
if (!isZabbixErrorResult(queryResult) && Array.isArray(queryResult)) {
const foundIds = queryResult.map(g => Number(g.groupid));
// Merge and deduplicate
idsToDelete = Array.from(new Set([...idsToDelete, ...foundIds]));
}
}
if (idsToDelete.length === 0) {
return [];
}
const deleteResult = await new ZabbixDeleteHostGroupsRequest(zabbixAuthToken, cookie)
.executeRequestReturnError(zabbixAPI, new ParsedArgs(idsToDelete));
if (isZabbixErrorResult(deleteResult)) {
let errorMessage = deleteResult.error.message;
if (deleteResult.error.data) {
errorMessage += " " + (typeof deleteResult.error.data === 'string' ? deleteResult.error.data : JSON.stringify(deleteResult.error.data));
}
for (const id of idsToDelete) {
result.push({
id: id,
message: errorMessage,
error: deleteResult.error
});
}
} else if (deleteResult?.groupids) {
for (const id of idsToDelete) {
result.push({
id: id,
message: `Host group ${id} deleted successfully`
});
}
}
return result;
}
}