Skip to content

Provide a way to easily manage custom helpers in templates #168

@dukanto

Description

@dukanto

What problem are you facing?

Sometimes, when developing a composition that creates several MRs (or multiple compositions, for the case), you'll find yourself creating some helper functions in every definition, leading to having the same helper templates over and over on your compositions.
You could try and create a template and use it in FileSystem mode, but then you'll need a pod running for each different object you want to create.

Imagine, for instance:

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: example-function-to-yaml
spec:
  compositeTypeRef:
    apiVersion: example.crossplane.io/v1beta1
    kind: XR
  mode: Pipeline
  pipeline:
    - step: render-deployment-1
      functionRef:
        name: function-go-templating
      input:
        apiVersion: gotemplating.fn.crossplane.io/v1beta1
        kind: GoTemplate
        source: Inline
        inline:
          template: |
            # Defining helper
            {{- define "labels" -}}
            some-text: {{.val1}}
            other-text: {{.val2}}
            {{- end }}
            ---
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: nginx-deployment-1
              annotations:
                gotemplating.fn.crossplane.io/composition-resource-name: test1
              labels:
                {{- include "labels" $vals | nindent 4}}
            spec:
              replicas: 3
              selector:
                matchLabels:
                  {{- include "labels" $vals | nindent 6}}
              [...]

    - step: render-deployment-2
      functionRef:
        name: function-go-templating
      input:
        apiVersion: gotemplating.fn.crossplane.io/v1beta1
        kind: GoTemplate
        source: Inline
        inline:
          template: |
            # Defining helper again
            {{- define "labels" -}}
            some-text: {{.val1}}
            other-text: {{.val2}}
            {{- end }}
            ---
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: nginx-deployment-2
              annotations:
                gotemplating.fn.crossplane.io/composition-resource-name: test2
              labels:
                {{- include "labels" $vals | nindent 4}}
            spec:
              replicas: 3
              selector:
                matchLabels:
                  {{- include "labels" $vals | nindent 6}}
              [...]

As you can see, you are defining "labels" everytime.

How could this Function help solve your problem?

Perhaps, by having some kind of mix, where you could include a helpers path in the FS and then using your inline function on top of that, we can have the best of both ways.
Something like this I think could be a nice approach:

    - step: render-deployment-1
      functionRef:
        name: function-go-templating
      input:
        apiVersion: gotemplating.fn.crossplane.io/v1beta1
        kind: GoTemplate
        source: Inline
        # load all helpers from this directory (which can be loaded into an image)
        helpers:
           dirPath: /helpers
        inline:
          template: |
            ---
            apiVersion: apps/v1
            kind: Deployment
            metadata:
              name: nginx-deployment-1
              annotations:
                gotemplating.fn.crossplane.io/composition-resource-name: test1
              labels:
                {{- include "labels" $vals | nindent 4}}
            spec:
              replicas: 3
              selector:
                matchLabels:
                  {{- include "labels" $vals | nindent 6}}
              [...]

Let me know if this could be interesting and I am happy to put a PR in place to implement it :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions