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

initial template and parameterization proposal #18215

Merged
merged 1 commit into from Feb 9, 2016

Conversation

@bparees
Copy link
Contributor

bparees commented Dec 4, 2015

@bgrant0607 @brendandburns @smarterclayton @derekwaynecarr

This is a proposal to define a syntax for authoring templates that represent k8s object topologies, while allowing those templates to be customized prior to instantiation via a parameterization mechanism.

Related discussions/template proposals:
#14918
#14993
#4210
#10408 (comment)
#11492

@googlebot googlebot added the cla: yes label Dec 4, 2015
@k8s-github-robot

This comment has been minimized.

Copy link
Contributor

k8s-github-robot commented Dec 4, 2015

Labelling this PR as size/L

@k8s-bot

This comment has been minimized.

Copy link

k8s-bot commented Dec 4, 2015

GCE e2e test build/test passed for commit 5da37eb.

@bgrant0607

This comment has been minimized.

Copy link
Member

bgrant0607 commented Dec 5, 2015

Thanks. WTAL

@bgrant0607

This comment has been minimized.

Copy link
Member

bgrant0607 commented Dec 5, 2015

cc @kubernetes/sig-config

### Use cases for templates in general

* Providing a full baked application experience in a single portable object that can be repeatably deployed in different environments.
* eg Wordpress deployment with separate standalone database pod

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

Nit: a standalone pod is an anti-pattern

This comment has been minimized.

Copy link
@bparees

bparees Dec 6, 2015

Author Contributor

you mean a pod w/o a replication controller? yeah sorry i was a bit sloppy with my language here. I was only trying to distinguish from "single pod containing both a web app an db container", not imply there wasn't also a replication controller managing the DB pod. i'll clarify in the next revision.


### Use cases for templates in general

* Providing a full baked application experience in a single portable object that can be repeatably deployed in different environments.

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

In general, bulk creation, as with List.

This comment has been minimized.

Copy link
@bparees

bparees Dec 18, 2015

Author Contributor

added bulk object creation as another bullet.

This comment has been minimized.

Copy link
@jackgr

jackgr Jan 13, 2016

Contributor

@bparees +1 because bulk creation is quite different from application specification, although the 2 use cases share some common requirements, such as parameterization and iterative expansion.


* Explicitly constructing a new template that merges the existing templates (tooling can easily be constructed to perform this
operation since the templates are first class api objects).
* Manually instantiating each template and utilizing service linking (as described in the service catalog proposal) to share

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

For others, service catalog is #17543

In addition, the template can be repeatedly instantiated for a consistent application deployment experience in different
namespaces or Kubernetes clusters.

Lastly, we propose the Template API object include a “Labels” section in which the template author can define a set of labels

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

Use cases are similar to #17097 and #15390, just with a smaller scope.

Parameters []Parameter
// Required: A list of resources to create
Objects []runtime.Object

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

FWIW, List uses Items I think.

This comment has been minimized.

Copy link
@smarterclayton

smarterclayton Dec 5, 2015

Contributor

These are objects specifically so that the objects aren't confused with lists. Objects that have nested "items" are considered lists and decomposed by our client processing. For a template, invoking create -f is more about creating an instance of the template on the server. But creating a List or PodList is not. Other ways to solve that but keeping lists semantically distinct has been helpful so far.

This comment has been minimized.

