diff --git a/internal/addrs/instance_key.go b/internal/addrs/instance_key.go index bb2ac0149b49..cfd918af2862 100644 --- a/internal/addrs/instance_key.go +++ b/internal/addrs/instance_key.go @@ -53,6 +53,11 @@ func ParseInstanceKey(key cty.Value) (InstanceKey, error) { // of a configuration object that does not use "count" or "for_each" at all. var NoKey InstanceKey +// WildcardKey represents the "unknown" value of an InstanceKey. This is used +// within the deferral logic to express absolute module and resource addresses +// that are not known at the time of planning. +var WildcardKey InstanceKey = StringKey("*") + // IntKey is the InstanceKey representation representing integer indices, as // used when the "count" argument is specified or if for_each is used with // a sequence type. diff --git a/internal/addrs/partial_expanded.go b/internal/addrs/partial_expanded.go index 6b2cac149b8e..2bc9f86f5b35 100644 --- a/internal/addrs/partial_expanded.go +++ b/internal/addrs/partial_expanded.go @@ -36,6 +36,19 @@ func (m ModuleInstance) UnexpandedChild(call ModuleCall) PartialExpandedModule { } } +// UnknownModuleInstance expands the receiver to a full ModuleInstance by +// replacing the unknown instance keys with a wildcard value. +func (pem PartialExpandedModule) UnknownModuleInstance() ModuleInstance { + base := pem.expandedPrefix + for _, call := range pem.unexpandedSuffix { + base = append(base, ModuleInstanceStep{ + Name: call, + InstanceKey: WildcardKey, + }) + } + return base +} + // LevelsKnown returns the number of module path segments of the address that // have known instance keys. // @@ -195,8 +208,8 @@ func (pem PartialExpandedModule) String() string { return buf.String() } -func (per PartialExpandedModule) UniqueKey() UniqueKey { - return partialExpandedModuleKey(per.String()) +func (pem PartialExpandedModule) UniqueKey() UniqueKey { + return partialExpandedModuleKey(pem.String()) } type partialExpandedModuleKey string @@ -261,6 +274,16 @@ func (r AbsResource) UnexpandedResource() PartialExpandedResource { } } +// UnknownResourceInstance returns an [AbsResourceInstance] that represents the +// same resource as the receiver but with all instance keys replaced with a +// wildcard value. +func (per PartialExpandedResource) UnknownResourceInstance() AbsResourceInstance { + return AbsResourceInstance{ + Module: per.module.UnknownModuleInstance(), + Resource: per.resource.Instance(WildcardKey), + } +} + // MatchesInstance returns true if and only if the given resource instance // belongs to the recieving partially-expanded resource address pattern. func (per PartialExpandedResource) MatchesInstance(inst AbsResourceInstance) bool { diff --git a/internal/plans/deferring.go b/internal/plans/deferring.go new file mode 100644 index 000000000000..4d52ee5f359c --- /dev/null +++ b/internal/plans/deferring.go @@ -0,0 +1,80 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package plans + +import "github.com/zclconf/go-cty/cty" + +type DeferredReason string + +const ( + // DeferredReasonInvalid is used when the reason for deferring is + // unknown or irrelevant. + DeferredReasonInvalid DeferredReason = "invalid" + + // DeferredReasonInstanceCountUnknown is used when the reason for deferring + // is that the count or for_each meta-attribute was unknown. + DeferredReasonInstanceCountUnknown DeferredReason = "instance_count_unknown" + + // DeferredReasonResourceConfigUnknown is used when the reason for deferring + // is that the resource configuration was unknown. + DeferredReasonResourceConfigUnknown DeferredReason = "resource_config_unknown" + + // DeferredReasonProviderConfigUnknown is used when the reason for deferring + // is that the provider configuration was unknown. + DeferredReasonProviderConfigUnknown DeferredReason = "provider_config_unknown" + + // DeferredReasonAbsentPrereq is used when the reason for deferring is that + // a required prerequisite resource was absent. + DeferredReasonAbsentPrereq DeferredReason = "absent_prereq" + + // DeferredReasonDeferredPrereq is used when the reason for deferring is + // that a required prerequisite resource was itself deferred. + DeferredReasonDeferredPrereq DeferredReason = "deferred_prereq" +) + +// DeferredResourceInstanceChangeSrc tracks information about a resource that +// has been deferred for some reason. +type DeferredResourceInstanceChangeSrc struct { + // DeferredReason is the reason why this resource instance was deferred. + DeferredReason DeferredReason + + // ChangeSrc contains any information we have about the deferred change. + // This could be incomplete so must be parsed with care. + ChangeSrc *ResourceInstanceChangeSrc +} + +func (rcs *DeferredResourceInstanceChangeSrc) Decode(ty cty.Type) (*DeferredResourceInstanceChange, error) { + change, err := rcs.ChangeSrc.Decode(ty) + if err != nil { + return nil, err + } + + return &DeferredResourceInstanceChange{ + DeferredReason: rcs.DeferredReason, + Change: change, + }, nil +} + +// DeferredResourceInstanceChange tracks information about a resource that +// has been deferred for some reason. +type DeferredResourceInstanceChange struct { + // DeferredReason is the reason why this resource instance was deferred. + DeferredReason DeferredReason + + // Change contains any information we have about the deferred change. This + // could be incomplete so must be parsed with care. + Change *ResourceInstanceChange +} + +func (rcs *DeferredResourceInstanceChange) Encode(ty cty.Type) (*DeferredResourceInstanceChangeSrc, error) { + change, err := rcs.Change.Encode(ty) + if err != nil { + return nil, err + } + + return &DeferredResourceInstanceChangeSrc{ + DeferredReason: rcs.DeferredReason, + ChangeSrc: change, + }, nil +} diff --git a/internal/plans/deferring/deferred.go b/internal/plans/deferring/deferred.go index 35c0bc52f555..a553199197bf 100644 --- a/internal/plans/deferring/deferred.go +++ b/internal/plans/deferring/deferred.go @@ -7,8 +7,6 @@ import ( "fmt" "sync" - "github.com/zclconf/go-cty/cty" - "github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/plans" ) @@ -65,7 +63,7 @@ type Deferred struct { // configuration block at different amounts of instance expansion under // different prefixes, and so some queries require us to search across // all of those options to decide if each instance is relevant. - resourceInstancesDeferred addrs.Map[addrs.ConfigResource, addrs.Map[addrs.AbsResourceInstance, deferredResourceInstance]] + resourceInstancesDeferred addrs.Map[addrs.ConfigResource, addrs.Map[addrs.AbsResourceInstance, *plans.DeferredResourceInstanceChange]] // partialExpandedResourcesDeferred tracks placeholders that cover an // unbounded set of potential resource instances in situations where we @@ -77,7 +75,17 @@ type Deferred struct { // configuration block at different amounts of instance expansion under // different prefixes, and so some queries require us to search across // all of those options to find the one that matches most closely. - partialExpandedResourcesDeferred addrs.Map[addrs.ConfigResource, addrs.Map[addrs.PartialExpandedResource, deferredPartialExpandedResource]] + partialExpandedResourcesDeferred addrs.Map[addrs.ConfigResource, addrs.Map[addrs.PartialExpandedResource, *plans.DeferredResourceInstanceChange]] + + // partialExpandedDataSourcesDeferred tracks placeholders that cover an + // unbounded set of potential data sources in situations where we don't yet + // even have enough information to predict which instances of a data source + // will exist. + // + // Data sources are never written into the plan, even when deferred, so we + // are tracking these for purely internal reasons. If a resource depends on + // a deferred data source, then that resource should be deferred as well. + partialExpandedDataSourcesDeferred addrs.Map[addrs.ConfigResource, addrs.Set[addrs.PartialExpandedResource]] // partialExpandedModulesDeferred tracks all of the partial-expanded module // prefixes we were notified about. @@ -103,12 +111,30 @@ type Deferred struct { // calling this function. func NewDeferred(resourceGraph addrs.DirectedGraph[addrs.ConfigResource], enabled bool) *Deferred { return &Deferred{ - resourceGraph: resourceGraph, - deferralAllowed: enabled, - resourceInstancesDeferred: addrs.MakeMap[addrs.ConfigResource, addrs.Map[addrs.AbsResourceInstance, deferredResourceInstance]](), - partialExpandedResourcesDeferred: addrs.MakeMap[addrs.ConfigResource, addrs.Map[addrs.PartialExpandedResource, deferredPartialExpandedResource]](), - partialExpandedModulesDeferred: addrs.MakeSet[addrs.PartialExpandedModule](), + resourceGraph: resourceGraph, + deferralAllowed: enabled, + resourceInstancesDeferred: addrs.MakeMap[addrs.ConfigResource, addrs.Map[addrs.AbsResourceInstance, *plans.DeferredResourceInstanceChange]](), + partialExpandedResourcesDeferred: addrs.MakeMap[addrs.ConfigResource, addrs.Map[addrs.PartialExpandedResource, *plans.DeferredResourceInstanceChange]](), + partialExpandedDataSourcesDeferred: addrs.MakeMap[addrs.ConfigResource, addrs.Set[addrs.PartialExpandedResource]](), + partialExpandedModulesDeferred: addrs.MakeSet[addrs.PartialExpandedModule](), + } +} + +// GetDeferredChanges returns a slice of all the deferred changes that have +// been reported to the receiver. +func (d *Deferred) GetDeferredChanges() []*plans.DeferredResourceInstanceChange { + var changes []*plans.DeferredResourceInstanceChange + for _, configMapElem := range d.resourceInstancesDeferred.Elems { + for _, changeElem := range configMapElem.Value.Elems { + changes = append(changes, changeElem.Value) + } + } + for _, configMapElem := range d.partialExpandedResourcesDeferred.Elems { + for _, changeElem := range configMapElem.Value.Elems { + changes = append(changes, changeElem.Value) + } } + return changes } // SetExternalDependencyDeferred modifies a freshly-constructed [Deferred] @@ -146,12 +172,13 @@ func (d *Deferred) HaveAnyDeferrals() bool { (d.externalDependencyDeferred || d.resourceInstancesDeferred.Len() != 0 || d.partialExpandedResourcesDeferred.Len() != 0 || + d.partialExpandedDataSourcesDeferred.Len() != 0 || len(d.partialExpandedModulesDeferred) != 0) } -// ShouldDeferResourceChanges returns true if the receiver knows some reason -// why the resource instance with the given address should have its planned -// action deferred for a future plan/apply round. +// ShouldDeferResourceInstanceChanges returns true if the receiver knows some +// reason why the resource instance with the given address should have its +// planned action deferred for a future plan/apply round. // // This method is specifically for resource instances whose full address is // known and thus it would be possible in principle to plan changes, but we @@ -181,7 +208,9 @@ func (d *Deferred) ShouldDeferResourceInstanceChanges(addr addrs.AbsResourceInst // when the deferred-actions-related experiments are inactive, so we can // minimize the risk of impacting non-participants. // (Maybe we'll remove this check once this stuff is non-experimental.) - if d.resourceInstancesDeferred.Len() == 0 && d.partialExpandedResourcesDeferred.Len() == 0 { + if d.resourceInstancesDeferred.Len() == 0 && + d.partialExpandedResourcesDeferred.Len() == 0 && + d.partialExpandedDataSourcesDeferred.Len() == 0 { return false } @@ -238,6 +267,9 @@ func (d *Deferred) ShouldDeferResourceInstanceChanges(addr addrs.AbsResourceInst // at least one is enough. return true } + if d.partialExpandedDataSourcesDeferred.Has(configDep) { + return true + } // We don't check d.partialExpandedModulesDeferred here because // we expect that the graph nodes representing any resource under @@ -256,18 +288,18 @@ func (d *Deferred) ShouldDeferResourceInstanceChanges(addr addrs.AbsResourceInst // ReportResourceExpansionDeferred reports that we cannot even predict which // instances of a resource will be declared and thus we must defer all planning // for that resource. -// -// Use the most precise partial-expanded resource address possible, and provide -// a valuePlaceholder that has known values only for attributes/elements that -// we can guarantee will be equal across all potential resource instances -// under the partial-expanded prefix. -func (d *Deferred) ReportResourceExpansionDeferred(addr addrs.PartialExpandedResource, valuePlaceholder cty.Value) { +func (d *Deferred) ReportResourceExpansionDeferred(addr addrs.PartialExpandedResource, change *plans.ResourceInstanceChange) { d.mu.Lock() defer d.mu.Unlock() + if addr.Resource().Mode != addrs.ManagedResourceMode { + // Use ReportDataSourceExpansionDeferred for data sources. + panic(fmt.Sprintf("unexpected resource mode %q for %s", addr.Resource().Mode, addr)) + } + configAddr := addr.ConfigResource() if !d.partialExpandedResourcesDeferred.Has(configAddr) { - d.partialExpandedResourcesDeferred.Put(configAddr, addrs.MakeMap[addrs.PartialExpandedResource, deferredPartialExpandedResource]()) + d.partialExpandedResourcesDeferred.Put(configAddr, addrs.MakeMap[addrs.PartialExpandedResource, *plans.DeferredResourceInstanceChange]()) } configMap := d.partialExpandedResourcesDeferred.Get(configAddr) @@ -277,39 +309,49 @@ func (d *Deferred) ReportResourceExpansionDeferred(addr addrs.PartialExpandedRes // prefix only once. panic(fmt.Sprintf("duplicate deferral report for %s", addr)) } - configMap.Put(addr, deferredPartialExpandedResource{ - valuePlaceholder: valuePlaceholder, + configMap.Put(addr, &plans.DeferredResourceInstanceChange{ + DeferredReason: plans.DeferredReasonInstanceCountUnknown, + Change: change, }) } +// ReportDataSourceExpansionDeferred reports that we cannot even predict which +// instances of a data source will be declared and thus we must defer all +// planning for that data source. +func (d *Deferred) ReportDataSourceExpansionDeferred(addr addrs.PartialExpandedResource) { + d.mu.Lock() + defer d.mu.Unlock() + + if addr.Resource().Mode != addrs.DataResourceMode { + // Use ReportResourceExpansionDeferred for resources. + panic(fmt.Sprintf("unexpected resource mode %q for %s", addr.Resource().Mode, addr)) + } + + configAddr := addr.ConfigResource() + if !d.partialExpandedDataSourcesDeferred.Has(configAddr) { + d.partialExpandedDataSourcesDeferred.Put(configAddr, addrs.MakeSet[addrs.PartialExpandedResource]()) + } + + configSet := d.partialExpandedDataSourcesDeferred.Get(configAddr) + if configSet.Has(addr) { + // This indicates a bug in the caller, since our graph walk should + // ensure that we visit and evaluate each distinct partial-expanded + // prefix only once. + panic(fmt.Sprintf("duplicate deferral report for %s", addr)) + } + configSet.Add(addr) +} + // ReportResourceInstanceDeferred records that a fully-expanded resource // instance has had its planned action deferred to a future round for a reason // other than its address being only partially-decided. -// -// For example, this is the method to use if the reason for deferral is -// that [Deferred.ShouldDeferResourceInstanceChanges] returns true for the -// same address, or if the responsible provider indicated in its planning -// response that it does not have enough information to produce a final -// plan. -// -// expectedAction and expectedValue together provide an approximation of -// what Terraform is expecting to plan in a future round. expectedAction may -// be [plans.Undecided] if there isn't even enough information to decide on -// an action. expectedValue should use unknown values to stand in for values -// that cannot be predicted while being as precise as is practical; in the -// worst case it's okay to provide a totally-unknown value, but better to -// provide a known object with unknown values inside it when possible. -// -// TODO: Allow the caller to pass something representing the reason for the -// deferral, so we can distinguish between the different variations in the -// plan reported to the operator. -func (d *Deferred) ReportResourceInstanceDeferred(addr addrs.AbsResourceInstance, expectedAction plans.Action, expectedValue cty.Value) { +func (d *Deferred) ReportResourceInstanceDeferred(addr addrs.AbsResourceInstance, reason plans.DeferredReason, change *plans.ResourceInstanceChange) { d.mu.Lock() defer d.mu.Unlock() configAddr := addr.ConfigResource() if !d.resourceInstancesDeferred.Has(configAddr) { - d.resourceInstancesDeferred.Put(configAddr, addrs.MakeMap[addrs.AbsResourceInstance, deferredResourceInstance]()) + d.resourceInstancesDeferred.Put(configAddr, addrs.MakeMap[addrs.AbsResourceInstance, *plans.DeferredResourceInstanceChange]()) } configMap := d.resourceInstancesDeferred.Get(configAddr) @@ -318,9 +360,9 @@ func (d *Deferred) ReportResourceInstanceDeferred(addr addrs.AbsResourceInstance // ensure that we visit and evaluate each resource instance only once. panic(fmt.Sprintf("duplicate deferral report for %s", addr)) } - configMap.Put(addr, deferredResourceInstance{ - plannedAction: expectedAction, - plannedValue: expectedValue, + configMap.Put(addr, &plans.DeferredResourceInstanceChange{ + DeferredReason: reason, + Change: change, }) } diff --git a/internal/plans/deferring/deferred_partial_expanded_resource.go b/internal/plans/deferring/deferred_partial_expanded_resource.go deleted file mode 100644 index 2f97f230c283..000000000000 --- a/internal/plans/deferring/deferred_partial_expanded_resource.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package deferring - -import ( - "github.com/zclconf/go-cty/cty" -) - -// deferredPartialExpandedResource tracks placeholder information for an -// unbounded set of potential resource instances sharing a common known -// address prefix. -// -// This is for situations where we can't even predict which instances of -// a resource will be declared, due to a count or for_each argument being -// unknown. The unknown repetition argument could either be on the resource -// itself or on one of its ancestor module calls. -type deferredPartialExpandedResource struct { - // valuePlaceholder is a placeholder value describes what all of the - // potential instances in the unbounded set represented by this object - // have in common, using unknown values for any parts where we cannot - // guarantee that all instances will agree. - valuePlaceholder cty.Value -} diff --git a/internal/plans/deferring/deferred_resource_instance.go b/internal/plans/deferring/deferred_resource_instance.go deleted file mode 100644 index 7ce4ade0bf99..000000000000 --- a/internal/plans/deferring/deferred_resource_instance.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package deferring - -import ( - "github.com/hashicorp/terraform/internal/plans" - "github.com/zclconf/go-cty/cty" -) - -// deferredResourceInstance tracks information about a resource instance whose -// address is precisely known but whose planned action has been deferred for -// some other reason. -type deferredResourceInstance struct { - // plannedAction is the action that Terraform expects to take for this - // resource instance in a future round. - // - // This can be set to plans.Undecided in situations where there isn't - // even enough information to decide what the action would be. - plannedAction plans.Action - - // plannedValue is an approximation of the value that Terraform expects - // to plan for this resource instance in a future round, using unknown - // values in locations where a concrete value cannot yet be decided. - // - // In the most extreme case, plannedValue could be cty.DynamicVal to - // reflect that we know nothing at all about the resource instance, or - // an unknown value of the resource instance's schema type if the values - // are completely unknown but we've at least got enough information to - // approximate the type of the value. - // - // However, ideally this should be a known object value that potentially - // has unknown values for individual attributes inside, since that gives - // the most context to aid in finding errors that would definitely arise - // on a future round, and thus shorten the iteration time to find that - // problem. - plannedValue cty.Value -} diff --git a/internal/plans/deferring/deferred_test.go b/internal/plans/deferring/deferred_test.go index 2f9e8a16be4e..1a9a7a7984fb 100644 --- a/internal/plans/deferring/deferred_test.go +++ b/internal/plans/deferring/deferred_test.go @@ -6,9 +6,10 @@ package deferring import ( "testing" + "github.com/zclconf/go-cty/cty" + "github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/plans" - "github.com/zclconf/go-cty/cty" ) func TestDeferred_externalDependency(t *testing.T) { @@ -89,7 +90,13 @@ func TestDeferred_absResourceInstanceDeferred(t *testing.T) { }) // Instance A has its Create action deferred for some reason. - deferred.ReportResourceInstanceDeferred(instAAddr, plans.Create, cty.DynamicVal) + deferred.ReportResourceInstanceDeferred(instAAddr, plans.DeferredReasonResourceConfigUnknown, &plans.ResourceInstanceChange{ + Addr: instAAddr, + Change: plans.Change{ + Action: plans.Create, + After: cty.DynamicVal, + }, + }) t.Run("with one resource instance deferred", func(t *testing.T) { if !deferred.ShouldDeferResourceInstanceChanges(instCAddr) { @@ -101,6 +108,70 @@ func TestDeferred_absResourceInstanceDeferred(t *testing.T) { }) } +func TestDeferred_partialExpandedDatasource(t *testing.T) { + instAAddr := addrs.AbsResourceInstance{ + Module: addrs.RootModuleInstance.Child("foo", addrs.NoKey), + Resource: addrs.ResourceInstance{ + Resource: addrs.Resource{ + Mode: addrs.DataResourceMode, + Type: "test", + Name: "a", + }, + }, + } + instBAddr := addrs.AbsResourceInstance{ + Module: addrs.RootModuleInstance, + Resource: addrs.ResourceInstance{ + Resource: addrs.Resource{ + Mode: addrs.ManagedResourceMode, + Type: "test", + Name: "a", + }, + }, + } + instCAddr := addrs.AbsResourceInstance{ + Module: addrs.RootModuleInstance, + Resource: addrs.ResourceInstance{ + Resource: addrs.Resource{ + Mode: addrs.DataResourceMode, + Type: "test", + Name: "c", + }, + }, + } + instAPartial := addrs.RootModuleInstance. + UnexpandedChild(addrs.ModuleCall{Name: "foo"}). + Resource(instAAddr.Resource.Resource) + + resourceGraph := addrs.NewDirectedGraph[addrs.ConfigResource]() + resourceGraph.AddDependency(instCAddr.ConfigResource(), instBAddr.ConfigResource()) + resourceGraph.AddDependency(instCAddr.ConfigResource(), instAAddr.ConfigResource()) + deferred := NewDeferred(resourceGraph, true) + + // Before we report anything, all three addresses should indicate that + // they don't need to have their actions deferred. + t.Run("without any deferrals yet", func(t *testing.T) { + for _, instAddr := range []addrs.AbsResourceInstance{instAAddr, instBAddr, instCAddr} { + if deferred.ShouldDeferResourceInstanceChanges(instAddr) { + t.Errorf("%s reported as needing deferred; should not be, yet", instAddr) + } + } + }) + + // Resource A hasn't been expanded fully, so is deferred. + deferred.ReportDataSourceExpansionDeferred(instAPartial) + + t.Run("with one resource instance deferred", func(t *testing.T) { + if !deferred.ShouldDeferResourceInstanceChanges(instCAddr) { + t.Errorf("%s was not reported as needing deferred; should be deferred", instCAddr) + } + if deferred.ShouldDeferResourceInstanceChanges(instBAddr) { + t.Errorf("%s reported as needing deferred; should not be", instCAddr) + } + }) + +} + func TestDeferred_partialExpandedResource(t *testing.T) { instAAddr := addrs.AbsResourceInstance{ Module: addrs.RootModuleInstance.Child("foo", addrs.NoKey), @@ -152,7 +223,13 @@ func TestDeferred_partialExpandedResource(t *testing.T) { }) // Resource A hasn't been expanded fully, so is deferred. - deferred.ReportResourceExpansionDeferred(instAPartial, cty.DynamicVal) + deferred.ReportResourceExpansionDeferred(instAPartial, &plans.ResourceInstanceChange{ + Addr: instAAddr, + Change: plans.Change{ + Action: plans.Create, + After: cty.DynamicVal, + }, + }) t.Run("with one resource instance deferred", func(t *testing.T) { if !deferred.ShouldDeferResourceInstanceChanges(instCAddr) { diff --git a/internal/plans/plan.go b/internal/plans/plan.go index 034af64b8527..e31ab65e72d0 100644 --- a/internal/plans/plan.go +++ b/internal/plans/plan.go @@ -46,6 +46,7 @@ type Plan struct { VariableMarks map[string][]cty.PathValueMarks Changes *Changes DriftedResources []*ResourceInstanceChangeSrc + DeferredResources []*DeferredResourceInstanceChangeSrc TargetAddrs []addrs.Targetable ForceReplaceAddrs []addrs.AbsResourceInstance Backend Backend diff --git a/internal/plans/planfile/planfile_test.go b/internal/plans/planfile/planfile_test.go index d970aadaf9ae..d55614246d3d 100644 --- a/internal/plans/planfile/planfile_test.go +++ b/internal/plans/planfile/planfile_test.go @@ -57,7 +57,8 @@ func TestRoundtrip(t *testing.T) { Resources: []*plans.ResourceInstanceChangeSrc{}, Outputs: []*plans.OutputChangeSrc{}, }, - DriftedResources: []*plans.ResourceInstanceChangeSrc{}, + DriftedResources: []*plans.ResourceInstanceChangeSrc{}, + DeferredResources: []*plans.DeferredResourceInstanceChangeSrc{}, VariableValues: map[string]plans.DynamicValue{ "foo": plans.DynamicValue([]byte("foo placeholder")), }, diff --git a/internal/plans/planfile/tfplan.go b/internal/plans/planfile/tfplan.go index a1b7aeb954f7..603318abc40c 100644 --- a/internal/plans/planfile/tfplan.go +++ b/internal/plans/planfile/tfplan.go @@ -63,8 +63,9 @@ func readTfplan(r io.Reader) (*plans.Plan, error) { Outputs: []*plans.OutputChangeSrc{}, Resources: []*plans.ResourceInstanceChangeSrc{}, }, - DriftedResources: []*plans.ResourceInstanceChangeSrc{}, - Checks: &states.CheckResults{}, + DriftedResources: []*plans.ResourceInstanceChangeSrc{}, + DeferredResources: []*plans.DeferredResourceInstanceChangeSrc{}, + Checks: &states.CheckResults{}, } plan.Applyable = rawPlan.Applyable @@ -125,6 +126,15 @@ func readTfplan(r io.Reader) (*plans.Plan, error) { plan.DriftedResources = append(plan.DriftedResources, change) } + for _, rawDC := range rawPlan.DeferredChanges { + change, err := deferredChangeFromTfplan(rawDC) + if err != nil { + return nil, err + } + + plan.DeferredResources = append(plan.DeferredResources, change) + } + for _, rawRA := range rawPlan.RelevantAttributes { ra, err := resourceAttrFromTfplan(rawRA) if err != nil { @@ -433,6 +443,44 @@ func valueFromTfplan(rawV *planproto.DynamicValue) (plans.DynamicValue, error) { return plans.DynamicValue(rawV.Msgpack), nil } +func deferredChangeFromTfplan(dc *planproto.DeferredResourceInstanceChange) (*plans.DeferredResourceInstanceChangeSrc, error) { + if dc == nil { + return nil, fmt.Errorf("deferred change object is absent") + } + + change, err := resourceChangeFromTfplan(dc.Change) + if err != nil { + return nil, err + } + + reason, err := deferredReasonFromProto(dc.Deferred.Reason) + if err != nil { + return nil, err + } + + return &plans.DeferredResourceInstanceChangeSrc{ + DeferredReason: reason, + ChangeSrc: change, + }, nil +} + +func deferredReasonFromProto(reason planproto.DeferredReason) (plans.DeferredReason, error) { + switch reason { + case planproto.DeferredReason_INSTANCE_COUNT_UNKNOWN: + return plans.DeferredReasonInstanceCountUnknown, nil + case planproto.DeferredReason_RESOURCE_CONFIG_UNKNOWN: + return plans.DeferredReasonResourceConfigUnknown, nil + case planproto.DeferredReason_PROVIDER_CONFIG_UNKNOWN: + return plans.DeferredReasonProviderConfigUnknown, nil + case planproto.DeferredReason_ABSENT_PREREQ: + return plans.DeferredReasonAbsentPrereq, nil + case planproto.DeferredReason_DEFERRED_PREREQ: + return plans.DeferredReasonDeferredPrereq, nil + default: + return plans.DeferredReasonInvalid, fmt.Errorf("invalid deferred reason %s", reason) + } +} + // writeTfplan serializes the given plan into the protobuf-based format used // for the "tfplan" portion of a plan file. func writeTfplan(plan *plans.Plan, w io.Writer) error { @@ -452,6 +500,7 @@ func writeTfplan(plan *plans.Plan, w io.Writer) error { CheckResults: []*planproto.CheckResults{}, ResourceChanges: []*planproto.ResourceInstanceChange{}, ResourceDrift: []*planproto.ResourceInstanceChange{}, + DeferredChanges: []*planproto.DeferredResourceInstanceChange{}, } rawPlan.Applyable = plan.Applyable @@ -516,6 +565,14 @@ func writeTfplan(plan *plans.Plan, w io.Writer) error { rawPlan.ResourceDrift = append(rawPlan.ResourceDrift, rawRC) } + for _, dc := range plan.DeferredResources { + rawDC, err := deferredChangeToTfplan(dc) + if err != nil { + return err + } + rawPlan.DeferredChanges = append(rawPlan.DeferredChanges, rawDC) + } + for _, ra := range plan.RelevantAttributes { rawRA, err := resourceAttrToTfplan(ra) if err != nil { @@ -855,6 +912,42 @@ func pathToTfplan(path cty.Path) (*planproto.Path, error) { return planproto.NewPath(path) } +func deferredChangeToTfplan(dc *plans.DeferredResourceInstanceChangeSrc) (*planproto.DeferredResourceInstanceChange, error) { + change, err := resourceChangeToTfplan(dc.ChangeSrc) + if err != nil { + return nil, err + } + + reason, err := deferredReasonToProto(dc.DeferredReason) + if err != nil { + return nil, err + } + + return &planproto.DeferredResourceInstanceChange{ + Change: change, + Deferred: &planproto.Deferred{ + Reason: reason, + }, + }, nil +} + +func deferredReasonToProto(reason plans.DeferredReason) (planproto.DeferredReason, error) { + switch reason { + case plans.DeferredReasonInstanceCountUnknown: + return planproto.DeferredReason_INSTANCE_COUNT_UNKNOWN, nil + case plans.DeferredReasonResourceConfigUnknown: + return planproto.DeferredReason_RESOURCE_CONFIG_UNKNOWN, nil + case plans.DeferredReasonProviderConfigUnknown: + return planproto.DeferredReason_PROVIDER_CONFIG_UNKNOWN, nil + case plans.DeferredReasonAbsentPrereq: + return planproto.DeferredReason_ABSENT_PREREQ, nil + case plans.DeferredReasonDeferredPrereq: + return planproto.DeferredReason_DEFERRED_PREREQ, nil + default: + return planproto.DeferredReason_INVALID, fmt.Errorf("invalid deferred reason %s", reason) + } +} + // CheckResultsFromPlanProto decodes a slice of check results from their protobuf // representation into the "states" package's representation. // diff --git a/internal/plans/planfile/tfplan_test.go b/internal/plans/planfile/tfplan_test.go index 8ffb7ad3fc91..2663e5a94760 100644 --- a/internal/plans/planfile/tfplan_test.go +++ b/internal/plans/planfile/tfplan_test.go @@ -193,6 +193,32 @@ func TestTFPlanRoundTrip(t *testing.T) { }, }, }, + DeferredResources: []*plans.DeferredResourceInstanceChangeSrc{ + { + DeferredReason: plans.DeferredReasonInstanceCountUnknown, + ChangeSrc: &plans.ResourceInstanceChangeSrc{ + Addr: addrs.Resource{ + Mode: addrs.ManagedResourceMode, + Type: "test_thing", + Name: "woot", + }.Instance(addrs.WildcardKey).Absolute(addrs.RootModuleInstance), + ProviderAddr: addrs.AbsProviderConfig{ + Provider: addrs.NewDefaultProvider("test"), + Module: addrs.RootModule, + }, + ChangeSrc: plans.ChangeSrc{ + Action: plans.Create, + After: mustNewDynamicValue(cty.ObjectVal(map[string]cty.Value{ + "id": cty.UnknownVal(cty.String), + "boop": cty.ListVal([]cty.Value{ + cty.StringVal("beep"), + cty.StringVal("bonk"), + }), + }), objTy), + }, + }, + }, + }, RelevantAttributes: []globalref.ResourceAttr{ { Resource: addrs.Resource{ diff --git a/internal/plans/planproto/planfile.pb.go b/internal/plans/planproto/planfile.pb.go index 3379d2a9cd30..3561f3539c9e 100644 --- a/internal/plans/planproto/planfile.pb.go +++ b/internal/plans/planproto/planfile.pb.go @@ -228,6 +228,66 @@ func (ResourceInstanceActionReason) EnumDescriptor() ([]byte, []int) { return file_planfile_proto_rawDescGZIP(), []int{2} } +// DeferredReason describes the reason why a resource instance change was +// deferred. +type DeferredReason int32 + +const ( + DeferredReason_INVALID DeferredReason = 0 + DeferredReason_INSTANCE_COUNT_UNKNOWN DeferredReason = 1 + DeferredReason_RESOURCE_CONFIG_UNKNOWN DeferredReason = 2 + DeferredReason_PROVIDER_CONFIG_UNKNOWN DeferredReason = 3 + DeferredReason_ABSENT_PREREQ DeferredReason = 4 + DeferredReason_DEFERRED_PREREQ DeferredReason = 5 +) + +// Enum value maps for DeferredReason. +var ( + DeferredReason_name = map[int32]string{ + 0: "INVALID", + 1: "INSTANCE_COUNT_UNKNOWN", + 2: "RESOURCE_CONFIG_UNKNOWN", + 3: "PROVIDER_CONFIG_UNKNOWN", + 4: "ABSENT_PREREQ", + 5: "DEFERRED_PREREQ", + } + DeferredReason_value = map[string]int32{ + "INVALID": 0, + "INSTANCE_COUNT_UNKNOWN": 1, + "RESOURCE_CONFIG_UNKNOWN": 2, + "PROVIDER_CONFIG_UNKNOWN": 3, + "ABSENT_PREREQ": 4, + "DEFERRED_PREREQ": 5, + } +) + +func (x DeferredReason) Enum() *DeferredReason { + p := new(DeferredReason) + *p = x + return p +} + +func (x DeferredReason) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DeferredReason) Descriptor() protoreflect.EnumDescriptor { + return file_planfile_proto_enumTypes[3].Descriptor() +} + +func (DeferredReason) Type() protoreflect.EnumType { + return &file_planfile_proto_enumTypes[3] +} + +func (x DeferredReason) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DeferredReason.Descriptor instead. +func (DeferredReason) EnumDescriptor() ([]byte, []int) { + return file_planfile_proto_rawDescGZIP(), []int{3} +} + // Status describes the status of a particular checkable object at the // completion of the plan. type CheckResults_Status int32 @@ -266,11 +326,11 @@ func (x CheckResults_Status) String() string { } func (CheckResults_Status) Descriptor() protoreflect.EnumDescriptor { - return file_planfile_proto_enumTypes[3].Descriptor() + return file_planfile_proto_enumTypes[4].Descriptor() } func (CheckResults_Status) Type() protoreflect.EnumType { - return &file_planfile_proto_enumTypes[3] + return &file_planfile_proto_enumTypes[4] } func (x CheckResults_Status) Number() protoreflect.EnumNumber { @@ -279,7 +339,7 @@ func (x CheckResults_Status) Number() protoreflect.EnumNumber { // Deprecated: Use CheckResults_Status.Descriptor instead. func (CheckResults_Status) EnumDescriptor() ([]byte, []int) { - return file_planfile_proto_rawDescGZIP(), []int{5, 0} + return file_planfile_proto_rawDescGZIP(), []int{6, 0} } type CheckResults_ObjectKind int32 @@ -321,11 +381,11 @@ func (x CheckResults_ObjectKind) String() string { } func (CheckResults_ObjectKind) Descriptor() protoreflect.EnumDescriptor { - return file_planfile_proto_enumTypes[4].Descriptor() + return file_planfile_proto_enumTypes[5].Descriptor() } func (CheckResults_ObjectKind) Type() protoreflect.EnumType { - return &file_planfile_proto_enumTypes[4] + return &file_planfile_proto_enumTypes[5] } func (x CheckResults_ObjectKind) Number() protoreflect.EnumNumber { @@ -334,7 +394,7 @@ func (x CheckResults_ObjectKind) Number() protoreflect.EnumNumber { // Deprecated: Use CheckResults_ObjectKind.Descriptor instead. func (CheckResults_ObjectKind) EnumDescriptor() ([]byte, []int) { - return file_planfile_proto_rawDescGZIP(), []int{5, 1} + return file_planfile_proto_rawDescGZIP(), []int{6, 1} } // Plan is the root message type for the tfplan file @@ -396,6 +456,11 @@ type Plan struct { // Terraform, computed by comparing the previous run's state to the state // after refresh. ResourceDrift []*ResourceInstanceChange `protobuf:"bytes,18,rep,name=resource_drift,json=resourceDrift,proto3" json:"resource_drift,omitempty"` + // An unordered set of deferred changes. These are changes that will be + // applied in a subsequent plan, but were deferred in this plan for some + // reason. Generally, if complete is set to false there should be entries + // in this list. + DeferredChanges []*DeferredResourceInstanceChange `protobuf:"bytes,27,rep,name=deferred_changes,json=deferredChanges,proto3" json:"deferred_changes,omitempty"` // An unordered set of proposed changes to outputs in the root module // of the configuration. This set also includes "no action" changes for // outputs that are not changing, as context for detecting inconsistencies @@ -517,6 +582,13 @@ func (x *Plan) GetResourceDrift() []*ResourceInstanceChange { return nil } +func (x *Plan) GetDeferredChanges() []*DeferredResourceInstanceChange { + if x != nil { + return x.DeferredChanges + } + return nil +} + func (x *Plan) GetOutputChanges() []*OutputChange { if x != nil { return x.OutputChanges @@ -883,6 +955,68 @@ func (x *ResourceInstanceChange) GetActionReason() ResourceInstanceActionReason return ResourceInstanceActionReason_NONE } +// DeferredResourceInstanceChange represents a resource instance change that +// was deferred for some reason. +// +// It contains the original change that was deferred, along with the reason +// why it was deferred. +type DeferredResourceInstanceChange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The reason why the change was deferred. + Deferred *Deferred `protobuf:"bytes,1,opt,name=deferred,proto3" json:"deferred,omitempty"` + // The original change that was deferred. + Change *ResourceInstanceChange `protobuf:"bytes,2,opt,name=change,proto3" json:"change,omitempty"` +} + +func (x *DeferredResourceInstanceChange) Reset() { + *x = DeferredResourceInstanceChange{} + if protoimpl.UnsafeEnabled { + mi := &file_planfile_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeferredResourceInstanceChange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeferredResourceInstanceChange) ProtoMessage() {} + +func (x *DeferredResourceInstanceChange) ProtoReflect() protoreflect.Message { + mi := &file_planfile_proto_msgTypes[4] + 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 DeferredResourceInstanceChange.ProtoReflect.Descriptor instead. +func (*DeferredResourceInstanceChange) Descriptor() ([]byte, []int) { + return file_planfile_proto_rawDescGZIP(), []int{4} +} + +func (x *DeferredResourceInstanceChange) GetDeferred() *Deferred { + if x != nil { + return x.Deferred + } + return nil +} + +func (x *DeferredResourceInstanceChange) GetChange() *ResourceInstanceChange { + if x != nil { + return x.Change + } + return nil +} + type OutputChange struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -902,7 +1036,7 @@ type OutputChange struct { func (x *OutputChange) Reset() { *x = OutputChange{} if protoimpl.UnsafeEnabled { - mi := &file_planfile_proto_msgTypes[4] + mi := &file_planfile_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -915,7 +1049,7 @@ func (x *OutputChange) String() string { func (*OutputChange) ProtoMessage() {} func (x *OutputChange) ProtoReflect() protoreflect.Message { - mi := &file_planfile_proto_msgTypes[4] + mi := &file_planfile_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -928,7 +1062,7 @@ func (x *OutputChange) ProtoReflect() protoreflect.Message { // Deprecated: Use OutputChange.ProtoReflect.Descriptor instead. func (*OutputChange) Descriptor() ([]byte, []int) { - return file_planfile_proto_rawDescGZIP(), []int{4} + return file_planfile_proto_rawDescGZIP(), []int{5} } func (x *OutputChange) GetName() string { @@ -971,7 +1105,7 @@ type CheckResults struct { func (x *CheckResults) Reset() { *x = CheckResults{} 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) } @@ -984,7 +1118,7 @@ func (x *CheckResults) String() string { func (*CheckResults) ProtoMessage() {} func (x *CheckResults) 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 { @@ -997,7 +1131,7 @@ func (x *CheckResults) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckResults.ProtoReflect.Descriptor instead. func (*CheckResults) Descriptor() ([]byte, []int) { - return file_planfile_proto_rawDescGZIP(), []int{5} + return file_planfile_proto_rawDescGZIP(), []int{6} } func (x *CheckResults) GetKind() CheckResults_ObjectKind { @@ -1043,7 +1177,7 @@ type ProviderFunctionCallHash struct { func (x *ProviderFunctionCallHash) Reset() { *x = ProviderFunctionCallHash{} 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) } @@ -1056,7 +1190,7 @@ func (x *ProviderFunctionCallHash) String() string { func (*ProviderFunctionCallHash) ProtoMessage() {} func (x *ProviderFunctionCallHash) 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 { @@ -1069,7 +1203,7 @@ func (x *ProviderFunctionCallHash) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderFunctionCallHash.ProtoReflect.Descriptor instead. func (*ProviderFunctionCallHash) Descriptor() ([]byte, []int) { - return file_planfile_proto_rawDescGZIP(), []int{6} + return file_planfile_proto_rawDescGZIP(), []int{7} } func (x *ProviderFunctionCallHash) GetKey() []byte { @@ -1109,7 +1243,7 @@ type DynamicValue struct { func (x *DynamicValue) Reset() { *x = DynamicValue{} if protoimpl.UnsafeEnabled { - mi := &file_planfile_proto_msgTypes[7] + mi := &file_planfile_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1122,7 +1256,7 @@ func (x *DynamicValue) String() string { func (*DynamicValue) ProtoMessage() {} func (x *DynamicValue) ProtoReflect() protoreflect.Message { - mi := &file_planfile_proto_msgTypes[7] + mi := &file_planfile_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1135,7 +1269,7 @@ func (x *DynamicValue) ProtoReflect() protoreflect.Message { // Deprecated: Use DynamicValue.ProtoReflect.Descriptor instead. func (*DynamicValue) Descriptor() ([]byte, []int) { - return file_planfile_proto_rawDescGZIP(), []int{7} + return file_planfile_proto_rawDescGZIP(), []int{8} } func (x *DynamicValue) GetMsgpack() []byte { @@ -1159,7 +1293,7 @@ type Path struct { func (x *Path) Reset() { *x = Path{} 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) } @@ -1172,7 +1306,7 @@ func (x *Path) String() string { func (*Path) ProtoMessage() {} func (x *Path) 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 { @@ -1185,7 +1319,7 @@ func (x *Path) ProtoReflect() protoreflect.Message { // Deprecated: Use Path.ProtoReflect.Descriptor instead. func (*Path) Descriptor() ([]byte, []int) { - return file_planfile_proto_rawDescGZIP(), []int{8} + return file_planfile_proto_rawDescGZIP(), []int{9} } func (x *Path) GetSteps() []*Path_Step { @@ -1209,7 +1343,7 @@ type Importing struct { func (x *Importing) Reset() { *x = Importing{} 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) } @@ -1222,7 +1356,7 @@ func (x *Importing) String() string { func (*Importing) ProtoMessage() {} func (x *Importing) 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 { @@ -1235,7 +1369,7 @@ func (x *Importing) ProtoReflect() protoreflect.Message { // Deprecated: Use Importing.ProtoReflect.Descriptor instead. func (*Importing) Descriptor() ([]byte, []int) { - return file_planfile_proto_rawDescGZIP(), []int{9} + return file_planfile_proto_rawDescGZIP(), []int{10} } func (x *Importing) GetId() string { @@ -1245,6 +1379,55 @@ func (x *Importing) GetId() string { return "" } +// Deferred contains all the metadata about a the deferral of a resource +// instance change. +type Deferred struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Reason DeferredReason `protobuf:"varint,1,opt,name=reason,proto3,enum=tfplan.DeferredReason" json:"reason,omitempty"` +} + +func (x *Deferred) Reset() { + *x = Deferred{} + if protoimpl.UnsafeEnabled { + mi := &file_planfile_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Deferred) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Deferred) ProtoMessage() {} + +func (x *Deferred) ProtoReflect() protoreflect.Message { + mi := &file_planfile_proto_msgTypes[11] + 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 Deferred.ProtoReflect.Descriptor instead. +func (*Deferred) Descriptor() ([]byte, []int) { + return file_planfile_proto_rawDescGZIP(), []int{11} +} + +func (x *Deferred) GetReason() DeferredReason { + if x != nil { + return x.Reason + } + return DeferredReason_INVALID +} + type PlanResourceAttr struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1257,7 +1440,7 @@ type PlanResourceAttr struct { func (x *PlanResourceAttr) Reset() { *x = PlanResourceAttr{} if protoimpl.UnsafeEnabled { - mi := &file_planfile_proto_msgTypes[11] + mi := &file_planfile_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1270,7 +1453,7 @@ func (x *PlanResourceAttr) String() string { func (*PlanResourceAttr) ProtoMessage() {} func (x *PlanResourceAttr) ProtoReflect() protoreflect.Message { - mi := &file_planfile_proto_msgTypes[11] + mi := &file_planfile_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1313,7 +1496,7 @@ type CheckResults_ObjectResult struct { func (x *CheckResults_ObjectResult) Reset() { *x = CheckResults_ObjectResult{} if protoimpl.UnsafeEnabled { - mi := &file_planfile_proto_msgTypes[12] + mi := &file_planfile_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1326,7 +1509,7 @@ func (x *CheckResults_ObjectResult) String() string { func (*CheckResults_ObjectResult) ProtoMessage() {} func (x *CheckResults_ObjectResult) ProtoReflect() protoreflect.Message { - mi := &file_planfile_proto_msgTypes[12] + mi := &file_planfile_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1339,7 +1522,7 @@ func (x *CheckResults_ObjectResult) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckResults_ObjectResult.ProtoReflect.Descriptor instead. func (*CheckResults_ObjectResult) Descriptor() ([]byte, []int) { - return file_planfile_proto_rawDescGZIP(), []int{5, 0} + return file_planfile_proto_rawDescGZIP(), []int{6, 0} } func (x *CheckResults_ObjectResult) GetObjectAddr() string { @@ -1378,7 +1561,7 @@ type Path_Step struct { func (x *Path_Step) Reset() { *x = Path_Step{} if protoimpl.UnsafeEnabled { - mi := &file_planfile_proto_msgTypes[13] + mi := &file_planfile_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1391,7 +1574,7 @@ func (x *Path_Step) String() string { func (*Path_Step) ProtoMessage() {} func (x *Path_Step) ProtoReflect() protoreflect.Message { - mi := &file_planfile_proto_msgTypes[13] + mi := &file_planfile_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1404,7 +1587,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{8, 0} + return file_planfile_proto_rawDescGZIP(), []int{9, 0} } func (m *Path_Step) GetSelector() isPath_Step_Selector { @@ -1452,7 +1635,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, 0xf7, 0x07, 0x0a, 0x04, 0x50, 0x6c, 0x61, + 0x12, 0x06, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x22, 0xca, 0x08, 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, @@ -1475,199 +1658,227 @@ var file_planfile_proto_rawDesc = []byte{ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x72, - 0x69, 0x66, 0x74, 0x12, 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, 0x39, 0x0a, 0x0d, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, - 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x0c, 0x63, - 0x68, 0x65, 0x63, 0x6b, 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, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x5c, 0x0a, 0x19, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x16, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, - 0x6c, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x52, 0x17, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 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, 0xc0, 0x02, - 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, + 0x69, 0x66, 0x74, 0x12, 0x51, 0x0a, 0x10, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0f, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 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, 0x39, 0x0a, 0x0d, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x52, 0x0c, 0x63, 0x68, 0x65, 0x63, 0x6b, 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, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x12, 0x5c, 0x0a, 0x19, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x18, 0x16, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, + 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x61, 0x6c, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x52, 0x17, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 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, - 0x13, 0x61, 0x66, 0x74, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x50, - 0x61, 0x74, 0x68, 0x73, 0x12, 0x2f, 0x0a, 0x09, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, - 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, - 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x69, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 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, 0xfc, 0x03, 0x0a, 0x0c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x12, 0x33, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, - 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, - 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x07, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, - 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x73, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x1a, 0x8f, 0x01, 0x0a, 0x0c, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x66, + 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, 0xc0, 0x02, 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, 0x12, 0x2f, 0x0a, 0x09, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x61, 0x6e, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 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, 0x86, 0x01, 0x0a, 0x1e, 0x44, 0x65, + 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x08, + 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, + 0x52, 0x08, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x12, 0x36, 0x0a, 0x06, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x61, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 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, 0xfc, 0x03, 0x0a, + 0x0c, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x33, 0x0a, + 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x29, 0x0a, 0x10, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x61, 0x69, 0x6c, - 0x75, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x06, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x41, 0x53, 0x53, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, - 0x46, 0x41, 0x49, 0x4c, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, - 0x03, 0x22, 0x5c, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, - 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x01, 0x12, 0x10, - 0x0a, 0x0c, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02, - 0x12, 0x09, 0x0a, 0x05, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x49, - 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x22, - 0x44, 0x0a, 0x18, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x46, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6c, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 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, 0x22, 0x1b, 0x0a, 0x09, 0x49, 0x6d, 0x70, 0x6f, 0x72, - 0x74, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 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, 0x94, 0x01, 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, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x4f, - 0x52, 0x47, 0x45, 0x54, 0x10, 0x08, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, - 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x46, 0x4f, 0x52, 0x47, 0x45, 0x54, 0x10, 0x09, 0x2a, 0xc8, - 0x03, 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, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x50, 0x4c, - 0x41, 0x43, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x54, 0x52, 0x49, 0x47, 0x47, 0x45, 0x52, 0x53, 0x10, - 0x09, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, - 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, - 0x53, 0x45, 0x5f, 0x44, 0x45, 0x50, 0x45, 0x4e, 0x44, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x50, 0x45, - 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x41, 0x44, 0x5f, - 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x4e, 0x45, - 0x53, 0x54, 0x45, 0x44, 0x10, 0x0d, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x56, 0x45, - 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x10, 0x0c, 0x42, 0x39, 0x5a, 0x37, 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, 0x70, 0x6c, 0x61, 0x6e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, + 0x6e, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, + 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x61, 0x6e, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x1a, 0x8f, 0x01, 0x0a, 0x0c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, + 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x10, + 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, + 0x0a, 0x04, 0x50, 0x41, 0x53, 0x53, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x41, 0x49, 0x4c, + 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x22, 0x5c, 0x0a, + 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, + 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x55, + 0x54, 0x50, 0x55, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, + 0x43, 0x48, 0x45, 0x43, 0x4b, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x50, 0x55, 0x54, + 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x22, 0x44, 0x0a, 0x18, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, + 0x61, 0x6c, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 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, 0x22, 0x1b, 0x0a, 0x09, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, + 0x22, 0x3a, 0x0a, 0x08, 0x44, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x06, + 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x44, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x52, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 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, + 0x94, 0x01, 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, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x4f, 0x52, 0x47, 0x45, 0x54, 0x10, 0x08, 0x12, 0x16, + 0x0a, 0x12, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x46, 0x4f, + 0x52, 0x47, 0x45, 0x54, 0x10, 0x09, 0x2a, 0xc8, 0x03, 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, + 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x54, + 0x52, 0x49, 0x47, 0x47, 0x45, 0x52, 0x53, 0x10, 0x09, 0x12, 0x1f, 0x0a, 0x1b, 0x52, 0x45, 0x41, + 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, + 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, + 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x44, 0x45, 0x50, 0x45, 0x4e, + 0x44, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x0b, 0x12, + 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, + 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x4e, 0x45, 0x53, 0x54, 0x45, 0x44, 0x10, 0x0d, 0x12, 0x21, + 0x0a, 0x1d, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, + 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x10, + 0x0c, 0x2a, 0x9b, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x52, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, + 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x43, 0x4f, + 0x55, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x12, 0x1b, 0x0a, + 0x17, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, + 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x12, 0x1b, 0x0a, 0x17, 0x50, 0x52, + 0x4f, 0x56, 0x49, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x42, 0x53, 0x45, 0x4e, + 0x54, 0x5f, 0x50, 0x52, 0x45, 0x52, 0x45, 0x51, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, + 0x46, 0x45, 0x52, 0x52, 0x45, 0x44, 0x5f, 0x50, 0x52, 0x45, 0x52, 0x45, 0x51, 0x10, 0x05, 0x42, + 0x39, 0x5a, 0x37, 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, 0x70, 0x6c, 0x61, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -1682,62 +1893,69 @@ func file_planfile_proto_rawDescGZIP() []byte { return file_planfile_proto_rawDescData } -var file_planfile_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_planfile_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_planfile_proto_enumTypes = make([]protoimpl.EnumInfo, 6) +var file_planfile_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_planfile_proto_goTypes = []interface{}{ - (Mode)(0), // 0: tfplan.Mode - (Action)(0), // 1: tfplan.Action - (ResourceInstanceActionReason)(0), // 2: tfplan.ResourceInstanceActionReason - (CheckResults_Status)(0), // 3: tfplan.CheckResults.Status - (CheckResults_ObjectKind)(0), // 4: tfplan.CheckResults.ObjectKind - (*Plan)(nil), // 5: tfplan.Plan - (*Backend)(nil), // 6: tfplan.Backend - (*Change)(nil), // 7: tfplan.Change - (*ResourceInstanceChange)(nil), // 8: tfplan.ResourceInstanceChange - (*OutputChange)(nil), // 9: tfplan.OutputChange - (*CheckResults)(nil), // 10: tfplan.CheckResults - (*ProviderFunctionCallHash)(nil), // 11: tfplan.ProviderFunctionCallHash - (*DynamicValue)(nil), // 12: tfplan.DynamicValue - (*Path)(nil), // 13: tfplan.Path - (*Importing)(nil), // 14: tfplan.Importing - nil, // 15: tfplan.Plan.VariablesEntry - (*PlanResourceAttr)(nil), // 16: tfplan.Plan.resource_attr - (*CheckResults_ObjectResult)(nil), // 17: tfplan.CheckResults.ObjectResult - (*Path_Step)(nil), // 18: tfplan.Path.Step + (Mode)(0), // 0: tfplan.Mode + (Action)(0), // 1: tfplan.Action + (ResourceInstanceActionReason)(0), // 2: tfplan.ResourceInstanceActionReason + (DeferredReason)(0), // 3: tfplan.DeferredReason + (CheckResults_Status)(0), // 4: tfplan.CheckResults.Status + (CheckResults_ObjectKind)(0), // 5: tfplan.CheckResults.ObjectKind + (*Plan)(nil), // 6: tfplan.Plan + (*Backend)(nil), // 7: tfplan.Backend + (*Change)(nil), // 8: tfplan.Change + (*ResourceInstanceChange)(nil), // 9: tfplan.ResourceInstanceChange + (*DeferredResourceInstanceChange)(nil), // 10: tfplan.DeferredResourceInstanceChange + (*OutputChange)(nil), // 11: tfplan.OutputChange + (*CheckResults)(nil), // 12: tfplan.CheckResults + (*ProviderFunctionCallHash)(nil), // 13: tfplan.ProviderFunctionCallHash + (*DynamicValue)(nil), // 14: tfplan.DynamicValue + (*Path)(nil), // 15: tfplan.Path + (*Importing)(nil), // 16: tfplan.Importing + (*Deferred)(nil), // 17: tfplan.Deferred + nil, // 18: tfplan.Plan.VariablesEntry + (*PlanResourceAttr)(nil), // 19: tfplan.Plan.resource_attr + (*CheckResults_ObjectResult)(nil), // 20: tfplan.CheckResults.ObjectResult + (*Path_Step)(nil), // 21: tfplan.Path.Step } var file_planfile_proto_depIdxs = []int32{ 0, // 0: tfplan.Plan.ui_mode:type_name -> tfplan.Mode - 15, // 1: tfplan.Plan.variables:type_name -> tfplan.Plan.VariablesEntry - 8, // 2: tfplan.Plan.resource_changes:type_name -> tfplan.ResourceInstanceChange - 8, // 3: tfplan.Plan.resource_drift:type_name -> tfplan.ResourceInstanceChange - 9, // 4: tfplan.Plan.output_changes:type_name -> tfplan.OutputChange - 10, // 5: tfplan.Plan.check_results:type_name -> tfplan.CheckResults - 6, // 6: tfplan.Plan.backend:type_name -> tfplan.Backend - 16, // 7: tfplan.Plan.relevant_attributes:type_name -> tfplan.Plan.resource_attr - 11, // 8: tfplan.Plan.provider_function_results:type_name -> tfplan.ProviderFunctionCallHash - 12, // 9: tfplan.Backend.config:type_name -> tfplan.DynamicValue - 1, // 10: tfplan.Change.action:type_name -> tfplan.Action - 12, // 11: tfplan.Change.values:type_name -> tfplan.DynamicValue - 13, // 12: tfplan.Change.before_sensitive_paths:type_name -> tfplan.Path - 13, // 13: tfplan.Change.after_sensitive_paths:type_name -> tfplan.Path - 14, // 14: tfplan.Change.importing:type_name -> tfplan.Importing - 7, // 15: tfplan.ResourceInstanceChange.change:type_name -> tfplan.Change - 13, // 16: tfplan.ResourceInstanceChange.required_replace:type_name -> tfplan.Path - 2, // 17: tfplan.ResourceInstanceChange.action_reason:type_name -> tfplan.ResourceInstanceActionReason - 7, // 18: tfplan.OutputChange.change:type_name -> tfplan.Change - 4, // 19: tfplan.CheckResults.kind:type_name -> tfplan.CheckResults.ObjectKind - 3, // 20: tfplan.CheckResults.status:type_name -> tfplan.CheckResults.Status - 17, // 21: tfplan.CheckResults.objects:type_name -> tfplan.CheckResults.ObjectResult - 18, // 22: tfplan.Path.steps:type_name -> tfplan.Path.Step - 12, // 23: tfplan.Plan.VariablesEntry.value:type_name -> tfplan.DynamicValue - 13, // 24: tfplan.Plan.resource_attr.attr:type_name -> tfplan.Path - 3, // 25: tfplan.CheckResults.ObjectResult.status:type_name -> tfplan.CheckResults.Status - 12, // 26: tfplan.Path.Step.element_key:type_name -> tfplan.DynamicValue - 27, // [27:27] is the sub-list for method output_type - 27, // [27:27] is the sub-list for method input_type - 27, // [27:27] is the sub-list for extension type_name - 27, // [27:27] is the sub-list for extension extendee - 0, // [0:27] is the sub-list for field type_name + 18, // 1: tfplan.Plan.variables:type_name -> tfplan.Plan.VariablesEntry + 9, // 2: tfplan.Plan.resource_changes:type_name -> tfplan.ResourceInstanceChange + 9, // 3: tfplan.Plan.resource_drift:type_name -> tfplan.ResourceInstanceChange + 10, // 4: tfplan.Plan.deferred_changes:type_name -> tfplan.DeferredResourceInstanceChange + 11, // 5: tfplan.Plan.output_changes:type_name -> tfplan.OutputChange + 12, // 6: tfplan.Plan.check_results:type_name -> tfplan.CheckResults + 7, // 7: tfplan.Plan.backend:type_name -> tfplan.Backend + 19, // 8: tfplan.Plan.relevant_attributes:type_name -> tfplan.Plan.resource_attr + 13, // 9: tfplan.Plan.provider_function_results:type_name -> tfplan.ProviderFunctionCallHash + 14, // 10: tfplan.Backend.config:type_name -> tfplan.DynamicValue + 1, // 11: tfplan.Change.action:type_name -> tfplan.Action + 14, // 12: tfplan.Change.values:type_name -> tfplan.DynamicValue + 15, // 13: tfplan.Change.before_sensitive_paths:type_name -> tfplan.Path + 15, // 14: tfplan.Change.after_sensitive_paths:type_name -> tfplan.Path + 16, // 15: tfplan.Change.importing:type_name -> tfplan.Importing + 8, // 16: tfplan.ResourceInstanceChange.change:type_name -> tfplan.Change + 15, // 17: tfplan.ResourceInstanceChange.required_replace:type_name -> tfplan.Path + 2, // 18: tfplan.ResourceInstanceChange.action_reason:type_name -> tfplan.ResourceInstanceActionReason + 17, // 19: tfplan.DeferredResourceInstanceChange.deferred:type_name -> tfplan.Deferred + 9, // 20: tfplan.DeferredResourceInstanceChange.change:type_name -> tfplan.ResourceInstanceChange + 8, // 21: tfplan.OutputChange.change:type_name -> tfplan.Change + 5, // 22: tfplan.CheckResults.kind:type_name -> tfplan.CheckResults.ObjectKind + 4, // 23: tfplan.CheckResults.status:type_name -> tfplan.CheckResults.Status + 20, // 24: tfplan.CheckResults.objects:type_name -> tfplan.CheckResults.ObjectResult + 21, // 25: tfplan.Path.steps:type_name -> tfplan.Path.Step + 3, // 26: tfplan.Deferred.reason:type_name -> tfplan.DeferredReason + 14, // 27: tfplan.Plan.VariablesEntry.value:type_name -> tfplan.DynamicValue + 15, // 28: tfplan.Plan.resource_attr.attr:type_name -> tfplan.Path + 4, // 29: tfplan.CheckResults.ObjectResult.status:type_name -> tfplan.CheckResults.Status + 14, // 30: tfplan.Path.Step.element_key:type_name -> tfplan.DynamicValue + 31, // [31:31] is the sub-list for method output_type + 31, // [31:31] is the sub-list for method input_type + 31, // [31:31] is the sub-list for extension type_name + 31, // [31:31] is the sub-list for extension extendee + 0, // [0:31] is the sub-list for field type_name } func init() { file_planfile_proto_init() } @@ -1795,7 +2013,7 @@ func file_planfile_proto_init() { } } file_planfile_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OutputChange); i { + switch v := v.(*DeferredResourceInstanceChange); i { case 0: return &v.state case 1: @@ -1807,7 +2025,7 @@ func file_planfile_proto_init() { } } file_planfile_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckResults); i { + switch v := v.(*OutputChange); i { case 0: return &v.state case 1: @@ -1819,7 +2037,7 @@ func file_planfile_proto_init() { } } file_planfile_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProviderFunctionCallHash); i { + switch v := v.(*CheckResults); i { case 0: return &v.state case 1: @@ -1831,7 +2049,7 @@ func file_planfile_proto_init() { } } file_planfile_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DynamicValue); i { + switch v := v.(*ProviderFunctionCallHash); i { case 0: return &v.state case 1: @@ -1843,7 +2061,7 @@ func file_planfile_proto_init() { } } file_planfile_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Path); i { + switch v := v.(*DynamicValue); i { case 0: return &v.state case 1: @@ -1855,6 +2073,18 @@ func file_planfile_proto_init() { } } file_planfile_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Path); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_planfile_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Importing); i { case 0: return &v.state @@ -1867,6 +2097,18 @@ func file_planfile_proto_init() { } } file_planfile_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Deferred); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_planfile_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanResourceAttr); i { case 0: return &v.state @@ -1878,7 +2120,7 @@ func file_planfile_proto_init() { return nil } } - file_planfile_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_planfile_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CheckResults_ObjectResult); i { case 0: return &v.state @@ -1890,7 +2132,7 @@ func file_planfile_proto_init() { return nil } } - file_planfile_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_planfile_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Path_Step); i { case 0: return &v.state @@ -1903,7 +2145,7 @@ func file_planfile_proto_init() { } } } - file_planfile_proto_msgTypes[13].OneofWrappers = []interface{}{ + file_planfile_proto_msgTypes[15].OneofWrappers = []interface{}{ (*Path_Step_AttributeName)(nil), (*Path_Step_ElementKey)(nil), } @@ -1912,8 +2154,8 @@ func file_planfile_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_planfile_proto_rawDesc, - NumEnums: 5, - NumMessages: 14, + NumEnums: 6, + NumMessages: 16, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/plans/planproto/planfile.proto b/internal/plans/planproto/planfile.proto index baf3aee54570..882c00a80c08 100644 --- a/internal/plans/planproto/planfile.proto +++ b/internal/plans/planproto/planfile.proto @@ -71,6 +71,12 @@ message Plan { // after refresh. repeated ResourceInstanceChange resource_drift = 18; + // An unordered set of deferred changes. These are changes that will be + // applied in a subsequent plan, but were deferred in this plan for some + // reason. Generally, if complete is set to false there should be entries + // in this list. + repeated DeferredResourceInstanceChange deferred_changes = 27; + // An unordered set of proposed changes to outputs in the root module // of the configuration. This set also includes "no action" changes for // outputs that are not changing, as context for detecting inconsistencies @@ -253,6 +259,19 @@ message ResourceInstanceChange { ResourceInstanceActionReason action_reason = 12; } +// DeferredResourceInstanceChange represents a resource instance change that +// was deferred for some reason. +// +// It contains the original change that was deferred, along with the reason +// why it was deferred. +message DeferredResourceInstanceChange { + // The reason why the change was deferred. + Deferred deferred = 1; + + // The original change that was deferred. + ResourceInstanceChange change = 2; +} + message OutputChange { // Name of the output as defined in the root module. string name = 1; @@ -353,3 +372,20 @@ message Importing { // The original ID of the resource. string id = 1; } + +// DeferredReason describes the reason why a resource instance change was +// deferred. +enum DeferredReason { + INVALID = 0; + INSTANCE_COUNT_UNKNOWN = 1; + RESOURCE_CONFIG_UNKNOWN = 2; + PROVIDER_CONFIG_UNKNOWN = 3; + ABSENT_PREREQ = 4; + DEFERRED_PREREQ = 5; +} + +// Deferred contains all the metadata about a the deferral of a resource +// instance change. +message Deferred { + DeferredReason reason = 1; +} diff --git a/internal/terraform/context_apply_deferred_test.go b/internal/terraform/context_apply_deferred_test.go index f2638c57f62c..f3784d45ca4c 100644 --- a/internal/terraform/context_apply_deferred_test.go +++ b/internal/terraform/context_apply_deferred_test.go @@ -40,6 +40,9 @@ type deferredActionsTestStage struct { // The values we want to be planned within each cycle. wantPlanned map[string]cty.Value + // The values we want to be deferred within each cycle. + wantDeferred map[string]plans.DeferredReason + // The expected actions from the plan step. wantActions map[string]plans.Action @@ -133,6 +136,10 @@ output "c" { // The other resources will be deferred, so shouldn't // have any action at this stage. }, + wantDeferred: map[string]plans.DeferredReason{ + "test.b[\"*\"]": plans.DeferredReasonInstanceCountUnknown, + "test.c": plans.DeferredReasonDeferredPrereq, + }, wantApplied: map[string]cty.Value{ "a": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("a"), @@ -231,6 +238,7 @@ output "c" { `test.b["2"]`: plans.Create, `test.c`: plans.Create, }, + wantDeferred: make(map[string]plans.DeferredReason), wantApplied: map[string]cty.Value{ // Since test.a is no-op, it isn't visited during apply. The // other instances should all be applied, though. @@ -328,7 +336,8 @@ output "c" { `test.b["2"]`: plans.NoOp, `test.c`: plans.NoOp, }, - complete: true, + wantDeferred: make(map[string]plans.DeferredReason), + complete: true, // We won't execute an apply step in this stage, because the // plan should be empty. }, @@ -390,10 +399,6 @@ func TestContextApply_deferredActions(t *testing.T) { t.Errorf("wrong completion status in plan: got %v, want %v", plan.Complete, stage.complete) } - // TODO: Once we are including information about the - // individual deferred actions in the plan, this would be - // a good place to assert that they are correct! - // We expect the correct planned changes and no diagnostics. assertNoDiagnostics(t, diags) provider.plannedChanges.Test(t, stage.wantPlanned) @@ -407,6 +412,14 @@ func TestContextApply_deferredActions(t *testing.T) { t.Errorf("wrong actions in plan\n%s", diff) } + gotDeferred := make(map[string]plans.DeferredReason) + for _, dc := range plan.DeferredResources { + gotDeferred[dc.ChangeSrc.Addr.String()] = dc.DeferredReason + } + if diff := cmp.Diff(stage.wantDeferred, gotDeferred); diff != "" { + t.Errorf("wrong deferred reasons in plan\n%s", diff) + } + if stage.wantApplied == nil { // Don't execute the apply stage if wantApplied is nil. return diff --git a/internal/terraform/context_plan.go b/internal/terraform/context_plan.go index cdc1ad9fcdf9..39f77280c045 100644 --- a/internal/terraform/context_plan.go +++ b/internal/terraform/context_plan.go @@ -734,6 +734,9 @@ func (c *Context) planWalk(config *configs.Config, prevRunState *states.State, o driftedResources, driftDiags := c.driftedResources(config, prevRunState, priorState, moveResults) diags = diags.Append(driftDiags) + deferredResources, deferredDiags := c.deferredResources(config, walker.Deferrals.GetDeferredChanges(), priorState) + diags = diags.Append(deferredDiags) + var forgottenResources []string for _, rc := range changes.Resources { if rc.Action == plans.Forget { @@ -753,6 +756,7 @@ func (c *Context) planWalk(config *configs.Config, prevRunState *states.State, o UIMode: opts.Mode, Changes: changes, DriftedResources: driftedResources, + DeferredResources: deferredResources, PrevRunState: prevRunState, PriorState: priorState, PlannedState: walker.State.Close(), @@ -805,6 +809,36 @@ func (c *Context) planWalk(config *configs.Config, prevRunState *states.State, o return plan, evalScope, diags } +func (c *Context) deferredResources(config *configs.Config, deferrals []*plans.DeferredResourceInstanceChange, state *states.State) ([]*plans.DeferredResourceInstanceChangeSrc, tfdiags.Diagnostics) { + var deferredResources []*plans.DeferredResourceInstanceChangeSrc + + schemas, diags := c.Schemas(config, state) + if diags.HasErrors() { + return deferredResources, diags + } + + for _, deferral := range deferrals { + + schema, _ := schemas.ResourceTypeConfig( + deferral.Change.ProviderAddr.Provider, + deferral.Change.Addr.Resource.Resource.Mode, + deferral.Change.Addr.Resource.Resource.Type) + + ty := schema.ImpliedType() + deferralSrc, err := deferral.Encode(ty) + if err != nil { + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Failed to prepare deferred resource for plan", + fmt.Sprintf("The deferred resource %q could not be serialized to store in the plan: %s.", deferral.Change.Addr, err))) + continue + } + + deferredResources = append(deferredResources, deferralSrc) + } + return deferredResources, diags +} + func (c *Context) planGraph(config *configs.Config, prevRunState *states.State, opts *PlanOpts) (*Graph, walkOperation, tfdiags.Diagnostics) { var externalProviderConfigs map[addrs.RootProviderConfig]providers.Interface if opts != nil { diff --git a/internal/terraform/node_resource_plan_instance.go b/internal/terraform/node_resource_plan_instance.go index ff916267eed9..9565cf77b580 100644 --- a/internal/terraform/node_resource_plan_instance.go +++ b/internal/terraform/node_resource_plan_instance.go @@ -359,7 +359,7 @@ func (n *NodePlannableResourceInstance) managedResourceExecute(ctx EvalContext) // In this case, the expression evaluator should use the placeholder // value registered here as the value of this resource instance, // instead of using the plan. - deferrals.ReportResourceInstanceDeferred(n.Addr, change.Action, change.After) + deferrals.ReportResourceInstanceDeferred(n.Addr, plans.DeferredReasonDeferredPrereq, change) } } else { // In refresh-only mode we need to evaluate the for-each expression in diff --git a/internal/terraform/node_resource_plan_partialexp.go b/internal/terraform/node_resource_plan_partialexp.go index aab2c692ec9e..7e16b44f7a56 100644 --- a/internal/terraform/node_resource_plan_partialexp.go +++ b/internal/terraform/node_resource_plan_partialexp.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/terraform/internal/addrs" "github.com/hashicorp/terraform/internal/configs" "github.com/hashicorp/terraform/internal/instances" + "github.com/hashicorp/terraform/internal/plans" "github.com/hashicorp/terraform/internal/plans/objchange" "github.com/hashicorp/terraform/internal/providers" "github.com/hashicorp/terraform/internal/tfdiags" @@ -85,13 +86,15 @@ func (n *nodePlannablePartialExpandedResource) Execute(ctx EvalContext, op walkO // log.Printf("[TRACE] nodePlannablePartialExpandedResource: checking all of %s", n.addr.String()) - var placeholderVal cty.Value var diags tfdiags.Diagnostics switch n.addr.Resource().Mode { case addrs.ManagedResourceMode: - placeholderVal, diags = n.managedResourceExecute(ctx) + change, changeDiags := n.managedResourceExecute(ctx) + diags = diags.Append(changeDiags) + ctx.Deferrals().ReportResourceExpansionDeferred(n.addr, change) case addrs.DataResourceMode: - placeholderVal, diags = n.dataResourceExecute(ctx) + _, diags = n.dataResourceExecute(ctx) + ctx.Deferrals().ReportDataSourceExpansionDeferred(n.addr) default: panic(fmt.Errorf("unsupported resource mode %s", n.config.Mode)) } @@ -99,11 +102,10 @@ func (n *nodePlannablePartialExpandedResource) Execute(ctx EvalContext, op walkO // Registering this allows downstream resources that depend on this one // to know that they need to defer themselves too, in order to preserve // correct dependency order. - ctx.Deferrals().ReportResourceExpansionDeferred(n.addr, placeholderVal) return diags } -func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalContext) (cty.Value, tfdiags.Diagnostics) { +func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalContext) (*plans.ResourceInstanceChange, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics // We cannot fully plan partial-expanded resources because we don't know @@ -114,22 +116,36 @@ func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalCo // to shorten the iterative journey, so nothing here actually contributes // new actions to the plan. + // We'll make a basic change for us to use as a placeholder for the time + // being, and we'll populate it as we get more info. + change := plans.ResourceInstanceChange{ + Addr: n.addr.UnknownResourceInstance(), + ProviderAddr: n.resolvedProvider, + Change: plans.Change{ + // We don't actually know the action, but we simulate the plan later + // as a create action so we'll use that here too. + Action: plans.Create, + Before: cty.NullVal(cty.DynamicPseudoType), + After: cty.DynamicVal, // This will be populated later + }, + } + provider, providerSchema, err := getProvider(ctx, n.resolvedProvider) diags = diags.Append(err) if diags.HasErrors() { - return cty.DynamicVal, diags + return &change, diags } diags = diags.Append(validateSelfRef(n.addr.Resource(), n.config.Config, providerSchema)) if diags.HasErrors() { - return cty.DynamicVal, diags + return &change, diags } schema, _ := providerSchema.SchemaForResourceAddr(n.addr.Resource()) if schema == nil { // Should be caught during validation, so we don't bother with a pretty error here diags = diags.Append(fmt.Errorf("provider does not support resource type %q", n.addr.Resource().Type)) - return cty.DynamicVal, diags + return &change, diags } // TODO: Normal managed resource planning @@ -149,7 +165,7 @@ func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalCo // not really anything else to do here, since we can only refresh // specific known resource instances (which another graph node should // handle), so we'll just return early. - return cty.DynamicVal, diags + return &change, diags } // Because we don't know the instance keys yet, we'll be evaluating using @@ -179,7 +195,7 @@ func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalCo configVal, _, configDiags := ctx.EvaluateBlock(n.config.Config, schema, nil, keyData) diags = diags.Append(configDiags) if configDiags.HasErrors() { - return cty.DynamicVal, diags + return &change, diags } unmarkedConfigVal, _ := configVal.UnmarkDeep() @@ -191,7 +207,7 @@ func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalCo ) diags = diags.Append(validateResp.Diagnostics.InConfigBody(n.config.Config, n.addr.String())) if diags.HasErrors() { - return cty.DynamicVal, diags + return &change, diags } unmarkedConfigVal, unmarkedPaths := configVal.UnmarkDeepWithPaths() @@ -217,7 +233,7 @@ func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalCo }) diags = diags.Append(resp.Diagnostics.InConfigBody(n.config.Config, n.addr.String())) if diags.HasErrors() { - return cty.DynamicVal, diags + return &change, diags } plannedNewVal := resp.PlannedState @@ -239,7 +255,7 @@ func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalCo )) } if diags.HasErrors() { - return cty.DynamicVal, diags + return &change, diags } if errs := objchange.AssertPlanValid(schema, priorVal, unmarkedConfigVal, plannedNewVal); len(errs) > 0 { @@ -269,7 +285,7 @@ func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalCo ), )) } - return cty.DynamicVal, diags + return &change, diags } } @@ -280,7 +296,9 @@ func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalCo plannedNewVal = plannedNewVal.MarkWithPaths(unmarkedPaths) } - return plannedNewVal, diags + change.After = plannedNewVal + change.Private = resp.PlannedPrivate + return &change, diags } func (n *nodePlannablePartialExpandedResource) dataResourceExecute(ctx EvalContext) (cty.Value, tfdiags.Diagnostics) {