screwdriver-api 8.0.49 → 8.0.51

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screwdriver-api",
3
- "version": "8.0.49",
3
+ "version": "8.0.51",
4
4
  "description": "API server for the Screwdriver.cd service",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,65 @@
1
+ 'use strict';
2
+
3
+ const boom = require('@hapi/boom');
4
+ const schema = require('screwdriver-data-schema');
5
+ const joi = require('joi');
6
+ const idSchema = schema.models.pipeline.base.extract('id');
7
+ const scmContextSchema = schema.models.pipeline.base.extract('scmContext');
8
+ const usernameSchema = schema.models.user.base.extract('username');
9
+ const { updatePipelineAdmins } = require('./helper/updateAdmins');
10
+
11
+ module.exports = () => ({
12
+ method: 'PUT',
13
+ path: '/pipelines/updateAdmins',
14
+ options: {
15
+ description: 'Update admins for a collection of pipelines',
16
+ notes: 'Update the admins for a collection of pipelines',
17
+ tags: ['api', 'pipelines'],
18
+ auth: {
19
+ strategies: ['token'],
20
+ scope: ['user', '!guest']
21
+ },
22
+ handler: async (request, h) => {
23
+ const { scmContext, username, scmUserId } = request.auth.credentials;
24
+ const { payload } = request;
25
+
26
+ const { bannerFactory } = request.server.app;
27
+
28
+ // Check token permissions
29
+ // Only SD cluster admins can update the admins
30
+ const scmDisplayName = bannerFactory.scm.getDisplayName({ scmContext });
31
+
32
+ const adminDetails = request.server.plugins.banners.screwdriverAdminDetails(
33
+ username,
34
+ scmDisplayName,
35
+ scmUserId
36
+ );
37
+
38
+ if (!adminDetails.isAdmin) {
39
+ throw boom.forbidden(
40
+ `User ${username} does not have Screwdriver administrative privileges to update the admins for pipelines`
41
+ );
42
+ }
43
+
44
+ await Promise.all(
45
+ payload.map(e => {
46
+ return updatePipelineAdmins(e, request.server);
47
+ })
48
+ );
49
+
50
+ return h.response().code(204);
51
+ },
52
+ validate: {
53
+ payload: joi
54
+ .array()
55
+ .items(
56
+ joi.object({
57
+ id: idSchema.required(),
58
+ scmContext: scmContextSchema.required(),
59
+ usernames: joi.array().items(usernameSchema).min(1).max(50).required()
60
+ })
61
+ )
62
+ .min(1)
63
+ }
64
+ }
65
+ });
@@ -0,0 +1,66 @@
1
+ 'use strict';
2
+
3
+ const boom = require('@hapi/boom');
4
+ const logger = require('screwdriver-logger');
5
+
6
+ /**
7
+ * @typedef {import('screwdriver-models/lib/pipeline')} Pipeline
8
+ */
9
+
10
+ /**
11
+ * Adds the users as admins for the specified pipeline
12
+ *
13
+ * @method updateBuildAndTriggerDownstreamJobs
14
+ * @param {Object} config
15
+ * @param {Number} config.id Pipeline id
16
+ * @param {Array} [config.usernames] List of usernames to be added as admins to the pipeline
17
+ * @param {String} config.scmContext SCM Context the users are associated with
18
+ * @param {Object} server
19
+ * @returns {Promise<Pipeline>} Updated pipeline
20
+ */
21
+ async function updatePipelineAdmins(config, server) {
22
+ const { pipelineFactory, userFactory } = server.app;
23
+ const { id, scmContext, usernames } = config;
24
+
25
+ const pipeline = await pipelineFactory.get({ id });
26
+
27
+ // check if pipeline exists
28
+ if (!pipeline) {
29
+ throw boom.notFound(`Pipeline ${id} does not exist`);
30
+ }
31
+ if (pipeline.state === 'DELETING') {
32
+ throw boom.conflict('This pipeline is being deleted.');
33
+ }
34
+
35
+ const users = await userFactory.list({
36
+ params: {
37
+ username: usernames,
38
+ scmContext
39
+ }
40
+ });
41
+
42
+ const adminUsernamesForUpdate = [];
43
+ const newAdmins = new Set(pipeline.adminUserIds);
44
+
45
+ users.forEach(user => {
46
+ newAdmins.add(user.id);
47
+ adminUsernamesForUpdate.push(user.username);
48
+ });
49
+
50
+ pipeline.adminUserIds = Array.from(newAdmins);
51
+
52
+ try {
53
+ const updatedPipeline = await pipeline.update();
54
+
55
+ logger.info(`Updated admins ${adminUsernamesForUpdate} for pipeline(id=${id})`);
56
+
57
+ return updatedPipeline;
58
+ } catch (err) {
59
+ logger.error(`Failed to update admins ${adminUsernamesForUpdate} for pipeline(id=${id}): ${err.message}`);
60
+ throw boom.internal(`Failed to update admins for pipeline ${id}`);
61
+ }
62
+ }
63
+
64
+ module.exports = {
65
+ updatePipelineAdmins
66
+ };
@@ -45,6 +45,7 @@ const removeTemplateVersionRoute = require('./templates/removeVersion');
45
45
  const updateTrustedRoute = require('./templates/updateTrusted');
