Repository: kubernetes-sigs/kueue

Issue:
[flaky test] Creating a Job With Queueing Should allow to schedule Jobs via CronJob
**What happened**:

Failure on unreleated branch; https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/5327/pull-kueue-test-e2e-main-1-31/1926944014251069440

**What you expected to happen**:
no failure

**How to reproduce it (as minimally and precisely as possible)**:
ci
**Anything else we need to know?**:
```
{Timed out after 10.001s.
The function passed to Eventually failed at /home/prow/go/src/sigs.k8s.io/kueue/test/util/util.go:125 with:
Error matcher expects an error.  Got:
    <nil>: nil failed [FAILED] Timed out after 10.001s.
The function passed to Eventually failed at /home/prow/go/src/sigs.k8s.io/kueue/test/util/util.go:125 with:
Error matcher expects an error.  Got:
    <nil>: nil
In [AfterEach] at: /home/prow/go/src/sigs.k8s.io/kueue/test/e2e/singlecluster/e2e_test.go:118 @ 05/26/25 10:25:10.353
}
```

Discussion:
@mbobrovskyi: /assign@mimowo: /reopen 
as this occurred on 0.11 branch: https://prow.k8s.io/view/gs/kubernetes-ci-logs/logs/periodic-kueue-test-e2e-release-0-11-1-31/1932601473795887104@k8s-ci-robot: @mimowo: Reopened this issue.

<details>

