-
Notifications
You must be signed in to change notification settings - Fork 170
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add create and remove template tag routes
- Loading branch information
Showing
7 changed files
with
356 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,18 +32,18 @@ server.register({ | |
|
||
`GET /templates?page={pageNumber}&count={countNumber}` | ||
|
||
#### Get single template | ||
#### Get a single template | ||
|
||
`GET /templates/{id}` | ||
|
||
#### Create a template | ||
Create a template will store the template data (`config`, `name`, `version`, `description`, `maintainer`, `labels`) into the datastore. | ||
Creating a template will store the template data (`config`, `name`, `version`, `description`, `maintainer`, `labels`) into the datastore. | ||
|
||
If the exact template and version already exist, the only thing that can be changed is `labels`. | ||
|
||
If the template already exists but not the version, the new version will be stored provided that the build has correct permissions. | ||
|
||
This endpoint is only accessible in `build` scope. | ||
*Note: This endpoint is only accessible in `build` scope and the permission is tied to the pipeline that first creates the template.* | ||
|
||
`POST /templates` | ||
|
||
|
@@ -73,3 +73,26 @@ Example payload: | |
} | ||
} | ||
``` | ||
|
||
#### Create/Update a tag for a template version | ||
|
||
Tagging a template version allows fetching on template version by tag. For example, tag `[email protected]` as `stable`. | ||
|
||
*Note: This endpoint is only accessible in `build` scope and the permission is tied to the pipeline that creates the template.* | ||
|
||
`POST /templates/tags` with the following payload | ||
|
||
* `name` - Name of the template (ex: `mytemplate`) | ||
* `version` - Version of the template (ex: `1.1.0`) | ||
* `tag` - Name of the tag (ex: `stable`) | ||
|
||
#### Delete a template tag | ||
|
||
Delete the template tag. This does not delete the template itself. | ||
|
||
*Note: This endpoint is only accessible in `build` scope and the permission is tied to the pipeline that creates the template.* | ||
|
||
`DELETE /templates/tags` with the following payload | ||
|
||
* `name` - Name of the template (ex: `mytemplate`) | ||
* `tag` - Name of the tag (ex: `stable`) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
'use strict'; | ||
|
||
const boom = require('boom'); | ||
const schema = require('screwdriver-data-schema'); | ||
const urlLib = require('url'); | ||
|
||
/* Currently, only build scope is allowed to tag template due to security reasons. | ||
* The same pipeline that publishes the template has the permission to tag it. | ||
*/ | ||
module.exports = () => ({ | ||
method: 'PUT', | ||
path: '/templates/tags', | ||
config: { | ||
description: 'Add or update a template tag', | ||
notes: 'Add or update a specific template', | ||
tags: ['api', 'templates'], | ||
auth: { | ||
strategies: ['token', 'session'], | ||
scope: ['build'] | ||
}, | ||
plugins: { | ||
'hapi-swagger': { | ||
security: [{ token: [] }] | ||
} | ||
}, | ||
handler: (request, reply) => { | ||
const pipelineFactory = request.server.app.pipelineFactory; | ||
const templateFactory = request.server.app.templateFactory; | ||
const templateTagFactory = request.server.app.templateTagFactory; | ||
const pipelineId = request.auth.credentials.pipelineId; | ||
const config = request.payload; | ||
|
||
return Promise.all([ | ||
pipelineFactory.get(pipelineId), | ||
templateFactory.get({ | ||
name: config.name, | ||
version: config.version | ||
}), | ||
templateTagFactory.get({ | ||
name: config.name, | ||
tag: config.tag | ||
}) | ||
]).then(([pipeline, template, templateTag]) => { | ||
// If template doesn't exist, throw error | ||
if (!template) { | ||
throw boom.notFound(`Template ${config.name}@${config.version} not found`); | ||
} | ||
|
||
// If template exists, but this build's pipelineId is not the same as template's pipelineId | ||
// Then this build does not have permission to tag the template | ||
if (pipeline.id !== template.pipelineId) { | ||
throw boom.unauthorized('Not allowed to tag this template'); | ||
} | ||
|
||
// If template tag exists, then the only thing it can update is the version | ||
if (templateTag) { | ||
templateTag.version = config.version; | ||
|
||
return templateTag.update().then(tag => reply(tag.toJson()).code(200)); | ||
} | ||
|
||
// If template exists, then create the tag | ||
return templateTagFactory.create(config).then((tag) => { | ||
const location = urlLib.format({ | ||
host: request.headers.host, | ||
port: request.headers.port, | ||
protocol: request.server.info.protocol, | ||
pathname: `${request.path}/${tag.id}` | ||
}); | ||
|
||
return reply(tag.toJson()).header('Location', location).code(201); | ||
}); | ||
}).catch(err => reply(boom.wrap(err))); | ||
}, | ||
validate: { | ||
payload: schema.models.templateTag.create | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
'use strict'; | ||
|
||
const boom = require('boom'); | ||
const schema = require('screwdriver-data-schema'); | ||
|
||
/* Currently, only build scope is allowed to tag template due to security reasons. | ||
* The same pipeline that publishes the template has the permission to tag it. | ||
*/ | ||
module.exports = () => ({ | ||
method: 'DELETE', | ||
path: '/templates/tags', | ||
config: { | ||
description: 'Delete a template tag', | ||
notes: 'Delete a specific template', | ||
tags: ['api', 'templates'], | ||
auth: { | ||
strategies: ['token', 'session'], | ||
scope: ['build'] | ||
}, | ||
plugins: { | ||
'hapi-swagger': { | ||
security: [{ token: [] }] | ||
} | ||
}, | ||
handler: (request, reply) => { | ||
const pipelineFactory = request.server.app.pipelineFactory; | ||
const templateFactory = request.server.app.templateFactory; | ||
const templateTagFactory = request.server.app.templateTagFactory; | ||
const pipelineId = request.auth.credentials.pipelineId; | ||
const config = request.payload; | ||
|
||
return templateTagFactory.get({ | ||
name: config.name, | ||
tag: config.tag | ||
}) | ||
.then((templateTag) => { | ||
if (!templateTag) { | ||
throw boom.notFound('Template tag does not exist'); | ||
} | ||
|
||
return Promise.all([ | ||
pipelineFactory.get(pipelineId), | ||
templateFactory.get({ | ||
name: config.name, | ||
version: templateTag.version | ||
}) | ||
]) | ||
.then(([pipeline, template]) => { | ||
// Check for permission | ||
if (pipeline.id !== template.pipelineId) { | ||
throw boom.unauthorized('Not allowed to delete this template tag'); | ||
} | ||
|
||
// Remove the template tag, not the template | ||
return templateTag.remove(); | ||
}); | ||
}) | ||
.then(() => reply().code(204)) | ||
.catch(err => reply(boom.wrap(err))); | ||
}, | ||
validate: { | ||
payload: schema.models.templateTag.remove | ||
} | ||
} | ||
}); |
Oops, something went wrong.