diff options
Diffstat (limited to 'server/middlewares/validators/runners/jobs.ts')
-rw-r--r-- | server/middlewares/validators/runners/jobs.ts | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/server/middlewares/validators/runners/jobs.ts b/server/middlewares/validators/runners/jobs.ts new file mode 100644 index 000000000..8cb87e946 --- /dev/null +++ b/server/middlewares/validators/runners/jobs.ts | |||
@@ -0,0 +1,156 @@ | |||
1 | import express from 'express' | ||
2 | import { body, param } from 'express-validator' | ||
3 | import { isUUIDValid } from '@server/helpers/custom-validators/misc' | ||
4 | import { | ||
5 | isRunnerJobAbortReasonValid, | ||
6 | isRunnerJobErrorMessageValid, | ||
7 | isRunnerJobProgressValid, | ||
8 | isRunnerJobSuccessPayloadValid, | ||
9 | isRunnerJobTokenValid, | ||
10 | isRunnerJobUpdatePayloadValid | ||
11 | } from '@server/helpers/custom-validators/runners/jobs' | ||
12 | import { isRunnerTokenValid } from '@server/helpers/custom-validators/runners/runners' | ||
13 | import { cleanUpReqFiles } from '@server/helpers/express-utils' | ||
14 | import { RunnerJobModel } from '@server/models/runner/runner-job' | ||
15 | import { HttpStatusCode, RunnerJobState, RunnerJobSuccessBody, RunnerJobUpdateBody, ServerErrorCode } from '@shared/models' | ||
16 | import { areValidationErrors } from '../shared' | ||
17 | |||
18 | const tags = [ 'runner' ] | ||
19 | |||
20 | export const acceptRunnerJobValidator = [ | ||
21 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
22 | if (res.locals.runnerJob.state !== RunnerJobState.PENDING) { | ||
23 | return res.fail({ | ||
24 | status: HttpStatusCode.BAD_REQUEST_400, | ||
25 | message: 'This runner job is not in pending state', | ||
26 | tags | ||
27 | }) | ||
28 | } | ||
29 | |||
30 | return next() | ||
31 | } | ||
32 | ] | ||
33 | |||
34 | export const abortRunnerJobValidator = [ | ||
35 | body('reason').custom(isRunnerJobAbortReasonValid), | ||
36 | |||
37 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
38 | if (areValidationErrors(req, res, { tags })) return | ||
39 | |||
40 | return next() | ||
41 | } | ||
42 | ] | ||
43 | |||
44 | export const updateRunnerJobValidator = [ | ||
45 | body('progress').optional().custom(isRunnerJobProgressValid), | ||
46 | |||
47 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
48 | if (areValidationErrors(req, res, { tags })) return cleanUpReqFiles(req) | ||
49 | |||
50 | const body = req.body as RunnerJobUpdateBody | ||
51 | |||
52 | if (isRunnerJobUpdatePayloadValid(body.payload, res.locals.runnerJob.type, req.files) !== true) { | ||
53 | cleanUpReqFiles(req) | ||
54 | |||
55 | return res.fail({ | ||
56 | status: HttpStatusCode.BAD_REQUEST_400, | ||
57 | message: 'Payload is invalid', | ||
58 | tags | ||
59 | }) | ||
60 | } | ||
61 | |||
62 | return next() | ||
63 | } | ||
64 | ] | ||
65 | |||
66 | export const errorRunnerJobValidator = [ | ||
67 | body('message').custom(isRunnerJobErrorMessageValid), | ||
68 | |||
69 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
70 | if (areValidationErrors(req, res, { tags })) return | ||
71 | |||
72 | return next() | ||
73 | } | ||
74 | ] | ||
75 | |||
76 | export const successRunnerJobValidator = [ | ||
77 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
78 | const body = req.body as RunnerJobSuccessBody | ||
79 | |||
80 | if (isRunnerJobSuccessPayloadValid(body.payload, res.locals.runnerJob.type, req.files) !== true) { | ||
81 | cleanUpReqFiles(req) | ||
82 | |||
83 | return res.fail({ | ||
84 | status: HttpStatusCode.BAD_REQUEST_400, | ||
85 | message: 'Payload is invalid', | ||
86 | tags | ||
87 | }) | ||
88 | } | ||
89 | |||
90 | return next() | ||
91 | } | ||
92 | ] | ||
93 | |||
94 | export const runnerJobGetValidator = [ | ||
95 | param('jobUUID').custom(isUUIDValid), | ||
96 | |||
97 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
98 | if (areValidationErrors(req, res, { tags })) return | ||
99 | |||
100 | const runnerJob = await RunnerJobModel.loadWithRunner(req.params.jobUUID) | ||
101 | |||
102 | if (!runnerJob) { | ||
103 | return res.fail({ | ||
104 | status: HttpStatusCode.NOT_FOUND_404, | ||
105 | message: 'Unknown runner job', | ||
106 | tags | ||
107 | }) | ||
108 | } | ||
109 | |||
110 | res.locals.runnerJob = runnerJob | ||
111 | |||
112 | return next() | ||
113 | } | ||
114 | ] | ||
115 | |||
116 | export const jobOfRunnerGetValidator = [ | ||
117 | param('jobUUID').custom(isUUIDValid), | ||
118 | |||
119 | body('runnerToken').custom(isRunnerTokenValid), | ||
120 | body('jobToken').custom(isRunnerJobTokenValid), | ||
121 | |||
122 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
123 | if (areValidationErrors(req, res, { tags })) return cleanUpReqFiles(req) | ||
124 | |||
125 | const runnerJob = await RunnerJobModel.loadByRunnerAndJobTokensWithRunner({ | ||
126 | uuid: req.params.jobUUID, | ||
127 | runnerToken: req.body.runnerToken, | ||
128 | jobToken: req.body.jobToken | ||
129 | }) | ||
130 | |||
131 | if (!runnerJob) { | ||
132 | cleanUpReqFiles(req) | ||
133 | |||
134 | return res.fail({ | ||
135 | status: HttpStatusCode.NOT_FOUND_404, | ||
136 | message: 'Unknown runner job', | ||
137 | tags | ||
138 | }) | ||
139 | } | ||
140 | |||
141 | if (runnerJob.state !== RunnerJobState.PROCESSING) { | ||
142 | cleanUpReqFiles(req) | ||
143 | |||
144 | return res.fail({ | ||
145 | status: HttpStatusCode.BAD_REQUEST_400, | ||
146 | type: ServerErrorCode.RUNNER_JOB_NOT_IN_PROCESSING_STATE, | ||
147 | message: 'Job is not in "processing" state', | ||
148 | tags | ||
149 | }) | ||
150 | } | ||
151 | |||
152 | res.locals.runnerJob = runnerJob | ||
153 | |||
154 | return next() | ||
155 | } | ||
156 | ] | ||