Skip to content

Reusable code/snippets #31

@fernandezcuesta

Description

@fernandezcuesta

What problem are you facing?

Inline CEL expressions might be reused by different resources in a single composition. Other functions such as function-go-templating address this with helper functions.
function-kro doesn't look to support a mechanism to reuse code.

How could this Function help solve your problem?

I can think of several options, specified by example:

Computed variables

As an example, see the following snippet where we define the ´managementPolicies´ and ´providerConfig´ once, and use it many:

input:
  apiVersion: kro.fn.crossplane.io/v1beta1
  kind: ResourceGraph
  variables:
    managementPolicies: >-
      ${schema.spec.deletionProtection
        ? ["Create", "LateInitialize", "Observe", "Update"]
        : ["Create", "Delete", "LateInitialize", "Observe", "Update"])}
    providerConfigKind: ${schema.spec.providerConfigRef.?kind.orValue("ClusterProviderConfig")}
    providerConfigName: ${schema.spec.providerConfigRef.?name.orValue("default")}
  resources:
    - id: role
      template:
        spec:
          managementPolicies: ${variables.managementPolicies}
          providerConfigRef:
            kind: ${variables.providerConfigKind}
            name: ${variables.providerConfigName}
        ...
    - ...

Registered CEL custom functions

Implementation of functions, which could be registered as CEL custom functions.

input:
  apiVersion: kro.fn.crossplane.io/v1beta1
  kind: ResourceGraph
  # List of custom functions
  functions:
    managementPolicies:
      params:
        - name: deletionProtection
          type: bool
        - name: hasImports
          type: bool
      body: >-
        deletionProtection
          ? ["Create", "LateInitialize", "Observe", "Update"]
          : ["Create", "Delete", "LateInitialize", "Observe", "Update"]
    providerConfigRef:
      params:
        - name: kind
          type: optional(string)
        - name: name
          type: optional(string)
      body:
        kind: ${kind.orValue("ClusterProviderConfig")}
        name: ${name.orValue("default")}

  resources:
    - id: role
      template:
        spec:
          managementPolicies: >-
            ${fn.managementPolicies(schema.spec.deletionProtection, has(schema.spec.imports))}
          providerConfigRef: >-
            ${fn.providerConfigRef(schema.spec.providerConfigRef.?kind, schema.spec.providerConfigRef.?name)}
          forProvider:
            ...
    - ...

or even something like the following, where after defining the functions, we might reference them for all resources in the composition:

input:
 ...
  functions: ... # same as above
  resourceDefaults:
    spec:
      managementPolicies: >-
        ${fn.managementPolicies(schema.spec.deletionProtection, has(schema.spec.imports))}
      providerConfigRef: >-
         ${fn.providerConfigRef(schema.spec.providerConfigRef.?kind, schema.spec.providerConfigRef.?name)}
  resources: ...

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