-
Notifications
You must be signed in to change notification settings - Fork 224
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
[TEP-0141] Platform Context Variables -- implementable #1087
Conversation
WG /assign @pritidesai |
1bef8ba
to
4daa7cd
Compare
|
||
## Design Details | ||
### TaskRun and PipelineRun syntax |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @afrittoli @pritidesai, it would be great if you could take a look at this section first? I want to get some early feedback on whether this proposed solution makes sense, or we need to make some changes, or seek alternatives.
Thanks!
4daa7cd
to
ab9901d
Compare
ab9901d
to
1bb0710
Compare
/assign |
1bb0710
to
3d3c6ad
Compare
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 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 |
This commit adds a design for allowing platforms to inject "context" variables as PipelineRun and TaskRun parameters.
3d3c6ad
to
c1a9ecf
Compare
metadata: | ||
name: clone-kaniko-build-push-run | ||
spec: | ||
context: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the proposal about introducing a new section called context
in pipelineRun.spec
to define platform context? How is this different from a param
section i.e. can a param repo-url
reference a context variable without defining it in a context
section?
Are there any pre-defined context variables available for the users to run with? for example, as a platform provider, I have defined (somewhere out side of a pipelineRun
) a few options for the users to choose from. The available options are:
STORAGECLASS-A: class-A,
STORAGECLASS-B: class-B,
STORAGECLASS-C: class-C
Will the pipeline author be able to utilize STORAGECLASS-A
variable and tekton controller will be able to replace this with the right value - class-A?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the proposal about introducing a new section called context in pipelineRun.spec to define platform context?
Yes. The field is used to accept the platform context. We add this field to PipelineRun.Spec, and platform can populate the values when creating the PipelineRun
Are there any pre-defined context variables available for the users to run with?
Yes. And I think this is up to the platforms if they want to have pre-defined values. They need to add code to populate those values to pipelinerun, and users can use $(context.platform.STORAGECLASS-A) to use class-A.
$(context.platform.STORAGECLASS-A) the syntax can also be customized by the platform. I added an optional section for this feature
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kind-of share the same question as @pritidesai. If the value of the context.platform
variable has to be specified in the PipelineRun
spec, what's the benefit over just using params
only ?
For me, those values should be populated outside of the PipelineRun
definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, how about putting it our of spec, and making it like this:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
name: clone-kaniko-build-push-run
context:
params:
- name: repo_url
value: https://github.com/tektoncd/pipeline
- name: image_registry
value: gcr.io/user
spec:
pipelineRef:
name: clone-kaniko-build-push
params:
- name: repo-url
value: $(context.platform.repo_url)
- name: image
value: $(context.platform.image_registry)/myapp
what's the benefit over just using params only
The benefits are: 1) platform params won't have conflicts with users' params 2) provenance generator(Chains) would be able to tell which are internal params (platform params), which are external params (users params)
- name: fetch-source | ||
params: | ||
- name: repo-url | ||
value: $(context.platform.repo_url) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is repo-url
context defined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great question. It is not defined in Pipeline
since it is a platform variable, so the pipelines used in this platform can reference to the repo_url
directly. The feature is not designed for reusable tasks, pipelines, and I have mentioned this in the design evaluation section
file name, for example, "/teps/images/NNNN-workflow.jpg". | ||
--> | ||
This TEP proposes adding support for the context variable substitutions in TaskRuns and PipelineRuns of the form `$(context.platform.foo)`, where `foo` is the name of a parameter supplied by the platform. Platforms may provide string, array, or object parameters, so TaskRuns and PipelineRuns may also use substitutions like `$(context.platform.my-array-param[*])` or `$(context.platform.my-object-param.key)`. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens when a string parameter references an array context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the same as current params? A string param references an array param will have validation errs
workspaces: | ||
- name: source-code | ||
... | ||
context: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are there any additional way of providing context
instead of or in addition to pipelineRun.context
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I may not understand this question. Are you asking alternatives of the proposed solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an exercise to reduce this proposal to the smallest TL;DR I could come up with: it's essentially a way to pass another set of parameters, but covered by RBAC (aka only allow a subset of users to use that field), am I right ?
I really think this should be limited to runtime types (aka not able to refer to context.plaftorm
variable from Pipeline
or Task
definition).
Other possible concern: What about the "size" of the object ? What if the amount of context.platform
parameters one "builder" adds make the PipelineRun
too big to be created ?
I think we should experiment with a project like #1083 and this approach to validate that our thoughts match the usage.
|
||
## Design Details | ||
### TaskRun and PipelineRun syntax |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naive question, how does a user "discover" the context.platform
variable available ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Via documentation, the vendors who want to use this would use documentation to inform users the available list of context params
metadata: | ||
name: clone-kaniko-build-push-run | ||
spec: | ||
context: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kind-of share the same question as @pritidesai. If the value of the context.platform
variable has to be specified in the PipelineRun
spec, what's the benefit over just using params
only ?
For me, those values should be populated outside of the PipelineRun
definition.
|
||
These variables will be supported for Tasks defined inline in TaskRuns or Pipelines defined inline in PipelineRuns and can be used in any Task/Pipeline fields that [currently accept variable substitutions](https://github.com/tektoncd/pipeline/blob/main/docs/variables.md#fields-that-accept-variable-substitutions). These variable substitutions will be supported in referenced remote Tasks and Pipelines as well. | ||
|
||
For example, the following example is how to reference the platform variables in remote Pipeline: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think this would be a mistake. As said below, this make Pipeline
less/not portable. It's just there to remove one (or more) parameters (explicit) and use an implicit value that might not even be there, right ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this is a mistake? This sub-feature is not designed for reusable Pipeline/Task (e.g. catalog tasks which can be used by anyone), it won't affect current reusability.
And it will add more simplicity for users who need them. Vendors will tell users this is a list of params you can use on their platform, so users can create their pipelines/tasks under the platform's context
.
How about we reach this consensus: The feature is not designed to be shared across platforms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we reach this consensus: The feature is not designed to be shared across platforms.
Yes, but we can limit the effect it has. If we allow to use those at Pipeline
/Task
definition time, we essentially allow relying on implicit value and implicitely allow "lock-in" of Pipeline
or Task
for a given vendor. And I do believe this (encouraging users to uses those in definition types) would be a mistake. Task
/ Pipeline
should be as runtime-free (and vendor-free) as possible.
### (Optional) Customized Syntax | ||
|
||
We can add a new key `default-context-variable-syntax` to current `config-defaults` config map to allow the platform operators to customize the syntax for variable substitutions. The `$(context.platform.NAME)` would be the default syntax. To use `$(NAME)` we can just change `substitution-syntax` to "$(%s)". We need validation to make sure that the customized syntax has no conflicts with current params, results and context syntax. This could be an optional work if vendors want to customize the syntax. | ||
|
||
```yaml | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: config-defaults | ||
namespace: tekton-pipelines | ||
labels: | ||
app.kubernetes.io/instance: default | ||
app.kubernetes.io/part-of: tekton-pipelines | ||
data: | ||
default-context-variable-syntax: "context.platform.%s" | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am definitely worried about that as well. It's giving way too much option to refer to those. Imaging reviewing the failing PipelineRun
from a user, that is using these kind of customization. You would need to be aware of a lot of context in addition to the spec itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to propose a general solution, and different platforms may want to have different syntax (they don't like the $(contxt.platform.foo)) How can we support that?
It's just giving option to platforms not end users to use a unified syntax, and users can review the runtime values of them in the PipelineRun.Context.Params
Platform can choose whatever syntax they want, as long as it doesn't conflict with our current variable replacements.
Anyways I think this is an optional thing, if we don't want it I'm happy to remove it from the proposal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Yongxuanzhang but this would mean, I could write a Pipeline
with a variable called $(foo.is.bar.toto)
and be very dependent on where it runs.
- Are there any implicit behaviors in the proposal? Would users expect these implicit behaviors or would they be | ||
surprising? Are there security implications for these implicit behaviors? | ||
--> | ||
This proposal requires less infrastructure for the platform builder to maintain than the alternative of a [webhook server](#webhook-responds-to-requests-for-context-parameters). It also results in a more consistent user experience for Task/Pipeline users, since all platforms that inject parameters will use the `$(context.platform.foo)` syntax rather than customized syntax. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"customized syntax" refers to what pipelineascode does, right ? (from here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, I guess so. I basically copied most of the contents from Lee's original proposal. 😄
I think if we choose to propose $(context.platform.foo)
, it indeed adds the simplicity. (I can remove my customized syntax option since it conflicts with this :/)
|
||
Consider including folks that also work on CLI and dashboard. | ||
--> | ||
With [Pipelines as Code](https://pipelinesascode.com/), a cluster operator is responsible for [installation](https://pipelinesascode.com/docs/install/operator_installation/) and configuring [connected repositories](https://pipelinesascode.com/docs/guide/repositorycrd/). This might be an infrastructure team member setting up CI/CD for their organization. Team members (CI/CD users) can then write PipelineRuns [referencing context from the connected repository](https://pipelinesascode.com/docs/guide/authoringprs/), and Pipelines as Code is responsible for creating the PipelineRun. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Configuring connected repository (aka creating the Repository
CRD) is not necessarily the responsability of a cluster operator.
|
||
## Implementation Plan | ||
### Webhook responds to requests for context parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that, technically, this proposal is doable toady, isn't it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it just have more cons
|
||
Consider including folks that also work on CLI and dashboard. | ||
--> | ||
With [Pipelines as Code](https://pipelinesascode.com/), a cluster operator is responsible for [installation](https://pipelinesascode.com/docs/install/operator_installation/) and configuring [connected repositories](https://pipelinesascode.com/docs/guide/repositorycrd/). This might be an infrastructure team member setting up CI/CD for their organization. Team members (CI/CD users) can then write PipelineRuns [referencing context from the connected repository](https://pipelinesascode.com/docs/guide/authoringprs/), and Pipelines as Code is responsible for creating the PipelineRun. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can support this in Pipelines as Code for the simple key/value we provide (ie: standard params as per screenshot)

We do have advanced use case we are introducing in the form of CEL expressions inside the expressions
openshift-pipelines/pipelines-as-code#1466
which i'd think would be useful for platform variable as well.. altho may need an API change we want to consider here (i.e: a type
field which in this case would be cel and evaluate as CEL expression)
We need as well being able to access those variables replaced from anywhere, I think there is some limitation currently where the params substitution occur on pipelinerun?
We probably want to specify what happen after remote resolver resolution occured, for example for PaaC we need to be able to do this when we are using the remote pipeline feature or remote task if there is $(context.platforms.*) variables they would be expanded after resolution..
for the foreseeable future we would have to support both form from our side but if we get features parity with platform context variable we would try to slowly make users migrate to it by generating context variable from our {{ }} variables
let me know if you want me to expand on any of those point since i am guessing it's a comment with a lot of different topics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestions and information!
We do have advanced use case we are introducing in the form of CEL expressions inside the expressions
Happy to add CEL if this proposal makes sense!
We need as well being able to access those variables replaced from anywhere, I think there is some limitation currently where the params substitution occur on pipelinerun?
Yes, this tep proposes that users can access those variables anywhere, the same as current params
. I don't think we want the limitation to only use in pipelinerun
We probably want to specify what happen after remote resolver resolution occured
After the resolution, those $(context.platforms.*) variables would be replaced. I think we mentioned this in the tep's design details section.
for the foreseeable future we would have to support both form from our side but if we get features parity with platform context variable we would try to slowly make users migrate to it by generating context variable from our {{ }} variables
It's totally up to the vendors who want to adopt this feature. For vendors who don't features like pipeline-as-code, they can use this feature to build their own params populate logic. I don't know if it makes sense for pac users to migrate to this feature.
Since it is also gated by feature flag, and the api is omit empty, it won't affect any current users if it is disabled.
At first when reading this (initial proposal) TEP I was confused between this and implicit params: https://github.com/tektoncd/community/blob/main/teps/0023-implicit-mapping.md#design-details I think we may want to explain to our users when to use context and when to use implicit params, if context is supposed to be something set by the user in her PipelineRun or something that is only going to be added by platform builders that sit on top of the PipelineRun creation (i.e pac and others). additionally and not asking for a change because i know that naming is hard, context is a over used term that may mean different things, it's really context parameters in this case. |
Thanks for the reviews!
RBAC is mainly used to restrict the updating permissions, so only platform controller can update those fields, make sure that other roles in the cluster don't have the permission. But users would be able to access those params via our variable substitution, same as current params.
What's the reason for that? We're hoping that this context param can do the same variable substitution as current
Do we currently have limitation on
I see, I'm happy to do that if the proposal makes sense to you |
Thanks!! It's very different from the implicit params(now it is tep107, propagate params), I know the naming are very similar! The implicit params or propatating params are used for inline pipelinespec, taskspec, that users don't need to specify params in their And users cannot set the proposed params, the update permission is restricted to platform via RBAC. So it is |
So the worry to have it in definition types ( |
Thanks! This is actually our use case 😢 .
This is complex to users and we want to avoid that. I know there are people like them, and some not. That's one reason we have TEP-107 for inline spec. I know the case we're discussing here is remote tasks and pipelines. But they kind like share the similar purpose It is true that this is a bit vendor lock-in because this feature is designed for vendors. Vendors have the option to use or not use this feature. Some vendors want to have the implicit variables in pipelines and tasks (convenient for end users) and they won't share them to other vendors. |
Can you describe the use case in more detail ? What make it "hard" to have to define explicit parameters for a
For me this is explicit, this might be verbose, but this is not complex. It is easy to understand, easy to follow, it's just verbose. Propagating parameters is a different "beast", it is there to reduce the duplication, on embedded task (because all is defined at the same place), but it doesn't do anything on usual
Is there anything vendor specific in Pod definition ? Or vendor specific things are coming from "elsewhere" ? If a vendor would like to apply this proposal today, how would it do ? Probably writing an admission controller that looks at the definition, and replace |
|
||
### RBAC on the Context fields | ||
|
||
This TEP proposes adding a new "context" section directly into PipelineRuns and TaskRuns, and implement our own RBAC to ensure that only authorized users can set the "context" field. For example, for the PipelineRun defined above by a PipelineRun author, the platform would submit the following PipelineRun to the Kubernetes cluster: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused, which clone-kaniko-build-push pipeline do you mean here? The one in the "Existing Workaround" or "TaskRun and PipelineRun syntax"?
Maybe it is a good idea to split inline and PipelineRef/remote pipelines scenarios to different subsections to make it easier to follow.
of the file, but general guidance is to include at least TEP number in the | ||
file name, for example, "/teps/images/NNNN-workflow.jpg". | ||
--> | ||
This TEP proposes adding support for the context variable substitutions in TaskRuns and PipelineRuns of the form `$(context.platform.foo)`, where `foo` is the name of a parameter supplied by the platform. Platforms may provide string, array, or object parameters, so TaskRuns and PipelineRuns may also use substitutions like `$(context.platform.my-array-param[*])` or `$(context.platform.my-object-param.key)`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why do we call it $(context.platform.foo)? Based on the below syntax and usage, I feel something like context.param.foo/ platform.param.foo could be better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is because our existing context variables, e.g. $(context.taskRun.name). So it has the context.LEVEL.NAME format
@Yongxuanzhang: 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. |
This commit adds a design for allowing platforms to inject "context" variables as PipelineRun and TaskRun parameters.
/kind tep