configs: stub out main configuration structs

These types represent the individual elements within configuration, the
modules a configuration is made of, and the configuration (static module
tree) itself.
This commit is contained in:
Martin Atkins 2018-02-01 20:33:06 -08:00
parent 05e3b47ba1
commit 13fa73c63e
12 changed files with 400 additions and 0 deletions

14
configs/backend.go Normal file
View File

@ -0,0 +1,14 @@
package configs
import (
"github.com/hashicorp/hcl2/hcl"
)
// Backend represents a "backend" block inside a "terraform" block in a module
// or file.
type Backend struct {
Type string
Config hcl.Body
DeclRange hcl.Range
}

30
configs/config.go Normal file
View File

@ -0,0 +1,30 @@
package configs
// A Config is a node in the tree of modules within a configuration.
//
// The module tree is constructed by following ModuleCall instances recursively
// through the root module transitively into descendent modules.
//
// A module tree described in *this* package represents the static tree
// represented by configuration. During evaluation a static ModuleNode may
// expand into zero or more module instances depending on the use of count and
// for_each configuration attributes within each call.
type Config struct {
// RootModule points to the Config for the root module within the same
// module tree as this module. If this module _is_ the root module then
// this is self-referential.
Root *Config
// ParentModule points to the Config for the module that directly calls
// this module. If this is the root module then this field is nil.
Parent *Config
// ChildModules points to the Config for each of the direct child modules
// called from this module. The keys in this map match the keys in
// Module.ModuleCalls.
Children map[string]*Config
// Elements points to the object describing the configuration for the
// various elements (variables, resources, etc) defined by this module.
Elements *Module
}

66
configs/module.go Normal file
View File

@ -0,0 +1,66 @@
package configs
import (
"github.com/hashicorp/hcl2/hcl"
)
// Module is a container for a set of configuration constructs that are
// evaluated within a common namespace.
type Module struct {
CoreVersionConstraints []VersionConstraint
Backend *Backend
ProviderConfigs map[string]*Provider
ProviderRequirements map[string][]VersionConstraint
Variables map[string]*Variable
Locals map[string]*Local
Outputs map[string]*Output
ModuleCalls map[string]*ModuleCall
ManagedResources map[string]*ManagedResource
DataResources map[string]*DataResource
}
// NewModule takes a list of primary files and a list of override files and
// produces a *Module by combining the files together.
//
// If there are any conflicting declarations in the given files -- for example,
// if the same variable name is defined twice -- then the resulting module
// will be incomplete and error diagnostics will be returned. Careful static
// analysis of the returned Module is still possible in this case, but the
// module will probably not be semantically valid.
func NewModule(primaryFiles, overrideFiles []*File) (*Module, hcl.Diagnostics) {
// TODO: process each file in turn, combining and merging as necessary
// to produce a single flat *Module.
panic("NewModule not yet implemented")
}
// File describes the contents of a single configuration file.
//
// Individual files are not usually used alone, but rather combined together
// with other files (conventionally, those in the same directory) to produce
// a *Module, using NewModule.
//
// At the level of an individual file we represent directly the structural
// elements present in the file, without any attempt to detect conflicting
// declarations. A File object can therefore be used for some basic static
// analysis of individual elements, but must be built into a Module to detect
// duplicate declarations.
type File struct {
CoreVersionConstraints []*VersionConstraint
Backends []*Backend
ProviderConfigs []*Provider
ProviderRequirements []*ProviderRequirement
Variables []*Variable
Locals []*Local
Outputs []*Output
ModuleCalls []*ModuleCall
ManagedResources []*ManagedResource
DataResources []*DataResource
}

18
configs/module_call.go Normal file
View File

@ -0,0 +1,18 @@
package configs
import (
"github.com/hashicorp/hcl2/hcl"
)
// ModuleCall represents a "module" block in a module or file.
type ModuleCall struct {
Source string
SourceRange hcl.Range
Version VersionConstraint
Count hcl.Expression
ForEach hcl.Expression
DeclRange hcl.Range
}

37
configs/named_values.go Normal file
View File

