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(kuma-cp) save service's tags to header #647

Merged
merged 12 commits into from
Apr 1, 2020
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# CHANGELOG

## master
* feat: save service's tags to header for L7-traffic
[#647](https://github.com/Kong/kuma/pull/647/files)
* chore: the API root `/` now returns the hostname
[#645](https://github.com/Kong/kuma/pull/645)
* feat: FaultInjection entity, support in API and `kumactl`
Expand Down
1 change: 1 addition & 0 deletions pkg/xds/envoy/listeners/http_inbound_route_configurer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func (c *HttpInboundRouteConfigurer) Configure(filterChain *envoy_listener.Filte
routeName := envoy_names.GetInboundRouteName(c.service)
routeConfig, err := envoy_routes.NewRouteConfigurationBuilder().
Configure(envoy_routes.CommonRouteConfiguration(routeName)).
Configure(envoy_routes.ResetTagsHeader()).
Configure(envoy_routes.VirtualHost(envoy_routes.NewVirtualHostBuilder().
Configure(envoy_routes.CommonVirtualHost(c.service)).
Configure(envoy_routes.DefaultRoute(c.cluster)))).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ var _ = Describe("HttpInboundRouteConfigurer", func() {
- name: envoy.router
routeConfig:
name: inbound:backend
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down
19 changes: 19 additions & 0 deletions pkg/xds/envoy/routes/reset_tags_header_configurer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package routes

import envoy_api_v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2"

// ResetTagsHeader adds x-kuma-tags header to the RequestHeadersToRemove list. x-kuma-tags header is planned to be used
// internally, so we don't want to expose it to the destination application.
func ResetTagsHeader() RouteConfigurationBuilderOpt {
return RouteConfigurationBuilderOptFunc(func(config *RouteConfigurationBuilderConfig) {
config.Add(&ResetTagsHeaderConfigurer{})
})
}

type ResetTagsHeaderConfigurer struct {
}

func (r *ResetTagsHeaderConfigurer) Configure(rc *envoy_api_v2.RouteConfiguration) error {
rc.RequestHeadersToRemove = append(rc.RequestHeadersToRemove, TagsHeaderName)
return nil
}
30 changes: 30 additions & 0 deletions pkg/xds/envoy/routes/reset_tags_header_configurer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package routes_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

util_proto "github.com/Kong/kuma/pkg/util/proto"
"github.com/Kong/kuma/pkg/xds/envoy/routes"
)

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

It("should generate proper Envoy config", func() {
// when
routeConfiguration, err := routes.NewRouteConfigurationBuilder().
Configure(routes.ResetTagsHeader()).
Build()
// then
Expect(err).ToNot(HaveOccurred())

// when
actual, err := util_proto.ToYAML(routeConfiguration)
// then
Expect(err).ToNot(HaveOccurred())
// and
Expect(actual).To(MatchYAML(`
requestHeadersToRemove:
- x-kuma-tags`))
})
})
46 changes: 46 additions & 0 deletions pkg/xds/envoy/routes/tags_header_configurer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package routes

import (
"fmt"
"strings"

envoy_api_v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2"
envoy_core "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"

mesh_proto "github.com/Kong/kuma/api/mesh/v1alpha1"
)

const TagsHeaderName = "x-kuma-tags"

func TagsHeader(tags mesh_proto.MultiValueTagSet) RouteConfigurationBuilderOpt {
return RouteConfigurationBuilderOptFunc(func(config *RouteConfigurationBuilderConfig) {
config.Add(&TagsHeaderConfigurer{
tags: tags,
})
})
}

type TagsHeaderConfigurer struct {
tags mesh_proto.MultiValueTagSet
}

func (t *TagsHeaderConfigurer) Configure(rc *envoy_api_v2.RouteConfiguration) error {
if len(t.tags) == 0 {
return nil
}
rc.RequestHeadersToAdd = append(rc.RequestHeadersToAdd, &envoy_core.HeaderValueOption{
Header: &envoy_core.HeaderValue{Key: TagsHeaderName, Value: serializeTags(t.tags)},
})
return nil
}

func serializeTags(tags mesh_proto.MultiValueTagSet) string {
var pairs []string
for _, key := range tags.Keys() {
pairs = append(pairs, fmt.Sprintf("%s=%s", key, strings.Join(tags.Values(key), ",")))
}
if len(pairs) == 0 {
return ""
}
return "&" + strings.Join(pairs, "&") + "&"
}
53 changes: 53 additions & 0 deletions pkg/xds/envoy/routes/tags_header_configurer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package routes_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"

mesh_proto "github.com/Kong/kuma/api/mesh/v1alpha1"
util_proto "github.com/Kong/kuma/pkg/util/proto"
"github.com/Kong/kuma/pkg/xds/envoy/routes"
)

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

type testCase struct {
tags mesh_proto.MultiValueTagSet
expected string
}

DescribeTable("should generate proper Envoy config",
func(given testCase) {
// when
routeConfiguration, err := routes.NewRouteConfigurationBuilder().
Configure(routes.TagsHeader(given.tags)).
Build()
// then
Expect(err).ToNot(HaveOccurred())

// when
actual, err := util_proto.ToYAML(routeConfiguration)
// then
Expect(err).ToNot(HaveOccurred())
// and
Expect(actual).To(MatchYAML(given.expected))
},
Entry("basic tags", testCase{
tags: map[string]map[string]bool{
"tag2": {"value21": true},
"tag3": {"value31": true, "value32": true, "value33": true},
"tag1": {"value11": true, "value12": true},
},
expected: `
requestHeadersToAdd:
- header:
key: x-kuma-tags
value: '&tag1=value11,value12&tag2=value21&tag3=value31,value32,value33&'`,
}),
Entry("empty tags", testCase{
tags: map[string]map[string]bool{},
expected: `{}`,
}),
)
})
6 changes: 4 additions & 2 deletions pkg/xds/generator/proxy_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,13 @@ func (g OutboundProxyGenerator) Generate(ctx xds_context.Context, proxy *model.P
})

