Skip to content

Commit

Permalink
support both, XRD Pkl file and XRD Yaml file to Pkl Module conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
Avarei committed Jun 19, 2024
1 parent e426080 commit a26baf8
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 15 deletions.
58 changes: 45 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,28 +42,41 @@ spec:
see [examples](./example/)
### Building a new Composition Function from Scratch
#### Create a XRD
If you already have an XRD skip this and the next section.
Most Crossplane resources can be Converted to Pkl.
> Note: In Pkl there is a difference between CRDs which are Modules vs. amending CRD itself.
> the latter can be rendered to yaml and applied to Clusters.
- [Composite Resource Definitions](#create-a-composite-resource-definition-xrd-in-pkl) (XRD) can be created in Pkl
- Pkl XRDs can be [converted to Modules](#create-a-module-of-your-xrd)
- Yaml XRDs can also be converted to Modules
- CRDs/Managed Resources can be converted to Pkl
- Compositions themselves must be created in Yaml
- The CompositionFunction Pkl file
#### Create a Composite Resource Definition (XRD) in Pkl
Create a new Pkl file
```pkl
amends "package://pkg.pkl-lang.org/github.com/crossplane-contrib/function-pkl/[email protected]#/CompositeResourceDefinition.pkl"
```
the Pkl file can be rendered as Yaml using `pkl eval <nameOfYourPklFile>.pkl`

#### Create a Module of your XRD
#### Create a Module of your XRD (from Pkl)
To Convert the XRD.pkl to Pkl Module a small helper file `xrd2module.pkl` is needed:
```pkl
amends "package://pkg.pkl-lang.org/github.com/crossplane-contrib/function-pkl/[email protected]#/generate.pkl"
// To convert from a Yaml file uncomment the following section
// source = "./XR.yaml"
crds {
import("XR.pkl")
}
// To convert from a Pkl file uncomment the following section
// crds {
// import("XR.pkl")
// }
k8sImportPath = "@k8s"
crossplaneImportPath = "@crossplane.contrib"
// The Package references to be used within the Module
k8sImportPath = "@k8s" // package://pkg.pkl-lang.org/pkl-k8s/[email protected]#
crossplaneImportPath = "@crossplane.contrib" // package://pkg.pkl-lang.org/github.com/crossplane-contrib/function-pkl/crossplane.contrib
```

running `pkl eval generate.pkl -m .` will generate a new Module that can be imported and referenced in the Composition.

#### Create Managed Resources in Pkl
Expand Down Expand Up @@ -109,9 +122,28 @@ desired {
}
```
#### Create Composition
TODO.


```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: function-pkl
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: XR
mode: Pipeline
pipeline:
- step: run-the-template
functionRef:
name: function-pkl
input:
apiVersion: template.fn.crossplane.io/v1beta1
kind: Pkl
spec:
type: uri
# This pkl file is at `pkl/crossplane-example/full.pkl` in this repo
uri: "package://pkg.pkl-lang.org/github.com/crossplane-contrib/function-pkl/[email protected]#/full.pkl"
```
## Building a Pkl Package
A Pkl Package can be built in the following steps:
Expand Down
33 changes: 31 additions & 2 deletions pkl/crossplane.contrib.xrd/generate.pkl
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,16 @@ import "pkl:semver"

import "internal/ModuleGenerator.pkl"
import "CompositeResourceDefinition.pkl"
import "pkl:platform"
import "pkl:yaml"
import "@uri/URI.pkl"
import "@deepToTyped/deepToTyped.pkl"

/// The version of the Pkl Kubernetes package to import.
///
/// This property is not used if [k8sImportPath] is set directly.
k8sVersion: String(semver.isValid(this)) = "1.0.1"
crossplaneVersion: String(semver.isValid(this)) = "0.0.0"
crossplaneVersion: String(semver.isValid(this)) = "1.0.0"

/// The base path to use for the Kubernetes imports.
///
Expand All @@ -82,12 +86,37 @@ k8sImportPath: String = "package://pkg.pkl-lang.org/pkl-k8s/k8s@\(k8sVersion)#"

crossplaneImportPath: String = "package://pkg.pkl-lang.org/github.com/crossplane-contrib/function-pkl/crossplane.contrib@\(crossplaneVersion)#"

/// Where to find the CRDs; can be a URI (`https:`, `file:` etc), an absolute file path, or a relative file path
source: String = read?("prop:source") ?? ""

local sourceUri =
if (source.startsWith(Regex(#"\w+:"#))) source // absolute URI
else if (source.startsWith("/")) "file://\(source)" // absolute file path
else // relative file path
let (pwd = read("env:PWD"))
let (path =
if (platform.current.operatingSystem.name == "Windows") "/\(pwd)/\(source)".replaceAll("\\", "/")
else "\(pwd)/\(source)"
)
"file://\(URI.encode(path))"

/// The CRD's source contents, as computed from [source].
sourceContents: String|Resource = read(URI.encode(sourceUri))

/// Whether to log out every path we find in each CRD to aid in setting converters.
///
/// Default: `false`.
logPaths: Boolean? = read?("prop:logPaths")?.toBoolean()

crds: Listing<CompositeResourceDefinition>
crds: Listing<CompositeResourceDefinition> =
let (parser = new yaml.Parser { useMapping = true })
new {
for (crd in parser.parseAll(sourceContents)) {
when (crd is Mapping && crd.getOrNull("kind") == CompositeResourceDefinition.kind) {
deepToTyped.apply(CompositeResourceDefinition.getClass(), crd) as CompositeResourceDefinition
}
}
}

/// Type conversions when generating property types.
///
Expand Down

0 comments on commit a26baf8

Please sign in to comment.