@@ -33,7 +33,10 @@ import (
33
33
kcpcore "github.com/kcp-dev/kcp/sdk/apis/core"
34
34
kcpdevcorev1alpha1 "github.com/kcp-dev/kcp/sdk/apis/core/v1alpha1"
35
35
36
+ corev1 "k8s.io/api/core/v1"
37
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
36
38
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
39
+ "k8s.io/apimachinery/pkg/labels"
37
40
"k8s.io/apimachinery/pkg/types"
38
41
"k8s.io/utils/ptr"
39
42
ctrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -165,6 +168,27 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) (
165
168
return reconcile.Result {}, nil
166
169
}
167
170
171
+ // if there is a namespace, get it if a namespace filter is also configured
172
+ var namespace * corev1.Namespace
173
+ if filter := r .pubRes .Spec .Filter ; filter != nil && filter .Namespace != nil && remoteObj .GetNamespace () != "" {
174
+ namespace = & corev1.Namespace {}
175
+ key := types.NamespacedName {Name : remoteObj .GetNamespace ()}
176
+
177
+ if err := r .vwClient .Get (wsCtx , key , namespace ); err != nil {
178
+ return reconcile.Result {}, fmt .Errorf ("failed to retrieve remote object's namespace: %w" , err )
179
+ }
180
+ }
181
+
182
+ // apply filtering rules to scope down the number of objects we sync
183
+ include , err := r .objectMatchesFilter (remoteObj , namespace )
184
+ if err != nil {
185
+ return reconcile.Result {}, fmt .Errorf ("failed to apply filtering rules: %w" , err )
186
+ }
187
+
188
+ if ! include {
189
+ return reconcile.Result {}, nil
190
+ }
191
+
168
192
syncContext := sync .NewContext (ctx , wsCtx )
169
193
170
194
// if desired, fetch the cluster path as well (some downstream service providers might make use of it,
@@ -193,3 +217,34 @@ func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) (
193
217
194
218
return result , nil
195
219
}
220
+
221
+ func (r * Reconciler ) objectMatchesFilter (remoteObj * unstructured.Unstructured , namespace * corev1.Namespace ) (bool , error ) {
222
+ if r .pubRes .Spec .Filter == nil {
223
+ return true , nil
224
+ }
225
+
226
+ objMatches , err := r .matchesFilter (remoteObj , r .pubRes .Spec .Filter .Resource )
227
+ if err != nil || ! objMatches {
228
+ return false , err
229
+ }
230
+
231
+ nsMatches , err := r .matchesFilter (namespace , r .pubRes .Spec .Filter .Namespace )
232
+ if err != nil || ! nsMatches {
233
+ return false , err
234
+ }
235
+
236
+ return true , nil
237
+ }
238
+
239
+ func (r * Reconciler ) matchesFilter (obj metav1.Object , selector * metav1.LabelSelector ) (bool , error ) {
240
+ if selector == nil {
241
+ return true , nil
242
+ }
243
+
244
+ s , err := metav1 .LabelSelectorAsSelector (selector )
245
+ if err != nil {
246
+ return false , err
247
+ }
248
+
249
+ return s .Matches (labels .Set (obj .GetLabels ())), nil
250
+ }
0 commit comments