github.com/kiali/kiali@v1.84.0/graph/telemetry/istio/appender/mesh_check.go (about)

     1  package appender
     2  
     3  import (
     4  	"github.com/kiali/kiali/config"
     5  	"github.com/kiali/kiali/graph"
     6  )
     7  
     8  const MeshCheckAppenderName = "meshCheck"
     9  const SidecarsCheckAppenderName = "sidecarsCheck"
    10  
    11  // MeshCheckAppender flags nodes whose backing workloads are missing at least one Envoy sidecar. Note that
    12  // a node with no backing workloads is not flagged.
    13  // Name: meshCheck
    14  type MeshCheckAppender struct {
    15  	AccessibleNamespaces graph.AccessibleNamespaces
    16  }
    17  
    18  // Name implements Appender
    19  func (a MeshCheckAppender) Name() string {
    20  	return MeshCheckAppenderName
    21  }
    22  
    23  // IsFinalizer implements Appender
    24  func (a MeshCheckAppender) IsFinalizer() bool {
    25  	return false
    26  }
    27  
    28  // AppendGraph implements Appender
    29  func (a MeshCheckAppender) AppendGraph(trafficMap graph.TrafficMap, globalInfo *graph.AppenderGlobalInfo, namespaceInfo *graph.AppenderNamespaceInfo) {
    30  	if len(trafficMap) == 0 {
    31  		return
    32  	}
    33  
    34  	a.applyMeshChecks(trafficMap, globalInfo, namespaceInfo)
    35  }
    36  
    37  func (a *MeshCheckAppender) applyMeshChecks(trafficMap graph.TrafficMap, globalInfo *graph.AppenderGlobalInfo, namespaceInfo *graph.AppenderNamespaceInfo) {
    38  	for _, n := range trafficMap {
    39  		// skip if we've already determined the node is out-of-mesh. we may process the same
    40  		// node multiple times to ensure we check every node (e.g. missing sidecars indicate missing
    41  		// telemetry and so we need to check nodes when we can, regardless of namespace)
    42  		if n.Metadata[graph.IsOutOfMesh] == true {
    43  			continue
    44  		}
    45  
    46  		// skip if the node is not in an accessible namespace, we can't do the checking
    47  		if !a.nodeOK(n) {
    48  			continue
    49  		}
    50  
    51  		// We whitelist istio components because they may not report telemetry using injected sidecars.
    52  		if config.IsIstioNamespace(n.Namespace) {
    53  			continue
    54  		}
    55  
    56  		// dead nodes tell no tales (er, have no pods)
    57  		if isDead, ok := n.Metadata[graph.IsDead]; ok && isDead.(bool) {
    58  			continue
    59  		}
    60  
    61  		// get the workloads for the node and check to see if they have sidecars. Note that
    62  		// if there are no workloads/pods we don't flag it as missing sidecars.  No pods means
    63  		// no missing sidecars.  (In most cases this means it was flagged as dead, and handled above)
    64  		hasIstioSidecar := true
    65  		hasIstioAmbient := true
    66  		switch n.NodeType {
    67  		case graph.NodeTypeWorkload:
    68  			if workload, found := getWorkload(n.Cluster, n.Namespace, n.Workload, globalInfo); found {
    69  				hasIstioSidecar = workload.IstioSidecar
    70  				hasIstioAmbient = workload.IstioAmbient
    71  			}
    72  		case graph.NodeTypeApp:
    73  			workloads := getAppWorkloads(n.Cluster, n.Namespace, n.App, n.Version, globalInfo)
    74  			if len(workloads) > 0 {
    75  				for _, workload := range workloads {
    76  					if !workload.IstioSidecar {
    77  						hasIstioSidecar = false
    78  					}
    79  					if !workload.IstioAmbient {
    80  						hasIstioAmbient = false
    81  					}
    82  					if !hasIstioSidecar && !hasIstioAmbient {
    83  						break
    84  					}
    85  				}
    86  			}
    87  		default:
    88  			continue
    89  		}
    90  
    91  		if !hasIstioSidecar && !hasIstioAmbient && n.Metadata[graph.IsWaypoint] != true {
    92  			n.Metadata[graph.IsOutOfMesh] = true
    93  		}
    94  
    95  	}
    96  }
    97  
    98  // nodeOK returns true if we have access to its workload info
    99  func (a *MeshCheckAppender) nodeOK(node *graph.Node) bool {
   100  	key := graph.GetClusterSensitiveKey(node.Cluster, node.Namespace)
   101  	_, ok := a.AccessibleNamespaces[key]
   102  	return ok
   103  }