mirror of https://github.com/hashicorp/packer
parent
5f3316350d
commit
cfd1189baf
@ -0,0 +1,82 @@
|
||||
package addrs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/gocty"
|
||||
)
|
||||
|
||||
// InstanceKey represents the key of an instance within an object that
|
||||
// contains multiple instances due to using "count" or "for_each" arguments
|
||||
// in configuration.
|
||||
//
|
||||
// IntKey and StringKey are the two implementations of this type. No other
|
||||
// implementations are allowed. The single instance of an object that _isn't_
|
||||
// using "count" or "for_each" is represented by NoKey, which is a nil
|
||||
// InstanceKey.
|
||||
type InstanceKey interface {
|
||||
instanceKeySigil()
|
||||
String() string
|
||||
|
||||
// Value returns the cty.Value of the appropriate type for the InstanceKey
|
||||
// value.
|
||||
Value() cty.Value
|
||||
}
|
||||
|
||||
// ParseInstanceKey returns the instance key corresponding to the given value,
|
||||
// which must be known and non-null.
|
||||
//
|
||||
// If an unknown or null value is provided then this function will panic. This
|
||||
// function is intended to deal with the values that would naturally be found
|
||||
// in a hcl.TraverseIndex, which (when parsed from source, at least) can never
|
||||
// contain unknown or null values.
|
||||
func ParseInstanceKey(key cty.Value) (InstanceKey, error) {
|
||||
switch key.Type() {
|
||||
case cty.String:
|
||||
return StringKey(key.AsString()), nil
|
||||
case cty.Number:
|
||||
var idx int
|
||||
err := gocty.FromCtyValue(key, &idx)
|
||||
return IntKey(idx), err
|
||||
default:
|
||||
return NoKey, fmt.Errorf("either a string or an integer is required")
|
||||
}
|
||||
}
|
||||
|
||||
// NoKey represents the absense of an InstanceKey, for the single instance
|
||||
// of a configuration object that does not use "count" or "for_each" at all.
|
||||
var NoKey InstanceKey
|
||||
|
||||
// IntKey is the InstanceKey representation representing integer indices, as
|
||||
// used when the "count" argument is specified or if for_each is used with
|
||||
// a sequence type.
|
||||
type IntKey int
|
||||
|
||||
func (k IntKey) instanceKeySigil() {
|
||||
}
|
||||
|
||||
func (k IntKey) String() string {
|
||||
return fmt.Sprintf("[%d]", int(k))
|
||||
}
|
||||
|
||||
func (k IntKey) Value() cty.Value {
|
||||
return cty.NumberIntVal(int64(k))
|
||||
}
|
||||
|
||||
// StringKey is the InstanceKey representation representing string indices, as
|
||||
// used when the "for_each" argument is specified with a map or object type.
|
||||
type StringKey string
|
||||
|
||||
func (k StringKey) instanceKeySigil() {
|
||||
}
|
||||
|
||||
func (k StringKey) String() string {
|
||||
// FIXME: This isn't _quite_ right because Go's quoted string syntax is
|
||||
// slightly different than HCL's, but we'll accept it for now.
|
||||
return fmt.Sprintf("[%q]", string(k))
|
||||
}
|
||||
|
||||
func (k StringKey) Value() cty.Value {
|
||||
return cty.StringVal(string(k))
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package addrs
|
||||
|
||||
// LocalValue is the address of a local value.
|
||||
type LocalValue struct {
|
||||
referenceable
|
||||
Name string
|
||||
}
|
||||
|
||||
func (v LocalValue) String() string {
|
||||
return "local." + v.Name
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
package addrs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Resource is an address for a resource block within configuration, which
|
||||
// contains potentially-multiple resource instances if that configuration
|
||||
// block uses "count" or "for_each".
|
||||
type Resource struct {
|
||||
referenceable
|
||||
Mode ResourceMode
|
||||
Type string
|
||||
Name string
|
||||
}
|
||||
|
||||
func (r Resource) String() string {
|
||||
switch r.Mode {
|
||||
case DataResourceMode:
|
||||
return fmt.Sprintf("data.%s.%s", r.Type, r.Name)
|
||||
default:
|
||||
// Should never happen, but we'll return a string here rather than
|
||||
// crashing just in case it does.
|
||||
return fmt.Sprintf("<invalid>.%s.%s", r.Type, r.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func (r Resource) Equal(o Resource) bool {
|
||||
return r.Mode == o.Mode && r.Name == o.Name && r.Type == o.Type
|
||||
}
|
||||
|
||||
// ResourceInstance is an address for a specific instance of a resource.
|
||||
// When a resource is defined in configuration with "count" or "for_each" it
|
||||
// produces zero or more instances, which can be addressed using this type.
|
||||
type ResourceInstance struct {
|
||||
referenceable
|
||||
Resource Resource
|
||||
Key InstanceKey
|
||||
}
|
||||
|
||||
func (r ResourceInstance) ContainingResource() Resource {
|
||||
return r.Resource
|
||||
}
|
||||
|
||||
func (r ResourceInstance) String() string {
|
||||
if r.Key == NoKey {
|
||||
return r.Resource.String()
|
||||
}
|
||||
return r.Resource.String() + r.Key.String()
|
||||
}
|
||||
|
||||
func (r ResourceInstance) Equal(o ResourceInstance) bool {
|
||||
return r.Key == o.Key && r.Resource.Equal(o.Resource)
|
||||
}
|
||||
|
||||
// ResourceMode defines which lifecycle applies to a given resource. Each
|
||||
// resource lifecycle has a slightly different address format.
|
||||
type ResourceMode rune
|
||||
|
||||
//go:generate go run golang.org/x/tools/cmd/stringer -type ResourceMode
|
||||
|
||||
const (
|
||||
// InvalidResourceMode is the zero value of ResourceMode and is not
|
||||
// a valid resource mode.
|
||||
InvalidResourceMode ResourceMode = 0
|
||||
|
||||
// BuildResourceMode indicates a build, as defined by "build" blocks in
|
||||
// configuration.
|
||||
BuildResourceMode ResourceMode = 'B'
|
||||
|
||||
// DataResourceMode indicates a data resource, as defined by
|
||||
// "data" blocks in configuration.
|
||||
DataResourceMode ResourceMode = 'D'
|
||||
)
|
||||
Loading…
Reference in new issue