Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request to add DNS server implementation for sidecar #328

Merged
merged 27 commits into from
Nov 2, 2016
Merged
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8e00c22
Added miekg/dns package to vendor
tomerGolany Sep 29, 2016
eea6343
Added DNS server implementation
tomerGolany Oct 6, 2016
d11c171
Added configurations for dns server
tomerGolany Oct 5, 2016
2d82883
fixed rejects from code review with Zvi, for DNS server configuraions
tomerGolany Oct 9, 2016
965ac9c
Fixed rejects from code review with Zvi, for DNS server implementation
tomerGolany Oct 9, 2016
0346ee5
Fixed rejects from code review with Zvi, for adding dns server to sid…
tomerGolany Oct 9, 2016
aee1751
Fixed confilcts on sidecar/config/flags.go and glie.yaml
tomerGolany Oct 13, 2016
78b4aff
Added implementation of registry monitor for the DNS server queries
tomerGolany Oct 13, 2016
f039e24
Fixed rejects from pull request of DNS server implementation
tomerGolany Oct 13, 2016
ae12a7d
Fixed formatting
tomerGolany Oct 13, 2016
e15cecd
Removed Comment
tomerGolany Oct 20, 2016
69cf771
Merge branch 'master' of github.com:amalgam8/amalgam8
tomerGolany Oct 20, 2016
8822193
Fixed conflicts
tomerGolany Oct 27, 2016
ab93fd6
Added implementation to support SRV records
tomerGolany Oct 27, 2016
abc3094
SRV implementation
tomerGolany Oct 27, 2016
7aeb0b4
Fixed rejects from Zvi after implementing support for SRV records
tomerGolany Oct 30, 2016
7ae0355
Resolved confilcts
tomerGolany Oct 30, 2016
fe2e8b2
Fixed more rejects from Zvi
tomerGolany Oct 31, 2016
9842da4
Fixed conflicts and reduced sleep time of dns server test
tomerGolany Oct 31, 2016
a9393e1
fix and refactor registry monitor
zcahana Nov 1, 2016
ce956ec
fix dns ip/port parsing
zcahana Nov 1, 2016
18fa860
use weight=priority=0 for SRV records
zcahana Nov 1, 2016
dbf701d
randomize returned dns records
zcahana Nov 1, 2016
2dd1632
update dns server query format
zcahana Nov 2, 2016
4265f3e
update dns server unit tests
zcahana Nov 2, 2016
a3302c6
Merge branch 'master' into master
zcahana Nov 2, 2016
e7a9c8c
fix A record names returned for SRV queries
zcahana Nov 2, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions sidecar/dns/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,13 @@ func (s *Server) handleQuestion(question dns.Question, request, response *dns.Ms
if err != nil {
return err
}

err = s.findMatchingServices(question, request, response, serviceInstances)
err = s.createRecordsForInstances(question, request, response, serviceInstances)
return err

}

func (s *Server) retrieveServices(question dns.Question, request, response *dns.Msg) ([]*client.ServiceInstance, error) {
var ServiceInstances []*client.ServiceInstance
var serviceInstances []*client.ServiceInstance
var err error
// parse query :
// Query format:
Expand Down Expand Up @@ -172,22 +171,21 @@ func (s *Server) retrieveServices(question dns.Question, request, response *dns.
// SRV Query :
tagOrProtocol := fullDomainRequestArray[1][1:]
serviceName := fullDomainRequestArray[0][1:]
ServiceInstances, err = s.retrieveInstancesForServiceQuery(serviceName, request, response, tagOrProtocol)
serviceInstances, err = s.retrieveInstancesForServiceQuery(serviceName, request, response, tagOrProtocol)
} else {
serviceName := fullDomainRequestArray[numberOfLabels-3]
tagsOrProtocol := fullDomainRequestArray[:numberOfLabels-3]
ServiceInstances, err = s.retrieveInstancesForServiceQuery(serviceName, request, response, tagsOrProtocol...)
serviceInstances, err = s.retrieveInstancesForServiceQuery(serviceName, request, response, tagsOrProtocol...)

}

} else if fullDomainRequestArray[numberOfLabels-2] == "instance" && (question.Qtype == dns.TypeA ||
question.Qtype == dns.TypeAAAA) && numberOfLabels == 3 {

instanceID := fullDomainRequestArray[0]
ServiceInstances, err = s.retrieveServicesFromInstanceQuery(instanceID, request, response)
serviceInstances, err = s.retrieveInstancesForInstanceQuery(instanceID, request, response)
}

return ServiceInstances, err
return serviceInstances, err
}

