consul/testing/deployer/topology/relationships.go

93 lines
1.9 KiB
Go

// 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
// downstream/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 _, s := range n.Services {
for _, u := range s.Upstreams {
out = append(out, Relationship{
Caller: s,
Upstream: u,
})
}
for _, u := range s.ImpliedUpstreams {
out = append(out, Relationship{
Caller: s,
Upstream: u,
})
}
}
}
}
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, "DOWN\tnode\tservice\tport\tUP\tservice\t\n")
for _, r := range ships {
suffix := ""
if r.Upstream.Implied {
suffix = " (implied)"
}
fmt.Fprintf(w,
"%s\t%s\t%s\t%d\t%s\t%s\t\n",
r.downCluster(),
r.Caller.Node.ID().String(),
r.Caller.ID.String(),
r.Upstream.LocalPort,
r.upCluster(),
r.Upstream.ID.String()+suffix,
)
}
fmt.Fprintf(w, "\t\t\t\t\t\t\n")
w.Flush()
return buf.String()
}
type Relationship struct {
Caller *Service
Upstream *Upstream
}
func (r Relationship) String() string {
suffix := ""
if r.Upstream.PortName != "" {
suffix = " port " + r.Upstream.PortName
}
return fmt.Sprintf(
"%s on %s in %s via :%d => %s in %s%s",
r.Caller.ID.String(),
r.Caller.Node.ID().String(),
r.downCluster(),
r.Upstream.LocalPort,
r.Upstream.ID.String(),
r.upCluster(),
suffix,
)
}
func (r Relationship) downCluster() string {
return r.Caller.Node.Cluster
}
func (r Relationship) upCluster() string {
return r.Upstream.Cluster
}