mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
e8381db778
* Update Kubernetes to v1.21.0 * Update to golang v1.16.2 * Update dependent modules to track with upstream * Switch to upstream flannel * Track changes to upstream cloud-controller-manager and FeatureGates Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
150 lines
4.7 KiB
Go
150 lines
4.7 KiB
Go
// Copyright 2019 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Package kio contains low-level libraries for reading, modifying and writing
|
|
// Resource Configuration and packages.
|
|
package kio
|
|
|
|
import (
|
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
|
)
|
|
|
|
// Reader reads ResourceNodes. Analogous to io.Reader.
|
|
type Reader interface {
|
|
Read() ([]*yaml.RNode, error)
|
|
}
|
|
|
|
// ResourceNodeSlice is a collection of ResourceNodes.
|
|
// While ResourceNodeSlice has no inherent constraints on ordering or uniqueness, specific
|
|
// Readers, Filters or Writers may have constraints.
|
|
type ResourceNodeSlice []*yaml.RNode
|
|
|
|
var _ Reader = ResourceNodeSlice{}
|
|
|
|
func (o ResourceNodeSlice) Read() ([]*yaml.RNode, error) {
|
|
return o, nil
|
|
}
|
|
|
|
// Writer writes ResourceNodes. Analogous to io.Writer.
|
|
type Writer interface {
|
|
Write([]*yaml.RNode) error
|
|
}
|
|
|
|
// WriterFunc implements a Writer as a function.
|
|
type WriterFunc func([]*yaml.RNode) error
|
|
|
|
func (fn WriterFunc) Write(o []*yaml.RNode) error {
|
|
return fn(o)
|
|
}
|
|
|
|
// ReaderWriter implements both Reader and Writer interfaces
|
|
type ReaderWriter interface {
|
|
Reader
|
|
Writer
|
|
}
|
|
|
|
// Filter modifies a collection of Resource Configuration by returning the modified slice.
|
|
// When possible, Filters should be serializable to yaml so that they can be described
|
|
// as either data or code.
|
|
//
|
|
// Analogous to http://www.linfo.org/filters.html
|
|
type Filter interface {
|
|
Filter([]*yaml.RNode) ([]*yaml.RNode, error)
|
|
}
|
|
|
|
// FilterFunc implements a Filter as a function.
|
|
type FilterFunc func([]*yaml.RNode) ([]*yaml.RNode, error)
|
|
|
|
func (fn FilterFunc) Filter(o []*yaml.RNode) ([]*yaml.RNode, error) {
|
|
return fn(o)
|
|
}
|
|
|
|
// Pipeline reads Resource Configuration from a set of Inputs, applies some
|
|
// transformation filters, and writes the results to a set of Outputs.
|
|
//
|
|
// Analogous to http://www.linfo.org/pipes.html
|
|
type Pipeline struct {
|
|
// Inputs provide sources for Resource Configuration to be read.
|
|
Inputs []Reader `yaml:"inputs,omitempty"`
|
|
|
|
// Filters are transformations applied to the Resource Configuration.
|
|
// They are applied in the order they are specified.
|
|
// Analogous to http://www.linfo.org/filters.html
|
|
Filters []Filter `yaml:"filters,omitempty"`
|
|
|
|
// Outputs are where the transformed Resource Configuration is written.
|
|
Outputs []Writer `yaml:"outputs,omitempty"`
|
|
|
|
// ContinueOnEmptyResult configures what happens when a filter in the pipeline
|
|
// returns an empty result.
|
|
// If it is false (default), subsequent filters will be skipped and the result
|
|
// will be returned immediately. This is useful as an optimization when you
|
|
// know that subsequent filters will not alter the empty result.
|
|
// If it is true, the empty result will be provided as input to the next
|
|
// filter in the list. This is useful when subsequent functions in the
|
|
// pipeline may generate new resources.
|
|
ContinueOnEmptyResult bool `yaml:"continueOnEmptyResult,omitempty"`
|
|
}
|
|
|
|
// Execute executes each step in the sequence, returning immediately after encountering
|
|
// any error as part of the Pipeline.
|
|
func (p Pipeline) Execute() error {
|
|
return p.ExecuteWithCallback(nil)
|
|
}
|
|
|
|
// PipelineExecuteCallbackFunc defines a callback function that will be called each time a step in the pipeline succeeds.
|
|
type PipelineExecuteCallbackFunc = func(op Filter)
|
|
|
|
// ExecuteWithCallback executes each step in the sequence, returning immediately after encountering
|
|
// any error as part of the Pipeline. The callback will be called each time a step succeeds.
|
|
func (p Pipeline) ExecuteWithCallback(callback PipelineExecuteCallbackFunc) error {
|
|
var result []*yaml.RNode
|
|
|
|
// read from the inputs
|
|
for _, i := range p.Inputs {
|
|
nodes, err := i.Read()
|
|
if err != nil {
|
|
return errors.Wrap(err)
|
|
}
|
|
result = append(result, nodes...)
|
|
}
|
|
|
|
// apply operations
|
|
var err error
|
|
for i := range p.Filters {
|
|
op := p.Filters[i]
|
|
if callback != nil {
|
|
callback(op)
|
|
}
|
|
result, err = op.Filter(result)
|
|
// TODO (issue 2872): This len(result) == 0 should be removed and empty result list should be
|
|
// handled by outputs. However currently some writer like LocalPackageReadWriter
|
|
// will clear the output directory and which will cause unpredictable results
|
|
if len(result) == 0 && !p.ContinueOnEmptyResult || err != nil {
|
|
return errors.Wrap(err)
|
|
}
|
|
}
|
|
|
|
// write to the outputs
|
|
for _, o := range p.Outputs {
|
|
if err := o.Write(result); err != nil {
|
|
return errors.Wrap(err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// FilterAll runs the yaml.Filter against all inputs
|
|
func FilterAll(filter yaml.Filter) Filter {
|
|
return FilterFunc(func(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
|
for i := range nodes {
|
|
_, err := filter.Filter(nodes[i])
|
|
if err != nil {
|
|
return nil, errors.Wrap(err)
|
|
}
|
|
}
|
|
return nodes, nil
|
|
})
|
|
}
|