diff --git a/api/v1/store.go b/api/v1/store.go index e86265ba..20f9858f 100644 --- a/api/v1/store.go +++ b/api/v1/store.go @@ -218,16 +218,23 @@ type NetworkSpec struct { IngressAnnotations map[string]string `json:"ingressAnnotations,omitempty"` IngressLabels map[string]string `json:"ingressLabels,omitempty"` - GatewayName string `json:"gatewayName,omitempty"` - GatewayNamespace string `json:"gatewayNamespace,omitempty"` - GatewaySectionName string `json:"gatewaySectionName,omitempty"` - GatewayAnnotations map[string]string `json:"gatewayAnnotations,omitempty"` - GatewayLabels map[string]string `json:"gatewayLabels,omitempty"` + GatewayName string `json:"gatewayName,omitempty"` + GatewayNamespace string `json:"gatewayNamespace,omitempty"` + GatewaySectionName string `json:"gatewaySectionName,omitempty"` + GatewayAnnotations map[string]string `json:"gatewayAnnotations,omitempty"` + GatewayLabels map[string]string `json:"gatewayLabels,omitempty"` + GatewayRetry *HTTPRouteRetrySpec `json:"gatewayRetry,omitempty"` // +kubebuilder:default=store-tls TLSSecretName string `json:"tlsSecretName,omitempty"` } +type HTTPRouteRetrySpec struct { + Codes []int `json:"codes,omitempty"` + Attempts *int `json:"attempts,omitempty"` + Backoff *string `json:"backoff,omitempty"` +} + type ContainerSpec struct { // +kubebuilder:validation:MinLength=1 Image string `json:"image"` diff --git a/internal/controller/store_controller.go b/internal/controller/store_controller.go index 418db9a3..8334e699 100644 --- a/internal/controller/store_controller.go +++ b/internal/controller/store_controller.go @@ -422,14 +422,16 @@ func (r *StoreReconciler) reconcileHTTPRoute(ctx context.Context, store *v1.Stor return fmt.Errorf("reconcile unready httproute: %w", err) } - if changed { - r.Recorder.Event(store, "Normal", "Diff httproute hash", - fmt.Sprintf("Update Store %s httproute in namespace %s. Diff hash", - store.Name, - store.Namespace)) - if err := k8s.EnsureHTTPRoute(ctx, r.Client, store, obj, r.Scheme, true); err != nil { - return fmt.Errorf("reconcile unready httproute: %w", err) - } + if !changed { + return nil + } + + r.Recorder.Event(store, "Normal", "Diff httproute hash", + fmt.Sprintf("Update Store %s httproute in namespace %s. Diff hash", + store.Name, + store.Namespace)) + if err := k8s.EnsureHTTPRoute(ctx, r.Client, store, obj, r.Scheme, true); err != nil { + return fmt.Errorf("reconcile unready httproute: %w", err) } return nil diff --git a/internal/httproute/httproute.go b/internal/httproute/httproute.go index e72a6ce7..6d324976 100644 --- a/internal/httproute/httproute.go +++ b/internal/httproute/httproute.go @@ -54,6 +54,8 @@ func StoreHTTPRoute(store v1.Store) *gatewayv1.HTTPRoute { storefrontServiceName := gatewayv1.ObjectName(service.GetStorefrontServiceName(store)) port := gatewayv1.PortNumber(store.Spec.Network.Port) + retry := BuildHTTPRouteRetry(store.Spec.Network.GatewayRetry) + rules := []gatewayv1.HTTPRouteRule{ { Matches: []gatewayv1.HTTPRouteMatch{ @@ -137,6 +139,12 @@ func StoreHTTPRoute(store v1.Store) *gatewayv1.HTTPRoute { }, } + if retry != nil { + for i := range rules { + rules[i].Retry = retry + } + } + parentRef := gatewayv1.ParentReference{ Name: gatewayv1.ObjectName(store.Spec.Network.GatewayName), } @@ -174,6 +182,27 @@ func StoreHTTPRoute(store v1.Store) *gatewayv1.HTTPRoute { } } +func BuildHTTPRouteRetry(spec *v1.HTTPRouteRetrySpec) *gatewayv1.HTTPRouteRetry { + if spec == nil { + return nil + } + retry := &gatewayv1.HTTPRouteRetry{ + Attempts: spec.Attempts, + } + if len(spec.Codes) > 0 { + codes := make([]gatewayv1.HTTPRouteRetryStatusCode, len(spec.Codes)) + for i, c := range spec.Codes { + codes[i] = gatewayv1.HTTPRouteRetryStatusCode(c) + } + retry.Codes = codes + } + if spec.Backoff != nil { + backoff := gatewayv1.Duration(*spec.Backoff) + retry.Backoff = &backoff + } + return retry +} + func GetStoreHTTPRouteName(store v1.Store) string { return fmt.Sprintf("store-%s", store.Name) }