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

Update README and examples #8

Merged
merged 1 commit into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 112 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,128 @@
# function-go-templating
[![CI](https://github.com/crossplane-contrib/function-go-templating/actions/workflows/ci.yml/badge.svg)](https://github.com/crossplane-contrib/function-go-templating/actions/workflows/ci.yml) ![GitHub release (latest SemVer)](https://img.shields.io/github/release/crossplane-contrib/function-go-templating)

A [Crossplane] Composition Function for Golang Templating.
This [composition function][docs-functions] allows you to compose Crossplane
resources using [Go templates][go-templates]. If you've written a [Helm
chart][helm-chart] before, using this function will be a familiar experience.

## What is this?

This is a composition function which allows users to render Crossplane resources
using Go templating capabilities. With this function, users can use features like
conditionals, loops, and they can use values in the environment configs or other
resource fields to render Crossplane resources.

Currently, users can provider inputs in two different ways: inline and file system.

Here's an example of a Composition that uses a Composition Function with inline input.
Here's an example:

```yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xusers.aws.platformref.upbound.io
name: example
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: aws.platformref.upbound.io/v1alpha1
kind: XUser
apiVersion: example.crossplane.io/v1beta1
kind: XR
mode: Pipeline
pipeline:
- step: render-templates
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline: |
{{- range $i := until ( .observed.composite.resource.spec.count | int ) }}
---
apiVersion: iam.aws.upbound.io/v1beta1
kind: User
- step: create-a-bucket
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
name: test-user-{{ $i }}
labels:
testing.upbound.io/example-name: test-user-{{ $i }}
{{ if eq $.observed.resources nil }}
dummy: {{ randomChoice "foo" "bar" "baz" }}
{{ else }}
dummy: {{ ( index $.observed.resources ( print "test-user-" $i ) ).resource.metadata.labels.dummy }}
{{ end }}
{{-end}}
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: bucket
spec:
forProvider:
region: {{ .observed.composite.resource.spec.region }}
- step: automatically-detect-ready-composed-resources
functionRef:
name: function-auto-ready
```


## Using this function

This function can load templates from two sources: `Inline` and `FileSystem`.

Use the `Inline` source to specify a simple template inline in your Composition.
Multiple YAML manifests can be specified using the `---` document separator.

Use the `FileSystem` source to specify a directory of templates. The
`FileSystem` source treats all files under the specified directory as templates.

The templates are passed a [`RunFunctionRequest`][bsr] as data. This means that
you can access the composite resource, any composed resources, and the function
pipeline context using notation like:

* `{{ .observed.composite.resource.metadata.name }}`
* `{{ .desired.composite.resource.status.widgets }}`
* `{{ (index .desired.composed.resource "resource-name").spec.widgets }}`
* `{{ index .context "apiextensions.crossplane.io/environment" }}`

This function supports all of Go's [built-in template functions][builtin]. The
above examples use the `index` function to access keys like `resource-name` that
contain periods, hyphens and other special characters. Like Helm, this function
also supports [Sprig template functions][sprig].

To return desired composite resource connection details, include a template that
produces the special `CompositeConnectionDetails` resource:

```yaml
apiVersion: meta.gotemplating.fn.crossplane.io/v1alpha1
kind: CompositeConnectionDetails
data:
connection-secret-key: connection-secret-value
```

Notice that it has a `pipeline` (of Composition Functions) instead of an array
of `resources`.
To mark a desired composed resource as ready, use the
`gotemplating.fn.crossplane.io/ready` annotation:

```yaml
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: bucket
gotemplating.fn.crossplane.io/ready: True
spec: {}
```

See the [example](example) directory for examples that you can run locally using
the Crossplane CLI:

```shell
$ crossplane beta render xr.yaml composition.yaml functions.yaml
```

See the [composition functions documentation][docs-functions] to learn more
about `crossplane beta render`.

## Developing this function

This function uses [Go][go], [Docker][docker], and the [Crossplane CLI][cli] to
build functions.

```shell
# Run code generation - see input/generate.go
$ go generate ./...

# Run tests - see fn_test.go
$ go test ./...

# Build the function's runtime image - see Dockerfile
$ docker build . --tag=runtime

# Build a function package - see package/crossplane.yaml
$ crossplane xpkg build -f package --embed-runtime-image=runtime
```

[Crossplane]: https://crossplane.io
[docs-functions]: https://docs.crossplane.io/v1.14/concepts/composition-functions/
[go-templates]: https://pkg.go.dev/text/template
[helm-chart]: https://helm.sh/docs/chart_template_guide/getting_started/
[bsr]: https://buf.build/crossplane/crossplane/docs/main:apiextensions.fn.proto.v1beta1#apiextensions.fn.proto.v1beta1.RunFunctionRequest
[builtin]: https://pkg.go.dev/text/template#hdr-Functions
[sprig]: http://masterminds.github.io/sprig/
[go]: https://go.dev
[docker]: https://www.docker.com
[cli]: https://docs.crossplane.io/latest/cli
4 changes: 4 additions & 0 deletions example/filesystem/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# The `FileSystem` source

You can't run the example in this directory using `crossplane beta render`
because it loads templates from a ConfigMap. See `functions.yaml` for details.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# This composition expects to find the templates in filesystem.
# You can create a configmap and mount it using DeploymentRuntimeConfig.
# Please check the examples/functions.yaml file for an example.
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
Expand Down
27 changes: 11 additions & 16 deletions examples/functions.yaml → example/filesystem/functions.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-auto-ready
spec:
package: xpkg.upbound.io/crossplane-contrib/function-auto-ready:v0.1.0
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-go-templating
spec:
package: xpkg.upbound.io/ezgi/function-go-templating:v0.0.1 # TODO(ezgidemirel): Update package
packagePullPolicy: Always
# Please uncomment the following lines if you want to mount the templates from a config map with the following DeploymentRuntimeConfig resource.
# runtimeConfigRef:
# name: mount-templates

package: xpkg.upbound.io/crossplane-contrib/function-go-templating:v0.0.0-20231101231317-cdb49945da4e
runtimeConfigRef:
name: mount-templates
---

apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
Expand All @@ -31,12 +35,3 @@ spec:
- name: templates
configMap:
name: templates

---

apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-auto-ready
spec:
package: xpkg.upbound.io/crossplane-contrib/function-auto-ready:v0.1.0
File renamed without changes.
23 changes: 5 additions & 18 deletions examples/composition.yaml → example/inline/composition.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xusers.aws.platformref.upbound.io
name: example-inline
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: aws.platformref.upbound.io/v1alpha1
kind: XUser
apiVersion: example.crossplane.io/v1beta1
kind: XR
mode: Pipeline
pipeline:
- step: render-templates
Expand All @@ -25,7 +24,6 @@ spec:
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: test-user-{{ $i }}
name: test-user-{{ $i }}
labels:
testing.upbound.io/example-name: test-user-{{ $i }}
{{ if eq $.observed.resources nil }}
Expand All @@ -41,7 +39,6 @@ spec:
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: sample-access-key-{{ $i }}
name: sample-access-key-{{ $i }}
spec:
forProvider:
userSelector:
Expand All @@ -54,10 +51,6 @@ spec:
---
apiVersion: meta.gotemplating.fn.crossplane.io/v1alpha1
kind: CompositeConnectionDetails
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: connection-details
name: connection-details
{{ if eq $.observed.resources nil }}
data: {}
{{ else }}
Expand All @@ -67,13 +60,7 @@ spec:
url: {{ "http://www.example.com" | b64enc }}
{{ end }}
---
apiVersion: aws.platformref.upbound.io/v1alpha1
kind: XUser
metadata:
annotations:
gotemplating.fn.crossplane.io/composition-resource-name: {{ .observed.composite.resource.metadata.name }}
apiVersion: example.crossplane.io/v1beta1
kind: XR
status:
dummy: cool-status
- step: ready
functionRef:
name: function-auto-ready
6 changes: 6 additions & 0 deletions example/inline/functions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-go-templating
spec:
package: xpkg.upbound.io/crossplane-contrib/function-go-templating:v0.0.0-20231101231317-cdb49945da4e
6 changes: 6 additions & 0 deletions example/inline/xr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: example.crossplane.io/v1beta1
kind: XR
metadata:
name: example
spec:
count: 2