core: Store condition block results in plan

In order to include condition block results in the JSON plan output, we
must store them in the plan and its serialization.

Terraform can evaluate condition blocks multiple times, so we must be
able to update the result. Accordingly, the plan.Conditions object is a
map with keys representing the condition block's address. Condition
blocks are not referenceable in any other context, so this address form
cannot be used anywhere in the configuration.

The commit includes a new test case for the JSON output of a
refresh-only plan, which is currently the only way for a failing
condition result to be rendered through this path.
This commit is contained in:
Alisdair McDiarmid 2022-03-28 07:24:28 -04:00
parent 1e56e1fe0f
commit c5d10bdef1
32 changed files with 1702 additions and 329 deletions

86
internal/addrs/check.go Normal file
View File

@ -0,0 +1,86 @@
package addrs
import "fmt"
// Check is the address of a check rule within a checkable object.
//
// This represents the check rule globally within a configuration, and is used
// during graph evaluation to identify a condition result object to update with
// the result of check rule evaluation.
//
// The check address is not distinct from resource traversals, and check rule
// values are not intended to be available to the language, so the address is
// not Referenceable.
//
// Note also that the check address is only relevant within the scope of a run,
// as reordering check blocks between runs will result in their addresses
// changing.
type Check struct {
Container Checkable
Type CheckType
Index int
}
func (c Check) String() string {
container := c.Container.String()
switch c.Type {
case ResourcePrecondition:
return fmt.Sprintf("%s.preconditions[%d]", container, c.Index)
case ResourcePostcondition:
return fmt.Sprintf("%s.postconditions[%d]", container, c.Index)
case OutputPrecondition:
return fmt.Sprintf("%s.preconditions[%d]", container, c.Index)
default:
// This should not happen
return fmt.Sprintf("%s.conditions[%d]", container, c.Index)
}
}
// Checkable is an interface implemented by all address types that can contain
// condition blocks.
type Checkable interface {
checkableSigil()
// Check returns the address of an individual check rule of a specified
// type and index within this checkable container.
Check(CheckType, int) Check
String() string
}
var (
_ Checkable = AbsResourceInstance{}
_ Checkable = AbsOutputValue{}
)
type checkable struct {
}
func (c checkable) checkableSigil() {
}
// CheckType describes the category of check.
//go:generate go run golang.org/x/tools/cmd/stringer -type=CheckType check.go
type CheckType int
const (
InvalidCondition CheckType = 0
ResourcePrecondition CheckType = 1
ResourcePostcondition CheckType = 2
OutputPrecondition CheckType = 3
)
// Description returns a human-readable description of the check type. This is
// presented in the user interface through a diagnostic summary.
func (c CheckType) Description() string {
switch c {
case ResourcePrecondition:
return "Resource precondition"
case ResourcePostcondition:
return "Resource postcondition"
case OutputPrecondition:
return "Module output value precondition"
default:
// This should not happen
return "Condition"
}
}

View File

@ -0,0 +1,26 @@
// Code generated by "stringer -type=CheckType check.go"; DO NOT EDIT.
package addrs
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[InvalidCondition-0]
_ = x[ResourcePrecondition-1]
_ = x[ResourcePostcondition-2]
_ = x[OutputPrecondition-3]
}
const _CheckType_name = "InvalidConditionResourcePreconditionResourcePostconditionOutputPrecondition"
var _CheckType_index = [...]uint8{0, 16, 36, 57, 75}
func (i CheckType) String() string {
if i < 0 || i >= CheckType(len(_CheckType_index)-1) {
return "CheckType(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _CheckType_name[_CheckType_index[i]:_CheckType_index[i+1]]
}

View File

@ -2,6 +2,10 @@ package addrs
import (
"fmt"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/terraform/internal/tfdiags"
)
// OutputValue is the address of an output value, in the context of the module
@ -34,6 +38,7 @@ func (v OutputValue) Absolute(m ModuleInstance) AbsOutputValue {
// configuration. It is related to but separate from ModuleCallOutput, which
// represents a module output from the perspective of its parent module.
type AbsOutputValue struct {
checkable
Module ModuleInstance
OutputValue OutputValue
}
@ -49,6 +54,14 @@ func (m ModuleInstance) OutputValue(name string) AbsOutputValue {
}
}
func (v AbsOutputValue) Check(t CheckType, i int) Check {
return Check{
Container: v,
Type: t,
Index: i,
}
}
func (v AbsOutputValue) String() string {
if v.Module.IsRoot() {
return v.OutputValue.String()
@ -60,6 +73,68 @@ func (v AbsOutputValue) Equal(o AbsOutputValue) bool {
return v.OutputValue == o.OutputValue && v.Module.Equal(o.Module)
}
func ParseAbsOutputValue(traversal hcl.Traversal) (AbsOutputValue, tfdiags.Diagnostics) {
path, remain, diags := parseModuleInstancePrefix(traversal)
if diags.HasErrors() {
return AbsOutputValue{}, diags
}
if len(remain) != 2 {
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid address",
Detail: "An output name is required.",
Subject: traversal.SourceRange().Ptr(),
})
return AbsOutputValue{}, diags
}
if remain.RootName() != "output" {
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid address",
Detail: "Output address must start with \"output.\".",
Subject: remain[0].SourceRange().Ptr(),
})
return AbsOutputValue{}, diags
}
var name string
switch tt := remain[1].(type) {
case hcl.TraverseAttr:
name = tt.Name
default:
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid address",
Detail: "An output name is required.",
Subject: remain[1].SourceRange().Ptr(),
})
return AbsOutputValue{}, diags
}
return AbsOutputValue{
Module: path,
OutputValue: OutputValue{
Name: name,
},
}, diags
}
func ParseAbsOutputValueStr(str string) (AbsOutputValue, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
traversal, parseDiags := hclsyntax.ParseTraversalAbs([]byte(str), "", hcl.Pos{Line: 1, Column: 1})
diags = diags.Append(parseDiags)
if parseDiags.HasErrors() {
return AbsOutputValue{}, diags
}
addr, addrDiags := ParseAbsOutputValue(traversal)
diags = diags.Append(addrDiags)
return addr, diags
}
// ModuleCallOutput converts an AbsModuleOutput into a ModuleCallOutput,
// returning also the module instance that the ModuleCallOutput is relative
// to.

View File

@ -2,7 +2,10 @@ package addrs
import (
"fmt"
"strings"
"testing"
"github.com/go-test/deep"
)
func TestAbsOutputValueInstanceEqual_true(t *testing.T) {
@ -63,3 +66,66 @@ func TestAbsOutputValueInstanceEqual_false(t *testing.T) {
})
}
}
func TestParseAbsOutputValueStr(t *testing.T) {
tests := map[string]struct {
want AbsOutputValue
wantErr string
}{
"module.foo": {
wantErr: "An output name is required",
},
"module.foo.output": {
wantErr: "An output name is required",
},
"module.foo.boop.beep": {
wantErr: "Output address must start with \"output.\"",
},
"module.foo.output[0]": {
wantErr: "An output name is required",
},
"output": {
wantErr: "An output name is required",
},
"output[0]": {
wantErr: "An output name is required",
},
"output.boop": {
want: AbsOutputValue{
Module: RootModuleInstance,
OutputValue: OutputValue{
Name: "boop",
},
},
},
"module.foo.output.beep": {
want: AbsOutputValue{
Module: mustParseModuleInstanceStr("module.foo"),
OutputValue: OutputValue{
Name: "beep",
},
},
},
}
for input, tc := range tests {
t.Run(input, func(t *testing.T) {
got, diags := ParseAbsOutputValueStr(input)
for _, problem := range deep.Equal(got, tc.want) {
t.Errorf(problem)
}
if len(diags) > 0 {
gotErr := diags.Err().Error()
if tc.wantErr == "" {
t.Errorf("got error, expected success: %s", gotErr)
} else if !strings.Contains(gotErr, tc.wantErr) {
t.Errorf("unexpected error\n got: %s\nwant: %s", gotErr, tc.wantErr)
}
} else {
if tc.wantErr != "" {
t.Errorf("got success, expected error: %s", tc.wantErr)
}
}
})
}
}

View File

