Select Git revision
service.go 2.37 KiB
package graph
import (
"strings"
floatschema "git.autistici.org/ai3/tools/float-dashboard/schema/float"
)
// ServiceGraph extracts a service dependency graph from a float schema.
func ServiceGraph(services map[string]*floatschema.Service) *Graph {
g := NewGraph()
// Create all nodes first.
for svcname, s := range services {
pelists := [][]floatschema.PublicEndpoint{s.PublicEndpoints, s.PublicTCPEndpoints}
for _, pelist := range pelists {
for _, pe := range pelist {
name := pe.Name
if name == "" {
name = pe.Domains[0]
}
g.addNode(newWebNode(name, svcname))
}
}
for _, c := range s.Containers {
g.addNode(NewNode(mkTag(c.Name, svcname), svcname))
}
for _, sv := range s.SystemdServices {
if strings.HasPrefix(sv, "docker-") {
continue
}
name := strings.TrimSuffix(sv, ".service")
g.addNode(NewNode(mkTag(name, svcname), svcname))
}
}
// Now add all edges.
for svcname, s := range services {
pelists := [][]floatschema.PublicEndpoint{s.PublicEndpoints, s.PublicTCPEndpoints}
for _, pelist := range pelists {
for _, pe := range pelist {
name := pe.Name
if name == "" {
name = pe.Domains[0]
}
g.addEdge(INTERNET, name)
// Match the port with a container, if possible, or
// fall back to the first systemd unit defined for the
// service.
if c := findContainerByPort(s, pe.Port); c != nil {
g.addEdge(name, mkTag(c.Name, svcname))
} else if unitName, ok := findFirstRealSystemdService(s); ok {
g.addEdge(name, mkTag(unitName, svcname))
}
}
}
for _, d := range s.Annotations.Dependencies {
g.addEdge(nodeNameFromDep(d.Client, svcname),
nodeNameFromDep(d.Server, svcname))
}
}
return g
}
func nodeNameFromDep(name, svcname string) string {
if strings.Contains(name, "/") {
return name
}