mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
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:
parent
1e56e1fe0f
commit
c5d10bdef1
86
internal/addrs/check.go
Normal file
86
internal/addrs/check.go
Normal 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"
|
||||
}
|
||||
}
|
26
internal/addrs/checktype_string.go
Normal file
26
internal/addrs/checktype_string.go
Normal 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]]
|
||||
}
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
26
internal/command/jsonplan/condition.go
Normal file
26
internal/command/jsonplan/condition.go
Normal 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"`
|
||||
}
|
@ -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)
|
||||
|
@ -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"
|
||||
|
39
internal/command/testdata/show-json/conditions/for-refresh.tfstate
vendored
Normal file
39
internal/command/testdata/show-json/conditions/for-refresh.tfstate
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
44
internal/command/testdata/show-json/conditions/main.tf
vendored
Normal file
44
internal/command/testdata/show-json/conditions/main.tf
vendored
Normal 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!"
|
||||
}
|
||||
}
|
165
internal/command/testdata/show-json/conditions/output-refresh-only.json
vendored
Normal file
165
internal/command/testdata/show-json/conditions/output-refresh-only.json
vendored
Normal 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-\"."
|
||||
}
|
||||
]
|
||||
}
|
188
internal/command/testdata/show-json/conditions/output.json
vendored
Normal file
188
internal/command/testdata/show-json/conditions/output.json
vendored
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
53
internal/plans/conditions.go
Normal file
53
internal/plans/conditions.go
Normal 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
|
||||
}
|
@ -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,
|
||||
},
|
||||
|
@ -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.
|
||||
//
|
||||
|
@ -32,6 +32,7 @@ type Plan struct {
|
||||
|
||||
VariableValues map[string]DynamicValue
|
||||
Changes *Changes
|
||||
Conditions Conditions
|
||||
DriftedResources []*ResourceInstanceChangeSrc
|
||||
TargetAddrs []addrs.Targetable
|
||||
ForceReplaceAddrs []addrs.AbsResourceInstance
|
||||
|
@ -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{},
|
||||
|
@ -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 {
|
||||
|
@ -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{
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user