@ -210,6 +210,7 @@ func (r AbsResource) UniqueKey() UniqueKey {
// AbsResourceInstance is an absolute address for a resource instance under a
// given module path.
type AbsResourceInstance struct {
checkable
targetable
Module ModuleInstance
Resource ResourceInstance
@ -280,6 +281,14 @@ func (r AbsResourceInstance) AffectedAbsResource() AbsResource {
}
}
func (r AbsResourceInstance) Check(t CheckType, i int) Check {
return Check{
Container: r,
Type: t,
Index: i,
}
}
func (r AbsResourceInstance) Equal(o AbsResourceInstance) bool {
return r.Module.Equal(o.Module) && r.Resource.Equal(o.Resource)
}

View File

@ -0,0 +1,26 @@
package jsonplan
// conditionResult is the representation of an evaluated condition block.
type conditionResult struct {
// checkAddress is the globally-unique address of the condition block. This
// is intentionally unexported as it is an implementation detail.
checkAddress string
// Address is the absolute address of the condition's containing object.
Address string `json:"address,omitempty"`
// Type is the condition block type, and is one of ResourcePrecondition,
// ResourcePostcondition, or OutputPrecondition.
Type string `json:"condition_type,omitempty"`
// Result is true if the condition succeeds, and false if it fails or is
// known only at apply time.
Result bool `json:"result"`
// Unknown is true if the condition can only be evaluated at apply time.
Unknown bool `json:"unknown"`
// ErrorMessage is the custom error for a failing condition. It is only
// present if the condition fails.
ErrorMessage string `json:"error_message,omitempty"`
}

View File

@ -39,6 +39,7 @@ type plan struct {
PriorState json.RawMessage `json:"prior_state,omitempty"`
Config json.RawMessage `json:"configuration,omitempty"`
RelevantAttributes []resourceAttr `json:"relevant_attributes,omitempty"`
Conditions []conditionResult `json:"condition_results,omitempty"`
}
func newPlan() *plan {
@ -177,6 +178,12 @@ func Marshal(
return nil, fmt.Errorf("error in marshaling output changes: %s", err)
}
// output.Conditions
err = output.marshalConditionResults(p.Conditions)
if err != nil {
return nil, fmt.Errorf("error in marshaling condition results: %s", err)
}
// output.PriorState
if sf != nil && !sf.State.Empty() {
output.PriorState, err = jsonstate.Marshal(sf, schemas)
@ -476,6 +483,27 @@ func (p *plan) marshalOutputChanges(changes *plans.Changes) error {
return nil
}
func (p *plan) marshalConditionResults(conditions plans.Conditions) error {
for addr, c := range conditions {
cr := conditionResult{
checkAddress: addr,
Address: c.Address.String(),
Type: c.Type.String(),
ErrorMessage: c.ErrorMessage,
}
if c.Result.IsKnown() {
cr.Result = c.Result.True()
} else {
cr.Unknown = true
}
p.Conditions = append(p.Conditions, cr)
}
sort.Slice(p.Conditions, func(i, j int) bool {
return p.Conditions[i].checkAddress < p.Conditions[j].checkAddress
})
return nil
}
func (p *plan) marshalPlannedValues(changes *plans.Changes, schemas *terraform.Schemas) error {
// marshal the planned changes into a module
plan, err := marshalPlannedValues(changes, schemas)

View File

@ -679,6 +679,103 @@ func TestShow_json_output_sensitive(t *testing.T) {
}
}
// Failing conditions are only present in JSON output for refresh-only plans,
// so we test that separately here.
func TestShow_json_output_conditions_refresh_only(t *testing.T) {
td := tempDir(t)
inputDir := "testdata/show-json/conditions"
testCopyDir(t, inputDir, td)
defer os.RemoveAll(td)
defer testChdir(t, td)()
providerSource, close := newMockProviderSource(t, map[string][]string{"test": {"1.2.3"}})
defer close()
p := showFixtureSensitiveProvider()
// init
ui := new(cli.MockUi)
ic := &InitCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
Ui: ui,
ProviderSource: providerSource,
},
}
if code := ic.Run([]string{}); code != 0 {
t.Fatalf("init failed\n%s", ui.ErrorWriter)
}
// plan
planView, planDone := testView(t)
pc := &PlanCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
View: planView,
ProviderSource: providerSource,
},
}
args := []string{
"-refresh-only",
"-out=terraform.plan",
"-var=ami=bad-ami",
"-state=for-refresh.tfstate",
}
code := pc.Run(args)
planOutput := planDone(t)
if code != 0 {
t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, planOutput.Stderr())
}
// show
showView, showDone := testView(t)
sc := &ShowCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
View: showView,
ProviderSource: providerSource,
},
}
args = []string{
"-json",
"terraform.plan",
}
defer os.Remove("terraform.plan")
code = sc.Run(args)
showOutput := showDone(t)
if code != 0 {
t.Fatalf("unexpected exit status %d; want 0\ngot: %s", code, showOutput.Stderr())
}
// compare JSON output to wanted output
var got, want plan
gotString := showOutput.Stdout()
json.Unmarshal([]byte(gotString), &got)
wantFile, err := os.Open("output-refresh-only.json")
if err != nil {
t.Fatalf("unexpected err: %s", err)
}
defer wantFile.Close()
byteValue, err := ioutil.ReadAll(wantFile)
if err != nil {
t.Fatalf("unexpected err: %s", err)
}
json.Unmarshal([]byte(byteValue), &want)
// Disregard format version to reduce needless test fixture churn
want.FormatVersion = got.FormatVersion
if !cmp.Equal(got, want) {
t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, want))
}
}
// similar test as above, without the plan
func TestShow_json_output_state(t *testing.T) {
fixtureDir := "testdata/show-json-state"

View File

@ -0,0 +1,39 @@
{
"version": 4,
"terraform_version": "1.2.0-dev",
"serial": 1,
"lineage": "no",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "test_instance",
"name": "foo",
"provider": "provider[\"registry.terraform.io/hashicorp/test\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"ami": "ami-test",
"id": "placeholder"
}
}
]
},
{
"mode": "managed",
"type": "test_instance",
"name": "bar",
"provider": "provider[\"registry.terraform.io/hashicorp/test\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"ami": "ami-test",
"id": "placeheld"
}
}
]
}
]
}

View File

@ -0,0 +1,44 @@
terraform {
experiments = [preconditions_postconditions]
}
variable "ami" {
type = string
default = "ami-test"
}
variable "id_minimum_length" {
type = number
default = 10
}
resource "test_instance" "foo" {
ami = var.ami
lifecycle {
precondition {
condition = can(regex("^ami-", var.ami))
error_message = "Invalid AMI ID: must start with \"ami-\"."
}
}
}
resource "test_instance" "bar" {
ami = "ami-boop"
lifecycle {
postcondition {
condition = length(self.id) >= var.id_minimum_length
error_message = "Resource ID is unacceptably short (${length(self.id)} characters)."
}
}
}
output "foo_id" {
value = test_instance.foo.id
precondition {
condition = test_instance.foo.ami != "ami-bad"
error_message = "Foo has a bad AMI again!"
}
}

View File

@ -0,0 +1,165 @@
{
"format_version": "1.1",
"terraform_version": "1.2.0-dev",
"variables": {
"ami": {
"value": "bad-ami"
},
"id_minimum_length": {
"value": 10
}
},
"planned_values": {
"outputs": {
"foo_id": {
"sensitive": false,
"value": "placeholder"
}
},
"root_module": {}
},
"output_changes": {
"foo_id": {
"actions": [
"create"
],
"before": null,
"after": "placeholder",
"after_unknown": false,
"before_sensitive": false,
"after_sensitive": false
}
},
"prior_state": {
"format_version": "1.0",
"terraform_version": "1.1.0",
"values": {
"outputs": {
"foo_id": {
"sensitive": false,
"value": "placeholder"
}
},
"root_module": {
"resources": [
{
"address": "test_instance.bar",
"mode": "managed",
"type": "test_instance",
"name": "bar",
"provider_name": "registry.terraform.io/hashicorp/test",
"schema_version": 0,
"values": {
"ami": "ami-test",
"id": "placeheld",
"password": null
},
"sensitive_values": {}
},
{
"address": "test_instance.foo",
"mode": "managed",
"type": "test_instance",
"name": "foo",
"provider_name": "registry.terraform.io/hashicorp/test",
"schema_version": 0,
"values": {
"ami": "ami-test",
"id": "placeholder",
"password": null
},
"sensitive_values": {}
}
]
}
}
},
"configuration": {
"provider_config": {
"test": {
"name": "test",
"full_name": "registry.terraform.io/hashicorp/test"
}
},
"root_module": {
"outputs": {
"foo_id": {
"expression": {
"references": [
"test_instance.foo.id",
"test_instance.foo"
]
}
}
},
"resources": [
{
"address": "test_instance.bar",
"mode": "managed",
"type": "test_instance",
"name": "bar",
"provider_config_key": "test",
"expressions": {
"ami": {
"constant_value": "ami-boop"
}
},
"schema_version": 0
},
{
"address": "test_instance.foo",
"mode": "managed",
"type": "test_instance",
"name": "foo",
"provider_config_key": "test",
"expressions": {
"ami": {
"references": [
"var.ami"
]
}
},
"schema_version": 0
}
],
"variables": {
"ami": {
"default": "ami-test"
},
"id_minimum_length": {
"default": 10
}
}
}
},
"relevant_attributes": [
{
"resource": "test_instance.foo",
"attribute": [
"id"
]
}
],
"condition_results": [
{
"address": "output.foo_id",
"condition_type": "OutputPrecondition",
"result": true,
"unknown": false
},
{
"address": "test_instance.bar",
"condition_type": "ResourcePostcondition",
"result": false,
"unknown": false,
"error_message": "Resource ID is unacceptably short (9 characters)."
},
{
"address": "test_instance.foo",
"condition_type": "ResourcePrecondition",
"result": false,
"unknown": false,
"error_message": "Invalid AMI ID: must start with \"ami-\"."
}
]
}

View File

