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

Feat/vip outbound #834

Merged
merged 16 commits into from
Jun 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion pkg/dns-server/resolver/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (h *SimpleDNSHandler) parseQuery(m *dns.Msg) {
switch q.Qtype {
case dns.TypeA:
simpleDNSLog.Info("Query for " + q.Name)
ip, err := h.resolver.ForwardLookup(q.Name)
ip, err := h.resolver.ForwardLookupFQDN(q.Name)
if err != nil {
simpleDNSLog.Error(err, "unable to resolve", "Name", q.Name)
return
Expand Down
3 changes: 2 additions & 1 deletion pkg/dns-server/resolver/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type DNSResolver interface {
AddService(service string) (string, error)
RemoveService(service string) error
SyncServices(services map[string]bool) error
ForwardLookup(name string) (string, error)
ForwardLookup(service string) (string, error)
ForwardLookupFQDN(name string) (string, error)
ReverseLookup(ip string) (string, error)
}
16 changes: 14 additions & 2 deletions pkg/dns-server/resolver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func (d *SimpleDNSResolver) SyncServices(services map[string]bool) (errs error)
errs = multierr.Append(errs, errors.Wrapf(err, "unable to allocate an ip for service %s", service))
} else {
d.viplist[service] = ip
simpleDNSLog.Info("Adding ", "service", service, "ip", ip)
}
}
}
Expand All @@ -138,7 +139,18 @@ func (d *SimpleDNSResolver) SyncServices(services map[string]bool) (errs error)
return errs
}

