Skip to content

Commit

Permalink
s
Browse files Browse the repository at this point in the history
  • Loading branch information
kahirokunn committed Dec 16, 2024
1 parent 0e8e527 commit b711e6d
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 1,665 deletions.
566 changes: 34 additions & 532 deletions artifacts/flagger/crd.yaml

Large diffs are not rendered by default.

566 changes: 34 additions & 532 deletions charts/flagger/crds/crd.yaml

Large diffs are not rendered by default.

566 changes: 34 additions & 532 deletions kustomize/base/flagger/crd.yaml

Large diffs are not rendered by default.

34 changes: 28 additions & 6 deletions pkg/apis/flagger/v1beta1/canary.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,11 @@ type CanaryService struct {

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

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

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

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

// BackendRef is a reference to a backend to forward matched requests to.
// Backend 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"`
Backend *HTTPBackendRefTemplate `json:"backendRef,omitempty"`
}

// HTTPBackendRefTemplate is a reference to a backend to forward matched requests to.
type HTTPBackendRefTemplate struct {
// Ref references a Kubernetes object.
BackendObjectReference *v1.BackendObjectReference `json:"ref,omitempty"`

// Filters defined at this level should be executed if and only if the
// request is being forwarded to the backend defined here.
//
// Support: Implementation-specific (For broader support of filters, use the
// Filters field in HTTPRouteRule.)
//
// +optional
// +kubebuilder:validation:MaxItems=16
// +kubebuilder:validation:XValidation:message="May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both",rule="!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))"
// +kubebuilder:validation:XValidation:message="May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both",rule="!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))"
// +kubebuilder:validation:XValidation:message="RequestHeaderModifier filter cannot be repeated",rule="self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1"
// +kubebuilder:validation:XValidation:message="ResponseHeaderModifier filter cannot be repeated",rule="self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1"
// +kubebuilder:validation:XValidation:message="RequestRedirect filter cannot be repeated",rule="self.filter(f, f.type == 'RequestRedirect').size() <= 1"
// +kubebuilder:validation:XValidation:message="URLRewrite filter cannot be repeated",rule="self.filter(f, f.type == 'URLRewrite').size() <= 1"
Filters []v1.HTTPRouteFilter `json:"filters,omitempty"`
}

// HTTPRewrite holds information about how to modify a request URI during
Expand Down
46 changes: 37 additions & 9 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.

