@@ -153,91 +153,14 @@ func (r *ApisixRouteReconciler) processApisixRoute(ctx context.Context, tc *prov
153153
154154 // check plugin config reference
155155 if http .PluginConfigName != "" {
156- pcNamespace := in .Namespace
157- if http .PluginConfigNamespace != "" {
158- pcNamespace = http .PluginConfigNamespace
159- }
160- var (
161- pc = apiv2.ApisixPluginConfig {
162- ObjectMeta : metav1.ObjectMeta {
163- Name : http .PluginConfigName ,
164- Namespace : pcNamespace ,
165- },
166- }
167- pcNN = utils .NamespacedName (& pc )
168- )
169- if err := r .Get (ctx , pcNN , & pc ); err != nil {
170- return ReasonError {
171- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
172- Message : fmt .Sprintf ("failed to get ApisixPluginConfig: %s" , pcNN ),
173- }
174- }
175-
176- // Check if ApisixPluginConfig has IngressClassName and if it matches
177- if in .Spec .IngressClassName != pc .Spec .IngressClassName && pc .Spec .IngressClassName != "" {
178- var pcIC networkingv1.IngressClass
179- if err := r .Get (ctx , client.ObjectKey {Name : pc .Spec .IngressClassName }, & pcIC ); err != nil {
180- return ReasonError {
181- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
182- Message : fmt .Sprintf ("failed to get IngressClass %s for ApisixPluginConfig %s: %v" , pc .Spec .IngressClassName , pcNN , err ),
183- }
184- }
185- if ! matchesController (pcIC .Spec .Controller ) {
186- return ReasonError {
187- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
188- Message : fmt .Sprintf ("ApisixPluginConfig %s references IngressClass %s with non-matching controller" , pcNN , pc .Spec .IngressClassName ),
189- }
190- }
191- }
192-
193- tc .ApisixPluginConfigs [pcNN ] = & pc
194-
195- // Also check secrets referenced by plugin config
196- for _ , plugin := range pc .Spec .Plugins {
197- if ! plugin .Enable || plugin .Config == nil || plugin .SecretRef == "" {
198- continue
199- }
200- var (
201- secret = corev1.Secret {
202- ObjectMeta : metav1.ObjectMeta {
203- Name : plugin .SecretRef ,
204- Namespace : pc .Namespace ,
205- },
206- }
207- secretNN = utils .NamespacedName (& secret )
208- )
209- if err := r .Get (ctx , secretNN , & secret ); err != nil {
210- return ReasonError {
211- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
212- Message : fmt .Sprintf ("failed to get Secret: %s" , secretNN ),
213- }
214- }
215- tc .Secrets [secretNN ] = & secret
156+ if err := r .validatePluginConfig (ctx , tc , in , http ); err != nil {
157+ return err
216158 }
217159 }
218160
219161 // check secret
220- for _ , plugin := range http .Plugins {
221- if ! plugin .Enable || plugin .Config == nil || plugin .SecretRef == "" {
222- continue
223- }
224- var (
225- secret = corev1.Secret {
226- ObjectMeta : metav1.ObjectMeta {
227- Name : plugin .SecretRef ,
228- Namespace : in .Namespace ,
229- },
230- }
231- secretNN = utils .NamespacedName (& secret )
232- )
233- if err := r .Get (ctx , secretNN , & secret ); err != nil {
234- return ReasonError {
235- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
236- Message : fmt .Sprintf ("failed to get Secret: %s" , secretNN ),
237- }
238- }
239-
240- tc .Secrets [utils .NamespacedName (& secret )] = & secret
162+ if err := r .validateSecrets (ctx , tc , in , http ); err != nil {
163+ return err
241164 }
242165
243166 // check vars
@@ -258,66 +181,164 @@ func (r *ApisixRouteReconciler) processApisixRoute(ctx context.Context, tc *prov
258181 }
259182
260183 // process backend
261- var backends = make (map [types.NamespacedName ]struct {})
262- for _ , backend := range http .Backends {
263- var (
264- service = corev1.Service {
265- ObjectMeta : metav1.ObjectMeta {
266- Name : backend .ServiceName ,
267- Namespace : in .Namespace ,
268- },
269- }
270- serviceNN = utils .NamespacedName (& service )
271- )
272- if _ , ok := backends [serviceNN ]; ok {
273- return ReasonError {
274- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
275- Message : fmt .Sprintf ("duplicate backend service: %s" , serviceNN ),
276- }
184+ if err := r .validateBackends (ctx , tc , in , http ); err != nil {
185+ return err
186+ }
187+ }
188+
189+ return nil
190+ }
191+
192+ func (r * ApisixRouteReconciler ) validatePluginConfig (ctx context.Context , tc * provider.TranslateContext , in * apiv2.ApisixRoute , http apiv2.ApisixRouteHTTP ) error {
193+ pcNamespace := in .Namespace
194+ if http .PluginConfigNamespace != "" {
195+ pcNamespace = http .PluginConfigNamespace
196+ }
197+ var (
198+ pc = apiv2.ApisixPluginConfig {
199+ ObjectMeta : metav1.ObjectMeta {
200+ Name : http .PluginConfigName ,
201+ Namespace : pcNamespace ,
202+ },
203+ }
204+ pcNN = utils .NamespacedName (& pc )
205+ )
206+ if err := r .Get (ctx , pcNN , & pc ); err != nil {
207+ return ReasonError {
208+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
209+ Message : fmt .Sprintf ("failed to get ApisixPluginConfig: %s" , pcNN ),
210+ }
211+ }
212+
213+ // Check if ApisixPluginConfig has IngressClassName and if it matches
214+ if in .Spec .IngressClassName != pc .Spec .IngressClassName && pc .Spec .IngressClassName != "" {
215+ var pcIC networkingv1.IngressClass
216+ if err := r .Get (ctx , client.ObjectKey {Name : pc .Spec .IngressClassName }, & pcIC ); err != nil {
217+ return ReasonError {
218+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
219+ Message : fmt .Sprintf ("failed to get IngressClass %s for ApisixPluginConfig %s: %v" , pc .Spec .IngressClassName , pcNN , err ),
220+ }
221+ }
222+ if ! matchesController (pcIC .Spec .Controller ) {
223+ return ReasonError {
224+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
225+ Message : fmt .Sprintf ("ApisixPluginConfig %s references IngressClass %s with non-matching controller" , pcNN , pc .Spec .IngressClassName ),
277226 }
278- backends [serviceNN ] = struct {}{}
227+ }
228+ }
279229
280- if err := r .Get (ctx , serviceNN , & service ); err != nil {
281- if err := client .IgnoreNotFound (err ); err == nil {
282- r .Log .Error (errors .New ("service not found" ), "Service" , serviceNN )
283- continue
284- }
285- return err
230+ tc .ApisixPluginConfigs [pcNN ] = & pc
231+
232+ // Also check secrets referenced by plugin config
233+ for _ , plugin := range pc .Spec .Plugins {
234+ if ! plugin .Enable || plugin .Config == nil || plugin .SecretRef == "" {
235+ continue
236+ }
237+ var (
238+ secret = corev1.Secret {
239+ ObjectMeta : metav1.ObjectMeta {
240+ Name : plugin .SecretRef ,
241+ Namespace : pc .Namespace ,
242+ },
286243 }
287- if service .Spec .Type == corev1 .ServiceTypeExternalName {
288- tc .Services [serviceNN ] = & service
289- continue
244+ secretNN = utils .NamespacedName (& secret )
245+ )
246+ if err := r .Get (ctx , secretNN , & secret ); err != nil {
247+ return ReasonError {
248+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
249+ Message : fmt .Sprintf ("failed to get Secret: %s" , secretNN ),
290250 }
251+ }
252+ tc .Secrets [secretNN ] = & secret
253+ }
254+ return nil
255+ }
291256
292- if backend .ResolveGranularity == "service" && service .Spec .ClusterIP == "" {
293- r .Log .Error (errors .New ("service has no ClusterIP" ), "Service" , serviceNN , "ResolveGranularity" , backend .ResolveGranularity )
294- continue
257+ func (r * ApisixRouteReconciler ) validateSecrets (ctx context.Context , tc * provider.TranslateContext , in * apiv2.ApisixRoute , http apiv2.ApisixRouteHTTP ) error {
258+ for _ , plugin := range http .Plugins {
259+ if ! plugin .Enable || plugin .Config == nil || plugin .SecretRef == "" {
260+ continue
261+ }
262+ var (
263+ secret = corev1.Secret {
264+ ObjectMeta : metav1.ObjectMeta {
265+ Name : plugin .SecretRef ,
266+ Namespace : in .Namespace ,
267+ },
295268 }
269+ secretNN = utils .NamespacedName (& secret )
270+ )
271+ if err := r .Get (ctx , secretNN , & secret ); err != nil {
272+ return ReasonError {
273+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
274+ Message : fmt .Sprintf ("failed to get Secret: %s" , secretNN ),
275+ }
276+ }
296277
297- if ! slices .ContainsFunc (service .Spec .Ports , func (port corev1.ServicePort ) bool {
298- return port .Port == int32 (backend .ServicePort .IntValue ())
299- }) {
300- r .Log .Error (errors .New ("port not found in service" ), "Service" , serviceNN , "port" , backend .ServicePort .String ())
278+ tc .Secrets [utils .NamespacedName (& secret )] = & secret
279+ }
280+ return nil
281+ }
282+
283+ func (r * ApisixRouteReconciler ) validateBackends (ctx context.Context , tc * provider.TranslateContext , in * apiv2.ApisixRoute , http apiv2.ApisixRouteHTTP ) error {
284+ var backends = make (map [types.NamespacedName ]struct {})
285+ for _ , backend := range http .Backends {
286+ var (
287+ service = corev1.Service {
288+ ObjectMeta : metav1.ObjectMeta {
289+ Name : backend .ServiceName ,
290+ Namespace : in .Namespace ,
291+ },
292+ }
293+ serviceNN = utils .NamespacedName (& service )
294+ )
295+ if _ , ok := backends [serviceNN ]; ok {
296+ return ReasonError {
297+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
298+ Message : fmt .Sprintf ("duplicate backend service: %s" , serviceNN ),
299+ }
300+ }
301+ backends [serviceNN ] = struct {}{}
302+
303+ if err := r .Get (ctx , serviceNN , & service ); err != nil {
304+ if err := client .IgnoreNotFound (err ); err == nil {
305+ r .Log .Error (errors .New ("service not found" ), "Service" , serviceNN )
301306 continue
302307 }
308+ return err
309+ }
310+ if service .Spec .Type == corev1 .ServiceTypeExternalName {
303311 tc .Services [serviceNN ] = & service
312+ continue
313+ }
304314
305- var endpoints discoveryv1.EndpointSliceList
306- if err := r .List (ctx , & endpoints ,
307- client .InNamespace (service .Namespace ),
308- client.MatchingLabels {
309- discoveryv1 .LabelServiceName : service .Name ,
310- },
311- ); err != nil {
312- return ReasonError {
313- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
314- Message : fmt .Sprintf ("failed to list endpoint slices: %v" , err ),
315- }
315+ if backend .ResolveGranularity == "service" && service .Spec .ClusterIP == "" {
316+ r .Log .Error (errors .New ("service has no ClusterIP" ), "Service" , serviceNN , "ResolveGranularity" , backend .ResolveGranularity )
317+ continue
318+ }
319+
320+ if ! slices .ContainsFunc (service .Spec .Ports , func (port corev1.ServicePort ) bool {
321+ return port .Port == int32 (backend .ServicePort .IntValue ())
322+ }) {
323+ r .Log .Error (errors .New ("port not found in service" ), "Service" , serviceNN , "port" , backend .ServicePort .String ())
324+ continue
325+ }
326+ tc .Services [serviceNN ] = & service
327+
328+ var endpoints discoveryv1.EndpointSliceList
329+ if err := r .List (ctx , & endpoints ,
330+ client .InNamespace (service .Namespace ),
331+ client.MatchingLabels {
332+ discoveryv1 .LabelServiceName : service .Name ,
333+ },
334+ ); err != nil {
335+ return ReasonError {
336+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
337+ Message : fmt .Sprintf ("failed to list endpoint slices: %v" , err ),
316338 }
317- tc .EndpointSlices [serviceNN ] = endpoints .Items
318339 }
340+ tc .EndpointSlices [serviceNN ] = endpoints .Items
319341 }
320-
321342 return nil
322343}
323344
0 commit comments