Copy link
@bgrant0607
// the Template to Config transformation.
type Parameter struct {
// Required: Parameter name must be set and it can be referenced in Template
// Items using ${PARAMETER_NAME}

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

Do you find it problematic that curly braces break yaml parsing? What do you think about using the same syntax as env var expansion $()? Since both the parameters and the env vars would be explicitly declared we could detect ambiguity.

This comment has been minimized.

Copy link
@smarterclayton

smarterclayton Dec 5, 2015

Contributor

We picked curly before we chose $( for env, so no real preference. It has not been a challenge for yaml, authors figure it out easily enough

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

Ok. I'd prefer to settle on $() as the universal substitution syntax.

This comment has been minimized.

Copy link
@bparees

bparees Dec 6, 2015

Author Contributor

fine with changing to $(). the current solution doesn't break yaml parsing because of the requirement/restriction that we only substitute string fields, which means the ${} value is always quoted.


1. Optionally set an explicit `value` for any parameter values the user wishes to explicitly set (eg non-generated parameters for
which the default value is not desired)
2. Optionally set a generator input (`from`) value to override the default input to a generator for a parameter (eg password

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

How common is that?

This comment has been minimized.

Copy link
@smarterclayton

smarterclayton Dec 5, 2015

Contributor

Pretty common for passwords or fields that have to be unique but benefit when a user picks them (like the name of the user). Presenting a default or generated value and being able to override that feels natural to users - forcing them to mutate the template in order to accomplish the same thing is irritating.


Given a well-formed template, a client will

1. Optionally set an explicit `value` for any parameter values the user wishes to explicitly set (eg non-generated parameters for

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

I'd like to be able to specify value overrides in a separate map that is passed to the processing endpoint, so that users wouldn't even necessarily have to look at a template in order to use it. They just need a simple parameter form to fill out.

This comment has been minimized.

Copy link
@bparees

bparees Dec 6, 2015

Author Contributor

this could handled via a separate endpoint which took a new object consisting of a parameter map and a template name/template reference.

it would retrieve the template, set the parameter values, and submit to the existing endpoint for substitution.

(or the existing endpoint could be extended to take this new object type and do the above work).

thoughts?

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Jan 13, 2016

Member

One possibility would be to leverage my proposal for PetSet: #18016 (comment)

If we thought users might not want a persistent object capturing their parameter values (though that usually seems desirable to me), I'd leverage my existence-dependency proposal (#1535 (comment)) to make the ParameterizedSet get deleted automatically when the resources generated by it were deleted.

Otherwise, yes, a separate API endpoint would work. The workflow would be:

  • GET the template
  • substitute the values in the parameter list
  • perform template substitution
  • create the fully expanded resources

*It should be possible to validate templates and template parameters, both values and the schema.*

* Template objects are subject to standard api validation.

This comment has been minimized.

Copy link
@smarterclayton

smarterclayton Dec 5, 2015

Contributor

Except when the value does not validate - such as replacement in names ($( is not valid)

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

We should be able to validate the template field names.

As for values, if we had jsonschema-like validation specifications for parameters and/or for the resource fields, we could validate the values to some degree.

This comment has been minimized.

Copy link
@bparees

bparees Dec 6, 2015

Author Contributor

Except when the value does not validate - such as replacement in names ($( is not valid)

we don't validate the objects within the template definition, they are just runtime.Object, right? i'm just saying the template api object is validated as such, not that the things it contains are validated as whatever type they are. that does not happen (and as you note, really can't happen until after substitution happens. This situation will be even worse once we add support for substitution into integer fields)

* Customize cross-component references (eg user provides the name of a secret that already exists in their namespace, to use in
a pod as a TLS cert).
* Provide guidance to users for parameters such as default values, descriptions, and whether or not a particular parameter value
is required or can be left blank.

This comment has been minimized.

Copy link
@smarterclayton

smarterclayton Dec 5, 2015

Contributor

Parameterize the replica count of a deployment or PetSet
Parameterize at least part of the labels and selector for a DaemonSet.

This comment has been minimized.

Copy link
@bparees

bparees Dec 6, 2015

Author Contributor

keeping in mind that parameterizing replica counts requires addressing the current "string only substitution" limitation. I was trying to restrict the use cases to ones solved by the proposal. if we agree on how we want to add generic type substitution to this proposal, we can certainly add other use cases that are solved with it.

This comment has been minimized.

Copy link
@sparkprime

sparkprime Dec 16, 2015

It's definitely a valid use case and one that can be achieved with several of the options on the table so I think it should be included.

This comment has been minimized.

Copy link
@bparees

bparees Dec 18, 2015

Author Contributor

parameter types other than string are now supported by this proposal.

* Currently only string fields can be parameterized. See discussion [here](https://github.com/openshift/origin/issues/3946) for some proposed
solutions. (tldr: a syntax like ${FOO | int} could instruct the template processor to convert the json field to an integer when doing the
substitution. This could also support secret generation by using a syntax like `${FOO | base64}` which would take the value of parameter
`$FOO` and base64 encode it before setting the json field to the resulting value)

This comment has been minimized.

Copy link
@smarterclayton

smarterclayton Dec 5, 2015

Contributor

Definitely need a solution for this. Functor pipelines start to increase the complexity of the proposal and the line between template and language gets blurry.

@bgrant0607

This comment has been minimized.

Copy link
Member

bgrant0607 commented Dec 5, 2015

I think we need something like this.

Kubernetes is about automating operations:
https://github.com/kubernetes/kubernetes/blob/master/docs/whatisk8s.md

Templates could also be used for a new generation of controllers #14961, like PetSet #18016, replacing the original idea of just pod templates #170.

We also have at least half a dozen cases in flight where we need parameter substitution.

solutions. (tldr: a syntax like ${FOO | int} could instruct the template processor to convert the json field to an integer when doing the
substitution. This could also support secret generation by using a syntax like `${FOO | base64}` which would take the value of parameter
`$FOO` and base64 encode it before setting the json field to the resulting value)
* Another option would be to add type information to the parameter definitions, making it slightly easier to reference a parameter within a

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

Can't we use the swagger to get the type?

This comment has been minimized.

Copy link
@bparees

bparees Dec 8, 2015

Author Contributor

only if template processing becomes schema aware which it currently is not. will add it as an option.

*It shouldn't be inordinately difficult to evolve templates. Thus, strategies such as versioning and encapsulation should be
encouraged, at least by convention.*

* Templates are an api object and as such can be evolved and versioned along with the rest of the Kubernetes api.

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Dec 5, 2015

Member

I meant that individual templates should be versioned. But that's possible with this proposal, by convention.

This comment has been minimized.

Copy link
@bparees

bparees Dec 6, 2015

Author Contributor

ah. yes, annotations on the template object could be used for that purpose.

@bparees

This comment has been minimized.

Copy link
Contributor Author

bparees commented Dec 8, 2015

@bgrant0607 @smarterclayton addressed some of your comments, in particular changed to the $() syntax and added making template processing schema aware to the list of ways to address typed parameter substitution.

I have not addressed @bgrant0607's request to support a map of parameter values + template for instantiation, i'd like to see a little more discussion on the use case for that given that we've so far not seen a need for it in openshift. blind submission of parameter key/value pairs for a template seems likely to lead to failure for a user.

@k8s-bot

This comment has been minimized.

Copy link

k8s-bot commented Dec 8, 2015

GCE e2e test build/test passed for commit 2d0df64.

* Utilizes multiple files with different syntax to define an application topology.
* Does not define a first class API object.
* Does not appear to natively offer generation logic for producing parameter values.

This comment has been minimized.

Copy link
@jackgr

jackgr Dec 8, 2015

Contributor

The preceding statements about DM are inaccurate. Please read the DM documentation at https://github.com/kubernetes/deployment-manager, including the contents of the docs folder, and correct these statements.

This comment has been minimized.

Copy link
@bparees

bparees Dec 8, 2015

Author Contributor

Utilizes multiple files with different syntax to define an application topology.

this example uses 4 files including both yaml and jinja formats: https://github.com/kubernetes/deployment-manager/tree/master/examples/wordpress

the docs also indicate templates can be written in python. none of the examples/formats match k8s api objects/syntax.

Does not define a first class API object.

see above, what DM defines/consumes is not a first class k8s api object. Perhaps there's some confusion in what i meant by api object, I did not mean that DM doesn't define an api for itself, I meant it does not define api objects that are consumed by k8s. I can clarify this statement.

Does not appear to natively offer generation logic for producing parameter values.

I understand DM has parameters, i don't see native logic for defining how a parameter value should be generated (eg generate a random password). Presumably it's possible to make that happen via jinja or python, but I wouldn't consider that native support within DM, hence my statement. Again, I can clarify this to indicate value generation is deferred to jinja/python.

If I am still not understanding the design of DM, I'm afraid I'm going to need you to be more explicit about what is inaccurate/what I have misunderstood.

This comment has been minimized.

Copy link
@jackgr

jackgr Dec 8, 2015

Contributor

DM defines a single template usage format. It's a YAML based list of resource, each of which contains a name, type and parameters. True, the template definition can be written either in Jinja, which is simply marked up YAML, or Python, which produces YAML. A Jinja template for a k8s primitive is easily recognizable as a k8s configuration file with mustache markup.

Also, there's no requirement to use both languages in a single example, or to use multiple files, so both assertions are inaccurate.

DM can also take vanilla k8s configuration files as input. And, when a template is expanded, the result is always a flat list of vanilla k8s configuration files, which is readily accessible via the API.

DM doesn't define a k8s API object specifically because a native implementation baked into k8s has been discouraged by the preceding discussion. If that has somehow changed, we could easily make a DM template a native API object. However, we believe there are good reasons not to do that, not least of which is the well established precedent of publishing content in registries, rather than in runtimes. That said, when a configuration is deployed using DM, it is capture and stored in the cluster, providing a record of the deployment, including the parameters and expansion results.

If by native support for generation logic, you mean hard wired, as opposed to programmable, then no, DM doesn't have hard wired generators. We consider hard wired implementations to be an anti-pattern, in general.

This comment has been minimized.

Copy link
@bparees

bparees Dec 10, 2015

Author Contributor

Also, there's no requirement to use both languages in a single example, or to use multiple files, so both assertions are inaccurate.

is it possible to write a single file, in k8s-compatible json syntax, which provides parameterization? That is what is achieved by the openshift template schema, and what I am trying to distinguish here as a desirable trait. Whether an example can be created which doesn't need additional syntax or files isn't really my point, the question is whether the full power of DM can be realized without branching out into multiple files and multiple syntaxes (above and beyond the k8s syntax).

My impression is that the answer is no. Is it a desirable goal (single file, k8s syntax, api object)? in my opinion, based on the user experience we have been able to deliver in openshift by integrating templates as a first class concept, is that it is, but I think we'll be hashing that out in the syntax/schema discussion once I update this PR per our discussion yesterday.

Regarding parameter generation, I agree with the concerns about it being compiled into the runtime and it would be nice to make it more flexible. On the other hand, by being a little opinionated here, we provided a generation function that covers probably 70% of the use cases for parameter generation (no one has come to us so far asking for additional generation functionality) in an extremely consumable format that minimizes complexity or requirements to learn new languages.

* Provide a management mechanism for deleting/uninstalling an entire set of components related to a single deployed application
* As a developer I want to select the template to use from a list of available templates
* Enabling the creation of user interfaces that can guide an application deployer through the deployment process with descriptive help about the configuration value decisions they are making, and useful default values where appropriate

This comment has been minimized.

Copy link
@jackgr

jackgr Dec 8, 2015

Contributor

Additional use case:

  • Capturing the topology of an application from template expansion as metadata within the cluster, so that
    • visualizations can be provided that expose application structure,
    • developers can inspect a cluster to determine what's running in it,
    • tools can use the metadata to aggregate and analyze signals.

This comment has been minimized.

Copy link
@bparees

bparees Dec 10, 2015

Author Contributor

is
"* Exporting a set of objects in a namespace as a template so the topology can be inspected/visualized or recreated in another environment"

a fair summary of that?

This comment has been minimized.

Copy link
@bgrant0607

bgrant0607 Jan 4, 2016

Member

Note that application topology could be captured by labels and/or annotations, as well, without templates.

@bparees

This comment has been minimized.

Copy link
Contributor Author

bparees commented Feb 8, 2016

@bgrant0607: comments addressed in latest commit.

@k8s-bot

This comment has been minimized.

Copy link

k8s-bot commented Feb 8, 2016

GCE e2e test build/test passed for commit 246fd71.

@bgrant0607

This comment has been minimized.

Copy link
Member

bgrant0607 commented Feb 9, 2016

LGTM. Please rebase, run hack/update-generated-docs.sh, and squash, and then I'll apply the label for merging.

@bparees bparees force-pushed the bparees:templates branch 2 times, most recently from 88cd5de to a2b5112 Feb 9, 2016
@bparees bparees force-pushed the bparees:templates branch from a2b5112 to 89a6561 Feb 9, 2016
@bparees

This comment has been minimized.

Copy link
Contributor Author

bparees commented Feb 9, 2016

@bgrant0607 done.

@k8s-teamcity-mesosphere

This comment has been minimized.

Copy link

k8s-teamcity-mesosphere commented on 89a6561 Feb 9, 2016

TeamCity OSS :: Kubernetes Mesos :: 4 - Smoke Tests Build 15061 outcome was SUCCESS
Summary: Tests passed: 1, ignored: 225 Build time: 00:03:59

This comment has been minimized.

Copy link

k8s-teamcity-mesosphere replied Feb 9, 2016

TeamCity OSS :: Kubernetes Mesos :: 4 - Smoke Tests Build 15062 outcome was SUCCESS
Summary: Tests passed: 1, ignored: 225 Build time: 00:03:56

@k8s-bot

This comment has been minimized.

Copy link

k8s-bot commented Feb 9, 2016

GCE e2e test build/test passed for commit a2b5112.

@k8s-bot

This comment has been minimized.

Copy link

k8s-bot commented Feb 9, 2016

GCE e2e test build/test passed for commit 89a6561.

@bgrant0607 bgrant0607 added the lgtm label Feb 9, 2016
@bgrant0607

This comment has been minimized.

Copy link
Member

bgrant0607 commented Feb 9, 2016

LGTM!

@k8s-github-robot

This comment has been minimized.

Copy link
Contributor

k8s-github-robot commented Feb 9, 2016

Automatic merge from submit-queue

k8s-github-robot added a commit that referenced this pull request Feb 9, 2016
Auto commit by PR queue bot
@k8s-github-robot k8s-github-robot merged commit 33636a3 into kubernetes:master Feb 9, 2016
5 checks passed
5 checks passed
Jenkins GCE e2e 226 tests run, 106 skipped, 0 failed.
Details
Jenkins unit/integration 2724 tests run, 9 skipped, 0 failed.
Details
Submit Queue Queued to run github e2e tests a second time.
Details
cla/google All necessary CLAs are signed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@bparees

This comment has been minimized.

Copy link
Contributor Author

bparees commented Feb 9, 2016

thanks @bgrant0607. Hopefully we can find some people to start the implementation come early march.

@jimmycuadra

This comment has been minimized.

Copy link
Member

jimmycuadra commented Feb 25, 2016

Not sure if this is the best place to discuss this now that the proposal has been merged or whether or I should start a new issue, but:

I've started on a CLI tool that attempts to implement client-side template processing using the format described in this proposal. You can find the program at https://github.com/InQuicker/ktmpl. It's written in Rust, but the details of the source code are not really important for discussion.

There are a few issues I've coming across while working on this implementation (some minor, some more significant):

  • The example shown in the proposal is not valid JSON. (Extra comma, I think?)
  • The example shown in the proposal uses the default value "password" for the parameter "MONGODB_USER" which is confusing and initially made me think my program was putting values in the wrong place until I went back and looked at the original text.
  • The example shown in the proposal does not include interpolations that cover all the cases described elsewhere in the proposal. I know it's just an example and not a comprehensive test suite, but without a more detailed specification, there wasn't much else to go on. Specifically, there are no examples of the two types of interpolation combined in one value, and there aren't examples of each of the types of interpolation surrounded by literal text.
  • ktmpl only supports YAML for now, since it's for my company's use specifically and our manifests will only be in YAML. When using the non-quoted interpolation, the type of the resulting value may be ambiguous without making ParameterType mandatory. If the template processor is implemented using simple text substitution, it may not be a problem to just output the value as a string without quotes and let the Kubernetes API figure it out, but in my case I'm actually walking the YAML document and transforming string values that include the interpolation syntax into their final type. Since the decision of whether or value will have quotes around it or not comes from the data type, there are cases (e.g. true vs. "true") where I'd need to know during substitution what the final type should be.
  • The comment above the ParameterType field says "one of string, int, bool, or base64" but that list doesn't quite make sense. Neither YAML nor JSON have a native base64 type (it'd just be a string) and a simple "int" does not cover how numbers are represented in either YAML or JSON. In YAML, there are many more number types, and it's unclear if or why a non-integer number should be rejected. In JSON, all numbers are the same type, so specifying "int" either seems like a mistake or implies some additional validation beyond what the the serialization format can represent.
  • The meaning of the Required field for a parameter is not well explained. It seems like it could be inferred from whether or not there is a default Value specified in the manifest. Or is Required supposed to indicate whether or not a literal null is acceptable?
@bparees

This comment has been minimized.

Copy link
Contributor Author

bparees commented Feb 25, 2016

thanks for the feedback, i've pushed fixes to the syntactical issues here:
#21981

Specifically, there are no examples of the two types of interpolation combined in one value

I believe there is:
// if both types of substitution exist, quoting is performed:

somefield: "prefix_$((FOO))_$(FOO)_suffix"  ->  somefield: "prefix_BAR_BAR_suffix"

and there aren't examples of each of the types of interpolation surrounded by literal text.

there can't be such an example because the format precludes using literal text (by which I assume you mean unquoted text). That's the purpose of the $(()) syntax, to strip the quotes where appropriate.

When using the non-quoted interpolation, the type of the resulting value may be ambiguous without making ParameterType mandatory. If the template processor is implemented using simple text substitution, it may not be a problem to just output the value as a string without quotes and let the Kubernetes API figure it out, but in my case I'm actually walking the YAML document and transforming string values that include the interpolation syntax into their final type.

There is an inherent assumption that the user who put the $() or $(()) reference into the field understood the type of the field and used the correct syntax/type. The purpose of the type field on the parameter definition is to allow clients to guide users with providing a value, not to aid in the actual substitution logic.

The comment above the ParameterType field says "one of string, int, bool, or base64" but that list doesn't quite make sense. Neither YAML nor JSON have a native base64 type (it'd just be a string) and a simple "int" does not cover how numbers are represented in either YAML or JSON.

"int" was probably overly shorthand(ie we should include other types), but the point of "base64" is again that this is intended to hint to the user of the template how the value is going to be used. Telling them the type is base64 tells them they need to provide a base64 encoded value for this parameter. The fact that ultimately that base64 value gets plugged in as a json string isn't relevant.

The meaning of the Required field for a parameter is not well explained. It seems like it could be inferred from whether or not there is a default Value specified in the manifest. Or is Required supposed to indicate whether or not a literal null is acceptable?

Required is intended to indicate that null/empty string is not an acceptable value for this parameter. The parameter must have a non-empty value either provided via the default, or provided by the user. I will update this in the above PR as well.

@jimmycuadra

This comment has been minimized.

Copy link
Member

jimmycuadra commented Feb 25, 2016

Thank you, @bparees, that was very helpful! Your changes in that PR do well to clarify the things that tripped me up.

When I said "there are no examples of the two types of interpolation combined in one value and there aren't examples of each of the types of interpolation surrounded by literal text," I meant that the example template doesn't include those forms, so you don't see them in a realistic context and you can't use that example as a very complete test case. That's a minor issue, though, and I can adjust for my own needs.

Thanks again!

@jolestar

This comment has been minimized.

Copy link
Contributor

jolestar commented Sep 5, 2017

Not sure if this is the best place to ask that the proposal has been merged, but I can not find the progress of this proposal's implement anywhere. How about this proposal?

@bparees

This comment has been minimized.

Copy link
Contributor Author

bparees commented Sep 5, 2017

@jolestar it has not been implemented and at this point seems unlikely to be.

@bgrant0607

This comment has been minimized.

Copy link
Member

bgrant0607 commented Sep 5, 2017

@jolestar A client-based implementation is mentioned above: https://github.com/InQuicker/ktmpl

Openshift also has an implementation.

I agree with @bparees that it is unlikely to be implemented at this point.

My current thinking on this and related topics is here:
https://goo.gl/T66ZcD

@jolestar

This comment has been minimized.

Copy link
Contributor

jolestar commented Sep 6, 2017

Thank you @bparees @bgrant0607 for reply

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.