73 changes: 28 additions & 45 deletions pkg/router/gateway_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,8 @@ func (gwr *GatewayAPIRouter) Reconcile(canary *flaggerv1.Canary) error {
Matches: matches,
Filters: gwr.makeFilters(canary),
BackendRefs: []v1.HTTPBackendRef{
{
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, &canary.Spec.Service.Canary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Canary.BackendRef.Filters,
},
gwr.makeHTTPBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port, canary.Spec.Service.Primary),
gwr.makeHTTPBackendRef(canarySvcName, initialCanaryWeight, canary.Spec.Service.Port, canary.Spec.Service.Canary),
},
},
},
Expand All @@ -124,10 +118,7 @@ func (gwr *GatewayAPIRouter) Reconcile(canary *flaggerv1.Canary) error {
Matches: matches,
Filters: gwr.makeFilters(canary),
BackendRefs: []v1.HTTPBackendRef{
{
BackendRef: gwr.makeBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Primary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Primary.BackendRef.Filters,
},
gwr.makeHTTPBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port, canary.Spec.Service.Primary),
},
})
if canary.Spec.Service.Timeout != "" {
Expand Down Expand Up @@ -394,14 +385,8 @@ func (gwr *GatewayAPIRouter) SetRoutes(
Matches: matches,
Filters: gwr.makeFilters(canary),
BackendRefs: []v1.HTTPBackendRef{
{
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, &canary.Spec.Service.Canary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Canary.BackendRef.Filters,
},
gwr.makeHTTPBackendRef(primarySvcName, pWeight, canary.Spec.Service.Port, canary.Spec.Service.Primary),
gwr.makeHTTPBackendRef(canarySvcName, cWeight, canary.Spec.Service.Port, canary.Spec.Service.Canary),
},
}
if canary.Spec.Service.Timeout != "" {
Expand Down Expand Up @@ -455,10 +440,7 @@ func (gwr *GatewayAPIRouter) SetRoutes(
Matches: matches,
Filters: gwr.makeFilters(canary),
BackendRefs: []v1.HTTPBackendRef{
{
BackendRef: gwr.makeBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Primary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Primary.BackendRef.Filters,
},
gwr.makeHTTPBackendRef(primarySvcName, initialPrimaryWeight, canary.Spec.Service.Port, canary.Spec.Service.Primary),
},
Timeouts: &v1.HTTPRouteTimeouts{
Request: &timeout,
Expand Down Expand Up @@ -541,14 +523,8 @@ func (gwr *GatewayAPIRouter) getSessionAffinityRouteRules(canary *flaggerv1.Cana
mergedMatches := gwr.mergeMatchConditions([]v1.HTTPRouteMatch{cookieMatch}, svcMatches)
stickyRouteRule.Matches = mergedMatches
stickyRouteRule.BackendRefs = []v1.HTTPBackendRef{
{
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, &canary.Spec.Service.Canary.BackendRef.BackendRef),
Filters: canary.Spec.Service.Canary.BackendRef.Filters,
},
gwr.makeHTTPBackendRef(primarySvcName, 0, canary.Spec.Service.Port, canary.Spec.Service.Primary),
gwr.makeHTTPBackendRef(canarySvcName, 100, canary.Spec.Service.Port, canary.Spec.Service.Canary),
}
} else {
// If canary weight is 0 and SessionAffinityCookie is non-blank, then it belongs to a previous canary run.
Expand Down Expand Up @@ -671,21 +647,28 @@ func (gwr *GatewayAPIRouter) mapRouteMatches(requestMatches []istiov1beta1.HTTPM
return matches, nil
}

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),
Kind: (*v1.Kind)(&backendRefKind),
Name: v1.ObjectName(svcName),
Port: (*v1.PortNumber)(&port),
func (gwr *GatewayAPIRouter) makeHTTPBackendRef(svcName string, weight, port int32, customBackend *flaggerv1.CustomBackend) v1.HTTPBackendRef {
httpBackendRef := v1.HTTPBackendRef{
BackendRef: v1.BackendRef{
BackendObjectReference: v1.BackendObjectReference{
Group: (*v1.Group)(&backendRefGroup),
Kind: (*v1.Kind)(&backendRefKind),
Name: v1.ObjectName(svcName),
Port: (*v1.PortNumber)(&port),
},
Weight: &weight,
},
Weight: &weight,
}
if customBackend != nil && customBackend.Backend != nil {
if customBackend.Backend.BackendObjectReference != nil {
httpBackendRef.BackendObjectReference = *customBackend.Backend.BackendObjectReference
}
if customBackend.Backend.Filters != nil {
httpBackendRef.Filters = customBackend.Backend.Filters
}
}

return httpBackendRef
}

func (gwr *GatewayAPIRouter) mergeMatchConditions(analysis, service []v1.HTTPRouteMatch) []v1.HTTPRouteMatch {
Expand Down
8 changes: 2 additions & 6 deletions pkg/router/gateway_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,8 @@ func TestGatewayAPIRouter_getSessionAffinityRouteRules(t *testing.T) {
_, pSvcName, cSvcName := canary.GetServiceNames()
weightedRouteRule := &v1.HTTPRouteRule{
BackendRefs: []v1.HTTPBackendRef{
{
BackendRef: router.makeBackendRef(pSvcName, initialPrimaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Primary.BackendRef.BackendRef),
},
{
BackendRef: router.makeBackendRef(cSvcName, initialCanaryWeight, canary.Spec.Service.Port, &canary.Spec.Service.Canary.BackendRef.BackendRef),
},
router.makeHTTPBackendRef(pSvcName, initialPrimaryWeight, canary.Spec.Service.Port, canary.Spec.Service.Primary),
router.makeHTTPBackendRef(cSvcName, initialCanaryWeight, canary.Spec.Service.Port, canary.Spec.Service.Canary),
},
}
rules, err := router.getSessionAffinityRouteRules(canary, 10, weightedRouteRule)
Expand Down
12 changes: 10 additions & 2 deletions pkg/router/kubernetes_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,21 @@ 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.CustomMetadata)
canaryCustomMetadata := &flaggerv1.CustomMetadata{}
if canary.Spec.Service.Canary != nil {
canaryCustomMetadata = &canary.Spec.Service.Canary.CustomMetadata
}
err := c.reconcileService(canary, canaryName, c.labelValue, canaryCustomMetadata)
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.CustomMetadata)
primaryCustomMetadata := &flaggerv1.CustomMetadata{}
if canary.Spec.Service.Primary != nil {
primaryCustomMetadata = &canary.Spec.Service.Primary.CustomMetadata
}
err = c.reconcileService(canary, primaryName, fmt.Sprintf("%s-primary", c.labelValue), primaryCustomMetadata)
if err != nil {
return fmt.Errorf("reconcileService failed: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/router/kubernetes_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ func TestServiceRouter_InitializeMetadata(t *testing.T) {
labelSelector: "app",
}

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

0 comments on commit b711e6d

Please sign in to comment.