@ -0,0 +1,37 @@
package configs
import (
"github.com/hashicorp/hcl2/hcl"
"github.com/zclconf/go-cty/cty"
)
// Variable represents a "variable" block in a module or file.
type Variable struct {
Name string
Description string
Default cty.Value
TypeHint VariableTypeHint
DeclRange hcl.Range
}
// Output represents an "output" block in a module or file.
type Output struct {
Name string
Description string
Expr hcl.Expression
DependsOn []hcl.Traversal
Sensitive bool
DeclRange hcl.Range
}
// Local represents a single entry from a "locals" block in a module or file.
// The "locals" block itself is not represented, because it serves only to
// provide context for us to interpret its contents.
type Local struct {
Name string
Expr hcl.Expression
DeclRange hcl.Range
}

28
configs/provider.go Normal file
View File

@ -0,0 +1,28 @@
package configs
import (
"github.com/hashicorp/hcl2/hcl"
)
// Provider represents a "provider" block in a module or file. A provider
// block is a provider configuration, and there can be zero or more
// configurations for each actual provider.
type Provider struct {
Name string
Alias string
AliasRange hcl.Range
Version VersionConstraint
Config hcl.Body
DeclRange hcl.Range
}
// ProviderRequirement represents a declaration of a dependency on a particular
// provider version without actually configuring that provider. This is used in
// child modules that expect a provider to be passed in from their parent.
type ProviderRequirement struct {
Name string
Requirement VersionConstraint
}

View File

