package resolution import ( "fmt" "sort" "strings" mcat "git.novox.be/novox/mesh-sdk/go/catalogue" ) // ZoneOn is one module's zone as one node places it: the name settled from the node's settings, the // port its answering listen is published on there. Nothing when the module declares no zone. func ZoneOn(m mcat.Manifest, layers []mcat.Layer, published map[int]int, node, address string) (*mcat.ZoneAt, error) { if m.Zone == nil { return nil, nil } settled, err := Settle(map[string]any{"zone": m.Zone.Name}, layers) if err != nil { return nil, fmt.Errorf("%s's zone on %s: %w", m.Module, node, err) } zone := strings.Trim(strings.ToLower(fmt.Sprint(settled["zone"])), ".") var port int for _, l := range m.Listens { if l.Name == m.Zone.Listen { port = l.Port if at, given := published[l.Port]; given { port = at } } } return &mcat.ZoneAt{Zone: zone, Node: node, Module: m.Module, Address: address, Port: port}, nil } // ZonesProblems is what the mesh refuses about its zones together: one zone declared twice, a zone // that is the mesh's suffix or under it, a zone that is a node's public domain or under one. A module // may not shadow names the mesh's resolver or the public DNS answers. func ZonesProblems(zones []mcat.ZoneAt, suffix string, publicDomains []string) []string { var problems []string under := func(zone, domain string) bool { domain = strings.Trim(strings.ToLower(domain), ".") return domain != "" && (zone == domain || strings.HasSuffix(zone, "."+domain)) } seen := map[string]mcat.ZoneAt{} for _, z := range zones { if other, twice := seen[z.Zone]; twice && (other.Node != z.Node || other.Module != z.Module) { problems = append(problems, fmt.Sprintf("zone %q is declared by %s on %s and by %s on %s; one module answers a zone", z.Zone, other.Module, other.Node, z.Module, z.Node)) } seen[z.Zone] = z if under(z.Zone, suffix) { problems = append(problems, fmt.Sprintf("%s on %s declares zone %q, which is the mesh's own suffix or under it", z.Module, z.Node, z.Zone)) } for _, d := range publicDomains { if under(z.Zone, d) { problems = append(problems, fmt.Sprintf("%s on %s declares zone %q, which is the public domain %q or under it", z.Module, z.Node, z.Zone, d)) } } } sort.Strings(problems) return problems }