In response to [this](https://github.com/kubernetes-sigs/kueue/issues/5350#issuecomment-2961682683):

>/reopen 
>as this occurred on 0.11 branch: https://prow.k8s.io/view/gs/kubernetes-ci-logs/logs/periodic-kueue-test-e2e-release-0-11-1-31/1932601473795887104


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>@mbobrovskyi: /close

Due to fixed on https://github.com/kubernetes-sigs/kueue/pull/5619.@k8s-ci-robot: @mbobrovskyi: Closing this issue.

<details>

In response to [this](https://github.com/kubernetes-sigs/kueue/issues/5350#issuecomment-2961945457):

>/close
>
>Due to fixed on https://github.com/kubernetes-sigs/kueue/pull/5619.


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>

Solution patch:
diff --git a/Makefile-test.mk b/Makefile-test.mk
index b5d36caa4..3c3bcab61 100644
--- a/Makefile-test.mk
+++ b/Makefile-test.mk
@@ -34,6 +34,7 @@ INTEGRATION_TARGET_MULTIKUEUE ?= ./test/integration/multikueue/...
 # Verbosity level for apiserver logging.
 # The logging is disabled if 0.
 INTEGRATION_API_LOG_LEVEL ?= 0
+INTEGRATION_OUTPUT_OPTIONS ?= --output-interceptor-mode=none 
 
 # Folder where the e2e tests are located.
 E2E_TARGET ?= ./test/e2e/...
@@ -85,7 +86,7 @@ test-integration: gomod-download envtest ginkgo dep-crds kueuectl ginkgo-top ##
 	KUEUE_BIN=$(PROJECT_DIR)/bin \
 	ENVTEST_K8S_VERSION=$(ENVTEST_K8S_VERSION) \
 	TEST_LOG_LEVEL=$(TEST_LOG_LEVEL) API_LOG_LEVEL=$(INTEGRATION_API_LOG_LEVEL) \
-	$(GINKGO) $(INTEGRATION_FILTERS) $(GINKGO_ARGS) $(GOFLAGS) -procs=$(INTEGRATION_NPROCS) --race --junit-report=junit.xml --json-report=integration.json --output-dir=$(ARTIFACTS) -v $(INTEGRATION_TARGET)
+	$(GINKGO) $(INTEGRATION_FILTERS) $(GINKGO_ARGS) $(GOFLAGS) -procs=$(INTEGRATION_NPROCS) --race --junit-report=junit.xml --json-report=integration.json $(INTEGRATION_OUTPUT_OPTIONS) --output-dir=$(ARTIFACTS) -v $(INTEGRATION_TARGET)
 	$(PROJECT_DIR)/bin/ginkgo-top -i $(ARTIFACTS)/integration.json > $(ARTIFACTS)/integration-top.yaml
 
 .PHONY: test-integration-baseline
@@ -103,7 +104,7 @@ test-multikueue-integration: gomod-download envtest ginkgo dep-crds ginkgo-top #
 	KUEUE_BIN=$(PROJECT_DIR)/bin \
 	ENVTEST_K8S_VERSION=$(ENVTEST_K8S_VERSION) \
 	TEST_LOG_LEVEL=$(TEST_LOG_LEVEL) API_LOG_LEVEL=$(INTEGRATION_API_LOG_LEVEL) \
-	$(GINKGO) $(INTEGRATION_FILTERS) $(GINKGO_ARGS) $(GOFLAGS) -procs=$(INTEGRATION_NPROCS_MULTIKUEUE) --race --junit-report=multikueue-junit.xml --json-report=multikueue-integration.json --output-dir=$(ARTIFACTS) -v $(INTEGRATION_TARGET_MULTIKUEUE)
+	$(GINKGO) $(INTEGRATION_FILTERS) $(GINKGO_ARGS) $(GOFLAGS) -procs=$(INTEGRATION_NPROCS_MULTIKUEUE) --race --junit-report=multikueue-junit.xml --json-report=multikueue-integration.json $(INTEGRATION_OUTPUT_OPTIONS) --output-dir=$(ARTIFACTS) -v $(INTEGRATION_TARGET_MULTIKUEUE)
 	$(PROJECT_DIR)/bin/ginkgo-top -i $(ARTIFACTS)/multikueue-integration.json > $(ARTIFACTS)/multikueue-integration-top.yaml
 
 CREATE_KIND_CLUSTER ?= true
diff --git a/charts/kueue/templates/webhook/manifests.yaml b/charts/kueue/templates/webhook/manifests.yaml
index 5b7a9c9af..2123b9ac3 100644
--- a/charts/kueue/templates/webhook/manifests.yaml
+++ b/charts/kueue/templates/webhook/manifests.yaml
@@ -21,6 +21,10 @@ webhooks:
         path: /mutate-workload-codeflare-dev-v1beta2-appwrapper
     failurePolicy: Fail
     name: mappwrapper.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - workload.codeflare.dev
@@ -77,6 +81,10 @@ webhooks:
         path: /mutate-batch-v1-job
     failurePolicy: Fail
     name: mjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - batch
@@ -97,6 +105,10 @@ webhooks:
         path: /mutate-jobset-x-k8s-io-v1alpha2-jobset
     failurePolicy: Fail
     name: mjobset.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - jobset.x-k8s.io
@@ -117,6 +129,10 @@ webhooks:
         path: /mutate-kubeflow-org-v1-jaxjob
     failurePolicy: Fail
     name: mjaxjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -137,6 +153,10 @@ webhooks:
         path: /mutate-kubeflow-org-v1-paddlejob
     failurePolicy: Fail
     name: mpaddlejob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -157,6 +177,10 @@ webhooks:
         path: /mutate-kubeflow-org-v1-pytorchjob
     failurePolicy: Fail
     name: mpytorchjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -177,6 +201,10 @@ webhooks:
         path: /mutate-kubeflow-org-v1-tfjob
     failurePolicy: Fail
     name: mtfjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -197,6 +225,10 @@ webhooks:
         path: /mutate-kubeflow-org-v1-xgboostjob
     failurePolicy: Fail
     name: mxgboostjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -252,6 +284,10 @@ webhooks:
         path: /mutate-leaderworkerset-x-k8s-io-v1-leaderworkerset
     failurePolicy: Fail
     name: mleaderworkerset.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - leaderworkerset.x-k8s.io
@@ -273,6 +309,10 @@ webhooks:
         path: /mutate-kubeflow-org-v2beta1-mpijob
     failurePolicy: Fail
     name: mmpijob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -293,6 +333,10 @@ webhooks:
         path: /mutate-ray-io-v1-raycluster
     failurePolicy: Fail
     name: mraycluster.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - ray.io
@@ -313,6 +357,10 @@ webhooks:
         path: /mutate-ray-io-v1-rayjob
     failurePolicy: Fail
     name: mrayjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - ray.io
@@ -442,6 +490,10 @@ webhooks:
         path: /validate-workload-codeflare-dev-v1beta2-appwrapper
     failurePolicy: Fail
     name: vappwrapper.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - workload.codeflare.dev
@@ -497,6 +549,10 @@ webhooks:
         path: /validate-batch-v1-job
     failurePolicy: Fail
     name: vjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - batch
@@ -517,6 +573,10 @@ webhooks:
         path: /validate-jobset-x-k8s-io-v1alpha2-jobset
     failurePolicy: Fail
     name: vjobset.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - jobset.x-k8s.io
@@ -537,6 +597,10 @@ webhooks:
         path: /validate-kubeflow-org-v1-jaxjob
     failurePolicy: Fail
     name: vjaxjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -557,6 +621,10 @@ webhooks:
         path: /validate-kubeflow-org-v1-paddlejob
     failurePolicy: Fail
     name: vpaddlejob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -577,6 +645,10 @@ webhooks:
         path: /validate-kubeflow-org-v1-pytorchjob
     failurePolicy: Fail
     name: vpytorchjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -597,6 +669,10 @@ webhooks:
         path: /validate-kubeflow-org-v1-tfjob
     failurePolicy: Fail
     name: vtfjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -617,6 +693,10 @@ webhooks:
         path: /validate-kubeflow-org-v1-xgboostjob
     failurePolicy: Fail
     name: vxgboostjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -672,6 +752,10 @@ webhooks:
         path: /validate-leaderworkerset-x-k8s-io-v1-leaderworkerset
     failurePolicy: Fail
     name: vleaderworkerset.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - leaderworkerset.x-k8s.io
@@ -692,6 +776,10 @@ webhooks:
         path: /validate-kubeflow-org-v2beta1-mpijob
     failurePolicy: Fail
     name: vmpijob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - kubeflow.org
@@ -712,6 +800,10 @@ webhooks:
         path: /validate-ray-io-v1-raycluster
     failurePolicy: Fail
     name: vraycluster.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - ray.io
@@ -732,6 +824,10 @@ webhooks:
         path: /validate-ray-io-v1-rayjob
     failurePolicy: Fail
     name: vrayjob.kb.io
+    {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+    namespaceSelector:
+      {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+    {{- end }}
     rules:
       - apiGroups:
           - ray.io
diff --git a/hack/processing-plan.yaml b/hack/processing-plan.yaml
index 73731e57f..7260558ca 100644
--- a/hack/processing-plan.yaml
+++ b/hack/processing-plan.yaml
@@ -320,6 +320,222 @@ files:
             {{- end }}
         onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
         onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-apps-v1-statefulset"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-batch-v1-job"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-jobset-x-k8s-io-v1alpha2-jobset"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-kubeflow-org-v1-jaxjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-kubeflow-org-v1-paddlejob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-kubeflow-org-v1-pytorchjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-kubeflow-org-v1-tfjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-kubeflow-org-v1-xgboostjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-leaderworkerset-x-k8s-io-v1-leaderworkerset"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-kubeflow-org-v2beta1-mpijob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-ray-io-v1-raycluster"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-ray-io-v1-rayjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-workload-codeflare-dev-v1beta2-appwrapper"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-batch-v1-job"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-jobset-x-k8s-io-v1alpha2-jobset"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-kubeflow-org-v1-jaxjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-kubeflow-org-v1-paddlejob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-kubeflow-org-v1-pytorchjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-kubeflow-org-v1-tfjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-kubeflow-org-v1-xgboostjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-leaderworkerset-x-k8s-io-v1-leaderworkerset"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-kubeflow-org-v2beta1-mpijob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-ray-io-v1-raycluster"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "MutatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/mutate-ray-io-v1-rayjob"'
+      - type: INSERT_TEXT
+        key: .webhooks.[].name
+        value: |
+            {{- if (hasKey $managerConfig "managedJobsNamespaceSelector") -}}
+            namespaceSelector:
+              {{- toYaml $managerConfig.managedJobsNamespaceSelector | nindent 6 -}}
+            {{- end }}
+        onFileCondition: '.kind == "ValidatingWebhookConfiguration"'
+        onItemCondition: '.webhooks.[].clientConfig.service.path == "/validate-workload-codeflare-dev-v1beta2-appwrapper"'
   - path: ./config/components/kueueviz/*.yaml
     outputDir: ./charts/kueue/templates/kueueviz
     excludes:
diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go
index d37e1af1f..d15e6a461 100644
--- a/pkg/cache/cache.go
+++ b/pkg/cache/cache.go
@@ -42,7 +42,6 @@ import (
 	"sigs.k8s.io/kueue/pkg/metrics"
 	"sigs.k8s.io/kueue/pkg/queue"
 	"sigs.k8s.io/kueue/pkg/resources"
-	utiltas "sigs.k8s.io/kueue/pkg/util/tas"
 	"sigs.k8s.io/kueue/pkg/workload"
 )
 
@@ -114,7 +113,7 @@ type Cache struct {
 
 	hm hierarchy.Manager[*clusterQueue, *cohort]
 
-	tasCache TASCache
+	tasCache tasCache
 }
 
 func New(client client.Client, opts ...Option) *Cache {
@@ -247,7 +246,7 @@ func (c *Cache) ActiveClusterQueues() sets.Set[kueue.ClusterQueueReference] {
 	return cqs
 }
 
-func (c *Cache) TASCache() *TASCache {
+func (c *Cache) TASCache() *tasCache {
 	return &c.tasCache
 }
 
@@ -255,6 +254,9 @@ func (c *Cache) AddOrUpdateResourceFlavor(log logr.Logger, rf *kueue.ResourceFla
 	c.Lock()
 	defer c.Unlock()
 	c.resourceFlavors[kueue.ResourceFlavorReference(rf.Name)] = rf
+	if handleTASFlavor(rf) {
+		c.tasCache.AddFlavor(rf)
+	}
 	return c.updateClusterQueues(log)
 }
 
@@ -262,28 +264,32 @@ func (c *Cache) DeleteResourceFlavor(log logr.Logger, rf *kueue.ResourceFlavor)
 	c.Lock()
 	defer c.Unlock()
 	delete(c.resourceFlavors, kueue.ResourceFlavorReference(rf.Name))
+	if handleTASFlavor(rf) {
+		c.tasCache.DeleteFlavor(kueue.ResourceFlavorReference(rf.Name))
+	}
 	return c.updateClusterQueues(log)
 }
 
-func (c *Cache) AddTopologyForFlavor(log logr.Logger, topology *kueuealpha.Topology, flv *kueue.ResourceFlavor) sets.Set[kueue.ClusterQueueReference] {
+func (c *Cache) AddOrUpdateTopology(log logr.Logger, topology *kueuealpha.Topology) sets.Set[kueue.ClusterQueueReference] {
 	c.Lock()
 	defer c.Unlock()
-	levels := utiltas.Levels(topology)
-	tasFlavor := kueue.ResourceFlavorReference(flv.Name)
-	if c.tasCache.Get(tasFlavor) == nil {
-		tasInfo := c.tasCache.NewTASFlavorCache(kueue.TopologyReference(topology.Name), levels, flv.Spec.NodeLabels, flv.Spec.Tolerations)
-		c.tasCache.Set(tasFlavor, tasInfo)
-	}
+	c.tasCache.AddTopology(topology)
 	return c.updateClusterQueues(log)
 }
 
-func (c *Cache) DeleteTopologyForFlavor(log logr.Logger, flv kueue.ResourceFlavorReference) sets.Set[kueue.ClusterQueueReference] {
+func (c *Cache) DeleteTopology(log logr.Logger, name kueue.TopologyReference) sets.Set[kueue.ClusterQueueReference] {
 	c.Lock()
 	defer c.Unlock()
-	c.tasCache.Delete(flv)
+	c.tasCache.DeleteTopology(name)
 	return c.updateClusterQueues(log)
 }
 
+func (c *Cache) CloneTASCache() map[kueue.ResourceFlavorReference]*TASFlavorCache {
+	c.RLock()
+	defer c.RUnlock()
+	return c.tasCache.Clone()
+}
+
 func (c *Cache) AddOrUpdateAdmissionCheck(log logr.Logger, ac *kueue.AdmissionCheck) sets.Set[kueue.ClusterQueueReference] {
 	c.Lock()
 	defer c.Unlock()
@@ -832,11 +838,11 @@ func (c *Cache) LocalQueueUsage(qObj *kueue.LocalQueue) (*LocalQueueUsageStats,
 				if rf, ok := c.resourceFlavors[rgFlavor]; ok {
 					flavor.NodeLabels = rf.Spec.NodeLabels
 					flavor.NodeTaints = rf.Spec.NodeTaints
-					if features.Enabled(features.TopologyAwareScheduling) && rf.Spec.TopologyName != nil {
-						if topology, ok := c.tasCache.flavors[rgFlavor]; ok {
+					if handleTASFlavor(rf) {
+						if cache := c.tasCache.Get(rgFlavor); cache != nil {
 							flavor.Topology = &kueue.TopologyInfo{
-								Name:   topology.TopologyName,
-								Levels: topology.Levels,
+								Name:   cache.flavor.TopologyName,
+								Levels: cache.topology.Levels,
 							}
 						}
 					}
@@ -855,6 +861,10 @@ func (c *Cache) LocalQueueUsage(qObj *kueue.LocalQueue) (*LocalQueueUsageStats,
 	}, nil
 }
 
+func handleTASFlavor(rf *kueue.ResourceFlavor) bool {
+	return features.Enabled(features.TopologyAwareScheduling) && rf.Spec.TopologyName != nil
+}
+
 func filterLocalQueueUsage(orig resources.FlavorResourceQuantities, resourceGroups []ResourceGroup) []kueue.LocalQueueFlavorUsage {
 	qFlvUsages := make([]kueue.LocalQueueFlavorUsage, 0, len(orig))
 	for _, rg := range resourceGroups {
diff --git a/pkg/cache/clusterqueue.go b/pkg/cache/clusterqueue.go
index e403a1c33..b29d35599 100644
--- a/pkg/cache/clusterqueue.go
+++ b/pkg/cache/clusterqueue.go
@@ -86,7 +86,7 @@ type clusterQueue struct {
 	resourceNode resourceNode
 	hierarchy.ClusterQueue[*cohort]
 
-	tasCache *TASCache
+	tasCache *tasCache
 
 	workloadsNotAccountedForTAS sets.Set[string]
 }
diff --git a/pkg/cache/tas_cache.go b/pkg/cache/tas_cache.go
index 0502148dc..f1e73c47e 100644
--- a/pkg/cache/tas_cache.go
+++ b/pkg/cache/tas_cache.go
@@ -18,47 +18,94 @@ package cache
 
 import (
 	"maps"
+	"slices"
 	"sync"
 
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	kueuealpha "sigs.k8s.io/kueue/apis/kueue/v1alpha1"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
+	utiltas "sigs.k8s.io/kueue/pkg/util/tas"
 )
 
-type TASCache struct {
+type tasCache struct {
 	sync.RWMutex
-	client  client.Client
-	flavors map[kueue.ResourceFlavorReference]*TASFlavorCache
+	client      client.Client
+	flavors     map[kueue.ResourceFlavorReference]flavorInformation
+	topologies  map[kueue.TopologyReference]topologyInformation
+	flavorCache map[kueue.ResourceFlavorReference]*TASFlavorCache
 }
 
-func NewTASCache(client client.Client) TASCache {
-	return TASCache{
-		client:  client,
-		flavors: make(map[kueue.ResourceFlavorReference]*TASFlavorCache),
+func NewTASCache(client client.Client) tasCache {
+	return tasCache{
+		client:      client,
+		flavors:     make(map[kueue.ResourceFlavorReference]flavorInformation),
+		topologies:  make(map[kueue.TopologyReference]topologyInformation),
+		flavorCache: make(map[kueue.ResourceFlavorReference]*TASFlavorCache),
 	}
 }
 
-func (t *TASCache) Get(name kueue.ResourceFlavorReference) *TASFlavorCache {
+func (t *tasCache) Get(name kueue.ResourceFlavorReference) *TASFlavorCache {
 	t.RLock()
 	defer t.RUnlock()
-	return t.flavors[name]
+	return t.flavorCache[name]
 }
 
 // Clone returns a shallow copy of the map
-func (t *TASCache) Clone() map[kueue.ResourceFlavorReference]*TASFlavorCache {
+func (t *tasCache) Clone() map[kueue.ResourceFlavorReference]*TASFlavorCache {
 	t.RLock()
 	defer t.RUnlock()
-	return maps.Clone(t.flavors)
+	return maps.Clone(t.flavorCache)
 }
 
-func (t *TASCache) Set(name kueue.ResourceFlavorReference, info *TASFlavorCache) {
+func (t *tasCache) AddFlavor(flavor *kueue.ResourceFlavor) {
 	t.Lock()
 	defer t.Unlock()
-	t.flavors[name] = info
+	name := kueue.ResourceFlavorReference(flavor.Name)
+	if _, ok := t.flavors[name]; !ok {
+		flavorInfo := flavorInformation{
+			TopologyName: *flavor.Spec.TopologyName,
+			NodeLabels:   maps.Clone(flavor.Spec.NodeLabels),
+			Tolerations:  slices.Clone(flavor.Spec.Tolerations),
+		}
+		t.flavors[name] = flavorInfo
+		if tInfo, ok := t.topologies[flavorInfo.TopologyName]; ok {
+			t.flavorCache[name] = t.NewTASFlavorCache(tInfo, flavorInfo)
+		}
+	}
+}
+
+func (t *tasCache) AddTopology(topology *kueuealpha.Topology) {
+	t.Lock()
+	defer t.Unlock()
+	name := kueue.TopologyReference(topology.Name)
+	if _, ok := t.topologies[name]; !ok {
+		tInfo := topologyInformation{
+			Levels: utiltas.Levels(topology),
+		}
+		t.topologies[name] = tInfo
+		for fName, flavorInfo := range t.flavors {
+			if flavorInfo.TopologyName == name {
+				t.flavorCache[fName] = t.NewTASFlavorCache(tInfo, flavorInfo)
+			}
+		}
+	}
 }
 
-func (t *TASCache) Delete(name kueue.ResourceFlavorReference) {
+func (t *tasCache) DeleteFlavor(name kueue.ResourceFlavorReference) {
 	t.Lock()
 	defer t.Unlock()
 	delete(t.flavors, name)
+	delete(t.flavorCache, name)
+}
+
+func (t *tasCache) DeleteTopology(name kueue.TopologyReference) {
+	t.Lock()
+	defer t.Unlock()
+	delete(t.topologies, name)
+	for flavor, c := range t.flavorCache {
+		if c.flavor.TopologyName == name {
+			delete(t.flavorCache, flavor)
+		}
+	}
 }
diff --git a/pkg/cache/tas_flavor.go b/pkg/cache/tas_flavor.go
index f5c09d53a..22dd7b248 100644
--- a/pkg/cache/tas_flavor.go
+++ b/pkg/cache/tas_flavor.go
@@ -57,37 +57,48 @@ func (u usageOp) asSignedOne() int {
 	return -1
 }
 
-type TASFlavorCache struct {
-	sync.RWMutex
-
-	client client.Client
-
-	// TopologyName indicates the name of the topology specified in the
+type flavorInformation struct {
+	// Name indicates the name of the topology specified in the
 	// ResourceFlavor spec.topologyName field.
 	TopologyName kueue.TopologyReference
+
 	// nodeLabels is a map of nodeLabels defined in the ResourceFlavor object.
 	NodeLabels map[string]string
+	// tolerations represents the list of tolerations specified for the resource
+	// flavor
+	Tolerations []corev1.Toleration
+}
+
+type topologyInformation struct {
 	// levels is a list of levels defined in the Topology object referenced
 	// by the flavor corresponding to the cache.
 	Levels []string
+}
 
-	// tolerations represents the list of tolerations specified for the resource
-	// flavor
-	Tolerations []corev1.Toleration
+type TASFlavorCache struct {
+	sync.RWMutex
+
+	client client.Client
+
+	// topology represents the part of the Topology specification, e.g. the list
+	// of topology levels, relevant for TAS-scheduling.
+	topology topologyInformation
+
+	// flavor represents the part of the ResourceFlavor specification, e.g. the
+	// list of node labels and tolerations, relevant for TAS-scheduling.
+	flavor flavorInformation
 
 	// usage maintains the usage per topology domain
 	usage map[utiltas.TopologyDomainID]resources.Requests
 }
 
-func (t *TASCache) NewTASFlavorCache(topologyName kueue.TopologyReference, levels []string, nodeLabels map[string]string,
-	tolerations []corev1.Toleration) *TASFlavorCache {
+func (t *tasCache) NewTASFlavorCache(topologyInfo topologyInformation,
+	flavorInfo flavorInformation) *TASFlavorCache {
 	return &TASFlavorCache{
-		client:       t.client,
-		TopologyName: topologyName,
-		Levels:       slices.Clone(levels),
-		NodeLabels:   maps.Clone(nodeLabels),
-		Tolerations:  slices.Clone(tolerations),
-		usage:        make(map[utiltas.TopologyDomainID]resources.Requests),
+		client:   t.client,
+		topology: topologyInfo,
+		flavor:   flavorInfo,
+		usage:    make(map[utiltas.TopologyDomainID]resources.Requests),
 	}
 }
 
@@ -95,8 +106,8 @@ func (c *TASFlavorCache) snapshot(ctx context.Context) (*TASFlavorSnapshot, erro
 	log := ctrl.LoggerFrom(ctx)
 	nodes := &corev1.NodeList{}
 
-	var requiredLabels client.MatchingLabels = maps.Clone(c.NodeLabels)
-	var requiredLabelKeys client.HasLabels = slices.Clone(c.Levels)
+	var requiredLabels client.MatchingLabels = maps.Clone(c.flavor.NodeLabels)
+	var requiredLabelKeys client.HasLabels = slices.Clone(c.topology.Levels)
 
 	err := c.client.List(ctx, nodes, requiredLabels, requiredLabelKeys, client.MatchingFields{
 		indexer.ReadyNode:       "true",
@@ -120,13 +131,25 @@ func (c *TASFlavorCache) snapshot(ctx context.Context) (*TASFlavorSnapshot, erro
 	return c.snapshotForNodes(log, nodes.Items, pods.Items), nil
 }
 
+func (c *TASFlavorCache) NodeLabels() map[string]string {
+	return c.flavor.NodeLabels
+}
+
+func (c *TASFlavorCache) Topology() kueue.TopologyReference {
+	return c.flavor.TopologyName
+}
+
+func (c *TASFlavorCache) TopologyLevels() []string {
+	return c.topology.Levels
+}
+
 func (c *TASFlavorCache) snapshotForNodes(log logr.Logger, nodes []corev1.Node, pods []corev1.Pod) *TASFlavorSnapshot {
 	c.RLock()
 	defer c.RUnlock()
 
-	log.V(3).Info("Constructing TAS snapshot", "nodeLabels", c.NodeLabels,
-		"levels", c.Levels, "nodeCount", len(nodes), "podCount", len(pods))
-	snapshot := newTASFlavorSnapshot(log, c.TopologyName, c.Levels, c.Tolerations)
+	log.V(3).Info("Constructing TAS snapshot", "nodeLabels", c.flavor.NodeLabels,
+		"levels", c.topology.Levels, "nodeCount", len(nodes), "podCount", len(pods))
+	snapshot := newTASFlavorSnapshot(log, c.flavor.TopologyName, c.topology.Levels, c.flavor.Tolerations)
 	nodeToDomain := make(map[string]utiltas.TopologyDomainID)
 	for _, node := range nodes {
 		nodeToDomain[node.Name] = snapshot.addNode(node)
diff --git a/pkg/controller/tas/resource_flavor.go b/pkg/controller/tas/resource_flavor.go
index 909884518..0c6ce685f 100644
--- a/pkg/controller/tas/resource_flavor.go
+++ b/pkg/controller/tas/resource_flavor.go
@@ -19,6 +19,7 @@ package tas
 import (
 	"context"
 
+	"github.com/go-logr/logr"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/client-go/tools/record"
@@ -35,7 +36,6 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/source"
 
 	configapi "sigs.k8s.io/kueue/apis/config/v1beta1"
-	kueuealpha "sigs.k8s.io/kueue/apis/kueue/v1alpha1"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/cache"
 	"sigs.k8s.io/kueue/pkg/constants"
@@ -44,9 +44,9 @@ import (
 )
 
 type rfReconciler struct {
+	log      logr.Logger
 	queues   *queue.Manager
 	cache    *cache.Cache
-	tasCache *cache.TASCache
 	client   client.Client
 	recorder record.EventRecorder
 }
@@ -60,17 +60,17 @@ var _ predicate.TypedPredicate[*kueue.ResourceFlavor] = (*rfReconciler)(nil)
 
 func newRfReconciler(c client.Client, queues *queue.Manager, cache *cache.Cache, recorder record.EventRecorder) *rfReconciler {
 	return &rfReconciler{
+		log:      ctrl.Log.WithName(TASResourceFlavorController),
 		client:   c,
 		queues:   queues,
 		cache:    cache,
-		tasCache: cache.TASCache(),
 		recorder: recorder,
 	}
 }
 
 func (r *rfReconciler) setupWithManager(mgr ctrl.Manager, cache *cache.Cache, cfg *configapi.Configuration) (string, error) {
 	nodeHandler := nodeHandler{
-		tasCache: cache.TASCache(),
+		cache: cache,
 	}
 	return TASResourceFlavorController, builder.TypedControllerManagedBy[reconcile.Request](mgr).
 		Named("tas_resource_flavor_controller").
@@ -89,7 +89,7 @@ var _ handler.EventHandler = (*nodeHandler)(nil)
 
 // nodeHandler handles node update events.
 type nodeHandler struct {
-	tasCache *cache.TASCache
+	cache *cache.Cache
 }
 
 func (h *nodeHandler) Create(_ context.Context, e event.CreateEvent, q workqueue.TypedRateLimitingInterface[reconcile.Request]) {
@@ -123,8 +123,8 @@ func (h *nodeHandler) queueReconcileForNode(node *corev1.Node, q workqueue.Typed
 		return
 	}
 	// trigger reconcile for TAS flavors affected by the node being created or updated
-	for name, flavor := range h.tasCache.Clone() {
-		if nodeBelongsToFlavor(node, flavor.NodeLabels, flavor.Levels) {
+	for name, cache := range h.cache.CloneTASCache() {
+		if nodeBelongsToFlavor(node, cache.NodeLabels(), cache.TopologyLevels()) {
 			q.AddAfter(reconcile.Request{NamespacedName: types.NamespacedName{
 				Name: string(name),
 			}}, constants.UpdatesBatchPeriod)
@@ -144,20 +144,8 @@ func (r *rfReconciler) Reconcile(ctx context.Context, req reconcile.Request) (re
 		if client.IgnoreNotFound(err) != nil {
 			return reconcile.Result{}, err
 		}
-		r.tasCache.Delete(kueue.ResourceFlavorReference(req.Name))
 	}
 	if flv.Spec.TopologyName != nil {
-		flavorReference := kueue.ResourceFlavorReference(flv.Name)
-		if r.tasCache.Get(flavorReference) == nil {
-			topology := kueuealpha.Topology{}
-			if err := r.client.Get(ctx, types.NamespacedName{Name: string(*flv.Spec.TopologyName)}, &topology); err != nil {
-				return reconcile.Result{}, client.IgnoreNotFound(err)
-			}
-			log.V(3).Info("Adding topology to cache for flavor", "flavorName", flv.Name)
-			r.cache.AddTopologyForFlavor(log, &topology, flv)
-		} else {
-			log.V(3).Info("Skip topology update to cache as already present for flavor", "flavorName", flv.Name)
-		}
 		// requeue inadmissible workloads as a change to the resource flavor
 		// or the set of nodes can allow admitting a workload which was
 		// previously inadmissible.
@@ -169,16 +157,20 @@ func (r *rfReconciler) Reconcile(ctx context.Context, req reconcile.Request) (re
 }
 
 func (r *rfReconciler) Create(event event.TypedCreateEvent[*kueue.ResourceFlavor]) bool {
-	return event.Object.Spec.TopologyName != nil
-}
-
-func (r *rfReconciler) Delete(event event.TypedDeleteEvent[*kueue.ResourceFlavor]) bool {
 	if event.Object.Spec.TopologyName != nil {
-		r.tasCache.Delete(kueue.ResourceFlavorReference(event.Object.Name))
+		log := r.log.WithValues("flavor", event.Object.Name)
+		log.V(2).Info("Topology TAS ResourceFlavor event")
+
+		r.cache.AddOrUpdateResourceFlavor(log, event.Object)
+		return true
 	}
 	return false
 }
 
+func (r *rfReconciler) Delete(event event.TypedDeleteEvent[*kueue.ResourceFlavor]) bool {
+	return event.Object.Spec.TopologyName != nil
+}
+
 func (r *rfReconciler) Update(event event.TypedUpdateEvent[*kueue.ResourceFlavor]) bool {
 	switch {
 	case ptr.Equal(event.ObjectOld.Spec.TopologyName, event.ObjectNew.Spec.TopologyName):
@@ -187,7 +179,6 @@ func (r *rfReconciler) Update(event event.TypedUpdateEvent[*kueue.ResourceFlavor
 		return true
 	default:
 		// topologyName was set so is changed or removed
-		r.tasCache.Delete(kueue.ResourceFlavorReference(*event.ObjectOld.Spec.TopologyName))
 		return event.ObjectNew.Spec.TopologyName != nil
 	}
 }
diff --git a/pkg/controller/tas/topology_controller.go b/pkg/controller/tas/topology_controller.go
index ee2a90711..5ef80eb5a 100644
--- a/pkg/controller/tas/topology_controller.go
+++ b/pkg/controller/tas/topology_controller.go
@@ -41,7 +41,6 @@ import (
 	"sigs.k8s.io/kueue/pkg/cache"
 	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/controller/core"
-	"sigs.k8s.io/kueue/pkg/controller/tas/indexer"
 	"sigs.k8s.io/kueue/pkg/queue"
 )
 
@@ -54,7 +53,6 @@ type topologyReconciler struct {
 	client           client.Client
 	queues           *queue.Manager
 	cache            *cache.Cache
-	tasCache         *cache.TASCache
 	topologyUpdateCh chan event.GenericEvent
 }
 
@@ -67,7 +65,6 @@ func newTopologyReconciler(c client.Client, queues *queue.Manager, cache *cache.
 		client:           c,
 		queues:           queues,
 		cache:            cache,
-		tasCache:         cache.TASCache(),
 		topologyUpdateCh: make(chan event.GenericEvent, updateChBuffer),
 	}
 }
@@ -102,8 +99,8 @@ func (r *topologyReconciler) Reconcile(ctx context.Context, req reconcile.Reques
 	if !topology.DeletionTimestamp.IsZero() {
 		if controllerutil.ContainsFinalizer(topology, kueue.ResourceInUseFinalizerName) {
 			var flavors []kueue.ResourceFlavorReference
-			for flName, flCache := range r.tasCache.Clone() {
-				if flCache.TopologyName == kueue.TopologyReference(topology.Name) {
+			for flName, flCache := range r.cache.CloneTASCache() {
+				if flCache.Topology() == kueue.TopologyReference(topology.Name) {
 					flavors = append(flavors, flName)
 				}
 			}
@@ -135,28 +132,8 @@ func (r *topologyReconciler) Create(e event.TypedCreateEvent[*kueuealpha.Topolog
 	log := r.log.WithValues("topology", klog.KObj(e.Object))
 	log.V(2).Info("Topology create event")
 
-	ctx := context.Background()
-
-	flavors := &kueue.ResourceFlavorList{}
-	if err := r.client.List(ctx, flavors, client.MatchingFields{indexer.ResourceFlavorTopologyNameKey: e.Object.Name}); err != nil {
-		log.Error(err, "Could not list resource flavors")
-		return true
-	}
-
 	defer r.queues.NotifyTopologyUpdateWatchers(nil, e.Object)
-
-	// Update the cache to account for the created topology, before
-	// notifying the listeners.
-	for _, flv := range flavors.Items {
-		if flv.Spec.TopologyName == nil {
-			continue
-		}
-		if *flv.Spec.TopologyName == kueue.TopologyReference(e.Object.Name) {
-			log.V(3).Info("Updating Topology cache for flavor", "flavor", flv.Name)
-			r.cache.AddTopologyForFlavor(log, e.Object, &flv)
-		}
-	}
-
+	r.cache.AddOrUpdateTopology(log, e.Object)
 	return true
 }
 
@@ -169,14 +146,7 @@ func (r *topologyReconciler) Delete(e event.TypedDeleteEvent[*kueuealpha.Topolog
 	log.V(2).Info("Topology delete event")
 
 	defer r.queues.NotifyTopologyUpdateWatchers(e.Object, nil)
-	// Update the cache to account for the deleted topology, before notifying
-	// the listeners.
-	for flName, flCache := range r.tasCache.Clone() {
-		if kueue.TopologyReference(e.Object.Name) == flCache.TopologyName {
-			log.V(3).Info("Deleting topology from cache for flavor", "flavorName", flName)
-			r.cache.DeleteTopologyForFlavor(log, flName)
-		}
-	}
+	r.cache.DeleteTopology(log, kueue.TopologyReference(e.Object.Name))
 	return true
 }
 



Test patch:
diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go
index 3cc7414b3..c1596756a 100644
--- a/pkg/cache/cache_test.go
+++ b/pkg/cache/cache_test.go
@@ -3886,8 +3886,18 @@ func TestSnapshotError(t *testing.T) {
 	cache := New(client)
 	cache.AddOrUpdateResourceFlavor(log, &flavor)
 	if flavor.Spec.TopologyName != nil {
-		tasFlavorCache := cache.tasCache.NewTASFlavorCache(*flavor.Spec.TopologyName, []string{corev1.LabelHostname}, flavor.Spec.NodeLabels, flavor.Spec.Tolerations)
-		cache.tasCache.Set(kueue.ResourceFlavorReference(flavor.Name), tasFlavorCache)
+		cache.AddOrUpdateTopology(log, &kueuealpha.Topology{
+			ObjectMeta: metav1.ObjectMeta{
+				Name: string(*flavor.Spec.TopologyName),
+			},
+			Spec: kueuealpha.TopologySpec{
+				Levels: []kueuealpha.TopologyLevel{
+					{
+						NodeLabel: corev1.LabelHostname,
+					},
+				},
+			},
+		})
 	}
 	if err := cache.AddClusterQueue(ctx, &clusterQueue); err != nil {
 		t.Fatalf("failed to add CQ: %v", err)
diff --git a/pkg/cache/clusterqueue_test.go b/pkg/cache/clusterqueue_test.go
index 72bedc42e..f9bc339ce 100644
--- a/pkg/cache/clusterqueue_test.go
+++ b/pkg/cache/clusterqueue_test.go
@@ -595,7 +595,7 @@ func TestClusterQueueReadinessWithTAS(t *testing.T) {
 			cqCache.AddOrUpdateResourceFlavor(log, rf)
 
 			if !tc.skipTopology {
-				cqCache.AddTopologyForFlavor(log, topology, rf)
+				cqCache.AddOrUpdateTopology(log, topology)
 			}
 
 			mkAC := utiltesting.MakeAdmissionCheck("mk-check").ControllerName(kueue.MultiKueueControllerName).Active(metav1.ConditionTrue).Obj()
diff --git a/pkg/cache/tas_cache_test.go b/pkg/cache/tas_cache_test.go
index 8078f7545..3f823e27d 100644
--- a/pkg/cache/tas_cache_test.go
+++ b/pkg/cache/tas_cache_test.go
@@ -2078,7 +2078,15 @@ func TestFindTopologyAssignment(t *testing.T) {
 			client := clientBuilder.Build()
 
 			tasCache := NewTASCache(client)
-			tasFlavorCache := tasCache.NewTASFlavorCache("default", tc.levels, tc.nodeLabels, tc.tolerations)
+			topologyInformation := topologyInformation{
+				Levels: tc.levels,
+			}
+			flavorInformation := flavorInformation{
+				TopologyName: "default",
+				NodeLabels:   tc.nodeLabels,
+				Tolerations:  tc.tolerations,
+			}
+			tasFlavorCache := tasCache.NewTASFlavorCache(topologyInformation, flavorInformation)
 
 			snapshot, err := tasFlavorCache.snapshot(ctx)
 			if err != nil {
@@ -2225,7 +2233,13 @@ func buildSnapshot(ctx context.Context, t *testing.T, nodes []corev1.Node, level
 	client := clientBuilder.Build()
 
 	tasCache := NewTASCache(client)
-	tasFlavorCache := tasCache.NewTASFlavorCache("default", levels, map[string]string{}, []corev1.Toleration{})
+	topologyInformation := topologyInformation{
+		Levels: levels,
+	}
+	flavorInformation := flavorInformation{
+		TopologyName: "default",
+	}
+	tasFlavorCache := tasCache.NewTASFlavorCache(topologyInformation, flavorInformation)
 
 	snapshot, err := tasFlavorCache.snapshot(ctx)
 	if err != nil {
diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go
index 41154d974..a38bbb658 100644
--- a/pkg/scheduler/scheduler_test.go
+++ b/pkg/scheduler/scheduler_test.go
@@ -6812,10 +6812,7 @@ func TestScheduleForTAS(t *testing.T) {
 				cqCache.AddOrUpdateResourceFlavor(log, &flavor)
 				if flavor.Spec.TopologyName != nil {
 					t := topologyByName[*flavor.Spec.TopologyName]
-					tasCache := cqCache.TASCache()
-					levels := utiltas.Levels(&t)
-					tasFlavorCache := tasCache.NewTASFlavorCache(*flavor.Spec.TopologyName, levels, flavor.Spec.NodeLabels, flavor.Spec.Tolerations)
-					tasCache.Set(kueue.ResourceFlavorReference(flavor.Name), tasFlavorCache)
+					cqCache.AddOrUpdateTopology(log, &t)
 				}
 			}
 			for _, cq := range tc.clusterQueues {
@@ -7378,10 +7375,7 @@ func TestScheduleForTASPreemption(t *testing.T) {
 				cqCache.AddOrUpdateResourceFlavor(log, &flavor)
 				if flavor.Spec.TopologyName != nil {
 					t := topologyByName[*flavor.Spec.TopologyName]
-					tasCache := cqCache.TASCache()
-					levels := utiltas.Levels(&t)
-					tasFlavorCache := tasCache.NewTASFlavorCache(*flavor.Spec.TopologyName, levels, flavor.Spec.NodeLabels, flavor.Spec.Tolerations)
-					tasCache.Set(kueue.ResourceFlavorReference(flavor.Name), tasFlavorCache)
+					cqCache.AddOrUpdateTopology(log, &t)
 				}
 			}
 			for _, cq := range tc.clusterQueues {
@@ -8647,10 +8641,7 @@ func TestScheduleForTASCohorts(t *testing.T) {
 				cqCache.AddOrUpdateResourceFlavor(log, &flavor)
 				if flavor.Spec.TopologyName != nil {
 					t := topologyByName[*flavor.Spec.TopologyName]
-					tasCache := cqCache.TASCache()
-					levels := utiltas.Levels(&t)
-					tasFlavorCache := tasCache.NewTASFlavorCache(*flavor.Spec.TopologyName, levels, flavor.Spec.NodeLabels, flavor.Spec.Tolerations)
-					tasCache.Set(kueue.ResourceFlavorReference(flavor.Name), tasFlavorCache)
+					cqCache.AddOrUpdateTopology(log, &t)
 				}
 			}
 			for _, cq := range tc.clusterQueues {