This section provides documentation about the generic resource generators shipped with component-operator-runtime
This is the multi-page printable view of this section. Click here to print.
Generators
1 - Kustomize Generator
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 well-known template function set that is available in Helm can be used; that is, all the sprig functions, plus functions like include
, tpl
, lookup
, plus further functions are supported:
Function name | Description |
---|---|
toYaml <input any> | Encode input to YAML string. |
mustToYaml <input any> | Same as toYaml . |
fromYaml <input string> | Parse YAML string to object. |
mustFromYaml <input string> | Same as fromYaml . |
fromYamlArray <input string> | Parse YAML string to array. |
mustFromYamlArray <input string> | Same as fromYamlArray . |
toJson <input any> | Encode input to JSON string. |
mustToJson <input any> | Same as toJson . |
toPrettyJson <input any> | Encode object to pretty JSON string. |
mustToPrettyJson <input any> | Same as toPrettyJson . |
toRawJson <input any> | Encode input to JSON string with no escaping of HTML characters. |
mustToRawJson <input any> | Same as toRawJson . |
fromJson <input string> | Parse JSON string to object. |
mustFromJson <input string> | Same as fromJson . |
fromJsonArray <input string> | Parse JSON string to array. |
mustFromJsonArray <input string> | Same as fromJsonArray . |
required <warn string, input any> | Fail with the given error message if the input is nil or can be converted to an empty string. |
bitwiseShiftLeft <by any, input any> | Perform a bitwise left shift on the input by the given number of places. |
bitwiseShiftRight <by any, input any> | Perform a bitwise right shift on the input by the given number of places. |
bitwiseAnd <input ...any> | Perform a bitwise logical ‘and’ on the inputs. |
bitwiseOr <input ...any> | Perform a bitwise logical ‘or’ on the inputs. |
bitwiseXor <input ...any> | Perform a bitwise logical ‘xor’ on the inputs. |
parseIPv4Address <input any> | Convert a string representation of an IPv4 address into a 32 bit integer. |
formatIPv4Address <input any> | Convert a 32 bit integer representation of an IPv4 address into a string. |
include <name string, input any> | Render the given named template with the input as data values. |
tpl <template string, input any> | Render the given template string with the input as data values. |
lookup <apiVersion string, kind string, namespace string, name string> | Lookup a Kubernetes resource with the target client; return nil in case of 404 (not found) errors. |
mustLookup <apiVersion string, kind string, namespace string, name string> | Lookup a Kubernetes resource with the target client; fail in case of 404 (not found) errors. |
localLookup <apiVersion string, kind string, namespace string, name string> | Lookup a Kubernetes resource with the local client; return nil in case of 404 (not found) errors. |
mustLocalLookup <apiVersion string, kind string, namespace string, name string> | Lookup a Kubernetes resource with the local client; fail in case of 404 (not found) errors. |
lookupWithKubeConfig <apiVersion string, kind string, namespace string, name string kubeConfig string> | Lookup a Kubernetes resource with the given kubeconfig; return nil in case of 404 (not found) errors. |
mustLookupWithKubeConfig <apiVersion string, kind string, namespace string, name string, kubeConfig string> | Lookup a Kubernetes resource with the given kubeconfig; fail in case of 404 (not found) errors. |
listFiles <pattern string> | List files relative to the provided kustomization directory, matching the given pattern. |
existsFile <path string> | Check if the given file path exists, relative to the provided kustomization directory. |
readFile <path string> | Read the given file, relative to the provided kustomization directory. |
namespace | Return the deployment namespace as passed to the generator. |
name | Return the deployment name as passed to the generator. |
kubernetesVersion | Return a *version.Info struct containing Kubernetes version details about the deployment target. |
apiResources | Return a slice of []*metav1.APIResourceList structs containing Kubernetes API discovery details about the deployment target. |
Notes:
- in case a function is provided by sprig and by us, our implementation is used
- all functions (unless otherwise stated) make the using template fail in case of errors
- as for the lookup functions, the target client points to the deployment target, the local client points to the cluster where the executing controller is running.
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,
clnt client.Client,
options KustomizeGeneratorOptions
) (*KustomizeGenerator, error) {
Here:
fsys
must be an implementation offs.FS
, such asembed.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; iffsys
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).clnt
should be a client for the local cluster (i.e. the cluster where the component object exists).options
allows to tweak the generator:package kustomize type KustomizeGeneratorOptions struct { // If defined, only files with that suffix will be subject to templating. TemplateSuffix *string // If defined, the given left delimiter will be used to parse go templates; // otherwise, defaults to '{{' LeftTemplateDelimiter *string // If defined, the given right delimiter will be used to parse go templates; // otherwise, defaults to '}}' RightTemplateDelimiter *string }
The generator options can be overridden on source level by creating a file
.component-config.yaml
in the specifiedkustomizationPath
; the file can contain JSON or YAML, compatible with theKustomizeGeneratorOptions
struct.
As of now, the specified kustomization must not reference files or paths outside kustomizationPath
. Remote references are generally not supported.
By default, all .yaml
or .yml
files in kustomizationPath
, and its subdirectories, are subject to templating, and are considered if a kustomization.yaml
is auto-generated. It is possible to exclude certain files by creating a file .component-ignore
in kustomizationPath
; this .component-ignore
file uses
the common .gitignore
syntax.
2 - Helm Generator
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,
clnt client.Client,
) (*HelmGenerator, error)
Here:
fsys
must be an implementation offs.FS
, such asembed.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; iffsys
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).clnt
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
is not supported; all other functions should be supported, but may 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 totrue
, andRelease.IsUpgrade
is always set tofalse
- 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 supported but does not return any of the paths reserved by Helm (such asChart.yaml
,templates/
and so on)
- for the
- Regarding hooks,
pre-delete
andpost-delete
hooks are not allowed; test and rollback hooks are ignored, andpre-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 policyhook-failed
is not allowed, butbefore-hook-creation
andhook-succeeded
should work as expected. - The
.helmignore
file is currently not evaluated; in particular, files can be accessed through.Files
altough they are listed in.helmignore
.
3 - Enhance 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)
}