CEL for function inputs
johnbelamaric opened this issue · 0 comments
In the value propagation pattern description, a Starlark function is used to construct values from input sources, and then the apply replacements function is used to copy those throughout the package. That works, but the UX is a bit painful, and having to write a function to do concatenation in the manner of setters is painful.
In #3396 #3155 there is a lot of discussion of the needs and troubles. One thing I am thinking about for this is CEL. In the PackageVariantSet implementation I used CEL to allow variance of the PackageVariant resources as they are fanned out across targets. Similarly, in the extension of this to work with the PackageVariant Pipeline editing, I am enabling CEL for function inputs of the functions being added to the pipeline.
There is no reason that this cannot be plumbed all the way down through to the Kptfile. In that case, in addition to the configMap in the function inputs, we would have a []MapExpr
called configMapExpr
, just like this. These are used to calculate config map entries, which overlay the static entries.
In the Kptfile, we could enable navigation of the ResourceList by chained maps. For example, a map byName
would be indexed by resource name, byKind
would be indexed by kind, etc., and you could chain them to get to a value. So, to access the replicas field of a deployment named 'foo' could be accessed any of these ways:
byName["foo"].spec.replicas
if I know it is uniquely namedbyKind["Deployment"].spec.replicas
if I know there is only one DeploymentbyKind["Deployment"].byName["foo"].spec.replicas
if I need both to qualifybyAPIVersion["v1"].byKind["Deployment"].byName["foo"].spec.replicas
if there could be other groups with that kind and name in this package- etc.
with it being an error if you try to resolved spec
and there is more than one entry still in the selection list.
This allows us to very simply reference any field in any resource in the entire package and use it as an input. We can define some convenience variable names also - for example, kptfile
and context
for the Kptfile and PackageContext resources. And since it's an expression, you can manipulate it however you need. For example, this pipeline would copy the region
entry from the context to a label, and ensure that all resource names are prefixed with the package name:
pipeline:
mutators:
- image: gcr.io/kpt-fn/set-labels:v0.2.0
configMapExprs:
- key: nephio.org/region
valueExpr: context.region
- image: gcr.io/kpt-fn/ensure-name-substring:v0.2.0
configMapExprs:
- key: prepend
valueExpr: context.name + '-'
Of course, as written here, it doesn't help for function configs that are not config maps - but we should be able to use something like search-replace by-path along with this in that case, which will still be simpler than Starlark.
Now, I would also extend this to PackageVariant and PackageVariantSet, such that the expressions in those resources could use successive resolution of variables and be passed on down through. That is, the expression defined in PVS could contain PVS variables, PV variables, and Package (Kptfile) variables. Any unresolved variables in the PVS expressions would be passed to PV in the expressions of the generated PV, which would in turn pass any unresolved expressions down to the Kptfile.
Thoughts?