Skip to content

jcooklin/function-patch-and-transform

 
 

Repository files navigation

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.

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.

Composition functions use Kubernetes server-side apply to intelligently merge arrays and objects. This requires merge configuration to be specified at the composed resource schema level (i.e. in CRDs) per #4617.

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

About

A patch & transform composition function

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 99.6%
  • Dockerfile 0.4%