@@ -141,7 +141,7 @@ func (r *ApisixRouteReconciler) processApisixRoute(ctx context.Context, tc *prov
141141 var (
142142 rules = make (map [string ]struct {})
143143 )
144- for httpIndex , http := range in .Spec .HTTP {
144+ for _ , http := range in .Spec .HTTP {
145145 // check rule names
146146 if _ , ok := rules [http .Name ]; ok {
147147 return ReasonError {
@@ -151,126 +151,166 @@ func (r *ApisixRouteReconciler) processApisixRoute(ctx context.Context, tc *prov
151151 }
152152 rules [http .Name ] = struct {}{}
153153
154- // check secret
155- for _ , plugin := range http .Plugins {
156- if ! plugin .Enable || plugin .Config == nil || plugin .SecretRef == "" {
157- continue
158- }
159- var (
160- secret = corev1.Secret {
161- ObjectMeta : metav1.ObjectMeta {
162- Name : plugin .SecretRef ,
163- Namespace : in .Namespace ,
164- },
165- }
166- secretNN = utils .NamespacedName (& secret )
167- )
168- if err := r .Get (ctx , secretNN , & secret ); err != nil {
169- return ReasonError {
170- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
171- Message : fmt .Sprintf ("failed to get Secret: %s" , secretNN ),
172- }
173- }
174-
175- tc .Secrets [utils .NamespacedName (& secret )] = & secret
154+ if err := r .processApisixRouteHTTPRule (ctx , tc , in , http ); err != nil {
155+ r .Log .Error (err , "failed to process ApisixRoute http rule" )
156+ return err
176157 }
158+ }
159+
160+ return nil
161+ }
177162
178- // check vars
179- // todo: cache the result to tctx
180- if _ , err := http .Match .NginxVars .ToVars (); err != nil {
163+ func (r * ApisixRouteReconciler ) processApisixRouteHTTPRule (ctx context.Context , tc * provider.TranslateContext , in * apiv2.ApisixRoute , rule apiv2.ApisixRouteHTTP ) error {
164+ // check secret
165+ for _ , plugin := range rule .Plugins {
166+ if ! plugin .Enable || plugin .Config == nil || plugin .SecretRef == "" {
167+ continue
168+ }
169+ var (
170+ secret = corev1.Secret {
171+ ObjectMeta : metav1.ObjectMeta {
172+ Name : plugin .SecretRef ,
173+ Namespace : in .Namespace ,
174+ },
175+ }
176+ secretNN = utils .NamespacedName (& secret )
177+ )
178+ if err := r .Get (ctx , secretNN , & secret ); err != nil {
181179 return ReasonError {
182180 Reason : string (apiv2 .ConditionReasonInvalidSpec ),
183- Message : fmt .Sprintf (".spec.http[%d].match.exprs : %s" , httpIndex , err . Error () ),
181+ Message : fmt .Sprintf ("failed to get Secret : %s" , secretNN ),
184182 }
185183 }
186184
187- // validate remote address
188- if err := utils .ValidateRemoteAddrs (http .Match .RemoteAddrs ); err != nil {
189- return ReasonError {
190- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
191- Message : fmt .Sprintf (".spec.http[%d].match.remoteAddrs: %s" , httpIndex , err .Error ()),
192- }
185+ tc .Secrets [utils .NamespacedName (& secret )] = & secret
186+ }
187+
188+ // check vars
189+ // todo: cache the result to tctx
190+ if _ , err := rule .Match .NginxVars .ToVars (); err != nil {
191+ return ReasonError {
192+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
193+ Message : fmt .Sprintf (".spec.http[].match.exprs: %v" , err ),
193194 }
195+ }
194196
195- // process backend
196- var backends = make (map [types.NamespacedName ]struct {})
197- for _ , backend := range http .Backends {
198- var (
199- service = corev1.Service {
200- ObjectMeta : metav1.ObjectMeta {
201- Name : backend .ServiceName ,
202- Namespace : in .Namespace ,
203- },
204- }
205- serviceNN = utils .NamespacedName (& service )
206- )
207- if _ , ok := backends [serviceNN ]; ok {
208- return ReasonError {
209- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
210- Message : fmt .Sprintf ("duplicate backend service: %s" , serviceNN ),
211- }
212- }
213- backends [serviceNN ] = struct {}{}
197+ // validate remote address
198+ if err := utils .ValidateRemoteAddrs (rule .Match .RemoteAddrs ); err != nil {
199+ return ReasonError {
200+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
201+ Message : fmt .Sprintf (".spec.http[].match.remoteAddrs: %v" , err ),
202+ }
203+ }
214204
215- if err := r .Get (ctx , serviceNN , & service ); err != nil {
216- if err := client .IgnoreNotFound (err ); err == nil {
217- r .Log .Error (errors .New ("service not found" ), "Service" , serviceNN )
218- continue
219- }
220- return err
221- }
222- if service .Spec .Type == corev1 .ServiceTypeExternalName {
223- tc .Services [serviceNN ] = & service
224- continue
205+ // process backend
206+ var backends = make (map [types.NamespacedName ]struct {})
207+ for _ , backend := range rule .Backends {
208+ var (
209+ service = corev1.Service {
210+ ObjectMeta : metav1.ObjectMeta {
211+ Name : backend .ServiceName ,
212+ Namespace : in .Namespace ,
213+ },
225214 }
226-
227- if backend .ResolveGranularity == "service" && service .Spec .ClusterIP == "" {
228- r .Log .Error (errors .New ("service has no ClusterIP" ), "Service" , serviceNN , "ResolveGranularity" , backend .ResolveGranularity )
229- continue
215+ serviceNN = utils .NamespacedName (& service )
216+ )
217+ if _ , ok := backends [serviceNN ]; ok {
218+ return ReasonError {
219+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
220+ Message : fmt .Sprintf ("duplicate backend service: %s" , serviceNN ),
230221 }
222+ }
223+ backends [serviceNN ] = struct {}{}
231224
232- if ! slices .ContainsFunc (service .Spec .Ports , func (port corev1.ServicePort ) bool {
233- return port .Port == int32 (backend .ServicePort .IntValue ())
234- }) {
235- r .Log .Error (errors .New ("port not found in service" ), "Service" , serviceNN , "port" , backend .ServicePort .String ())
225+ if err := r .Get (ctx , serviceNN , & service ); err != nil {
226+ if err := client .IgnoreNotFound (err ); err == nil {
227+ r .Log .Error (errors .New ("service not found" ), "Service" , serviceNN )
236228 continue
237229 }
230+ return err
231+ }
232+ if service .Spec .Type == corev1 .ServiceTypeExternalName {
238233 tc .Services [serviceNN ] = & service
234+ continue
235+ }
239236
240- var endpoints discoveryv1.EndpointSliceList
241- if err := r .List (ctx , & endpoints ,
242- client .InNamespace (service .Namespace ),
243- client.MatchingLabels {
244- discoveryv1 .LabelServiceName : service .Name ,
245- },
246- ); err != nil {
247- return ReasonError {
248- Reason : string (apiv2 .ConditionReasonInvalidSpec ),
249- Message : fmt .Sprintf ("failed to list endpoint slices: %v" , err ),
250- }
237+ if backend .ResolveGranularity == "service" && service .Spec .ClusterIP == "" {
238+ r .Log .Error (errors .New ("service has no ClusterIP" ), "Service" , serviceNN , "ResolveGranularity" , backend .ResolveGranularity )
239+ continue
240+ }
241+
242+ if ! slices .ContainsFunc (service .Spec .Ports , func (port corev1.ServicePort ) bool {
243+ return port .Port == int32 (backend .ServicePort .IntValue ())
244+ }) {
245+ r .Log .Error (errors .New ("port not found in service" ), "Service" , serviceNN , "port" , backend .ServicePort .String ())
246+ continue
247+ }
248+ tc .Services [serviceNN ] = & service
249+
250+ var endpoints discoveryv1.EndpointSliceList
251+ if err := r .List (ctx , & endpoints ,
252+ client .InNamespace (service .Namespace ),
253+ client.MatchingLabels {
254+ discoveryv1 .LabelServiceName : service .Name ,
255+ },
256+ ); err != nil {
257+ return ReasonError {
258+ Reason : string (apiv2 .ConditionReasonInvalidSpec ),
259+ Message : fmt .Sprintf ("failed to list endpoint slices: %v" , err ),
251260 }
252- tc .EndpointSlices [serviceNN ] = endpoints .Items
253261 }
262+ tc .EndpointSlices [serviceNN ] = endpoints .Items
263+ }
254264
255- for _ , upstream := range http .Upstreams {
256- if upstream .Name == "" {
265+ for _ , upstream := range rule .Upstreams {
266+ if upstream .Name == "" {
267+ continue
268+ }
269+ var (
270+ ups apiv2.ApisixUpstream
271+ upsNN = types.NamespacedName {
272+ Namespace : in .GetNamespace (),
273+ Name : upstream .Name ,
274+ }
275+ )
276+ if err := r .Get (ctx , upsNN , & ups ); err != nil {
277+ r .Log .Error (err , "failed to get ApisixUpstream" , "ApisixUpstream" , upsNN )
278+ if client .IgnoreNotFound (err ) == nil {
257279 continue
258280 }
259- var ups = apiv2.ApisixUpstream {
260- ObjectMeta : metav1.ObjectMeta {
261- Name : upstream .Name ,
262- SelfLink : in .GetNamespace (),
263- },
281+ return err
282+ }
283+ tc .Upstreams [upsNN ] = & ups
284+
285+ for _ , node := range ups .Spec .ExternalNodes {
286+ if node .Type == apiv2 .ExternalTypeService {
287+ var (
288+ service corev1.Service
289+ serviceNN = types.NamespacedName {Namespace : ups .GetNamespace (), Name : node .Name }
290+ )
291+ if err := r .Get (ctx , serviceNN , & service ); err != nil {
292+ r .Log .Error (err , "failed to get service in ApisixUpstream" , "ApisixUpstream" , upsNN , "Service" , serviceNN )
293+ if client .IgnoreNotFound (err ) == nil {
294+ continue
295+ }
296+ return err
297+ }
298+ tc .Services [utils .NamespacedName (& service )] = & service
264299 }
265- upsNN := utils .NamespacedName (& ups )
266- if err := r .Get (ctx , upsNN , & ups ); err != nil {
267- if client .IgnoreNotFound (err ) == nil {
268- r .Log .Error (err , "ApisixUpstream not found" )
269- continue
300+ }
301+
302+ if ups .Spec .TLSSecret != nil && ups .Spec .TLSSecret .Name != "" {
303+ var (
304+ secret corev1.Secret
305+ secretNN = types.NamespacedName {Namespace : cmp .Or (ups .Spec .TLSSecret .Namespace , in .GetNamespace ()), Name : ups .Spec .TLSSecret .Name }
306+ )
307+ if err := r .Get (ctx , secretNN , & secret ); err != nil {
308+ r .Log .Error (err , "failed to get secret in ApisixUpstream" , "ApisixUpstream" , upsNN , "Secret" , secretNN )
309+ if client .IgnoreNotFound (err ) != nil {
310+ return err
270311 }
271- return err
272312 }
273- tc .Upstreams [ utils . NamespacedNameKind ( & ups ) ] = & ups
313+ tc .Secrets [ secretNN ] = & secret
274314 }
275315 }
276316
0 commit comments