package host import ( "fmt" "net" "strings" "git.giaever.org/joachimmg/go-log.git/log" "git.giaever.org/joachimmg/m-dns/errors" ) type Host interface { GetInstance() Instance GetService() Service GetDomain() Domain GetHostname() Hostname GetIPs() []HostIP GetPort() HostPort GetTXTs() []string GetServiceAddr() HostString GetInstanceAddr() HostString GetHostnameAddr() HostString GetDiscoveryAddr() HostString String() string } type host struct { instance Instance service Service domain Domain hostname Hostname ip []HostIP port HostPort txt []TXT } func New(instance, service, domain, hostname string, ip []net.IP, port int, txt []string) (Host, error) { h := new(host) if h == nil { log.Traceln(errors.Host, errors.OutOfMemory) return nil, errors.OutOfMemory } var err error if h.instance, err = String(instance).IsInstanceVariable(); err != nil { return nil, err } if h.service, err = String(service).IsServiceVariable(); err != nil { return nil, err } if h.domain, err = String(domain).IsDomainVariable(); err != nil { return nil, err } if h.hostname, err = String(hostname).IsHostnameVariable(); err != nil { return nil, err } for _, _ip := range ip { if hip, err := IP(_ip).validForHostname(h.hostname); err == nil { h.ip = append(h.ip, hip) } } if len(h.ip) == 0 { addrs, err := net.InterfaceAddrs() if err != nil { log.Traceln(errors.Host, err) return nil, err } for _, addr := range addrs { ip := strings.SplitN(addr.String(), "/", 2) if len(ip) >= 1 { if hip, err := IP(net.ParseIP(ip[0])).validForHostname(h.GetHostname()); err == nil { h.ip = append(h.ip, hip) } } } } if err := Port(port).isValid(); err != nil { return nil, err } h.port = Port(port) for _, t := range txt { ht, err := String(t).IsTxtVariable() if err != nil { return nil, err } else if !ht.Empty() { // Silently ignore empty txt entries h.txt = append(h.txt, ht) } } return h, nil } func (h *host) GetInstance() Instance { return h.instance } func (h *host) GetService() Service { return h.service } func (h *host) GetDomain() Domain { return h.domain } func (h *host) GetHostname() Hostname { return h.hostname } func (h *host) GetIPs() []HostIP { return h.ip } func (h *host) HasIPs() bool { if len(h.GetIPs()) == 0 { return false } for _, ip := range h.GetIPs() { if _, t := ip.Type(); t == IPv4 || t == IPv6 { return true } } return false } func (h *host) GetPort() HostPort { return h.port } func (h *host) GetTXTs() []string { s := []string{} for _, t := range h.txt { s = append(s, t.String()) } return s } func (h *host) GetServiceAddr() HostString { return h.GetService().ServiceAddr(h.GetDomain()) } func (h *host) GetInstanceAddr() HostString { return h.GetInstance().InstanceAddr(h.GetService(), h.GetDomain()) } func (h *host) GetHostnameAddr() HostString { return h.GetHostname().HostnameAddr(h.GetDomain()) } func (h *host) GetDiscoveryAddr() HostString { return h.GetDomain().DiscoveryAddr() } func (h *host) String() string { ips := []string{} for _, ip := range h.GetIPs() { ips = append(ips, ip.String()) } return fmt.Sprintf(` Host: %s + Instance: %s + Service: %s + Domain: %s + IP(s): * %s + Port: %d + Txt(s): * %s Addr: + Instance: %s + Service: %s + Discovery: %s Service-protocol: %s`, h.GetHostname(), h.GetInstance(), h.GetService(), h.GetDomain(), strings.Join(ips, "\n\t\t* "), h.port, strings.Join(h.GetTXTs(), "\n\t\t* "), h.GetInstanceAddr(), h.GetServiceAddr(), h.GetDiscoveryAddr(), h.GetService().RootType()[1:], ) }