screwdriver-api 7.0.262 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +1 -1
- package/Dockerfile.local +1 -1
- package/package.json +30 -30
- package/plugins/jobs/buildCluster/remove.js +70 -0
- package/plugins/jobs/buildCluster/update.js +85 -0
- package/plugins/jobs/index.js +5 -1
package/Dockerfile
CHANGED
package/Dockerfile.local
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "screwdriver-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.1",
|
|
4
4
|
"description": "API server for the Screwdriver.cd service",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"url": "git@github.com:screwdriver-cd/screwdriver.git"
|
|
30
30
|
},
|
|
31
31
|
"engines": {
|
|
32
|
-
"node": ">=
|
|
32
|
+
"node": ">=22.0.0"
|
|
33
33
|
},
|
|
34
34
|
"greenkeeper": {
|
|
35
35
|
"ignore": [
|
|
@@ -104,33 +104,33 @@
|
|
|
104
104
|
"node-env-file": "^0.1.8",
|
|
105
105
|
"prom-client": "^12.0.0",
|
|
106
106
|
"redlock": "^4.2.0",
|
|
107
|
-
"screwdriver-artifact-bookend": "^
|
|
108
|
-
"screwdriver-build-bookend": "^
|
|
109
|
-
"screwdriver-cache-bookend": "^
|
|
110
|
-
"screwdriver-command-validator": "^
|
|
111
|
-
"screwdriver-config-parser": "^
|
|
112
|
-
"screwdriver-coverage-bookend": "^
|
|
113
|
-
"screwdriver-coverage-sonar": "^
|
|
114
|
-
"screwdriver-data-schema": "^
|
|
115
|
-
"screwdriver-datastore-sequelize": "^
|
|
116
|
-
"screwdriver-executor-base": "^
|
|
117
|
-
"screwdriver-executor-docker": "^
|
|
118
|
-
"screwdriver-executor-k8s": "^
|
|
107
|
+
"screwdriver-artifact-bookend": "^3.0.0",
|
|
108
|
+
"screwdriver-build-bookend": "^5.0.0",
|
|
109
|
+
"screwdriver-cache-bookend": "^4.0.0",
|
|
110
|
+
"screwdriver-command-validator": "^5.0.0",
|
|
111
|
+
"screwdriver-config-parser": "^12.0.0",
|
|
112
|
+
"screwdriver-coverage-bookend": "^3.0.0",
|
|
113
|
+
"screwdriver-coverage-sonar": "^5.0.0",
|
|
114
|
+
"screwdriver-data-schema": "^25.1.0",
|
|
115
|
+
"screwdriver-datastore-sequelize": "^10.0.0",
|
|
116
|
+
"screwdriver-executor-base": "^11.0.0",
|
|
117
|
+
"screwdriver-executor-docker": "^8.0.1",
|
|
118
|
+
"screwdriver-executor-k8s": "^17.1.0",
|
|
119
119
|
"screwdriver-executor-k8s-vm": "^5.0.0",
|
|
120
|
-
"screwdriver-executor-queue": "^
|
|
121
|
-
"screwdriver-executor-router": "^
|
|
122
|
-
"screwdriver-logger": "^
|
|
123
|
-
"screwdriver-models": "^
|
|
124
|
-
"screwdriver-notifications-email": "^
|
|
125
|
-
"screwdriver-notifications-slack": "^
|
|
126
|
-
"screwdriver-request": "^
|
|
127
|
-
"screwdriver-scm-base": "^
|
|
128
|
-
"screwdriver-scm-bitbucket": "^
|
|
129
|
-
"screwdriver-scm-github": "^
|
|
130
|
-
"screwdriver-scm-gitlab": "^
|
|
131
|
-
"screwdriver-scm-router": "^
|
|
132
|
-
"screwdriver-template-validator": "^
|
|
133
|
-
"screwdriver-workflow-parser": "^
|
|
120
|
+
"screwdriver-executor-queue": "^6.0.0",
|
|
121
|
+
"screwdriver-executor-router": "^5.0.0",
|
|
122
|
+
"screwdriver-logger": "^3.0.0",
|
|
123
|
+
"screwdriver-models": "^32.0.0",
|
|
124
|
+
"screwdriver-notifications-email": "^5.0.0",
|
|
125
|
+
"screwdriver-notifications-slack": "^7.0.0",
|
|
126
|
+
"screwdriver-request": "^3.0.0",
|
|
127
|
+
"screwdriver-scm-base": "^10.0.0",
|
|
128
|
+
"screwdriver-scm-bitbucket": "^7.0.1",
|
|
129
|
+
"screwdriver-scm-github": "^14.1.0",
|
|
130
|
+
"screwdriver-scm-gitlab": "^5.0.1",
|
|
131
|
+
"screwdriver-scm-router": "^9.0.0",
|
|
132
|
+
"screwdriver-template-validator": "^10.0.0",
|
|
133
|
+
"screwdriver-workflow-parser": "^6.0.0",
|
|
134
134
|
"sqlite3": "^5.1.4",
|
|
135
135
|
"stream": "0.0.3",
|
|
136
136
|
"tinytim": "^0.1.1",
|
|
@@ -150,8 +150,8 @@
|
|
|
150
150
|
"chai-as-promised": "^7.1.1",
|
|
151
151
|
"chai-jwt": "^2.0.0",
|
|
152
152
|
"coveralls": "^3.1.1",
|
|
153
|
-
"eslint": "^8.
|
|
154
|
-
"eslint-config-screwdriver": "^
|
|
153
|
+
"eslint": "^8.57.0",
|
|
154
|
+
"eslint-config-screwdriver": "^8.0.0",
|
|
155
155
|
"form-data": "^4.0.0",
|
|
156
156
|
"import-fresh": "^3.3.0",
|
|
157
157
|
"mocha": "^10.1.0",
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const boom = require('@hapi/boom');
|
|
4
|
+
const joi = require('joi');
|
|
5
|
+
const schema = require('screwdriver-data-schema');
|
|
6
|
+
const logger = require('screwdriver-logger');
|
|
7
|
+
const idSchema = schema.models.job.base.extract('id');
|
|
8
|
+
|
|
9
|
+
module.exports = () => ({
|
|
10
|
+
method: 'DELETE',
|
|
11
|
+
path: '/jobs/{id}/buildCluster',
|
|
12
|
+
options: {
|
|
13
|
+
description: 'Delete the buildCluster override of a job',
|
|
14
|
+
notes: 'Returns null if successful',
|
|
15
|
+
tags: ['api', 'jobs'],
|
|
16
|
+
auth: {
|
|
17
|
+
strategies: ['token'],
|
|
18
|
+
scope: ['admin', '!guest']
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
handler: async (request, h) => {
|
|
22
|
+
const { jobFactory, pipelineFactory } = request.server.app;
|
|
23
|
+
const { username } = request.auth.credentials;
|
|
24
|
+
const { id } = request.params;
|
|
25
|
+
const adminAnnotation = 'screwdriver.cd/sdAdminBuildClusterOverride';
|
|
26
|
+
const job = await jobFactory.get(id);
|
|
27
|
+
|
|
28
|
+
if (!job) {
|
|
29
|
+
throw boom.notFound(`Job ${id} does not exist`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const pipeline = await pipelineFactory.get(job.pipelineId);
|
|
33
|
+
|
|
34
|
+
if (!pipeline) {
|
|
35
|
+
throw boom.notFound('Pipeline does not exist');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// remove buildClusterOverride annotation from job
|
|
39
|
+
const [permutation] = job.permutations;
|
|
40
|
+
const buildClusterOverride =
|
|
41
|
+
permutation && permutation.annotations && permutation.annotations[adminAnnotation];
|
|
42
|
+
|
|
43
|
+
if (!buildClusterOverride) {
|
|
44
|
+
logger.info(`[Audit] ${adminAnnotation} does not exists for jobId:${id}.`);
|
|
45
|
+
|
|
46
|
+
return h.response().code(204);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
logger.info(`[Audit] ${adminAnnotation} for jobId:${id} set to ${buildClusterOverride}, deleting.`);
|
|
50
|
+
|
|
51
|
+
delete permutation.annotations[adminAnnotation];
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const result = await job.updateBuildCluster();
|
|
55
|
+
|
|
56
|
+
logger.info(`[Audit] user ${username} deleted ${adminAnnotation} for jobId:${id}.`);
|
|
57
|
+
|
|
58
|
+
return h.response(result.toJson()).code(200);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
logger.error(`Failed to remove ${adminAnnotation} for job ${id}: ${err.message}`);
|
|
61
|
+
throw boom.internal(`Failed to remove ${adminAnnotation} for job ${id}`);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
validate: {
|
|
65
|
+
params: joi.object({
|
|
66
|
+
id: idSchema
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const boom = require('@hapi/boom');
|
|
4
|
+
const joi = require('joi');
|
|
5
|
+
const schema = require('screwdriver-data-schema');
|
|
6
|
+
const logger = require('screwdriver-logger');
|
|
7
|
+
const idSchema = schema.models.job.base.extract('id');
|
|
8
|
+
|
|
9
|
+
module.exports = () => ({
|
|
10
|
+
method: 'PUT',
|
|
11
|
+
path: '/jobs/{id}/buildCluster',
|
|
12
|
+
options: {
|
|
13
|
+
description: 'Update the buildCluster of a job',
|
|
14
|
+
notes: 'Update the buildCluster of a specific job',
|
|
15
|
+
tags: ['api', 'jobs'],
|
|
16
|
+
auth: {
|
|
17
|
+
strategies: ['token'],
|
|
18
|
+
scope: ['admin', '!guest']
|
|
19
|
+
},
|
|
20
|
+
handler: async (request, h) => {
|
|
21
|
+
const adminAnnotation = 'screwdriver.cd/sdAdminBuildClusterOverride';
|
|
22
|
+
const { payload } = request;
|
|
23
|
+
const { id } = request.params;
|
|
24
|
+
|
|
25
|
+
if (!payload[adminAnnotation]) {
|
|
26
|
+
throw boom.badRequest(`Payload must contain ${adminAnnotation}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { jobFactory, buildClusterFactory, pipelineFactory } = request.server.app;
|
|
30
|
+
const { scmContext, username } = request.auth.credentials;
|
|
31
|
+
|
|
32
|
+
const job = await jobFactory.get(id);
|
|
33
|
+
|
|
34
|
+
if (!job) {
|
|
35
|
+
throw boom.notFound(`Job ${id} does not exist`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const pipeline = await pipelineFactory.get(job.pipelineId);
|
|
39
|
+
|
|
40
|
+
if (!pipeline) {
|
|
41
|
+
throw boom.notFound('Pipeline does not exist');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ensure that the buildCluster is a valid cluster
|
|
45
|
+
const buildClusterName = payload[adminAnnotation];
|
|
46
|
+
const buildCluster = await buildClusterFactory.get({ name: buildClusterName, scmContext });
|
|
47
|
+
|
|
48
|
+
if (!buildCluster || !buildCluster.isActive) {
|
|
49
|
+
throw boom.badRequest(`Build cluster ${buildClusterName} does not exist or is not active`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// update job with buildClusterOverride annotation
|
|
53
|
+
const [permutation] = job.permutations;
|
|
54
|
+
|
|
55
|
+
permutation.annotations = permutation.annotations || {};
|
|
56
|
+
|
|
57
|
+
const annotations = permutation.annotations;
|
|
58
|
+
|
|
59
|
+
if (annotations[adminAnnotation]) {
|
|
60
|
+
logger.info(
|
|
61
|
+
`[Audit] ${adminAnnotation} for jobId:${id} already set to ${annotations[adminAnnotation]}, updating.`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
permutation.annotations[adminAnnotation] = buildClusterName;
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const result = await job.updateBuildCluster();
|
|
68
|
+
|
|
69
|
+
logger.info(
|
|
70
|
+
`[Audit] user ${username} updates ${adminAnnotation} for jobId:${id} to ${buildClusterName}.`
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
return h.response(result.toJson()).code(200);
|
|
74
|
+
} catch (err) {
|
|
75
|
+
logger.error(`Failed to update ${adminAnnotation} for job ${id}: ${err.message}`);
|
|
76
|
+
throw boom.internal(`Failed to update ${adminAnnotation} for job ${id}`);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
validate: {
|
|
80
|
+
params: joi.object({
|
|
81
|
+
id: idSchema
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
package/plugins/jobs/index.js
CHANGED
|
@@ -7,6 +7,8 @@ const lastSuccessfulMeta = require('./lastSuccessfulMeta');
|
|
|
7
7
|
const latestBuild = require('./latestBuild');
|
|
8
8
|
const metrics = require('./metrics');
|
|
9
9
|
const notify = require('./notify');
|
|
10
|
+
const addBuildCluster = require('./buildCluster/update');
|
|
11
|
+
const removeBuildCluster = require('./buildCluster/remove');
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Job API Plugin
|
|
@@ -23,7 +25,9 @@ const jobsPlugin = {
|
|
|
23
25
|
lastSuccessfulMeta(),
|
|
24
26
|
metrics(),
|
|
25
27
|
latestBuild(),
|
|
26
|
-
notify()
|
|
28
|
+
notify(),
|
|
29
|
+
addBuildCluster(),
|
|
30
|
+
removeBuildCluster()
|
|
27
31
|
]);
|
|
28
32
|
}
|
|
29
33
|
};
|