Repository: fluxcd/flagger
Pull request #777 (2021-01-12 12:04:40)

Update HTTPMatchRequest to match Istio's definitions
### Summary
Fix: #776 , #678
 
[artifacts/flagger/crd.yaml](https://github.com/fluxcd/flagger/blob/main/artifacts/flagger/crd.yaml): Update spec.service.match and analysis.match based on [Istio's definitions](https://github.com/istio/api/blob/1.8.1/kubernetes/customresourcedefinitions.gen.yaml).
[pkg/apis/istio/v1alpha3/virtual_service.go](pkg/apis/istio/v1alpha3/virtual_service.go): Update based on [Istio - virtual_service.pb.go](https://github.com/istio/api/blob/1.8.1/networking/v1alpha3/virtual_service.pb.go).
[pkg/router/istio.go](https://github.com/fluxcd/flagger/blob/main/pkg/router/istio.go): Changed the merge logic of analysis.match and service.match to avoid missing service.match.

### Supplement

As far as I can see in istio.go, Basically when creating VirtualService, Http.Match is just copied from canary.Spec.Service.Match.
So I thnk no change is necessary.
https://github.com/fluxcd/flagger/blob/main/pkg/router/istio.go#L169
https://github.com/fluxcd/flagger/blob/main/pkg/router/istio.go#L193

The analysis part had a specific merge logic, so I changed this code.
https://github.com/fluxcd/flagger/blob/main/pkg/router/istio.go#L442




Patch:
diff --git a/artifacts/flagger/crd.yaml b/artifacts/flagger/crd.yaml
index b4f490ea..3713834f 100644
--- a/artifacts/flagger/crd.yaml
+++ b/artifacts/flagger/crd.yaml
@@ -172,15 +172,94 @@ spec:
                       description: URI match conditions
                       type: array
                       items:
-                        type: object
                         properties:
-                          uri:
+                          authority:
+                            oneOf:
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
+                            properties:
+                              exact:
+                                format: string
+                                type: string
+                              prefix:
+                                format: string
+                                type: string
+                              regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                format: string
+                                type: string
                             type: object
+                          gateways:
+                            description:
+                              Names of gateways where the rule should be
+                              applied.
+                            items:
+                              format: string
+                              type: string
+                            type: array
+                          headers:
+                            additionalProperties:
+                              oneOf:
+                                - not:
+                                    anyOf:
+                                      - required:
+                                          - exact
+                                      - required:
+                                          - prefix
+                                      - required:
+                                          - regex
+                                - required:
+                                    - exact
+                                - required:
+                                    - prefix
+                                - required:
+                                    - regex
+                              properties:
+                                exact:
+                                  format: string
+                                  type: string
+                                prefix:
+                                  format: string
+                                  type: string
+                                regex:
+                                  description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                  format: string
+                                  type: string
+                              type: object
+                            type: object
+                          ignoreUriCase:
+                            description:
+                              Flag to specify whether the URI matching should
+                              be case-insensitive.
+                            type: boolean
+                          method:
                             oneOf:
-                              - required: ["exact"]
-                              - required: ["prefix"]
-                              - required: ["suffix"]
-                              - required: ["regex"]
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
                             properties:
                               exact:
                                 format: string
@@ -188,12 +267,152 @@ spec:
                               prefix:
                                 format: string
                                 type: string
-                              suffix:
+                              regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                format: string
+                                type: string
+                            type: object
+                          name:
+                            description: The name assigned to a match.
+                            format: string
+                            type: string
+                          port:
+                            description:
+                              Specifies the ports on the host that is being
+                              addressed.
+                            type: integer
+                          queryParams:
+                            additionalProperties:
+                              oneOf:
+                                - not:
+                                    anyOf:
+                                      - required:
+                                          - exact
+                                      - required:
+                                          - prefix
+                                      - required:
+                                          - regex
+                                - required:
+                                    - exact
+                                - required:
+                                    - prefix
+                                - required:
+                                    - regex
+                              properties:
+                                exact:
+                                  format: string
+                                  type: string
+                                prefix:
+                                  format: string
+                                  type: string
+                                regex:
+                                  description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                  format: string
+                                  type: string
+                              type: object
+                            description: Query parameters for matching.
+                            type: object
+                          scheme:
+                            oneOf:
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
+                            properties:
+                              exact:
+                                format: string
+                                type: string
+                              prefix:
+                                format: string
+                                type: string
+                              regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                format: string
+                                type: string
+                            type: object
+                          sourceLabels:
+                            additionalProperties:
+                              format: string
+                              type: string
+                            type: object
+                          sourceNamespace:
+                            description:
+                              Source namespace constraining the applicability
+                              of a rule to workloads in that namespace.
+                            format: string
+                            type: string
+                          uri:
+                            oneOf:
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
+                            properties:
+                              exact:
+                                format: string
+                                type: string
+                              prefix:
                                 format: string
                                 type: string
                               regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
                                 format: string
                                 type: string
+                            type: object
+                          withoutHeaders:
+                            additionalProperties:
+                              oneOf:
+                                - not:
+                                    anyOf:
+                                      - required:
+                                          - exact
+                                      - required:
+                                          - prefix
+                                      - required:
+                                          - regex
+                                - required:
+                                    - exact
+                                - required:
+                                    - prefix
+                                - required:
+                                    - regex
+                              properties:
+                                exact:
+                                  format: string
+                                  type: string
+                                prefix:
+                                  format: string
+                                  type: string
+                                regex:
+                                  description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                  format: string
+                                  type: string
+                              type: object
+                            description:
+                              withoutHeader has the same syntax with the
+                              header, but has opposite meaning.
+                            type: object
+                        type: object
                     retries:
                       description: Retry policy for HTTP requests
                       type: object
diff --git a/charts/flagger/crds/crd.yaml b/charts/flagger/crds/crd.yaml
index b4f490ea..3713834f 100644
--- a/charts/flagger/crds/crd.yaml
+++ b/charts/flagger/crds/crd.yaml
@@ -172,15 +172,94 @@ spec:
                       description: URI match conditions
                       type: array
                       items:
-                        type: object
                         properties:
-                          uri:
+                          authority:
+                            oneOf:
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
+                            properties:
+                              exact:
+                                format: string
+                                type: string
+                              prefix:
+                                format: string
+                                type: string
+                              regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                format: string
+                                type: string
                             type: object
+                          gateways:
+                            description:
+                              Names of gateways where the rule should be
+                              applied.
+                            items:
+                              format: string
+                              type: string
+                            type: array
+                          headers:
+                            additionalProperties:
+                              oneOf:
+                                - not:
+                                    anyOf:
+                                      - required:
+                                          - exact
+                                      - required:
+                                          - prefix
+                                      - required:
+                                          - regex
+                                - required:
+                                    - exact
+                                - required:
+                                    - prefix
+                                - required:
+                                    - regex
+                              properties:
+                                exact:
+                                  format: string
+                                  type: string
+                                prefix:
+                                  format: string
+                                  type: string
+                                regex:
+                                  description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                  format: string
+                                  type: string
+                              type: object
+                            type: object
+                          ignoreUriCase:
+                            description:
+                              Flag to specify whether the URI matching should
+                              be case-insensitive.
+                            type: boolean
+                          method:
                             oneOf:
-                              - required: ["exact"]
-                              - required: ["prefix"]
-                              - required: ["suffix"]
-                              - required: ["regex"]
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
                             properties:
                               exact:
                                 format: string
@@ -188,12 +267,152 @@ spec:
                               prefix:
                                 format: string
                                 type: string
-                              suffix:
+                              regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                format: string
+                                type: string
+                            type: object
+                          name:
+                            description: The name assigned to a match.
+                            format: string
+                            type: string
+                          port:
+                            description:
+                              Specifies the ports on the host that is being
+                              addressed.
+                            type: integer
+                          queryParams:
+                            additionalProperties:
+                              oneOf:
+                                - not:
+                                    anyOf:
+                                      - required:
+                                          - exact
+                                      - required:
+                                          - prefix
+                                      - required:
+                                          - regex
+                                - required:
+                                    - exact
+                                - required:
+                                    - prefix
+                                - required:
+                                    - regex
+                              properties:
+                                exact:
+                                  format: string
+                                  type: string
+                                prefix:
+                                  format: string
+                                  type: string
+                                regex:
+                                  description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                  format: string
+                                  type: string
+                              type: object
+                            description: Query parameters for matching.
+                            type: object
+                          scheme:
+                            oneOf:
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
+                            properties:
+                              exact:
+                                format: string
+                                type: string
+                              prefix:
+                                format: string
+                                type: string
+                              regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                format: string
+                                type: string
+                            type: object
+                          sourceLabels:
+                            additionalProperties:
+                              format: string
+                              type: string
+                            type: object
+                          sourceNamespace:
+                            description:
+                              Source namespace constraining the applicability
+                              of a rule to workloads in that namespace.
+                            format: string
+                            type: string
+                          uri:
+                            oneOf:
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
+                            properties:
+                              exact:
+                                format: string
+                                type: string
+                              prefix:
                                 format: string
                                 type: string
                               regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
                                 format: string
                                 type: string
+                            type: object
+                          withoutHeaders:
+                            additionalProperties:
+                              oneOf:
+                                - not:
+                                    anyOf:
+                                      - required:
+                                          - exact
+                                      - required:
+                                          - prefix
+                                      - required:
+                                          - regex
+                                - required:
+                                    - exact
+                                - required:
+                                    - prefix
+                                - required:
+                                    - regex
+                              properties:
+                                exact:
+                                  format: string
+                                  type: string
+                                prefix:
+                                  format: string
+                                  type: string
+                                regex:
+                                  description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                  format: string
+                                  type: string
+                              type: object
+                            description:
+                              withoutHeader has the same syntax with the
+                              header, but has opposite meaning.
+                            type: object
+                        type: object
                     retries:
                       description: Retry policy for HTTP requests
                       type: object
diff --git a/kustomize/base/flagger/crd.yaml b/kustomize/base/flagger/crd.yaml
index b4f490ea..3713834f 100644
--- a/kustomize/base/flagger/crd.yaml
+++ b/kustomize/base/flagger/crd.yaml
@@ -172,15 +172,94 @@ spec:
                       description: URI match conditions
                       type: array
                       items:
-                        type: object
                         properties:
-                          uri:
+                          authority:
+                            oneOf:
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
+                            properties:
+                              exact:
+                                format: string
+                                type: string
+                              prefix:
+                                format: string
+                                type: string
+                              regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                format: string
+                                type: string
                             type: object
+                          gateways:
+                            description:
+                              Names of gateways where the rule should be
+                              applied.
+                            items:
+                              format: string
+                              type: string
+                            type: array
+                          headers:
+                            additionalProperties:
+                              oneOf:
+                                - not:
+                                    anyOf:
+                                      - required:
+                                          - exact
+                                      - required:
+                                          - prefix
+                                      - required:
+                                          - regex
+                                - required:
+                                    - exact
+                                - required:
+                                    - prefix
+                                - required:
+                                    - regex
+                              properties:
+                                exact:
+                                  format: string
+                                  type: string
+                                prefix:
+                                  format: string
+                                  type: string
+                                regex:
+                                  description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                  format: string
+                                  type: string
+                              type: object
+                            type: object
+                          ignoreUriCase:
+                            description:
+                              Flag to specify whether the URI matching should
+                              be case-insensitive.
+                            type: boolean
+                          method:
                             oneOf:
-                              - required: ["exact"]
-                              - required: ["prefix"]
-                              - required: ["suffix"]
-                              - required: ["regex"]
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
                             properties:
                               exact:
                                 format: string
@@ -188,12 +267,152 @@ spec:
                               prefix:
                                 format: string
                                 type: string
-                              suffix:
+                              regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                format: string
+                                type: string
+                            type: object
+                          name:
+                            description: The name assigned to a match.
+                            format: string
+                            type: string
+                          port:
+                            description:
+                              Specifies the ports on the host that is being
+                              addressed.
+                            type: integer
+                          queryParams:
+                            additionalProperties:
+                              oneOf:
+                                - not:
+                                    anyOf:
+                                      - required:
+                                          - exact
+                                      - required:
+                                          - prefix
+                                      - required:
+                                          - regex
+                                - required:
+                                    - exact
+                                - required:
+                                    - prefix
+                                - required:
+                                    - regex
+                              properties:
+                                exact:
+                                  format: string
+                                  type: string
+                                prefix:
+                                  format: string
+                                  type: string
+                                regex:
+                                  description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                  format: string
+                                  type: string
+                              type: object
+                            description: Query parameters for matching.
+                            type: object
+                          scheme:
+                            oneOf:
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
+                            properties:
+                              exact:
+                                format: string
+                                type: string
+                              prefix:
+                                format: string
+                                type: string
+                              regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                format: string
+                                type: string
+                            type: object
+                          sourceLabels:
+                            additionalProperties:
+                              format: string
+                              type: string
+                            type: object
+                          sourceNamespace:
+                            description:
+                              Source namespace constraining the applicability
+                              of a rule to workloads in that namespace.
+                            format: string
+                            type: string
+                          uri:
+                            oneOf:
+                              - not:
+                                  anyOf:
+                                    - required:
+                                        - exact
+                                    - required:
+                                        - prefix
+                                    - required:
+                                        - regex
+                              - required:
+                                  - exact
+                              - required:
+                                  - prefix
+                              - required:
+                                  - regex
+                            properties:
+                              exact:
+                                format: string
+                                type: string
+                              prefix:
                                 format: string
                                 type: string
                               regex:
+                                description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
                                 format: string
                                 type: string
+                            type: object
+                          withoutHeaders:
+                            additionalProperties:
+                              oneOf:
+                                - not:
+                                    anyOf:
+                                      - required:
+                                          - exact
+                                      - required:
+                                          - prefix
+                                      - required:
+                                          - regex
+                                - required:
+                                    - exact
+                                - required:
+                                    - prefix
+                                - required:
+                                    - regex
+                              properties:
+                                exact:
+                                  format: string
+                                  type: string
+                                prefix:
+                                  format: string
+                                  type: string
+                                regex:
+                                  description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
+                                  format: string
+                                  type: string
+                              type: object
+                            description:
+                              withoutHeader has the same syntax with the
+                              header, but has opposite meaning.
+                            type: object
+                        type: object
                     retries:
                       description: Retry policy for HTTP requests
                       type: object
diff --git a/pkg/apis/istio/v1alpha3/virtual_service.go b/pkg/apis/istio/v1alpha3/virtual_service.go
index b8c762e3..60f97628 100644
--- a/pkg/apis/istio/v1alpha3/virtual_service.go
+++ b/pkg/apis/istio/v1alpha3/virtual_service.go
@@ -394,6 +394,11 @@ type HeaderOperations struct {
 //
 // HTTPMatchRequest CANNOT be empty.
 type HTTPMatchRequest struct {
+	// The name assigned to a match. The match's name will be
+	// concatenated with the parent route's name and will be logged in
+	// the access logs for requests matching this route.
+	Name string `json:"name,omitempty"`
+
 	// URI to match
 	// values are case-sensitive and formatted as follows:
 	//
@@ -467,6 +472,35 @@ type HTTPMatchRequest struct {
 	// at the top of the VirtualService (if any) are overridden. The gateway match is
 	// independent of sourceLabels.
 	Gateways []string `json:"gateways,omitempty"`
+
+	// Query parameters for matching.
+	//
+	// Ex:
+	// - For a query parameter like "?key=true", the map key would be "key" and
+	//   the string match could be defined as `exact: "true"`.
+	// - For a query parameter like "?key", the map key would be "key" and the
+	//   string match could be defined as `exact: ""`.
+	// - For a query parameter like "?key=123", the map key would be "key" and the
+	//   string match could be defined as `regex: "\d+$"`. Note that this
+	//   configuration will only match values like "123" but not "a123" or "123a".
+	//
+	// **Note:** `prefix` matching is currently not supported.
+	QueryParams map[string]v1alpha1.StringMatch `json:"queryParams,omitempty"`
+
+	// Flag to specify whether the URI matching should be case-insensitive.
+	//
+	// **Note:** The case will be ignored only in the case of `exact` and `prefix`
+	// URI matches.
+	IgnoreUriCase bool `json:"ignoreUriCase,omitempty"`
+
+	// withoutHeader has the same syntax with the header, but has opposite meaning.
+	// If a header is matched with a matching rule among withoutHeader, the traffic becomes not matched one.
+	WithoutHeaders map[string]v1alpha1.StringMatch `json:"withoutHeaders,omitempty"`
+
+	// Source namespace constraining the applicability of a rule to workloads in that namespace.
+	// If the VirtualService has a list of gateways specified in the top-level `gateways` field,
+	// it must include the reserved gateway `mesh` for this field to be applicable.
+	SourceNamespace string `json:"sourceNamespace,omitempty"`
 }
 
 type DestinationWeight struct {
diff --git a/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go
index c0173ba2..61050fa0 100644
--- a/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go
+++ b/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go
@@ -329,6 +329,20 @@ func (in *HTTPMatchRequest) DeepCopyInto(out *HTTPMatchRequest) {
 		*out = make([]string, len(*in))
 		copy(*out, *in)
 	}
+	if in.QueryParams != nil {
+		in, out := &in.QueryParams, &out.QueryParams
+		*out = make(map[string]v1alpha1.StringMatch, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	if in.WithoutHeaders != nil {
+		in, out := &in.WithoutHeaders, &out.WithoutHeaders
+		*out = make(map[string]v1alpha1.StringMatch, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
 	return
 }
 
diff --git a/pkg/router/istio.go b/pkg/router/istio.go
index a42b6e6d..7cf6d6f1 100644
--- a/pkg/router/istio.go
+++ b/pkg/router/istio.go
@@ -440,15 +440,26 @@ func (ir *IstioRouter) Finalize(canary *flaggerv1.Canary) error {
 
 // mergeMatchConditions appends the URI match rules to canary conditions
 func mergeMatchConditions(canary, defaults []istiov1alpha3.HTTPMatchRequest) []istiov1alpha3.HTTPMatchRequest {
-	for i := range canary {
+	if len(defaults) == 0 {
+		return canary
+	}
+
+	merged := make([]istiov1alpha3.HTTPMatchRequest, len(canary)*len(defaults))
+	num := 0
+	for _, c := range canary {
 		for _, d := range defaults {
-			if d.Uri != nil {
-				canary[i].Uri = d.Uri
+			merged[num] = *d.DeepCopy()
+			if c.Headers != nil {
+				merged[num].Headers = c.Headers
+			}
+			if c.SourceLabels != nil {
+				merged[num].SourceLabels = c.SourceLabels
 			}
+			num++
 		}
 	}
 
-	return canary
+	return merged
 }
 
 // makeDestination returns a an destination weight for the specified host


Test patch:
diff --git a/pkg/router/istio_test.go b/pkg/router/istio_test.go
index 350acc57..5ec52012 100644
--- a/pkg/router/istio_test.go
+++ b/pkg/router/istio_test.go
@@ -27,6 +27,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/fluxcd/flagger/pkg/apis/flagger/v1beta1"
+	istiov1alpha1 "github.com/fluxcd/flagger/pkg/apis/istio/common/v1alpha1"
 	istiov1alpha3 "github.com/fluxcd/flagger/pkg/apis/istio/v1alpha3"
 )
 
@@ -492,3 +493,74 @@ func TestIstioRouter_Finalize(t *testing.T) {
 		}
 	}
 }
+
+func TestIstioRouter_Match(t *testing.T) {
+	mocks := newFixture(nil)
+	router := &IstioRouter{
+		logger:        mocks.logger,
+		flaggerClient: mocks.flaggerClient,
+		istioClient:   mocks.meshClient,
+		kubeClient:    mocks.kubeClient,
+	}
+
+	// service.match is not exists, analysis match is exists
+	err := router.Reconcile(mocks.abtest)
+	require.NoError(t, err)
+
+	// test insert
+	vs, err := mocks.meshClient.NetworkingV1alpha3().VirtualServices("default").Get(context.TODO(), "abtest", metav1.GetOptions{})
+	require.NoError(t, err)
+	assert.Len(t, vs.Spec.Http, 2)
+	assert.Len(t, vs.Spec.Http[0].Match, 1) // check for abtest-canary
+	require.Equal(t, vs.Spec.Http[0].Match[0].Headers["x-user-type"].Exact, "test")
+	assert.Len(t, vs.Spec.Http[1].Match, 0) // check for abtest-primary
+
+	// Test Case that is service.match exists and multiple analysis.match
+	mocks.abtest.Spec.Service.Match = []istiov1alpha3.HTTPMatchRequest{
+		{
+			Name: "podinfo",
+			Uri: &istiov1alpha1.StringMatch{
+				Prefix: "/podinfo",
+			},
+			Method: &istiov1alpha1.StringMatch{
+				Exact: "GET",
+			},
+			IgnoreUriCase: true,
+		},
+	}
+	mocks.abtest.Spec.Analysis.Match = []istiov1alpha3.HTTPMatchRequest{
+		{
+			Headers: map[string]istiov1alpha1.StringMatch{
+				"x-user-type": {
+					Exact: "test",
+				},
+				"x-auth-test": {
+					Exact: "test",
+				},
+			},
+		},
+		{
+			Headers: map[string]istiov1alpha1.StringMatch{
+				"x-session-id": {
+					Exact: "test",
+				},
+			},
+		},
+	}
+
+	// apply changes
+	err = router.Reconcile(mocks.abtest)
+	require.NoError(t, err)
+
+	vs, err = mocks.meshClient.NetworkingV1alpha3().VirtualServices("default").Get(context.TODO(), "abtest", metav1.GetOptions{})
+	require.NoError(t, err)
+	assert.Len(t, vs.Spec.Http, 2)
+	assert.Len(t, vs.Spec.Http[0].Match, 2) // check for abtest-canary
+	require.Equal(t, vs.Spec.Http[0].Match[0].Uri.Prefix, "/podinfo")
+	require.Equal(t, vs.Spec.Http[0].Match[0].Headers["x-user-type"].Exact, "test")
+	require.Equal(t, vs.Spec.Http[0].Match[0].Headers["x-auth-test"].Exact, "test")
+	require.Equal(t, vs.Spec.Http[0].Match[1].Uri.Prefix, "/podinfo")
+	require.Equal(t, vs.Spec.Http[0].Match[1].Headers["x-session-id"].Exact, "test")
+	assert.Len(t, vs.Spec.Http[1].Match, 1) // check for abtest-primary
+	require.Equal(t, vs.Spec.Http[1].Match[0].Uri.Prefix, "/podinfo")
+}
diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go
index c6e2de9c..9ecbd93d 100644
--- a/pkg/router/router_test.go
+++ b/pkg/router/router_test.go
@@ -116,9 +116,16 @@ func newTestCanary() *flaggerv1.Canary {
 					},
 				},
 				Match: []istiov1alpha3.HTTPMatchRequest{
-					{Uri: &istiov1alpha1.StringMatch{
-						Prefix: "/podinfo",
-					}},
+					{
+						Name: "podinfo",
+						Uri: &istiov1alpha1.StringMatch{
+							Prefix: "/podinfo",
+						},
+						Method: &istiov1alpha1.StringMatch{
+							Exact: "GET",
+						},
+						IgnoreUriCase: true,
+					},
 				},
 				Retries: &istiov1alpha3.HTTPRetry{
 					Attempts:      10,