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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screwdriver-api",
3
- "version": "7.0.260",
3
+ "version": "7.0.262",
4
4
  "description": "API server for the Screwdriver.cd service",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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
+ });