peter-toth commented on code in PR #827:
URL: 
https://github.com/apache/spark-kubernetes-operator/pull/827#discussion_r4013705790


##########
build-tools/helm/spark-kubernetes-operator/templates/tests/test-rbac.yaml:
##########
@@ -77,6 +77,19 @@ spec:
             kubectl auth can-i watch  grpcroutes.gateway.networking.k8s.io 
--all-namespaces
             kubectl auth can-i create grpcroutes.gateway.networking.k8s.io 
--all-namespaces
           fi
+          {{- if .Values.operatorRbac.kueue.enabled }}
+
+          # The Kueue grant is opt-in and, like Gateway API, can only be 
asserted
+          # where the Kueue CRDs are installed.
+          if kubectl api-resources --api-group=kueue.x-k8s.io --no-headers -o 
name | grep -q workloads; then

Review Comment:
   **Finding 1.** These assertions cannot run in any CI job as things stand, so 
the new rules ship with no automated coverage.
   
   Two gates have to open and neither does:
   
   - The Helm `{{- if .Values.operatorRbac.kueue.enabled }}` at `:80`. No 
workflow or values file sets it, `grep -rni kueue .github/ tests/` returns 
nothing.
   - The `kubectl api-resources --api-group=kueue.x-k8s.io` check on this line. 
No CI cluster installs the Kueue CRDs.
   
   The repo already has the mechanism. 
`.github/workflows/build_and_test.yml:270-279` runs a `helm-tests` matrix that 
installs the chart with `tests/e2e/helm/helm-test-values/<group>/values.yaml` 
and then `helm test spark`. A new group opens the first gate:
   
   ```yaml
   # tests/e2e/helm/helm-test-values/kueue/values.yaml
   operatorRbac:
     kueue:
       enabled: true
   ```
   
   plus `- kueue` in the `test-group` list at `:239-242`. That alone proves the 
chart renders and installs with the flag on. To open the second gate, the job 
needs the Kueue CRDs, which is one guarded step before `helm install`:
   
   ```yaml
         - name: Install Kueue CRDs
           if: matrix.test-group == 'kueue'
           run: |
             kubectl apply --server-side -f 
https://github.com/kubernetes-sigs/kueue/releases/download/v0.19.4/manifests.yaml
   ```
   
   One more assertion worth adding in that job: with the default `enabled: 
false` the operator should be *denied* `create` on `workloads.kueue.x-k8s.io`. 
Nothing currently proves the opt-in gate actually gates. That check is only 
meaningful on a cluster that serves the CRDs, so it belongs here rather than in 
the default `helm test`.
   



##########
build-tools/helm/spark-kubernetes-operator/templates/operator-rbac.yaml:
##########
@@ -122,6 +122,43 @@ rules:
       - patch
       - delete
 {{- end }}
+{{- if .Values.operatorRbac.kueue.enabled }}
+  - apiGroups:
+      - "kueue.x-k8s.io"
+    resources:
+      - workloads
+    verbs:
+      - get
+      - list
+      - watch
+      - create
+      - update
+      - patch
+      - delete
+  - apiGroups:
+      - "kueue.x-k8s.io"
+    resources:
+      - workloads/status
+    verbs:
+      - get
+      - update
+      - patch
+  - apiGroups:
+      - "kueue.x-k8s.io"
+    resources:
+      - workloads/finalizers
+    verbs:
+      - update
+  - apiGroups:
+      - "kueue.x-k8s.io"
+    resources:
+      - resourceflavors
+      - workloadpriorityclasses
+    verbs:
+      - get
+      - list
+      - watch
+{{- end }}

Review Comment:
   **Finding 2.** The description says this grants "the RBAC rules that Kueue 
requires from an external framework integration" and links the custom-job doc. 
That doc lists seven `+kubebuilder:rbac` markers under "Extend your existing 
RBAC Authorizations". This block ships five.
   
   Missing:
   
   - `scheduling.k8s.io/priorityclasses` with `get;list;watch`. This is the one 
that matters. `WorkloadSpec` already carries `priority` and `priorityClassRef` 
(`spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/v1beta2/WorkloadSpec.java:47-48`).
 As soon as the runtime resolves a pod's `priorityClassName` into a Workload 
priority it will 403 here.
   - `events.k8s.io/events` with `create;watch;update;patch`. RBAC matches API 
groups literally, so the `apiGroups: [""]` rule at `:21-36` does not cover this 
group. The operator emits no Events today, so leaving it out is defensible. 
Then it is worth saying so, rather than letting the table read as the complete 
set.
   
   The suggestion below adds the first one. I rendered it with `--set 
operatorRbac.kueue.enabled=true` and ran `helm lint --strict`, both pass.
   
   ```suggestion
     - apiGroups:
         - "scheduling.k8s.io"
       resources:
         - priorityclasses
       verbs:
         - get
         - list
         - watch
   {{- end }}
   ```
   



##########
build-tools/helm/spark-kubernetes-operator/templates/operator-rbac.yaml:
##########
@@ -122,6 +122,43 @@ rules:
       - patch
       - delete
 {{- end }}
