init after v1 corruption

This commit is contained in:
2026-01-02 22:48:32 +00:00
parent 305f69836c
commit 166ee1fc73
91 changed files with 15801 additions and 0 deletions

View File

@@ -0,0 +1,294 @@
{
"id": "akfNprhHotiw4e2s",
"name": "Zabbix Alert Ingestion",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "zabbix-alert",
"options": {}
},
"id": "webhook-trigger",
"name": "Zabbix Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
400
],
"webhookId": "zabbix-alert-webhook",
"notes": "Receives POST requests from Zabbix with alert data"
},
{
"parameters": {
"jsCode": "// Parse and normalize incoming Zabbix alert data\nconst body = $input.item.json.body || $input.item.json;\n\nconsole.log('=== Zabbix Alert Received ===');\nconsole.log('Raw payload:', JSON.stringify(body, null, 2));\n\n// Extract alert fields from Zabbix webhook payload\nconst alert = {\n event_id: body.event_id || body.eventid || 'unknown',\n event_value: body.event_value || body.value || '1',\n problem_name: body.trigger_name || body.name || 'Unknown Problem',\n severity: parseInt(body.trigger_severity || body.severity || '0'),\n host_id: body.host_id || body.hostid || '',\n host_name: body.host_name || body.host || 'Unknown Host',\n trigger_id: body.trigger_id || body.triggerid || '',\n operational_data: body.event_opdata || body.opdata || '',\n tags: body.event_tags || body.tags || [],\n timestamp: body.event_date && body.event_time ? `${body.event_date} ${body.event_time}` : new Date().toISOString(),\n clock: body.clock || Math.floor(Date.now() / 1000)\n};\n\nif (typeof alert.tags === 'string') {\n try {\n alert.tags = JSON.parse(alert.tags);\n } catch (e) {\n alert.tags = alert.tags.includes(',') ? alert.tags.split(',').map(t => ({tag: t.trim()})) : [{tag: alert.tags}];\n }\n}\n\nif (!Array.isArray(alert.tags)) {\n alert.tags = [];\n}\n\nconst severityNames = {0: 'Not classified', 1: 'Information', 2: 'Warning', 3: 'Average', 4: 'High', 5: 'Disaster'};\nalert.severity_name = severityNames[alert.severity] || 'Unknown';\n\nconst locationMatch = alert.host_name.match(/\\.(dfw|lax|rdu|tpa|local)\\./i);\nalert.location = locationMatch ? locationMatch[1].toLowerCase() : 'unknown';\n\nlet systemType = 'unknown';\nconst hostname = alert.host_name.toLowerCase();\nconst tagStr = alert.tags.map(t => (t.tag || t.value || '').toLowerCase()).join(' ');\n\nif (hostname.includes('pve') || tagStr.includes('proxmox')) {\n systemType = 'proxmox';\n} else if (hostname.includes('pfsense') || tagStr.includes('pfsense')) {\n systemType = 'pfsense';\n} else if (hostname.includes('truenas') || tagStr.includes('truenas')) {\n systemType = 'truenas';\n} else if (hostname.includes('mysql') || tagStr.includes('mysql')) {\n systemType = 'database';\n} else if (hostname.includes('web') || hostname.includes('www')) {\n systemType = 'web';\n} else if (hostname.includes('usw') || hostname.includes('uap') || hostname.includes('ucg')) {\n systemType = 'network';\n} else if (hostname.includes('qnap') || hostname.includes('nas')) {\n systemType = 'storage';\n} else if (tagStr.includes('linux')) {\n systemType = 'linux';\n}\nalert.system_type = systemType;\n\nlet category = 'unknown';\nif (tagStr.includes('availability')) {\n category = 'availability';\n} else if (tagStr.includes('performance')) {\n category = 'performance';\n} else if (tagStr.includes('capacity')) {\n category = 'capacity';\n} else if (tagStr.includes('hardware') || tagStr.includes('temperature')) {\n category = 'hardware';\n}\nalert.category = category;\n\nlet priorityScore = alert.severity * 10;\nif (category === 'availability') priorityScore += 5;\nif (systemType === 'proxmox' || systemType === 'pfsense') priorityScore += 3;\nalert.priority_score = priorityScore;\nalert.raw_payload = body;\n\nconsole.log('=== Parsed Alert ===');\nconsole.log('Event ID:', alert.event_id);\nconsole.log('Host:', alert.host_name);\nconsole.log('Problem:', alert.problem_name);\nconsole.log('Severity:', alert.severity_name, `(${alert.severity})`);\nconsole.log('Location:', alert.location);\nconsole.log('System Type:', alert.system_type);\nconsole.log('Category:', alert.category);\n\nreturn { json: alert };"
},
"id": "parse-alert-data",
"name": "Parse Alert Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
464,
400
],
"notes": "Extracts and normalizes alert data from webhook payload"
},
{
"parameters": {
"method": "POST",
"url": "https://zabbix.ext.ben.io/api_jsonrpc.php",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zabbixApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"jsonrpc\": \"2.0\", \"method\": \"host.get\", \"params\": {\"hostids\": \"{{ $json.host_id }}\", \"output\": [\"hostid\", \"host\", \"name\", \"status\"], \"selectGroups\": \"extend\", \"selectInterfaces\": [\"type\", \"ip\", \"port\"], \"selectInventory\": [\"location\", \"notes\", \"os\"]}, \"id\": 1}",
"options": {}
},
"id": "query-host-details",
"name": "Query Host Details",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
688,
400
],
"credentials": {
"zabbixApi": {
"id": "j03eT0qxJpv7H5an",
"name": "Zabbix account"
}
},
"notes": "Fetches full host information from Zabbix API"
},
{
"parameters": {
"method": "POST",
"url": "https://zabbix.ext.ben.io/api_jsonrpc.php",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zabbixApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"jsonrpc\": \"2.0\", \"method\": \"problem.get\", \"params\": {\"eventids\": \"{{ $('Parse Alert Data').item.json.event_id }}\", \"output\": \"extend\", \"selectAcknowledges\": \"extend\", \"selectTags\": \"extend\", \"selectSuppressionData\": \"extend\"}, \"id\": 2}",
"options": {}
},
"id": "query-problem-details",
"name": "Query Problem Details",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
912,
400
],
"credentials": {
"zabbixApi": {
"id": "j03eT0qxJpv7H5an",
"name": "Zabbix account"
}
},
"notes": "Fetches problem details including acknowledgements"
},
{
"parameters": {
"method": "POST",
"url": "https://zabbix.ext.ben.io/api_jsonrpc.php",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zabbixApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"jsonrpc\": \"2.0\", \"method\": \"trigger.get\", \"params\": {\"triggerids\": \"{{ $('Parse Alert Data').item.json.trigger_id }}\", \"output\": \"extend\", \"selectTags\": \"extend\"}, \"id\": 3}",
"options": {}
},
"id": "query-trigger-details",
"name": "Query Trigger Details",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1120,
400
],
"credentials": {
"zabbixApi": {
"id": "j03eT0qxJpv7H5an",
"name": "Zabbix account"
}
},
"notes": "Fetches trigger configuration including resolution hints"
},
{
"parameters": {
"jsCode": "const parsedAlert = $('Parse Alert Data').item.json;\nconst hostData = $('Query Host Details').item.json.result?.[0] || {};\nconst problemData = $('Query Problem Details').item.json.result?.[0] || {};\nconst triggerData = $('Query Trigger Details').item.json.result?.[0] || {};\n\nconst enrichedAlert = {\n ...parsedAlert,\n host_status: hostData.status === '0' ? 'enabled' : 'disabled',\n host_groups: (hostData.groups || []).map(g => g.name),\n host_interfaces: hostData.interfaces || [],\n host_inventory: hostData.inventory || {},\n acknowledged: problemData.acknowledged === '1',\n suppressed: problemData.suppressed === '1',\n acknowledgements: problemData.acknowledges || [],\n problem_tags: problemData.tags || [],\n trigger_description: triggerData.description || parsedAlert.problem_name,\n trigger_comments: triggerData.comments || '',\n trigger_expression: triggerData.expression || '',\n trigger_priority: triggerData.priority || parsedAlert.severity,\n enriched_at: new Date().toISOString(),\n enrichment_success: true\n};\n\nif (enrichedAlert.trigger_comments) {\n const comments = enrichedAlert.trigger_comments.toLowerCase();\n enrichedAlert.resolution_hints = [];\n if (comments.includes('restart')) enrichedAlert.resolution_hints.push('Service restart may resolve this issue');\n if (comments.includes('connectivity') || comments.includes('ping')) enrichedAlert.resolution_hints.push('Check network connectivity');\n if (comments.includes('acknowledge')) enrichedAlert.resolution_hints.push('Manual acknowledgement suggested');\n}\n\nenrichedAlert.should_notify = enrichedAlert.severity >= 3;\nenrichedAlert.notification_channels = [];\nif (enrichedAlert.severity >= 4) {\n enrichedAlert.notification_channels.push('email');\n} else if (enrichedAlert.severity === 3 && !enrichedAlert.suppressed) {\n enrichedAlert.notification_channels.push('email');\n}\n\nconsole.log('=== Enriched Alert Complete ===');\nconsole.log('Should Notify:', enrichedAlert.should_notify);\n\nreturn { json: enrichedAlert };"
},
"id": "enrich-alert",
"name": "Enrich Alert",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1344,
400
],
"notes": "Combines all enrichment data and determines notification strategy"
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.should_notify }}",
"value2": true
}
]
},
"options": {}
},
"id": "should-notify-check",
"name": "Should Notify?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1568,
400
],
"notes": "Checks if notification should be sent based on severity and suppression"
},
{
"parameters": {
"jsCode": "const alert = $input.item.json;\nconsole.log('=== Notification Skipped ===');\nconsole.log('Reason: Severity too low or alert suppressed');\nconsole.log('Severity:', alert.severity_name);\nconsole.log('Suppressed:', alert.suppressed);\nreturn {json: {skipped: true, reason: alert.suppressed ? 'Alert is suppressed' : 'Severity below notification threshold', alert_summary: `${alert.problem_name} on ${alert.host_name}`}};"
},
"id": "skip-notification-log",
"name": "Skip Notification Log",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1792,
512
],
"notes": "Logs when notification is skipped"
},
{
"parameters": {
"sendTo": "admin@ben.io",
"subject": "=[{{ $json.severity_name }}] {{ $json.problem_name }} on {{ $json.host_name }}",
"message": "Test Message",
"options": {}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1776,
304
],
"id": "e814bfea-ec17-46ac-8f98-7ab9b2e6244e",
"name": "Send a message",
"webhookId": "daf00ce2-f6a0-4c4e-94a8-0962bd3a1224",
"credentials": {
"gmailOAuth2": {
"id": "Os1ux3h3zFlC2XkG",
"name": "Gmail account"
}
}
}
],
"connections": {
"Zabbix Webhook": {
"main": [
[
{
"node": "Parse Alert Data",
"type": "main",
"index": 0
}
]
]
},
"Parse Alert Data": {
"main": [
[
{
"node": "Query Host Details",
"type": "main",
"index": 0
}
]
]
},
"Query Host Details": {
"main": [
[
{
"node": "Query Problem Details",
"type": "main",
"index": 0
}
]
]
},
"Query Problem Details": {
"main": [
[
{
"node": "Query Trigger Details",
"type": "main",
"index": 0
}
]
]
},
"Query Trigger Details": {
"main": [
[
{
"node": "Enrich Alert",
"type": "main",
"index": 0
}
]
]
},
"Enrich Alert": {
"main": [
[
{
"node": "Should Notify?",
"type": "main",
"index": 0
}
]
]
},
"Should Notify?": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
],
[
{
"node": "Skip Notification Log",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"saveExecutionProgress": true,
"saveManualExecutions": true,
"saveDataErrorExecution": "all",
"saveDataSuccessExecution": "all",
"executionOrder": "v1"
},
"triggerCount": 1,
"versionId": "baf99192-61ed-4321-b831-5c212e89bf23",
"owner": {
"type": "personal",
"projectId": "FeLO36wNUAcn61Wj",
"projectName": "Ben W <admin@ben.io>",
"personalEmail": "admin@ben.io"
},
"parentFolderId": "LTWZD96boqxk9sIs",
"isArchived": false
}