Skip to content

Commit

Permalink
schema: introduce lifecycle conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
radeksimko committed Jun 28, 2022
1 parent dbeca98 commit 01dad3e
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
115 changes: 115 additions & 0 deletions internal/schema/1.2/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package schema

import (
"github.com/hashicorp/go-version"
"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl-lang/schema"
"github.com/zclconf/go-cty/cty"

v015_mod "github.com/hashicorp/terraform-schema/internal/schema/0.15"
)

var v1_2 = version.Must(version.NewVersion("1.2.0"))

func ModuleSchema(v *version.Version) *schema.BodySchema {
bs := v015_mod.ModuleSchema(v)
if v.GreaterThanOrEqual(v1_2) {
bs.Blocks["data"].Body.Blocks = map[string]*schema.BlockSchema{
"lifecycle": datasourceLifecycleBlock,
}
bs.Blocks["resource"].Body.Blocks["lifecycle"] = resourceLifecycleBlock
bs.Blocks["output"].Body.Blocks = map[string]*schema.BlockSchema{
"lifecycle": outputLifecycleBlock,
}
}

return bs
}

var datasourceLifecycleBlock = &schema.BlockSchema{
Description: lang.Markdown("Lifecycle customizations to set validity conditions of the datasource"),
Body: &schema.BodySchema{
Blocks: map[string]*schema.BlockSchema{
"precondition": {
Body: conditionBody,
},
"postcondition": {
Body: conditionBody,
},
},
},
}

var outputLifecycleBlock = &schema.BlockSchema{
Description: lang.Markdown("Lifecycle customizations, to set a validity condition of the output"),
Body: &schema.BodySchema{
Blocks: map[string]*schema.BlockSchema{
"precondition": {
Body: conditionBody,
},
},
},
}

var resourceLifecycleBlock = &schema.BlockSchema{
Description: lang.Markdown("Lifecycle customizations to change default resource behaviours during plan or apply"),
Body: &schema.BodySchema{
Attributes: map[string]*schema.AttributeSchema{
"create_before_destroy": {
Expr: schema.LiteralTypeOnly(cty.Bool),
IsOptional: true,
Description: lang.Markdown("Whether to reverse the default order of operations (destroy -> create) during apply " +
"when the resource requires replacement (cannot be updated in-place)"),
},
"prevent_destroy": {
Expr: schema.LiteralTypeOnly(cty.Bool),
IsOptional: true,
Description: lang.Markdown("Whether to prevent accidental destruction of the resource and cause Terraform " +
"to reject with an error any plan that would destroy the resource"),
},
"ignore_changes": {
Expr: schema.ExprConstraints{
schema.TupleConsExpr{},
schema.KeywordExpr{
Keyword: "all",
Description: lang.Markdown("Ignore all attributes, which means that Terraform can create" +
" and destroy the remote object but will never propose updates to it"),
},
},
IsOptional: true,
Description: lang.Markdown("A set of fields (references) of which to ignore changes to, e.g. `tags`"),
},
},
Blocks: map[string]*schema.BlockSchema{
"precondition": {
Body: conditionBody,
},
"postcondition": {
Body: conditionBody,
},
},
},
}

var conditionBody = &schema.BodySchema{
Attributes: map[string]*schema.AttributeSchema{
"condition": {
Expr: schema.ExprConstraints{
schema.TraversalExpr{OfType: cty.Bool},
schema.LiteralTypeExpr{Type: cty.Bool},
},
IsRequired: true,
Description: lang.Markdown("Condition, a boolean expression that should return `true` " +
"if the intended assumption or guarantee is fulfilled or `false` if it is not."),
},
"error_message": {
Expr: schema.ExprConstraints{
schema.TraversalExpr{OfType: cty.String},
schema.LiteralTypeExpr{Type: cty.String},
},
IsRequired: true,
Description: lang.Markdown("Error message to return if the `condition` isn't met " +
"(evaluates to `false`)."),
},
},
}
5 changes: 5 additions & 0 deletions schema/core_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
mod_v0_13 "github.com/hashicorp/terraform-schema/internal/schema/0.13"
mod_v0_14 "github.com/hashicorp/terraform-schema/internal/schema/0.14"
mod_v0_15 "github.com/hashicorp/terraform-schema/internal/schema/0.15"
mod_v1_2 "github.com/hashicorp/terraform-schema/internal/schema/1.2"
universal "github.com/hashicorp/terraform-schema/internal/schema/universal"
)

Expand All @@ -17,6 +18,7 @@ var (
v0_13 = version.Must(version.NewVersion("0.13"))
v0_14 = version.Must(version.NewVersion("0.14"))
v0_15 = version.Must(version.NewVersion("0.15"))
v1_2 = version.Must(version.NewVersion("1.2"))
)

// CoreModuleSchemaForVersion finds a module schema which is relevant
Expand All @@ -28,6 +30,9 @@ func CoreModuleSchemaForVersion(v *version.Version) (*schema.BodySchema, error)
return nil, fmt.Errorf("invalid version: %w", err)
}

if ver.GreaterThanOrEqual(v1_2) {
return mod_v1_2.ModuleSchema(ver), nil
}
if ver.GreaterThanOrEqual(v0_15) {
return mod_v0_15.ModuleSchema(ver), nil
}
Expand Down

0 comments on commit 01dad3e

Please sign in to comment.