Skip to content

Commit

Permalink
feat: Add custom backendRef support for Gateway API
Browse files Browse the repository at this point in the history
Signed-off-by: kahirokunn <okinakahiro@gmail.com>
  • Loading branch information
kahirokunn committed Dec 16, 2024
1 parent a85887d commit cdf638e
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 22 deletions.
15 changes: 13 additions & 2 deletions pkg/apis/flagger/v1beta1/canary.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"time"

v1 "github.com/fluxcd/flagger/pkg/apis/gatewayapi/v1"
"github.com/fluxcd/flagger/pkg/apis/gatewayapi/v1beta1"
istiov1beta1 "github.com/fluxcd/flagger/pkg/apis/istio/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -213,11 +214,11 @@ type CanaryService struct {

// Primary is the metadata to add to the primary service
// +optional
Primary *CustomMetadata `json:"primary,omitempty"`
Primary *Custom `json:"primary,omitempty"`

// Canary is the metadata to add to the canary service
// +optional
Canary *CustomMetadata `json:"canary,omitempty"`
Canary *Custom `json:"canary,omitempty"`
}

// CanaryAnalysis is used to describe how the analysis should be done
Expand Down Expand Up @@ -496,6 +497,16 @@ type CustomMetadata struct {
Annotations map[string]string `json:"annotations,omitempty"`
}

// Custom holds labels, annotations, and proxyRef to set on generated objects.
type Custom struct {
CustomMetadata

// BackendRef is a reference to a backend to forward matched requests to.
// Defaults to the primary or canary service.
// +optional
BackendRef *v1.HTTPBackendRef `json:"backendRef,omitempty"`
}

