From 287d291a32af201c8e7e0a1aceee1d2cf17d468c Mon Sep 17 00:00:00 2001 From: S-mishina Date: Wed, 15 May 2024 23:17:57 +0900 Subject: [PATCH 1/3] Support Istio FaultInjection Signed-off-by: S-mishina --- artifacts/flagger/crd.yaml | 35 +++++++++++++++++++++++ charts/flagger/crds/crd.yaml | 35 +++++++++++++++++++++++ kustomize/base/flagger/crd.yaml | 35 +++++++++++++++++++++++ pkg/apis/flagger/v1beta1/canary.go | 4 +++ pkg/apis/istio/v1beta1/virtual_service.go | 16 +++++++++-- pkg/router/istio.go | 6 ++++ 6 files changed, 128 insertions(+), 3 deletions(-) diff --git a/artifacts/flagger/crd.yaml b/artifacts/flagger/crd.yaml index 3a124a4d9..620e8047e 100644 --- a/artifacts/flagger/crd.yaml +++ b/artifacts/flagger/crd.yaml @@ -667,6 +667,41 @@ spec: type: array maxAge: type: string + FaultInjection: + description: Istio HTTP FaultInjection + type: object + properties: + delay: + description: Delay HTTP requests + type: object + properties: + fixedDelay: + description: The fixed delay to wait before returning a response + type: string + percent: + type: integer + minimum: 0 + maximum: 100 + percentage: + type: object + properties: + value: + type: number + abort: + description: Abort HTTP requests + type: object + properties: + httpStatus: + description: The HTTP status code to return + type: integer + grpcStatus: + description: The gRPC status code to return + type: string + percentage: + type: object + properties: + value: + type: number trafficPolicy: description: Istio traffic policy type: object diff --git a/charts/flagger/crds/crd.yaml b/charts/flagger/crds/crd.yaml index 3a124a4d9..620e8047e 100644 --- a/charts/flagger/crds/crd.yaml +++ b/charts/flagger/crds/crd.yaml @@ -667,6 +667,41 @@ spec: type: array maxAge: type: string + FaultInjection: + description: Istio HTTP FaultInjection + type: object + properties: + delay: + description: Delay HTTP requests + type: object + properties: + fixedDelay: + description: The fixed delay to wait before returning a response + type: string + percent: + type: integer + minimum: 0 + maximum: 100 + percentage: + type: object + properties: + value: + type: number + abort: + description: Abort HTTP requests + type: object + properties: + httpStatus: + description: The HTTP status code to return + type: integer + grpcStatus: + description: The gRPC status code to return + type: string + percentage: + type: object + properties: + value: + type: number trafficPolicy: description: Istio traffic policy type: object diff --git a/kustomize/base/flagger/crd.yaml b/kustomize/base/flagger/crd.yaml index 3a124a4d9..620e8047e 100644 --- a/kustomize/base/flagger/crd.yaml +++ b/kustomize/base/flagger/crd.yaml @@ -667,6 +667,41 @@ spec: type: array maxAge: type: string + FaultInjection: + description: Istio HTTP FaultInjection + type: object + properties: + delay: + description: Delay HTTP requests + type: object + properties: + fixedDelay: + description: The fixed delay to wait before returning a response + type: string + percent: + type: integer + minimum: 0 + maximum: 100 + percentage: + type: object + properties: + value: + type: number + abort: + description: Abort HTTP requests + type: object + properties: + httpStatus: + description: The HTTP status code to return + type: integer + grpcStatus: + description: The gRPC status code to return + type: string + percentage: + type: object + properties: + value: + type: number trafficPolicy: description: Istio traffic policy type: object diff --git a/pkg/apis/flagger/v1beta1/canary.go b/pkg/apis/flagger/v1beta1/canary.go index 93fe004ed..defd36966 100644 --- a/pkg/apis/flagger/v1beta1/canary.go +++ b/pkg/apis/flagger/v1beta1/canary.go @@ -218,6 +218,10 @@ type CanaryService struct { // Canary is the metadata to add to the canary service // +optional Canary *CustomMetadata `json:"canary,omitempty"` + + // fault injection policy for the generated virtual service + // +optional + Fault *istiov1beta1.HTTPFaultInjection `json:"FaultInjection,omitempty"` } // CanaryAnalysis is used to describe how the analysis should be done diff --git a/pkg/apis/istio/v1beta1/virtual_service.go b/pkg/apis/istio/v1beta1/virtual_service.go index bc4858709..340e9b9b9 100644 --- a/pkg/apis/istio/v1beta1/virtual_service.go +++ b/pkg/apis/istio/v1beta1/virtual_service.go @@ -850,9 +850,18 @@ type HTTPFaultInjection struct { // seconds. An optional _percent_ field, a value between 0 and 100, can // be used to only delay a certain percentage of requests. If left // unspecified, all request will be delayed. + +type PercentagePercent struct { + Value float64 `json:"value,omitempty"` +} + type InjectDelay struct { // Percentage of requests on which the delay will be injected (0-100). Percent int `json:"percent,omitempty"` + // Percentage of the traffic to be mirrored by the `mirror` field. + // If this field is absent, all the traffic (100%) will be mirrored. + // Max value is 100. + Percentage *PercentagePercent `json:"percentage,omitempty"` // REQUIRED. Add a fixed delay before forwarding the request. Format: // 1h/1m/1s/1ms. MUST be >=1ms. @@ -890,11 +899,12 @@ type InjectDelay struct { // and 100, is used to only abort a certain percentage of requests. If // not specified, all requests are aborted. type InjectAbort struct { - // Percentage of requests to be aborted with the error code provided (0-100). - Perecent int `json:"percent,omitempty"` - // REQUIRED. HTTP status code to use to abort the Http request. HttpStatus int `json:"httpStatus"` + // GRPC status code to use to abort the request + GrpcStatus string `json:"grpcstatus,omitempty"` + // Percentage of requests to be aborted with the error code provided. + Percentage *PercentagePercent `json:"percentage,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/router/istio.go b/pkg/router/istio.go index 75b3701a7..b5ea6539b 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -217,6 +217,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, + Fault: canary.Spec.Service.Fault, Route: canaryRoute, }, }, @@ -245,6 +246,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, + Fault: canary.Spec.Service.Fault, Route: canaryRoute, }, { @@ -254,6 +256,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, + Fault: canary.Spec.Service.Fault, Route: []istiov1beta1.HTTPRouteDestination{ makeDestination(canary, primaryName, 100), }, @@ -504,6 +507,7 @@ func (ir *IstioRouter) SetRoutes( Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, + Fault: canary.Spec.Service.Fault, Route: []istiov1beta1.HTTPRouteDestination{ makeDestination(canary, primaryName, primaryWeight), makeDestination(canary, canaryName, canaryWeight), @@ -619,6 +623,7 @@ func (ir *IstioRouter) SetRoutes( Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, + Fault: canary.Spec.Service.Fault, Route: []istiov1beta1.HTTPRouteDestination{ makeDestination(canary, primaryName, primaryWeight), makeDestination(canary, canaryName, canaryWeight), @@ -631,6 +636,7 @@ func (ir *IstioRouter) SetRoutes( Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, + Fault: canary.Spec.Service.Fault, Route: []istiov1beta1.HTTPRouteDestination{ makeDestination(canary, primaryName, primaryWeight), }, From 6b0e7ee3d0e3cd209e87bb99fac273d6eea99044 Mon Sep 17 00:00:00 2001 From: S-mishina Date: Wed, 15 May 2024 23:44:39 +0900 Subject: [PATCH 2/3] fix fmt pkg/router/istio.go Signed-off-by: S-mishina --- pkg/router/istio.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/router/istio.go b/pkg/router/istio.go index b5ea6539b..83ceb7834 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -217,7 +217,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, - Fault: canary.Spec.Service.Fault, + Fault: canary.Spec.Service.Fault, Route: canaryRoute, }, }, @@ -246,7 +246,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, - Fault: canary.Spec.Service.Fault, + Fault: canary.Spec.Service.Fault, Route: canaryRoute, }, { @@ -256,7 +256,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, - Fault: canary.Spec.Service.Fault, + Fault: canary.Spec.Service.Fault, Route: []istiov1beta1.HTTPRouteDestination{ makeDestination(canary, primaryName, 100), }, @@ -507,7 +507,7 @@ func (ir *IstioRouter) SetRoutes( Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, - Fault: canary.Spec.Service.Fault, + Fault: canary.Spec.Service.Fault, Route: []istiov1beta1.HTTPRouteDestination{ makeDestination(canary, primaryName, primaryWeight), makeDestination(canary, canaryName, canaryWeight), @@ -623,7 +623,7 @@ func (ir *IstioRouter) SetRoutes( Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, - Fault: canary.Spec.Service.Fault, + Fault: canary.Spec.Service.Fault, Route: []istiov1beta1.HTTPRouteDestination{ makeDestination(canary, primaryName, primaryWeight), makeDestination(canary, canaryName, canaryWeight), @@ -636,7 +636,7 @@ func (ir *IstioRouter) SetRoutes( Retries: canary.Spec.Service.Retries, CorsPolicy: canary.Spec.Service.CorsPolicy, Headers: canary.Spec.Service.Headers, - Fault: canary.Spec.Service.Fault, + Fault: canary.Spec.Service.Fault, Route: []istiov1beta1.HTTPRouteDestination{ makeDestination(canary, primaryName, primaryWeight), }, From 9e867299ddb5f08b056cdb9229adf18de4eb1e73 Mon Sep 17 00:00:00 2001 From: S-mishina Date: Thu, 16 May 2024 00:08:35 +0900 Subject: [PATCH 3/3] codegen Signed-off-by: S-mishina --- .../flagger/v1beta1/zz_generated.deepcopy.go | 5 ++++ .../istio/v1beta1/zz_generated.deepcopy.go | 30 +++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go b/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go index 340fc0439..ea13325b6 100644 --- a/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go @@ -450,6 +450,11 @@ func (in *CanaryService) DeepCopyInto(out *CanaryService) { *out = new(CustomMetadata) (*in).DeepCopyInto(*out) } + if in.Fault != nil { + in, out := &in.Fault, &out.Fault + *out = new(istiov1beta1.HTTPFaultInjection) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/apis/istio/v1beta1/zz_generated.deepcopy.go b/pkg/apis/istio/v1beta1/zz_generated.deepcopy.go index 2667de29d..8c0f70e83 100644 --- a/pkg/apis/istio/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/istio/v1beta1/zz_generated.deepcopy.go @@ -290,12 +290,12 @@ func (in *HTTPFaultInjection) DeepCopyInto(out *HTTPFaultInjection) { if in.Delay != nil { in, out := &in.Delay, &out.Delay *out = new(InjectDelay) - **out = **in + (*in).DeepCopyInto(*out) } if in.Abort != nil { in, out := &in.Abort, &out.Abort *out = new(InjectAbort) - **out = **in + (*in).DeepCopyInto(*out) } return } @@ -599,6 +599,11 @@ func (in *Headers) DeepCopy() *Headers { // 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 + if in.Percentage != nil { + in, out := &in.Percentage, &out.Percentage + *out = new(PercentagePercent) + **out = **in + } return } @@ -615,6 +620,11 @@ func (in *InjectAbort) DeepCopy() *InjectAbort { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *InjectDelay) DeepCopyInto(out *InjectDelay) { *out = *in + if in.Percentage != nil { + in, out := &in.Percentage, &out.Percentage + *out = new(PercentagePercent) + **out = **in + } return } @@ -757,6 +767,22 @@ func (in *Percent) DeepCopy() *Percent { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PercentagePercent) DeepCopyInto(out *PercentagePercent) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PercentagePercent. +func (in *PercentagePercent) DeepCopy() *PercentagePercent { + if in == nil { + return nil + } + out := new(PercentagePercent) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PortSelector) DeepCopyInto(out *PortSelector) { *out = *in