@ -0,0 +1,16 @@
// Code generated by "stringer -type ProvisionerOnFailure"; DO NOT EDIT.
package configs
import "strconv"
const _ProvisionerOnFailure_name = "ProvisionerOnFailureInvalidProvisionerOnFailureContinueProvisionerOnFailureFail"
var _ProvisionerOnFailure_index = [...]uint8{0, 27, 55, 79}
func (i ProvisionerOnFailure) String() string {
if i < 0 || i >= ProvisionerOnFailure(len(_ProvisionerOnFailure_index)-1) {
return "ProvisionerOnFailure(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _ProvisionerOnFailure_name[_ProvisionerOnFailure_index[i]:_ProvisionerOnFailure_index[i+1]]
}

View File

@ -0,0 +1,16 @@
// Code generated by "stringer -type ProvisionerWhen"; DO NOT EDIT.
package configs
import "strconv"
const _ProvisionerWhen_name = "ProvisionerWhenInvalidProvisionerWhenCreateProvisionerWhenDestroy"
var _ProvisionerWhen_index = [...]uint8{0, 22, 43, 65}
func (i ProvisionerWhen) String() string {
if i < 0 || i >= ProvisionerWhen(len(_ProvisionerWhen_index)-1) {
return "ProvisionerWhen(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _ProvisionerWhen_name[_ProvisionerWhen_index[i]:_ProvisionerWhen_index[i+1]]
}

86
configs/resource.go Normal file
View File

@ -0,0 +1,86 @@
package configs
import (
"github.com/hashicorp/hcl2/hcl"
)
// ManagedResource represents a "resource" block in a module or file.
type ManagedResource struct {
Name string
Type string
Config hcl.Body
Count hcl.Expression
ForEach hcl.Expression
ProviderConfigAddr hcl.Traversal
DependsOn []hcl.Traversal
Connection *Connection
Provisioners []*Provisioner
CreateBeforeDestroy bool
PreventDestroy bool
IgnoreChanges []hcl.Traversal
DeclRange hcl.Range
}
// DataResource represents a "data" block in a module or file.
type DataResource struct {
Name string
Type string
Config hcl.Body
Count hcl.Expression
ForEach hcl.Expression
ProviderConfigAddr hcl.Traversal
DependsOn []hcl.Traversal
DeclRange hcl.Range
}
// Provisioner represents a "provisioner" block when used within a
// "resource" block in a module or file.
type Provisioner struct {
Type string
Config hcl.Body
Connection *Connection
When ProvisionerWhen
OnFailure ProvisionerOnFailure
DeclRange hcl.Range
}
// Connection represents a "connection" block when used within either a
// "resource" or "provisioner" block in a module or file.
type Connection struct {
Type string
Config hcl.Body
DeclRange hcl.Range
}
// ProvisionerWhen is an enum for valid values for when to run provisioners.
type ProvisionerWhen int
//go:generate stringer -type ProvisionerWhen
const (
ProvisionerWhenInvalid ProvisionerWhen = iota
ProvisionerWhenCreate
ProvisionerWhenDestroy
)
// ProvisionerOnFailure is an enum for valid values for on_failure options
// for provisioners.
type ProvisionerOnFailure int
//go:generate stringer -type ProvisionerOnFailure
const (
ProvisionerOnFailureInvalid ProvisionerOnFailure = iota
ProvisionerOnFailureContinue
ProvisionerOnFailureFail
)

View File

@ -0,0 +1,45 @@
package configs
// VariableTypeHint is an enumeration used for the Variable.TypeHint field,
// which is an incompletely-specified type for the variable which is used
// as a hint for whether a value provided in an ambiguous context (on the
// command line or in an environment variable) should be taken literally as a
// string or parsed as an HCL expression to produce a data structure.
//
// The type hint is applied to runtime values as well, but since it does not
// accurately describe a precise type it is not fully-sufficient to infer
// the dynamic type of a value passed through a variable.
//
// These hints use inaccurate terminology for historical reasons. Full details
// are in the documentation for each constant in this enumeration, but in
// summary:
//
// TypeHintString requires a primitive type
// TypeHintList requires a type that could be converted to a tuple
// TypeHintMap requires a type that could be converted to an object
type VariableTypeHint rune
//go:generate stringer -type VariableTypeHint
// TypeHintNone indicates the absense of a type hint. Values specified in
// ambiguous contexts will be treated as literal strings, as if TypeHintString
// were selected, but no runtime value checks will be applied. This is reasonable
// type hint for a module that is never intended to be used at the top-level
// of a configuration, since descendent modules never recieve values from
// ambiguous contexts.
const TypeHintNone VariableTypeHint = 0
// TypeHintString spec indicates that a value provided in an ambiguous context
// should be treated as a literal string, and additionally requires that the
// runtime value for the variable is of a primitive type (string, number, bool).
const TypeHintString VariableTypeHint = 'S'
// TypeHintList indicates that a value provided in an ambiguous context should
// be treated as an HCL expression, and additionally requires that the
// runtime value for the variable is of an tuple, list, or set type.
const TypeHintList VariableTypeHint = 'L'
// TypeHintMap indicates that a value provided in an ambiguous context should
// be treated as an HCL expression, and additionally requires that the
// runtime value for the variable is of an object or map type.
const TypeHintMap VariableTypeHint = 'M'

View File

@ -0,0 +1,29 @@
// Code generated by "stringer -type VariableTypeHint"; DO NOT EDIT.
package configs
import "strconv"
const (
_VariableTypeHint_name_0 = "TypeHintNone"
_VariableTypeHint_name_1 = "TypeHintListTypeHintMap"
_VariableTypeHint_name_2 = "TypeHintString"
)
var (
_VariableTypeHint_index_1 = [...]uint8{0, 12, 23}
)
func (i VariableTypeHint) String() string {
switch {
case i == 0:
return _VariableTypeHint_name_0
case 76 <= i && i <= 77:
i -= 76
return _VariableTypeHint_name_1[_VariableTypeHint_index_1[i]:_VariableTypeHint_index_1[i+1]]
case i == 83:
return _VariableTypeHint_name_2
default:
return "VariableTypeHint(" + strconv.FormatInt(int64(i), 10) + ")"
}
}

View File

@ -0,0 +1,15 @@
package configs
import (
version "github.com/hashicorp/go-version"
"github.com/hashicorp/hcl2/hcl"
)
// VersionConstraint represents a version constraint on some resource
// (e.g. Terraform Core, a provider, a module, ...) that carries with it
// a source range so that a helpful diagnostic can be printed in the event
// that a particular constraint does not match.
type VersionConstraint struct {
Required []version.Constraints
DeclRange hcl.Range
}