tools/gcpviz/queries/network-basic.js (93 lines of code) (raw):

/* # Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # */ var containerResourceTypes = [ "cloudresourcemanager.googleapis.com/Organization", "cloudresourcemanager.googleapis.com/Folder", "cloudresourcemanager.googleapis.com/Project", ]; var wantedResourceTypes = [ "compute.googleapis.com/Address", "compute.googleapis.com/Network", "compute.googleapis.com/Subnetwork", "compute.googleapis.com/Router", "compute.googleapis.com/VpnTunnel", "compute.googleapis.com/VpnGateway", "compute.googleapis.com/TargetVpnGateway", "compute.googleapis.com/Interconnect", "compute.googleapis.com/InterconnectAttachment", "dns.googleapis.com/ManagedZone", "dns.googleapis.com/Policy", ]; var resourceTypes = containerResourceTypes.concat(wantedResourceTypes); var nodes = []; var follow = function (n, depth) { var out = n.tag("parent").labelContext(resourceTypes, "type").out("child"); if (out.count() == 0) { return; } nodes = nodes.concat(out.tagArray()); follow(out, depth + 1); }; // Filters disconnected vertexes from results var filterEmptyNodes = function (nodes) { var filteredNodes = []; var m = g.Morphism().labelContext(resourceTypes, "type").in(["child", "uses"]); nodes.forEach(function (node) { if (wantedResourceTypes.indexOf(node.type) > -1) { if (g.V(node.id).follow(m).count() > 0) { filteredNodes.push(node); } } else { filteredNodes.push(node); } }); return filteredNodes; } // Filters empty projects from results var filterEmptyProjects = function (nodes) { var filteredNodes = []; var projectM = g.Morphism().labelContext(resourceTypes, "type").in(["child", "uses"]); nodes.forEach(function (node) { if (node.type == "cloudresourcemanager.googleapis.com/Project") { if (g.V(node.id).follow(projectM).count() > 1) { filteredNodes.push(node); } } else { filteredNodes.push(node); } }); return filteredNodes; } // Filters empty folders from results var filterEmptyFolders = function (nodes) { var folderMap = {}; var folderItemCount = {}; var filteredNodes = []; nodes.forEach(function (node) { if (containerResourceTypes.indexOf(node.type) > -1) { folderMap[node.id] = node; if (node.type == "cloudresourcemanager.googleapis.com/Folder") { folderItemCount[node.id] = 0; } } }); nodes.forEach(function (node) { if (node.type == "cloudresourcemanager.googleapis.com/Project") { var iNode = node; while (iNode && iNode.parent in folderMap) { folderItemCount[iNode.parent] += 1; iNode = folderMap[iNode.parent]; } } }); nodes.forEach(function (node) { if (node.type == "cloudresourcemanager.googleapis.com/Folder") { if (folderItemCount[node.id] > 0) { filteredNodes.push(node); } } else { filteredNodes.push(node); } }); return filteredNodes; } var root = g.V("{{ index .Organizations 0 }}"); follow(root, 1); filterEmptyFolders(filterEmptyProjects(root.tagArray().concat(nodes))).forEach(function (node) { g.emit(node); });