crossplane-contrib / function-cue Goto Github PK
View Code? Open in Web Editor NEWA crossplane function that runs cue scripts to produce desired resources
License: Apache License 2.0
A crossplane function that runs cue scripts to produce desired resources
License: Apache License 2.0
If you attempt to import a non stdlib package, for example
import (
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
corev1 "k8s.io/api/core/v1"
)
These packages will not be able to be found because the current module root /
has no packages.
This issue is to track adding this support
Potentially there could be certain set of core packages that can be generated by a function-cue contributor and stored normally in a cue.mod
folder via go get
+ cue get go
, this folder could be COPY
'd in the dockerfile and then referenced in the load.Config
https://github.com/crossplane-contrib/function-cue/blob/main/cue.go#L70. However, it would be nice if there was a way to have the user specify this, I suppose one could build their own dockerfile that reference's FROM
this dockerfile and adds its own cue.mod
additions
It may also be the case that instead of loading all of the MRs provider schemas from configmaps, that instead this repo gets the MR schemas stored into the cue mod file and loaded that way
Currently the functionality for a user to express #connectionDetails
and #readinessChecks
is at the root of the cuelang template at just #connectionDetails
and #readinessChecks
. This is more cumbersome than necessary, because this requires that the user specify a gvk+name to match the readinessCheck/connectionDetail with a specific document resource.
If we allow for these configurations to be expressed per document, this would remove the whole excess of adding the gvk+name targetting twice
Supporting this functionality
ie - current imlementation
#connectionDetails: [
{
Match: apiVersion: "example.org/v1"
Match: kind: "xkind"
metadata: name: "somename"
someConnectionDetails...etc...
}
...etc
]
#readinessChecks: [
{
Match: apiVersion: "example.org/v1"
Match: kind: "xkind"
metadata: name: "somename"
readinessCheck...etc...
}
...etc
]
output: [
{
apiVersion: "example.org/v1"
kind: "xkind"
metadata: name: "somename"
}
...
]
Desired implementation
output: [
{
apiVersion: "example.org/v1"
kind: "xkind"
metadata: name: "somename"
#connectionDetail: {
someConnectionDetails...etc
}
#readinessCheck: {
someReadinessCheck...etc
}
}
...
]
This can be achieved by
$expr.#readinessCheck
etc..yaml.MarshalStream(list.FlattenN([for e in $expr {e.#readinessCheck}], 2))
How can I inject several fields at once from the observed resource into the managed resource?
In my example, I would like to transfer everything under spec.test to the managed resource.
apiVersion: nopexample.org/v1
kind: XSubnetwork
metadata:
name: test-xrender
spec:
test:
key1: "hello"
key2: "dummy string"
karray:
- v1
- v2
key3: 5
---
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xnopresources.nop.example.org
spec:
compositeTypeRef:
apiVersion: nop.example.org/v1alpha1
kind: XNopResource
mode: Pipeline
pipeline:
- step: conditional
functionRef:
name: function-cue
input:
apiVersion: cue.fn.crossplane.io/v1beta1
kind: CUEInput
metadata:
name: patch-xr
export:
options:
inject:
- name: test
path: spec.test
target: XR
value: |
#env: string @tag("test")
name: "XRPatching"
resource: {
spec: test: #env
}
crossplane beta render xr.yaml composition.yaml function.yaml
When executing - using the function-cue - I get the following resource.
---
apiVersion: nopexample.org/v1
kind: XSubnetwork
metadata:
name: test-xrender
spec:
test: map[karray:[v1 v2] key1:hello key2:dummy string key3:%!s(float64=5)]
How can I iterate over the string "test" in Cuelang so that I get the desired output?
---
apiVersion: nopexample.org/v1
kind: XSubnetwork
metadata:
name: test-xrender
spec:
test:
key1: "hello"
key2: "dummy string"
karray:
- v1
- v2
key3: 5
Looking at the function a little more, I wonder if this would make sense:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
# Removed for Brevity
spec:
# Removed for Brevity
mode: Pipeline
pipeline:
- step: cue-export-resources
functionRef:
name: function-cue
input:
apiVersion: cue.fn.crossplane.io/v1beta1
kind: Export
export:
target: Resources
value: |
apiVersion: "s3.aws.upbound.io/v1beta1"
kind: "Bucket"
spec: forProvider: {
region: "us-east-2"
}
The idea being that the "input" to the CUE function is the export configuration. It seems like the primary field folks are working with is export
. This would match function-patch-and-transform
where you mostly work with the resources
input field, and the kind of the input is Resources
in the pt.fn.crossplane.io
API group.
This is really just a minor optimization so I could be convinced it's not worth the breaking change.
apiVersion: template.fn.crossplane.io/v1beta1
kind: CUEInput
I notice the input uses the template.fn.crossplane.io
API group. My intention was that folks would s/template/something-more-specific-to-their-function
/.
What do you think about using cue.fn.crossplane.io
instead? Not sure what kind
would be appropriate then though. We could just use Input
I suppose.
this issue is for tracking migrating this function to use cue.Context() instead of the current implementation of cueCompile
https://pkg.go.dev/cuelang.org/go/[email protected]#Context
This will allow the base Encode()
and the Compile
to function off of cue's core apis that are being built currently
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates are pending. To force PRs open, click the checkbox below.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
k8s.io/api
, k8s.io/apimachinery
)These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
Dockerfile
docker/dockerfile 1
golang 1
tools/cuemod-generator/Dockerfile
golang 1.20
.github/workflows/ci.yml
actions/checkout v4
actions/setup-go v5
golangci/golangci-lint-action v4
actions/checkout v4
actions/setup-go v5
docker/setup-qemu-action v3
docker/setup-buildx-action v3
actions/checkout v4
docker/build-push-action v5
actions/upload-artifact v4
actions/checkout v4
actions/download-artifact v4
docker/login-action v3
ubuntu 22.04
ubuntu 22.04
ubuntu 22.04
ubuntu 22.04
go.mod
go 1.21
go 1.21.3
cuelang.org/go v0.7.0
github.com/alecthomas/kong v0.8.1
github.com/crossplane/crossplane-runtime v1.15.0-rc.0.0.20231215091746-d23a82b3a2f5
github.com/crossplane/function-sdk-go v0.2.0
github.com/ghodss/yaml v1.0.0
github.com/google/go-cmp v0.6.0
github.com/stretchr/testify v1.8.4
google.golang.org/protobuf v1.32.0
k8s.io/api v0.29.2
k8s.io/apimachinery v0.29.2
k8s.io/utils v0.0.0-20240102154912-e7106e64919e@e7106e64919e
sigs.k8s.io/controller-tools v0.14.0
See the current test that is commented out
#deployment: [ID=_]: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: name: ID
spec: {
replicas: *1 | int
template: {
metadata: labels: {
app: ID
domain: "prod"
component: string
}
spec: containers: [{name: ID}]
}
}
}
#deployment: echoserver: spec: template: {
metadata: annotations: {
"prometheus.io.scrape": "true"
"prometheus.io.port": "7080"
}
metadata: labels: {
"component": "core"
}
}
#deployment.echoserver
should produce
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "echoserver"
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"annotations": {
"prometheus.io.scrape": "true",
"prometheus.io.port": "7080"
},
"labels": {
"app": "echoserver",
"domain": "prod",
"component": "core"
}
},
"spec": {
"containers": [
{
"name": "echoserver"
}
]
}
}
}
}
Run a test with this uncommented and you will see the failure
+ "failed compiling cue template: failed to encode: spec.template.m",
+ "etadata.labels.app: incomplete value string (and 2 more errors)",
there is probably some configuration that is not being set correctly in encConfig or the loadConfig. Start basing more of this implementations off of the cue/cmd/export.go intead of /play
We now have a nascent CI setup for functions. See:
If you're interested, I can open a PR to add these and create xpkg.upbound.io/crossplane-contrib/function-cue as a repo to push this to.
This issue - #79 - around injecting multiple fields is quite cumbersome and problematic for users. Allowing the EnvironmentConfigs created on Compositions to be converted into CUE and made available would alleviate this problem.
There may still be a use case for also injecting multiple nested fields as is requested in issue #79 but this seems to require a more native crossplane solution
multiple nested fields could be better alleviated with the conversion of the Environment Configs into CUE it can be injected into the build through an #Env
variable, thus allowing multiple injected variable configurations for environments
This should be fairly straightforward to do with cuecontext
support readiness checks similar to function patch and transform
Allow a means for users to specify readiness checks for the XR and also propagate readiness from the composed resources
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.