Skip to content
Snippets Groups Projects
Select Git revision
  • 6b724c8fce31d5e70eae4eacc1a7d32b3e73b6a7
  • noblogs default
  • noblogs-5.7.1
  • upstream
  • noblogs-5.7
  • noblogs-5.6new
  • upstream5.5.1
  • noblogs28dic
  • upstream28dic
  • noblogs-5.5.1
  • noblogs-5.4.2
  • noblogs-5.4_seconda
  • noblogs-5.4
  • noblogs-7c
  • wp5.2.3p3
  • mergedbconf
  • noblogs-5.7.1
  • noblogs.5.7.0p1
  • noblogs-5.7.0
  • noblogs-5.6p3
  • noblogs5.6p2
  • noblogs-5.6p1
  • noblogs-5.6
  • noblogs-5.4.2p1
  • noblogs-5.4.2
  • noblogs-5.4.1
  • noblogs-5.4
  • noblogs-p5.4
  • noblogs-5.3.2p2
  • noblogs-5.3.2p1
  • noblogs-5.3.2
  • noblogs-5.3
  • noblogs-5.2.3p4
  • noblogs-5.2.3p3
  • noblogs-5.2.3p2
  • noblogs-5.2.3p1
36 results

edit-comments.js

Blame
  • 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
    	}
    	return mkTag(name, svcname)
    }
    
    func findContainerByPort(service *floatschema.Service, port int) *floatschema.Container {
    	for i := 0; i < len(service.Containers); i++ {
    		c := &service.Containers[i]
    		if c.Port > 0 && c.Port == port {
    			return c
    		}
    		for _, p := range c.Ports {
    			if p == port {
    				return c
    			}
    		}
    	}
    	return nil
    }
    
    func findFirstRealSystemdService(service *floatschema.Service) (string, bool) {
    	for _, s := range service.SystemdServices {
    		if !strings.HasPrefix(s, "docker-") {
    			return strings.TrimSuffix(s, ".service"), true
    		}
    	}
    	return "", false
    }