diff --git a/orchestrator/packages/api/src/controllers/validations-controller.ts b/orchestrator/packages/api/src/controllers/validations-controller.ts index 688f7c0..93411ef 100644 --- a/orchestrator/packages/api/src/controllers/validations-controller.ts +++ b/orchestrator/packages/api/src/controllers/validations-controller.ts @@ -11,3 +11,13 @@ export const gradingJobValidation = async (req: Request, res: Response) => { res.json({ "message": "Provided request body is a valid grading job configuration." }) : res.json({ "errors": formatValidationErrors(validator.errors) }); } + +export const gradingScriptValidation = async (req: Request, res: Response) => { + if (!req.body || req.body.length === 0) { + return errorResponse(res, 400, ['No request body provided for grading script schema validation.']); + } + const validator = validations.gradingScript; + return validator(req.body) ? + res.json({ "message": "Provided request body is a valid grading script configuration." }) : + res.json({ "errors": formatValidationErrors(validator.errors) }); +} diff --git a/orchestrator/packages/api/src/routes/validations.ts b/orchestrator/packages/api/src/routes/validations.ts index 099802d..5412560 100644 --- a/orchestrator/packages/api/src/routes/validations.ts +++ b/orchestrator/packages/api/src/routes/validations.ts @@ -1,9 +1,10 @@ import { Router } from "express"; import verifyAPIKey from "../middleware/verify-api-key"; -import { gradingJobValidation } from "../controllers/validations-controller"; +import { gradingJobValidation, gradingScriptValidation } from "../controllers/validations-controller"; const validationsRouter = Router(); validationsRouter.post('/validate_grading_job', verifyAPIKey, gradingJobValidation); +validationsRouter.post('/validate_grading_script', verifyAPIKey, gradingScriptValidation); export default validationsRouter; diff --git a/orchestrator/packages/common/src/types/grading-queue.ts b/orchestrator/packages/common/src/types/grading-queue.ts index 100e993..64b5b74 100644 --- a/orchestrator/packages/common/src/types/grading-queue.ts +++ b/orchestrator/packages/common/src/types/grading-queue.ts @@ -36,6 +36,8 @@ export interface FileInfo { export type CollationType = "team" | "user"; +export type GradingScript = GradingScriptCommand[]; + export interface Collation { type: CollationType; id: string; @@ -47,7 +49,7 @@ export interface GradingJobConfig { metadata_table: Record; files: Record; priority: number; - script: GradingScriptCommand[]; + script: GradingScript; response_url: string; container_response_url?: string; grader_image_sha: string; diff --git a/orchestrator/packages/common/src/validations/index.ts b/orchestrator/packages/common/src/validations/index.ts index 87af718..07c061a 100644 --- a/orchestrator/packages/common/src/validations/index.ts +++ b/orchestrator/packages/common/src/validations/index.ts @@ -3,17 +3,19 @@ import { collationSchema } from "./schemas/shared"; import { gradingJobConfigSchema, gradingJobConfigSubSchemas, + gradingScriptSchema } from "./schemas/grading-job-config"; import { moveJobRequestSchema } from "./schemas/move-job-request"; import { GradingJobConfig, + GradingScript, MoveJobRequest, } from "../types/grading-queue"; import { GraderImageBuildRequest } from "../types/image-build-service"; import { graderImageBuildRequestSchema } from "./schemas/grader-image-build-request"; let ajv = new Ajv().addSchema(collationSchema); -ajv = gradingJobConfigSubSchemas.reduce( +ajv = [gradingJobConfigSubSchemas].reduce( (prev, curr) => prev.addSchema(curr), ajv, ); @@ -22,8 +24,9 @@ export type ValidationErrors = typeof ajv.errors; export default { gradingJobConfig: ajv.compile(gradingJobConfigSchema), + gradingScript: ajv.compile(gradingScriptSchema), moveJobRequest: ajv.compile(moveJobRequestSchema), graderImageBuildRequest: ajv.compile( graderImageBuildRequestSchema, - ), + ) }; diff --git a/orchestrator/packages/common/src/validations/schemas/grading-job-config.ts b/orchestrator/packages/common/src/validations/schemas/grading-job-config.ts index 59e3d9a..6e3569e 100644 --- a/orchestrator/packages/common/src/validations/schemas/grading-job-config.ts +++ b/orchestrator/packages/common/src/validations/schemas/grading-job-config.ts @@ -14,7 +14,7 @@ const fileInfo = { additionalProperties: false, } as const; -const bashGradingScriptCommand = { +const bashGradingScriptCommandSchema = { $id: "https://orca-schemas.com/grading-job-config/bash-grading-script-command", type: "object", properties: { @@ -53,7 +53,7 @@ const bashGradingScriptCommand = { additionalProperties: false, } as const; -const gradingScriptCondition = { +const gradingScriptConditionSchema = { $id: "https://orca-schemas.com/grading-job-config/grading-script-condition", type: "object", properties: { @@ -67,7 +67,7 @@ const gradingScriptCondition = { additionalProperties: false, } as const; -const conditionalGradingScriptCommand = { +const conditionalGradingScriptCommandSchema = { $id: "https://orca-schemas.com/grading-job-config/conditional-grading-script-command", type: "object", properties: { @@ -102,7 +102,7 @@ const conditionalGradingScriptCommand = { additionalProperties: false, } as const; -const gradingScriptCommand = { +export const gradingScriptCommandSchema = { $id: "https://orca-schemas.com/grading-job-config/grading-script-command", oneOf: [ { @@ -114,12 +114,25 @@ const gradingScriptCommand = { ], } as const; +export const gradingScriptSubSchemas = [ + bashGradingScriptCommandSchema, + gradingScriptConditionSchema, + conditionalGradingScriptCommandSchema, + gradingScriptCommandSchema +]; + +export const gradingScriptSchema = { + $id: "https://orca-schemas.com/grading-job-config/grading-script", + type: "array", + items: { + $ref: "https://orca-schemas.com/grading-job-config/grading-script-command", + }, +} as const; + export const gradingJobConfigSubSchemas = [ fileInfo, - gradingScriptCommand, - bashGradingScriptCommand, - gradingScriptCondition, - conditionalGradingScriptCommand, + ...gradingScriptSubSchemas, + gradingScriptSchema ]; export const gradingJobConfigSchema = { @@ -140,12 +153,7 @@ export const gradingJobConfigSchema = { }, }, priority: { type: "number" }, - script: { - type: "array", - items: { - $ref: "https://orca-schemas.com/grading-job-config/grading-script-command", - }, - }, + script: { $ref: "https://orca-schemas.com/grading-job-config/grading-script" }, response_url: { type: "string" }, container_response_url: { type: "string" }, grader_image_sha: { type: "string" },