+{{- if .Values.operatorRbac.kueue.enabled }}
+  - apiGroups:
+      - "kueue.x-k8s.io"
+    resources:
+      - workloads
+    verbs:
+      - get
+      - list
+      - watch
+      - create
+      - update
+      - patch
+      - delete
+  - apiGroups:
+      - "kueue.x-k8s.io"
+    resources:
+      - workloads/status
+    verbs:
+      - get
+      - update
+      - patch
+  - apiGroups:
+      - "kueue.x-k8s.io"
+    resources:
+      - workloads/finalizers
+    verbs:
+      - update
+  - apiGroups:
+      - "kueue.x-k8s.io"
+    resources:
+      - resourceflavors

Review Comment:
   **Finding 3.** Both of these are cluster-scoped. Kueue marks them 
`+kubebuilder:resource:scope=Cluster` in 
`apis/kueue/v1beta2/resourceflavor_types.go:28` and 
`workloadpriorityclass_types.go:27`. This define also backs the 
per-workload-namespace `Role` at `:263`, and a rule for a cluster-scoped 
resource in a namespaced `Role` is silently inert.
   
   Rendering with `--set operatorRbac.kueue.enabled=true --set 
operatorRbac.role.create=true --set 
workloadResources.namespaces.data={spark-1}` puts both into the `spark-1` 
`Role`, where they grant nothing. Every other rule in this block is for a 
namespaced resource, so this is the first one that splits.
   
   The `values.yaml` comment already says `clusterRole.create` is required for 
these two. The template can say it instead. Moving the pair into a 
ClusterRole-only wrapper works:
   
   ```gotemplate
   {{/*
   Rules used only by the operator ClusterRole, for cluster-scoped resources
   */}}
   {{- define "spark-operator.operatorClusterRbacRules" }}
   {{- include "spark-operator.operatorRbacRules" . }}
   {{- if .Values.operatorRbac.kueue.enabled }}
     - apiGroups:
         - "kueue.x-k8s.io"
       resources:
         - resourceflavors
         - workloadpriorityclasses
       verbs:
         - get
         - list
         - watch
   {{- end }}
   {{- end }}
   ```
   
   with `:210` calling the wrapper and `:263` keeping the plain define. The 
`workloads`, `workloads/status` and `workloads/finalizers` rules stay shared, 
since `Workload` is namespaced. I applied this and re-rendered: the operator 
ClusterRole keeps both resources, the `spark-1` `Role` keeps `workloads` and 
drops them, and `helm lint --strict` passes.
   



##########
build-tools/helm/spark-kubernetes-operator/values.schema.json:
##########
@@ -563,6 +563,19 @@
             }
           }
         },
+        "kueue": {

Review Comment:
   **Finding 4.** `kueue` should also join the `operatorRbac.required` list at 
`:427`. Both `operator-rbac.yaml:125` and `tests/test-rbac.yaml:80` dereference 
`.Values.operatorRbac.kueue.enabled` unconditionally, and every other sub-block 
they dereference is already required.
   
   The difference shows up when the block goes missing:
   
   ```
   $ helm template t . --set 'operatorRbac.clusterRole=null'
   Error: values don't meet the specifications of the schema(s) in the 
following chart(s):
   spark-kubernetes-operator:
   - at '/operatorRbac': missing property 'clusterRole'
   
   $ helm template t . --set 'operatorRbac.kueue=null'
   Error: template: 
spark-kubernetes-operator/templates/tests/test-rbac.yaml:80:24:
   executing "..." at <.Values.operatorRbac.kueue.enabled>: nil pointer 
evaluating interface {}.enabled
   ```
   



##########
docs/operations.md:
##########
@@ -108,6 +108,7 @@ following table:
 | operatorRbac.configManagement.create                             | Enable 
this to create a Role for operator configuration management (hot property 
loading and leader election).                                                   
              | true                                                            
                                        |
 | operatorRbac.configManagement.roleName                           | Role name 
for operator configuration management.                                          
                                                                                
     | `spark-operator-config-role`                                             
                               |
 | operatorRbac.configManagement.roleBinding                        | 
RoleBinding name for operator configuration management.                         
                                                                                
               | `"spark-operator-config-monitor-role-binding"`                 
                                         |
+| operatorRbac.kueue.enabled                                       | Grant the 
operator access to Kueue `workloads`, `resourceflavors` and 
`workloadpriorityclasses`. Needs `clusterRole.create`. Also register 
`SparkApplication` in Kueue.        | false                                     
                                                              |

Review Comment:
   **Finding 5.** Two things in this cell.
   
   `KueueWorkloadFactory.buildWorkload` has a `SparkCluster` overload 
(`spark-operator/src/main/java/org/apache/spark/k8s/operator/kueue/KueueWorkloadFactory.java:124`),
 so the registration note should name both kinds. Kueue takes them in 
`integrations.externalFrameworks` as `Kind.version.group`, which is worth 
spelling out because it is not guessable from the cell.
   
   "Needs `clusterRole.create`" is true only for `resourceflavors` and 
`workloadpriorityclasses`. `Workload` is namespaced, so the `workloads` half 
works through the per-namespace `Role` too.
   
   ```suggestion
   | operatorRbac.kueue.enabled                                       | Grant 
the operator access to Kueue `workloads`, `resourceflavors` and 
`workloadpriorityclasses`. The two cluster-scoped ones need 
`clusterRole.create`. Also register `SparkApplication.v1.spark.apache.org` and 
`SparkCluster.v1.spark.apache.org` in Kueue's 
`integrations.externalFrameworks`. | false                                      
                                                             |
   ```
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to