func/config.go

88 lines
2.4 KiB
Go

package faas
import (
"io/ioutil"
"os"
"path/filepath"
"gopkg.in/yaml.v2"
)
// ConfigFileName is an optional file checked for in the function root.
const ConfigFileName = ".faas.yaml"
// Config object which provides another mechanism for overriding client static
// defaults. Applied prior to the WithX options, such that the options take
// precedence if they are provided.
type Config struct {
// Name specifies the name to be used for this function. As a config option,
// this value, if provided, takes precidence over the path-derived name but
// not over the Option WithName, if provided.
Name string `yaml:"name"`
// Runtime of the implementation.
Runtime string `yaml:"runtime"`
// Add new values to the applyConfig function as necessary.
}
// newConfig creates a config object from a function, effectively exporting mutable
// fields for the config file while preserving the immutability of the client
// post-instantiation.
func newConfig(f *Function) Config {
return Config{
Name: f.name,
Runtime: f.runtime,
}
}
// writeConfig out to disk.
func writeConfig(f *Function) (err error) {
var (
cfg = newConfig(f)
cfgFile = filepath.Join(f.root, ConfigFileName)
bb []byte
)
if bb, err = yaml.Marshal(&cfg); err != nil {
return
}
return ioutil.WriteFile(cfgFile, bb, 0644)
}
// Apply the config, if it exists, to the function struct.
// if an entry exists in the config file and is empty, this is interpreted as
// the intent to zero-value that field.
func applyConfig(f *Function, root string) error {
// abort if the config file does not exist.
filename := filepath.Join(root, ConfigFileName)
if _, err := os.Stat(filename); os.IsNotExist(err) {
return nil
}
// Read in as bytes
bb, err := ioutil.ReadFile(filepath.Join(root, ConfigFileName))
if err != nil {
return err
}
// Create a config with defaults set to the current value of the Client object.
// These gymnastics are necessary because we want the Client's members to be
// private to disallow mutation post instantiation, and thus they are unavailable
// to be set automatically
cfg := newConfig(f)
// Decode yaml, overriding values in the config if they were defined in the yaml.
if err := yaml.Unmarshal(bb, &cfg); err != nil {
return err
}
// Apply the config to the client object, which effectiely writes back the default
// if it was not defined in the yaml.
f.name = cfg.Name
f.runtime = cfg.Runtime
// NOTE: cleverness < clarity
return nil
}