configschema

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2026 License: MPL-2.0 Imports: 17 Imported by: 0

Documentation

Overview

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 OpenTofu 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.

Index

Constants

This section is empty.

Variables

View Source
var (
	FilterReadOnlyAttribute = func(name string, attribute *Attribute) bool {
		return attribute.Computed && !attribute.Optional
	}

	FilterHelperSchemaIdAttribute = func(name string, attribute *Attribute) bool {
		if name == "id" && attribute.Computed && attribute.Optional {
			return true
		}
		return false
	}

	FilterDeprecatedAttribute = func(name string, attribute *Attribute) bool {
		return attribute.Deprecated
	}

	FilterDeprecatedBlock = func(name string, block *NestedBlock) bool {
		return block.Deprecated
	}
)

Functions

This section is empty.

Types

type Attribute

type Attribute struct {
	// Type is a type specification that the attribute's value must conform to.
	// It conflicts with NestedType.
	Type cty.Type

	// NestedType indicates that the attribute is a NestedBlock-style object.
	// This field conflicts with Type.
	NestedType *Object

	// Description is an English-language description of the purpose and
	// usage of the attribute. A description should be concise and use only
	// one or two sentences, leaving full definition to longer-form
	// documentation defined elsewhere.
	Description     string
	DescriptionKind StringKind

	// Required, Optional, and Computed together represent how this attribute
	// may be set in the configuration and in responses from a provider.
	//
	// Only the following combinations of true values are valid:
	// - Required: must be set to a non-null value in the configuration.
	// - Optional: may be set to either a null or non-null value in the
	//   configuration. If not set, the value defaults to null.
	// - Computed: may NOT be set in the configuration; the value is decided
	//   only by the provider, typically based on something returned from
	//   the underlying remote API.
	// - Optional+Computed: As with optional, except that if and only if the
	//   configuration causes it to be set to null (either explicitly or by
	//   omission) then the provider decides the final value, such as by
	//   providing a default.
	//
	// All other combinations of these flags are invalid and so have no meaning.
	//
	// The "Computed" flag only applies to schemas used in contexts where a
	// provider returns a value derived from the given configuration. For
	// example, it's used in the schema for a resource type because the
	// provider returns a new result representing a combination of
	// configuration, prior state, and remote API data, but it is not used in
	// the schema for a provider's own configuration because that is used only
	// as an input to the provider and so there is no means for a provider to
	// return a derived object.
	Required, Optional, Computed bool

	// Sensitive, if set to true, indicates that an attribute may contain
	// sensitive information.
	//
	// At present nothing is done with this information, but callers are
	// encouraged to set it where appropriate so that it may be used in the
	// future to help OpenTofu mask sensitive information. (OpenTofu
	// currently achieves this in a limited sense via other mechanisms.)
	Sensitive bool

	Deprecated         bool
	DeprecationMessage string

	// WriteOnly indicates that such an attribute can receive ephemeral values.
	// When configured as true, these attributes cannot have values returned by
	// the provider, and an error will be returned if OpenTofu detects such a thing.
	WriteOnly bool
}

Attribute represents a configuration attribute, within a block.

func (*Attribute) EmptyValue

func (a *Attribute) EmptyValue() cty.Value

EmptyValue returns the "empty value" for the receiving attribute, which is the value that would be returned if there were no definition of the attribute at all, ignoring any required constraint.

func (*Attribute) ImpliedType

func (a *Attribute) ImpliedType() cty.Type

ImpliedType returns the cty.Type that would result from decoding a Block's ImpliedType and getting the resulting AttributeType.

ImpliedType always returns a result, even if the given schema is inconsistent. Code that creates configschema.Object 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 (*Attribute) InternalValidate

func (a *Attribute) InternalValidate(name string) error

InternalValidate returns an error if the receiving attribute and its child schema definitions have any inconsistencies with the documented rules for valid schema.

type Block

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

	Description     string
	DescriptionKind StringKind

	Deprecated         bool
	DeprecationMessage string

	// Ephemeral is a flag indicating that this is an ephemeral block marking it as an "ephemeral context".
	// There are multiple places where this is set to "true". Generally speaking,
	// any Block that is meant to accept ephemeral values should have this set as "true".
	Ephemeral bool
}

Block represents a configuration block.

"Block" here is a logical grouping construct, though it happens to map directly onto the physical block syntax of OpenTofu'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

func (*Block) AttributeByPath

func (b *Block) AttributeByPath(path cty.Path) *Attribute

AttributeByPath looks up the Attribute schema which corresponds to the given cty.Path. A nil value is returned if the given path does not correspond to a specific attribute.

func (*Block) CoerceValue

func (b *Block) CoerceValue(in cty.Value) (cty.Value, error)

CoerceValue attempts to force the given value to conform to the type implied by the receiver.

This is useful in situations where a configuration must be derived from an already-decoded value. It is always better to decode directly from configuration where possible since then source location information is still available to produce diagnostics, but in special situations this function allows a compatible result to be obtained even if the configuration objects are not available.

