screwdriver-api 8.0.35 → 8.0.37

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.35",
3
+ "version": "8.0.37",
4
4
  "description": "API server for the Screwdriver.cd service",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -44,6 +44,7 @@ const removeTemplateTagRoute = require('./templates/removeTag');
44
44
  const removeTemplateVersionRoute = require('./templates/removeVersion');
45
45
  const updateTrustedRoute = require('./templates/updateTrusted');
46
46
  const updateBuildCluster = require('./updateBuildCluster');
47
+ const updateAdminsRoute = require('./updateAdmins');
47
48
 
48
49
  /**
49
50
  * Pipeline API Plugin
@@ -278,7 +279,8 @@ const pipelinesPlugin = {
278
279
  removeTemplateTagRoute(),
279
280
  removeTemplateVersionRoute(),
280
281
  updateTrustedRoute(),
281
- updateBuildCluster()
282
+ updateBuildCluster(),
283
+ updateAdminsRoute()
282
284
  ]);
283
285
  }
284
286
  };
@@ -4,6 +4,7 @@ const joi = require('joi');
4
4
  const schema = require('screwdriver-data-schema');
5
5
  const idSchema = schema.models.pipeline.base.extract('id');
6
6
  const scmUriSchema = schema.models.pipeline.base.extract('scmUri');
7
+ const scmContextSchema = schema.models.pipeline.base.extract('scmContext');
7
8
  const listSchema = joi.array().items(schema.models.pipeline.get).label('List of Pipelines');
8
9
  const pipelineIdsSchema = joi.alternatives().try(joi.array().items(idSchema), idSchema).required();
9
10
  const IDS_KEY = 'ids[]';
@@ -23,12 +24,14 @@ module.exports = () => ({
23
24
  handler: async (request, h) => {
24
25
  const { pipelineFactory } = request.server.app;
25
26
  const { sort, configPipelineId, sortBy, search, scmUri, page, count } = request.query;
26
- const scmContexts = pipelineFactory.scm.getScmContexts();
27
+ const scmContexts = request.query.scmContext
28
+ ? [request.query.scmContext]
29
+ : pipelineFactory.scm.getScmContexts();
27
30
  let pipelineArray = [];
28
31
 
29
- scmContexts.forEach(scmContext => {
32
+ scmContexts.forEach(sc => {
30
33
  const config = {
31
- params: { scmContext },
34
+ params: { scmContext: sc },
32
35
  sort
33
36
  };
34
37
 
@@ -129,7 +132,8 @@ module.exports = () => ({
129
132
  joi.object({
130
133
  configPipelineId: idSchema,
131
134
  'ids[]': pipelineIdsSchema.optional(),
132
- scmUri: scmUriSchema
135
+ scmUri: scmUriSchema,
136
+ scmContext: scmContextSchema.optional()
133
137
  })
134
138
  )
135
139
  }
@@ -0,0 +1,106 @@
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}/updateAdmins',
12
+ options: {
13
+ description: 'Update admins of a pipeline',
14
+ notes: 'Update the admins of a specific pipeline',
15
+ tags: ['api', 'pipelines'],
16
+ auth: {
17
+ strategies: ['token'],
18
+ scope: ['user', '!guest', 'pipeline']
19
+ },
20
+ handler: async (request, h) => {
21
+ const { id } = request.params;
22
+ const { scmContext, username, scmUserId, scope } = request.auth.credentials;
23
+ const isPipeline = scope.includes('pipeline');
24
+
25
+ const { usernames } = request.payload;
26
+ const payloadScmContext = request.payload.scmContext;
27
+
28
+ if (!Array.isArray(usernames) || usernames.length === 0) {
29
+ throw boom.badRequest(`Payload must contain admin usernames`);
30
+ } else if (!payloadScmContext) {
31
+ throw boom.badRequest(`Payload must contain scmContext`);
32
+ }
33
+
34
+ const { pipelineFactory, bannerFactory, userFactory } = request.server.app;
35
+
36
+ // Check token permissions
37
+ if (isPipeline) {
38
+ if (username !== id) {
39
+ throw boom.forbidden(
40
+ `User ${username} is not authorized to update admins for the pipeline (id=${id})`
41
+ );
42
+ }
43
+ } else {
44
+ // Only SD cluster admins can update the admins
45
+ const scmDisplayName = bannerFactory.scm.getDisplayName({ scmContext });
46
+
47
+ const adminDetails = request.server.plugins.banners.screwdriverAdminDetails(
48
+ username,
49
+ scmDisplayName,
50
+ scmUserId
51
+ );
52
+
53
+ if (!adminDetails.isAdmin) {
54
+ throw boom.forbidden(
55
+ `User ${username} does not have Screwdriver administrative privileges to update the admins for the pipeline (id=${id})`
56
+ );
57
+ }
58
+ }
59
+
60
+ const pipeline = await pipelineFactory.get({ id });
61
+
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
+ }
99
+ },
100
+ validate: {
101
+ params: joi.object({
102
+ id: idSchema
103
+ })
104
+ }
105
+ }
106
+ });
@@ -778,11 +778,17 @@ async function createPrClosedEvent(options, request) {
778
778
  try {
779
779
  const b = await p.branch;
780
780
  let eventConfig = {};
781
-
782
- let configPipelineSha = '';
781
+ const token = await p.token;
782
+ const pScmConfig = {
783
+ scmUri: p.scmUri,
784
+ token,
785
+ scmRepo: p.scmRepo,
786
+ scmContext: scmConfig.scmContext
787
+ };
788
+ let latestPipelineSha = '';
783
789
 
784
790
  try {
785
- configPipelineSha = await pipelineFactory.scm.getCommitSha(scmConfig);
791
+ latestPipelineSha = await pipelineFactory.scm.getCommitSha(pScmConfig);
786
792
  } catch (err) {
787
793
  if (err.status >= 500) {
788
794
  throw err;
@@ -808,14 +814,14 @@ async function createPrClosedEvent(options, request) {
808
814
  webhooks: true,
809
815
  username,
810
816
  scmContext: scmConfig.scmContext,
811
- sha,
817
+ sha: latestPipelineSha || sha,
812
818
  startFrom: isPipelineBranch ? startFrom : `${startFrom}:${branch}`,
813
819
  changedFiles,
814
820
  causeMessage: isPipelineBranch ? causeMessage : `${causeMessage} on branch ${branch}`,
815
821
  ref,
816
822
  baseBranch: branch,
817
823
  meta: createMeta(options),
818
- configPipelineSha,
824
+ configPipelineSha: latestPipelineSha,
819
825
  prNum,
820
826
  chainPR: resolvedChainPR
821
827
  };