Skip to content

Commit aac6fe7

Browse files
fix: ProviderConfig reconciler to filter usages by namespace (Fixes crossplane/crossplane#7154)
Signed-off-by: Sai Kruthi Wusirika <kruthi@multiscale.ai>
1 parent 8fa945b commit aac6fe7

File tree

2 files changed

+87
-4
lines changed

2 files changed

+87
-4
lines changed

pkg/reconciler/providerconfig/reconciler.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco
166166
"uid", pc.GetUID(),
167167
"version", pc.GetResourceVersion(),
168168
"name", pc.GetName(),
169+
"namespace", pc.GetNamespace(),
169170
)
170171

171172
l := r.newUsageList()
@@ -178,7 +179,12 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco
178179
matchingLabels[xpv1.LabelKeyProviderKind] = pc.GetObjectKind().GroupVersionKind().Kind
179180
}
180181

181-
if err := r.client.List(ctx, l, matchingLabels); err != nil {
182+
listOpts := []client.ListOption{matchingLabels}
183+
if pc.GetNamespace() != "" {
184+
listOpts = append(listOpts, client.InNamespace(pc.GetNamespace()))
185+
}
186+
187+
if err := r.client.List(ctx, l, listOpts...); err != nil {
182188
log.Debug(errListPCUs, "error", err)
183189
r.record.Event(pc, event.Warning(reasonAccount, errors.Wrap(err, errListPCUs)))
184190

pkg/reconciler/providerconfig/reconciler_test.go

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ func TestReconciler(t *testing.T) {
7777
}
7878

7979
type want struct {
80-
result reconcile.Result
81-
err error
80+
result reconcile.Result
81+
err error
82+
request reconcile.Request
8283
}
8384

8485
cases := map[string]struct {
@@ -333,13 +334,89 @@ func TestReconciler(t *testing.T) {
333334
result: reconcile.Result{Requeue: false},
334335
},
335336
},
337+
"ListUsagesScopedToNamespaceWhenNamespaced": {
338+
reason: "When ProviderConfig is namespaced, List should be called with InNamespace option",
339+
args: args{
340+
m: &fake.Manager{
341+
Client: &test.MockClient{
342+
MockGet: test.NewMockGetFn(nil, func(obj client.Object) error {
343+
pc := obj.(*fake.ProviderConfig)
344+
pc.SetNamespace("test-ns")
345+
pc.SetName("my-pc")
346+
return nil
347+
}),
348+
MockList: func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
349+
// Capture and verify list options: should include InNamespace("test-ns")
350+
listOpts := &client.ListOptions{}
351+
for _, opt := range opts {
352+
opt.ApplyToList(listOpts)
353+
}
354+
if listOpts.Namespace != "test-ns" {
355+
t.Errorf("List called with namespace %q, want InNamespace(\"test-ns\")", listOpts.Namespace)
356+
}
357+
return nil
358+
},
359+
MockUpdate: test.NewMockUpdateFn(nil),
360+
MockStatusUpdate: test.NewMockSubResourceUpdateFn(nil),
361+
},
362+
Scheme: fake.SchemeWith(&fake.ProviderConfig{}, &fake.ProviderConfigUsage{}, &ProviderConfigUsageList{}),
363+
},
364+
of: resource.ProviderConfigKinds{
365+
Config: fake.GVK(&fake.ProviderConfig{}),
366+
Usage: fake.GVK(&fake.ProviderConfigUsage{}),
367+
UsageList: fake.GVK(&ProviderConfigUsageList{}),
368+
},
369+
},
370+
want: want{
371+
result: reconcile.Result{Requeue: false},
372+
request: reconcile.Request{NamespacedName: types.NamespacedName{Name: "my-pc", Namespace: "test-ns"}},
373+
},
374+
},
375+
"ListUsagesNotScopedToNamespaceWhenClusterScoped": {
376+
reason: "When ProviderConfig is cluster-scoped (empty namespace), List should not include InNamespace",
377+
args: args{
378+
m: &fake.Manager{
379+
Client: &test.MockClient{
380+
MockGet: test.NewMockGetFn(nil, func(obj client.Object) error {
381+
pc := obj.(*fake.ProviderConfig)
382+
pc.SetNamespace("") // cluster-scoped
383+
pc.SetName("my-pc")
384+
return nil
385+
}),
386+
MockList: func(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
387+
listOpts := &client.ListOptions{}
388+
for _, opt := range opts {
389+
opt.ApplyToList(listOpts)
390+
}
391+
if listOpts.Namespace != "" {
392+
t.Errorf("List called with namespace %q for cluster-scoped ProviderConfig, want empty", listOpts.Namespace)
393+
}
394+
return nil
395+
},
396+
MockUpdate: test.NewMockUpdateFn(nil),
397+
MockStatusUpdate: test.NewMockSubResourceUpdateFn(nil),
398+
},
399+
Scheme: fake.SchemeWith(&fake.ProviderConfig{}, &fake.ProviderConfigUsage{}, &ProviderConfigUsageList{}),
400+
},
401+
of: resource.ProviderConfigKinds{
402+
Config: fake.GVK(&fake.ProviderConfig{}),
403+
Usage: fake.GVK(&fake.ProviderConfigUsage{}),
404+
UsageList: fake.GVK(&ProviderConfigUsageList{}),
405+
},
406+
},
407+
want: want{
408+
result: reconcile.Result{Requeue: false},
409+
request: reconcile.Request{NamespacedName: types.NamespacedName{Name: "my-pc"}},
410+
},
411+
},
336412
}
337413

338414
for name, tc := range cases {
339415
t.Run(name, func(t *testing.T) {
340416
r := NewReconciler(tc.args.m, tc.args.of)
341417

342-
got, err := r.Reconcile(context.Background(), reconcile.Request{})
418+
req := tc.want.request
419+
got, err := r.Reconcile(context.Background(), req)
343420
if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
344421
t.Errorf("\n%s\nr.Reconcile(...): -want error, +got error:\n%s", tc.reason, diff)
345422
}

0 commit comments

Comments
 (0)