@kinvolk/headlamp-plugin
Version:
The needed infrastructure for building Headlamp plugins.
135 lines (134 loc) • 4.17 kB
JavaScript
/*
* Copyright 2025 The Kubernetes Authors
*
* 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.
*/
/**
* Iterates graph, breadth first
*/
export function forEachNode(graph, cb) {
cb(graph);
graph.nodes?.forEach(it => forEachNode(it, cb));
}
/**
* Deduplicates graph nodes and edges by ID.
*
* When duplicate nodes or edges are found, the first graph element is preserved.
*
* @param nodes - list of graph Nodes
* @param edges - list of graph Edges
* @returns graph elements with unique node and edge IDs
*/
export function deduplicateGraphElements(nodes, edges) {
return {
nodes: deduplicateGraphNodes(nodes),
edges: deduplicateGraphEdges(edges),
};
}
/**
* Deduplicates graph nodes by ID, preserving the first node for each ID.
*
* @param nodes - list of graph Nodes
* @returns graph Nodes with unique IDs
*/
function deduplicateGraphNodes(nodes) {
const nodesById = new Map();
nodes.forEach(node => {
if (!nodesById.has(node.id)) {
nodesById.set(node.id, node);
}
});
return Array.from(nodesById.values());
}
/**
* Deduplicates graph edges by ID, preserving the first edge for each ID.
*
* @param edges - list of graph Edges
* @returns graph Edges with unique IDs
*/
export function deduplicateGraphEdges(edges) {
const edgesById = new Map();
edges.forEach(edge => {
if (!edgesById.has(edge.id)) {
edgesById.set(edge.id, edge);
}
});
return Array.from(edgesById.values());
}
/**
* Default node weight assignments for different Kubernetes resource types.
* Higher weight = higher priority/importance in graph layout.
*/
const DEFAULT_NODE_WEIGHTS = {
// Tier 1: Top-Level Orchestration & Scaling
HorizontalPodAutoscaler: 1000,
// Tier 2: Primary Workload Controllers
Deployment: 980,
StatefulSet: 960,
DaemonSet: 960,
// Tier 3: Job-based Workloads
CronJob: 960,
JobSet: 960,
Job: 920,
// Tier 4: Intermediate Controllers
ReplicaSet: 960,
// Tier 5: Core Runtime & Direct Dependencies
Pod: 800,
// All resources directly connected to Pod at the same level
ServiceAccount: 960,
Role: 790,
ClusterRole: 790,
Service: 790,
NetworkPolicy: 790,
PersistentVolumeClaim: 790,
ConfigMap: 790,
Secret: 790,
// Tier 6: Supporting Resources
// Network supporting resources (cascading from Service/NetworkPolicy)
Endpoints: 780,
EndpointSlice: 780,
MutatingWebhookConfiguration: 780,
ValidatingWebhookConfiguration: 780,
IngressClass: 780,
Ingress: 780,
// RBAC supporting resources (cascading from ServiceAccount/Role/ClusterRole)
RoleBinding: 800,
ClusterRoleBinding: 800,
// Storage supporting resources (cascading from PVC)
StorageClass: 770,
CSIDriver: 760,
PersistentVolume: 750,
// Tier 7: Meta-definitions & Extensions
CustomResourceDefinition: 600,
// Default for unspecified resources
default: 500,
};
/**
* Gets the effective weight of a node, considering both explicit weight
* and default weights based on Kubernetes resource type.
*
* @param node - The GraphNode to get weight for
* @returns The effective weight (higher = more important)
*/
export function getNodeWeight(node) {
// if explicit weight is set, use it
if (node.weight !== undefined) {
return node.weight;
}
// otherwise, use default weight based on Kubernetes resource kind
const kind = node.kubeObject?.kind;
if (kind && kind in DEFAULT_NODE_WEIGHTS) {
return DEFAULT_NODE_WEIGHTS[kind];
}
return DEFAULT_NODE_WEIGHTS.default;
}