46
46
  const updateBuildCluster = require('./updateBuildCluster');
47
47
  const updateAdminsRoute = require('./updateAdmins');
48
+ const batchUpdateAdminsRoute = require('./batchUpdateAdmins');
48
49
 
49
50
  /**
50
51
  * Pipeline API Plugin
@@ -280,7 +281,8 @@ const pipelinesPlugin = {
280
281
  removeTemplateVersionRoute(),
281
282
  updateTrustedRoute(),
282
283
  updateBuildCluster(),
283
- updateAdminsRoute()
284
+ updateAdminsRoute(),
285
+ batchUpdateAdminsRoute()
284
286
  ]);
285
287
  }
286
288
  };
@@ -3,8 +3,8 @@
3
3
  const boom = require('@hapi/boom');
4
4
  const joi = require('joi');
5
5
  const schema = require('screwdriver-data-schema');
6
- const logger = require('screwdriver-logger');
7
6
  const idSchema = schema.models.pipeline.base.extract('id');
7
+ const { updatePipelineAdmins } = require('./helper/updateAdmins');
8
8
 
9
9
  module.exports = () => ({
10
10
  method: 'PUT',
@@ -31,7 +31,7 @@ module.exports = () => ({
31
31
  throw boom.badRequest(`Payload must contain scmContext`);
32
32
  }
33
33
 
34
- const { pipelineFactory, bannerFactory, userFactory } = request.server.app;
34
+ const { bannerFactory } = request.server.app;
35
35
 
36
36
  // Check token permissions
37
37
  if (isPipeline) {
@@ -57,45 +57,16 @@ module.exports = () => ({
57
57
  }
58
58
  }
59
59
 
60
- const pipeline = await pipelineFactory.get({ id });
60
+ const updatedPipeline = await updatePipelineAdmins(
61
+ {
62
+ id,
63
+ scmContext: payloadScmContext,
64
+ usernames
65
+ },
66
+ request.server
67
+ );
61
68
 
62
- // check if pipeline exists
63
- if (!pipeline) {
64
- throw boom.notFound(`Pipeline ${id} does not exist`);
65
- }
66
- if (pipeline.state === 'DELETING') {
67
- throw boom.conflict('This pipeline is being deleted.');
68
- }
69
-
70
- const users = await userFactory.list({
71
- params: {
72
- username: usernames,
73
- scmContext: payloadScmContext
74
- }
75
- });
76
-
77
- const adminUsernamesForUpdate = [];
78
- const newAdmins = new Set(pipeline.adminUserIds);
79
-
80
- users.forEach(user => {
81
- newAdmins.add(user.id);
82
- adminUsernamesForUpdate.push(user.username);
83
- });
84
-
85
- pipeline.adminUserIds = Array.from(newAdmins);
86
-
87
- try {
88
- const result = await pipeline.update();
89
-
90
- logger.info(`Updated admins ${adminUsernamesForUpdate} for pipeline(id=${id})`);
91
-
92
- return h.response(result.toJson()).code(200);
93
- } catch (err) {
94
- logger.error(
95
- `Failed to update admins ${adminUsernamesForUpdate} for pipeline(id=${id}): ${err.message}`
96
- );
97
- throw boom.internal(`Failed to update admins for pipeline ${id}`);
98
- }
69
+ return h.response(updatedPipeline.toJson()).code(200);
99
70
  },
100
71
  validate: {
101
72
  params: joi.object({