Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add create and remove template tag routes #647

Merged
merged 2 commits into from
Jul 20, 2017
Merged

feat: Add create and remove template tag routes #647

merged 2 commits into from
Jul 20, 2017

Conversation

d2lam
Copy link
Member

@d2lam d2lam commented Jul 14, 2017

Context

This PR allows tagging a template, similar to how docker tagging works.

  • 1 tag can only map to 1 version
  • 1 version can have multiple tags

Example:

id name tag version
1 mytemplate stable 1.2.0
2 mytemplate latest 1.2.0

Objective

Add 2 routes for template tagging: CREATE and DELETE.
UPDATE uses the same route as CREATE: send a PUT templates/{templateTag}/tags/{tagName} with the payload as: {version} instead of the usual /id, since it doesn't make sense that users need to look up the id to update.

DELETE: DELETE templates/{templateTag}/tags/{tagName}

Notes: This only allows build scope to tag template due to security reasons. It will check if the build belongs to the pipeline that publishes this template. If not, then the build is not allowed to tag the template.

References

#616

})
])
.then(([pipeline, template]) => {
// Check for permission
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a check for the template existing

Copy link
Member Author

@d2lam d2lam Jul 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's necessary because of our logic. templatetag can't be created if the template itself doesn't exist. There is already a check if templateTag exists. If templateTag exists, then template should exist.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Create template
  2. Create tag
  3. Delete template
  4. Lookup tag
  5. 500 error

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleting a template does not clean up the tags. And since you can operate on tags independently from templates, that delete operation isn't there yet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleting a template should delete the tags that are associated with it. It doesn't make sense to keep a tag that references something that doesn't exist. Just like how deleting a pipelines should delete all its jobs & builds.
Also, we don't have delete template at the moment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add it for extra safety, but it will never reach the code with our current design.

const schema = require('screwdriver-data-schema');
const urlLib = require('url');

/* Currently, only build scope is allowed to tag template due to security reasons.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 good comment

pathname: `${request.path}/${tag.id}`
});

return reply(tag.toJson()).header('Location', location).code(201);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm should this return the template or the templateTag or some combination of the two?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes more sense to return just the tag. If it returns the template itself, it might be confusing to the users: "Did I just create this template?"

Copy link
Member

@tkyi tkyi Jul 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. If the object returned has the template info AND the tag would that be more clear? Or still confusing

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally I think it should return what GOT CREATED. That's why I don't want to include the template information since the template is not created, the tag is created. For a GET it makes sense to return the template.
What are others' opinions on this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think template name, version and tag together should be good enough.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No preference here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't mind any way you end up choosing, as long as the UI can consume it easily. If you want my opinion, I would have expected the resource that was created to be returned.

Copy link
Member

@minzcmu minzcmu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update README?

const templateFactory = request.server.app.templateFactory;
const templateTagFactory = request.server.app.templateTagFactory;
const pipelineId = request.auth.credentials.pipelineId;
const config = request.payload;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it weird to pass in a payload for a DELETE?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is unusual, but not forbidden according to RFC 7231.
A couple posts related to this:

I would say it's weird and we should avoid it if we can. But I think in this case, it makes sense to send a payload with it. An alternative would be delete templates/tags/{name}/{tag}? I'm not sure if that's weird either. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think to it would be safer for us to use the /templates/tags/{name}/{tag} endpoint instead of getting the data from the payload. Just in case other browsers drop the payload. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RESTful endpoint would be DELETE /templates/{name}/tags/{tagName}. You should be able to fetch the pipeline data from the template data and the JWT when comparing for authorization [build scope].

Alternatively, this could be DELETE /templates/{name}/{tagName or version} if it was less restful, but this adds a layer of confusion.

Copy link
Member Author

@d2lam d2lam Jul 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go with DELETE /templates/{name}/tags/{tagName}

Copy link
Member

@tkyi tkyi Jul 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petey Should the GET endpoint for template tags be GET /templates/{name}/tags/{tagName} then?

Update: keeping the GET /templates/{name}/{versionOrTag}

@petey petey mentioned this pull request Jul 17, 2017
16 tasks
Copy link
Contributor

@petey petey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -73,3 +73,26 @@ Example payload:
}
}
```

#### Create a tag for a template version
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about update / retagging?

@d2lam d2lam force-pushed the templatetag branch 2 times, most recently from e936260 to 0d1f988 Compare July 18, 2017 17:48
@tkyi
Copy link
Member

tkyi commented Jul 18, 2017

Also do we do any checks to make sure the build that deletes the tag is the one that created the tag? Or can anyone create/delete a tag right now?

Copy link
Collaborator

@FenrirUnbound FenrirUnbound left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

patagonia-cinemagraph

@d2lam
Copy link
Member Author

d2lam commented Jul 19, 2017

@tkyi Yes it does check for permission. It's specified in the README:

Note: This endpoint is only accessible in build scope and the permission is tied to the pipeline that creates the template.

In the code:
https://github.com/screwdriver-cd/screwdriver/blob/templatetag/plugins/templates/createTag.js#L49-L53

https://github.com/screwdriver-cd/screwdriver/blob/templatetag/plugins/templates/removeTag.js#L49-L52

@d2lam
Copy link
Member Author

d2lam commented Jul 19, 2017

@tkyi @petey Updated with the new endpoints in this commit: 7d34294

  • PUT templates/{templateName}/tags/{tagName} with payload as {version}
  • DELETE templates/{templateName}/tags/{tagName}

#### Get all templates
`page` and `count` optional
#### Template
##### Get all templates
Copy link
Member

@tkyi tkyi Jul 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm this heading style gets interesting because it looks smaller than the Arguments


return Promise.all([
pipelineFactory.get(pipelineId),
templateFactory.get({ name, version }),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be getTemplate?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be get, since we want to get the exact version. And getTemplate will be refactored into string only later.

@d2lam d2lam force-pushed the templatetag branch 2 times, most recently from 93d92be to 726ea94 Compare July 20, 2017 22:03

You can get a single template by providing the template name and the specific version or the tag.

`GET /templates/{name}/{tag}` or `GET /templates/{name}/{version}`

**Arguments**
###### Arguments

'name', 'tag' or 'version'

* `name` - Name of the template
* `tag` - Tag of the template (e.g. `stable`, `latest`, etc)
* `version` - Version of the template
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could call out that we'll autobump versions for them when they create templates.

Copy link
Member

@tkyi tkyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tkyi tkyi merged commit 11bc128 into master Jul 20, 2017
@tkyi tkyi deleted the templatetag branch July 20, 2017 22:20
d2lam pushed a commit that referenced this pull request Jul 21, 2017
feat: Add create and remove template tag routes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants