Skip to content

Commit e18339d

Browse files
committed
fix: r
Signed-off-by: ashing <axingfly@gmail.com>
1 parent 8aa3839 commit e18339d

2 files changed

Lines changed: 148 additions & 144 deletions

File tree

internal/controller/apisixpluginconfig_controller.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -95,26 +95,9 @@ func (r *ApisixPluginConfigReconciler) Reconcile(ctx context.Context, req ctrl.R
9595
if err = r.processIngressClassParameters(ctx, tctx, &pc, ic); err != nil {
9696
return ctrl.Result{}, err
9797
}
98-
if err = r.processApisixPluginConfig(ctx, tctx, &pc); err != nil {
99-
return ctrl.Result{}, err
100-
}
10198
return ctrl.Result{}, nil
10299
}
103100

104-
func (r *ApisixPluginConfigReconciler) processApisixPluginConfig(_ context.Context, _ *provider.TranslateContext, in *apiv2.ApisixPluginConfig) error {
105-
// Validate plugins
106-
for _, plugin := range in.Spec.Plugins {
107-
if plugin.Name == "" {
108-
return ReasonError{
109-
Reason: string(apiv2.ConditionReasonInvalidSpec),
110-
Message: "plugin name cannot be empty",
111-
}
112-
}
113-
}
114-
115-
return nil
116-
}
117-
118101
func (r *ApisixPluginConfigReconciler) listApisixPluginConfigForIngressClass(ctx context.Context, object client.Object) (requests []reconcile.Request) {
119102
ic, ok := object.(*networkingv1.IngressClass)
120103
if !ok {

internal/controller/apisixroute_controller.go

Lines changed: 148 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)