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

Escaping quotes in TriggerTemplates. #321

Closed
wants to merge 1 commit into from
Closed

Escaping quotes in TriggerTemplates. #321

wants to merge 1 commit into from

Conversation

bigkevmcd
Copy link
Member

This is a proposal to allow escaping non-JSON friendly strings when rendering
TriggerTemplate resources.

@tekton-robot tekton-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jan 28, 2021
@dibyom
Copy link
Member

dibyom commented Jan 28, 2021

/kind tep

@tekton-robot tekton-robot added the kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). label Jan 28, 2021
@dibyom
Copy link
Member

dibyom commented Jan 28, 2021

/assign

@tekton-robot tekton-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 29, 2021
@tekton-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please assign dibyom
You can assign the PR to them by writing /assign @dibyom in a comment when ready.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tekton-robot tekton-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 29, 2021

// Escape indicates whether or not the value should be escaped as JSON
// before inserting into the templated bodies.
Escape bool `json:"escape,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Escape is a bit generic...what kind of escaping does it mean? I think the alternative where we have different "strategies" sounds a bit more descriptive.

The annotation approach was considered temporary at that point, but we could
consider this permanent.

Another would be to change the escaping to be some sort of strategy based
Copy link
Member

Choose a reason for hiding this comment

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

Another option I was discussing with @wlynch was having the escaping done at the TriggerBinding level not at the TriggerTemplate level. Is there ever a case where we extract a value that contains an escaped quote but then we'd sometimes want to escape it but not always?

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 mulled this over a lot, both when implementing tektoncd/triggers#823 and writing this up.

I had thought about applying it to TriggerBindings something like this:

apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
  name: pipeline-binding
spec:
  params:
  - name: gitrevision
    value: $(body.head_commit.id)
    escapeQuotes: true

And when I was writing this:

Ultimately, this is about escaping external data being received into the system,
it does feel somewhat odd that the template insertion has to know whether or not
the data should be escaped...

I reasoned that the entire purpose of triggers is to generate templated resources from incoming data, and so differentiation on whether or not "tainted" values should be escaped could be deemed to be moot, because all data is "tainted", which got me to the view that perhaps the issue is with the way it's escaped (string replace quotes), and not with the escaping itself, which is what got me to different strategies for escaping data.

This then got me back to, yes, the TriggerTemplate is probably the best place for this, because you're inserting the value into the body, and it has the context of where the value is being inserted, and so, I reconsidered the %(param.name) approach.

Another approach entirely, which was also suggested by @chmouel (and is probably not in scope for this particular change) would be to apply Jinja (or other another templating languge) to the resources?

Copy link
Member

Choose a reason for hiding this comment

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

Another approach entirely, which was also suggested by @chmouel (and is probably not in scope for this particular change) would be to apply Jinja (or other another templating languge) to the resources?

Yeah using an actual templating engine has come up before. I think in the past we decided that we wanted to keep things as simple as possible so just simple variable interpolation would be sufficient. Though as we found out there are a few edge cases (like newlines, quotes) with such an approach.

This then got me back to, yes, the TriggerTemplate is probably the best place for this, because you're inserting the value into the body, and it has the context of where the value is being inserted, and so, I reconsidered the %(param.name) approach.

I think I agree but the way I was thinking about adding it to Bindings instead is that bindings should only capture "valid" values. For our use case, any value that is extracted has to be usable in a JSON document. If we do this at the binding level, we only need to do it once per binding. Otherwise, we'd have to do it for each trigger template that uses that binding which sounds less user friendly.

Copy link
Member

Choose a reason for hiding this comment

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

In Tekton based CI we use bindings to create an interface for CI jobs - we provide a fixed set of parameters, so that a user writing a CI job does not have to worry about events, interceptors or bindings. With this in mind, the person writing the bindings does not have the context to decide whether a parameter should be escaped or not, because they don't actually know how the parameter is going to be used.

@dibyom
Copy link
Member

dibyom commented Feb 1, 2021

/lgtm

@tekton-robot tekton-robot added lgtm Indicates that a PR is ready to be merged. and removed lgtm Indicates that a PR is ready to be merged. labels Feb 1, 2021
@tekton-robot
Copy link
Contributor

New changes are detected. LGTM label has been removed.

This is a proposal to allow escaping non-JSON friendly strings when rendering
TriggerTemplate resources.
Use this section to add links to GitHub issues, other TEPs, design docs in Tekton
shared drive, examples, etc. This is useful to refer back to any other related links
to get more details.
-->
Copy link
Contributor

Choose a reason for hiding this comment

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

is it possible to include some examples of how other systems handle this kind of issue?

Comment on lines +219 to +221
- name: title
description: The title from the incoming body
escape: true
Copy link
Member

Choose a reason for hiding this comment

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

If I understand correctly, in the example above, the title was already escaped Revert \"Test Commit\", so to match that example we could have escape false here or refer to a different field perhaps?

The problem I see with this approach is that the escaping is controlled on the receiving side, which is not specific to the content producer, so using escaping in a template would bind the template to a specific content producer.

Trigger bindings are by nature specific to a content producer, so it feels to me that they would be a better place where to specify if escaping is needed or not.

Copy link
Member

Choose a reason for hiding this comment

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

But at the same time, as well written by @bigkevmcd in https://github.com/tektoncd/community/pull/321/files#diff-9129936dcf33d43ca73c0a506952028c7f718c3e15d512ad586044d61579ad0bR174-R181, the receiving side also has context about the need (or not) for escaping.

I like, among the alternatives proposed, the idea of controlling escaping when the variable associated to a parameter is used, for instance using an alternative syntax like %(tt.params.name) or some other syntax like $(tt.params.name|escape).

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 suspect %(tt.params.name) is easier to implement $(tt.params.name|escape) implies (from Django/Jinja2) that the result of tt.params.name should be passed through a "filter" called escape?

Copy link
Member

Choose a reason for hiding this comment

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

I like %(tt.params.name) over $(tt.params.name|escape).

Base automatically changed from master to main February 3, 2021 16:34
@tekton-robot
Copy link
Contributor

@bigkevmcd: PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@tekton-robot tekton-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 23, 2021
@vdemeester
Copy link
Member

/assign @afrittoli
/assign

@afrittoli
Copy link
Member

@bigkevmcd the more I think about it, the more I like the option of escaping at insertion point.

@chmouel
Copy link
Member

chmouel commented May 4, 2021

Maybe I am not understanding the problem correctly, but having the user be in control of how the parameters is going to be escaped is not going to change much, because the user usually doesn't have the ability to make sure what's coming to its payload is in a certain format.

Is the problem perhaps an issue with the standard go json library parsing?

another json library https://github.com/buger/jsonparser has an extensive section on escaping :

https://github.com/buger/jsonparser/blob/master/escape.go

perhaps we should look at how it's done there?

@bigkevmcd
Copy link
Member Author

@chmouel You can vary it, if you use a simple $(param.value) then sometimes you want that escaped (you're inserting it within the body of another string) and sometimes it can be standalone, if you wrap it in quotes"$(param.value)" for example, then quotes within quotes fail.

Copy link
Member

@dibyom dibyom left a comment

Choose a reason for hiding this comment

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

So, it sounds like the 2 most likely options are:

  1. We allow a %(tt.params.name) type syntax in the trigger templates to indicate quotes should be escaped or not. This adds additional flexibility in that escaping is decided where the parameter is actually used.

  2. We add a escapeQuotes field to the TriggerTemplate param field. This does mean that every usage of that param would be escaped but avoids new syntax.

Does this sound like an accurate summary or am I missing something? @bigkevmcd @afrittoli

Comment on lines +219 to +221
- name: title
description: The title from the incoming body
escape: true
Copy link
Member

Choose a reason for hiding this comment

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

I like %(tt.params.name) over $(tt.params.name|escape).

@tekton-robot
Copy link
Contributor

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale with a justification.
Stale issues rot after an additional 30d of inactivity and eventually close.
If this issue is safe to close now please do so with /close with a justification.
If this issue should be exempted, mark the issue as frozen with /lifecycle frozen with a justification.

/lifecycle stale

Send feedback to tektoncd/plumbing.

@tekton-robot tekton-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Oct 15, 2021
@tekton-robot
Copy link
Contributor

Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten with a justification.
Rotten issues close after an additional 30d of inactivity.
If this issue is safe to close now please do so with /close with a justification.
If this issue should be exempted, mark the issue as frozen with /lifecycle frozen with a justification.

/lifecycle rotten

Send feedback to tektoncd/plumbing.

@tekton-robot tekton-robot added lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Nov 14, 2021
@tekton-robot
Copy link
Contributor

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen with a justification.
Mark the issue as fresh with /remove-lifecycle rotten with a justification.
If this issue should be exempted, mark the issue as frozen with /lifecycle frozen with a justification.

/close

Send feedback to tektoncd/plumbing.

@tekton-robot
Copy link
Contributor

@tekton-robot: Closed this PR.

In response to this:

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen with a justification.
Mark the issue as fresh with /remove-lifecycle rotten with a justification.
If this issue should be exempted, mark the issue as frozen with /lifecycle frozen with a justification.

/close

Send feedback to tektoncd/plumbing.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants