This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Generators

Included resource generators

This section provides documentation about the generic resource generators shipped with component-operator-runtime

1 - Kustomize Generator

A resource generator for kustomizations

This generator allows to generate the manifests of the component’s resources from a given kustomization. As a special case, one or more simple Kubernetes manifests (without a kustomization.yaml) are supported as well. In addition, all (or selected; see below) files in the kustomization directory can be templatized in a helm’ish way. That means, they will be considered as a common template group (where all templates are associated with each other), and the same template function set that is available on Helm can be used; so, all the sprig functions, and custom functions such as include, tpl, lookup can be used. In addition:

  • parameterless functions namespace and name are defined, which return the corresponding arguments passed to Generate()
  • a function kubernetesVersion is available, which returns the version information of the target cluster, as a version.Info structure.

In the generation step, first, all the go templates will be rendered, and the result of this pre-step will be passed to kustomize.

A kustomize generator can be instantiated by calling the following constructor:

package kustomize

func NewKustomizeGenerator(
  fsys fs.FS,
  kustomizationPath string,
  templateSuffix string,
  client client.Client
) (*KustomizeGenerator, error) {

Here:

  • fsys must be an implementation of fs.FS, such as embed.FS; or it can be passed as nil; then, all file operations will be executed on the current OS filesystem.
  • kustomizationPath is the directory containing the (potentially templatized) kustomatization; if fsys was provided, this has to be a relative path; otherwise, it will be interpreted with respect to the OS filesystem (as an absolute path, or relative to the current working directory of the controller).
  • templateSuffx is optional; if empty, all files under kustomizationPath will be subject to go templating; otherwise, only files matching the specified suffix will be considered as templates.
  • client should be a client for the local cluster (i.e. the cluster where the component object exists).

As of now, the specified kustomization must not reference files or paths outside kustomizationPath. Remote references are generally not supported.

2 - Helm Generator

A resource generator for Helm charts

Sometimes it is desired to write a component operator (using component-operator-runtime) for some cluster component, which already has a productive Helm chart. Then it can make sense to use the HelmGenerator implementation of the Generator interface included in this module:

package helm

func NewHelmGenerator(
  fsys                  fs.FS,
  chartPath             string,
  client                client.Client,
) (*HelmGenerator, error)

Here:

  • fsys must be an implementation of fs.FS, such as embed.FS; or it can be passed as nil; then, all file operations will be executed on the current OS filesystem.
  • chartPath is the directory containing the used Helm chart; if fsys was provided, this has to be a relative path; otherwise, it will be interpreted with respect to the OS filesystem (as an absolute path, or relative to the current working directory of the controller).
  • client should be a client for the local cluster (i.e. the cluster where the component object exists).

It should be noted that HelmGenerator does not use the Helm SDK; instead it tries to emulate the Helm behavior as good as possible. A few differences and restrictions arise from this:

  • Not all Helm template functions are supported. To be exact, toToml, fromYamlArray, fromJsonArray are not supported; the functions toYaml, fromYaml, toJson, fromJson are supported, but will behave more strictly in error situtations.
  • Not all builtin variables are supported; the following restrictions apply:
    • for the .Release builtin, only .Release.Namespace, .Release.Name, .Release.Service, .Release.IsInstall, .Release.IsUpgrade are supported; note that - since this framework does not really distinguish between installations and upgrades - Release.IsInstall is always set to true, and Release.IsUpgrade is always set to false
    • for the .Chart builtin, only .Chart.Name, .Chart.Version, .Chart.Type, .Chart.AppVersion, .Chart.Dependencies are supported
    • for the .Capabilities builtin, only .Capabilities.KubeVersion and .Capabilities.APIVersions are supported
    • the .Template builtin is fully supported
    • the .Files builtin is not supported at all.
  • Regarding hooks, pre-delete and post-delete hooks are not allowed; test and rollback hooks are ignored, and pre-install, post-install, pre-upgrade, post-upgrade hooks might be handled in a sligthly different way; hook weights will be handled in a compatible way; hook deletion policy hook-failed is not allowed, but before-hook-creation and hook-succeeded should work as expected.

3 - Enhance Existing Generators

How to derive generators from existing generators

In some cases it is desirable to modify the behaviour of an existing generator by transforming the input parameters passed to the generation step, or by transforming the object manifests returned by the generation step. This can be achieved by wrapping an existing generator into a

package manifests

type TransformableGenerator interface {
  Generator
  WithParameterTransformer(transformer ParameterTransformer) TransformableGenerator
  WithObjectTransformer(transformer ObjectTransformer) TransformableGenerator
}

object tby calling

package manifests

func NewGenerator(generator Generator) TransformableGenerator

The generator obtained this way can now be extended by calling its methods WithParameterTransformer() and WithObjectTransformer(). The actual modification logic happens by implementing the respective interfaces

package manifests

type ParameterTransformer interface {
  TransformParameters(parameters types.Unstructurable) (types.Unstructurable, error)
}

type ObjectTransformer interface {
  TransformObjects(objects []client.Object) ([]client.Object, error)
}