Documentation ¶
Overview ¶
Package framework contains a framework for writing functions in Go. The function specification is defined at: https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md
Functions are executables that generate, modify, delete or validate Kubernetes resources. They are often used used to implement abstractions ("kind: JavaSpringBoot") and cross-cutting logic ("kind: SidecarInjector").
Functions may be run as standalone executables or invoked as part of an orchestrated pipeline (e.g. kustomize).
Example function implementation using framework.SimpleProcessor with a struct input
import ( "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" ) type Spec struct { Value string `yaml:"value,omitempty"` } type Example struct { Spec Spec `yaml:"spec,omitempty"` } func runFunction(rlSource *kio.ByteReadWriter) error { functionConfig := &Example{} fn := func(items []*yaml.RNode) ([]*yaml.RNode, error) { for i := range items { // modify the items... } return items, nil } p := framework.SimpleProcessor{Config: functionConfig, Filter: kio.FilterFunc(fn)} err := framework.Execute(p, rlSource) return errors.Wrap(err) }
Architecture ¶
Functions modify a slice of resources (ResourceList.Items) which are read as input and written as output. The function itself may be configured through a functionConfig (ResourceList.FunctionConfig).
Example function input:
kind: ResourceList items: - kind: Deployment ... - kind: Service .... functionConfig: kind: Example spec: value: foo
The functionConfig may be specified declaratively and run with
kustomize fn run DIR/
Declarative function declaration:
kind: Example metadata: annotations: # run the function by creating this container and providing this # Example as the functionConfig config.kubernetes.io/function: | container: image: image/containing/function:impl spec: value: foo
The framework takes care of serializing and deserializing the ResourceList.
Generated ResourceList.functionConfig -- ConfigMaps Functions may also be specified imperatively and run using:
kustomize fn run DIR/ --image image/containing/function:impl -- value=foo
When run imperatively, a ConfigMap is generated for the functionConfig, and the command arguments are set as ConfigMap data entries.
kind: ConfigMap data: value: foo
To write a function that can be run imperatively on the commandline, have it take a ConfigMap as its functionConfig.
Mutator and Generator Functions ¶
Functions may add, delete or modify resources by modifying the ResourceList.Items slice.
Validator Functions ¶
A function may emit validation results by setting the ResourceList.Result ¶
Configuring Functions ¶
Functions may be configured through a functionConfig (i.e. a client-side custom resource), or through flags (which the framework parses from a ConfigMap provided as input).
Functions may also access environment variables set by the caller.
Building a container image for the function ¶
The go program may be built into a container and run as a function. The framework can be used to generate a Dockerfile to build the function container.
# create the ./Dockerfile for the container $ go run ./main.go gen ./ # build the function's container $ docker build . -t gcr.io/my-project/my-image:my-version
Index ¶
- Constants
- func ContainerNameMatcher(names ...string) func(node *yaml.RNode) bool
- func Execute(p ResourceListProcessor, rlSource *kio.ByteReadWriter) error
- func LoadFunctionConfig(src *yaml.RNode, api interface{}) error
- func SchemaFromFunctionDefinition(gvk resid.Gvk, data string) (*spec.Schema, error)
- type AndSelector
- type ContainerPatchTemplate
- type Defaulter
- type Field
- type File
- type FilterProvider
- type FilterProviderFunc
- type GVKFilterMap
- type KRMFunctionDefinition
- type KRMFunctionNames
- type KRMFunctionValidation
- type KRMFunctionVersion
- type KrmFunctionDefinitionSpec
- type OrSelector
- type PatchTemplate
- type ResourceList
- type ResourceListProcessor
- type ResourceListProcessorFunc
- type ResourceMatcher
- type ResourceMatcherFunc
- type ResourcePatchTemplate
- type ResourceTemplate
- type ResourceTemplateMatcher
- func APIVersionMatcher(names ...string) ResourceTemplateMatcher
- func AnnotationMatcher(ann map[string]string) ResourceTemplateMatcher
- func GVKMatcher(names ...string) ResourceTemplateMatcher
- func KindMatcher(names ...string) ResourceTemplateMatcher
- func LabelMatcher(labels map[string]string) ResourceTemplateMatcher
- func NameMatcher(names ...string) ResourceTemplateMatcher
- func NamespaceMatcher(names ...string) ResourceTemplateMatcher
- type Result
- type Results
- type SchemaParser
- type SchemaParserFunc
- type Selector
- type Severity
- type SimpleProcessor
- type TemplateParser
- type TemplateParserFunc
- type TemplateProcessor
- type TemplatedMetaMapMatcher
- type TemplatedMetaSliceMatcher
- type ValidationSchemaProvider
- type Validator
- type VersionedAPIProcessor
Examples ¶
- Selector (TemplatizeAnnotations)
- Selector (TemplatizeKinds)
- SimpleProcessor (GenerateReplace)
- SimpleProcessor (Modify)
- TemplateProcessor (Container_patch)
- TemplateProcessor (Container_patch_by_name)
- TemplateProcessor (Generate_files)
- TemplateProcessor (Generate_inline)
- TemplateProcessor (Patch)
- TemplateProcessor (Postprocess)
- TemplateProcessor (Preprocess)
- VersionedAPIProcessor
Constants ¶
const FunctionDefinitionGroupVersion = "config.kubernetes.io/v1alpha1"
const FunctionDefinitionKind = "KRMFunctionDefinition"
Variables ¶
This section is empty.
Functions ¶
func ContainerNameMatcher ¶ added in v0.10.14
ContainerNameMatcher returns a function that returns true if the "name" field of the provided container node matches one of the given container names. If no names are provided, the function always returns true. Note that this is not a ResourceMatcher, since the node it matches against must be container-level (e.g. "name", "env" and "image" would be top level fields).
func Execute ¶ added in v0.10.14
func Execute(p ResourceListProcessor, rlSource *kio.ByteReadWriter) error
Execute is the entrypoint for invoking configuration functions built with this framework from code. See framework/command#Build for a Cobra-based command-line equivalent. Execute reads a ResourceList from the given source, passes it to a ResourceListProcessor, and then writes the result to the target. STDIN and STDOUT will be used if no reader or writer respectively is provided.
func LoadFunctionConfig ¶ added in v0.10.14
LoadFunctionConfig reads a configuration resource from YAML into the provided data structure and then prepares it for use by running defaulting and validation on it, if supported. ResourceListProcessors should use this function to load ResourceList.functionConfig.
func SchemaFromFunctionDefinition ¶ added in v0.13.4
SchemaFromFunctionDefinition extracts the schema for a particular GVK from the provided KRMFunctionDefinition Since the relevant fields of KRMFunctionDefinition exactly match the ones in CustomResourceDefinition, this helper can also load CRDs (e.g. produced by KubeBuilder) transparently.
Types ¶
type AndSelector ¶ added in v0.10.14
type AndSelector struct { // Matchers is the list of ResourceMatchers to try on the input resources. Matchers []ResourceMatcher // TemplateData, if present, is used to initialize any matchers that implement // ResourceTemplateMatcher. TemplateData interface{} // FailOnEmptyMatch makes the selector return an error when no items are selected. FailOnEmptyMatch bool }
OrSelector is a kio.Filter that selects resources when that match all of its embedded matchers.
func MatchAll ¶ added in v0.10.14
func MatchAll(matchers ...ResourceMatcher) *AndSelector
MatchAll is a shorthand for building an AndSelector from a list of ResourceMatchers.
func (*AndSelector) DefaultTemplateData ¶ added in v0.10.14
func (s *AndSelector) DefaultTemplateData(data interface{})
DefaultTemplateData makes AndSelector a ResourceTemplateMatcher. Although it does not contain templates itself, this allows it to support ResourceTemplateMatchers when being used as a matcher itself.
func (*AndSelector) Filter ¶ added in v0.10.14
Filter implements kio.Filter, returning only those items from the list that the selector matches.
func (*AndSelector) InitTemplates ¶ added in v0.10.14
func (s *AndSelector) InitTemplates() error
type ContainerPatchTemplate ¶ added in v0.10.1
type ContainerPatchTemplate struct { // Templates provides a list of templates to render into one or more patches that apply at the container level. // For example, "name", "env" and "image" would be top-level fields in container patches. Templates TemplateParser // Selector targets the rendered patches to containers within specific resources. // If no Selector is provided, all resources with containers will be patched (subject to // ContainerMatcher, if provided). // // Although any Filter can be used, this framework provides several especially for Selector use: // framework.Selector, framework.AndSelector, framework.OrSelector. You can also use any of the // framework's ResourceMatchers here directly. Selector kio.Filter // TemplateData is the data to use when rendering the templates provided by the Templates field. TemplateData interface{} // ContainerMatcher targets the rendered patch to only those containers it matches. // For example, it can be used with ContainerNameMatcher to patch only containers with // specific names. If no ContainerMatcher is provided, all containers will be patched. // // The node passed to ContainerMatcher will be container-level, not a full resource node. // For example, "name", "env" and "image" would be top level fields. // To filter based on resource-level context, use the Selector field. ContainerMatcher func(node *yaml.RNode) bool }
ContainerPatchTemplate defines a patch to be applied to containers
func (*ContainerPatchTemplate) DefaultTemplateData ¶ added in v0.10.14
func (cpt *ContainerPatchTemplate) DefaultTemplateData(data interface{})
DefaultTemplateData sets TemplateData to the provided default values if it has not already been set.
func (ContainerPatchTemplate) Filter ¶ added in v0.10.14
Filter applies the ContainerPatchTemplate to the appropriate resources in the input. First, it applies the Selector to identify target resources. Then, it renders the Templates into patches using TemplateData. Finally, it identifies target containers and applies the patches.
type Defaulter ¶ added in v0.10.2
type Defaulter interface {
Default() error
}
Defaulter is implemented by APIs to have Default invoked. The standard application is to create a type to hold your FunctionConfig data, and implement Defaulter on that type. All of the framework's processors will invoke Default() on your type after unmarshalling the FunctionConfig data into it.
type Field ¶
type Field struct { // Path is the field path. This field is required. Path string `yaml:"path,omitempty" json:"path,omitempty"` // CurrentValue is the current field value CurrentValue interface{} `yaml:"currentValue,omitempty" json:"currentValue,omitempty"` // ProposedValue is the proposed value of the field to fix an issue. ProposedValue interface{} `yaml:"proposedValue,omitempty" json:"proposedValue,omitempty"` }
Field references a field in a resource
type File ¶
type File struct { // Path is relative path to the file containing the resource. // This field is required. Path string `yaml:"path,omitempty" json:"path,omitempty"` // Index is the index into the file containing the resource // (i.e. if there are multiple resources in a single file) Index int `yaml:"index,omitempty" json:"index,omitempty"` }
File references a file containing a resource
type FilterProvider ¶ added in v0.10.14
type FilterProvider interface { // ProviderFor returns the appropriate filter for the given APIVersion and Kind. ProviderFor(apiVersion, kind string) (kio.Filter, error) }
FilterProvider is implemented by types that provide a way to look up which Filter should be used to process a ResourceList based on the ApiVersion and Kind of the ResourceList.functionConfig in the input. FilterProviders are intended to be used as part of VersionedAPIProcessor.
type FilterProviderFunc ¶ added in v0.10.14
FilterProviderFunc converts a compatible function to a FilterProvider.
func (FilterProviderFunc) ProviderFor ¶ added in v0.10.14
func (f FilterProviderFunc) ProviderFor(apiVersion, kind string) (kio.Filter, error)
ProviderFor makes FilterProviderFunc implement FilterProvider.
type GVKFilterMap ¶ added in v0.10.14
GVKFilterMap is a FilterProvider that resolves Filters through a simple lookup in a map. It is intended for use in VersionedAPIProcessor.
func (GVKFilterMap) ProviderFor ¶ added in v0.10.14
func (m GVKFilterMap) ProviderFor(apiVersion, kind string) (kio.Filter, error)
ProviderFor makes GVKFilterMap implement the FilterProvider interface. It uses the given apiVersion and kind to do a simple lookup in the map and returns an error if no exact match is found.
type KRMFunctionDefinition ¶ added in v0.13.4
type KRMFunctionDefinition struct { // APIVersion and Kind of the object. Must be config.kubernetes.io/v1alpha1 and KRMFunctionDefinition respectively. yaml.TypeMeta `yaml:",inline" json:",inline"` // Standard KRM object metadata yaml.ObjectMeta `yaml:"metadata,omitempty" json:"metadata,omitempty"` // Spec contains the properties of the KRM function this object defines. Spec KrmFunctionDefinitionSpec `yaml:"spec" json:"spec"` }
KRMFunctionDefinition is metadata that defines a KRM function the same way a CRD defines a custom resource. https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/2906-kustomize-function-catalog#function-metadata-schema
type KRMFunctionNames ¶ added in v0.13.4
type KRMFunctionNames struct { // Kind is the kind of the defined KRM Function. It is normally CamelCase and singular. Kind string `yaml:"kind" json:"kind"` }
type KRMFunctionValidation ¶ added in v0.13.4
type KRMFunctionVersion ¶ added in v0.13.4
type KRMFunctionVersion struct { // // The following fields are shared with CustomResourceDefinition. // // Name is the version name, e.g. “v1”, “v2beta1”, etc. Name string `yaml:"name" json:"name"` // Schema describes the schema of this version of the KRM function. // This can be used for validation, pruning, and/or defaulting. Schema *KRMFunctionValidation `yaml:"schema,omitempty" json:"schema,omitempty"` // // The following fields are custom to KRMFunctionDefinition // // Idempotent indicates whether the function can be re-run multiple times without changing the result. Idempotent bool `yaml:"idempotent,omitempty" json:"idempotent,omitempty"` // Usage is URI pointing to a README.md that describe the details of how to use the KRM function. // It should at least cover what the function does and should give a detailed explanation about each // field used to configure it. Usage string `yaml:"usage,omitempty" json:"usage,omitempty"` // A list of URIs that point to README.md files. Each README.md should cover an example. // It should at least cover how to get input resources, how to run it and what is the expected // output. Examples []string `yaml:"examples,omitempty" json:"examples,omitempty"` // License is the name of the license covering the function. License string `yaml:"license,omitempty" json:"license,omitempty"` // The maintainers for this version of the function, if different from the primary maintainers. Maintainers []string `yaml:"maintainers,omitempty" json:"maintainers,omitempty"` // The runtime information describing how to execute this function. Runtime runtimeutil.FunctionSpec `yaml:"runtime" json:"runtime"` }
type KrmFunctionDefinitionSpec ¶ added in v0.13.4
type KrmFunctionDefinitionSpec struct { // // The following fields are shared with CustomResourceDefinition. // // Group is the API group of the defined KRM function. Group string `yaml:"group" json:"group"` // Names specify the resource and kind names for the KRM function. Names KRMFunctionNames `yaml:"names" json:"names"` // Versions is the list of all API versions of the defined KRM function. Versions []KRMFunctionVersion `yaml:"versions" json:"versions"` // // The following fields are custom to KRMFunctionDefinition // // Description briefly describes the KRM function. Description string `yaml:"description,omitempty" json:"description,omitempty"` // Publisher is the entity (e.g. organization) that produced and owns this KRM function. Publisher string `yaml:"publisher,omitempty" json:"publisher,omitempty"` // Home is a URI pointing the home page of the KRM function. Home string `yaml:"home,omitempty" json:"home,omitempty"` // Maintainers lists the individual maintainers of the KRM function. Maintainers []string `yaml:"maintainers,omitempty" json:"maintainers,omitempty"` // Tags are keywords describing the function. e.g. mutator, validator, generator, prefix, GCP. Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"` }
type OrSelector ¶ added in v0.10.14
type OrSelector struct { // Matchers is the list of ResourceMatchers to try on the input resources. Matchers []ResourceMatcher // TemplateData, if present, is used to initialize any matchers that implement // ResourceTemplateMatcher. TemplateData interface{} // FailOnEmptyMatch makes the selector return an error when no items are selected. FailOnEmptyMatch bool }
OrSelector is a kio.Filter that selects resources when that match at least one of its embedded matchers.
func MatchAny ¶ added in v0.10.14
func MatchAny(matchers ...ResourceMatcher) *OrSelector
MatchAny is a shorthand for building an OrSelector from a list of ResourceMatchers.
func (*OrSelector) DefaultTemplateData ¶ added in v0.10.14
func (s *OrSelector) DefaultTemplateData(data interface{})
DefaultTemplateData makes OrSelector a ResourceTemplateMatcher. Although it does not contain templates itself, this allows it to support ResourceTemplateMatchers when being used as a matcher itself.
func (*OrSelector) Filter ¶ added in v0.10.14
Filter implements kio.Filter, returning only those items from the list that the selector matches.
func (*OrSelector) InitTemplates ¶ added in v0.10.14
func (s *OrSelector) InitTemplates() error
type PatchTemplate ¶ added in v0.10.0
type PatchTemplate interface { // Filter is a kio.Filter-compliant function that applies PatchTemplate's templates as patches // on the given resource nodes. Filter(items []*yaml.RNode) ([]*yaml.RNode, error) // DefaultTemplateData accepts default data to be used in template rendering when no template // data was explicitly provided to the PatchTemplate. DefaultTemplateData(interface{}) }
PatchTemplate is implemented by kio.Filters that work by rendering patches and applying them to the given resource nodes.
type ResourceList ¶
type ResourceList struct { // Items is the ResourceList.items input and output value. // // e.g. given the function input: // // kind: ResourceList // items: // - kind: Deployment // ... // - kind: Service // ... // // Items will be a slice containing the Deployment and Service resources // Mutating functions will alter this field during processing. // This field is required. Items []*yaml.RNode `yaml:"items" json:"items"` // FunctionConfig is the ResourceList.functionConfig input value. // // e.g. given the input: // // kind: ResourceList // functionConfig: // kind: Example // spec: // foo: var // // FunctionConfig will contain the RNodes for the Example: // kind: Example // spec: // foo: var FunctionConfig *yaml.RNode `yaml:"functionConfig,omitempty" json:"functionConfig,omitempty"` // Results is ResourceList.results output value. // Validating functions can optionally use this field to communicate structured // validation error data to downstream functions. Results Results `yaml:"results,omitempty" json:"results,omitempty"` }
ResourceList is a Kubernetes list type used as the primary data interchange format in the Configuration Functions Specification: https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md This framework facilitates building functions that receive and emit ResourceLists, as required by the specification.
func (*ResourceList) Filter ¶ added in v0.10.14
func (rl *ResourceList) Filter(api kio.Filter) error
Filter executes the given kio.Filter and replaces the ResourceList's items with the result. This can be used to help implement ResourceListProcessors. See SimpleProcessor for example.
Filters that return a Result as error will store the result in the ResourceList and continue processing instead of erroring out.
type ResourceListProcessor ¶ added in v0.10.14
type ResourceListProcessor interface {
Process(rl *ResourceList) error
}
ResourceListProcessor is implemented by configuration functions built with this framework to conform to the Configuration Functions Specification: https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md To invoke a processor, pass it to framework.Execute, which will also handle ResourceList IO.
This framework provides several ready-to-use ResourceListProcessors, including SimpleProcessor, VersionedAPIProcessor and TemplateProcessor. You can also build your own by implementing this interface.
type ResourceListProcessorFunc ¶ added in v0.10.14
type ResourceListProcessorFunc func(rl *ResourceList) error
ResourceListProcessorFunc converts a compatible function to a ResourceListProcessor.
func (ResourceListProcessorFunc) Process ¶ added in v0.10.14
func (p ResourceListProcessorFunc) Process(rl *ResourceList) error
Process makes ResourceListProcessorFunc implement the ResourceListProcessor interface.
type ResourceMatcher ¶ added in v0.10.14
type ResourceMatcher interface { // kio.Filter applies the matcher to multiple resources. // This makes individual matchers usable as selectors directly. kio.Filter // Match returns true if the given resource matches the matcher's configuration. Match(node *yaml.RNode) bool }
ResourceMatcher is implemented by types designed for use in or as selectors.
type ResourceMatcherFunc ¶ added in v0.10.14
ResourceMatcherFunc converts a compliant function into a ResourceMatcher
type ResourcePatchTemplate ¶ added in v0.10.14
type ResourcePatchTemplate struct { // Templates provides a list of templates to render into one or more patches. Templates TemplateParser // Selector targets the rendered patches to specific resources. If no Selector is provided, // all resources will be patched. // // Although any Filter can be used, this framework provides several especially for Selector use: // framework.Selector, framework.AndSelector, framework.OrSelector. You can also use any of the // framework's ResourceMatchers here directly. Selector kio.Filter // TemplateData is the data to use when rendering the templates provided by the Templates field. TemplateData interface{} }
ResourcePatchTemplate applies a patch to a collection of resources
func (*ResourcePatchTemplate) DefaultTemplateData ¶ added in v0.10.14
func (t *ResourcePatchTemplate) DefaultTemplateData(data interface{})
DefaultTemplateData sets TemplateData to the provided default values if it has not already been set.
func (ResourcePatchTemplate) Filter ¶ added in v0.10.14
Filter applies the ResourcePatchTemplate to the appropriate resources in the input. First, it applies the Selector to identify target resources. Then, it renders the Templates into patches using TemplateData. Finally, it identifies applies the patch to each resource.
type ResourceTemplate ¶ added in v0.10.14
type ResourceTemplate struct { // Templates provides a list of templates to render into one or more resources. Templates TemplateParser // TemplateData is the data to use when rendering the templates provided by the Templates field. TemplateData interface{} }
ResourceTemplate generates resources from templates.
func (*ResourceTemplate) DefaultTemplateData ¶ added in v0.10.14
func (rt *ResourceTemplate) DefaultTemplateData(data interface{})
DefaultTemplateData sets TemplateData to the provided default values if it has not already been set.
type ResourceTemplateMatcher ¶ added in v0.10.14
type ResourceTemplateMatcher interface { // ResourceMatcher makes matchers usable in or as selectors. ResourceMatcher // DefaultTemplateData is used to pass default template values down a chain of matchers. DefaultTemplateData(interface{}) // InitTemplates is used to render the templates in selectors that support // ResourceTemplateMatcher. The selector should call this exactly once per filter // operation, before beginning match comparisons. InitTemplates() error }
ResourceTemplateMatcher is implemented by ResourceMatcher types that accept text templates as part of their configuration.
func APIVersionMatcher ¶ added in v0.10.14
func APIVersionMatcher(names ...string) ResourceTemplateMatcher
APIVersionMatcher matches resources whose kind is equal to one of the provided values. e.g. `APIVersionMatcher("foo/v1", "bar/v1")` matches if `apiVersion` is either "foo/v1" or "bar/v1".
APIVersionMatcher supports templating. e.g. `APIVersionMatcher("{{.TargetAPI}}")` will match `apiVersion` "foo/v1" if TemplateData is `struct{ TargetAPI string }{ TargetAPI: "foo/v1" }`
func AnnotationMatcher ¶ added in v0.10.14
func AnnotationMatcher(ann map[string]string) ResourceTemplateMatcher
AnnotationMatcher matches resources that are annotated with all of the provided key-value pairs. e.g. `AnnotationMatcher(map[string]string{"app": "foo", "env": "prod"})` matches resources annotated app=foo AND env=prod.
AnnotationMatcher supports templating. e.g. `AnnotationMatcher(map[string]string{"app": "{{ .AppName}}"})` will match label app=foo if TemplateData is `struct{ AppName string }{ AppName: "foo" }`
func GVKMatcher ¶ added in v0.10.14
func GVKMatcher(names ...string) ResourceTemplateMatcher
GVKMatcher matches resources whose API group, version and kind match one of the provided values. e.g. `GVKMatcher("foo/v1/Widget", "bar/v1/App")` matches if `apiVersion` concatenated with `kind` is either "foo/v1/Widget" or "bar/v1/App".
GVKMatcher supports templating. e.g. `GVKMatcher("{{.TargetAPI}}")` will match "foo/v1/Widget" if TemplateData is `struct{ TargetAPI string }{ TargetAPI: "foo/v1/Widget" }`
func KindMatcher ¶ added in v0.10.14
func KindMatcher(names ...string) ResourceTemplateMatcher
KindMatcher matches resources whose kind is equal to one of the provided values. e.g. `KindMatcher("foo", "bar")` matches if `kind` is either "foo" or "bar".
KindMatcher supports templating. e.g. `KindMatcher("{{.TargetKind}}")` will match `kind` "foo" if TemplateData is `struct{ TargetKind string }{ TargetKind: "foo" }`
func LabelMatcher ¶ added in v0.10.14
func LabelMatcher(labels map[string]string) ResourceTemplateMatcher
LabelMatcher matches resources that are labelled with all of the provided key-value pairs. e.g. `LabelMatcher(map[string]string{"app": "foo", "env": "prod"})` matches resources labelled app=foo AND env=prod.
LabelMatcher supports templating. e.g. `LabelMatcher(map[string]string{"app": "{{ .AppName}}"})` will match label app=foo if TemplateData is `struct{ AppName string }{ AppName: "foo" }`
func NameMatcher ¶ added in v0.10.14
func NameMatcher(names ...string) ResourceTemplateMatcher
NameMatcher matches resources whose metadata.name is equal to one of the provided values. e.g. `NameMatcher("foo", "bar")` matches if `metadata.name` is either "foo" or "bar".
NameMatcher supports templating. e.g. `NameMatcher("{{.AppName}}")` will match `metadata.name` "foo" if TemplateData is `struct{ AppName string }{ AppName: "foo" }`
func NamespaceMatcher ¶ added in v0.10.14
func NamespaceMatcher(names ...string) ResourceTemplateMatcher
NamespaceMatcher matches resources whose metadata.namespace is equal to one of the provided values. e.g. `NamespaceMatcher("foo", "bar")` matches if `metadata.namespace` is either "foo" or "bar".
NamespaceMatcher supports templating. e.g. `NamespaceMatcher("{{.AppName}}")` will match `metadata.namespace` "foo" if TemplateData is `struct{ AppName string }{ AppName: "foo" }`
type Result ¶
type Result struct { // Message is a human readable message. This field is required. Message string `yaml:"message,omitempty" json:"message,omitempty"` // Severity is the severity of this result Severity Severity `yaml:"severity,omitempty" json:"severity,omitempty"` // ResourceRef is a reference to a resource. // Required fields: apiVersion, kind, name. ResourceRef *yaml.ResourceIdentifier `yaml:"resourceRef,omitempty" json:"resourceRef,omitempty"` // Field is a reference to the field in a resource this result refers to Field *Field `yaml:"field,omitempty" json:"field,omitempty"` // File references a file containing the resource this result refers to File *File `yaml:"file,omitempty" json:"file,omitempty"` // Tags is an unstructured key value map stored with a result that may be set // by external tools to store and retrieve arbitrary metadata Tags map[string]string `yaml:"tags,omitempty" json:"tags,omitempty"` }
ResultItem defines a validation result
type Results ¶ added in v0.13.0
type Results []*Result
type SchemaParser ¶ added in v0.10.20
type SchemaParser interface {
Parse() ([]*spec.Definitions, error)
}
type SchemaParserFunc ¶ added in v0.10.20
type SchemaParserFunc func() ([]*spec.Definitions, error)
func (SchemaParserFunc) Parse ¶ added in v0.10.20
func (s SchemaParserFunc) Parse() ([]*spec.Definitions, error)
type Selector ¶ added in v0.10.0
type Selector struct { // Names is a list of metadata.names to match. If empty match all names. // e.g. Names: ["foo", "bar"] matches if `metadata.name` is either "foo" or "bar". Names []string `json:"names" yaml:"names"` // Namespaces is a list of metadata.namespaces to match. If empty match all namespaces. // e.g. Namespaces: ["foo", "bar"] matches if `metadata.namespace` is either "foo" or "bar". Namespaces []string `json:"namespaces" yaml:"namespaces"` // Kinds is a list of kinds to match. If empty match all kinds. // e.g. Kinds: ["foo", "bar"] matches if `kind` is either "foo" or "bar". Kinds []string `json:"kinds" yaml:"kinds"` // APIVersions is a list of apiVersions to match. If empty apply match all apiVersions. // e.g. APIVersions: ["foo/v1", "bar/v1"] matches if `apiVersion` is either "foo/v1" or "bar/v1". APIVersions []string `json:"apiVersions" yaml:"apiVersions"` // Labels is a collection of labels to match. All labels must match exactly. // e.g. Labels: {"foo": "bar", "baz": "buz"] matches if BOTH "foo" and "baz" labels match. Labels map[string]string `json:"labels" yaml:"labels"` // Annotations is a collection of annotations to match. All annotations must match exactly. // e.g. Annotations: {"foo": "bar", "baz": "buz"] matches if BOTH "foo" and "baz" annotations match. Annotations map[string]string `json:"annotations" yaml:"annotations"` // ResourceMatcher is an arbitrary function used to match resources. // Selector matches if the function returns true. ResourceMatcher func(*yaml.RNode) bool // TemplateData if present will cause the selector values to be parsed as templates // and rendered using TemplateData before they are used. TemplateData interface{} // FailOnEmptyMatch makes the selector return an error when no items are selected. FailOnEmptyMatch bool }
Selector matches resources. A resource matches if and only if ALL of the Selector fields match the resource. An empty Selector matches all resources.
Example (TemplatizeAnnotations) ¶
ExampleSelector_templatizeKinds provides an example of using a template as a selector value, to dynamically match resources based on the functionConfig input. It also shows how Selector can be used with SimpleProcessor to implement a ResourceListProcessor the filters the input.
package main import ( "bytes" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/kio" ) func main() { type api struct { Value string `yaml:"value"` } rw := &kio.ByteReadWriter{Reader: bytes.NewBufferString(` apiVersion: config.kubernetes.io/v1 kind: ResourceList functionConfig: value: bar items: - apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default annotations: key: foo - apiVersion: apps/v1 kind: Deployment metadata: name: bar namespace: default annotations: key: bar `)} config := &api{} p := framework.SimpleProcessor{ Config: config, Filter: &framework.Selector{ TemplateData: config, Annotations: map[string]string{"key": "{{ .Value }}"}, }, } if err := framework.Execute(p, rw); err != nil { panic(err) } }
Output: apiVersion: config.kubernetes.io/v1 kind: ResourceList items: - apiVersion: apps/v1 kind: Deployment metadata: name: bar namespace: default annotations: key: bar functionConfig: value: bar
Example (TemplatizeKinds) ¶
ExampleSelector_templatizeKinds provides an example of using a template as a selector value, to dynamically match resources based on the functionConfig input. It also shows how Selector can be used with SimpleProcessor to implement a ResourceListProcessor the filters the input.
package main import ( "bytes" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/kio" ) func main() { type api struct { KindName string `yaml:"kindName"` } rw := &kio.ByteReadWriter{ Reader: bytes.NewBufferString(` apiVersion: config.kubernetes.io/v1 kind: ResourceList functionConfig: kindName: Deployment items: - apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default - apiVersion: apps/v1 kind: StatefulSet metadata: name: bar namespace: default `), } config := &api{} p := framework.SimpleProcessor{ Config: config, Filter: &framework.Selector{ TemplateData: config, Kinds: []string{"{{ .KindName }}"}, }, } err := framework.Execute(p, rw) if err != nil { panic(err) } }
Output: apiVersion: config.kubernetes.io/v1 kind: ResourceList items: - apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default functionConfig: kindName: Deployment
type SimpleProcessor ¶ added in v0.10.14
type SimpleProcessor struct { // Filter is the kio.Filter that will be used to process the ResourceList's items. // Note that kio.FilterFunc is available to transform a compatible func into a kio.Filter. Filter kio.Filter // Config must be a struct capable of receiving the data from ResourceList.functionConfig. // Filter functions may close over this struct to access its data. Config interface{} }
SimpleProcessor processes a ResourceList by loading the FunctionConfig into the given Config type and then running the provided Filter on the ResourceList. The provided Config MAY implement Defaulter and Validator to have Default and Validate respectively called between unmarshalling and filter execution.
Typical uses include functions that do not actually require config, and simple functions built with a filter that closes over the Config instance to access ResourceList.functionConfig values.
Example (GenerateReplace) ¶
ExampleSimpleProcessor_generateReplace generates a resource from a FunctionConfig. If the resource already exists, it replaces the resource with a new copy.
package main import ( "bytes" "fmt" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" ) const service = "Service" func main() { input := bytes.NewBufferString(` apiVersion: config.kubernetes.io/v1 kind: ResourceList # items are provided as nodes items: - apiVersion: apps/v1 kind: Deployment metadata: name: foo functionConfig: apiVersion: example.com/v1alpha1 kind: ExampleServiceGenerator spec: name: bar `) // function API definition which will be parsed from the ResourceList.FunctionConfig // read from stdin type Spec struct { Name string `yaml:"name,omitempty"` } type ExampleServiceGenerator struct { Spec Spec `yaml:"spec,omitempty"` } functionConfig := &ExampleServiceGenerator{} fn := func(items []*yaml.RNode) ([]*yaml.RNode, error) { // remove the last generated resource var newNodes []*yaml.RNode for i := range items { meta, err := items[i].GetMeta() if err != nil { return nil, err } // something we already generated, remove it from the list so we regenerate it if meta.Name == functionConfig.Spec.Name && meta.Kind == service && meta.APIVersion == "v1" { continue } newNodes = append(newNodes, items[i]) } items = newNodes // generate the resource again n, err := yaml.Parse(fmt.Sprintf(`apiVersion: v1 kind: Service metadata: name: %s `, functionConfig.Spec.Name)) if err != nil { return nil, err } items = append(items, n) return items, nil } p := framework.SimpleProcessor{Config: functionConfig, Filter: kio.FilterFunc(fn)} err := framework.Execute(p, &kio.ByteReadWriter{Reader: input}) if err != nil { panic(err) } }
Output: apiVersion: config.kubernetes.io/v1 kind: ResourceList items: - apiVersion: apps/v1 kind: Deployment metadata: name: foo - apiVersion: v1 kind: Service metadata: name: bar functionConfig: apiVersion: example.com/v1alpha1 kind: ExampleServiceGenerator spec: name: bar
Example (Modify) ¶
ExampleSimpleProcessor_modify implements a function that sets an annotation on each resource.
package main import ( "bytes" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" ) func main() { input := bytes.NewBufferString(` apiVersion: config.kubernetes.io/v1 kind: ResourceList # items are provided as nodes items: - apiVersion: apps/v1 kind: Deployment metadata: name: foo - apiVersion: v1 kind: Service metadata: name: foo functionConfig: apiVersion: v1 kind: ConfigMap data: value: baz `) config := new(struct { Data map[string]string `yaml:"data" json:"data"` }) fn := func(items []*yaml.RNode) ([]*yaml.RNode, error) { for i := range items { // set the annotation on each resource item if err := items[i].PipeE(yaml.SetAnnotation("value", config.Data["value"])); err != nil { return nil, err } } return items, nil } err := framework.Execute(framework.SimpleProcessor{Config: config, Filter: kio.FilterFunc(fn)}, &kio.ByteReadWriter{Reader: input}) if err != nil { panic(err) } }
Output: apiVersion: config.kubernetes.io/v1 kind: ResourceList items: - apiVersion: apps/v1 kind: Deployment metadata: name: foo annotations: value: 'baz' - apiVersion: v1 kind: Service metadata: name: foo annotations: value: 'baz' functionConfig: apiVersion: v1 kind: ConfigMap data: value: baz
func (SimpleProcessor) Process ¶ added in v0.10.14
func (p SimpleProcessor) Process(rl *ResourceList) error
Process makes SimpleProcessor implement the ResourceListProcessor interface. It loads the ResourceList.functionConfig into the provided Config type, applying defaulting and validation if supported by Config. It then executes the processor's filter.
type TemplateParser ¶ added in v0.10.20
type TemplateParserFunc ¶ added in v0.10.20
type TemplateProcessor ¶ added in v0.10.14
type TemplateProcessor struct { // TemplateData will will be exposed to all the templates in the processor (unless explicitly // overridden for a template). // If TemplateProcessor is used directly as a ResourceListProcessor, TemplateData will contain the // value of ResourceList.functionConfig. TemplateData interface{} // ResourceTemplates returns a list of templates to render into resources. // If MergeResources is set, any matching resources in ResourceList.items will be used as patches // modifying the rendered templates. Otherwise, the rendered resources will be appended to // the input resources as-is. ResourceTemplates []ResourceTemplate // PatchTemplates is a list of templates to render into patches that apply to ResourceList.items. // ResourcePatchTemplate can be used here to patch entire resources. // ContainerPatchTemplate can be used here to patch specific containers within resources. PatchTemplates []PatchTemplate // MergeResources, if set to true, will cause the resources in ResourceList.items to be // will be applied as patches on any matching resources generated by ResourceTemplates. MergeResources bool // PreProcessFilters provides a hook to manipulate the ResourceList's items or config after // TemplateData has been populated but before template-based filters are applied. PreProcessFilters []kio.Filter // PostProcessFilters provides a hook to manipulate the ResourceList's items after template // filters are applied. PostProcessFilters []kio.Filter // AdditionalSchemas is a function that returns a list of schema definitions to add to openapi. // This enables correct merging of custom resource fields. AdditionalSchemas SchemaParser }
TemplateProcessor is a ResourceListProcessor based on rendering templates with the data in ResourceList.functionConfig. It works as follows: - loads ResourceList.functionConfig into TemplateData - runs PreProcessFilters - renders ResourceTemplates and adds them to ResourceList.items - renders PatchTemplates and applies them to ResourceList.items - executes a merge on ResourceList.items if configured to - runs PostProcessFilters The TemplateData struct MAY implement Defaulter and Validator to have Default and Validate respectively called between unmarshalling and filter execution.
TemplateProcessor also implements kio.Filter directly and can be used in the construction of higher-level processors. For example, you might use TemplateProcessors as the filters for each API supported by a VersionedAPIProcessor (see VersionedAPIProcessor examples).
Example (Container_patch) ¶
ExampleTemplateProcessor_container_patch provides an example for using TemplateProcessor to patch all of the containers in the input.
package main import ( "bytes" "log" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/fn/framework/parser" "sigs.k8s.io/kustomize/kyaml/kio" ) func main() { input := ` apiVersion: apps/v1 kind: Deployment metadata: name: foo spec: template: spec: containers: - name: foo image: a - name: bar image: b --- apiVersion: v1 kind: Service metadata: name: foo spec: selector: foo: bar --- apiVersion: apps/v1 kind: Deployment metadata: name: bar spec: template: spec: containers: - name: foo image: a - name: baz image: b --- apiVersion: v1 kind: Service metadata: name: bar spec: selector: foo: bar ` p := framework.TemplateProcessor{ PatchTemplates: []framework.PatchTemplate{ &framework.ContainerPatchTemplate{ Templates: parser.TemplateStrings(` env: - name: KEY value: {{ .Value }} `), TemplateData: struct{ Value string }{Value: "new-value"}, }}, } err := framework.Execute(p, &kio.ByteReadWriter{Reader: bytes.NewBufferString(input)}) if err != nil { log.Fatal(err) } }
Output: apiVersion: apps/v1 kind: Deployment metadata: name: foo spec: template: spec: containers: - name: foo image: a env: - name: KEY value: new-value - name: bar image: b env: - name: KEY value: new-value --- apiVersion: v1 kind: Service metadata: name: foo spec: selector: foo: bar --- apiVersion: apps/v1 kind: Deployment metadata: name: bar spec: template: spec: containers: - name: foo image: a env: - name: KEY value: new-value - name: baz image: b env: - name: KEY value: new-value --- apiVersion: v1 kind: Service metadata: name: bar spec: selector: foo: bar
Example (Container_patch_by_name) ¶
PatchTemplateContainersWithString patches containers matching a specific name.
package main import ( "bytes" "log" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/fn/framework/parser" "sigs.k8s.io/kustomize/kyaml/kio" ) func main() { input := ` apiVersion: apps/v1 kind: Deployment metadata: name: foo spec: template: spec: containers: - name: foo image: a env: - name: EXISTING value: variable - name: bar image: b --- apiVersion: v1 kind: Service metadata: name: foo spec: selector: foo: bar --- apiVersion: apps/v1 kind: Deployment metadata: name: bar spec: template: spec: containers: - name: foo image: a - name: baz image: b --- apiVersion: v1 kind: Service metadata: name: bar spec: selector: foo: bar ` p := framework.TemplateProcessor{ TemplateData: struct{ Value string }{Value: "new-value"}, PatchTemplates: []framework.PatchTemplate{ &framework.ContainerPatchTemplate{ // Only patch containers named "foo" ContainerMatcher: framework.ContainerNameMatcher("foo"), Templates: parser.TemplateStrings(` env: - name: KEY value: {{ .Value }} `), }}, } err := framework.Execute(p, &kio.ByteReadWriter{Reader: bytes.NewBufferString(input)}) if err != nil { log.Fatal(err) } }
Output: apiVersion: apps/v1 kind: Deployment metadata: name: foo spec: template: spec: containers: - name: foo image: a env: - name: EXISTING value: variable - name: KEY value: new-value - name: bar image: b --- apiVersion: v1 kind: Service metadata: name: foo spec: selector: foo: bar --- apiVersion: apps/v1 kind: Deployment metadata: name: bar spec: template: spec: containers: - name: foo image: a env: - name: KEY value: new-value - name: baz image: b --- apiVersion: v1 kind: Service metadata: name: bar spec: selector: foo: bar
Example (Generate_files) ¶
ExampleTemplateProcessor_files provides an example for using the TemplateProcessor to add resources from templates defined in files.
package main import ( "fmt" "path/filepath" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/fn/framework/command" "sigs.k8s.io/kustomize/kyaml/fn/framework/parser" ) func main() { api := new(struct { Key string `json:"key" yaml:"key"` Value string `json:"value" yaml:"value"` }) // create the template templateFn := framework.TemplateProcessor{ // Templates input TemplateData: api, // Templates ResourceTemplates: []framework.ResourceTemplate{{ Templates: parser.TemplateFiles("testdata/example/templatefiles/deployment.template.yaml"), }}, } cmd := command.Build(templateFn, command.StandaloneEnabled, false) // mimic standalone mode: testdata/template/config.yaml will be parsed into `api` cmd.SetArgs([]string{filepath.Join("testdata", "example", "templatefiles", "config.yaml")}) if err := cmd.Execute(); err != nil { _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "%v\n", err) } }
Output: # Copyright 2021 The Kubernetes Authors. # SPDX-License-Identifier: Apache-2.0 apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default annotations: a: b
Example (Generate_inline) ¶
ExampleTemplateProcessor provides an example for using the TemplateProcessor to add resources from templates defined inline
package main import ( "fmt" "path/filepath" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/fn/framework/command" "sigs.k8s.io/kustomize/kyaml/fn/framework/parser" ) func main() { api := new(struct { Key string `json:"key" yaml:"key"` Value string `json:"value" yaml:"value"` }) // create the template fn := framework.TemplateProcessor{ // Templates input TemplateData: api, // Templates ResourceTemplates: []framework.ResourceTemplate{{ Templates: parser.TemplateStrings(` apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default annotations: {{ .Key }}: {{ .Value }} `)}}, } cmd := command.Build(fn, command.StandaloneEnabled, false) // mimic standalone mode: testdata/template/config.yaml will be parsed into `api` cmd.SetArgs([]string{filepath.Join("testdata", "example", "template", "config.yaml")}) if err := cmd.Execute(); err != nil { _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "%v\n", err) } }
Output: apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default annotations: a: b
Example (Patch) ¶
ExampleTemplateProcessor_patch provides an example for using the TemplateProcessor to create a function that patches resources.
package main import ( "fmt" "path/filepath" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/fn/framework/command" "sigs.k8s.io/kustomize/kyaml/fn/framework/parser" ) func main() { fn := framework.TemplateProcessor{ TemplateData: new(struct { Key string `json:"key" yaml:"key"` Value string `json:"value" yaml:"value"` }), ResourceTemplates: []framework.ResourceTemplate{{ Templates: parser.TemplateStrings(` apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default annotations: {{ .Key }}: {{ .Value }} --- apiVersion: apps/v1 kind: Deployment metadata: name: bar namespace: default annotations: {{ .Key }}: {{ .Value }} `), }}, // PatchTemplates are applied to BOTH ResourceList input resources AND templated resources PatchTemplates: []framework.PatchTemplate{ &framework.ResourcePatchTemplate{ // patch the foo resource only Selector: &framework.Selector{Names: []string{"foo"}}, Templates: parser.TemplateStrings(` metadata: annotations: patched: 'true' `), }}, } cmd := command.Build(fn, command.StandaloneEnabled, false) cmd.SetArgs([]string{filepath.Join("testdata", "example", "template", "config.yaml")}) if err := cmd.Execute(); err != nil { _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "%v\n", err) } }
Output: apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default annotations: a: b patched: 'true' --- apiVersion: apps/v1 kind: Deployment metadata: name: bar namespace: default annotations: a: b
Example (Postprocess) ¶
ExampleTemplateProcessor_postprocess provides an example for using the TemplateProcessor with PostProcess to modify the results.
package main import ( "fmt" "path/filepath" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/fn/framework/command" "sigs.k8s.io/kustomize/kyaml/fn/framework/parser" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" ) func main() { config := new(struct { Key string `json:"key" yaml:"key"` Value string `json:"value" yaml:"value"` }) // create the template fn := framework.TemplateProcessor{ // Templates input TemplateData: config, ResourceTemplates: []framework.ResourceTemplate{{ Templates: parser.TemplateStrings(` apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default annotations: {{ .Key }}: {{ .Value }} --- apiVersion: apps/v1 kind: Deployment metadata: name: bar namespace: default annotations: {{ .Key }}: {{ .Value }} `), }}, PostProcessFilters: []kio.Filter{ kio.FilterFunc(func(items []*yaml.RNode) ([]*yaml.RNode, error) { items = items[1:] return items, nil }), }, } cmd := command.Build(fn, command.StandaloneEnabled, false) cmd.SetArgs([]string{filepath.Join("testdata", "example", "template", "config.yaml")}) if err := cmd.Execute(); err != nil { _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "%v\n", err) } }
Output: apiVersion: apps/v1 kind: Deployment metadata: name: bar namespace: default annotations: a: b
Example (Preprocess) ¶
ExampleTemplateProcessor_preprocess provides an example for using the TemplateProcessor with PreProcess to configure the template based on the input resources observed.
package main import ( "fmt" "path/filepath" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/fn/framework/command" "sigs.k8s.io/kustomize/kyaml/fn/framework/parser" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" ) func main() { config := new(struct { Key string `json:"key" yaml:"key"` Value string `json:"value" yaml:"value"` Short bool }) // create the template fn := framework.TemplateProcessor{ // Templates input TemplateData: config, PreProcessFilters: []kio.Filter{ kio.FilterFunc(func(items []*yaml.RNode) ([]*yaml.RNode, error) { config.Short = len(items) < 3 return items, nil }), }, // Templates ResourceTemplates: []framework.ResourceTemplate{{ Templates: parser.TemplateStrings(` apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default annotations: {{ .Key }}: {{ .Value }} {{- if .Short }} short: 'true' {{- end }} --- apiVersion: apps/v1 kind: Deployment metadata: name: bar namespace: default annotations: {{ .Key }}: {{ .Value }} {{- if .Short }} short: 'true' {{- end }} `), }}, } cmd := command.Build(fn, command.StandaloneEnabled, false) // mimic standalone mode: testdata/template/config.yaml will be parsed into `api` cmd.SetArgs([]string{filepath.Join("testdata", "example", "template", "config.yaml")}) if err := cmd.Execute(); err != nil { _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "%v\n", err) } }
Output: apiVersion: apps/v1 kind: Deployment metadata: name: foo namespace: default annotations: a: b short: 'true' --- apiVersion: apps/v1 kind: Deployment metadata: name: bar namespace: default annotations: a: b short: 'true'
func (TemplateProcessor) Filter ¶ added in v0.10.14
Filter implements the kio.Filter interface, enabling you to use TemplateProcessor as part of a higher-level ResourceListProcessor like VersionedAPIProcessor. It sets up all the features of TemplateProcessors as a pipeline of filters and executes them.
func (TemplateProcessor) Process ¶ added in v0.10.14
func (tp TemplateProcessor) Process(rl *ResourceList) error
Process implements the ResourceListProcessor interface, enabling you to use TemplateProcessor directly as a processor. As a Processor, it loads the ResourceList.functionConfig into the TemplateData field, exposing it to all templates by default.
type TemplatedMetaMapMatcher ¶ added in v0.10.14
type TemplatedMetaMapMatcher struct { // Templates is the list of possibly templated strings to compare to. Templates map[string]string // TemplateData is the data to use in template rendering. // Rendering will not take place if it is nil when InitTemplates is called. TemplateData interface{} // MetaMatcher is a function that returns true if the given resource metadata matches at // least one of the given names. // The matcher implemented using TemplatedMetaSliceMatcher can compare names to any meta field. MetaMatcher func(names map[string]string, meta yaml.ResourceMeta) bool // contains filtered or unexported fields }
TemplatedMetaMapMatcher is a utility type for constructing matchers that compare resource metadata to a map of (possibly templated) key-value pairs.
func (*TemplatedMetaMapMatcher) DefaultTemplateData ¶ added in v0.10.14
func (m *TemplatedMetaMapMatcher) DefaultTemplateData(data interface{})
DefaultTemplateData sets TemplateData to the provided default values if it has not already been set.
func (*TemplatedMetaMapMatcher) Filter ¶ added in v0.10.14
Filter applies the matcher to a list of items, returning only those that match.
func (*TemplatedMetaMapMatcher) InitTemplates ¶ added in v0.10.14
func (m *TemplatedMetaMapMatcher) InitTemplates() error
InitTemplates is used to render any templates the selector's key-value pairs may contain before the selector is applied. It should be called exactly once per filter operation, before beginning match comparisons.
func (*TemplatedMetaMapMatcher) Match ¶ added in v0.10.14
func (m *TemplatedMetaMapMatcher) Match(node *yaml.RNode) bool
Match parses the resource node's metadata and delegates matching logic to the provided MetaMatcher func. This allows ResourceMatchers build with TemplatedMetaMapMatcher to match against any field in resource metadata.
type TemplatedMetaSliceMatcher ¶ added in v0.10.14
type TemplatedMetaSliceMatcher struct { // Templates is the list of possibly templated strings to compare to. Templates []string // TemplateData is the data to use in template rendering. // Rendering will not take place if it is nil when InitTemplates is called. TemplateData interface{} // MetaMatcher is a function that returns true if the given resource metadata matches at // least one of the given names. // The matcher implemented using TemplatedMetaSliceMatcher can compare names to any meta field. MetaMatcher func(names sets.String, meta yaml.ResourceMeta) bool // contains filtered or unexported fields }
TemplatedMetaSliceMatcher is a utility type for constructing matchers that compare resource metadata to a slice of (possibly templated) strings.
func (*TemplatedMetaSliceMatcher) DefaultTemplateData ¶ added in v0.10.14
func (m *TemplatedMetaSliceMatcher) DefaultTemplateData(data interface{})
DefaultTemplateData sets TemplateData to the provided default values if it has not already been set.
func (*TemplatedMetaSliceMatcher) Filter ¶ added in v0.10.14
Filter applies the matcher to a list of items, returning only those that match.
func (*TemplatedMetaSliceMatcher) InitTemplates ¶ added in v0.10.14
func (m *TemplatedMetaSliceMatcher) InitTemplates() error
InitTemplates is used to render any templates the selector's list of strings may contain before the selector is applied. It should be called exactly once per filter operation, before beginning match comparisons.
func (*TemplatedMetaSliceMatcher) Match ¶ added in v0.10.14
func (m *TemplatedMetaSliceMatcher) Match(node *yaml.RNode) bool
Match parses the resource node's metadata and delegates matching logic to the provided MetaMatcher func. This allows ResourceMatchers build with TemplatedMetaSliceMatcher to match against any field in resource metadata.
type ValidationSchemaProvider ¶ added in v0.13.4
ValidationSchemaProvider is implemented by APIs to have the openapi schema provided by Schema() used to validate the input functionConfig before it is parsed into the API's struct. Use this with framework.SchemaFromFunctionDefinition to load the schema out of a KRMFunctionDefinition or CRD (e.g. one generated with KubeBuilder).
func (t MyType) Schema() (*spec.Schema, error) { schema, err := framework.SchemaFromFunctionDefinition(resid.NewGvk("example.com", "v1", "MyType"), MyTypeDef) return schema, errors.WrapPrefixf(err, "parsing MyType schema") }
type Validator ¶ added in v0.10.7
type Validator interface {
Validate() error
}
Validator is implemented by APIs to have Validate invoked. The standard application is to create a type to hold your FunctionConfig data, and implement Validator on that type. All of the framework's processors will invoke Validate() on your type after unmarshalling the FunctionConfig data into it.
type VersionedAPIProcessor ¶ added in v0.10.14
type VersionedAPIProcessor struct { // FilterProvider resolves a kio.Filter for each supported API, based on its APIVersion and Kind. // GVKFilterMap is a simple FilterProvider implementation for use here. FilterProvider FilterProvider }
VersionedAPIProcessor selects the appropriate kio.Filter based on the ApiVersion and Kind of the ResourceList.functionConfig in the input. It can be used to implement configuration function APIs that evolve over time, or create processors that support multiple configuration APIs with a single entrypoint. All provided Filters MUST be structs capable of receiving ResourceList.functionConfig data. Provided Filters MAY implement Defaulter and Validator to have Default and Validate respectively called between unmarshalling and filter execution.
Example ¶
ExampleVersionedAPIProcessor shows how to use the VersionedAPIProcessor and TemplateProcessor to build functions that implement complex multi-version APIs that require defaulting and validation.
package main import ( "bytes" "log" "strings" validationErrors "k8s.io/kube-openapi/pkg/validation/errors" "k8s.io/kube-openapi/pkg/validation/spec" "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/fn/framework" "sigs.k8s.io/kustomize/kyaml/fn/framework/parser" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/resid" "sigs.k8s.io/kustomize/kyaml/yaml" ) type v1alpha1JavaSpringBoot struct { Metadata Metadata `yaml:"metadata" json:"metadata"` Spec v1alpha1JavaSpringBootSpec `yaml:"spec" json:"spec"` } type Metadata struct { Name string `yaml:"name" json:"name"` } type v1alpha1JavaSpringBootSpec struct { Replicas int `yaml:"replicas" json:"replicas"` Domain string `yaml:"domain" json:"domain"` Image string `yaml:"image" json:"image"` } func (a v1alpha1JavaSpringBoot) Filter(items []*yaml.RNode) ([]*yaml.RNode, error) { filter := framework.TemplateProcessor{ ResourceTemplates: []framework.ResourceTemplate{{ TemplateData: &a, Templates: parser.TemplateStrings(` apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Metadata.Name }} selector: app: {{ .Metadata.Name }} spec: replicas: {{ .Spec.Replicas }} template: spec: containers: - name: app image: {{ .Spec.Image }} {{ if .Spec.Domain }} ports: - containerPort: 80 name: http {{ end }} {{ if .Spec.Domain }} --- apiVersion: v1 kind: Service metadata: name: {{ .Metadata.Name }}-svc spec: selector: app: {{ .Metadata.Name }} ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ .Metadata.Name }}-ingress spec: tls: - hosts: - {{ .Spec.Domain }} secretName: secret-tls defaultBackend: service: name: {{ .Metadata.Name }} port: number: 80 {{ end }} `), }}, } return filter.Filter(items) } func (a *v1alpha1JavaSpringBoot) Default() error { if a.Spec.Replicas == 0 { a.Spec.Replicas = 3 } return nil } var javaSpringBootDefinition = ` apiVersion: config.kubernetes.io/v1alpha1 kind: KRMFunctionDefinition metadata: name: javaspringboot.example.com spec: group: example.com names: kind: JavaSpringBoot versions: - name: v1alpha1 schema: openAPIV3Schema: properties: apiVersion: type: string kind: type: string metadata: type: object properties: name: type: string minLength: 1 required: - name spec: properties: domain: pattern: example\.com$ type: string image: type: string replicas: maximum: 9 minimum: 0 type: integer type: object type: object ` func (a v1alpha1JavaSpringBoot) Schema() (*spec.Schema, error) { schema, err := framework.SchemaFromFunctionDefinition(resid.NewGvk("example.com", "v1alpha1", "JavaSpringBoot"), javaSpringBootDefinition) return schema, errors.WrapPrefixf(err, "parsing JavaSpringBoot schema") } func (a *v1alpha1JavaSpringBoot) Validate() error { var errs []error if strings.HasSuffix(a.Spec.Image, ":latest") { errs = append(errs, errors.Errorf("spec.image should not have latest tag")) } if len(errs) > 0 { return validationErrors.CompositeValidationError(errs...) } return nil } func main() { p := &framework.VersionedAPIProcessor{FilterProvider: framework.GVKFilterMap{ "JavaSpringBoot": { "example.com/v1alpha1": &v1alpha1JavaSpringBoot{}, }}} source := &kio.ByteReadWriter{Reader: bytes.NewBufferString(` apiVersion: config.kubernetes.io/v1 kind: ResourceList functionConfig: apiVersion: example.com/v1alpha1 kind: JavaSpringBoot metadata: name: my-app spec: image: example.docker.com/team/app:1.0 domain: demo.example.com `)} if err := framework.Execute(p, source); err != nil { log.Fatal(err) } }
Output: apiVersion: config.kubernetes.io/v1 kind: ResourceList items: - apiVersion: apps/v1 kind: Deployment metadata: name: my-app selector: app: my-app spec: replicas: 3 template: spec: containers: - name: app image: example.docker.com/team/app:1.0 ports: - containerPort: 80 name: http - apiVersion: v1 kind: Service metadata: name: my-app-svc spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 80 - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app-ingress spec: tls: - hosts: - demo.example.com secretName: secret-tls defaultBackend: service: name: my-app port: number: 80 functionConfig: apiVersion: example.com/v1alpha1 kind: JavaSpringBoot metadata: name: my-app spec: image: example.docker.com/team/app:1.0 domain: demo.example.com
func (*VersionedAPIProcessor) Process ¶ added in v0.10.14
func (p *VersionedAPIProcessor) Process(rl *ResourceList) error
Process makes VersionedAPIProcessor implement the ResourceListProcessor interface. It looks up the configuration object to use based on the ApiVersion and Kind of the input ResourceList.functionConfig, loads ResourceList.functionConfig into that object, invokes Validate and Default if supported, and finally invokes Filter.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package command contains a builder for creating cobra.Commands based on configuration functions written using the kyaml function framework.
|
Package command contains a builder for creating cobra.Commands based on configuration functions written using the kyaml function framework. |
Package main contains an example using the framework.
|
Package main contains an example using the framework. |
Package frameworktestutil contains utilities for testing functions written using the framework.
|
Package frameworktestutil contains utilities for testing functions written using the framework. |
Package parser contains implementations of the framework.TemplateParser and framework.SchemaParser interfaces.
|
Package parser contains implementations of the framework.TemplateParser and framework.SchemaParser interfaces. |