// HTTPRewrite holds information about how to modify a request URI during
// forwarding.
type HTTPRewrite struct {
Expand Down
27 changes: 25 additions & 2 deletions pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 22 additions & 9 deletions pkg/router/gateway_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@ func (gwr *GatewayAPIRouter) Reconcile(canary *flaggerv1.Canary) error {
Filters: gwr.makeFilters(canary),
BackendRefs: []v1.HTTPBackendRef{
{
BackendRef: gwr.makeBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port),
BackendRef: gwr.makeBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Primary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Primary.BackendRef.Filters,
},
{
BackendRef: gwr.makeBackendRef(canarySvcName, initialCanaryWeight, canary.Spec.Service.Port),
BackendRef: gwr.makeBackendRef(canarySvcName, initialCanaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Canary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Canary.BackendRef.Filters,
},
},
},
Expand All @@ -123,7 +125,8 @@ func (gwr *GatewayAPIRouter) Reconcile(canary *flaggerv1.Canary) error {
Filters: gwr.makeFilters(canary),
BackendRefs: []v1.HTTPBackendRef{
{
BackendRef: gwr.makeBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port),
BackendRef: gwr.makeBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Primary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Primary.BackendRef.Filters,
},
},
})
Expand Down Expand Up @@ -341,10 +344,12 @@ func (gwr *GatewayAPIRouter) SetRoutes(
Filters: gwr.makeFilters(canary),
BackendRefs: []v1.HTTPBackendRef{
{
BackendRef: gwr.makeBackendRef(primarySvcName, pWeight, canary.Spec.Service.Port),
BackendRef: gwr.makeBackendRef(primarySvcName, pWeight, canary.Spec.Service.Port, &canary.Spec.Service.Primary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Primary.BackendRef.Filters,
},
{
BackendRef: gwr.makeBackendRef(canarySvcName, cWeight, canary.Spec.Service.Port),
BackendRef: gwr.makeBackendRef(canarySvcName, cWeight, canary.Spec.Service.Port, &canary.Spec.Service.Canary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Canary.BackendRef.Filters,
},
},
}
Expand Down Expand Up @@ -400,7 +405,8 @@ func (gwr *GatewayAPIRouter) SetRoutes(
Filters: gwr.makeFilters(canary),
BackendRefs: []v1.HTTPBackendRef{
{
BackendRef: gwr.makeBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port),
BackendRef: gwr.makeBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Primary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Primary.BackendRef.Filters,
},
},
Timeouts: &v1.HTTPRouteTimeouts{
Expand Down Expand Up @@ -485,10 +491,12 @@ func (gwr *GatewayAPIRouter) getSessionAffinityRouteRules(canary *flaggerv1.Cana
stickyRouteRule.Matches = mergedMatches
stickyRouteRule.BackendRefs = []v1.HTTPBackendRef{
{
BackendRef: gwr.makeBackendRef(primarySvcName, 0, canary.Spec.Service.Port),
BackendRef: gwr.makeBackendRef(primarySvcName, 0, canary.Spec.Service.Port, &canary.Spec.Service.Primary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Primary.BackendRef.Filters,
},
{
BackendRef: gwr.makeBackendRef(canarySvcName, 100, canary.Spec.Service.Port),
BackendRef: gwr.makeBackendRef(canarySvcName, 100, canary.Spec.Service.Port, &canary.Spec.Service.Canary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Canary.BackendRef.Filters,
},
}
} else {
Expand Down Expand Up @@ -612,7 +620,12 @@ func (gwr *GatewayAPIRouter) mapRouteMatches(requestMatches []istiov1beta1.HTTPM
return matches, nil
}

func (gwr *GatewayAPIRouter) makeBackendRef(svcName string, weight, port int32) v1.BackendRef {
func (gwr *GatewayAPIRouter) makeBackendRef(svcName string, weight, port int32, backendRefTemplate *v1.BackendRef) v1.BackendRef {
if backendRefTemplate != nil {
backendRefTemplate.Weight = &weight
return *backendRefTemplate
}

return v1.BackendRef{
BackendObjectReference: v1.BackendObjectReference{
Group: (*v1.Group)(&backendRefGroup),
Expand Down
4 changes: 2 additions & 2 deletions pkg/router/gateway_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,10 @@ func TestGatewayAPIRouter_getSessionAffinityRouteRules(t *testing.T) {
weightedRouteRule := &v1.HTTPRouteRule{
BackendRefs: []v1.HTTPBackendRef{
{
BackendRef: router.makeBackendRef(pSvcName, initialPrimaryWeight, canary.Spec.Service.Port),
BackendRef: router.makeBackendRef(pSvcName, initialPrimaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Primary.BackendRef.BackendRef),
},
{
BackendRef: router.makeBackendRef(cSvcName, initialCanaryWeight, canary.Spec.Service.Port),
BackendRef: router.makeBackendRef(cSvcName, initialCanaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Canary.BackendRef.BackendRef),
},
},
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/router/kubernetes_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ func (c *KubernetesDefaultRouter) Initialize(canary *flaggerv1.Canary) error {
_, primaryName, canaryName := canary.GetServiceNames()

// canary svc
err := c.reconcileService(canary, canaryName, c.labelValue, canary.Spec.Service.Canary)
err := c.reconcileService(canary, canaryName, c.labelValue, &canary.Spec.Service.Canary.CustomMetadata)
if err != nil {
return fmt.Errorf("reconcileService failed: %w", err)
}

// primary svc
err = c.reconcileService(canary, primaryName, fmt.Sprintf("%s-primary", c.labelValue), canary.Spec.Service.Primary)
err = c.reconcileService(canary, primaryName, fmt.Sprintf("%s-primary", c.labelValue), &canary.Spec.Service.Primary.CustomMetadata)
if err != nil {
return fmt.Errorf("reconcileService failed: %w", err)
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/router/kubernetes_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,13 +375,13 @@ func TestServiceRouter_InitializeMetadata(t *testing.T) {
labelSelector: "app",
}

metadata := &flaggerv1.CustomMetadata{
Labels: map[string]string{"test": "test"},
Annotations: map[string]string{"test": "test"},
mocks.canary.Spec.Service.Canary = &flaggerv1.Custom{
CustomMetadata: flaggerv1.CustomMetadata{
Labels: map[string]string{"test": "test"},
Annotations: map[string]string{"test": "test"},
},
}

mocks.canary.Spec.Service.Canary = metadata

err := router.Initialize(mocks.canary)
require.NoError(t, err)

Expand Down

0 comments on commit cdf638e

Please sign in to comment.