From 7f0cd27591b1f48197c58e8627844c5eb3c878f9 Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Wed, 6 Mar 2019 12:17:41 +0200 Subject: [PATCH 1/6] Add Header manipulation rules to Istio Virtual Service --- pkg/apis/istio/v1alpha3/virtual_service.go | 30 ++++++++++ .../istio/v1alpha3/zz_generated.deepcopy.go | 58 +++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/pkg/apis/istio/v1alpha3/virtual_service.go b/pkg/apis/istio/v1alpha3/virtual_service.go index 2c61a4c1..c0298a66 100644 --- a/pkg/apis/istio/v1alpha3/virtual_service.go +++ b/pkg/apis/istio/v1alpha3/virtual_service.go @@ -325,6 +325,9 @@ type HTTPRoute struct { // destination. Mirror *Destination `json:"mirror,omitempty"` + // Cross-Origin Resource Sharing policy (CORS). Refer to + // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS + // for further details about cross origin resource sharing. CorsPolicy *CorsPolicy `json:"CorsPolicy,omitempty"` // Additional HTTP headers to add before forwarding a request to the @@ -333,6 +336,33 @@ type HTTPRoute struct { // Http headers to remove before returning the response to the caller RemoveResponseHeaders map[string]string `json:"removeResponseHeaders,omitempty"` + + // Header manipulation rules + Headers *Headers `json:"headers,omitempty"` +} + +// Header manipulation rules +type Headers struct { + // Header manipulation rules to apply before forwarding a request + // to the destination service + Request HeaderOperations `json:"request,omitempty"` + + // Header manipulation rules to apply before returning a response + // to the caller + Response HeaderOperations `json:"response,omitempty"` +} + +// HeaderOperations Describes the header manipulations to apply +type HeaderOperations struct { + // Overwrite the headers specified by key with the given values + Set map[string]string `json:"set"` + + // Append the given values to the headers specified by keys + // (will create a comma-separated list of values) + Add map[string]string `json:"add"` + + // Remove the specified headers + Remove []string `json:"remove"` } // HttpMatchRequest specifies a set of criterion to be met in order for the diff --git a/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go index f843c9be..f3619989 100644 --- a/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go +++ b/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go @@ -283,6 +283,11 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { (*out)[key] = val } } + if in.Headers != nil { + in, out := &in.Headers, &out.Headers + *out = new(Headers) + (*in).DeepCopyInto(*out) + } return } @@ -296,6 +301,59 @@ func (in *HTTPRoute) DeepCopy() *HTTPRoute { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HeaderOperations) DeepCopyInto(out *HeaderOperations) { + *out = *in + if in.Set != nil { + in, out := &in.Set, &out.Set + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Add != nil { + in, out := &in.Add, &out.Add + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Remove != nil { + in, out := &in.Remove, &out.Remove + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderOperations. +func (in *HeaderOperations) DeepCopy() *HeaderOperations { + if in == nil { + return nil + } + out := new(HeaderOperations) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Headers) DeepCopyInto(out *Headers) { + *out = *in + in.Request.DeepCopyInto(&out.Request) + in.Response.DeepCopyInto(&out.Response) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Headers. +func (in *Headers) DeepCopy() *Headers { + if in == nil { + return nil + } + out := new(Headers) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *InjectAbort) DeepCopyInto(out *InjectAbort) { *out = *in From 7d0df82861d96e79ecc488259b8a9dfd7448bf14 Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Wed, 6 Mar 2019 12:41:53 +0200 Subject: [PATCH 2/6] Add header manipulation rules to Canary CRD --- pkg/apis/flagger/v1alpha3/types.go | 16 ++--- .../flagger/v1alpha3/zz_generated.deepcopy.go | 10 ++- pkg/apis/istio/v1alpha3/virtual_service.go | 4 +- .../istio/v1alpha3/zz_generated.deepcopy.go | 12 +++- pkg/router/istio.go | 61 +++++++++++-------- 5 files changed, 61 insertions(+), 42 deletions(-) diff --git a/pkg/apis/flagger/v1alpha3/types.go b/pkg/apis/flagger/v1alpha3/types.go index 6937440d..dfbf51a6 100755 --- a/pkg/apis/flagger/v1alpha3/types.go +++ b/pkg/apis/flagger/v1alpha3/types.go @@ -109,14 +109,14 @@ type CanaryStatus struct { // CanaryService is used to create ClusterIP services // and Istio Virtual Service type CanaryService struct { - Port int32 `json:"port"` - Gateways []string `json:"gateways"` - Hosts []string `json:"hosts"` - Match []istiov1alpha3.HTTPMatchRequest `json:"match,omitempty"` - Rewrite *istiov1alpha3.HTTPRewrite `json:"rewrite,omitempty"` - Timeout string `json:"timeout,omitempty"` - Retries *istiov1alpha3.HTTPRetry `json:"retries,omitempty"` - AppendHeaders map[string]string `json:"appendHeaders,omitempty"` + Port int32 `json:"port"` + Gateways []string `json:"gateways"` + Hosts []string `json:"hosts"` + Match []istiov1alpha3.HTTPMatchRequest `json:"match,omitempty"` + Rewrite *istiov1alpha3.HTTPRewrite `json:"rewrite,omitempty"` + Timeout string `json:"timeout,omitempty"` + Retries *istiov1alpha3.HTTPRetry `json:"retries,omitempty"` + Headers *istiov1alpha3.Headers `json:"headers,omitempty"` } // CanaryAnalysis is used to describe how the analysis should be done diff --git a/pkg/apis/flagger/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/flagger/v1alpha3/zz_generated.deepcopy.go index fd5f8347..8f28a1d9 100644 --- a/pkg/apis/flagger/v1alpha3/zz_generated.deepcopy.go +++ b/pkg/apis/flagger/v1alpha3/zz_generated.deepcopy.go @@ -161,12 +161,10 @@ func (in *CanaryService) DeepCopyInto(out *CanaryService) { *out = new(istiov1alpha3.HTTPRetry) **out = **in } - if in.AppendHeaders != nil { - in, out := &in.AppendHeaders, &out.AppendHeaders - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } + if in.Headers != nil { + in, out := &in.Headers, &out.Headers + *out = new(istiov1alpha3.Headers) + (*in).DeepCopyInto(*out) } return } diff --git a/pkg/apis/istio/v1alpha3/virtual_service.go b/pkg/apis/istio/v1alpha3/virtual_service.go index c0298a66..8b4c12f0 100644 --- a/pkg/apis/istio/v1alpha3/virtual_service.go +++ b/pkg/apis/istio/v1alpha3/virtual_service.go @@ -345,11 +345,11 @@ type HTTPRoute struct { type Headers struct { // Header manipulation rules to apply before forwarding a request // to the destination service - Request HeaderOperations `json:"request,omitempty"` + Request *HeaderOperations `json:"request,omitempty"` // Header manipulation rules to apply before returning a response // to the caller - Response HeaderOperations `json:"response,omitempty"` + Response *HeaderOperations `json:"response,omitempty"` } // HeaderOperations Describes the header manipulations to apply diff --git a/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go index f3619989..2d137c8c 100644 --- a/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go +++ b/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go @@ -339,8 +339,16 @@ func (in *HeaderOperations) DeepCopy() *HeaderOperations { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Headers) DeepCopyInto(out *Headers) { *out = *in - in.Request.DeepCopyInto(&out.Request) - in.Response.DeepCopyInto(&out.Response) + if in.Request != nil { + in, out := &in.Request, &out.Request + *out = new(HeaderOperations) + (*in).DeepCopyInto(*out) + } + if in.Response != nil { + in, out := &in.Response, &out.Response + *out = new(HeaderOperations) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/router/istio.go b/pkg/router/istio.go index 17b802c9..3a62dc97 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -24,12 +24,12 @@ type IstioRouter struct { } // Sync creates or updates the Istio virtual service -func (ir *IstioRouter) Sync(cd *flaggerv1.Canary) error { - targetName := cd.Spec.TargetRef.Name +func (ir *IstioRouter) Sync(canary *flaggerv1.Canary) error { + targetName := canary.Spec.TargetRef.Name primaryName := fmt.Sprintf("%s-primary", targetName) // set hosts and add the ClusterIP service host if it doesn't exists - hosts := cd.Spec.Service.Hosts + hosts := canary.Spec.Service.Hosts var hasServiceHost bool for _, h := range hosts { if h == targetName { @@ -42,7 +42,7 @@ func (ir *IstioRouter) Sync(cd *flaggerv1.Canary) error { } // set gateways and add the mesh gateway if it doesn't exists - gateways := cd.Spec.Service.Gateways + gateways := canary.Spec.Service.Gateways var hasMeshGateway bool for _, g := range gateways { if g == "mesh" { @@ -60,7 +60,7 @@ func (ir *IstioRouter) Sync(cd *flaggerv1.Canary) error { Destination: istiov1alpha3.Destination{ Host: primaryName, Port: istiov1alpha3.PortSelector{ - Number: uint32(cd.Spec.Service.Port), + Number: uint32(canary.Spec.Service.Port), }, }, Weight: 100, @@ -69,36 +69,37 @@ func (ir *IstioRouter) Sync(cd *flaggerv1.Canary) error { Destination: istiov1alpha3.Destination{ Host: fmt.Sprintf("%s-canary", targetName), Port: istiov1alpha3.PortSelector{ - Number: uint32(cd.Spec.Service.Port), + Number: uint32(canary.Spec.Service.Port), }, }, Weight: 0, }, } + newSpec := istiov1alpha3.VirtualServiceSpec{ Hosts: hosts, Gateways: gateways, Http: []istiov1alpha3.HTTPRoute{ { - Match: cd.Spec.Service.Match, - Rewrite: cd.Spec.Service.Rewrite, - Timeout: cd.Spec.Service.Timeout, - Retries: cd.Spec.Service.Retries, - AppendHeaders: cd.Spec.Service.AppendHeaders, + Match: canary.Spec.Service.Match, + Rewrite: canary.Spec.Service.Rewrite, + Timeout: canary.Spec.Service.Timeout, + Retries: canary.Spec.Service.Retries, + AppendHeaders: setHeaders(canary), Route: route, }, }, } - virtualService, err := ir.istioClient.NetworkingV1alpha3().VirtualServices(cd.Namespace).Get(targetName, metav1.GetOptions{}) + virtualService, err := ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Get(targetName, metav1.GetOptions{}) // insert if errors.IsNotFound(err) { virtualService = &istiov1alpha3.VirtualService{ ObjectMeta: metav1.ObjectMeta{ Name: targetName, - Namespace: cd.Namespace, + Namespace: canary.Namespace, OwnerReferences: []metav1.OwnerReference{ - *metav1.NewControllerRef(cd, schema.GroupVersionKind{ + *metav1.NewControllerRef(canary, schema.GroupVersionKind{ Group: flaggerv1.SchemeGroupVersion.Group, Version: flaggerv1.SchemeGroupVersion.Version, Kind: flaggerv1.CanaryKind, @@ -107,17 +108,17 @@ func (ir *IstioRouter) Sync(cd *flaggerv1.Canary) error { }, Spec: newSpec, } - _, err = ir.istioClient.NetworkingV1alpha3().VirtualServices(cd.Namespace).Create(virtualService) + _, err = ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Create(virtualService) if err != nil { - return fmt.Errorf("VirtualService %s.%s create error %v", targetName, cd.Namespace, err) + return fmt.Errorf("VirtualService %s.%s create error %v", targetName, canary.Namespace, err) } - ir.logger.With("canary", fmt.Sprintf("%s.%s", cd.Name, cd.Namespace)). - Infof("VirtualService %s.%s created", virtualService.GetName(), cd.Namespace) + ir.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). + Infof("VirtualService %s.%s created", virtualService.GetName(), canary.Namespace) return nil } if err != nil { - return fmt.Errorf("VirtualService %s.%s query error %v", targetName, cd.Namespace, err) + return fmt.Errorf("VirtualService %s.%s query error %v", targetName, canary.Namespace, err) } // update service but keep the original destination weights @@ -128,12 +129,12 @@ func (ir *IstioRouter) Sync(cd *flaggerv1.Canary) error { if len(virtualService.Spec.Http) > 0 { vtClone.Spec.Http[0].Route = virtualService.Spec.Http[0].Route } - _, err = ir.istioClient.NetworkingV1alpha3().VirtualServices(cd.Namespace).Update(vtClone) + _, err = ir.istioClient.NetworkingV1alpha3().VirtualServices(canary.Namespace).Update(vtClone) if err != nil { - return fmt.Errorf("VirtualService %s.%s update error %v", targetName, cd.Namespace, err) + return fmt.Errorf("VirtualService %s.%s update error %v", targetName, canary.Namespace, err) } - ir.logger.With("canary", fmt.Sprintf("%s.%s", cd.Name, cd.Namespace)). - Infof("VirtualService %s.%s updated", virtualService.GetName(), cd.Namespace) + ir.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). + Infof("VirtualService %s.%s updated", virtualService.GetName(), canary.Namespace) } } @@ -200,7 +201,7 @@ func (ir *IstioRouter) SetRoutes( Rewrite: canary.Spec.Service.Rewrite, Timeout: canary.Spec.Service.Timeout, Retries: canary.Spec.Service.Retries, - AppendHeaders: canary.Spec.Service.AppendHeaders, + AppendHeaders: setHeaders(canary), Route: []istiov1alpha3.DestinationWeight{ { Destination: istiov1alpha3.Destination{ @@ -231,3 +232,15 @@ func (ir *IstioRouter) SetRoutes( } return nil } + +// setHeaders applies headers before forwarding a request to the destination service +// compatible with Istio 1.0.x and 1.1.0 +func setHeaders(canary *flaggerv1.Canary) (headers map[string]string) { + if canary.Spec.Service.Headers != nil && + canary.Spec.Service.Headers.Request != nil && + len(canary.Spec.Service.Headers.Request.Set) > 0 { + headers = canary.Spec.Service.Headers.Request.Set + } + + return +} From fe7547d83e4395eb5072ba81b6c75e21ef5f3096 Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Wed, 6 Mar 2019 12:42:34 +0200 Subject: [PATCH 3/6] Update Envoy headers example --- README.md | 10 +++--- artifacts/canaries/canary.yaml | 10 +++--- docs/gitbook/how-it-works.md | 62 ++++++++++++++-------------------- 3 files changed, 38 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index b46b32b5..347cb276 100644 --- a/README.md +++ b/README.md @@ -107,10 +107,12 @@ spec: rewrite: uri: / # Envoy timeout and retry policy (optional) - appendHeaders: - x-envoy-upstream-rq-timeout-ms: "15000" - x-envoy-max-retries: "10" - x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" + headers: + request: + set: + x-envoy-upstream-rq-timeout-ms: "15000" + x-envoy-max-retries: "10" + x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" # promote the canary without analysing it (default false) skipAnalysis: false # define the canary analysis timing and KPIs diff --git a/artifacts/canaries/canary.yaml b/artifacts/canaries/canary.yaml index 28d5f299..8ca0275f 100644 --- a/artifacts/canaries/canary.yaml +++ b/artifacts/canaries/canary.yaml @@ -34,10 +34,12 @@ spec: rewrite: uri: / # Envoy timeout and retry policy (optional) - appendHeaders: - x-envoy-upstream-rq-timeout-ms: "15000" - x-envoy-max-retries: "10" - x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" + headers: + request: + set: + x-envoy-upstream-rq-timeout-ms: "15000" + x-envoy-max-retries: "10" + x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" # promote the canary without analysing it (default false) skipAnalysis: false canaryAnalysis: diff --git a/docs/gitbook/how-it-works.md b/docs/gitbook/how-it-works.md index 0a897ff0..61729b3d 100644 --- a/docs/gitbook/how-it-works.md +++ b/docs/gitbook/how-it-works.md @@ -39,18 +39,6 @@ spec: # Istio virtual service host names (optional) hosts: - podinfo.example.com - # HTTP match conditions (optional) - match: - - uri: - prefix: / - # HTTP rewrite (optional) - rewrite: - uri: / - # Envoy timeout and retry policy (optional) - appendHeaders: - x-envoy-upstream-rq-timeout-ms: "15000" - x-envoy-max-retries: "10" - x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" # promote the canary without analysing it (default false) skipAnalysis: false # define the canary analysis timing and KPIs @@ -138,10 +126,12 @@ metadata: rewrite: uri: / # Envoy timeout and retry policy (optional) - appendHeaders: - x-envoy-upstream-rq-timeout-ms: "15000" - x-envoy-max-retries: "10" - x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" + headers: + request: + set: + x-envoy-upstream-rq-timeout-ms: "15000" + x-envoy-max-retries: "10" + x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" # retry policy when a HTTP request fails (optional) retries: attempts: 3 @@ -171,26 +161,26 @@ spec: - frontend.example.com - frontend http: - - match: - - uri: - prefix: / - rewrite: - uri: / - appendHeaders: - x-envoy-upstream-rq-timeout-ms: "15000" - x-envoy-max-retries: "10" - x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" - route: - - destination: - host: frontend-primary - port: - number: 9898 - weight: 100 - - destination: - host: frontend-canary - port: - number: 9898 - weight: 0 + - appendHeaders: + x-envoy-max-retries: "10" + x-envoy-retry-on: gateway-error,connect-failure,refused-stream + x-envoy-upstream-rq-timeout-ms: "15000" + match: + - uri: + prefix: / + rewrite: + uri: / + route: + - destination: + host: podinfo-primary + port: + number: 9898 + weight: 100 + - destination: + host: podinfo-canary + port: + number: 9898 + weight: 0 ``` Flagger keeps in sync the virtual service with the canary service spec. Any direct modification of the virtual From eab7f126a6b9fd323f7cee07d462d5d83fc14959 Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Wed, 6 Mar 2019 13:45:46 +0200 Subject: [PATCH 4/6] Use request.add for header append operation --- README.md | 2 +- artifacts/canaries/canary.yaml | 2 +- docs/gitbook/how-it-works.md | 2 +- pkg/router/istio.go | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 347cb276..e39710e8 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ spec: # Envoy timeout and retry policy (optional) headers: request: - set: + add: x-envoy-upstream-rq-timeout-ms: "15000" x-envoy-max-retries: "10" x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" diff --git a/artifacts/canaries/canary.yaml b/artifacts/canaries/canary.yaml index 8ca0275f..6e67c885 100644 --- a/artifacts/canaries/canary.yaml +++ b/artifacts/canaries/canary.yaml @@ -36,7 +36,7 @@ spec: # Envoy timeout and retry policy (optional) headers: request: - set: + add: x-envoy-upstream-rq-timeout-ms: "15000" x-envoy-max-retries: "10" x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" diff --git a/docs/gitbook/how-it-works.md b/docs/gitbook/how-it-works.md index 61729b3d..5935a819 100644 --- a/docs/gitbook/how-it-works.md +++ b/docs/gitbook/how-it-works.md @@ -128,7 +128,7 @@ metadata: # Envoy timeout and retry policy (optional) headers: request: - set: + add: x-envoy-upstream-rq-timeout-ms: "15000" x-envoy-max-retries: "10" x-envoy-retry-on: "gateway-error,connect-failure,refused-stream" diff --git a/pkg/router/istio.go b/pkg/router/istio.go index 3a62dc97..fd4c137d 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -85,7 +85,7 @@ func (ir *IstioRouter) Sync(canary *flaggerv1.Canary) error { Rewrite: canary.Spec.Service.Rewrite, Timeout: canary.Spec.Service.Timeout, Retries: canary.Spec.Service.Retries, - AppendHeaders: setHeaders(canary), + AppendHeaders: addHeaders(canary), Route: route, }, }, @@ -201,7 +201,7 @@ func (ir *IstioRouter) SetRoutes( Rewrite: canary.Spec.Service.Rewrite, Timeout: canary.Spec.Service.Timeout, Retries: canary.Spec.Service.Retries, - AppendHeaders: setHeaders(canary), + AppendHeaders: addHeaders(canary), Route: []istiov1alpha3.DestinationWeight{ { Destination: istiov1alpha3.Destination{ @@ -233,13 +233,13 @@ func (ir *IstioRouter) SetRoutes( return nil } -// setHeaders applies headers before forwarding a request to the destination service +// addHeaders applies headers before forwarding a request to the destination service // compatible with Istio 1.0.x and 1.1.0 -func setHeaders(canary *flaggerv1.Canary) (headers map[string]string) { +func addHeaders(canary *flaggerv1.Canary) (headers map[string]string) { if canary.Spec.Service.Headers != nil && canary.Spec.Service.Headers.Request != nil && - len(canary.Spec.Service.Headers.Request.Set) > 0 { - headers = canary.Spec.Service.Headers.Request.Set + len(canary.Spec.Service.Headers.Request.Add) > 0 { + headers = canary.Spec.Service.Headers.Request.Add } return From 1d4dfb0883eee3a0be894fc735334ce4c7b69797 Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Wed, 6 Mar 2019 13:46:19 +0200 Subject: [PATCH 5/6] Add request header add test --- pkg/router/istio_test.go | 30 ++++++++++++++++++++++++++++++ pkg/router/router_test.go | 8 ++++++++ 2 files changed, 38 insertions(+) diff --git a/pkg/router/istio_test.go b/pkg/router/istio_test.go index a5f6f9d6..807f80f1 100644 --- a/pkg/router/istio_test.go +++ b/pkg/router/istio_test.go @@ -177,3 +177,33 @@ func TestIstioRouter_GetRoutes(t *testing.T) { t.Errorf("Got canary weight %v wanted %v", c, 0) } } + +func TestIstioRouter_HTTPRequestHeaders(t *testing.T) { + mocks := setupfakeClients() + router := &IstioRouter{ + logger: mocks.logger, + flaggerClient: mocks.flaggerClient, + istioClient: mocks.istioClient, + kubeClient: mocks.kubeClient, + } + + err := router.Sync(mocks.canary) + if err != nil { + t.Fatal(err.Error()) + } + + // test insert + vs, err := mocks.istioClient.NetworkingV1alpha3().VirtualServices("default").Get("podinfo", metav1.GetOptions{}) + if err != nil { + t.Fatal(err.Error()) + } + + if len(vs.Spec.Http) != 1 { + t.Fatalf("Got HTTPRoute %v wanted %v", len(vs.Spec.Http), 1) + } + + timeout := vs.Spec.Http[0].AppendHeaders["x-envoy-upstream-rq-timeout-ms"] + if timeout != "15000" { + t.Errorf("Got timeout %v wanted %v", timeout, "15000") + } +} diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go index 7f912143..037c3391 100644 --- a/pkg/router/router_test.go +++ b/pkg/router/router_test.go @@ -2,6 +2,7 @@ package router import ( "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3" + istiov1alpha3 "github.com/stefanprodan/flagger/pkg/apis/istio/v1alpha3" clientset "github.com/stefanprodan/flagger/pkg/client/clientset/versioned" fakeFlagger "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/fake" "github.com/stefanprodan/flagger/pkg/logging" @@ -57,6 +58,13 @@ func newMockCanary() *v1alpha3.Canary { }, Service: v1alpha3.CanaryService{ Port: 9898, + Headers: &istiov1alpha3.Headers{ + Request: &istiov1alpha3.HeaderOperations{ + Set: map[string]string{ + "x-envoy-upstream-rq-timeout-ms": "15000", + }, + }, + }, }, CanaryAnalysis: v1alpha3.CanaryAnalysis{ Threshold: 10, StepWeight: 10, From 8b6aa73df094a9405a2b5399e8b71bd656d64eed Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Wed, 6 Mar 2019 13:51:04 +0200 Subject: [PATCH 6/6] Fix request header test --- pkg/router/router_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go index 037c3391..5d12aa25 100644 --- a/pkg/router/router_test.go +++ b/pkg/router/router_test.go @@ -60,7 +60,7 @@ func newMockCanary() *v1alpha3.Canary { Port: 9898, Headers: &istiov1alpha3.Headers{ Request: &istiov1alpha3.HeaderOperations{ - Set: map[string]string{ + Add: map[string]string{ "x-envoy-upstream-rq-timeout-ms": "15000", }, },