Add documentation and simplify framework

This commit is contained in:
Phillip Wittrock
2020-05-07 10:58:37 -07:00
parent 259624ac07
commit dab0f3cf22
15 changed files with 453 additions and 398 deletions

View File

@@ -1,54 +1,120 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package framework contains a framework for writing functions in go.
// Package framework contains a framework for writing functions in go. The function spec
// is defined at: https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md
//
// Example
// Examples
//
// Example function implementation to set an annotation on each resource.
// Example function implementation using framework.ResourceList with functionConfig
//
// type Spec struct {
// Value string `yaml:"value,omitempty"`
// }
// type Example struct {
// Spec Spec `yaml:"spec,omitempty"`
// }
// functionConfig := &Example{}
//
// rl := framework.ResourceList{FunctionConfig: functionConfig}
// if err := rl.Read(); err != nil { return err }
//
// for i := range rl.Items {
// // modify the items...
// }
// if err := rl.Write(); err != nil { return err }
//
// Example function implementation using framework.Command with flags
//
// var value string
// cmd := framework.Command(nil, func(items []*yaml.RNode) ([]*yaml.RNode, error) {
// for i := range items {
// if err := items[i].PipeE(yaml.SetAnnotation("value", value)); err != nil {
// return nil, err
// }
// // modify the items...
// }
// return items, nil
// })
// cmd.Flags().StringVar(&value, "value", "", "annotation value")
// if err := cmd.Execute(); err != nil {
// panic(err)
// }
// if err := cmd.Execute(); err != nil { return err }
//
// Architecture
//
// Functions are implemented as a go function which accept a slice of resources (items)
// and returns a modified slice of resources (items).
// 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
//
// config 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: |
// image: image/containing/fuction: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:
//
// config run DIR/ --image image/containing/fuction: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 for the returned slice.
// Functions may add, delete or modify resources by modifying the items slice.
// When using framework.Command this is done through returning the new items slice.
// When using framework.ResourceList this is done through modifying ResourceList.Items in place.
//
// Validator Functions
//
// Functions may validate resources, returning results as go errors. results may contain
// different items for different validation failures.
// A function may validate resources by providing a Result.
// When using framework.Command this is done through returning a framework.Result as an error.
// WHen using framework.ResourceList this is done through setting 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).
// Any flags registered on the cobra.Command will be parsed from the functionConfig input
// if they are defined as functionConfig.data entries.
//
// When using framework.Command, any flags registered on the cobra.Command will be parsed
// from the functionConfig input if they are defined as functionConfig.data entries.
//
// When using framework.ResourceList, any flags set on the ResourceList.Flags will be
// parsed from the functionConfig input if they are defined as functionConfig.data entries.
//
// Functions may also access environment variables set by the caller.
//
// Function Input
//
// The framework parses the function ResourceList.items into a slice of yaml.RNodes, and
// parses the ResourceList.functionConfig into a passed in struct (optional).
//
// Building the Container
// Building a container image for the function
//
// The go program must be built into a container to be run as a function. The framework
// can be used to generate a Dockerfile to build the function container.