screwdriver-api 7.0.260 → 7.0.262
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.
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
### Build Cluster Selection
|
|
2
|
+
|
|
3
|
+
##### On pipeline creation
|
|
4
|
+
|
|
5
|
+
```mermaid
|
|
6
|
+
graph TD
|
|
7
|
+
|
|
8
|
+
A(Start) -->|Create| B[Pipeline Create]
|
|
9
|
+
B -->|Sync| C[Pipeline Sync]
|
|
10
|
+
C -->|Fetch Config| D[Get Config]
|
|
11
|
+
|
|
12
|
+
subgraph GH
|
|
13
|
+
E1@{ shape: lean-r, label: "SD YAML" }
|
|
14
|
+
end
|
|
15
|
+
E1 --> D
|
|
16
|
+
|
|
17
|
+
D --> E{Pipeline-level build cluster annotation?}
|
|
18
|
+
E -->|Yes| F[Store annotation]
|
|
19
|
+
E -->|No| F1[Get pipeline annotation]
|
|
20
|
+
|
|
21
|
+
subgraph Database
|
|
22
|
+
F1
|
|
23
|
+
F
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
F1 --> H{Pipeline has build cluster annotation?}
|
|
27
|
+
H -->|Yes| I[Use annotation] --> F
|
|
28
|
+
H -->|No| J[Derive build cluster] --> F
|
|
29
|
+
F --> Z@{ shape: stadium, label: "End" }
|
|
30
|
+
|
|
31
|
+
subgraph buildCluster Table in DB
|
|
32
|
+
K@{ shape: lean-r, label: "group" }
|
|
33
|
+
L@{ shape: lean-r, label: "weight" }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
K --> J
|
|
37
|
+
L --> J
|
|
38
|
+
|
|
39
|
+
click B "https://github.com/screwdriver-cd/screwdriver/blob/master/plugins/pipelines/create.js"
|
|
40
|
+
click C "https://github.com/screwdriver-cd/screwdriver/blob/5a74c24e232a95a12d28e0ae7c4c3a5b25e6f872/plugins/pipelines/create.js#L104"
|
|
41
|
+
click D "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/pipeline.js#L1009-L1021"
|
|
42
|
+
click I "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/pipeline.js#L1018-L1020"
|
|
43
|
+
click J "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/helper.js#L229-L293"
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
##### On build creation
|
|
48
|
+
|
|
49
|
+
```mermaid
|
|
50
|
+
graph TD
|
|
51
|
+
|
|
52
|
+
A(Start) --> B[Build Create]
|
|
53
|
+
B --> C[Get build cluster]
|
|
54
|
+
subgraph input
|
|
55
|
+
D@{ shape: lean-r, label: "Job permutations" }
|
|
56
|
+
E@{ shape: lean-r, label: "Pipeline annotations" }
|
|
57
|
+
F@{ shape: lean-r, label: "Job provider" }
|
|
58
|
+
end
|
|
59
|
+
D --> C
|
|
60
|
+
E --> C
|
|
61
|
+
F --> C
|
|
62
|
+
C --> G{Is provider present?}
|
|
63
|
+
G -->|Yes| H[Derive build cluster based on provider]
|
|
64
|
+
H --> Z@{ shape: stadium, label: "Done" }
|
|
65
|
+
G -->|No| I{Is job annotation present?}
|
|
66
|
+
I --> |Yes| J[Use the build cluster from job annotation]
|
|
67
|
+
J --> Z
|
|
68
|
+
I --> |No| K{Is pipeline annotation present?}
|
|
69
|
+
K --> |Yes| L[Use the build cluster from pipeline annotation]
|
|
70
|
+
K --> |No| M[Derive randomly]
|
|
71
|
+
L --> Z
|
|
72
|
+
M --> Z
|
|
73
|
+
|
|
74
|
+
click C "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/buildFactory.js#L221-L226"
|
|
75
|
+
click D "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/buildFactory.js#L213"
|
|
76
|
+
click E "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/buildFactory.js#L214"
|
|
77
|
+
click F "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/buildFactory.js#L215-L219"
|
|
78
|
+
click H "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/helper.js#L245-L248"
|
|
79
|
+
click J "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/helper.js#L235-L237"
|
|
80
|
+
click L "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/helper.js#L239-L241"
|
|
81
|
+
click M "https://github.com/screwdriver-cd/models/blob/7eac5d79e11620793ab8936cf6e06971a2c04eea/lib/helper.js#L259-L265"
|
|
82
|
+
```
|
package/package.json
CHANGED
|
@@ -43,6 +43,7 @@ const removeTemplateRoute = require('./templates/remove');
|
|
|
43
43
|
const removeTemplateTagRoute = require('./templates/removeTag');
|
|
44
44
|
const removeTemplateVersionRoute = require('./templates/removeVersion');
|
|
45
45
|
const updateTrustedRoute = require('./templates/updateTrusted');
|
|
46
|
+
const updateBuildCluster = require('./updateBuildCluster');
|
|
46
47
|
|
|
47
48
|
/**
|
|
48
49
|
* Pipeline API Plugin
|
|
@@ -276,7 +277,8 @@ const pipelinesPlugin = {
|
|
|
276
277
|
removeTemplateRoute(),
|
|
277
278
|
removeTemplateTagRoute(),
|
|
278
279
|
removeTemplateVersionRoute(),
|
|
279
|
-
updateTrustedRoute()
|
|
280
|
+
updateTrustedRoute(),
|
|
281
|
+
updateBuildCluster()
|
|
280
282
|
]);
|
|
281
283
|
}
|
|
282
284
|
};
|
|
@@ -0,0 +1,102 @@
|
|
|
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.pipeline.base.extract('id');
|
|
8
|
+
|
|
9
|
+
module.exports = () => ({
|
|
10
|
+
method: 'PUT',
|
|
11
|
+
path: '/pipelines/{id}/buildCluster',
|
|
12
|
+
options: {
|
|
13
|
+
description: 'Update the buildCluster of a pipeline',
|
|
14
|
+
notes: 'Update the buildCluster of a specific pipeline',
|
|
15
|
+
tags: ['api', 'pipelines'],
|
|
16
|
+
auth: {
|
|
17
|
+
strategies: ['token'],
|
|
18
|
+
scope: ['user', '!guest']
|
|
19
|
+
},
|
|
20
|
+
handler: async (request, h) => {
|
|
21
|
+
const buildClusterAnnotation = 'screwdriver.cd/buildCluster';
|
|
22
|
+
const { payload } = request;
|
|
23
|
+
|
|
24
|
+
// payload should have buildCluster annotation
|
|
25
|
+
if (!payload[buildClusterAnnotation]) {
|
|
26
|
+
throw boom.badRequest(`Payload must contain ${buildClusterAnnotation}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { pipelineFactory, bannerFactory, buildClusterFactory } = request.server.app;
|
|
30
|
+
const { scmContext, username, scmUserId } = request.auth.credentials;
|
|
31
|
+
|
|
32
|
+
// only SD cluster admins can update the buildCluster
|
|
33
|
+
const scmDisplayName = bannerFactory.scm.getDisplayName({ scmContext });
|
|
34
|
+
const adminDetails = request.server.plugins.banners.screwdriverAdminDetails(
|
|
35
|
+
username,
|
|
36
|
+
scmDisplayName,
|
|
37
|
+
scmUserId
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (!adminDetails.isAdmin) {
|
|
41
|
+
throw boom.forbidden(
|
|
42
|
+
`User ${username} does not have Screwdriver administrative privileges to update the buildCluster`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const { id } = request.params;
|
|
47
|
+
const pipeline = await pipelineFactory.get({ id });
|
|
48
|
+
// check if pipeline exists
|
|
49
|
+
|
|
50
|
+
if (!pipeline) {
|
|
51
|
+
throw boom.notFound(`Pipeline ${id} does not exist`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const pipelineConfig = await pipeline.getConfiguration({});
|
|
55
|
+
// check if pipeline has buildCluster annotation
|
|
56
|
+
|
|
57
|
+
if (pipelineConfig.annotations && pipelineConfig.annotations[buildClusterAnnotation]) {
|
|
58
|
+
const scmUrl = pipeline.scmRepo.url;
|
|
59
|
+
|
|
60
|
+
throw boom.conflict(
|
|
61
|
+
`Pipeline ${id} already has a buildCluster annotation set in the YAML configuration: check ${scmUrl}`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ensure that the buildCluster is a valid cluster
|
|
66
|
+
const buildClusterName = payload[buildClusterAnnotation];
|
|
67
|
+
const buildCluster = await buildClusterFactory.get({ name: buildClusterName, scmContext });
|
|
68
|
+
|
|
69
|
+
if (!buildCluster) {
|
|
70
|
+
throw boom.badRequest(`Build cluster ${buildClusterName} does not exist`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ensure that the buildCluster is active
|
|
74
|
+
if (!buildCluster.isActive) {
|
|
75
|
+
throw boom.badRequest(`Build cluster ${buildClusterName} is not active`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// update pipeline with buildCluster annotation
|
|
79
|
+
if (!pipeline.annotations) {
|
|
80
|
+
pipeline.annotations = {};
|
|
81
|
+
}
|
|
82
|
+
pipeline.annotations[buildClusterAnnotation] = buildClusterName;
|
|
83
|
+
try {
|
|
84
|
+
const result = await pipeline.update();
|
|
85
|
+
|
|
86
|
+
logger.info(
|
|
87
|
+
`[Audit] user ${username} updates ${buildClusterAnnotation} for pipelineID:${id} to ${buildClusterName}.`
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
return h.response(result.toJson()).code(200);
|
|
91
|
+
} catch (err) {
|
|
92
|
+
logger.error(`Failed to update ${buildClusterAnnotation} for pipeline ${id}: ${err.message}`);
|
|
93
|
+
throw boom.internal(`Failed to update ${buildClusterAnnotation} for pipeline ${id}`);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
validate: {
|
|
97
|
+
params: joi.object({
|
|
98
|
+
id: idSchema
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|