@ -0,0 +1,188 @@
{
"format_version": "1.1",
"terraform_version": "1.2.0-dev",
"variables": {
"ami": {
"value": "ami-test"
},
"id_minimum_length": {
"value": 10
}
},
"planned_values": {
"outputs": {
"foo_id": {
"sensitive": false
}
},
"root_module": {
"resources": [
{
"address": "test_instance.bar",
"mode": "managed",
"type": "test_instance",
"name": "bar",
"provider_name": "registry.terraform.io/hashicorp/test",
"schema_version": 0,
"values": {
"ami": "ami-boop"
},
"sensitive_values": {}
},
{
"address": "test_instance.foo",
"mode": "managed",
"type": "test_instance",
"name": "foo",
"provider_name": "registry.terraform.io/hashicorp/test",
"schema_version": 0,
"values": {
"ami": "ami-test"
},
"sensitive_values": {}
}
]
}
},
"resource_changes": [
{
"address": "test_instance.bar",
"mode": "managed",
"type": "test_instance",
"name": "bar",
"provider_name": "registry.terraform.io/hashicorp/test",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"ami": "ami-boop"
},
"after_unknown": {
"id": true
},
"before_sensitive": false,
"after_sensitive": {}
}
},
{
"address": "test_instance.foo",
"mode": "managed",
"type": "test_instance",
"name": "foo",
"provider_name": "registry.terraform.io/hashicorp/test",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"ami": "ami-test"
},
"after_unknown": {
"id": true
},
"before_sensitive": false,
"after_sensitive": {}
}
}
],
"output_changes": {
"foo_id": {
"actions": [
"create"
],
"before": null,
"after_unknown": true,
"before_sensitive": false,
"after_sensitive": false
}
},
"configuration": {
"provider_config": {
"test": {
"name": "test",
"full_name": "registry.terraform.io/hashicorp/test"
}
},
"root_module": {
"outputs": {
"foo_id": {
"expression": {
"references": [
"test_instance.foo.id",
"test_instance.foo"
]
}
}
},
"resources": [
{
"address": "test_instance.bar",
"mode": "managed",
"type": "test_instance",
"name": "bar",
"provider_config_key": "test",
"expressions": {
"ami": {
"constant_value": "ami-boop"
}
},
"schema_version": 0
},
{
"address": "test_instance.foo",
"mode": "managed",
"type": "test_instance",
"name": "foo",
"provider_config_key": "test",
"expressions": {
"ami": {
"references": [
"var.ami"
]
}
},
"schema_version": 0
}
],
"variables": {
"ami": {
"default": "ami-test"
},
"id_minimum_length": {
"default": 10
}
}
}
},
"relevant_attributes": [
{
"resource": "test_instance.foo",
"attribute": [
"id"
]
}
],
"condition_results": [
{
"address": "output.foo_id",
"condition_type": "OutputPrecondition",
"result": true,
"unknown": false
},
{
"address": "test_instance.bar",
"condition_type": "ResourcePostcondition",
"result": false,
"unknown": true
},
{
"address": "test_instance.foo",
"condition_type": "ResourcePrecondition",
"result": true,
"unknown": false
}
]
}

View File

@ -0,0 +1,53 @@
package plans
import (
"sync"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/zclconf/go-cty/cty"
)
// Conditions describes a set of results for condition blocks evaluated during
// the planning process. In normal operation, each result will either represent
// a passed check (Result is cty.True) or a deferred check (Result is
// cty.UnknownVal(cty.Bool)). Failing checks result in errors, except in
// refresh-only mode.
//
// The map key is a string representation of the check rule address, which is
// globally unique. Condition blocks can be evaluated multiple times during the
// planning operation, so we must be able to update an existing result value.
type Conditions map[string]*ConditionResult
type ConditionResult struct {
Address addrs.Checkable
Result cty.Value
Type addrs.CheckType
ErrorMessage string
}
func NewConditions() Conditions {
return make(Conditions)
}
func (c Conditions) SyncWrapper() *ConditionsSync {
return &ConditionsSync{
results: c,
}
}
// ConditionsSync is a wrapper around a Conditions that provides a
// concurrency-safe interface to add or update a condition result value.
type ConditionsSync struct {
lock sync.Mutex
results Conditions
}
func (cs *ConditionsSync) SetResult(addr addrs.Check, result *ConditionResult) {
if cs == nil {
panic("SetResult on nil Conditions")
}
cs.lock.Lock()
defer cs.lock.Unlock()
cs.results[addr.String()] = result
}

View File