// generate RDS resources
rdsResources, err := g.generateRds(protocol, outbound.Service, outboundRouteName, clusters)
rdsResources, err := g.generateRds(protocol, outbound.Service, outboundRouteName, clusters, proxy.Dataplane.Spec.Tags())
if err != nil {
return nil, err
}
resources.Add(rdsResources...)
}

return resources.List(), nil
}

Expand Down Expand Up @@ -274,13 +275,14 @@ func (_ OutboundProxyGenerator) generateEds(ctx xds_context.Context, proxy *mode
return
}

func (_ OutboundProxyGenerator) generateRds(protocol mesh_core.Protocol, service string, outboundRouteName string, clusters []envoy_common.ClusterInfo) ([]*model.Resource, error) {
func (_ OutboundProxyGenerator) generateRds(protocol mesh_core.Protocol, service string, outboundRouteName string, clusters []envoy_common.ClusterInfo, tags kuma_mesh.MultiValueTagSet) ([]*model.Resource, error) {
resources := &model.ResourceSet{}
switch protocol {
case mesh_core.ProtocolHTTP:
// generate RDS resource
routeConfiguration, err := envoy_routes.NewRouteConfigurationBuilder().
Configure(envoy_routes.CommonRouteConfiguration(outboundRouteName)).
Configure(envoy_routes.TagsHeader(tags)).
Configure(envoy_routes.VirtualHost(envoy_routes.NewVirtualHostBuilder().
Configure(envoy_routes.CommonVirtualHost(service)).
Configure(envoy_routes.DefaultRoute(clusters...)))).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend1
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend1
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend1
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend1
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend1
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down Expand Up @@ -174,6 +176,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend3
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend1
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down Expand Up @@ -180,6 +182,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend3
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ resources:
resource:
'@type': type.googleapis.com/envoy.api.v2.RouteConfiguration
name: outbound:api-http
requestHeadersToAdd:
- header:
key: x-kuma-tags
value: '&service=gateway&'
validateClusters: true
virtualHosts:
- domains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,10 @@ resources:
resource:
'@type': type.googleapis.com/envoy.api.v2.RouteConfiguration
name: outbound:api-http
requestHeadersToAdd:
- header:
key: x-kuma-tags
value: '&service=web&'
validateClusters: true
virtualHosts:
- domains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ resources:
- name: envoy.router
routeConfig:
name: inbound:backend
requestHeadersToRemove:
- x-kuma-tags
validateClusters: true
virtualHosts:
- domains:
Expand Down