From dadec5210be3e53c3808207ba31f158cb85e984e Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Mon, 2 Oct 2017 16:07:39 -0700 Subject: [PATCH] config/configschema: stub out initial API --- config/configschema/decoder_spec.go | 16 +++++ config/configschema/doc.go | 14 ++++ config/configschema/implied_type.go | 16 +++++ config/configschema/nestingmode_string.go | 16 +++++ config/configschema/schema.go | 87 +++++++++++++++++++++++ 5 files changed, 149 insertions(+) create mode 100644 config/configschema/decoder_spec.go create mode 100644 config/configschema/doc.go create mode 100644 config/configschema/implied_type.go create mode 100644 config/configschema/nestingmode_string.go create mode 100644 config/configschema/schema.go diff --git a/config/configschema/decoder_spec.go b/config/configschema/decoder_spec.go new file mode 100644 index 000000000..8b592a3ea --- /dev/null +++ b/config/configschema/decoder_spec.go @@ -0,0 +1,16 @@ +package configschema + +import ( + "github.com/hashicorp/hcl2/hcldec" +) + +// DecoderSpec returns a zcldec.Spec that can be used to decode a zcl Body +// using the facilities in the zcldec package. +// +// The returned specification is guaranteed to return a value of the same type +// returned by method ImpliedType, but it may contain null or unknown values if +// any of the block attributes are defined as optional and/or computed +// respectively. +func (b *Block) DecoderSpec() hcldec.Spec { + return nil +} diff --git a/config/configschema/doc.go b/config/configschema/doc.go new file mode 100644 index 000000000..caf8d730c --- /dev/null +++ b/config/configschema/doc.go @@ -0,0 +1,14 @@ +// Package configschema contains types for describing the expected structure +// of a configuration block whose shape is not known until runtime. +// +// For example, this is used to describe the expected contents of a resource +// configuration block, which is defined by the corresponding provider plugin +// and thus not compiled into Terraform core. +// +// A configschema primarily describes the shape of configuration, but it is +// also suitable for use with other structures derived from the configuration, +// such as the cached state of a resource or a resource diff. +// +// This package should not be confused with the package helper/schema, which +// is the higher-level helper library used to implement providers themselves. +package configschema diff --git a/config/configschema/implied_type.go b/config/configschema/implied_type.go new file mode 100644 index 000000000..485d121b3 --- /dev/null +++ b/config/configschema/implied_type.go @@ -0,0 +1,16 @@ +package configschema + +import ( + "github.com/zclconf/go-cty/cty" +) + +// ImpliedType returns the cty.Type that would result from decoding a +// configuration block using the receiving block schema. +// +// ImpliedType always returns a result, even if the given schema is +// inconsistent. Code that creates configschema.Block objects should be +// tested using the InternalValidate method to detect any inconsistencies +// that would cause this method to fall back on defaults and assumptions. +func (b *Block) ImpliedType() cty.Type { + return cty.DynamicPseudoType +} diff --git a/config/configschema/nestingmode_string.go b/config/configschema/nestingmode_string.go new file mode 100644 index 000000000..d9253a20f --- /dev/null +++ b/config/configschema/nestingmode_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type=NestingMode"; DO NOT EDIT. + +package configschema + +import "fmt" + +const _NestingMode_name = "nestingModeInvalidNestingSingleNestingListNestingSetNestingMap" + +var _NestingMode_index = [...]uint8{0, 18, 31, 42, 52, 62} + +func (i NestingMode) String() string { + if i < 0 || i >= NestingMode(len(_NestingMode_index)-1) { + return fmt.Sprintf("NestingMode(%d)", i) + } + return _NestingMode_name[_NestingMode_index[i]:_NestingMode_index[i+1]] +} diff --git a/config/configschema/schema.go b/config/configschema/schema.go new file mode 100644 index 000000000..2a5704840 --- /dev/null +++ b/config/configschema/schema.go @@ -0,0 +1,87 @@ +package configschema + +import ( + "github.com/zclconf/go-cty/cty" +) + +// Block represents a configuration block. +// +// "Block" here is a logical grouping construct, though it happens to map +// directly onto the physical block syntax of Terraform's native configuration +// syntax. It may be a more a matter of convention in other syntaxes, such as +// JSON. +// +// When converted to a value, a Block always becomes an instance of an object +// type derived from its defined attributes and nested blocks +type Block struct { + // Attributes describes any attributes that may appear directly inside + // the block. + Attributes map[string]*Attribute + + // BlockTypes describes any nested block types that may appear directly + // inside the block. + BlockTypes map[string]*NestedBlock +} + +// Attribute represents a configuration attribute, within a block. +type Attribute struct { + // Type is a type specification that the attribute's value must conform to. + Type cty.Type + + // Required, if set to true, specifies that an omitted or null value is + // not permitted. + Required bool + + // Optional, if set to true, specifies that an omitted or null value is + // permitted. This field conflicts with Required. + Optional bool + + // Computed, if set to true, specifies that the value comes from the + // provider rather than from configuration. If combined with Optional, + // then the config may optionally provide an overridden value. + Computed bool +} + +// NestedBlock represents the embedding of one block within another. +type NestedBlock struct { + // Block is the description of the block that's nested. + Block + + // Nesting provides the nesting mode for the child block, which determines + // how many instances of the block are allowed, how many labels it expects, + // and how the resulting data will be converted into a data structure. + Nesting NestingMode +} + +// NestingMode is an enumeration of modes for nesting blocks inside other +// blocks. +type NestingMode int + +//go:generate stringer -type=NestingMode + +const ( + nestingModeInvalid NestingMode = iota + + // NestingSingle indicates that only a single instance of a given + // block type is permitted, with no labels, and its content should be + // provided directly as an object value. + NestingSingle + + // NestingList indicates that multiple blocks of the given type are + // permitted, with no labels, and that their corresponding objects should + // be provided in a list. + NestingList + + // NestingSet indicates that multiple blocks of the given type are + // permitted, with no labels, and that their corresponding objects should + // be provided in a set. + NestingSet + + // NestingMap indicates that multiple blocks of the given type are + // permitted, each with a single label, and that their corresponding + // objects should be provided in a map whose keys are the labels. + // + // It's an error, therefore, to use the same label value on multiple + // blocks. + NestingMap +)