func (s *Server) retrieveInstancesForServiceQuery(serviceName string, request, response *dns.Msg, tagOrProtocol ...string) ([]*client.ServiceInstance, error) {
Expand Down Expand Up @@ -231,7 +229,7 @@ func (s *Server) retrieveInstancesForServiceQuery(serviceName string, request, r
return serviceInstances, nil
}

func (s *Server) retrieveServicesFromInstanceQuery(instanceID string, request, response *dns.Msg) ([]*client.ServiceInstance, error) {
func (s *Server) retrieveInstancesForInstanceQuery(instanceID string, request, response *dns.Msg) ([]*client.ServiceInstance, error) {
serviceInstances, err := s.config.DiscoveryClient.ListInstances(client.InstanceFilter{})
if err != nil {
response.SetRcode(request, dns.RcodeServerFailure)
Expand All @@ -246,7 +244,7 @@ func (s *Server) retrieveServicesFromInstanceQuery(instanceID string, request, r
return nil, fmt.Errorf("Error : didn't find a service with the id given %s", instanceID)
}

func (s *Server) findMatchingServices(question dns.Question, request, response *dns.Msg,
func (s *Server) createRecordsForInstances(question dns.Question, request, response *dns.Msg,
serviceInstances []*client.ServiceInstance) error {
numOfMatchingRecords := 0
for _, serviceInstance := range serviceInstances {
Expand All @@ -258,7 +256,6 @@ func (s *Server) findMatchingServices(question dns.Question, request, response *
switch endPointType {
case "tcp", "udp":
ip, port, err = validateEndPointTypeTCPAndUDP(serviceInstance.Endpoint.Value)

case "http", "https":
ip, port, err = validateEndPointTypeHTTP(serviceInstance.Endpoint.Value)

Expand All @@ -270,10 +267,10 @@ func (s *Server) findMatchingServices(question dns.Question, request, response *
}
numOfMatchingRecords++
if question.Qtype == dns.TypeSRV {
fullDomainRequestArray := dns.SplitDomainName(question.Name)
domainName := fullDomainRequestArray[len(fullDomainRequestArray)-1]

domainName := s.config.Domain
instanceID := serviceInstance.ID
targetName := fmt.Sprintf("%s.instance.%s.", instanceID, domainName)
targetName := fmt.Sprintf("%s.instance.%s", instanceID, domainName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove the '.' from the suffix? I don't think domainName ends with a dot.

portNumber, _ := strconv.Atoi(port)
recordSRV := &dns.SRV{Hdr: dns.RR_Header{
Name: question.Name,
Expand Down Expand Up @@ -316,12 +313,18 @@ func (s *Server) findMatchingServices(question dns.Question, request, response *

func validateEndPointTypeTCPAndUDP(value string) (net.IP, string, error) {
ip, port, err := net.SplitHostPort(value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

net.SplitHostPort() doesn't work when no port is specified (e.g. 172.17.0.10): https://play.golang.org/p/kLnRJxrQAi
I think you'll have to parse it on your own.

var parsedIP net.IP
if err != nil {
return nil, port, err
}
parsedIP := net.ParseIP(ip)
if parsedIP == nil {
return nil, port, fmt.Errorf("tcp/udp ip value %s is not a valid ip format", ip)
parsedIP = net.ParseIP(value)
if parsedIP == nil {
return nil, port, err
}
port = "0"
} else {
parsedIP = net.ParseIP(ip)
if parsedIP == nil {
return nil, port, fmt.Errorf("tcp/udp ip value %s is not a valid ip format", ip)
}
}
return parsedIP, port, nil
}
Expand All @@ -330,23 +333,26 @@ func validateEndPointTypeHTTP(value string) (net.IP, string, error) {
startsWithHTTP := strings.HasPrefix(value, "http://")
startsWithHTTPS := strings.HasPrefix(value, "https://")
if !startsWithHTTPS && !startsWithHTTP {
value += "http://"
value = "http://" + value
}
var port string
parsedURL, err := url.Parse(value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YOu may not even have URLs in value. That case has to be handled. Today, that is the default case as well.


if err != nil {
return nil, port, err
}

host := parsedURL.Host
ip, port, err := net.SplitHostPort(host)
ip, port, err := validateEndPointTypeTCPAndUDP(host)
if err != nil {
return nil, port, err
}
parsedIP := net.ParseIP(ip)
if parsedIP == nil {
return nil, port, fmt.Errorf("url ip value %s is not a valid ip format", ip)
if port == "0" && startsWithHTTPS {
port = "430"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

433...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's port 443. :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops 😳

} else if port == "0" {
port = "80"
}
return parsedIP, port, nil
return ip, port, nil

}

Expand Down