Header manip for split legs plumbing
This commit is contained in:
parent
f70f7b2389
commit
1dd1683ed9
|
@ -417,8 +417,12 @@ func (c *compiler) flattenAdjacentSplitterNodes() {
|
||||||
effectiveWeight := split.Weight * innerSplit.Weight / 100
|
effectiveWeight := split.Weight * innerSplit.Weight / 100
|
||||||
|
|
||||||
newDiscoverySplit := &structs.DiscoverySplit{
|
newDiscoverySplit := &structs.DiscoverySplit{
|
||||||
Weight: structs.NormalizeServiceSplitWeight(effectiveWeight),
|
// Copy the definition from the inner node so any extra config (e.g.
|
||||||
NextNode: innerSplit.NextNode,
|
// header manipulation) will be applied to requests taking this
|
||||||
|
// path.
|
||||||
|
Definition: innerSplit.Definition,
|
||||||
|
Weight: structs.NormalizeServiceSplitWeight(effectiveWeight),
|
||||||
|
NextNode: innerSplit.NextNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
fixedSplits = append(fixedSplits, newDiscoverySplit)
|
fixedSplits = append(fixedSplits, newDiscoverySplit)
|
||||||
|
@ -723,9 +727,16 @@ func (c *compiler) getSplitterNode(sid structs.ServiceID) (*structs.DiscoveryGra
|
||||||
c.recordNode(splitNode)
|
c.recordNode(splitNode)
|
||||||
|
|
||||||
var hasLB bool
|
var hasLB bool
|
||||||
for _, split := range splitter.Splits {
|
for i := range splitter.Splits {
|
||||||
|
// We don't use range variables here because we'll take the address of
|
||||||
|
// this split and store that in a DiscoveryGraphNode and the range
|
||||||
|
// variables share memory addresses between iterations which is exactly
|
||||||
|
// wrong for us here.
|
||||||
|
split := splitter.Splits[i]
|
||||||
|
|
||||||
compiledSplit := &structs.DiscoverySplit{
|
compiledSplit := &structs.DiscoverySplit{
|
||||||
Weight: split.Weight,
|
Definition: &split,
|
||||||
|
Weight: split.Weight,
|
||||||
}
|
}
|
||||||
splitNode.Splits = append(splitNode.Splits, compiledSplit)
|
splitNode.Splits = append(splitNode.Splits, compiledSplit)
|
||||||
|
|
||||||
|
|
|
@ -1040,9 +1040,36 @@ func setupTestVariationConfigEntriesAndSnapshot(
|
||||||
Kind: structs.ServiceSplitter,
|
Kind: structs.ServiceSplitter,
|
||||||
Name: "db",
|
Name: "db",
|
||||||
Splits: []structs.ServiceSplit{
|
Splits: []structs.ServiceSplit{
|
||||||
{Weight: 95.5, Service: "big-side"},
|
{
|
||||||
{Weight: 4, Service: "goldilocks-side"},
|
Weight: 95.5,
|
||||||
{Weight: 0.5, Service: "lil-bit-side"},
|
Service: "big-side",
|
||||||
|
RequestHeaders: &structs.HTTPHeaderModifiers{
|
||||||
|
Set: map[string]string{"x-split-leg": "big"},
|
||||||
|
},
|
||||||
|
ResponseHeaders: &structs.HTTPHeaderModifiers{
|
||||||
|
Set: map[string]string{"x-split-leg": "big"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Weight: 4,
|
||||||
|
Service: "goldilocks-side",
|
||||||
|
RequestHeaders: &structs.HTTPHeaderModifiers{
|
||||||
|
Set: map[string]string{"x-split-leg": "goldilocks"},
|
||||||
|
},
|
||||||
|
ResponseHeaders: &structs.HTTPHeaderModifiers{
|
||||||
|
Set: map[string]string{"x-split-leg": "goldilocks"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Weight: 0.5,
|
||||||
|
Service: "lil-bit-side",
|
||||||
|
RequestHeaders: &structs.HTTPHeaderModifiers{
|
||||||
|
Set: map[string]string{"x-split-leg": "small"},
|
||||||
|
},
|
||||||
|
ResponseHeaders: &structs.HTTPHeaderModifiers{
|
||||||
|
Set: map[string]string{"x-split-leg": "small"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -1490,12 +1490,19 @@ type HTTPHeaderModifiers struct {
|
||||||
Remove []string `json:",omitempty"`
|
Remove []string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *HTTPHeaderModifiers) IsZero() bool {
|
||||||
|
if m == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return len(m.Add) == 0 && len(m.Set) == 0 && len(m.Remove) == 0
|
||||||
|
}
|
||||||
|
|
||||||
func (m *HTTPHeaderModifiers) Validate(protocol string) error {
|
func (m *HTTPHeaderModifiers) Validate(protocol string) error {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
// Empty is always valid
|
// Empty is always valid
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(m.Add) == 0 && len(m.Set) == 0 && len(m.Remove) == 0 {
|
if m.IsZero() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !IsProtocolHTTPLike(protocol) {
|
if !IsProtocolHTTPLike(protocol) {
|
||||||
|
|
|
@ -192,6 +192,13 @@ type DiscoveryRoute struct {
|
||||||
|
|
||||||
// compiled form of ServiceSplit
|
// compiled form of ServiceSplit
|
||||||
type DiscoverySplit struct {
|
type DiscoverySplit struct {
|
||||||
|
Definition *ServiceSplit `json:",omitempty"`
|
||||||
|
// Weight is not necessarily a duplicate of Definition.Weight since when
|
||||||
|
// multiple splits are compiled down to a single set of splits the effective
|
||||||
|
// weight of a split leg might not be the same as in the original definition.
|
||||||
|
// Proxies should use this compiled weight. The Definition is provided above
|
||||||
|
// for any other significant configuration that the proxy might need to apply
|
||||||
|
// to that leg of the split.
|
||||||
Weight float32 `json:",omitempty"`
|
Weight float32 `json:",omitempty"`
|
||||||
NextNode string `json:",omitempty"`
|
NextNode string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -633,6 +633,9 @@ func makeRouteActionForSplitter(splits []*structs.DiscoverySplit, chain *structs
|
||||||
Weight: makeUint32Value(int(split.Weight * 100)),
|
Weight: makeUint32Value(int(split.Weight * 100)),
|
||||||
Name: clusterName,
|
Name: clusterName,
|
||||||
}
|
}
|
||||||
|
if err := injectHeaderManipToWeightedCluster(split.Definition, cw); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
clusters = append(clusters, cw)
|
clusters = append(clusters, cw)
|
||||||
}
|
}
|
||||||
|
@ -719,7 +722,7 @@ func injectLBToRouteAction(lb *structs.LoadBalancer, action *envoy_route_v3.Rout
|
||||||
}
|
}
|
||||||
|
|
||||||
func injectHeaderManipToRoute(dest *structs.ServiceRouteDestination, r *envoy_route_v3.Route) error {
|
func injectHeaderManipToRoute(dest *structs.ServiceRouteDestination, r *envoy_route_v3.Route) error {
|
||||||
if dest.RequestHeaders != nil {
|
if !dest.RequestHeaders.IsZero() {
|
||||||
r.RequestHeadersToAdd = append(
|
r.RequestHeadersToAdd = append(
|
||||||
r.RequestHeadersToAdd,
|
r.RequestHeadersToAdd,
|
||||||
makeHeadersValueOptions(dest.RequestHeaders.Add, true)...,
|
makeHeadersValueOptions(dest.RequestHeaders.Add, true)...,
|
||||||
|
@ -733,7 +736,7 @@ func injectHeaderManipToRoute(dest *structs.ServiceRouteDestination, r *envoy_ro
|
||||||
dest.RequestHeaders.Remove...,
|
dest.RequestHeaders.Remove...,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if dest.ResponseHeaders != nil {
|
if !dest.ResponseHeaders.IsZero() {
|
||||||
r.ResponseHeadersToAdd = append(
|
r.ResponseHeadersToAdd = append(
|
||||||
r.ResponseHeadersToAdd,
|
r.ResponseHeadersToAdd,
|
||||||
makeHeadersValueOptions(dest.ResponseHeaders.Add, true)...,
|
makeHeadersValueOptions(dest.ResponseHeaders.Add, true)...,
|
||||||
|
@ -749,3 +752,35 @@ func injectHeaderManipToRoute(dest *structs.ServiceRouteDestination, r *envoy_ro
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func injectHeaderManipToWeightedCluster(split *structs.ServiceSplit, c *envoy_route_v3.WeightedCluster_ClusterWeight) error {
|
||||||
|
if !split.RequestHeaders.IsZero() {
|
||||||
|
c.RequestHeadersToAdd = append(
|
||||||
|
c.RequestHeadersToAdd,
|
||||||
|
makeHeadersValueOptions(split.RequestHeaders.Add, true)...,
|
||||||
|
)
|
||||||
|
c.RequestHeadersToAdd = append(
|
||||||
|
c.RequestHeadersToAdd,
|
||||||
|
makeHeadersValueOptions(split.RequestHeaders.Set, false)...,
|
||||||
|
)
|
||||||
|
c.RequestHeadersToRemove = append(
|
||||||
|
c.RequestHeadersToRemove,
|
||||||
|
split.RequestHeaders.Remove...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if !split.ResponseHeaders.IsZero() {
|
||||||
|
c.ResponseHeadersToAdd = append(
|
||||||
|
c.ResponseHeadersToAdd,
|
||||||
|
makeHeadersValueOptions(split.ResponseHeaders.Add, true)...,
|
||||||
|
)
|
||||||
|
c.ResponseHeadersToAdd = append(
|
||||||
|
c.ResponseHeadersToAdd,
|
||||||
|
makeHeadersValueOptions(split.ResponseHeaders.Set, false)...,
|
||||||
|
)
|
||||||
|
c.ResponseHeadersToRemove = append(
|
||||||
|
c.ResponseHeadersToRemove,
|
||||||
|
split.ResponseHeaders.Remove...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -20,15 +20,69 @@
|
||||||
"clusters": [
|
"clusters": [
|
||||||
{
|
{
|
||||||
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 9550
|
"weight": 9550,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "big"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "big"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 400
|
"weight": 400,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "goldilocks"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "goldilocks"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 50
|
"weight": 50,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "small"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "small"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"totalWeight": 10000
|
"totalWeight": 10000
|
||||||
|
|
|
@ -20,15 +20,69 @@
|
||||||
"clusters": [
|
"clusters": [
|
||||||
{
|
{
|
||||||
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 9550
|
"weight": 9550,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "big"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "big"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 400
|
"weight": 400,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "goldilocks"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "goldilocks"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 50
|
"weight": 50,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "small"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "small"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"totalWeight": 10000
|
"totalWeight": 10000
|
||||||
|
|
|
@ -21,15 +21,69 @@
|
||||||
"clusters": [
|
"clusters": [
|
||||||
{
|
{
|
||||||
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 9550
|
"weight": 9550,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "big"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "big"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 400
|
"weight": 400,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "goldilocks"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "goldilocks"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 50
|
"weight": 50,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "small"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "small"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"totalWeight": 10000
|
"totalWeight": 10000
|
||||||
|
|
|
@ -21,15 +21,69 @@
|
||||||
"clusters": [
|
"clusters": [
|
||||||
{
|
{
|
||||||
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 9550
|
"weight": 9550,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "big"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "big"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 400
|
"weight": 400,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "goldilocks"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "goldilocks"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
"name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
"weight": 50
|
"weight": 50,
|
||||||
|
"requestHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "small"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseHeadersToAdd": [
|
||||||
|
{
|
||||||
|
"header": {
|
||||||
|
"key": "x-split-leg",
|
||||||
|
"value": "small"
|
||||||
|
},
|
||||||
|
"append": false
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"totalWeight": 10000
|
"totalWeight": 10000
|
||||||
|
|
Loading…
Reference in New Issue