If the given value cannot be converted to conform to the receiving schema then an error is returned describing one of possibly many problems. This error may be a cty.PathError indicating a position within the nested data structure where the problem applies.

func (*Block) ContainsDeprecated

func (b *Block) ContainsDeprecated() bool

ContainsDeprecated returns true if any of the attributes of the receiving block or any of its descendent blocks are marked as deprecated.

func (*Block) ContainsMarks

func (b *Block) ContainsMarks() bool

ContainsMarks is a wrapper around Block.ContainsSensitive which adds another check for the ephemeral nature of the block. The schema attributes cannot be marked as ephemeral, only the whole block can have that mark. Therefore, we don't need to check the schema recursively.

NOTE: It's important to make the distinction between "schema attributes" and "value attributes". A schema attribute cannot have the ephemeral mark, but a value attribute can be marked as ephemeral if it's referencing attribute(s) from another ephemeral block.

func (*Block) ContainsSensitive

func (b *Block) ContainsSensitive() bool

ContainsSensitive returns true if any of the attributes of the receiving block or any of its descendent blocks are marked as sensitive.

Blocks themselves cannot be sensitive as a whole -- sensitivity is a per-attribute idea -- but sometimes we want to include a whole object decoded from a block in some UI output, and that is safe to do only if none of the contained attributes are sensitive.

func (*Block) ContainsWriteOnly

func (b *Block) ContainsWriteOnly() bool

ContainsWriteOnly returns true if any of the attributes of the receiving block or any of its descendent blocks are marked as write-only.

Blocks themselves cannot be write-only as a whole -- write-only is a per-attribute idea -- but sometimes we want to include a whole object decoded from a block in some UI output, and that is safe to do only if none of the contained attributes are write-only.

func (*Block) DecoderSpec

func (b *Block) DecoderSpec() hcldec.Spec

DecoderSpec returns a hcldec.Spec that can be used to decode a HCL Body using the facilities in the hcldec package.

The returned specification is guaranteed to return a value of the same type returned by method ImpliedType, but it may contain null values if any of the block attributes are defined as optional and/or computed respectively.

func (*Block) EmptyValue

func (b *Block) EmptyValue() cty.Value

EmptyValue returns the "empty value" for the receiving block, which for a block type is a non-null object where all of the attribute values are the empty values of the block's attributes and nested block types.

In other words, it returns the value that would be returned if an empty block were decoded against the receiving schema, assuming that no required attribute or block constraints were honored.

func (*Block) Filter

func (b *Block) Filter(filterAttribute FilterT[*Attribute], filterBlock FilterT[*NestedBlock]) *Block

func (*Block) ImpliedType

func (b *Block) ImpliedType() cty.Type

ImpliedType returns the cty.Type that would result from decoding a configuration block using the receiving block schema.

The type returned from Block.ImpliedType differs from the type returned by hcldec.ImpliedType in that there will be no objects with optional attributes, since this value is not to be used for the decoding of configuration.

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 (*Block) InternalValidate

func (b *Block) InternalValidate() error

InternalValidate returns an error if the receiving block and its child schema definitions have any inconsistencies with the documented rules for valid schema.

This can be used within unit tests to detect when a given schema is invalid, and is run when tofu loads provider schemas during NewContext.

func (*Block) NoneRequired

func (b *Block) NoneRequired() *Block

NoneRequired returns a deep copy of the receiver with any required attributes translated to optional.

func (*Block) PathSetContainsWriteOnly

func (b *Block) PathSetContainsWriteOnly(v cty.Value, ps cty.PathSet) bool

PathSetContainsWriteOnly checks that the given cty.PathSet contains *at least* one of write-only attribute from the given value's schema.

func (*Block) RemoveEphemeralFromWriteOnly

func (b *Block) RemoveEphemeralFromWriteOnly(v cty.Value) cty.Value

RemoveEphemeralFromWriteOnly gets the value and for the attributes that are configured as write-only removes the marks.Ephemeral mark. Write-only arguments are only available in managed resources. Write-only arguments are the only managed resource's attribute type that can reference ephemeral values. Also, the provider framework sdk is responsible with nullify these attributes before returning back to OpenTofu.

Therefore, before writing the changes/state of a managed resource to its store, we want to be sure that the nil value of the attribute is not marked as ephemeral in case it got its value from evaluating an expression where an ephemeral value has been involved.

func (*Block) StaticValidateTraversal

func (b *Block) StaticValidateTraversal(traversal hcl.Traversal) tfdiags.Diagnostics

StaticValidateTraversal checks whether the given traversal (which must be relative) refers to a construct in the receiving schema, returning error diagnostics if any problems are found.

This method is "optimistic" in that it will not return errors for possible problems that cannot be detected statically. It is possible that a traversal which passed static validation will still fail when evaluated.

func (*Block) UnknownValue

func (b *Block) UnknownValue() cty.Value

UnknownValue returns the "unknown value" for the receiving block, which for a block type is a non-null object where all of the attribute values are the unknown values of the block's attributes and nested block types.

In other words, it returns the value that would be returned if an unknown block were decoded against the receiving schema.

