fix(apiserver): apikeys whitelist + job_status type + mcp_operator queue:control

Three fixes found during scheduler-agent Phase 1 cluster verification:

- whitelist.go: add /xce/v1/apikeys to WhitelistPOSTURL (Phase 0 added the
  route but never whitelisted it → 403 "URL is not allowed"). bug-1489.
- jobs.go: fix job_status int64 assertion in job control. store.Jobs returns
  status as int/float64; the `.(int64)` assertion broke control with
  "job_status is not an int64". Add normalizeJobStatus() accepting int/int32/
  int64/float64/json.Number.
- rbac.yaml: mcp_operator role gains queue:control (the job-control handler
  also checks queue:control on the job's queue); add rbac_mcp_operator_test.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
lei.chen 2026-08-01 09:54:44 +00:00
parent 35416d5cf4
commit e36ed63ca0
4 changed files with 116 additions and 4 deletions

View file

@ -3011,10 +3011,14 @@ func validateJobControl(jobinfo utils.OrderMap, action string,
}
if rawStatus, exists := jobinfo.Data["job_status"]; exists {
if jobStatus, ok := rawStatus.(int64); ok {
db_job_status := int(jobStatus)
// job_status arrives as int (from store.Jobs), int64, or float64
// (from JSON decode paths). Normalize before use; the old `.(int64)`
// assertion broke control for every job whose status decoded as int
// or float64 ("job_status is not an int64").
if jobStatusInt, ok := normalizeJobStatus(rawStatus); ok {
db_job_status := jobStatusInt
job_status := models.JobStateStr(db_job_status)
jobStatus = int64(models.JOBSTAT[job_status])
jobStatus := int64(models.JOBSTAT[job_status])
if utils.IsControlActionAllowed(actionType, jobStatus, models.JobActionControlMap) {
if action == "kill" && signal != "" {
if !utils.IsControlActionAllowed(actionType, jobStatus, models.JobKillSignalControlMap) {
@ -3095,6 +3099,26 @@ func foundJob(jobid int64, array_idx int, jobinfos []utils.OrderMap) ([]utils.Or
}
}
// normalizeJobStatus converts a job_status value (int, int64, or float64 from
// JSON decode) into a plain int. Returns ok=false for unsupported types.
func normalizeJobStatus(v any) (int, bool) {
switch s := v.(type) {
case int:
return s, true
case int32:
return int(s), true
case int64:
return int(s), true
case float64:
return int(s), true
case json.Number:
if n, err := s.Int64(); err == nil {
return int(n), true
}
}
return 0, false
}
func processJobData(rows []utils.OrderMap, pagetoken string) utils.QueryResult {
logger.Debug("Enter processJobData() function", zap.Any("rows", rows))
for _, row := range rows {