11package controller
22
33import (
4- "cmp"
54 "context"
6- "time "
5+ "encoding/json "
76
87 networkingv1 "k8s.io/api/networking/v1"
98 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
109 "k8s.io/apimachinery/pkg/types"
1110 "k8s.io/utils/ptr"
12- "k8s.io/utils/strings/slices"
1311 "sigs.k8s.io/controller-runtime/pkg/client"
1412 gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
1513 "sigs.k8s.io/gateway-api/apis/v1alpha2"
@@ -22,134 +20,77 @@ import (
2220func (r * HTTPRouteReconciler ) processHTTPRoutePolicies (tctx * provider.TranslateContext , httpRoute * gatewayv1.HTTPRoute ) error {
2321 // list HTTPRoutePolices which sectionName is not specified
2422 var (
25- checker = conflictChecker {
26- object : httpRoute ,
27- policies : make (map [targetRefKey ][]v1alpha1.HTTPRoutePolicy ),
28- }
2923 list v1alpha1.HTTPRoutePolicyList
3024 key = indexer .GenIndexKeyWithGK (gatewayv1 .GroupName , "HTTPRoute" , httpRoute .GetNamespace (), httpRoute .GetName ())
3125 )
3226 if err := r .List (context .Background (), & list , client.MatchingFields {indexer .PolicyTargetRefs : key }); err != nil {
3327 return err
3428 }
3529
36- tctx .HTTPRoutePolicies = list .Items
37- if len (tctx .HTTPRoutePolicies ) == 0 {
30+ if len (list .Items ) == 0 {
3831 return nil
3932 }
4033
41- var conflict = false
42- Loop:
34+ var conflicts = make (map [types.NamespacedName ]v1alpha1.HTTPRoutePolicy )
4335 for _ , rule := range httpRoute .Spec .Rules {
44- if rule .Name == nil || * rule .Name == "" {
45- priority := tctx .HTTPRoutePolicies [0 ].Spec .Priority
46- for _ , policy := range tctx .HTTPRoutePolicies {
47- if ! ptr .Equal (priority , policy .Spec .Priority ) {
48- conflict = true
49- break Loop
50- }
36+ var policies = findPolicyWhichTargetRefTheRule (rule .Name , "HTTPRoute" , list )
37+ if conflict := isPoliciesConflict (policies ); conflict {
38+ for _ , policy := range policies {
39+ namespacedName := types.NamespacedName {Namespace : policy .GetNamespace (), Name : policy .GetName ()}
40+ conflicts [namespacedName ] = policy
5141 }
5242 }
5343 }
44+ data , _ := json .MarshalIndent (conflicts , "" , " " )
45+ r .Log .Info ("conflicts policies" , "data" , string (data ))
5446
55- for _ , item := range list .Items {
56- checker .append ("" , item )
57- tctx .HTTPRoutePolicies ["*" ] = append (tctx .HTTPRoutePolicies ["*" ], item )
58- }
59-
60- for _ , rule := range httpRoute .Spec .Rules {
61- if rule .Name == nil {
62- continue
63- }
64-
47+ for i := range list .Items {
6548 var (
66- ruleName = string (* rule .Name )
67- listForSectionRules v1alpha1.HTTPRoutePolicyList
68- key = indexer .GenHTTPRoutePolicyIndexKey (gatewayv1 .GroupName , "HTTPRoute" , httpRoute .GetNamespace (), httpRoute .GetName (), ruleName )
69- )
70- if err := r .List (context .Background (), & listForSectionRules , client.MatchingFields {indexer .PolicyTargetRefs : key }); err != nil {
71- continue
72- }
73- for _ , item := range listForSectionRules .Items {
74- checker .append (ruleName , item )
75- tctx .HTTPRoutePolicies [ruleName ] = append (tctx .HTTPRoutePolicies [ruleName ], item )
76- }
77- }
78-
79- // todo: unreachable
80- // if the HTTPRoute is deleted, clear tctx.HTTPRoutePolicies and delete Ancestors from HTTPRoutePolicies status
81- // if !httpRoute.GetDeletionTimestamp().IsZero() {
82- // for _, policies := range checker.policies {
83- // for i := range policies {
84- // policy := policies[i]
85- // _ = DeleteAncestors(&policy.Status, httpRoute.Spec.ParentRefs)
86- // data, _ := json.Marshal(policy.Status)
87- // r.Log.Info("policy status after delete ancestor", "data", string(data))
88- // if err := r.Status().Update(context.Background(), &policy); err != nil {
89- // r.Log.Error(err, "failed to Update policy status")
90- // }
91- // // tctx.StatusUpdaters = append(tctx.StatusUpdaters, &policy)
92- // }
93- // }
94- // return nil
95- // }
96-
97- var (
98- status = true
99- reason = string (v1alpha2 .PolicyReasonAccepted )
100- message string
101- )
102- if checker .conflict {
103- status = false
104- reason = string (v1alpha2 .PolicyReasonConflicted )
105- message = "HTTPRoutePolicy conflict with others target to the HTTPRoute"
49+ policy = list .Items [i ]
50+ namespacedName = types.NamespacedName {Namespace : policy .GetNamespace (), Name : policy .GetName ()}
10651
107- // clear HTTPRoutePolices from TranslateContext
108- tctx .HTTPRoutePolicies = make (map [string ][]v1alpha1.HTTPRoutePolicy )
109- }
52+ status = false
53+ reason = string (v1alpha2 .PolicyReasonConflicted )
54+ message = "HTTPRoutePolicy conflict with others target to the HTTPRoute"
55+ )
56+ if _ , conflict := conflicts [namespacedName ]; ! conflict {
57+ status = true
58+ reason = string (v1alpha2 .PolicyReasonAccepted )
59+ message = ""
11060
111- for _ , policies := range checker .policies {
112- for i := range policies {
113- policy := policies [i ]
114- modifyHTTPRoutePolicyStatus (httpRoute .Spec .ParentRefs , & policy , status , reason , message )
115- tctx .StatusUpdaters = append (tctx .StatusUpdaters , & policy )
61+ tctx .HTTPRoutePolicies = append (tctx .HTTPRoutePolicies , policy )
11662 }
63+ modifyHTTPRoutePolicyStatus (httpRoute .Spec .ParentRefs , & policy , status , reason , message )
64+ tctx .StatusUpdaters = append (tctx .StatusUpdaters , & policy )
11765 }
11866
11967 return nil
12068}
12169
12270func (r * IngressReconciler ) processHTTPRoutePolicies (tctx * provider.TranslateContext , ingress * networkingv1.Ingress ) error {
12371 var (
124- checker = conflictChecker {
125- object : ingress ,
126- policies : make (map [targetRefKey ][]v1alpha1.HTTPRoutePolicy ),
127- conflict : false ,
128- }
12972 list v1alpha1.HTTPRoutePolicyList
13073 key = indexer .GenIndexKeyWithGK (networkingv1 .GroupName , "Ingress" , ingress .GetNamespace (), ingress .GetName ())
13174 )
13275 if err := r .List (context .Background (), & list , client.MatchingFields {indexer .PolicyTargetRefs : key }); err != nil {
13376 return err
13477 }
13578
136- for _ , item := range list .Items {
137- checker .append ("" , item )
138- tctx .HTTPRoutePolicies ["*" ] = append (tctx .HTTPRoutePolicies ["*" ], item )
79+ if len (list .Items ) == 0 {
80+ return nil
13981 }
14082
14183 var (
142- status = true
143- reason = string (v1alpha2 .PolicyReasonAccepted )
144- message string
145- )
146- if checker .conflict {
147- status = false
148- reason = string (v1alpha2 .PolicyReasonConflicted )
84+ status = false
85+ reason = string (v1alpha2 .PolicyReasonConflicted )
14986 message = "HTTPRoutePolicy conflict with others target to the Ingress"
87+ )
88+ if conflict := isPoliciesConflict (list .Items ); ! conflict {
89+ status = true
90+ reason = string (v1alpha2 .PolicyReasonAccepted )
91+ message = ""
15092
151- // clear HTTPRoutePolicies from TranslateContext
152- tctx .HTTPRoutePolicies = make (map [string ][]v1alpha1.HTTPRoutePolicy )
93+ tctx .HTTPRoutePolicies = list .Items
15394 }
15495
15596 for i := range list .Items {
@@ -166,7 +107,7 @@ func modifyHTTPRoutePolicyStatus(parentRefs []gatewayv1.ParentReference, policy
166107 Type : string (v1alpha2 .PolicyConditionAccepted ),
167108 Status : metav1 .ConditionTrue ,
168109 ObservedGeneration : policy .GetGeneration (),
169- LastTransitionTime : metav1.Time { Time : time . Now ()} ,
110+ LastTransitionTime : metav1 .Now (),
170111 Reason : reason ,
171112 Message : message ,
172113 }
@@ -176,63 +117,27 @@ func modifyHTTPRoutePolicyStatus(parentRefs []gatewayv1.ParentReference, policy
176117 _ = SetAncestors (& policy .Status , parentRefs , condition )
177118}
178119
179- type conflictChecker struct {
180- object client.Object
181- policies map [targetRefKey ][]v1alpha1.HTTPRoutePolicy
182- conflict bool
183- }
184-
185- type targetRefKey struct {
186- Group gatewayv1.Group
187- Namespace gatewayv1.Namespace
188- Name gatewayv1.ObjectName
189- SectionName gatewayv1.SectionName
190- }
191-
192- func (c * conflictChecker ) append (sectionName string , policy v1alpha1.HTTPRoutePolicy ) {
193- key := targetRefKey {
194- Group : gatewayv1 .GroupName ,
195- Namespace : gatewayv1 .Namespace (c .object .GetNamespace ()),
196- Name : gatewayv1 .ObjectName (c .object .GetName ()),
197- SectionName : gatewayv1 .SectionName (sectionName ),
120+ func isPoliciesConflict (policies []v1alpha1.HTTPRoutePolicy ) bool {
121+ if len (policies ) == 0 {
122+ return false
198123 }
199- c .policies [key ] = append (c .policies [key ], policy )
200-
201- if ! c .conflict {
202- Loop:
203- for _ , items := range c .policies {
204- for _ , item := range items {
205- if ! ptr .Equal (item .Spec .Priority , policy .Spec .Priority ) {
206- c .conflict = true
207- break Loop
208- }
209- }
124+ priority := policies [0 ].Spec .Priority
125+ for _ , policy := range policies {
126+ if ! ptr .Equal (policy .Spec .Priority , priority ) {
127+ return true
210128 }
211129 }
130+ return false
212131}
213132
214- func isHTTPRoutePolicyConflictOnHTTPRoute (rules []gatewayv1.HTTPRouteRule , policies []v1alpha1.HTTPRoutePolicy ) bool {
215- var m = make (map [targetRefKey ]v1alpha1.HTTPRoutePolicy )
216- for _ , policy := range policies {
133+ func findPolicyWhichTargetRefTheRule (ruleName * gatewayv1.SectionName , kind string , list v1alpha1.HTTPRoutePolicyList ) (policies []v1alpha1.HTTPRoutePolicy ) {
134+ for _ , policy := range list .Items {
217135 for _ , ref := range policy .Spec .TargetRefs {
218- var sectionName gatewayv1.SectionName
219- if ref .SectionName != nil {
220- sectionName = * ref .SectionName
221- }
222- key := targetRefKey {
223- Group : ref .Group ,
224- Namespace : gatewayv1 .Namespace (policy .GetNamespace ()),
225- Name : ref .Name ,
226- SectionName : sectionName ,
136+ if string (ref .Kind ) == kind && (ref .SectionName == nil || * ref .SectionName == "" || ptr .Equal (ref .SectionName , ruleName )) {
137+ policies = append (policies , policy )
138+ break
227139 }
228- m [key ] = policy
229- }
230- }
231- for _ , rule := range rules {
232- if rule .Name == nil || * rule .Name == "" {
233-
234- } else {
235-
236140 }
237141 }
142+ return
238143}
0 commit comments