Shumoku

Custom Integration

Generate network diagrams from custom APIs and other systems

Shumoku uses JSON format as an intermediate format, allowing you to generate network diagrams from systems other than NetBox.

Workflow

Custom API / CMDB / Monitoring Systems

    Generate JSON

    Render with Shumoku

    SVG / HTML / PNG

Basic Flow

1. Fetch data from data source

// Example: Fetch device info from custom API
const devices = await fetch('https://api.example.com/devices').then(r => r.json())
const connections = await fetch('https://api.example.com/connections').then(r => r.json())

2. Convert to Shumoku JSON format

const networkGraph = {
  version: '1.0.0',
  name: 'Network from Custom API',
  nodes: devices.map(d => ({
    id: d.hostname,
    label: d.displayName,
    type: mapDeviceType(d.category),  // Map custom category to Shumoku type
    vendor: d.manufacturer,
    model: d.model,
    parent: d.location,
    metadata: {
      serial: d.serialNumber,
      firmware: d.firmwareVersion
    }
  })),
  links: connections.map(c => ({
    from: { node: c.sourceDevice, port: c.sourcePort },
    to: { node: c.targetDevice, port: c.targetPort },
    vlan: c.vlans
  })),
  subgraphs: locations.map(l => ({
    id: l.name,
    label: l.displayName
  }))
}

3. Render

import { renderGraphToSvg } from '@shumoku/renderer-svg'
import { renderGraphToHtml } from '@shumoku/renderer-html'
import { renderGraphToPng } from '@shumoku/renderer-png'  // Node.js only

// One-liner API (recommended)
const svg = await renderGraphToSvg(networkGraph)
const html = await renderGraphToHtml(networkGraph)
const pngBuffer = await renderGraphToPng(networkGraph)  // Node.js only

// Or use the pipeline API for more control
import { prepareRender, renderSvg } from '@shumoku/renderer-svg'
import { renderHtml } from '@shumoku/renderer-html'
import { renderPng } from '@shumoku/renderer-png'  // Node.js only

const prepared = await prepareRender(networkGraph)
const svg = await renderSvg(prepared)
const html = renderHtml(prepared)
const png = await renderPng(prepared)  // Node.js only

The pipeline automatically resolves icon dimensions from CDN for proper aspect ratio rendering.

CLI Workflow

# 1. Generate JSON with custom script
node generate-from-api.js > network.json

# 2. Render with Shumoku
npx @shumoku/cli render network.json -o diagram.html

Merging with NetBox Data

Example of adding custom information to NetBox data:

// merge-data.js
import { readFileSync, writeFileSync } from 'fs'

// JSON exported from NetBox
const netbox = JSON.parse(readFileSync('netbox.json', 'utf-8'))

// Status info from monitoring system
const monitoring = JSON.parse(readFileSync('monitoring.json', 'utf-8'))

// Add status info to nodes
for (const node of netbox.nodes) {
  const status = monitoring.devices[node.id]
  if (status) {
    node.metadata = {
      ...node.metadata,
      cpuUsage: status.cpu,
      memoryUsage: status.memory,
      lastSeen: status.lastSeen
    }
    // Change style for down devices
    if (status.state === 'down') {
      node.style = {
        stroke: '#ef4444',
        strokeWidth: 3
      }
    }
  }
}

// Add cloud resources
const cloud = JSON.parse(readFileSync('aws-inventory.json', 'utf-8'))
netbox.nodes.push(...cloud.instances.map(i => ({
  id: i.instanceId,
  label: i.name,
  vendor: 'aws',
  service: 'ec2',
  resource: 'instance',
  parent: 'aws-vpc'
})))

netbox.subgraphs.push({
  id: 'aws-vpc',
  label: 'AWS VPC',
  vendor: 'aws',
  service: 'vpc'
})

writeFileSync('merged.json', JSON.stringify(netbox, null, 2))
# Merge and generate diagram
node merge-data.js
npx @shumoku/cli render merged.json -f html -o diagram.html

JSON Schema

See JSON Schema for detailed JSON format.

Integration Examples

CMDB

// Fetch device info from ServiceNow or other CMDB
const cmdbData = await cmdbClient.query('cmdb_ci_netgear')

const nodes = cmdbData.map(ci => ({
  id: ci.sys_id,
  label: ci.name,
  type: mapCmdbClass(ci.sys_class_name),
  metadata: {
    location: ci.location,
    supportGroup: ci.support_group
  }
}))

Monitoring Systems

// From Zabbix, PRTG, Datadog, etc.
const hostGroups = await monitoringClient.getHostGroups()

const subgraphs = hostGroups.map(g => ({
  id: g.id,
  label: g.name
}))

const nodes = await Promise.all(
  hostGroups.flatMap(async g => {
    const hosts = await monitoringClient.getHosts(g.id)
    return hosts.map(h => ({
      id: h.id,
      label: h.name,
      parent: g.id,
      style: h.status === 'up' ? {} : { stroke: 'red' }
    }))
  })
)

Cloud APIs

// AWS SDK
import { EC2Client, DescribeInstancesCommand } from '@aws-sdk/client-ec2'

const ec2 = new EC2Client({ region: 'ap-northeast-1' })
const { Reservations } = await ec2.send(new DescribeInstancesCommand({}))

const nodes = Reservations.flatMap(r =>
  r.Instances.map(i => ({
    id: i.InstanceId,
    label: i.Tags?.find(t => t.Key === 'Name')?.Value || i.InstanceId,
    vendor: 'aws',
    service: 'ec2',
    resource: 'instance',
    parent: i.VpcId
  }))
)

Auto-Update with GitHub Actions

Collect data from multiple sources and update diagrams periodically:

name: Update Network Diagram

on:
  schedule:
    - cron: '0 * * * *'  # Hourly
  workflow_dispatch:

jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Fetch from NetBox
        run: node scripts/fetch-netbox.js > netbox.json
        env:
          NETBOX_URL: ${{ secrets.NETBOX_URL }}
          NETBOX_TOKEN: ${{ secrets.NETBOX_TOKEN }}

      - name: Fetch from monitoring
        run: node scripts/fetch-monitoring.js > monitoring.json

      - name: Merge and render
        run: |
          node scripts/merge-data.js
          npx @shumoku/cli render merged.json -f html -o docs/network.html

      - name: Commit changes
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add docs/network.html
          git commit -m "Update network diagram" || exit 0
          git push

Next Steps

On this page