Skip to content

Commit

Permalink
feat(): Support SRV queries
Browse files Browse the repository at this point in the history
Signed-off-by: Bharath Horatti <[email protected]>
  • Loading branch information
bharath-avesha committed May 10, 2024
1 parent 8bbe880 commit 63e15b2
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 35 deletions.
23 changes: 18 additions & 5 deletions plugin/kubeslice/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,34 @@ func (ks Kubeslice) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M
state := request.Request{W: w, Req: r}
zone := "slice.local"

records, truncated, err := plugin.A(ctx, &ks, zone, state, nil, plugin.Options{})

if err != nil {
return dns.RcodeServerFailure, err
var (
records, extra []dns.RR
truncated bool
err error
)

switch state.QType() {
case dns.TypeA:
records, truncated, err = plugin.A(ctx, &ks, zone, state, nil, plugin.Options{})
if err != nil {
return dns.RcodeServerFailure, err
}
case dns.TypeSRV:
records, extra, err = plugin.SRV(ctx, &ks, zone, state, plugin.Options{})
if err != nil {
return dns.RcodeServerFailure, err
}
}

m := new(dns.Msg)
m.SetReply(r)
m.Authoritative = true
m.Truncated = truncated
m.Answer = records
m.Extra = extra

w.WriteMsg(m)
return dns.RcodeSuccess, nil

}

// Name implements the Handler interface.
Expand Down
46 changes: 27 additions & 19 deletions plugin/kubeslice/kubeslice.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,43 @@ type Kubeslice struct {
}

func (ks *Kubeslice) Services(ctx context.Context, state request.Request, exact bool, opt plugin.Options) ([]msg.Service, error) {

var svcs []msg.Service

// kubeslice only support A records for now, so return empty list if request is not A
if state.QType() != dns.TypeA {
log.Debug("received invalid request type, only A is supported now")
return svcs, nil
}

log.Info("fetching kubeslice services")

name := state.Name()
name = name[:len(name)-1]

eps := ks.EndpointsCache.GetAll()

for _, ep := range eps {
if ep.Host == name {
svc := msg.Service{
Host: ep.IP,
TTL: 60,
switch state.QType() {
case dns.TypeA:
for _, ep := range eps {
if ep.Host == name {
svc := msg.Service{
Host: ep.IP,
TTL: 60,
}
svcs = append(svcs, svc)
}
}
case dns.TypeSRV:
for _, ep := range eps {
if ep.Host == name {
for _, port := range ep.Ports {
svc := msg.Service{
Host: ep.IP,
TTL: 60,
Port: int(port.Port),
Key: msg.Path(ep.Host, "slice"),
TargetStrip: ep.TargetStrip,
}
svcs = append(svcs, svc)
}
}

svcs = append(svcs, svc)
}
default:
log.Debug("received invalid request type, only A and SRV are supported")
return svcs, nil
}

return svcs, nil

}

// TODO fill later
Expand Down
56 changes: 47 additions & 9 deletions plugin/kubeslice/serviceimport_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package kubeslice

import (
"context"
"strings"

dnsCache "github.com/kubeslice/dns/plugin/kubeslice/cache"
"github.com/kubeslice/dns/plugin/kubeslice/slice"
Expand All @@ -19,6 +20,25 @@ type ServiceImportReconciler struct {

const finalizerName = "networking.kubeslice.io/dns-finalizer"

func getSrvEntries(si *kubeslicev1beta1.ServiceImport, name, ip string) []slice.Endpoint {
srvEntries := []slice.Endpoint{}
for _, port := range si.Spec.Ports {
srvEntry := slice.Endpoint{
Host: "_" + port.Name + "." + "_" + strings.ToLower(string(port.Protocol)) + "." + name,
TargetStrip: 2,
IP: ip,
Ports: []slice.ServicePort{{
Name: port.Name,
Port: port.ContainerPort,
Protocol: string(port.Protocol),
}},
}
srvEntries = append(srvEntries, srvEntry)
}

return srvEntries
}

// Watch the ServiceImport changes and adjust dns cache accordingly
func (r *ServiceImportReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {

Expand Down Expand Up @@ -61,23 +81,41 @@ func (r *ServiceImportReconciler) Reconcile(ctx context.Context, req reconcile.R
}

eps := []slice.Endpoint{}
ports := []slice.ServicePort{}
for _, port := range si.Spec.Ports {
ports = append(ports, slice.ServicePort{
Name: port.Name,
Port: port.ContainerPort,
Protocol: string(port.Protocol),
})
}

for _, ep := range si.Status.Endpoints {
// Add entries for the service dns name
endpoint := slice.Endpoint{
Host: ep.DNSName,
IP: ep.IP,
Host: ep.DNSName,
IP: ep.IP,
Ports: ports,
}
endpoint2 := slice.Endpoint{
Host: si.Spec.DNSName,
IP: ep.IP,
Host: si.Spec.DNSName,
IP: ep.IP,
Ports: ports,
}
eps = append(eps, endpoint, endpoint2)
// Add port number entries for SRV records
eps = append(eps, getSrvEntries(si, si.Spec.DNSName, ep.IP)...)

// Add entries for aliases for the service
for _, alias := range si.Spec.Aliases {
endpointN := slice.Endpoint{
Host: alias,
IP: ep.IP,
}
eps = append(eps, endpointN)
endpointN := slice.Endpoint{
Host: alias,
IP: ep.IP,
Ports: ports,
}
eps = append(eps, endpointN)
// Add port number entries for SRV records
eps = append(eps, getSrvEntries(si, alias, ep.IP)...)
}
}

Expand Down
12 changes: 10 additions & 2 deletions plugin/kubeslice/slice/endpoint.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package slice

type ServicePort struct {
Name string
Port int32
Protocol string
}

// Endpoint corresponds to a dns entry for an endpint in the slice
type Endpoint struct {
Host string
IP string
Host string
IP string
Ports []ServicePort
TargetStrip int
}

0 comments on commit 63e15b2

Please sign in to comment.