From f9da55e8a9d4fa6ca54984170fe647248185e266 Mon Sep 17 00:00:00 2001 From: Asim Aslam Date: Mon, 7 Jan 2019 07:41:26 +0000 Subject: [PATCH 1/2] Add dns selector --- cmd/cmd.go | 2 + selector/dns/dns.go | 100 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 selector/dns/dns.go diff --git a/cmd/cmd.go b/cmd/cmd.go index 7d41b452..5793b48f 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -26,6 +26,7 @@ import ( // selectors "github.com/micro/go-micro/selector" + "github.com/micro/go-micro/selector/dns" // transports "github.com/micro/go-micro/transport" @@ -177,6 +178,7 @@ var ( DefaultSelectors = map[string]func(...selector.Option) selector.Selector{ "default": selector.NewSelector, + "dns": dns.NewSelector, "cache": selector.NewSelector, } diff --git a/selector/dns/dns.go b/selector/dns/dns.go new file mode 100644 index 00000000..05f493cc --- /dev/null +++ b/selector/dns/dns.go @@ -0,0 +1,100 @@ +// Package dns provides a dns SRV selector +package dns + +import ( + "net" + + "github.com/micro/go-micro/registry" + "github.com/micro/go-micro/selector" +) + +type dnsSelector struct { + options selector.Options + domain string +} + +var ( + DefaultDomain = "local" +) + +func (d *dnsSelector) Init(opts ...selector.Option) error { + for _, o := range opts { + o(&d.options) + } + return nil +} + +func (d *dnsSelector) Options() selector.Options { + return d.options +} + +func (d *dnsSelector) Select(service string, opts ...selector.SelectOption) (selector.Next, error) { + _, srv, err := net.LookupSRV(service, "tcp", d.domain) + if err != nil { + return nil, err + } + + var nodes []*registry.Node + for _, node := range srv { + nodes = append(nodes, ®istry.Node{ + Id: node.Target, + Address: node.Target, + Port: int(node.Port), + }) + } + + services := []*registry.Service{ + ®istry.Service{ + Name: service, + Nodes: nodes, + }, + } + + sopts := selector.SelectOptions{ + Strategy: d.options.Strategy, + } + + for _, opt := range opts { + opt(&sopts) + } + + // apply the filters + for _, filter := range sopts.Filters { + services = filter(services) + } + + // if there's nothing left, return + if len(services) == 0 { + return nil, selector.ErrNoneAvailable + } + + return sopts.Strategy(services), nil +} + +func (d *dnsSelector) Mark(service string, node *registry.Node, err error) { + return +} + +func (d *dnsSelector) Reset(service string) { + return +} + +func (d *dnsSelector) Close() error { + return nil +} + +func (d *dnsSelector) String() string { + return "dns" +} + +func NewSelector(opts ...selector.Option) selector.Selector { + options := selector.Options{ + Strategy: selector.Random, + } + + for _, o := range opts { + o(&options) + } + + return &dnsSelector{options: options, domain: DefaultDomain} +} From d6a5ff432cf3df2db63a00e28d1875c86138e843 Mon Sep 17 00:00:00 2001 From: Asim Aslam Date: Mon, 7 Jan 2019 09:34:07 +0000 Subject: [PATCH 2/2] add net.LookupHost for dns --- selector/dns/dns.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/selector/dns/dns.go b/selector/dns/dns.go index 05f493cc..d3882ac1 100644 --- a/selector/dns/dns.go +++ b/selector/dns/dns.go @@ -3,6 +3,7 @@ package dns import ( "net" + "strconv" "github.com/micro/go-micro/registry" "github.com/micro/go-micro/selector" @@ -29,9 +30,36 @@ func (d *dnsSelector) Options() selector.Options { } func (d *dnsSelector) Select(service string, opts ...selector.SelectOption) (selector.Next, error) { - _, srv, err := net.LookupSRV(service, "tcp", d.domain) + var srv []*net.SRV + + // check if its host:port + host, port, err := net.SplitHostPort(service) + // not host:port if err != nil { - return nil, err + // lookup the SRV record + _, srvs, err := net.LookupSRV(service, "tcp", d.domain) + if err != nil { + return nil, err + } + // set SRV records + srv = srvs + // got host:port + } else { + p, _ := strconv.Atoi(port) + + // lookup the A record + ips, err := net.LookupHost(host) + if err != nil { + return nil, err + } + + // create SRV records + for _, ip := range ips { + srv = append(srv, &net.SRV{ + Target: ip, + Port: uint16(p), + }) + } } var nodes []*registry.Node