github.com/kiali/kiali@v1.84.0/graph/telemetry/istio/appender/idle_node.go (about) 1 package appender 2 3 import ( 4 "github.com/kiali/kiali/config" 5 "github.com/kiali/kiali/graph" 6 "github.com/kiali/kiali/log" 7 "github.com/kiali/kiali/models" 8 ) 9 10 const IdleNodeAppenderName = "idleNode" 11 12 // IdleNodeAppender looks for services that have never seen request traffic. It adds nodes to represent the 13 // idle/unused definitions. The added node types depend on the graph type and/or labeling on the definition. 14 // Name: idleNode 15 type IdleNodeAppender struct { 16 GraphType string 17 InjectServiceNodes bool // This appender adds idle services only when service nodes are injected or graphType=service 18 IsNodeGraph bool // This appender does not operate on node detail graphs because we want to focus on the specific node. 19 } 20 21 // Name implements Appender 22 func (a IdleNodeAppender) Name() string { 23 return IdleNodeAppenderName 24 } 25 26 // IsFinalizer implements Appender 27 func (a IdleNodeAppender) IsFinalizer() bool { 28 return false 29 } 30 31 // AppendGraph implements Appender 32 func (a IdleNodeAppender) AppendGraph(trafficMap graph.TrafficMap, globalInfo *graph.AppenderGlobalInfo, namespaceInfo *graph.AppenderNamespaceInfo) { 33 if a.IsNodeGraph { 34 return 35 } 36 37 serviceLists := map[string]*models.ServiceList{} 38 workloadLists := map[string]*models.WorkloadList{} 39 40 if a.GraphType != graph.GraphTypeService { 41 workloadLists = getWorkloadLists(nil, namespaceInfo.Namespace, globalInfo) 42 } 43 44 if a.GraphType == graph.GraphTypeService || a.InjectServiceNodes { 45 serviceLists = getServiceLists(nil, namespaceInfo.Namespace, globalInfo) 46 } 47 48 a.addIdleNodes(trafficMap, namespaceInfo.Namespace, serviceLists, workloadLists) 49 } 50 51 func (a IdleNodeAppender) addIdleNodes(trafficMap graph.TrafficMap, namespace string, serviceLists map[string]*models.ServiceList, workloadLists map[string]*models.WorkloadList) { 52 idleNodeTrafficMap := a.buildIdleNodeTrafficMap(trafficMap, namespace, serviceLists, workloadLists) 53 54 // Integrate the idle nodes into the existing traffic map 55 for id, idleNode := range idleNodeTrafficMap { 56 trafficMap[id] = idleNode 57 } 58 } 59 60 func (a IdleNodeAppender) buildIdleNodeTrafficMap(trafficMap graph.TrafficMap, namespace string, serviceLists map[string]*models.ServiceList, workloadLists map[string]*models.WorkloadList) graph.TrafficMap { 61 idleNodeTrafficMap := graph.NewTrafficMap() 62 63 for cluster, serviceList := range serviceLists { 64 for _, s := range serviceList.Services { 65 id, nodeType, _ := graph.Id(cluster, namespace, s.Name, "", "", "", "", a.GraphType) 66 if _, found := trafficMap[id]; !found { 67 if _, found = idleNodeTrafficMap[id]; !found { 68 log.Tracef("Adding idle node for service [%s]", s.Name) 69 node := graph.NewNodeExplicit(id, cluster, namespace, "", "", "", s.Name, nodeType, a.GraphType) 70 // note: we don't know what the protocol really should be, http is most common, it's a dead edge anyway 71 node.Metadata = graph.Metadata{"httpIn": 0.0, "httpOut": 0.0, graph.IsIdle: true} 72 idleNodeTrafficMap[id] = node 73 } 74 } 75 } 76 77 cfg := config.Get() 78 appLabel := cfg.IstioLabels.AppLabelName 79 versionLabel := cfg.IstioLabels.VersionLabelName 80 if workloadList, ok := workloadLists[cluster]; ok { 81 for _, w := range workloadList.Workloads { 82 labels := w.Labels 83 app := graph.Unknown 84 version := graph.Unknown 85 if v, ok := labels[appLabel]; ok { 86 app = v 87 } 88 if v, ok := labels[versionLabel]; ok { 89 version = v 90 } 91 id, nodeType, _ := graph.Id(cluster, "", "", namespace, w.Name, app, version, a.GraphType) 92 if _, found := trafficMap[id]; !found { 93 if _, found = idleNodeTrafficMap[id]; !found { 94 log.Tracef("Adding idle node for workload [%s] with labels [%v]", w.Name, labels) 95 node := graph.NewNodeExplicit(id, cluster, namespace, w.Name, app, version, "", nodeType, a.GraphType) 96 // note: we don't know what the protocol really should be, http is most common, it's a dead edge anyway 97 node.Metadata = graph.Metadata{"httpIn": 0.0, "httpOut": 0.0, graph.IsIdle: true} 98 idleNodeTrafficMap[id] = node 99 } 100 } 101 } 102 } 103 } 104 return idleNodeTrafficMap 105 }