// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package topology
import (
"bytes"
"fmt"
"text/tabwriter"
)
// ComputeRelationships will analyze a full topology and generate all of the
// caller/upstream information for all of them.
func ( t * Topology ) ComputeRelationships ( ) [ ] Relationship {
var out [ ] Relationship
for _ , cluster := range t . Clusters {
for _ , n := range cluster . Nodes {
for _ , w := range n . Workloads {
for _ , us := range w . Upstreams {
out = append ( out , Relationship {
Caller : w ,
Upstream : us ,
} )
}
}
}
}
return out
}
// RenderRelationships will take the output of ComputeRelationships and display
// it in tabular form.
func RenderRelationships ( ships [ ] Relationship ) string {
var buf bytes . Buffer
w := tabwriter . NewWriter ( & buf , 0 , 0 , 3 , ' ' , tabwriter . Debug )
fmt . Fprintf ( w , "CALLER\tnode\tservice\tport\tDEST\tservice\t\n" )
for _ , r := range ships {
fmt . Fprintf ( w ,
"%s\t%s\t%s\t%d\t%s\t%s\t\n" ,
r . callingCluster ( ) ,
r . Caller . Node . ID ( ) . String ( ) ,
r . Caller . ID . String ( ) ,
r . Upstream . LocalPort ,
r . upstreamCluster ( ) ,
r . Upstream . ID . String ( ) ,
)
}
fmt . Fprintf ( w , "\t\t\t\t\t\t\n" )
w . Flush ( )
return buf . String ( )
}
type Relationship struct {
Caller * Workload
Upstream * Upstream
}
func ( r Relationship ) String ( ) string {
return fmt . Sprintf (
"%s on %s in %s via :%d => %s in %s" ,
r . Caller . ID . String ( ) ,
r . Caller . Node . ID ( ) . String ( ) ,
r . callingCluster ( ) ,
r . Upstream . LocalPort ,
r . Upstream . ID . String ( ) ,
r . upstreamCluster ( ) ,
)
}
func ( r Relationship ) callingCluster ( ) string {
return r . Caller . Node . Cluster
}
func ( r Relationship ) upstreamCluster ( ) string {
return r . Upstream . Cluster
}