@ -204,6 +204,59 @@ func (ResourceInstanceActionReason) EnumDescriptor() ([]byte, []int) {
return file_planfile_proto_rawDescGZIP(), []int{2}
}
// ConditionType defines the type of condition block used to generate a result.
type ConditionType int32
const (
ConditionType_INVALID ConditionType = 0
ConditionType_RESOURCE_PRECONDITION ConditionType = 1
ConditionType_RESOURCE_POSTCONDITION ConditionType = 2
ConditionType_OUTPUT_PRECONDITION ConditionType = 3
)
// Enum value maps for ConditionType.
var (
ConditionType_name = map[int32]string{
0: "INVALID",
1: "RESOURCE_PRECONDITION",
2: "RESOURCE_POSTCONDITION",
3: "OUTPUT_PRECONDITION",
}
ConditionType_value = map[string]int32{
"INVALID": 0,
"RESOURCE_PRECONDITION": 1,
"RESOURCE_POSTCONDITION": 2,
"OUTPUT_PRECONDITION": 3,
}
)
func (x ConditionType) Enum() *ConditionType {
p := new(ConditionType)
*p = x
return p
}
func (x ConditionType) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (ConditionType) Descriptor() protoreflect.EnumDescriptor {
return file_planfile_proto_enumTypes[3].Descriptor()
}
func (ConditionType) Type() protoreflect.EnumType {
return &file_planfile_proto_enumTypes[3]
}
func (x ConditionType) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use ConditionType.Descriptor instead.
func (ConditionType) EnumDescriptor() ([]byte, []int) {
return file_planfile_proto_rawDescGZIP(), []int{3}
}
// Plan is the root message type for the tfplan file
type Plan struct {
state protoimpl.MessageState
@ -241,6 +294,10 @@ type Plan struct {
// outputs that are not changing, as context for detecting inconsistencies
// at apply time.
OutputChanges []*OutputChange `protobuf:"bytes,4,rep,name=output_changes,json=outputChanges,proto3" json:"output_changes,omitempty"`
// An undordered set of condition block results for the entire
// configuration. This set includes unknown results for conditions which
// can only be evaluated at apply time.
ConditionResults []*ConditionResult `protobuf:"bytes,19,rep,name=condition_results,json=conditionResults,proto3" json:"condition_results,omitempty"`
// An unordered set of target addresses to include when applying. If no
// target addresses are present, the plan applies to the whole
// configuration.
@ -334,6 +391,13 @@ func (x *Plan) GetOutputChanges() []*OutputChange {
return nil
}
func (x *Plan) GetConditionResults() []*ConditionResult {
if x != nil {
return x.ConditionResults
}
return nil
}
func (x *Plan) GetTargetAddrs() []string {
if x != nil {
return x.TargetAddrs
@ -721,6 +785,128 @@ func (x *OutputChange) GetSensitive() bool {
return false
}
type ConditionResult struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Address of the object containing the condition.
Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
// Globally-unique address of the condition block. This is a run-specific
// identifier and is only stored in the plan in order to reconstruct the
// set of condition results.
ConditionAddr string `protobuf:"bytes,2,opt,name=condition_addr,json=conditionAddr,proto3" json:"condition_addr,omitempty"`
// Result indicates the value of the condition expression, which is
// true if the condition succeeds, false if it fails, and unknown if the
// condition depends on values which are only known at apply time.
//
// Types that are assignable to Result:
// *ConditionResult_Value
// *ConditionResult_Unknown
Result isConditionResult_Result `protobuf_oneof:"result"`
// Type of the condition block.
Type ConditionType `protobuf:"varint,5,opt,name=type,proto3,enum=tfplan.ConditionType" json:"type,omitempty"`
// Custom error message for a failing condition.
ErrorMessage string `protobuf:"bytes,6,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"`
}
func (x *ConditionResult) Reset() {
*x = ConditionResult{}
if protoimpl.UnsafeEnabled {
mi := &file_planfile_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ConditionResult) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ConditionResult) ProtoMessage() {}
func (x *ConditionResult) ProtoReflect() protoreflect.Message {
mi := &file_planfile_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ConditionResult.ProtoReflect.Descriptor instead.
func (*ConditionResult) Descriptor() ([]byte, []int) {
return file_planfile_proto_rawDescGZIP(), []int{5}
}
func (x *ConditionResult) GetAddr() string {
if x != nil {
return x.Addr
}
return ""
}
func (x *ConditionResult) GetConditionAddr() string {
if x != nil {
return x.ConditionAddr
}
return ""
}
func (m *ConditionResult) GetResult() isConditionResult_Result {
if m != nil {
return m.Result
}
return nil
}
func (x *ConditionResult) GetValue() bool {
if x, ok := x.GetResult().(*ConditionResult_Value); ok {
return x.Value
}
return false
}
func (x *ConditionResult) GetUnknown() bool {
if x, ok := x.GetResult().(*ConditionResult_Unknown); ok {
return x.Unknown
}
return false
}
func (x *ConditionResult) GetType() ConditionType {
if x != nil {
return x.Type
}
return ConditionType_INVALID
}
func (x *ConditionResult) GetErrorMessage() string {
if x != nil {
return x.ErrorMessage
}
return ""
}
type isConditionResult_Result interface {
isConditionResult_Result()
}
type ConditionResult_Value struct {
Value bool `protobuf:"varint,3,opt,name=value,proto3,oneof"`
}
type ConditionResult_Unknown struct {
Unknown bool `protobuf:"varint,4,opt,name=unknown,proto3,oneof"`
}
func (*ConditionResult_Value) isConditionResult_Result() {}
func (*ConditionResult_Unknown) isConditionResult_Result() {}
// DynamicValue represents a value whose type is not decided until runtime,
// often based on schema information obtained from a plugin.
//
@ -744,7 +930,7 @@ type DynamicValue struct {
func (x *DynamicValue) Reset() {
*x = DynamicValue{}
if protoimpl.UnsafeEnabled {
mi := &file_planfile_proto_msgTypes[5]
mi := &file_planfile_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -757,7 +943,7 @@ func (x *DynamicValue) String() string {
func (*DynamicValue) ProtoMessage() {}
func (x *DynamicValue) ProtoReflect() protoreflect.Message {
mi := &file_planfile_proto_msgTypes[5]
mi := &file_planfile_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -770,7 +956,7 @@ func (x *DynamicValue) ProtoReflect() protoreflect.Message {
// Deprecated: Use DynamicValue.ProtoReflect.Descriptor instead.
func (*DynamicValue) Descriptor() ([]byte, []int) {
return file_planfile_proto_rawDescGZIP(), []int{5}
return file_planfile_proto_rawDescGZIP(), []int{6}
}
func (x *DynamicValue) GetMsgpack() []byte {
@ -794,7 +980,7 @@ type Path struct {
func (x *Path) Reset() {
*x = Path{}
if protoimpl.UnsafeEnabled {
mi := &file_planfile_proto_msgTypes[6]
mi := &file_planfile_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -807,7 +993,7 @@ func (x *Path) String() string {
func (*Path) ProtoMessage() {}
func (x *Path) ProtoReflect() protoreflect.Message {
mi := &file_planfile_proto_msgTypes[6]
mi := &file_planfile_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -820,7 +1006,7 @@ func (x *Path) ProtoReflect() protoreflect.Message {
// Deprecated: Use Path.ProtoReflect.Descriptor instead.
func (*Path) Descriptor() ([]byte, []int) {
return file_planfile_proto_rawDescGZIP(), []int{6}
return file_planfile_proto_rawDescGZIP(), []int{7}
}
func (x *Path) GetSteps() []*Path_Step {
@ -842,7 +1028,7 @@ type PlanResourceAttr struct {
func (x *PlanResourceAttr) Reset() {
*x = PlanResourceAttr{}
if protoimpl.UnsafeEnabled {
mi := &file_planfile_proto_msgTypes[8]
mi := &file_planfile_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -855,7 +1041,7 @@ func (x *PlanResourceAttr) String() string {
func (*PlanResourceAttr) ProtoMessage() {}
func (x *PlanResourceAttr) ProtoReflect() protoreflect.Message {
mi := &file_planfile_proto_msgTypes[8]
mi := &file_planfile_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -899,7 +1085,7 @@ type Path_Step struct {
func (x *Path_Step) Reset() {
*x = Path_Step{}
if protoimpl.UnsafeEnabled {
mi := &file_planfile_proto_msgTypes[9]
mi := &file_planfile_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -912,7 +1098,7 @@ func (x *Path_Step) String() string {
func (*Path_Step) ProtoMessage() {}
func (x *Path_Step) ProtoReflect() protoreflect.Message {
mi := &file_planfile_proto_msgTypes[9]
mi := &file_planfile_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -925,7 +1111,7 @@ func (x *Path_Step) ProtoReflect() protoreflect.Message {
// Deprecated: Use Path_Step.ProtoReflect.Descriptor instead.
func (*Path_Step) Descriptor() ([]byte, []int) {
return file_planfile_proto_rawDescGZIP(), []int{6, 0}
return file_planfile_proto_rawDescGZIP(), []int{7, 0}
}
func (m *Path_Step) GetSelector() isPath_Step_Selector {
@ -973,7 +1159,7 @@ var File_planfile_proto protoreflect.FileDescriptor
var file_planfile_proto_rawDesc = []byte{
0x0a, 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x06, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x22, 0xec, 0x05, 0x0a, 0x04, 0x50, 0x6c, 0x61,
0x12, 0x06, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x22, 0xb2, 0x06, 0x0a, 0x04, 0x50, 0x6c, 0x61,
0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x07, 0x75,
0x69, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x74,
@ -994,129 +1180,154 @@ var file_planfile_proto_rawDesc = []byte{
0x3b, 0x0a, 0x0e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65,
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e,
0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0d, 0x6f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c,
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03,
0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12,
0x2e, 0x0a, 0x13, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x66, 0x6f,
0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12,
0x2b, 0x0a, 0x11, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x65, 0x72, 0x72,
0x61, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x07,
0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e,
0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x07,
0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x12, 0x4b, 0x0a, 0x13, 0x72, 0x65, 0x6c, 0x65, 0x76,
0x61, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x6c,
0x61, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72,
0x52, 0x12, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62,
0x75, 0x74, 0x65, 0x73, 0x1a, 0x52, 0x0a, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e,
0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4d, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x61, 0x74, 0x74, 0x72, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74,
0x68, 0x52, 0x04, 0x61, 0x74, 0x74, 0x72, 0x22, 0x69, 0x0a, 0x07, 0x42, 0x61, 0x63, 0x6b, 0x65,
0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e,
0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
0x63, 0x65, 0x22, 0xe4, 0x01, 0x0a, 0x06, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x26, 0x0a,
0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e,
0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44,
0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x16, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x73, 0x65,
0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x03, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74,
0x68, 0x52, 0x14, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69,
0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x40, 0x0a, 0x15, 0x61, 0x66, 0x74, 0x65, 0x72,
0x5f, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73,
0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e,
0x50, 0x61, 0x74, 0x68, 0x52, 0x13, 0x61, 0x66, 0x74, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x73, 0x69,
0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, 0x22, 0xd3, 0x02, 0x0a, 0x16, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68,
0x61, 0x6e, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x0d, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x76,
0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0b, 0x70, 0x72, 0x65, 0x76, 0x52, 0x75, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x1f, 0x0a, 0x0b,
0x64, 0x65, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a,
0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x06, 0x63, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x66, 0x70, 0x6c,
0x61, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67,
0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x10, 0x72,
0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18,
0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50,
0x61, 0x74, 0x68, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x65, 0x70,
0x6c, 0x61, 0x63, 0x65, 0x12, 0x49, 0x0a, 0x0d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72,
0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x66,
0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73,
0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f,
0x6e, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22,
0x68, 0x0a, 0x0c, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73,
0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09,
0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x22, 0x28, 0x0a, 0x0c, 0x44, 0x79, 0x6e,
0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67,
0x70, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x70,
0x61, 0x63, 0x6b, 0x22, 0xa5, 0x01, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x05,
0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66,
0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05,
0x73, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x74, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, 0x12, 0x27, 0x0a,
0x0e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66,
0x75, 0x74, 0x70, 0x75, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x11,
0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e,
0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
0x52, 0x10, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c,
0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x64, 0x64,
0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x72,
0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x10, 0x20, 0x03,
0x28, 0x09, 0x52, 0x11, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65,
0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f,
0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09,
0x52, 0x10, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x18, 0x0d, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x42, 0x61, 0x63,
0x6b, 0x65, 0x6e, 0x64, 0x52, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x12, 0x4b, 0x0a,
0x13, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x66, 0x70,
0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x52, 0x12, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74,
0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x1a, 0x52, 0x0a, 0x0e, 0x56, 0x61,
0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61,
0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4d,
0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x12,
0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x04, 0x61,
0x74, 0x74, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x66, 0x70, 0x6c,
0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x61, 0x74, 0x74, 0x72, 0x22, 0x69, 0x0a,
0x07, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2c, 0x0a, 0x06,
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74,
0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x77,
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xe4, 0x01, 0x0a, 0x06, 0x43, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x41, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x06, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66,
0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x48, 0x00, 0x52, 0x0a, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x42,
0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2a, 0x31, 0x0a, 0x04, 0x4d,
0x6f, 0x64, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12,
0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c,
0x52, 0x45, 0x46, 0x52, 0x45, 0x53, 0x48, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x2a, 0x70,
0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4f, 0x50,
0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08,
0x0a, 0x04, 0x52, 0x45, 0x41, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41,
0x54, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x05,
0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f,
0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x52, 0x45, 0x41,
0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x07,
0x2a, 0xa7, 0x02, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73,
0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f,
0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x52,
0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x54,
0x41, 0x49, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x50, 0x4c,
0x41, 0x43, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x02,
0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41,
0x55, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54,
0x45, 0x10, 0x03, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45,
0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43,
0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x44, 0x45,
0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x57, 0x52, 0x4f,
0x4e, 0x47, 0x5f, 0x52, 0x45, 0x50, 0x45, 0x54, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12,
0x1e, 0x0a, 0x1a, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53,
0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x10, 0x06, 0x12,
0x1b, 0x0a, 0x17, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53,
0x45, 0x5f, 0x45, 0x41, 0x43, 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18,
0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e,
0x4f, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x08, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
0x72, 0x70, 0x2f, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74,
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x16, 0x62, 0x65, 0x66,
0x6f, 0x72, 0x65, 0x5f, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61,
0x74, 0x68, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x66, 0x70, 0x6c,
0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x52, 0x14, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x53,
0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x40, 0x0a,
0x15, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65,
0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74,
0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x52, 0x13, 0x61, 0x66, 0x74, 0x65,
0x72, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, 0x22,
0xd3, 0x02, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74,
0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64,
0x64, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x22,
0x0a, 0x0d, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18,
0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x76, 0x52, 0x75, 0x6e, 0x41, 0x64,
0x64, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x6b, 0x65,
0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x65, 0x64,
0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18,
0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12,
0x26, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x0e, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52,
0x06, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61,
0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74,
0x65, 0x12, 0x37, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65,
0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x66,
0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69,
0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x49, 0x0a, 0x0d, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28,
0x0e, 0x32, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x68, 0x0a, 0x0c, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x43,
0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x63, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x66, 0x70, 0x6c,
0x61, 0x6e, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, 0x67,
0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x22,
0xda, 0x01, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x64, 0x69,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0d, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x16,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1a, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f,
0x77, 0x6e, 0x12, 0x29, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a,
0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x28, 0x0a, 0x0c,
0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07,
0x6d, 0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d,
0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x22, 0xa5, 0x01, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12,
0x27, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11,
0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65,
0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x74, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70,
0x12, 0x27, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72,
0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x65, 0x6c, 0x65,
0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b,
0x65, 0x79, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2a, 0x31,
0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c,
0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x01, 0x12,
0x10, 0x0a, 0x0c, 0x52, 0x45, 0x46, 0x52, 0x45, 0x53, 0x48, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10,
0x02, 0x2a, 0x70, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e,
0x4f, 0x4f, 0x50, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10,
0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x41, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x55,
0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54,
0x45, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x54, 0x48,
0x45, 0x4e, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x43,
0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54,
0x45, 0x10, 0x07, 0x2a, 0xa7, 0x02, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x61, 0x73, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b,
0x0a, 0x17, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53,
0x45, 0x5f, 0x54, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x52,
0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53,
0x54, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42,
0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x41, 0x4e, 0x4e, 0x4f, 0x54, 0x5f, 0x55, 0x50,
0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x25, 0x0a, 0x21, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45,
0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x52, 0x45, 0x53, 0x4f,
0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x04, 0x12, 0x23, 0x0a,
0x1f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f,
0x57, 0x52, 0x4f, 0x4e, 0x47, 0x5f, 0x52, 0x45, 0x50, 0x45, 0x54, 0x49, 0x54, 0x49, 0x4f, 0x4e,
0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43,
0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58,
0x10, 0x06, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43,
0x41, 0x55, 0x53, 0x45, 0x5f, 0x45, 0x41, 0x43, 0x48, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x07, 0x12,
0x1c, 0x0a, 0x18, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53,
0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x10, 0x08, 0x2a, 0x6c, 0x0a,
0x0d, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b,
0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x52,
0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x50, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x49,
0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52,
0x43, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e,
0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x50, 0x52, 0x45,
0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x42, 0x42, 0x5a, 0x40, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
0x6f, 0x72, 0x70, 0x2f, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x2f, 0x69, 0x6e, 0x74,
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -1131,49 +1342,53 @@ func file_planfile_proto_rawDescGZIP() []byte {
return file_planfile_proto_rawDescData
}
var file_planfile_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
var file_planfile_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_planfile_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
var file_planfile_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_planfile_proto_goTypes = []interface{}{
(Mode)(0), // 0: tfplan.Mode
(Action)(0), // 1: tfplan.Action
(ResourceInstanceActionReason)(0), // 2: tfplan.ResourceInstanceActionReason
(*Plan)(nil), // 3: tfplan.Plan
(*Backend)(nil), // 4: tfplan.Backend
(*Change)(nil), // 5: tfplan.Change
(*ResourceInstanceChange)(nil), // 6: tfplan.ResourceInstanceChange
(*OutputChange)(nil), // 7: tfplan.OutputChange
(*DynamicValue)(nil), // 8: tfplan.DynamicValue
(*Path)(nil), // 9: tfplan.Path
nil, // 10: tfplan.Plan.VariablesEntry
(*PlanResourceAttr)(nil), // 11: tfplan.Plan.resource_attr
(*Path_Step)(nil), // 12: tfplan.Path.Step
(ConditionType)(0), // 3: tfplan.ConditionType
(*Plan)(nil), // 4: tfplan.Plan
(*Backend)(nil), // 5: tfplan.Backend
(*Change)(nil), // 6: tfplan.Change
(*ResourceInstanceChange)(nil), // 7: tfplan.ResourceInstanceChange
(*OutputChange)(nil), // 8: tfplan.OutputChange
(*ConditionResult)(nil), // 9: tfplan.ConditionResult
(*DynamicValue)(nil), // 10: tfplan.DynamicValue
(*Path)(nil), // 11: tfplan.Path
nil, // 12: tfplan.Plan.VariablesEntry
(*PlanResourceAttr)(nil), // 13: tfplan.Plan.resource_attr
(*Path_Step)(nil), // 14: tfplan.Path.Step
}
var file_planfile_proto_depIdxs = []int32{
0, // 0: tfplan.Plan.ui_mode:type_name -> tfplan.Mode
10, // 1: tfplan.Plan.variables:type_name -> tfplan.Plan.VariablesEntry
6, // 2: tfplan.Plan.resource_changes:type_name -> tfplan.ResourceInstanceChange
6, // 3: tfplan.Plan.resource_drift:type_name -> tfplan.ResourceInstanceChange
7, // 4: tfplan.Plan.output_changes:type_name -> tfplan.OutputChange
4, // 5: tfplan.Plan.backend:type_name -> tfplan.Backend
11, // 6: tfplan.Plan.relevant_attributes:type_name -> tfplan.Plan.resource_attr
8, // 7: tfplan.Backend.config:type_name -> tfplan.DynamicValue
1, // 8: tfplan.Change.action:type_name -> tfplan.Action
8, // 9: tfplan.Change.values:type_name -> tfplan.DynamicValue
9, // 10: tfplan.Change.before_sensitive_paths:type_name -> tfplan.Path
9, // 11: tfplan.Change.after_sensitive_paths:type_name -> tfplan.Path
5, // 12: tfplan.ResourceInstanceChange.change:type_name -> tfplan.Change
9, // 13: tfplan.ResourceInstanceChange.required_replace:type_name -> tfplan.Path
2, // 14: tfplan.ResourceInstanceChange.action_reason:type_name -> tfplan.ResourceInstanceActionReason
5, // 15: tfplan.OutputChange.change:type_name -> tfplan.Change
12, // 16: tfplan.Path.steps:type_name -> tfplan.Path.Step
8, // 17: tfplan.Plan.VariablesEntry.value:type_name -> tfplan.DynamicValue
9, // 18: tfplan.Plan.resource_attr.attr:type_name -> tfplan.Path
8, // 19: tfplan.Path.Step.element_key:type_name -> tfplan.DynamicValue
20, // [20:20] is the sub-list for method output_type
20, // [20:20] is the sub-list for method input_type
20, // [20:20] is the sub-list for extension type_name
20, // [20:20] is the sub-list for extension extendee
0, // [0:20] is the sub-list for field type_name
12, // 1: tfplan.Plan.variables:type_name -> tfplan.Plan.VariablesEntry
7, // 2: tfplan.Plan.resource_changes:type_name -> tfplan.ResourceInstanceChange
7, // 3: tfplan.Plan.resource_drift:type_name -> tfplan.ResourceInstanceChange
8, // 4: tfplan.Plan.output_changes:type_name -> tfplan.OutputChange
9, // 5: tfplan.Plan.condition_results:type_name -> tfplan.ConditionResult
5, // 6: tfplan.Plan.backend:type_name -> tfplan.Backend
13, // 7: tfplan.Plan.relevant_attributes:type_name -> tfplan.Plan.resource_attr
10, // 8: tfplan.Backend.config:type_name -> tfplan.DynamicValue
1, // 9: tfplan.Change.action:type_name -> tfplan.Action
10, // 10: tfplan.Change.values:type_name -> tfplan.DynamicValue
11, // 11: tfplan.Change.before_sensitive_paths:type_name -> tfplan.Path
11, // 12: tfplan.Change.after_sensitive_paths:type_name -> tfplan.Path
6, // 13: tfplan.ResourceInstanceChange.change:type_name -> tfplan.Change
11, // 14: tfplan.ResourceInstanceChange.required_replace:type_name -> tfplan.Path
2, // 15: tfplan.ResourceInstanceChange.action_reason:type_name -> tfplan.ResourceInstanceActionReason
6, // 16: tfplan.OutputChange.change:type_name -> tfplan.Change
3, // 17: tfplan.ConditionResult.type:type_name -> tfplan.ConditionType
14, // 18: tfplan.Path.steps:type_name -> tfplan.Path.Step
10, // 19: tfplan.Plan.VariablesEntry.value:type_name -> tfplan.DynamicValue
11, // 20: tfplan.Plan.resource_attr.attr:type_name -> tfplan.Path
10, // 21: tfplan.Path.Step.element_key:type_name -> tfplan.DynamicValue
22, // [22:22] is the sub-list for method output_type
22, // [22:22] is the sub-list for method input_type
22, // [22:22] is the sub-list for extension type_name
22, // [22:22] is the sub-list for extension extendee
0, // [0:22] is the sub-list for field type_name
}
func init() { file_planfile_proto_init() }
@ -1243,7 +1458,7 @@ func file_planfile_proto_init() {
}
}
file_planfile_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DynamicValue); i {
switch v := v.(*ConditionResult); i {
case 0:
return &v.state
case 1:
@ -1255,6 +1470,18 @@ func file_planfile_proto_init() {
}
}
file_planfile_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DynamicValue); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_planfile_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Path); i {
case 0:
return &v.state
@ -1266,7 +1493,7 @@ func file_planfile_proto_init() {
return nil
}
}
file_planfile_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
file_planfile_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PlanResourceAttr); i {
case 0:
return &v.state
@ -1278,7 +1505,7 @@ func file_planfile_proto_init() {
return nil
}
}
file_planfile_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
file_planfile_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Path_Step); i {
case 0:
return &v.state
@ -1291,7 +1518,11 @@ func file_planfile_proto_init() {
}
}
}
file_planfile_proto_msgTypes[9].OneofWrappers = []interface{}{
file_planfile_proto_msgTypes[5].OneofWrappers = []interface{}{
(*ConditionResult_Value)(nil),
(*ConditionResult_Unknown)(nil),
}
file_planfile_proto_msgTypes[10].OneofWrappers = []interface{}{
(*Path_Step_AttributeName)(nil),
(*Path_Step_ElementKey)(nil),
}
@ -1300,8 +1531,8 @@ func file_planfile_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_planfile_proto_rawDesc,
NumEnums: 3,
NumMessages: 10,
NumEnums: 4,
NumMessages: 11,
NumExtensions: 0,
NumServices: 0,
},

View File

@ -44,6 +44,11 @@ message Plan {
// at apply time.
repeated OutputChange output_changes = 4;
// An undordered set of condition block results for the entire
// configuration. This set includes unknown results for conditions which
// can only be evaluated at apply time.
repeated ConditionResult condition_results = 19;
// An unordered set of target addresses to include when applying. If no
// target addresses are present, the plan applies to the whole
// configuration.
@ -207,6 +212,38 @@ message OutputChange {
bool sensitive = 3;
}
// ConditionType defines the type of condition block used to generate a result.
enum ConditionType {
INVALID = 0;
RESOURCE_PRECONDITION = 1;
RESOURCE_POSTCONDITION = 2;
OUTPUT_PRECONDITION = 3;
}
message ConditionResult {
// Address of the object containing the condition.
string addr = 1;
// Globally-unique address of the condition block. This is a run-specific
// identifier and is only stored in the plan in order to reconstruct the
// set of condition results.
string condition_addr = 2;
// Result indicates the value of the condition expression, which is
// true if the condition succeeds, false if it fails, and unknown if the
// condition depends on values which are only known at apply time.
oneof result {
bool value = 3;
bool unknown = 4;
}
// Type of the condition block.
ConditionType type = 5;
// Custom error message for a failing condition.
string error_message = 6;
}
// DynamicValue represents a value whose type is not decided until runtime,
// often based on schema information obtained from a plugin.
//

View File

@ -32,6 +32,7 @@ type Plan struct {
VariableValues map[string]DynamicValue
Changes *Changes
Conditions Conditions
DriftedResources []*ResourceInstanceChangeSrc
TargetAddrs []addrs.Targetable
ForceReplaceAddrs []addrs.AbsResourceInstance

View File

@ -50,6 +50,7 @@ func TestRoundtrip(t *testing.T) {
// Minimal plan too, since the serialization of the tfplan portion of the
// file is tested more fully in tfplan_test.go .
planIn := &plans.Plan{
Conditions: plans.Conditions{},
Changes: &plans.Changes{
Resources: []*plans.ResourceInstanceChangeSrc{},
Outputs: []*plans.OutputChangeSrc{},

View File

@ -13,6 +13,7 @@ import (
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/plans/internal/planproto"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/tfdiags"
"github.com/hashicorp/terraform/version"
"github.com/zclconf/go-cty/cty"
)
@ -58,6 +59,7 @@ func readTfplan(r io.Reader) (*plans.Plan, error) {
Resources: []*plans.ResourceInstanceChangeSrc{},
},
DriftedResources: []*plans.ResourceInstanceChangeSrc{},
Conditions: make(plans.Conditions),
}
switch rawPlan.UiMode {
@ -88,6 +90,43 @@ func readTfplan(r io.Reader) (*plans.Plan, error) {
})
}
for _, rawCR := range rawPlan.ConditionResults {
conditionAddr := rawCR.ConditionAddr
cr := &plans.ConditionResult{
ErrorMessage: rawCR.ErrorMessage,
}
switch r := rawCR.Result.(type) {
case *planproto.ConditionResult_Value:
cr.Result = cty.BoolVal(r.Value)
case *planproto.ConditionResult_Unknown:
cr.Result = cty.UnknownVal(cty.Bool)
}
var diags tfdiags.Diagnostics
switch rawCR.Type {
case planproto.ConditionType_OUTPUT_PRECONDITION:
cr.Type = addrs.OutputPrecondition
cr.Address, diags = addrs.ParseAbsOutputValueStr(rawCR.Addr)
if diags.HasErrors() {
return nil, diags.Err()
}
case planproto.ConditionType_RESOURCE_PRECONDITION:
cr.Type = addrs.ResourcePrecondition
cr.Address, diags = addrs.ParseAbsResourceInstanceStr(rawCR.Addr)
if diags.HasErrors() {
return nil, diags.Err()
}
case planproto.ConditionType_RESOURCE_POSTCONDITION:
cr.Type = addrs.ResourcePostcondition
cr.Address, diags = addrs.ParseAbsResourceInstanceStr(rawCR.Addr)
if diags.HasErrors() {
return nil, diags.Err()
}
default:
return nil, fmt.Errorf("condition result %s has unsupported type %s", rawCR.ConditionAddr, rawCR.Type)
}
plan.Conditions[conditionAddr] = cr
}
for _, rawRC := range rawPlan.ResourceChanges {
change, err := resourceChangeFromTfplan(rawRC)
if err != nil {
@ -360,6 +399,7 @@ func writeTfplan(plan *plans.Plan, w io.Writer) error {
Variables: map[string]*planproto.DynamicValue{},
OutputChanges: []*planproto.OutputChange{},
ConditionResults: []*planproto.ConditionResult{},
ResourceChanges: []*planproto.ResourceInstanceChange{},
ResourceDrift: []*planproto.ResourceInstanceChange{},
}
@ -400,6 +440,35 @@ func writeTfplan(plan *plans.Plan, w io.Writer) error {
})
}
for addr, cr := range plan.Conditions {
pcr := &planproto.ConditionResult{
Addr: cr.Address.String(),
ConditionAddr: addr,
ErrorMessage: cr.ErrorMessage,
}
if cr.Result.IsKnown() {
pcr.Result = &planproto.ConditionResult_Value{
Value: cr.Result.True(),
}
} else {
pcr.Result = &planproto.ConditionResult_Unknown{
Unknown: true,
}
}
switch cr.Type {
case addrs.OutputPrecondition:
pcr.Type = planproto.ConditionType_OUTPUT_PRECONDITION
case addrs.ResourcePrecondition:
pcr.Type = planproto.ConditionType_RESOURCE_PRECONDITION
case addrs.ResourcePostcondition:
pcr.Type = planproto.ConditionType_RESOURCE_POSTCONDITION
default:
return fmt.Errorf("condition result %s has unsupported type %s", addr, cr.Type)
}
rawPlan.ConditionResults = append(rawPlan.ConditionResults, pcr)
}
for _, rc := range plan.Changes.Resources {
rawRC, err := resourceChangeToTfplan(rc)
if err != nil {

View File

@ -22,6 +22,32 @@ func TestTFPlanRoundTrip(t *testing.T) {
VariableValues: map[string]plans.DynamicValue{
"foo": mustNewDynamicValueStr("foo value"),
},
Conditions: plans.Conditions{
"test_thing.woot[0].preconditions[0]": &plans.ConditionResult{
Address: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "woot",
}.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance),
Result: cty.False,
Type: addrs.ResourcePrecondition,
ErrorMessage: "Invalid thing: too much woot.",
},
"test_thing.woot[0].postconditions[0]": &plans.ConditionResult{
Address: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "woot",
}.Instance(addrs.IntKey(0)).Absolute(addrs.RootModuleInstance),
Result: cty.UnknownVal(cty.Bool),
Type: addrs.ResourcePostcondition,
},
"output.bar.preconditions[0]": &plans.ConditionResult{
Address: addrs.OutputValue{Name: "bar"}.Absolute(addrs.RootModuleInstance),
Result: cty.True,
Type: addrs.OutputPrecondition,
},
},
Changes: &plans.Changes{
Outputs: []*plans.OutputChangeSrc{
{

View File

@ -35,6 +35,7 @@ func (c *Context) Apply(plan *plans.Plan, config *configs.Config) (*states.State
Config: config,
InputState: workingState,
Changes: plan.Changes,
Conditions: plan.Conditions,
})
diags = diags.Append(walker.NonFatalDiagnostics)
diags = diags.Append(walkDiags)

View File

@ -484,10 +484,12 @@ func (c *Context) planWalk(config *configs.Config, prevRunState *states.State, o
// If we get here then we should definitely have a non-nil "graph", which
// we can now walk.
changes := plans.NewChanges()
conditions := plans.NewConditions()
walker, walkDiags := c.walk(graph, walkOp, &graphWalkOpts{
Config: config,
InputState: prevRunState,
Changes: changes,
Conditions: conditions,
MoveResults: moveResults,
})
diags = diags.Append(walker.NonFatalDiagnostics)
@ -521,6 +523,7 @@ func (c *Context) planWalk(config *configs.Config, prevRunState *states.State, o
plan := &plans.Plan{
UIMode: opts.Mode,
Changes: changes,
Conditions: conditions,
DriftedResources: driftedResources,
PrevRunState: prevRunState,
PriorState: priorState,

View File

@ -2538,6 +2538,26 @@ resource "test_resource" "a" {
t.Fatalf("unexpected %s change for %s", res.Action, res.Addr)
}
}
addr := mustResourceInstanceAddr("data.test_data_source.a")
wantCheckTypes := []addrs.CheckType{
addrs.ResourcePrecondition,
addrs.ResourcePostcondition,
}
for _, ty := range wantCheckTypes {
checkAddr := addr.Check(ty, 0)
if result, ok := plan.Conditions[checkAddr.String()]; !ok {
t.Errorf("no condition result for %s", checkAddr)
} else {
wantResult := &plans.ConditionResult{
Address: addr,
Result: cty.True,
Type: ty,
}
if diff := cmp.Diff(wantResult, result, valueComparer); diff != "" {
t.Errorf("wrong condition result for %s\n%s", checkAddr, diff)
}
}
}
})
t.Run("precondition fail", func(t *testing.T) {
@ -2628,7 +2648,7 @@ resource "test_resource" "a" {
"results": cty.ListValEmpty(cty.String),
}),
}
_, diags := ctx.Plan(m, states.NewState(), &PlanOpts{
plan, diags := ctx.Plan(m, states.NewState(), &PlanOpts{
Mode: plans.RefreshOnlyMode,
SetVariables: InputValues{
"boop": &InputValue{
@ -2641,6 +2661,21 @@ resource "test_resource" "a" {
if got, want := diags.ErrWithWarnings().Error(), "Resource postcondition failed: Results cannot be empty."; got != want {
t.Fatalf("wrong error:\ngot: %s\nwant: %q", got, want)
}
addr := mustResourceInstanceAddr("data.test_data_source.a")
checkAddr := addr.Check(addrs.ResourcePostcondition, 0)
if result, ok := plan.Conditions[checkAddr.String()]; !ok {
t.Errorf("no condition result for %s", checkAddr)
} else {
wantResult := &plans.ConditionResult{
Address: addr,
Result: cty.False,
Type: addrs.ResourcePostcondition,
ErrorMessage: "Results cannot be empty.",
}
if diff := cmp.Diff(wantResult, result, valueComparer); diff != "" {
t.Errorf("wrong condition result\n%s", diff)
}
}
})
t.Run("precondition and postcondition fail refresh-only", func(t *testing.T) {
@ -2727,6 +2762,19 @@ output "a" {
if got, want := outputPlan.Action, plans.Create; got != want {
t.Errorf("wrong planned action\ngot: %s\nwant: %s", got, want)
}
checkAddr := addr.Check(addrs.OutputPrecondition, 0)
if result, ok := plan.Conditions[checkAddr.String()]; !ok {
t.Errorf("no condition result for %s", checkAddr)
} else {
wantResult := &plans.ConditionResult{
Address: addr,
Result: cty.True,
Type: addrs.OutputPrecondition,
}
if diff := cmp.Diff(wantResult, result, valueComparer); diff != "" {
t.Errorf("wrong condition result\n%s", diff)
}
}
})
t.Run("condition fail", func(t *testing.T) {
@ -2775,6 +2823,20 @@ output "a" {
if got, want := outputPlan.Action, plans.Create; got != want {
t.Errorf("wrong planned action\ngot: %s\nwant: %s", got, want)
}
checkAddr := addr.Check(addrs.OutputPrecondition, 0)
if result, ok := plan.Conditions[checkAddr.String()]; !ok {
t.Errorf("no condition result for %s", checkAddr)
} else {
wantResult := &plans.ConditionResult{
Address: addr,
Result: cty.False,
Type: addrs.OutputPrecondition,
ErrorMessage: "Wrong boop.",
}
if diff := cmp.Diff(wantResult, result, valueComparer); diff != "" {
t.Errorf("wrong condition result\n%s", diff)
}
}
})
}

View File

@ -21,6 +21,7 @@ import (
type graphWalkOpts struct {
InputState *states.State
Changes *plans.Changes
Conditions plans.Conditions
Config *configs.Config
MoveResults refactoring.MoveResults
@ -91,6 +92,12 @@ func (c *Context) graphWalker(operation walkOperation, opts *graphWalkOpts) *Con
// afterwards.
changes = plans.NewChanges()
}
conditions := opts.Conditions
if conditions == nil {
// This fallback conditions object is in place for the same reason as
// the changes object above: to avoid crashes for non-plan walks.
conditions = plans.NewConditions()
}
if opts.Config == nil {
panic("Context.graphWalker call without Config")
@ -103,6 +110,7 @@ func (c *Context) graphWalker(operation walkOperation, opts *graphWalkOpts) *Con
RefreshState: refreshState,
PrevRunState: prevRunState,
Changes: changes.SyncWrapper(),
Conditions: conditions.SyncWrapper(),
InstanceExpander: instances.NewExpander(),
MoveResults: opts.MoveResults,
Operation: operation,

View File

@ -14,32 +14,10 @@ import (
"github.com/hashicorp/terraform/internal/instances"
"github.com/hashicorp/terraform/internal/lang"
"github.com/hashicorp/terraform/internal/lang/marks"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/tfdiags"
)
type checkType int
const (
checkInvalid checkType = 0
checkResourcePrecondition checkType = 1
checkResourcePostcondition checkType = 2
checkOutputPrecondition checkType = 3
)
func (c checkType) FailureSummary() string {
switch c {
case checkResourcePrecondition:
return "Resource precondition failed"
case checkResourcePostcondition:
return "Resource postcondition failed"
case checkOutputPrecondition:
return "Module output value precondition failed"
default:
// This should not happen
return "Failed condition for invalid check type"
}
}
// evalCheckRules ensures that all of the given check rules pass against
// the given HCL evaluation context.
//
@ -49,7 +27,9 @@ func (c checkType) FailureSummary() string {
//
// If any of the rules do not pass, the returned diagnostics will contain
// errors. Otherwise, it will either be empty or contain only warnings.
func evalCheckRules(typ checkType, rules []*configs.CheckRule, ctx EvalContext, self addrs.Referenceable, keyData instances.RepetitionData, diagSeverity tfdiags.Severity) (diags tfdiags.Diagnostics) {
func evalCheckRules(typ addrs.CheckType, rules []*configs.CheckRule, ctx EvalContext, self addrs.Checkable, keyData instances.RepetitionData, diagSeverity tfdiags.Severity) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
if len(rules) == 0 {
// Nothing to do
return nil
@ -57,35 +37,63 @@ func evalCheckRules(typ checkType, rules []*configs.CheckRule, ctx EvalContext,
severity := diagSeverity.ToHCL()
for _, rule := range rules {
for i, rule := range rules {
checkAddr := self.Check(typ, i)
conditionResult, ruleDiags := evalCheckRule(typ, rule, ctx, self, keyData, severity)
diags = diags.Append(ruleDiags)
ctx.Conditions().SetResult(checkAddr, conditionResult)
}
return diags
}
func evalCheckRule(typ addrs.CheckType, rule *configs.CheckRule, ctx EvalContext, self addrs.Checkable, keyData instances.RepetitionData, severity hcl.DiagnosticSeverity) (*plans.ConditionResult, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
const errInvalidCondition = "Invalid condition result"
var ruleDiags tfdiags.Diagnostics
refs, moreDiags := lang.ReferencesInExpr(rule.Condition)
ruleDiags = ruleDiags.Append(moreDiags)
diags = diags.Append(moreDiags)
moreRefs, moreDiags := lang.ReferencesInExpr(rule.ErrorMessage)
ruleDiags = ruleDiags.Append(moreDiags)
diags = diags.Append(moreDiags)
refs = append(refs, moreRefs...)
scope := ctx.EvaluationScope(self, keyData)
conditionResult := &plans.ConditionResult{
Address: self,
Result: cty.UnknownVal(cty.Bool),
Type: typ,
}
var selfReference addrs.Referenceable
// Only resource postconditions can refer to self
if typ == addrs.ResourcePostcondition {
switch s := self.(type) {
case addrs.AbsResourceInstance:
selfReference = s.Resource
default:
panic(fmt.Sprintf("Invalid self reference type %t", self))
}
}
scope := ctx.EvaluationScope(selfReference, keyData)
hclCtx, moreDiags := scope.EvalContext(refs)
ruleDiags = ruleDiags.Append(moreDiags)
diags = diags.Append(moreDiags)
result, hclDiags := rule.Condition.Value(hclCtx)
ruleDiags = ruleDiags.Append(hclDiags)
diags = diags.Append(hclDiags)
errorValue, errorDiags := rule.ErrorMessage.Value(hclCtx)
ruleDiags = ruleDiags.Append(errorDiags)
diags = diags.Append(errorDiags)
diags = diags.Append(ruleDiags)
if ruleDiags.HasErrors() {
log.Printf("[TRACE] evalCheckRules: %s: %s", typ.FailureSummary(), ruleDiags.Err().Error())
if diags.HasErrors() {
log.Printf("[TRACE] evalCheckRule: %s: %s", typ, diags.Err().Error())
}
if !result.IsKnown() {
continue // We'll wait until we've learned more, then.
// We'll wait until we've learned more, then.
return conditionResult, diags
}
if result.IsNull() {
diags = diags.Append(&hcl.Diagnostic{
Severity: severity,
@ -95,28 +103,34 @@ func evalCheckRules(typ checkType, rules []*configs.CheckRule, ctx EvalContext,
Expression: rule.Condition,
EvalContext: hclCtx,
})
continue
conditionResult.Result = cty.False
conditionResult.ErrorMessage = "Condition expression must return either true or false, not null."
return conditionResult, diags
}
var err error
result, err = convert.Convert(result, cty.Bool)
if err != nil {
detail := fmt.Sprintf("Invalid condition result value: %s.", tfdiags.FormatError(err))
diags = diags.Append(&hcl.Diagnostic{
Severity: severity,
Summary: errInvalidCondition,
Detail: fmt.Sprintf("Invalid condition result value: %s.", tfdiags.FormatError(err)),
Detail: detail,
Subject: rule.Condition.Range().Ptr(),
Expression: rule.Condition,
EvalContext: hclCtx,
})
continue
conditionResult.Result = cty.False
conditionResult.ErrorMessage = detail
return conditionResult, diags
}
// The condition result may be marked if the expression refers to a
// sensitive value.
result, _ = result.Unmark()
conditionResult.Result = result
if result.True() {
continue
return conditionResult, diags
}
var errorMessage string
@ -157,13 +171,12 @@ You can correct this by removing references to sensitive values, or by carefully
}
diags = diags.Append(&hcl.Diagnostic{
Severity: severity,
Summary: typ.FailureSummary(),
Summary: fmt.Sprintf("%s failed", typ.Description()),
Detail: errorMessage,
Subject: rule.Condition.Range().Ptr(),
Expression: rule.Condition,
EvalContext: hclCtx,
})
}
return diags
conditionResult.ErrorMessage = errorMessage
return conditionResult, diags
}

View File

@ -159,6 +159,10 @@ type EvalContext interface {
// the global state.
State() *states.SyncState
// Conditions returns the writer object that can be used to store condition
// block results as they are evaluated.
Conditions() *plans.ConditionsSync
// RefreshState returns a wrapper object that provides safe concurrent
// access to the state used to store the most recently refreshed resource
// values.

View File

@ -66,6 +66,7 @@ type BuiltinEvalContext struct {
ProvisionerLock *sync.Mutex
ChangesValue *plans.ChangesSync
StateValue *states.SyncState
ConditionsValue *plans.ConditionsSync
RefreshStateValue *states.SyncState
PrevRunStateValue *states.SyncState
InstanceExpanderValue *instances.Expander
@ -367,6 +368,10 @@ func (ctx *BuiltinEvalContext) State() *states.SyncState {
return ctx.StateValue
}
func (ctx *BuiltinEvalContext) Conditions() *plans.ConditionsSync {
return ctx.ConditionsValue
}
func (ctx *BuiltinEvalContext) RefreshState() *states.SyncState {
return ctx.RefreshStateValue
}

View File

@ -133,6 +133,9 @@ type MockEvalContext struct {
StateCalled bool
StateState *states.SyncState
ConditionsCalled bool
ConditionsConditions *plans.ConditionsSync
RefreshStateCalled bool
RefreshStateState *states.SyncState
@ -367,6 +370,11 @@ func (c *MockEvalContext) State() *states.SyncState {
return c.StateState
}
func (c *MockEvalContext) Conditions() *plans.ConditionsSync {
c.ConditionsCalled = true
return c.ConditionsConditions
}
func (c *MockEvalContext) RefreshState() *states.SyncState {
c.RefreshStateCalled = true
return c.RefreshStateState

View File

@ -29,6 +29,7 @@ type ContextGraphWalker struct {
RefreshState *states.SyncState // Used for safe concurrent access to state
PrevRunState *states.SyncState // Used for safe concurrent access to state
Changes *plans.ChangesSync // Used for safe concurrent writes to changes
Conditions *plans.ConditionsSync // Used for safe concurrent writes to conditions
InstanceExpander *instances.Expander // Tracks our gradual expansion of module and resource instances
MoveResults refactoring.MoveResults // Read-only record of earlier processing of move statements
Operation walkOperation
@ -98,6 +99,7 @@ func (w *ContextGraphWalker) EvalContext() EvalContext {
ProvisionerCache: w.provisionerCache,
ProvisionerLock: &w.provisionerLock,
ChangesValue: w.Changes,
ConditionsValue: w.Conditions,
StateValue: w.State,
RefreshStateValue: w.RefreshState,
PrevRunStateValue: w.PrevRunState,

View File

@ -281,9 +281,9 @@ func (n *NodeApplyableOutput) Execute(ctx EvalContext, op walkOperation) (diags
checkRuleSeverity = tfdiags.Warning
}
checkDiags := evalCheckRules(
checkOutputPrecondition,
addrs.OutputPrecondition,
n.Config.Preconditions,
ctx, nil, EvalDataForNoInstanceKey,
ctx, n.Addr, EvalDataForNoInstanceKey,
checkRuleSeverity,
)
diags = diags.Append(checkDiags)

View File

@ -652,9 +652,9 @@ func (n *NodeAbstractResourceInstance) plan(
keyData = EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, forEach)
checkDiags := evalCheckRules(
checkResourcePrecondition,
addrs.ResourcePrecondition,
n.Config.Preconditions,
ctx, nil, keyData,
ctx, n.Addr, keyData,
tfdiags.Error,
)
diags = diags.Append(checkDiags)
@ -1508,9 +1508,9 @@ func (n *NodeAbstractResourceInstance) planDataSource(ctx EvalContext, currentSt
keyData = EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, forEach)
checkDiags := evalCheckRules(
checkResourcePrecondition,
addrs.ResourcePrecondition,
n.Config.Preconditions,
ctx, nil, keyData,
ctx, n.Addr, keyData,
checkRuleSeverity,
)
diags = diags.Append(checkDiags)
@ -1688,9 +1688,9 @@ func (n *NodeAbstractResourceInstance) applyDataSource(ctx EvalContext, planned
keyData = EvalDataForInstanceKey(n.Addr.Resource.Key, forEach)
checkDiags := evalCheckRules(
checkResourcePrecondition,
addrs.ResourcePrecondition,
n.Config.Preconditions,
ctx, nil, keyData,
ctx, n.Addr, keyData,
tfdiags.Error,
)
diags = diags.Append(checkDiags)

View File

@ -180,9 +180,9 @@ func (n *NodeApplyableResourceInstance) dataResourceExecute(ctx EvalContext) (di
// the result of the operation, and to fail on future operations
// until the user makes the condition succeed.
checkDiags := evalCheckRules(
checkResourcePostcondition,
addrs.ResourcePostcondition,
n.Config.Postconditions,
ctx, n.ResourceInstanceAddr().Resource,
ctx, n.ResourceInstanceAddr(),
repeatData,
tfdiags.Error,
)
@ -359,9 +359,9 @@ func (n *NodeApplyableResourceInstance) managedResourceExecute(ctx EvalContext)
// the result of the operation, and to fail on future operations
// until the user makes the condition succeed.
checkDiags := evalCheckRules(
checkResourcePostcondition,
addrs.ResourcePostcondition,
n.Config.Postconditions,
ctx, addr, repeatData,
ctx, n.ResourceInstanceAddr(), repeatData,
tfdiags.Error,
)
diags = diags.Append(checkDiags)

View File

@ -124,9 +124,9 @@ func (n *NodePlannableResourceInstance) dataResourceExecute(ctx EvalContext) (di
// the result of the operation, and to fail on future operations
// until the user makes the condition succeed.
checkDiags := evalCheckRules(
checkResourcePostcondition,
addrs.ResourcePostcondition,
n.Config.Postconditions,
ctx, addr.Resource, repeatData,
ctx, addr, repeatData,
checkRuleSeverity,
)
diags = diags.Append(checkDiags)
@ -266,9 +266,9 @@ func (n *NodePlannableResourceInstance) managedResourceExecute(ctx EvalContext)
// (Note that some preconditions will end up being skipped during
// planning, because their conditions depend on values not yet known.)
checkDiags := evalCheckRules(
checkResourcePostcondition,
addrs.ResourcePostcondition,
n.Config.Postconditions,
ctx, addr.Resource, repeatData,
ctx, n.ResourceInstanceAddr(), repeatData,
tfdiags.Error,
)
diags = diags.Append(checkDiags)
@ -284,9 +284,9 @@ func (n *NodePlannableResourceInstance) managedResourceExecute(ctx EvalContext)
repeatData := EvalDataForInstanceKey(n.ResourceInstanceAddr().Resource.Key, forEach)
checkDiags := evalCheckRules(
checkResourcePrecondition,
addrs.ResourcePrecondition,
n.Config.Preconditions,
ctx, nil, repeatData,
ctx, addr, repeatData,
tfdiags.Warning,
)
diags = diags.Append(checkDiags)
@ -307,9 +307,9 @@ func (n *NodePlannableResourceInstance) managedResourceExecute(ctx EvalContext)
// even if pre-conditions generated diagnostics, because we have no
// planned changes to block.
checkDiags = evalCheckRules(
checkResourcePostcondition,
addrs.ResourcePostcondition,
n.Config.Postconditions,
ctx, addr.Resource, repeatData,
ctx, addr, repeatData,
tfdiags.Warning,
)
diags = diags.Append(checkDiags)