func (*Block) ValueMarks

func (b *Block) ValueMarks(val cty.Value, path cty.Path, subject *addrs.AbsResourceInstance) []cty.PathValueMarks

ValueMarks returns a set of path value marks for a given value and path, based on the sensitive flag for each attribute within the schema. Nested blocks are descended (if present in the given value). If subject is nil, deprecated marks will not be added. This is an intended usage.

func (*Block) WriteOnlyPaths

func (b *Block) WriteOnlyPaths(val cty.Value, path cty.Path) []cty.Path

WriteOnlyPaths returns the list of paths where write-only attributes exist in the given value. This logic is similar to the Block.ValueMarks since the logic of drilling into the value is similar.

type FilterT

type FilterT[T any] func(string, T) bool

func FilterOr

func FilterOr[T any](filters ...FilterT[T]) FilterT[T]

type NestedBlock

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

	// MinItems and MaxItems set, for the NestingList and NestingSet nesting
	// modes, lower and upper limits on the number of child blocks allowed
	// of the given type. If both are left at zero, no limit is applied.
	//
	// As a special case, both values can be set to 1 for NestingSingle in
	// order to indicate that a particular single block is required.
	//
	// These fields are ignored for other nesting modes and must both be left
	// at zero.
	MinItems, MaxItems int
}

NestedBlock represents the embedding of one block within another.

func (*NestedBlock) EmptyValue

func (b *NestedBlock) EmptyValue() cty.Value

EmptyValue returns the "empty value" for when there are zero nested blocks present of the receiving type.

func (*NestedBlock) UnknownValue

func (b *NestedBlock) UnknownValue() cty.Value

UnknownValue returns the "unknown value" for when there are zero nested blocks present of the receiving type.

type NestingMode

type NestingMode int

NestingMode is an enumeration of modes for nesting blocks inside other blocks.

const (

	// 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 NestingMode

	// NestingGroup is similar to NestingSingle in that it calls for only a
	// single instance of a given block type with no labels, but it additionally
	// guarantees that its result will never be null, even if the block is
	// absent, and instead the nested attributes and blocks will be treated
	// as absent in that case. (Any required attributes or blocks within the
	// nested block are not enforced unless the block is explicitly present
	// in the configuration, so they are all effectively optional when the
	// block is not present.)
	//
	// This is useful for the situation where a remote API has a feature that
	// is always enabled but has a group of settings related to that feature
	// that themselves have default values. By using NestingGroup instead of
	// NestingSingle in that case, generated plans will show the block as
	// present even when not present in configuration, thus allowing any
	// default values within to be displayed to the user.
	NestingGroup

	// 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
)

func (NestingMode) String

func (i NestingMode) String() string

type Object

type Object struct {
	// Attributes describes the nested attributes which may appear inside the
	// Object.
	Attributes map[string]*Attribute

	// Nesting provides the nesting mode for this Object, which determines how
	// many instances of the Object are allowed, how many labels it expects, and
	// how the resulting data will be converted into a data structure.
	Nesting NestingMode
}

Object represents the embedding of a structural object inside an Attribute.

func (*Object) AttributeByPath

func (o *Object) AttributeByPath(path cty.Path) *Attribute

AttributeByPath recurses through a NestedType to look up the Attribute scheme which corresponds to the given cty.Path. A nil value is returned if the given path does not correspond to a specific attribute.

func (*Object) ContainsDeprecated

func (o *Object) ContainsDeprecated() bool

ContainsDeprecated returns true if any of the attributes of the receiving Object are marked as deprecated.

func (*Object) ContainsSensitive

func (o *Object) ContainsSensitive() bool

ContainsSensitive returns true if any of the attributes of the receiving Object are marked as sensitive.

func (*Object) ContainsWriteOnly

func (o *Object) ContainsWriteOnly() bool

ContainsWriteOnly returns true if any of the attributes of the receiving Object are marked as write-only.

func (*Object) ImpliedType

func (o *Object) ImpliedType() cty.Type

ImpliedType returns the cty.Type that would result from decoding a NestedType Attribute using the receiving block schema.

ImpliedType always returns a result, even if the given schema is inconsistent. Code that creates configschema.Object 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 (*Object) SpecType

func (o *Object) SpecType() cty.Type

SpecType returns the cty.Type used for decoding a NestedType Attribute using the receiving block schema.

func (*Object) ValueMarks

func (o *Object) ValueMarks(val cty.Value, path cty.Path, subject *addrs.AbsResourceInstance) []cty.PathValueMarks

ValueMarks returns a set of path value marks for a given value and path, based on the sensitive flag for each attribute within the nested attribute. Attributes with nested types are descended (if present in the given value). If subject is nil, deprecated marks will not be added. This is an intended usage.

func (*Object) WriteOnlyPaths

func (o *Object) WriteOnlyPaths(val cty.Value, path cty.Path) []cty.Path

WriteOnlyPaths returns a slice of paths pointing to the attributes that are configured as write-only.

type StringKind

type StringKind int
const (
	StringPlain StringKind = iota
	StringMarkdown
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL