github.com/kiali/kiali@v1.84.0/graph/telemetry/istio/appender/labeler.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  )
     8  
     9  const LabelerAppenderName = "labeler"
    10  
    11  // LabelerAppender is responsible for obtaining and attaching all k8s labels to all nodes in the graph.
    12  // Name: labeler
    13  type LabelerAppender struct{}
    14  
    15  // Name implements Appender
    16  func (f *LabelerAppender) Name() string {
    17  	return LabelerAppenderName
    18  }
    19  
    20  // IsFinalizer implements Appender
    21  func (a LabelerAppender) IsFinalizer() bool {
    22  	return true
    23  }
    24  
    25  // AppendGraph implements Appender
    26  func (f *LabelerAppender) AppendGraph(trafficMap graph.TrafficMap, globalInfo *graph.AppenderGlobalInfo, _namespaceInfo *graph.AppenderNamespaceInfo) {
    27  	if len(trafficMap) == 0 {
    28  		return
    29  	}
    30  
    31  	labelNodes(trafficMap, globalInfo)
    32  }
    33  
    34  // labelNodes puts all k8s labels in the metadata for all nodes.
    35  func labelNodes(trafficMap graph.TrafficMap, gi *graph.AppenderGlobalInfo) {
    36  	// We need to know the names of the Istio labels for app and version because we do not label the nodes with those.
    37  	// There is no need to get the Istio label names multiple times, so get them once now.
    38  	istioLabelNames := config.Get().IstioLabels
    39  
    40  	for _, n := range trafficMap {
    41  		// can't get labels for nodes on the outside or inaccessible nodes, so just go to the next and ignore this one.
    42  		if b, ok := n.Metadata[graph.IsOutside]; ok && b.(bool) {
    43  			continue
    44  		}
    45  		if b, ok := n.Metadata[graph.IsInaccessible]; ok && b.(bool) {
    46  			continue
    47  		}
    48  
    49  		var labelsMetadata graph.LabelsMetadata
    50  
    51  		switch n.NodeType {
    52  		case graph.NodeTypeApp:
    53  			if n.Version != "" {
    54  				// the node is a "versioned-app" node
    55  				if wl, ok := getWorkload(n.Cluster, n.Namespace, n.Workload, gi); ok {
    56  					labelsMetadata = copyMap(wl.Labels)
    57  				} else {
    58  					log.Debugf("Failed to obtain versioned-app details for [%+v]", n)
    59  				}
    60  			} else {
    61  				if app, ok := getApp(n.Namespace, n.App, gi); ok {
    62  					labelsMetadata = copyMap(app.Labels)
    63  				} else {
    64  					log.Debugf("Failed to obtain app details for [%+v]", n)
    65  				}
    66  			}
    67  		case graph.NodeTypeService:
    68  			if svc, ok := getServiceDefinition(n.Cluster, n.Namespace, n.Service, gi); ok {
    69  				labelsMetadata = copyMap(svc.Labels)
    70  			} else {
    71  				log.Debugf("Failed to obtain service details for [%+v]", n)
    72  			}
    73  		case graph.NodeTypeWorkload:
    74  			if wl, ok := getWorkload(n.Cluster, n.Namespace, n.Workload, gi); ok {
    75  				labelsMetadata = copyMap(wl.Labels)
    76  			} else {
    77  				log.Debugf("Failed to obtain workload details for [%+v].", n)
    78  			}
    79  		default:
    80  			// skip any other nodes
    81  		}
    82  
    83  		if len(labelsMetadata) > 0 {
    84  			n.Metadata[graph.Labels] = labelsMetadata
    85  			delete(n.Metadata[graph.Labels].(graph.LabelsMetadata), istioLabelNames.AppLabelName)
    86  			delete(n.Metadata[graph.Labels].(graph.LabelsMetadata), istioLabelNames.VersionLabelName)
    87  		}
    88  	}
    89  }
    90  
    91  func copyMap(orig map[string]string) map[string]string {
    92  	c := make(map[string]string, len(orig))
    93  	for k, v := range orig {
    94  		c[k] = v
    95  	}
    96  	return c
    97  }