function-patch-and-transform

command module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2024 License: Apache-2.0 Imports: 37 Imported by: 0

README

function-patch-and-transform

CI GitHub release (latest SemVer)

This composition function does everything Crossplane's built-in patch & transform (P&T) composition does. Instead of specifying spec.resources in your Composition, you can use this function.

Using this function, P&T looks like this:

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: example
spec:
  # Omitted for brevity.
  mode: Pipeline
  pipeline:
  - step: patch-and-transform
    functionRef:
      name: function-patch-and-transform
    input:
      apiVersion: pt.fn.crossplane.io/v1beta1
      kind: Resources
      resources:
      - name: bucket
        base:
          apiVersion: s3.aws.upbound.io/v1beta1
          kind: Bucket
          spec:
            forProvider:
              region: us-east-2
        patches:
        - type: FromCompositeFieldPath
          fromFieldPath: "spec.location"
          toFieldPath: "spec.forProvider.region"
          transforms:
          - type: map
            map: 
              EU: "eu-north-1"
              US: "us-east-2"

Notice that it looks very similar to native P&T. The difference is that everything is under spec.pipeline[0].input.resources, not spec.resources. This is the Function's input.

Okay, but why?

There are a lot of good reasons to use a function to use a function to do P&T composition. In fact, it's so compelling that the Crossplane maintainers are considering deprecating native P&T. See Crossplane issue #4746 for details.

Mix and match P&T with other functions

With this function you can use P&T with other functions. For example you can create a desired resource using the Go Templating function, then patch the result using this function.

To include results from previous functions, simply provide a resources entry for each and specify a name field that matches the name of the resource from the previous function. Also, do not specify any value for the base field of each resource.

It's not just patches either. You can use P&T to derive composite resource connection details from a resource produced by another function, or use it to determine whether a resource produced by another function is ready.

Decouple P&T development from Crossplane core

When P&T development happens in a function, it's not coupled to the Crossplane release cycle. The maintainers of this function can cut releases more frequently to add new features to P&T.

It also becomes easier to fork. You could fork this function, add a new kind of transform and try it out for a few weeks before sending a PR upstream. Or, if your new feature is controversial, it's now a lot less work to maintain your own fork long term.

Test P&T locally using the Crossplane CLI

You can use the Crossplane CLI to run any function locally and see what composed resources it would create. This only works with functions - not native P&T.

For example, using the files in the example directory:

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

Produces the following output, showing what resources Crossplane would compose:

---
apiVersion: example.crossplane.io/v1
kind: XR
metadata:
  name: example-xr
---
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
metadata:
  annotations:
    crossplane.io/composition-resource-name: bucket
  generateName: example-xr-
  labels:
    crossplane.io/composite: example-xr
  ownerReferences:
    # Omitted for brevity
spec:
  forProvider:
    region: us-east-2

See the composition functions documentation to learn how to use crossplane beta render.

Differences from the native implementation

This function has a few small, intentional breaking changes compared to the native implementation.

These fields are now required. This makes P&T configuration less ambiguous:

  • resources[i].name
  • resources[i].connectionDetails[i].name
  • resources[i].connectionDetails[i].type
  • resources[i].patches[i].transforms[i].string.type
  • resources[i].patches[i].transforms[i].math.type

Also, the resources[i].patches[i].policy.mergeOptions field is no longer supported. The same capability can be achieved by setting resources[i].patches[i].policy.toFieldPath to:

  • MergeObjects - equivalent to resources[i].patches[i].policy.mergeOptions.keepMapValues: true
  • MergeObjectsAppendArrays - equivalent to resources[i].patches[i].policy.mergeOptions{keepMapValues: true, appendSlice: true}
  • ForceMergeObjects - equivalent to resources[i].patches[i].policy.mergeOptions.keepMapValues: false
  • ForceMergeObjectsAppendArrays - equivalent to resources[i].patches[i].policy.mergeOptions.appendSlice: true

Developing this function

This function uses Go, Docker, and the Crossplane CLI to build functions.

# 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

Documentation

Overview

Package main implements a Composition Function.

Directories

Path Synopsis
input
v1beta1
Package v1beta1 contains the input type for the P&T Composition Function.
Package v1beta1 contains the input type for the P&T Composition Function.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL