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:
parent
b56255ffaa
commit
67357d0bc3
20 changed files with 690 additions and 50 deletions
110
src/execution/host_deleter.ts
Normal file
110
src/execution/host_deleter.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue