diff --git a/internal/stacks/tfstackdata1/tfstackdata1.pb.go b/internal/stacks/tfstackdata1/tfstackdata1.pb.go new file mode 100644 index 0000000000..17710b85c6 --- /dev/null +++ b/internal/stacks/tfstackdata1/tfstackdata1.pb.go @@ -0,0 +1,680 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v3.15.6 +// source: tfstackdata1.proto + +package tfstackdata1 + +import ( + planproto "github.com/hashicorp/terraform/internal/plans/planproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Appears early in a raw plan sequence to capture some metadata that we need +// to process subsequent messages, or to abort if we're being asked to decode +// a plan created by a different version of Terraform. +type PlanHeader struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The canonical version string for the version of Terraform that created + // the plan sequence that this message belongs to. + // + // The raw plan sequence loader will fail if it finds a message of this + // type with a version string that disagrees with the version of Terraform + // decoding the message, because we always expect plans to be applied by + // the same version of Terraform that created them. + TerraformVersion string `protobuf:"bytes,1,opt,name=terraform_version,json=terraformVersion,proto3" json:"terraform_version,omitempty"` +} + +func (x *PlanHeader) Reset() { + *x = PlanHeader{} + if protoimpl.UnsafeEnabled { + mi := &file_tfstackdata1_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlanHeader) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanHeader) ProtoMessage() {} + +func (x *PlanHeader) ProtoReflect() protoreflect.Message { + mi := &file_tfstackdata1_proto_msgTypes[0] + 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 PlanHeader.ProtoReflect.Descriptor instead. +func (*PlanHeader) Descriptor() ([]byte, []int) { + return file_tfstackdata1_proto_rawDescGZIP(), []int{0} +} + +func (x *PlanHeader) GetTerraformVersion() string { + if x != nil { + return x.TerraformVersion + } + return "" +} + +// Confirms whether the overall plan whose raw plan sequence includes this +// message is complete enough and valid enough to be applied. +// +// If a the sequence of raw plan messages includes multiple messages of this +// type then the one with the latest position in the list "wins" during +// decoding of the overall sequence, although in practice there isn't yet +// any clear reason to include more than one instance of this message type in a +// plan. +type PlanApplyable struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Applyable bool `protobuf:"varint,1,opt,name=applyable,proto3" json:"applyable,omitempty"` +} + +func (x *PlanApplyable) Reset() { + *x = PlanApplyable{} + if protoimpl.UnsafeEnabled { + mi := &file_tfstackdata1_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlanApplyable) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanApplyable) ProtoMessage() {} + +func (x *PlanApplyable) ProtoReflect() protoreflect.Message { + mi := &file_tfstackdata1_proto_msgTypes[1] + 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 PlanApplyable.ProtoReflect.Descriptor instead. +func (*PlanApplyable) Descriptor() ([]byte, []int) { + return file_tfstackdata1_proto_rawDescGZIP(), []int{1} +} + +func (x *PlanApplyable) GetApplyable() bool { + if x != nil { + return x.Applyable + } + return false +} + +// Represents the existence of a particular component instance, and so must +// always appear before any messages representing objects that belong to that +// component instance. +// +// This message type exists to avoid the ambiguity between a component instance +// existing with zero resource instances inside vs. a component instance +// not existing at all. +type PlanComponentInstance struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ComponentInstanceAddr string `protobuf:"bytes,1,opt,name=component_instance_addr,json=componentInstanceAddr,proto3" json:"component_instance_addr,omitempty"` + // plan_timestamp records the time when the plan for this component + // instance was created, exclusively for making sure that the + // "plantimestamp" function can return the same value during the apply + // phase. It must not be used for any other purpose. + PlanTimestamp string `protobuf:"bytes,2,opt,name=plan_timestamp,json=planTimestamp,proto3" json:"plan_timestamp,omitempty"` +} + +func (x *PlanComponentInstance) Reset() { + *x = PlanComponentInstance{} + if protoimpl.UnsafeEnabled { + mi := &file_tfstackdata1_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlanComponentInstance) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanComponentInstance) ProtoMessage() {} + +func (x *PlanComponentInstance) ProtoReflect() protoreflect.Message { + mi := &file_tfstackdata1_proto_msgTypes[2] + 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 PlanComponentInstance.ProtoReflect.Descriptor instead. +func (*PlanComponentInstance) Descriptor() ([]byte, []int) { + return file_tfstackdata1_proto_rawDescGZIP(), []int{2} +} + +func (x *PlanComponentInstance) GetComponentInstanceAddr() string { + if x != nil { + return x.ComponentInstanceAddr + } + return "" +} + +func (x *PlanComponentInstance) GetPlanTimestamp() string { + if x != nil { + return x.PlanTimestamp + } + return "" +} + +// Represents a planned change to a particular resource instance within a +// particular component instance. +type PlanResourceInstanceChangePlanned struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The same string must previously have been announced with a + // PlanComponentInstance message, or the overall plan sequence is invalid. + ComponentInstanceAddr string `protobuf:"bytes,1,opt,name=component_instance_addr,json=componentInstanceAddr,proto3" json:"component_instance_addr,omitempty"` + Change *planproto.ResourceInstanceChange `protobuf:"bytes,2,opt,name=change,proto3" json:"change,omitempty"` +} + +func (x *PlanResourceInstanceChangePlanned) Reset() { + *x = PlanResourceInstanceChangePlanned{} + if protoimpl.UnsafeEnabled { + mi := &file_tfstackdata1_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlanResourceInstanceChangePlanned) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanResourceInstanceChangePlanned) ProtoMessage() {} + +func (x *PlanResourceInstanceChangePlanned) ProtoReflect() protoreflect.Message { + mi := &file_tfstackdata1_proto_msgTypes[3] + 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 PlanResourceInstanceChangePlanned.ProtoReflect.Descriptor instead. +func (*PlanResourceInstanceChangePlanned) Descriptor() ([]byte, []int) { + return file_tfstackdata1_proto_rawDescGZIP(), []int{3} +} + +func (x *PlanResourceInstanceChangePlanned) GetComponentInstanceAddr() string { + if x != nil { + return x.ComponentInstanceAddr + } + return "" +} + +func (x *PlanResourceInstanceChangePlanned) GetChange() *planproto.ResourceInstanceChange { + if x != nil { + return x.Change + } + return nil +} + +// Represents a change to a particular resource instance within a particular +// component instance that Terraform has detected was made outside of Terraform +// since the most recent apply. +type PlanResourceInstanceChangeOutside struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The same string must previously have been announced with a + // PlanComponentInstance message, or the overall plan sequence is invalid. + ComponentInstanceAddr string `protobuf:"bytes,1,opt,name=component_instance_addr,json=componentInstanceAddr,proto3" json:"component_instance_addr,omitempty"` + Change *planproto.ResourceInstanceChange `protobuf:"bytes,2,opt,name=change,proto3" json:"change,omitempty"` +} + +func (x *PlanResourceInstanceChangeOutside) Reset() { + *x = PlanResourceInstanceChangeOutside{} + if protoimpl.UnsafeEnabled { + mi := &file_tfstackdata1_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlanResourceInstanceChangeOutside) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanResourceInstanceChangeOutside) ProtoMessage() {} + +func (x *PlanResourceInstanceChangeOutside) ProtoReflect() protoreflect.Message { + mi := &file_tfstackdata1_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 PlanResourceInstanceChangeOutside.ProtoReflect.Descriptor instead. +func (*PlanResourceInstanceChangeOutside) Descriptor() ([]byte, []int) { + return file_tfstackdata1_proto_rawDescGZIP(), []int{4} +} + +func (x *PlanResourceInstanceChangeOutside) GetComponentInstanceAddr() string { + if x != nil { + return x.ComponentInstanceAddr + } + return "" +} + +func (x *PlanResourceInstanceChangeOutside) GetChange() *planproto.ResourceInstanceChange { + if x != nil { + return x.Change + } + return nil +} + +// Represents the existence of a particular component instance. +// +// This is here just to remove the ambiguity between a component instance that +// exists but contains no resource instances vs. a component instance that +// doesn't exist at all. +// +// Because the state map is updated on a per-element basis rather than +// atomically, it's possible that the state map might contain resource instances +// which belong to a component instance that is not tracked by a message of +// this type. In that case, the state loader will just assume an implied +// message of this type with a matching component instance address and with +// all other fields unset. +type StateComponentInstanceV1 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ComponentInstanceAddr string `protobuf:"bytes,1,opt,name=component_instance_addr,json=componentInstanceAddr,proto3" json:"component_instance_addr,omitempty"` +} + +func (x *StateComponentInstanceV1) Reset() { + *x = StateComponentInstanceV1{} + if protoimpl.UnsafeEnabled { + mi := &file_tfstackdata1_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StateComponentInstanceV1) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StateComponentInstanceV1) ProtoMessage() {} + +func (x *StateComponentInstanceV1) ProtoReflect() protoreflect.Message { + mi := &file_tfstackdata1_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StateComponentInstanceV1.ProtoReflect.Descriptor instead. +func (*StateComponentInstanceV1) Descriptor() ([]byte, []int) { + return file_tfstackdata1_proto_rawDescGZIP(), []int{5} +} + +func (x *StateComponentInstanceV1) GetComponentInstanceAddr() string { + if x != nil { + return x.ComponentInstanceAddr + } + return "" +} + +// Represents the existence of a particular resource instance in a particular +// component instance. +// +// A resource instance message should typically be accompanied by a +// StateComponentInstanceV1 (or later version) that represents the existence +// of the component itself, but for robustness we tolerate the absense of +// such a message and just assume that all of its fields (other than the +// component instance address) are unset. +type StateResourceInstanceV1 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ComponentInstanceAddr string `protobuf:"bytes,1,opt,name=component_instance_addr,json=componentInstanceAddr,proto3" json:"component_instance_addr,omitempty"` + ResourceInstanceAddr string `protobuf:"bytes,2,opt,name=resource_instance_addr,json=resourceInstanceAddr,proto3" json:"resource_instance_addr,omitempty"` + DeposedKey string `protobuf:"bytes,3,opt,name=deposed_key,json=deposedKey,proto3" json:"deposed_key,omitempty"` + Value *planproto.DynamicValue `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + SensitivePaths *planproto.Path `protobuf:"bytes,5,opt,name=sensitive_paths,json=sensitivePaths,proto3" json:"sensitive_paths,omitempty"` +} + +func (x *StateResourceInstanceV1) Reset() { + *x = StateResourceInstanceV1{} + if protoimpl.UnsafeEnabled { + mi := &file_tfstackdata1_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StateResourceInstanceV1) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StateResourceInstanceV1) ProtoMessage() {} + +func (x *StateResourceInstanceV1) ProtoReflect() protoreflect.Message { + mi := &file_tfstackdata1_proto_msgTypes[6] + 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 StateResourceInstanceV1.ProtoReflect.Descriptor instead. +func (*StateResourceInstanceV1) Descriptor() ([]byte, []int) { + return file_tfstackdata1_proto_rawDescGZIP(), []int{6} +} + +func (x *StateResourceInstanceV1) GetComponentInstanceAddr() string { + if x != nil { + return x.ComponentInstanceAddr + } + return "" +} + +func (x *StateResourceInstanceV1) GetResourceInstanceAddr() string { + if x != nil { + return x.ResourceInstanceAddr + } + return "" +} + +func (x *StateResourceInstanceV1) GetDeposedKey() string { + if x != nil { + return x.DeposedKey + } + return "" +} + +func (x *StateResourceInstanceV1) GetValue() *planproto.DynamicValue { + if x != nil { + return x.Value + } + return nil +} + +func (x *StateResourceInstanceV1) GetSensitivePaths() *planproto.Path { + if x != nil { + return x.SensitivePaths + } + return nil +} + +var File_tfstackdata1_proto protoreflect.FileDescriptor + +var file_tfstackdata1_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x74, 0x66, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x64, 0x61, 0x74, 0x61, 0x31, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x74, 0x66, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x64, 0x61, 0x74, + 0x61, 0x31, 0x1a, 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x39, 0x0a, 0x0a, 0x50, 0x6c, 0x61, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x65, 0x72, + 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x2d, 0x0a, + 0x0d, 0x50, 0x6c, 0x61, 0x6e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x76, 0x0a, 0x15, + 0x50, 0x6c, 0x61, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x25, 0x0a, + 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x6c, 0x61, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x22, 0x93, 0x01, 0x0a, 0x21, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x64, + 0x64, 0x72, 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, 0x93, 0x01, 0x0a, 0x21, 0x50, + 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, + 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 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, 0x52, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x31, 0x12, 0x36, 0x0a, 0x17, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, + 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x41, 0x64, 0x64, 0x72, 0x22, 0x8b, 0x02, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x31, + 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x12, 0x1f, + 0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, + 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 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, 0x12, 0x35, 0x0a, 0x0f, 0x73, + 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x61, 0x6e, 0x2e, 0x50, 0x61, + 0x74, 0x68, 0x52, 0x0e, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, + 0x68, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_tfstackdata1_proto_rawDescOnce sync.Once + file_tfstackdata1_proto_rawDescData = file_tfstackdata1_proto_rawDesc +) + +func file_tfstackdata1_proto_rawDescGZIP() []byte { + file_tfstackdata1_proto_rawDescOnce.Do(func() { + file_tfstackdata1_proto_rawDescData = protoimpl.X.CompressGZIP(file_tfstackdata1_proto_rawDescData) + }) + return file_tfstackdata1_proto_rawDescData +} + +var file_tfstackdata1_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_tfstackdata1_proto_goTypes = []interface{}{ + (*PlanHeader)(nil), // 0: tfstackdata1.PlanHeader + (*PlanApplyable)(nil), // 1: tfstackdata1.PlanApplyable + (*PlanComponentInstance)(nil), // 2: tfstackdata1.PlanComponentInstance + (*PlanResourceInstanceChangePlanned)(nil), // 3: tfstackdata1.PlanResourceInstanceChangePlanned + (*PlanResourceInstanceChangeOutside)(nil), // 4: tfstackdata1.PlanResourceInstanceChangeOutside + (*StateComponentInstanceV1)(nil), // 5: tfstackdata1.StateComponentInstanceV1 + (*StateResourceInstanceV1)(nil), // 6: tfstackdata1.StateResourceInstanceV1 + (*planproto.ResourceInstanceChange)(nil), // 7: tfplan.ResourceInstanceChange + (*planproto.DynamicValue)(nil), // 8: tfplan.DynamicValue + (*planproto.Path)(nil), // 9: tfplan.Path +} +var file_tfstackdata1_proto_depIdxs = []int32{ + 7, // 0: tfstackdata1.PlanResourceInstanceChangePlanned.change:type_name -> tfplan.ResourceInstanceChange + 7, // 1: tfstackdata1.PlanResourceInstanceChangeOutside.change:type_name -> tfplan.ResourceInstanceChange + 8, // 2: tfstackdata1.StateResourceInstanceV1.value:type_name -> tfplan.DynamicValue + 9, // 3: tfstackdata1.StateResourceInstanceV1.sensitive_paths:type_name -> tfplan.Path + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_tfstackdata1_proto_init() } +func file_tfstackdata1_proto_init() { + if File_tfstackdata1_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_tfstackdata1_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlanHeader); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfstackdata1_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlanApplyable); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfstackdata1_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlanComponentInstance); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfstackdata1_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlanResourceInstanceChangePlanned); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfstackdata1_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlanResourceInstanceChangeOutside); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfstackdata1_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StateComponentInstanceV1); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfstackdata1_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StateResourceInstanceV1); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_tfstackdata1_proto_rawDesc, + NumEnums: 0, + NumMessages: 7, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_tfstackdata1_proto_goTypes, + DependencyIndexes: file_tfstackdata1_proto_depIdxs, + MessageInfos: file_tfstackdata1_proto_msgTypes, + }.Build() + File_tfstackdata1_proto = out.File + file_tfstackdata1_proto_rawDesc = nil + file_tfstackdata1_proto_goTypes = nil + file_tfstackdata1_proto_depIdxs = nil +} diff --git a/internal/stacks/tfstackdata1/tfstackdata1.proto b/internal/stacks/tfstackdata1/tfstackdata1.proto new file mode 100644 index 0000000000..0e21b2f1c3 --- /dev/null +++ b/internal/stacks/tfstackdata1/tfstackdata1.proto @@ -0,0 +1,155 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +syntax = "proto3"; +package tfstackdata1; + +import "planfile.proto"; // tfplan, from internal/plans/planproto + +// These definitions describe the PRIVATE raw format that we use to persist +// stack and plan information for stacks between operations. +// +// Nothing outside of this codebase should attempt to produce or consume +// these formats. They are subject to change at any time. + +///////////// PLAN SEQUENCE MESSAGES +// +// A "stack plan" consists of a sequence of messages emitted gradually from +// the streaming Stacks.PlanStackChanges RPC in the Terraform Core RPC API. +// +// From the perspective of that protocol the objects in the sequence are +// opaque and to be preserved byte-for-byte without any external interpretation, +// in the same order they were emitted from Terraform Core. +// +// Internally, we decode each one based on the type field of google.protobuf.Any, +// treating each one as some kind of mutation of our in-memory plan data +// structure. +// +// These message types only cover the data that Terraform needs to apply the +// plan, and so don't cover any information that Terraform Core might emit +// only for the caller's benefit. +////////////// + +// Appears early in a raw plan sequence to capture some metadata that we need +// to process subsequent messages, or to abort if we're being asked to decode +// a plan created by a different version of Terraform. +message PlanHeader { + // The canonical version string for the version of Terraform that created + // the plan sequence that this message belongs to. + // + // The raw plan sequence loader will fail if it finds a message of this + // type with a version string that disagrees with the version of Terraform + // decoding the message, because we always expect plans to be applied by + // the same version of Terraform that created them. + string terraform_version = 1; +} + +// Confirms whether the overall plan whose raw plan sequence includes this +// message is complete enough and valid enough to be applied. +// +// If a the sequence of raw plan messages includes multiple messages of this +// type then the one with the latest position in the list "wins" during +// decoding of the overall sequence, although in practice there isn't yet +// any clear reason to include more than one instance of this message type in a +// plan. +message PlanApplyable { + bool applyable = 1; +} + +// Represents the existence of a particular component instance, and so must +// always appear before any messages representing objects that belong to that +// component instance. +// +// This message type exists to avoid the ambiguity between a component instance +// existing with zero resource instances inside vs. a component instance +// not existing at all. +message PlanComponentInstance { + string component_instance_addr = 1; + + // plan_timestamp records the time when the plan for this component + // instance was created, exclusively for making sure that the + // "plantimestamp" function can return the same value during the apply + // phase. It must not be used for any other purpose. + string plan_timestamp = 2; +} + +// Represents a planned change to a particular resource instance within a +// particular component instance. +message PlanResourceInstanceChangePlanned { + // The same string must previously have been announced with a + // PlanComponentInstance message, or the overall plan sequence is invalid. + string component_instance_addr = 1; + + tfplan.ResourceInstanceChange change = 2; +} + +// Represents a change to a particular resource instance within a particular +// component instance that Terraform has detected was made outside of Terraform +// since the most recent apply. +message PlanResourceInstanceChangeOutside { + // The same string must previously have been announced with a + // PlanComponentInstance message, or the overall plan sequence is invalid. + string component_instance_addr = 1; + + tfplan.ResourceInstanceChange change = 2; +} + +///////////// STATE MAP MESSAGES +// +// A "stack state snapshot" is a mapping from arbitrary keys to messages +// emitted gradually from the streaming Stacks.ApplyStackChanges RPC in the +// Terraform Core RPC API. +// +// From the perspective of that protocol the keys and values in the map are +// opaque and to be preserved verbatim without any external interpretation, +// overwriting any previous value that had the same key. +// +// Internally, we decode each one based on the type field of google.protobuf.Any, +// treating each one as some kind of mutation of our in-memory plan data +// structure. +// +// These message types only cover the data that Terraform needs to produce +// a future plan based on this snapshot, and don't cover any information that +// Terraform Core might emit only for the caller's benefit. +// +// Because state messages survive from one run to the next, all top-level +// messages used for state snapshots have a format version suffix that is +// currently always 1. The functions that load a state map into the in-memory +// state structure will fail if any of the messages are of an unknown type, so +// we should increment the format version only as a last resort because this +// will prevent users from downgrading to an earlier version of Terraform once +// they've got at least one state map message that is of a newer version. +////////////// + +// Represents the existence of a particular component instance. +// +// This is here just to remove the ambiguity between a component instance that +// exists but contains no resource instances vs. a component instance that +// doesn't exist at all. +// +// Because the state map is updated on a per-element basis rather than +// atomically, it's possible that the state map might contain resource instances +// which belong to a component instance that is not tracked by a message of +// this type. In that case, the state loader will just assume an implied +// message of this type with a matching component instance address and with +// all other fields unset. +message StateComponentInstanceV1 { + string component_instance_addr = 1; +} + +// Represents the existence of a particular resource instance in a particular +// component instance. +// +// A resource instance message should typically be accompanied by a +// StateComponentInstanceV1 (or later version) that represents the existence +// of the component itself, but for robustness we tolerate the absense of +// such a message and just assume that all of its fields (other than the +// component instance address) are unset. +message StateResourceInstanceV1 { + string component_instance_addr = 1; + string resource_instance_addr = 2; + string deposed_key = 3; + + tfplan.DynamicValue value = 4; + tfplan.Path sensitive_paths = 5; +} diff --git a/tools/protobuf-compile/protobuf-compile.go b/tools/protobuf-compile/protobuf-compile.go index b37e8caf52..57c0b7fa48 100644 --- a/tools/protobuf-compile/protobuf-compile.go +++ b/tools/protobuf-compile/protobuf-compile.go @@ -63,6 +63,11 @@ var protocSteps = []protocStep{ "internal/plans/planproto", []string{"--go_out=paths=source_relative:.", "planfile.proto"}, }, + { + "tfstackdata1 (Internal data formats for Stack state and plan)", + "internal/stacks/tfstackdata1", + []string{"--go_out=paths=source_relative:.", "--go_opt=Mtfstackdata1.proto=github.com/hashicorp/terraform/internal/stacks/tfstackdata1", "-I.", "-I../../plans/planproto", "./tfstackdata1.proto"}, + }, { "cloudproto1 (cloud protocol version 1)", "internal/cloudplugin/cloudproto1",