Documentation ¶
Overview ¶
Example ¶
Example shows a simple HCL configuration being parsed and decoded. NOTE execute with go test -v -run Example$ ./pkg/config/example_test.go
package main import ( "fmt" "github.com/hashicorp/hcl/v2" kconf "github.com/sobchak-security/klutz/pkg/config" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/gocty" ) type exampleBlockType struct { Alias string `hcl:",label"` Value string `hcl:"custom_value" cty:"custom_value"` } func (b exampleBlockType) FirstLabel() string { return b.Alias } func (b exampleBlockType) AllLabels() []string { return []string{b.Alias} } func (b exampleBlockType) CtyValue() cty.Value { // consider also gocty.ImpliedType() to specify the cty.Type v, _ := gocty.ToCtyValue(b, cty.Object(map[string]cty.Type{"custom_value": cty.String})) return v } var hclConfig string = ` global_value = "default" custom dev { custom_value = "${global_value}" } custom prod { custom_value = "custom" } named_attribute = "${custom["${env.SOME_VARIABLE}"].custom_value}" ` type exampleConfig struct { RemainderVars hcl.Body `hcl:",remain"` CustomBlocks []exampleBlockType `hcl:"custom,block"` NamedAttribute string `hcl:"named_attribute"` } // Example shows a simple HCL configuration being parsed and decoded. // NOTE execute with go test -v -run Example$ ./pkg/config/example_test.go func main() { cfg, _ := kconf.New[exampleConfig]( kconf.ExplicitEnvVarsContextOption(`SOME_VARIABLE="dev"`), // this is to make the block's content available to the config's // evaluation context kconf.CustomBlockHandlerOption( "custom", kconf.DefaultCustomBlockHandler[exampleBlockType](), ), ) if err := cfg.Decode([]byte(hclConfig)); err != nil { panic(err) } fmt.Printf("env.-vars: %v\n", cfg.UsedEnvVars()) fmt.Printf("globals: %v\n", cfg.RemainderVars()) ec := cfg.Config() fmt.Printf("custom blocks: %v\n", ec.CustomBlocks) fmt.Printf("named attribute: %v\n", ec.NamedAttribute) }
Output: env.-vars: map[SOME_VARIABLE:dev] globals: map[global_value:default] custom blocks: [{dev default} {prod custom}] named attribute: default
Index ¶
- func RegisterService(decoder ServiceDecoder, serviceBlockTypes ...string)
- type Config
- type CustomBlock
- type CustomBlockHandler
- type Option
- func CustomBlockHandlerOption(blockType string, customBlockHandler CustomBlockHandler) Option
- func DotEnvFileContextOption(dotEnvFile string) Option
- func ExplicitEnvVarsContextOption(envVars ...string) Option
- func FilenameOption(filename string) Option
- func OSEnvVarsContextOption() Option
- func RemainderVarsKeyContextOption(key string) Option
- type Service
- type ServiceBase
- type ServiceBlock
- type ServiceBlocks
- type ServiceDecoder
- type Settings
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RegisterService ¶
func RegisterService(decoder ServiceDecoder, serviceBlockTypes ...string)
RegisterService adds a decoder to the service decoder registry for one or more block type identifiers.
Types ¶
type Config ¶
type Config[T any] interface { // Config is expected to return a decoded HCL-configuration. Config() T // Decode is expected to decode a HCL-configuration. Decode([]byte) error // contains filtered or unexported methods }
Config implementations are expected to parse and decode a HCL-configuration. Custom blocks will be decoded by applying corresponding block handlers. Global attributes (defined by an opaque "remain"-hcl.Body) and, optionally, environment variables (accessible with the "env" key) will be evaluated as HCL-expressions. Whenever reasonable, a configuration should be as specific as possible, with opaque remainder variables being, whenever possible, primitive value assignments and reduced to a minimum.
see Example() in example_test.go for an example.
type CustomBlock ¶
type CustomBlock interface { kcty.CtyMarshalable khcl.LabelReader }
CustomBlock implementations are expected to be convertible to a cty.Value (to allow the block to be accessible as en hcl.EvalContext variable) and to be a labeled HCL-block. // see exampleBlockType in example_test.go for an example.
func DefaultServiceBlockHandler ¶
func DefaultServiceBlockHandler(ctx *hcl.EvalContext, block *hcl.Block) (CustomBlock, error)
DefaultServiceBlockHandler decodes the HCL block and applies a ServiceDecoder for the ServiceBLock's block type, if one can be found in the ServiceDecoder registry.
type CustomBlockHandler ¶
type CustomBlockHandler func(*hcl.EvalContext, *hcl.Block) (CustomBlock, error)
A CustomBlockHandler decodes an HCL-block with an hcl.EvalContext,
func CustomServiceBlockHandler ¶
func CustomServiceBlockHandler[T Settings](decoder ServiceDecoder, serviceBlockTypes ...string) CustomBlockHandler
func DefaultCustomBlockHandler ¶
func DefaultCustomBlockHandler[T CustomBlock]() CustomBlockHandler
DefaultCustomBlockHandler is a convenience wrapper that decodes a custom block and assigns the decoded block to a hcl.EvalContext.
func DefaultCustomServiceBlockHandler ¶
func DefaultCustomServiceBlockHandler[T Settings](serviceBlockTypes ...string) CustomBlockHandler
type Option ¶
type Option func(*baseImpl)
Option allows for a custom Config instantiation.
func CustomBlockHandlerOption ¶
func CustomBlockHandlerOption(blockType string, customBlockHandler CustomBlockHandler) Option
CustomBlockHandlerOption adds a custom block handler for blockType to config at initialization; use AddCustomBlockHandler() for a later assignment.
func DotEnvFileContextOption ¶
DotEnvFileOption assigns envVars to the hcl.EvalContext under the root-key "env". NOTE the format for explicit env-vars is (value has to be in quotes!) name="value"
func ExplicitEnvVarsContextOption ¶
ExplicitEnvVarsContextOption assigns envVars to the hcl.EvalContext under the root-key "env". NOTE the format for explicit env-vars is (value has to be in quotes!) name="value"
func FilenameOption ¶
FilenameOption sets the name of the configuration file.
func OSEnvVarsContextOption ¶
func OSEnvVarsContextOption() Option
OSEnvVarsOption assigns the runtime env vars to the hcl.EvalContext under the root-key "env".
func RemainderVarsKeyContextOption ¶
RemainderVarsKeyContextOption sets the root key in Config's hcl.EvalContext for all variables defined in the "remain"-Body.
type Service ¶
type Service[T Settings] interface { ServiceBase // Settings implementations return a map of settings keyed by a settings' // alias. Settings() map[string]T }
Service implementations provide type settings keyed by the settings' alias.
func DecodeService ¶
func DecodeService[T Settings](ctx *hcl.EvalContext, sb *ServiceBlock) (Service[T], error)
DecodeService creates a service by parsing a service block. NOTE the evaluation context ctx is going to be modified by this function.
type ServiceBase ¶
type ServiceBase interface { kcty.CtyMarshalable khcl.LabelReader // Alias implementations return the first label of a service block. Alias() string // Type implementations return a string identifying the settings-type. Type() string }
ServiceBase implementations aim at supporting the Service[T] generics with basic functions by omitting any type-specific settings handling.
type ServiceBlock ¶
type ServiceBlock struct { SBAlias string `hcl:"alias,label" cty:"alias"` SBType string `hcl:"type" cty:"type"` SBSettings []*serviceBlockSettings `hcl:"settings,block" cty:"settings"` }
ServiceBlock provides a structure to be embedded in a custom config (file).
type ServiceBlocks ¶
type ServiceBlocks []*ServiceBlock
ServiceBlocks is a convenience type to be embedded in a custom config (file).
type ServiceDecoder ¶
type ServiceDecoder func(ctx *hcl.EvalContext, sb *ServiceBlock) (CustomBlock, error)
A ServiceDecoder is expected to decode an HCL ServiceBlock into a decoded Service[T] CustomBlock.
type Settings ¶
type Settings interface { kcty.CtyMarshalable khcl.LabelReader }
Settings implementations aim at providing customized services with specific settings and to populate variables in an hcl.EvalCtx.