func (d *SimpleDNSResolver) ForwardLookup(name string) (string, error) {
func (d *SimpleDNSResolver) ForwardLookup(service string) (string, error) {
d.RLock()
defer d.RUnlock()

ip, found := d.viplist[service]
if !found {
return "", errors.Errorf("service [%s] not found in domain [%s].", service, d.domain)
}
return ip, nil
}

func (d *SimpleDNSResolver) ForwardLookupFQDN(name string) (string, error) {
d.RLock()
defer d.RUnlock()
domain, err := d.domainFromName(name)
Expand Down Expand Up @@ -201,7 +213,7 @@ func (d *SimpleDNSResolver) domainFromName(name string) (string, error) {

func (d *SimpleDNSResolver) serviceFromName(name string) (string, error) {
split := dns.SplitDomainName(name)
if len(split) < 2 {
if len(split) < 1 {
return "", errors.Errorf("wrong DNS name: %s", name)
}

Expand Down
21 changes: 13 additions & 8 deletions pkg/dns-server/resolver/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ var _ = Describe("DNS server", func() {
_, err = resolver.AddService("service")
Expect(err).ToNot(HaveOccurred())

ip, err = resolver.ForwardLookup("service.mesh")
ip, err = resolver.ForwardLookupFQDN("service.mesh")
Expect(err).ToNot(HaveOccurred())

go func() {
Expand Down Expand Up @@ -115,16 +115,21 @@ var _ = Describe("DNS server", func() {
_, err = resolver.AddService("service")
Expect(err).ToNot(HaveOccurred())

ip, err := resolver.ForwardLookup("service.mesh")
ipService, err := resolver.ForwardLookup("service")
Expect(err).ToNot(HaveOccurred())

ipFQDN, err := resolver.ForwardLookupFQDN("service.mesh")
Expect(err).ToNot(HaveOccurred())

// when
service, err := resolver.ReverseLookup(ip)
service, err := resolver.ReverseLookup(ipFQDN)

// then
Expect(err).ToNot(HaveOccurred())
// and
Expect(service).To(Equal("service.mesh"))
// and
Expect(ipService).To(Equal(ipFQDN))
})

It("DNS Server service operation", func() {
Expand Down Expand Up @@ -171,17 +176,17 @@ var _ = Describe("DNS server", func() {
Expect(err).ToNot(HaveOccurred())

// when
_, err = resolver.ForwardLookup("example-one.mesh")
_, err = resolver.ForwardLookupFQDN("example-one.mesh")
// then
Expect(err).ToNot(HaveOccurred())

// when
_, err = resolver.ForwardLookup("example-five.mesh")
_, err = resolver.ForwardLookupFQDN("example-five.mesh")
// then
Expect(err).ToNot(HaveOccurred())

// when
_, err = resolver.ForwardLookup("example-five.other")
_, err = resolver.ForwardLookupFQDN("example-five.other")
// then
Expect(err).To(HaveOccurred())

Expand All @@ -194,7 +199,7 @@ var _ = Describe("DNS server", func() {
Expect(err).ToNot(HaveOccurred())

// when
_, err = resolver.ForwardLookup("example-five.mesh")
_, err = resolver.ForwardLookupFQDN("example-five.mesh")
// then
Expect(err).To(HaveOccurred())

Expand All @@ -204,7 +209,7 @@ var _ = Describe("DNS server", func() {
Expect(err).ToNot(HaveOccurred())

// when
_, err = resolver.ForwardLookup("example-five.mesh")
_, err = resolver.ForwardLookupFQDN("example-five.mesh")
// then
Expect(err).To(HaveOccurred())
})
Expand Down
13 changes: 8 additions & 5 deletions pkg/xds/server/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,6 @@ func DefaultDataplaneSyncTracker(rt core_runtime.Runtime, reconciler, ingressRec
},
}

otherDataplanes := &mesh_core.DataplaneResourceList{}
if err := rt.ReadOnlyResourceManager().List(ctx, otherDataplanes, core_store.ListByMesh(dataplane.Meta.GetMesh())); err != nil {
return err
}

if dataplane.Spec.IsIngress() {
// update Ingress
if err := ingress.UpdateAvailableServices(ctx, rt.ResourceManager(), dataplane, dataplanes.Items); err != nil {
Expand All @@ -157,6 +152,14 @@ func DefaultDataplaneSyncTracker(rt core_runtime.Runtime, reconciler, ingressRec
return ingressReconciler.Reconcile(envoyCtx, &proxy)
}

// Generate VIP outbounds only when not Ingress and Transparent Proxying is enabled
if !dataplane.Spec.IsIngress() && dataplane.Spec.Networking.GetTransparentProxying() != nil {
err = xds_topology.PatchDataplaneWithVIPOutbounds(dataplane, dataplanes, rt.DNSResolver())
if err != nil {
return err
}
}

// pick a single the most specific route for each outbound interface
routes, err := xds_topology.GetRoutes(ctx, dataplane, rt.ReadOnlyResourceManager())
if err != nil {
Expand Down
61 changes: 61 additions & 0 deletions pkg/xds/topology/vip_outbounds.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package topology

import (
"sort"
"strings"

"github.com/pkg/errors"
"go.uber.org/multierr"

mesh_proto "github.com/Kong/kuma/api/mesh/v1alpha1"
mesh_core "github.com/Kong/kuma/pkg/core/resources/apis/mesh"
"github.com/Kong/kuma/pkg/dns-server/resolver"
)

const VIPListenPort = uint32(80)

func PatchDataplaneWithVIPOutbounds(dataplane *mesh_core.DataplaneResource,
dataplanes *mesh_core.DataplaneResourceList, resolver resolver.DNSResolver) (errs error) {
serviceVIPMap := map[string]string{}
services := []string{}
for _, dp := range dataplanes.Items {
if dp.Meta.GetName() == dataplane.Meta.GetName() {
continue
}

for _, inbound := range dp.Spec.Networking.Inbound {
inService := inbound.GetTags()[mesh_proto.ServiceTag]

if _, found := serviceVIPMap[inService]; !found {
vip, err := resolver.ForwardLookup(inService)
if err != nil {
// TODO: remove this additional lookup once the service tag contains a `flat` service name
// try to get the first part of the FQDN service and look it up
split := strings.Split(inService, ".")
vip, err = resolver.ForwardLookup(split[0])
if err != nil {
errs = multierr.Append(errs, errors.Wrapf(err, "unable to resolve %s", inService))
}
}
serviceVIPMap[inService] = vip
services = append(services, inService)
}
}
}

sort.Strings(services)

for _, service := range services {
dataplane.Spec.Networking.Outbound = append(dataplane.Spec.Networking.Outbound,
&mesh_proto.Dataplane_Networking_Outbound{
Address: serviceVIPMap[service],
Port: VIPListenPort,
Service: service,
Tags: map[string]string{
mesh_proto.ServiceTag: service,
},
})
}

return
}
92 changes: 92 additions & 0 deletions pkg/xds/topology/vip_outbounds_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package topology_test

import (
"strconv"

"github.com/Kong/kuma/pkg/dns-server/resolver"
"github.com/Kong/kuma/pkg/test"

mesh_proto "github.com/Kong/kuma/api/mesh/v1alpha1"
core_mesh "github.com/Kong/kuma/pkg/core/resources/apis/mesh"
test_model "github.com/Kong/kuma/pkg/test/resources/model"
"github.com/Kong/kuma/pkg/xds/topology"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("PatchDataplaneWithVIPOutbounds", func() {

It("should update outbounds", func() {
dataplane := &core_mesh.DataplaneResource{
Meta: &test_model.ResourceMeta{
Name: "dp1",
Mesh: "default",
},
Spec: mesh_proto.Dataplane{
Networking: &mesh_proto.Dataplane_Networking{
Address: "192.168.0.1",
Inbound: []*mesh_proto.Dataplane_Networking_Inbound{
{
Port: 8080,
Tags: map[string]string{
"service": "backend",
},
},
},
},
},
}

// setup
p, err := test.GetFreePort()
Expect(err).ToNot(HaveOccurred())
port := strconv.Itoa(p)

resolver, err := resolver.NewSimpleDNSResolver("mesh", "127.0.0.1", port, "240.0.0.0/4")
Expect(err).ToNot(HaveOccurred())

// given
dataplanes := core_mesh.DataplaneResourceList{}
for i := 1; i <= 5; i++ {

service := "service-" + strconv.Itoa(i)
vip, err := resolver.AddService(service)
Expect(err).ToNot(HaveOccurred())

dataplanes.Items = append(dataplanes.Items, &core_mesh.DataplaneResource{
Meta: &test_model.ResourceMeta{
Name: "dp" + strconv.Itoa(i),
Mesh: "default",
},
Spec: mesh_proto.Dataplane{
Networking: &mesh_proto.Dataplane_Networking{
Inbound: []*mesh_proto.Dataplane_Networking_Inbound{
{
Port: uint32(1234 + i),
Address: vip,
Tags: map[string]string{
"service": service,
},
},
},
},
},
})
}

// when
err = topology.PatchDataplaneWithVIPOutbounds(dataplane, &dataplanes, resolver)
// then
Expect(err).ToNot(HaveOccurred())
// and
Expect(len(dataplane.Spec.Networking.Outbound)).To(Equal(4))
// and
Expect(dataplane.Spec.Networking.Outbound[3].GetService()).To(Equal("service-5"))
// and
Expect(dataplane.Spec.Networking.Outbound[3].GetTags()[mesh_proto.ServiceTag]).To(Equal("service-5"))
// and
Expect(dataplane.Spec.Networking.Outbound[3].Port).To(Equal(topology.VIPListenPort))
})

})
2 changes: 1 addition & 1 deletion test/e2e/kuma_deploy_dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
. "github.com/Kong/kuma/test/framework"
)

var _ = Describe("Test DNS", func() {
var _ = XDescribe("Test DNS", func() {

var clusters Clusters

Expand Down
Loading