mirror of
https://github.com/fluxcd/flagger.git
synced 2026-02-14 18:10:00 +00:00
Merge pull request #1791 from steved/main
fix: gateway router should wait for accepted condition
This commit is contained in:
2
go.mod
2
go.mod
@@ -29,6 +29,7 @@ require (
|
||||
k8s.io/client-go v0.34.1
|
||||
k8s.io/code-generator v0.34.1
|
||||
k8s.io/klog/v2 v2.130.1
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
|
||||
knative.dev/serving v0.46.6
|
||||
)
|
||||
|
||||
@@ -99,7 +100,6 @@ require (
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
|
||||
knative.dev/networking v0.0.0-20250902160145-7dad473f6351 // indirect
|
||||
knative.dev/pkg v0.0.0-20250909011231-077dcf0d00e8 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||
|
||||
@@ -273,6 +273,26 @@ func (gwr *GatewayAPIRouter) GetRoutes(canary *flaggerv1.Canary) (
|
||||
err = fmt.Errorf("HTTPRoute %s.%s get error: %w", apexSvcName, hrNamespace, err)
|
||||
return
|
||||
}
|
||||
|
||||
currentGeneration := httpRoute.GetGeneration()
|
||||
for _, parentRef := range httpRoute.Spec.CommonRouteSpec.ParentRefs {
|
||||
for _, parentStatus := range httpRoute.Status.Parents {
|
||||
if !reflect.DeepEqual(parentStatus.ParentRef, parentRef) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, condition := range parentStatus.Conditions {
|
||||
if condition.Type == string(v1.RouteConditionAccepted) && (condition.Status != metav1.ConditionTrue || condition.ObservedGeneration < currentGeneration) {
|
||||
err = fmt.Errorf(
|
||||
"HTTPRoute %s.%s parent %s is not ready (status: %s, observed generation: %d, current generation: %d)",
|
||||
apexSvcName, hrNamespace, parentRef.Name, string(condition.Status), condition.ObservedGeneration, currentGeneration,
|
||||
)
|
||||
return 0, 0, false, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var weightedRule *v1.HTTPRouteRule
|
||||
for _, rule := range httpRoute.Spec.Rules {
|
||||
// If session affinity is enabled, then we are only interested in the rule
|
||||
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
flaggerv1 "github.com/fluxcd/flagger/pkg/apis/flagger/v1beta1"
|
||||
v1 "github.com/fluxcd/flagger/pkg/apis/gatewayapi/v1"
|
||||
@@ -603,3 +604,106 @@ func TestGatewayAPIRouter_makeFilters_CORS(t *testing.T) {
|
||||
// Assert MaxAge (24h = 86400 seconds)
|
||||
assert.Equal(t, int32(86400), corsFilter.CORS.MaxAge)
|
||||
}
|
||||
|
||||
func TestGatewayAPIRouter_GetRoutes(t *testing.T) {
|
||||
canary := newTestGatewayAPICanary()
|
||||
mocks := newFixture(canary)
|
||||
router := &GatewayAPIRouter{
|
||||
gatewayAPIClient: mocks.meshClient,
|
||||
kubeClient: mocks.kubeClient,
|
||||
logger: mocks.logger,
|
||||
}
|
||||
|
||||
httpRoute := &v1.HTTPRoute{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "podinfo",
|
||||
Generation: 1,
|
||||
},
|
||||
Spec: v1.HTTPRouteSpec{
|
||||
Rules: []v1.HTTPRouteRule{
|
||||
{
|
||||
BackendRefs: []v1.HTTPBackendRef{
|
||||
{
|
||||
BackendRef: v1.BackendRef{
|
||||
BackendObjectReference: v1.BackendObjectReference{
|
||||
Name: "podinfo-canary",
|
||||
},
|
||||
Weight: ptr.To(int32(10)),
|
||||
},
|
||||
},
|
||||
{
|
||||
BackendRef: v1.BackendRef{
|
||||
BackendObjectReference: v1.BackendObjectReference{
|
||||
Name: "podinfo-primary",
|
||||
},
|
||||
Weight: ptr.To(int32(90)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
CommonRouteSpec: v1.CommonRouteSpec{
|
||||
ParentRefs: []v1.ParentReference{
|
||||
{
|
||||
Name: "podinfo",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
httpRoute, err := router.gatewayAPIClient.GatewayapiV1().HTTPRoutes("default").Create(context.TODO(), httpRoute, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("httproute generation", func(t *testing.T) {
|
||||
httpRoute.ObjectMeta.Generation = 5
|
||||
httpRoute.Status.Parents = []v1.RouteParentStatus{
|
||||
{
|
||||
ParentRef: v1.ParentReference{
|
||||
Name: "podinfo",
|
||||
SectionName: ptr.To(v1.SectionName("https")),
|
||||
},
|
||||
Conditions: []metav1.Condition{
|
||||
{
|
||||
Type: string(v1.RouteConditionAccepted),
|
||||
Status: metav1.ConditionTrue,
|
||||
ObservedGeneration: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ParentRef: v1.ParentReference{
|
||||
Name: "podinfo",
|
||||
},
|
||||
Conditions: []metav1.Condition{
|
||||
{
|
||||
Type: string(v1.RouteConditionAccepted),
|
||||
Status: metav1.ConditionFalse,
|
||||
ObservedGeneration: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
httpRoute, err := router.gatewayAPIClient.GatewayapiV1().HTTPRoutes("default").Update(context.TODO(), httpRoute, metav1.UpdateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, _, err = router.GetRoutes(canary)
|
||||
require.Error(t, err)
|
||||
|
||||
httpRoute.Status.Parents[1].Conditions[0].ObservedGeneration = 5
|
||||
_, err = router.gatewayAPIClient.GatewayapiV1().HTTPRoutes("default").Update(context.TODO(), httpRoute, metav1.UpdateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, _, err = router.GetRoutes(canary)
|
||||
require.Error(t, err)
|
||||
|
||||
httpRoute.Status.Parents[1].Conditions[0].Status = metav1.ConditionTrue
|
||||
_, err = router.gatewayAPIClient.GatewayapiV1().HTTPRoutes("default").Update(context.TODO(), httpRoute, metav1.UpdateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
primaryWeight, canaryWeight, mirrored, err := router.GetRoutes(canary)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 90, primaryWeight)
|
||||
assert.Equal(t, 10, canaryWeight)
|
||||
assert.False(t, mirrored)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user