jQuery(document).ready(function($) { "use strict"; function NetBox() { this.url = "http://netbox.alpin.pw/api"; this.endpoints = { circuits: [ "providers", "circuit-types", "circuits", "circuits-termination" ], dcim: [ "regions", "sites", "rack-groups", "rack-roles", "racks", "rack-reservations", "manufacturers", "device-types", "console-port-templates", "console-server-port-templates", "power-port-templates", "power-outlet-templates", "interface-templates", "device-bay-templates", "device-roles", "platforms", "devices", "console-ports", "console-server-ports", "power-ports", "power-outlets", "interfaces", "device-bays", "inventory-items", "console-connections", "power-connections", "interface-connections", "virtual-chassis", "connected-device" ], extras: [ "graphs", "export-termplates", "topology-maps", "tags", "image-attachments", "config-contexts", "reports", "object-changes", "recent-activity" ], ipam: [ "vrfs", "rirs", "aggregates", "roles", "prefixes", "ip-addresses", "vlan-groups", "vlans", "services" ], secrets: [ "secret-roles", "secrets", "get-session-key", "generate-rsa-key-pair" ], tenancy: [ "tenant-groups", "tenants" ], virtualization: [ "cluster-types", "cluster-groups", "clusters", "virtual-machines", "interfaces" ] }; } NetBox.prototype.visjs_data = function(cb) { this.pull("virtualization", "virtual-machines", function(r_vms) { let vms = r_vms.results, clusters = Array.from(new Set(vms.map(x => x.cluster.name))), nodes = [], edges = []; // add virtual machines to the list of nodes vms.forEach(function(el, idx) { nodes.push({ id: el.name, label: el.name, group: "virtual_machines", _cluster: el.cluster.name }); }); // add clusters to the list of nodes clusters.forEach(function(el, idx) { nodes.push({ id: el, label: el, group: "clusters" }); }); // add edges between all non-cluster nodes nodes .filter(x => x.group !== "clusters") .forEach(function(node) { if (node._cluster) { edges.push({ from: node.id, to: node._cluster }); } }); // filter out all netbox clusters from the list of nodes let t_nodes = nodes.filter(x => x.group === "clusters"); // make edges between all but the first and last nodes t_nodes.forEach(function(node, idx) { if (idx !== t_nodes.length - 1) { edges.push({ from: node.id, to: t_nodes[idx + 1].id, color: { color: "#FF851B" } }); } }); // last link edges.push({ from: t_nodes[0].id, to: t_nodes[t_nodes.length - 1].id, color: { color: "#FF851B" } }); cb({ nodes: nodes, edges: edges }); }); } NetBox.prototype.pull = function(category, item, cb) { if (!Object.keys(this.endpoints).includes(category)) { throw new Error(`the category '${category}' is not in the list ` + "of allowed categories"); } if (!Object.values(this.endpoints[category]).includes(item)) { throw new Error(`the item '${item}' is not in the list of ` + "allowed endpoints"); } $.ajax({ url: `${this.url}/${category}/${item}/`, data: { format: "json", limit: 1000 }, success: function(data) { cb(data); } }); } let nb = new NetBox(); nb.visjs_data(function(data) { let container = document.getElementById("network"), options = { nodes: { shape: 'dot', size: 20, font: { size: 15, color: '#ffffff' }, borderWidth: 2 }, edges: { width: 2 }, groups: { virtual_machines: { shape: "icon", icon: { face: "FontAwesome", code: "\uF233", color: "#0074D9" } }, clusters: { shape: "icon", icon: { face: "FontAwesome", code: "\uF0C2", color: "#FF851B" } } } }, network = new vis.Network(container, data, options); }); });