package resolver import ( "log" "strings" "firewall_containers/network-go/config" ) // Resolver resolves names to IPs using the networks.json configuration type Resolver struct { cfg *config.NetworksConfig retries int } // NewResolver creates a new name resolver backed by the networks.json config func NewResolver(cfg *config.NetworksConfig) *Resolver { return &Resolver{ cfg: cfg, retries: 2, } } // SetConfig updates the config used for name resolution func (r *Resolver) SetConfig(cfg *config.NetworksConfig) { r.cfg = cfg } // SetRetries sets the number of retries for resolution func (r *Resolver) SetRetries(n int) { r.retries = n } // Resolve resolves a name to one or more IP addresses // It looks up the name in the networks.json config by container_name and selector fields func (r *Resolver) Resolve(name string) []string { if r.cfg == nil { return nil } var ips []string // Look up by container_name and selector in the IPs section for _, ipCfg := range r.cfg.IPs { if ipCfg.ContainerName == name || ipCfg.Selector == name { ips = append(ips, ipCfg.IP) } } // If no exact match, try prefix matching: extract the prefix before the first dash // and match any container/selector starting with that prefix. // This allows "wireguardproxy-client" to match "wireguardproxyclient" (after dash stripping) // or "app-1"/"app-2" to match "app-x". if len(ips) == 0 && strings.Contains(name, "-") { prefix := name[:strings.Index(name, "-")] for _, ipCfg := range r.cfg.IPs { if strings.HasPrefix(ipCfg.ContainerName, prefix) || strings.HasPrefix(ipCfg.Selector, prefix) { ips = append(ips, ipCfg.IP) } } } if len(ips) == 0 { log.Printf("RESOLVER: no IP found for %s in networks.json config", name) } return ips }