From 7aa0a7107855d0f6d460843c5baef9cddce07452 Mon Sep 17 00:00:00 2001 From: Mutahhir Hayat Date: Mon, 12 Jan 2026 13:04:27 +0100 Subject: [PATCH 01/24] Create Protobuf changes for stack planning that includes Action invocations --- .../dependencies/dependencies.pb.go | 469 +++-- .../dependencies/dependencies.proto | 7 + .../rpcapi/terraform1/stacks/conversion.go | 7 + .../terraform1/stacks/conversion_test.go | 165 ++ .../rpcapi/terraform1/stacks/stacks.pb.go | 1820 ++++++++++++----- .../rpcapi/terraform1/stacks/stacks.proto | 107 + internal/stacks/stackaddrs/in_component.go | 4 + .../stacks/tfstackdata1/tfstackdata1.pb.go | 266 ++- .../stacks/tfstackdata1/tfstackdata1.proto | 22 + 9 files changed, 2109 insertions(+), 758 deletions(-) create mode 100644 internal/rpcapi/terraform1/stacks/conversion_test.go diff --git a/internal/rpcapi/terraform1/dependencies/dependencies.pb.go b/internal/rpcapi/terraform1/dependencies/dependencies.pb.go index d4ec82bf08..857968ba58 100644 --- a/internal/rpcapi/terraform1/dependencies/dependencies.pb.go +++ b/internal/rpcapi/terraform1/dependencies/dependencies.pb.go @@ -135,7 +135,7 @@ func (x Schema_NestedBlock_NestingMode) Number() protoreflect.EnumNumber { // Deprecated: Use Schema_NestedBlock_NestingMode.Descriptor instead. func (Schema_NestedBlock_NestingMode) EnumDescriptor() ([]byte, []int) { - return file_dependencies_proto_rawDescGZIP(), []int{13, 2, 0} + return file_dependencies_proto_rawDescGZIP(), []int{14, 2, 0} } type Schema_Object_NestingMode int32 @@ -190,7 +190,7 @@ func (x Schema_Object_NestingMode) Number() protoreflect.EnumNumber { // Deprecated: Use Schema_Object_NestingMode.Descriptor instead. func (Schema_Object_NestingMode) EnumDescriptor() ([]byte, []int) { - return file_dependencies_proto_rawDescGZIP(), []int{13, 3, 0} + return file_dependencies_proto_rawDescGZIP(), []int{14, 3, 0} } type Schema_DocString_Format int32 @@ -236,7 +236,7 @@ func (x Schema_DocString_Format) Number() protoreflect.EnumNumber { // Deprecated: Use Schema_DocString_Format.Descriptor instead. func (Schema_DocString_Format) EnumDescriptor() ([]byte, []int) { - return file_dependencies_proto_rawDescGZIP(), []int{13, 4, 0} + return file_dependencies_proto_rawDescGZIP(), []int{14, 4, 0} } type OpenSourceBundle struct { @@ -673,10 +673,11 @@ func (*GetProviderSchema) Descriptor() ([]byte, []int) { // ProviderSchema describes the full schema for a particular provider. type ProviderSchema struct { - state protoimpl.MessageState `protogen:"open.v1"` - ProviderConfig *Schema `protobuf:"bytes,1,opt,name=provider_config,json=providerConfig,proto3" json:"provider_config,omitempty"` - ManagedResourceTypes map[string]*Schema `protobuf:"bytes,2,rep,name=managed_resource_types,json=managedResourceTypes,proto3" json:"managed_resource_types,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - DataResourceTypes map[string]*Schema `protobuf:"bytes,3,rep,name=data_resource_types,json=dataResourceTypes,proto3" json:"data_resource_types,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + state protoimpl.MessageState `protogen:"open.v1"` + ProviderConfig *Schema `protobuf:"bytes,1,opt,name=provider_config,json=providerConfig,proto3" json:"provider_config,omitempty"` + ManagedResourceTypes map[string]*Schema `protobuf:"bytes,2,rep,name=managed_resource_types,json=managedResourceTypes,proto3" json:"managed_resource_types,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + DataResourceTypes map[string]*Schema `protobuf:"bytes,3,rep,name=data_resource_types,json=dataResourceTypes,proto3" json:"data_resource_types,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + ActionTypes map[string]*ActionSchema `protobuf:"bytes,4,rep,name=action_types,json=actionTypes,proto3" json:"action_types,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -732,6 +733,59 @@ func (x *ProviderSchema) GetDataResourceTypes() map[string]*Schema { return nil } +func (x *ProviderSchema) GetActionTypes() map[string]*ActionSchema { + if x != nil { + return x.ActionTypes + } + return nil +} + +// ActionSchema defines the schema for an action that can be invoked by +// Terraform. +type ActionSchema struct { + state protoimpl.MessageState `protogen:"open.v1"` + Schema *Schema `protobuf:"bytes,1,opt,name=schema,proto3" json:"schema,omitempty"` // of the action itself + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ActionSchema) Reset() { + *x = ActionSchema{} + mi := &file_dependencies_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ActionSchema) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActionSchema) ProtoMessage() {} + +func (x *ActionSchema) ProtoReflect() protoreflect.Message { + mi := &file_dependencies_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActionSchema.ProtoReflect.Descriptor instead. +func (*ActionSchema) Descriptor() ([]byte, []int) { + return file_dependencies_proto_rawDescGZIP(), []int{13} +} + +func (x *ActionSchema) GetSchema() *Schema { + if x != nil { + return x.Schema + } + return nil +} + // Schema describes a schema for an instance of a particular object, such as // a resource type or a provider's overall configuration. type Schema struct { @@ -744,7 +798,7 @@ type Schema struct { func (x *Schema) Reset() { *x = Schema{} - mi := &file_dependencies_proto_msgTypes[13] + mi := &file_dependencies_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -756,7 +810,7 @@ func (x *Schema) String() string { func (*Schema) ProtoMessage() {} func (x *Schema) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[13] + mi := &file_dependencies_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -769,7 +823,7 @@ func (x *Schema) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema.ProtoReflect.Descriptor instead. func (*Schema) Descriptor() ([]byte, []int) { - return file_dependencies_proto_rawDescGZIP(), []int{13} + return file_dependencies_proto_rawDescGZIP(), []int{14} } func (x *Schema) GetBlock() *Schema_Block { @@ -788,7 +842,7 @@ type OpenSourceBundle_Request struct { func (x *OpenSourceBundle_Request) Reset() { *x = OpenSourceBundle_Request{} - mi := &file_dependencies_proto_msgTypes[14] + mi := &file_dependencies_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -800,7 +854,7 @@ func (x *OpenSourceBundle_Request) String() string { func (*OpenSourceBundle_Request) ProtoMessage() {} func (x *OpenSourceBundle_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[14] + mi := &file_dependencies_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -832,7 +886,7 @@ type OpenSourceBundle_Response struct { func (x *OpenSourceBundle_Response) Reset() { *x = OpenSourceBundle_Response{} - mi := &file_dependencies_proto_msgTypes[15] + mi := &file_dependencies_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -844,7 +898,7 @@ func (x *OpenSourceBundle_Response) String() string { func (*OpenSourceBundle_Response) ProtoMessage() {} func (x *OpenSourceBundle_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[15] + mi := &file_dependencies_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -876,7 +930,7 @@ type CloseSourceBundle_Request struct { func (x *CloseSourceBundle_Request) Reset() { *x = CloseSourceBundle_Request{} - mi := &file_dependencies_proto_msgTypes[16] + mi := &file_dependencies_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -888,7 +942,7 @@ func (x *CloseSourceBundle_Request) String() string { func (*CloseSourceBundle_Request) ProtoMessage() {} func (x *CloseSourceBundle_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[16] + mi := &file_dependencies_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -919,7 +973,7 @@ type CloseSourceBundle_Response struct { func (x *CloseSourceBundle_Response) Reset() { *x = CloseSourceBundle_Response{} - mi := &file_dependencies_proto_msgTypes[17] + mi := &file_dependencies_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -931,7 +985,7 @@ func (x *CloseSourceBundle_Response) String() string { func (*CloseSourceBundle_Response) ProtoMessage() {} func (x *CloseSourceBundle_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[17] + mi := &file_dependencies_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -957,7 +1011,7 @@ type OpenDependencyLockFile_Request struct { func (x *OpenDependencyLockFile_Request) Reset() { *x = OpenDependencyLockFile_Request{} - mi := &file_dependencies_proto_msgTypes[18] + mi := &file_dependencies_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -969,7 +1023,7 @@ func (x *OpenDependencyLockFile_Request) String() string { func (*OpenDependencyLockFile_Request) ProtoMessage() {} func (x *OpenDependencyLockFile_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[18] + mi := &file_dependencies_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1009,7 +1063,7 @@ type OpenDependencyLockFile_Response struct { func (x *OpenDependencyLockFile_Response) Reset() { *x = OpenDependencyLockFile_Response{} - mi := &file_dependencies_proto_msgTypes[19] + mi := &file_dependencies_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1021,7 +1075,7 @@ func (x *OpenDependencyLockFile_Response) String() string { func (*OpenDependencyLockFile_Response) ProtoMessage() {} func (x *OpenDependencyLockFile_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[19] + mi := &file_dependencies_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1066,7 +1120,7 @@ type CreateDependencyLocks_Request struct { func (x *CreateDependencyLocks_Request) Reset() { *x = CreateDependencyLocks_Request{} - mi := &file_dependencies_proto_msgTypes[20] + mi := &file_dependencies_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1078,7 +1132,7 @@ func (x *CreateDependencyLocks_Request) String() string { func (*CreateDependencyLocks_Request) ProtoMessage() {} func (x *CreateDependencyLocks_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[20] + mi := &file_dependencies_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1110,7 +1164,7 @@ type CreateDependencyLocks_Response struct { func (x *CreateDependencyLocks_Response) Reset() { *x = CreateDependencyLocks_Response{} - mi := &file_dependencies_proto_msgTypes[21] + mi := &file_dependencies_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1122,7 +1176,7 @@ func (x *CreateDependencyLocks_Response) String() string { func (*CreateDependencyLocks_Response) ProtoMessage() {} func (x *CreateDependencyLocks_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[21] + mi := &file_dependencies_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1154,7 +1208,7 @@ type CloseDependencyLocks_Request struct { func (x *CloseDependencyLocks_Request) Reset() { *x = CloseDependencyLocks_Request{} - mi := &file_dependencies_proto_msgTypes[22] + mi := &file_dependencies_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1166,7 +1220,7 @@ func (x *CloseDependencyLocks_Request) String() string { func (*CloseDependencyLocks_Request) ProtoMessage() {} func (x *CloseDependencyLocks_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[22] + mi := &file_dependencies_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1197,7 +1251,7 @@ type CloseDependencyLocks_Response struct { func (x *CloseDependencyLocks_Response) Reset() { *x = CloseDependencyLocks_Response{} - mi := &file_dependencies_proto_msgTypes[23] + mi := &file_dependencies_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1209,7 +1263,7 @@ func (x *CloseDependencyLocks_Response) String() string { func (*CloseDependencyLocks_Response) ProtoMessage() {} func (x *CloseDependencyLocks_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[23] + mi := &file_dependencies_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1234,7 +1288,7 @@ type GetLockedProviderDependencies_Request struct { func (x *GetLockedProviderDependencies_Request) Reset() { *x = GetLockedProviderDependencies_Request{} - mi := &file_dependencies_proto_msgTypes[24] + mi := &file_dependencies_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1246,7 +1300,7 @@ func (x *GetLockedProviderDependencies_Request) String() string { func (*GetLockedProviderDependencies_Request) ProtoMessage() {} func (x *GetLockedProviderDependencies_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[24] + mi := &file_dependencies_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1278,7 +1332,7 @@ type GetLockedProviderDependencies_Response struct { func (x *GetLockedProviderDependencies_Response) Reset() { *x = GetLockedProviderDependencies_Response{} - mi := &file_dependencies_proto_msgTypes[25] + mi := &file_dependencies_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1290,7 +1344,7 @@ func (x *GetLockedProviderDependencies_Response) String() string { func (*GetLockedProviderDependencies_Response) ProtoMessage() {} func (x *GetLockedProviderDependencies_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[25] + mi := &file_dependencies_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1333,7 +1387,7 @@ type BuildProviderPluginCache_Request struct { func (x *BuildProviderPluginCache_Request) Reset() { *x = BuildProviderPluginCache_Request{} - mi := &file_dependencies_proto_msgTypes[26] + mi := &file_dependencies_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1345,7 +1399,7 @@ func (x *BuildProviderPluginCache_Request) String() string { func (*BuildProviderPluginCache_Request) ProtoMessage() {} func (x *BuildProviderPluginCache_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[26] + mi := &file_dependencies_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1409,7 +1463,7 @@ type BuildProviderPluginCache_Event struct { func (x *BuildProviderPluginCache_Event) Reset() { *x = BuildProviderPluginCache_Event{} - mi := &file_dependencies_proto_msgTypes[27] + mi := &file_dependencies_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1421,7 +1475,7 @@ func (x *BuildProviderPluginCache_Event) String() string { func (*BuildProviderPluginCache_Event) ProtoMessage() {} func (x *BuildProviderPluginCache_Event) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[27] + mi := &file_dependencies_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1599,7 +1653,7 @@ type BuildProviderPluginCache_Request_InstallMethod struct { func (x *BuildProviderPluginCache_Request_InstallMethod) Reset() { *x = BuildProviderPluginCache_Request_InstallMethod{} - mi := &file_dependencies_proto_msgTypes[28] + mi := &file_dependencies_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1611,7 +1665,7 @@ func (x *BuildProviderPluginCache_Request_InstallMethod) String() string { func (*BuildProviderPluginCache_Request_InstallMethod) ProtoMessage() {} func (x *BuildProviderPluginCache_Request_InstallMethod) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[28] + mi := &file_dependencies_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1709,7 +1763,7 @@ type BuildProviderPluginCache_Event_Pending struct { func (x *BuildProviderPluginCache_Event_Pending) Reset() { *x = BuildProviderPluginCache_Event_Pending{} - mi := &file_dependencies_proto_msgTypes[29] + mi := &file_dependencies_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1721,7 +1775,7 @@ func (x *BuildProviderPluginCache_Event_Pending) String() string { func (*BuildProviderPluginCache_Event_Pending) ProtoMessage() {} func (x *BuildProviderPluginCache_Event_Pending) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[29] + mi := &file_dependencies_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1754,7 +1808,7 @@ type BuildProviderPluginCache_Event_ProviderConstraints struct { func (x *BuildProviderPluginCache_Event_ProviderConstraints) Reset() { *x = BuildProviderPluginCache_Event_ProviderConstraints{} - mi := &file_dependencies_proto_msgTypes[30] + mi := &file_dependencies_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1766,7 +1820,7 @@ func (x *BuildProviderPluginCache_Event_ProviderConstraints) String() string { func (*BuildProviderPluginCache_Event_ProviderConstraints) ProtoMessage() {} func (x *BuildProviderPluginCache_Event_ProviderConstraints) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[30] + mi := &file_dependencies_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1806,7 +1860,7 @@ type BuildProviderPluginCache_Event_ProviderVersion struct { func (x *BuildProviderPluginCache_Event_ProviderVersion) Reset() { *x = BuildProviderPluginCache_Event_ProviderVersion{} - mi := &file_dependencies_proto_msgTypes[31] + mi := &file_dependencies_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1818,7 +1872,7 @@ func (x *BuildProviderPluginCache_Event_ProviderVersion) String() string { func (*BuildProviderPluginCache_Event_ProviderVersion) ProtoMessage() {} func (x *BuildProviderPluginCache_Event_ProviderVersion) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[31] + mi := &file_dependencies_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1858,7 +1912,7 @@ type BuildProviderPluginCache_Event_ProviderWarnings struct { func (x *BuildProviderPluginCache_Event_ProviderWarnings) Reset() { *x = BuildProviderPluginCache_Event_ProviderWarnings{} - mi := &file_dependencies_proto_msgTypes[32] + mi := &file_dependencies_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1870,7 +1924,7 @@ func (x *BuildProviderPluginCache_Event_ProviderWarnings) String() string { func (*BuildProviderPluginCache_Event_ProviderWarnings) ProtoMessage() {} func (x *BuildProviderPluginCache_Event_ProviderWarnings) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[32] + mi := &file_dependencies_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1910,7 +1964,7 @@ type BuildProviderPluginCache_Event_FetchBegin struct { func (x *BuildProviderPluginCache_Event_FetchBegin) Reset() { *x = BuildProviderPluginCache_Event_FetchBegin{} - mi := &file_dependencies_proto_msgTypes[33] + mi := &file_dependencies_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1922,7 +1976,7 @@ func (x *BuildProviderPluginCache_Event_FetchBegin) String() string { func (*BuildProviderPluginCache_Event_FetchBegin) ProtoMessage() {} func (x *BuildProviderPluginCache_Event_FetchBegin) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[33] + mi := &file_dependencies_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1968,7 +2022,7 @@ type BuildProviderPluginCache_Event_FetchComplete struct { func (x *BuildProviderPluginCache_Event_FetchComplete) Reset() { *x = BuildProviderPluginCache_Event_FetchComplete{} - mi := &file_dependencies_proto_msgTypes[34] + mi := &file_dependencies_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1980,7 +2034,7 @@ func (x *BuildProviderPluginCache_Event_FetchComplete) String() string { func (*BuildProviderPluginCache_Event_FetchComplete) ProtoMessage() {} func (x *BuildProviderPluginCache_Event_FetchComplete) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[34] + mi := &file_dependencies_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2035,7 +2089,7 @@ type OpenProviderPluginCache_Request struct { func (x *OpenProviderPluginCache_Request) Reset() { *x = OpenProviderPluginCache_Request{} - mi := &file_dependencies_proto_msgTypes[35] + mi := &file_dependencies_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2047,7 +2101,7 @@ func (x *OpenProviderPluginCache_Request) String() string { func (*OpenProviderPluginCache_Request) ProtoMessage() {} func (x *OpenProviderPluginCache_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[35] + mi := &file_dependencies_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2086,7 +2140,7 @@ type OpenProviderPluginCache_Response struct { func (x *OpenProviderPluginCache_Response) Reset() { *x = OpenProviderPluginCache_Response{} - mi := &file_dependencies_proto_msgTypes[36] + mi := &file_dependencies_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2098,7 +2152,7 @@ func (x *OpenProviderPluginCache_Response) String() string { func (*OpenProviderPluginCache_Response) ProtoMessage() {} func (x *OpenProviderPluginCache_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[36] + mi := &file_dependencies_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2130,7 +2184,7 @@ type CloseProviderPluginCache_Request struct { func (x *CloseProviderPluginCache_Request) Reset() { *x = CloseProviderPluginCache_Request{} - mi := &file_dependencies_proto_msgTypes[37] + mi := &file_dependencies_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2142,7 +2196,7 @@ func (x *CloseProviderPluginCache_Request) String() string { func (*CloseProviderPluginCache_Request) ProtoMessage() {} func (x *CloseProviderPluginCache_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[37] + mi := &file_dependencies_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2173,7 +2227,7 @@ type CloseProviderPluginCache_Response struct { func (x *CloseProviderPluginCache_Response) Reset() { *x = CloseProviderPluginCache_Response{} - mi := &file_dependencies_proto_msgTypes[38] + mi := &file_dependencies_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2185,7 +2239,7 @@ func (x *CloseProviderPluginCache_Response) String() string { func (*CloseProviderPluginCache_Response) ProtoMessage() {} func (x *CloseProviderPluginCache_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[38] + mi := &file_dependencies_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2210,7 +2264,7 @@ type GetCachedProviders_Request struct { func (x *GetCachedProviders_Request) Reset() { *x = GetCachedProviders_Request{} - mi := &file_dependencies_proto_msgTypes[39] + mi := &file_dependencies_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2222,7 +2276,7 @@ func (x *GetCachedProviders_Request) String() string { func (*GetCachedProviders_Request) ProtoMessage() {} func (x *GetCachedProviders_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[39] + mi := &file_dependencies_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2254,7 +2308,7 @@ type GetCachedProviders_Response struct { func (x *GetCachedProviders_Response) Reset() { *x = GetCachedProviders_Response{} - mi := &file_dependencies_proto_msgTypes[40] + mi := &file_dependencies_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2266,7 +2320,7 @@ func (x *GetCachedProviders_Response) String() string { func (*GetCachedProviders_Response) ProtoMessage() {} func (x *GetCachedProviders_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[40] + mi := &file_dependencies_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2297,7 +2351,7 @@ type GetBuiltInProviders_Request struct { func (x *GetBuiltInProviders_Request) Reset() { *x = GetBuiltInProviders_Request{} - mi := &file_dependencies_proto_msgTypes[41] + mi := &file_dependencies_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2309,7 +2363,7 @@ func (x *GetBuiltInProviders_Request) String() string { func (*GetBuiltInProviders_Request) ProtoMessage() {} func (x *GetBuiltInProviders_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[41] + mi := &file_dependencies_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2341,7 +2395,7 @@ type GetBuiltInProviders_Response struct { func (x *GetBuiltInProviders_Response) Reset() { *x = GetBuiltInProviders_Response{} - mi := &file_dependencies_proto_msgTypes[42] + mi := &file_dependencies_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2353,7 +2407,7 @@ func (x *GetBuiltInProviders_Response) String() string { func (*GetBuiltInProviders_Response) ProtoMessage() {} func (x *GetBuiltInProviders_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[42] + mi := &file_dependencies_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2408,7 +2462,7 @@ type GetProviderSchema_Request struct { func (x *GetProviderSchema_Request) Reset() { *x = GetProviderSchema_Request{} - mi := &file_dependencies_proto_msgTypes[43] + mi := &file_dependencies_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2420,7 +2474,7 @@ func (x *GetProviderSchema_Request) String() string { func (*GetProviderSchema_Request) ProtoMessage() {} func (x *GetProviderSchema_Request) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[43] + mi := &file_dependencies_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2466,7 +2520,7 @@ type GetProviderSchema_Response struct { func (x *GetProviderSchema_Response) Reset() { *x = GetProviderSchema_Response{} - mi := &file_dependencies_proto_msgTypes[44] + mi := &file_dependencies_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2478,7 +2532,7 @@ func (x *GetProviderSchema_Response) String() string { func (*GetProviderSchema_Response) ProtoMessage() {} func (x *GetProviderSchema_Response) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[44] + mi := &file_dependencies_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2513,7 +2567,7 @@ type Schema_Block struct { func (x *Schema_Block) Reset() { *x = Schema_Block{} - mi := &file_dependencies_proto_msgTypes[47] + mi := &file_dependencies_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2525,7 +2579,7 @@ func (x *Schema_Block) String() string { func (*Schema_Block) ProtoMessage() {} func (x *Schema_Block) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[47] + mi := &file_dependencies_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2538,7 +2592,7 @@ func (x *Schema_Block) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema_Block.ProtoReflect.Descriptor instead. func (*Schema_Block) Descriptor() ([]byte, []int) { - return file_dependencies_proto_rawDescGZIP(), []int{13, 0} + return file_dependencies_proto_rawDescGZIP(), []int{14, 0} } func (x *Schema_Block) GetAttributes() []*Schema_Attribute { @@ -2586,7 +2640,7 @@ type Schema_Attribute struct { func (x *Schema_Attribute) Reset() { *x = Schema_Attribute{} - mi := &file_dependencies_proto_msgTypes[48] + mi := &file_dependencies_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2598,7 +2652,7 @@ func (x *Schema_Attribute) String() string { func (*Schema_Attribute) ProtoMessage() {} func (x *Schema_Attribute) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[48] + mi := &file_dependencies_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2611,7 +2665,7 @@ func (x *Schema_Attribute) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema_Attribute.ProtoReflect.Descriptor instead. func (*Schema_Attribute) Descriptor() ([]byte, []int) { - return file_dependencies_proto_rawDescGZIP(), []int{13, 1} + return file_dependencies_proto_rawDescGZIP(), []int{14, 1} } func (x *Schema_Attribute) GetName() string { @@ -2688,7 +2742,7 @@ type Schema_NestedBlock struct { func (x *Schema_NestedBlock) Reset() { *x = Schema_NestedBlock{} - mi := &file_dependencies_proto_msgTypes[49] + mi := &file_dependencies_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2700,7 +2754,7 @@ func (x *Schema_NestedBlock) String() string { func (*Schema_NestedBlock) ProtoMessage() {} func (x *Schema_NestedBlock) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[49] + mi := &file_dependencies_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2713,7 +2767,7 @@ func (x *Schema_NestedBlock) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema_NestedBlock.ProtoReflect.Descriptor instead. func (*Schema_NestedBlock) Descriptor() ([]byte, []int) { - return file_dependencies_proto_rawDescGZIP(), []int{13, 2} + return file_dependencies_proto_rawDescGZIP(), []int{14, 2} } func (x *Schema_NestedBlock) GetTypeName() string { @@ -2747,7 +2801,7 @@ type Schema_Object struct { func (x *Schema_Object) Reset() { *x = Schema_Object{} - mi := &file_dependencies_proto_msgTypes[50] + mi := &file_dependencies_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2759,7 +2813,7 @@ func (x *Schema_Object) String() string { func (*Schema_Object) ProtoMessage() {} func (x *Schema_Object) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[50] + mi := &file_dependencies_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2772,7 +2826,7 @@ func (x *Schema_Object) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema_Object.ProtoReflect.Descriptor instead. func (*Schema_Object) Descriptor() ([]byte, []int) { - return file_dependencies_proto_rawDescGZIP(), []int{13, 3} + return file_dependencies_proto_rawDescGZIP(), []int{14, 3} } func (x *Schema_Object) GetAttributes() []*Schema_Attribute { @@ -2799,7 +2853,7 @@ type Schema_DocString struct { func (x *Schema_DocString) Reset() { *x = Schema_DocString{} - mi := &file_dependencies_proto_msgTypes[51] + mi := &file_dependencies_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2811,7 +2865,7 @@ func (x *Schema_DocString) String() string { func (*Schema_DocString) ProtoMessage() {} func (x *Schema_DocString) ProtoReflect() protoreflect.Message { - mi := &file_dependencies_proto_msgTypes[51] + mi := &file_dependencies_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2824,7 +2878,7 @@ func (x *Schema_DocString) ProtoReflect() protoreflect.Message { // Deprecated: Use Schema_DocString.ProtoReflect.Descriptor instead. func (*Schema_DocString) Descriptor() ([]byte, []int) { - return file_dependencies_proto_rawDescGZIP(), []int{13, 4} + return file_dependencies_proto_rawDescGZIP(), []int{14, 4} } func (x *Schema_DocString) GetDescription() string { @@ -2963,17 +3017,23 @@ const file_dependencies_proto_rawDesc = "" + "\x10provider_version\x18\x02 \x01(\tR\x0fproviderVersion\x122\n" + "\x15provider_cache_handle\x18\x03 \x01(\x03R\x13providerCacheHandle\x1aK\n" + "\bResponse\x12?\n" + - "\x06schema\x18\x01 \x01(\v2'.terraform1.dependencies.ProviderSchemaR\x06schema\"\x94\x04\n" + + "\x06schema\x18\x01 \x01(\v2'.terraform1.dependencies.ProviderSchemaR\x06schema\"\xd8\x05\n" + "\x0eProviderSchema\x12H\n" + "\x0fprovider_config\x18\x01 \x01(\v2\x1f.terraform1.dependencies.SchemaR\x0eproviderConfig\x12w\n" + "\x16managed_resource_types\x18\x02 \x03(\v2A.terraform1.dependencies.ProviderSchema.ManagedResourceTypesEntryR\x14managedResourceTypes\x12n\n" + - "\x13data_resource_types\x18\x03 \x03(\v2>.terraform1.dependencies.ProviderSchema.DataResourceTypesEntryR\x11dataResourceTypes\x1ah\n" + + "\x13data_resource_types\x18\x03 \x03(\v2>.terraform1.dependencies.ProviderSchema.DataResourceTypesEntryR\x11dataResourceTypes\x12[\n" + + "\faction_types\x18\x04 \x03(\v28.terraform1.dependencies.ProviderSchema.ActionTypesEntryR\vactionTypes\x1ah\n" + "\x19ManagedResourceTypesEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x125\n" + "\x05value\x18\x02 \x01(\v2\x1f.terraform1.dependencies.SchemaR\x05value:\x028\x01\x1ae\n" + "\x16DataResourceTypesEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x125\n" + - "\x05value\x18\x02 \x01(\v2\x1f.terraform1.dependencies.SchemaR\x05value:\x028\x01\"\xc4\n" + + "\x05value\x18\x02 \x01(\v2\x1f.terraform1.dependencies.SchemaR\x05value:\x028\x01\x1ae\n" + + "\x10ActionTypesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12;\n" + + "\x05value\x18\x02 \x01(\v2%.terraform1.dependencies.ActionSchemaR\x05value:\x028\x01\"G\n" + + "\fActionSchema\x127\n" + + "\x06schema\x18\x01 \x01(\v2\x1f.terraform1.dependencies.SchemaR\x06schema\"\xc4\n" + "\n" + "\x06Schema\x12;\n" + "\x05block\x18\x01 \x01(\v2%.terraform1.dependencies.Schema.BlockR\x05block\x1a\x8d\x02\n" + @@ -3058,7 +3118,7 @@ func file_dependencies_proto_rawDescGZIP() []byte { } var file_dependencies_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_dependencies_proto_msgTypes = make([]protoimpl.MessageInfo, 52) +var file_dependencies_proto_msgTypes = make([]protoimpl.MessageInfo, 54) var file_dependencies_proto_goTypes = []any{ (BuildProviderPluginCache_Event_FetchComplete_AuthResult)(0), // 0: terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete.AuthResult (Schema_NestedBlock_NestingMode)(0), // 1: terraform1.dependencies.Schema.NestedBlock.NestingMode @@ -3077,116 +3137,121 @@ var file_dependencies_proto_goTypes = []any{ (*GetBuiltInProviders)(nil), // 14: terraform1.dependencies.GetBuiltInProviders (*GetProviderSchema)(nil), // 15: terraform1.dependencies.GetProviderSchema (*ProviderSchema)(nil), // 16: terraform1.dependencies.ProviderSchema - (*Schema)(nil), // 17: terraform1.dependencies.Schema - (*OpenSourceBundle_Request)(nil), // 18: terraform1.dependencies.OpenSourceBundle.Request - (*OpenSourceBundle_Response)(nil), // 19: terraform1.dependencies.OpenSourceBundle.Response - (*CloseSourceBundle_Request)(nil), // 20: terraform1.dependencies.CloseSourceBundle.Request - (*CloseSourceBundle_Response)(nil), // 21: terraform1.dependencies.CloseSourceBundle.Response - (*OpenDependencyLockFile_Request)(nil), // 22: terraform1.dependencies.OpenDependencyLockFile.Request - (*OpenDependencyLockFile_Response)(nil), // 23: terraform1.dependencies.OpenDependencyLockFile.Response - (*CreateDependencyLocks_Request)(nil), // 24: terraform1.dependencies.CreateDependencyLocks.Request - (*CreateDependencyLocks_Response)(nil), // 25: terraform1.dependencies.CreateDependencyLocks.Response - (*CloseDependencyLocks_Request)(nil), // 26: terraform1.dependencies.CloseDependencyLocks.Request - (*CloseDependencyLocks_Response)(nil), // 27: terraform1.dependencies.CloseDependencyLocks.Response - (*GetLockedProviderDependencies_Request)(nil), // 28: terraform1.dependencies.GetLockedProviderDependencies.Request - (*GetLockedProviderDependencies_Response)(nil), // 29: terraform1.dependencies.GetLockedProviderDependencies.Response - (*BuildProviderPluginCache_Request)(nil), // 30: terraform1.dependencies.BuildProviderPluginCache.Request - (*BuildProviderPluginCache_Event)(nil), // 31: terraform1.dependencies.BuildProviderPluginCache.Event - (*BuildProviderPluginCache_Request_InstallMethod)(nil), // 32: terraform1.dependencies.BuildProviderPluginCache.Request.InstallMethod - (*BuildProviderPluginCache_Event_Pending)(nil), // 33: terraform1.dependencies.BuildProviderPluginCache.Event.Pending - (*BuildProviderPluginCache_Event_ProviderConstraints)(nil), // 34: terraform1.dependencies.BuildProviderPluginCache.Event.ProviderConstraints - (*BuildProviderPluginCache_Event_ProviderVersion)(nil), // 35: terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion - (*BuildProviderPluginCache_Event_ProviderWarnings)(nil), // 36: terraform1.dependencies.BuildProviderPluginCache.Event.ProviderWarnings - (*BuildProviderPluginCache_Event_FetchBegin)(nil), // 37: terraform1.dependencies.BuildProviderPluginCache.Event.FetchBegin - (*BuildProviderPluginCache_Event_FetchComplete)(nil), // 38: terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete - (*OpenProviderPluginCache_Request)(nil), // 39: terraform1.dependencies.OpenProviderPluginCache.Request - (*OpenProviderPluginCache_Response)(nil), // 40: terraform1.dependencies.OpenProviderPluginCache.Response - (*CloseProviderPluginCache_Request)(nil), // 41: terraform1.dependencies.CloseProviderPluginCache.Request - (*CloseProviderPluginCache_Response)(nil), // 42: terraform1.dependencies.CloseProviderPluginCache.Response - (*GetCachedProviders_Request)(nil), // 43: terraform1.dependencies.GetCachedProviders.Request - (*GetCachedProviders_Response)(nil), // 44: terraform1.dependencies.GetCachedProviders.Response - (*GetBuiltInProviders_Request)(nil), // 45: terraform1.dependencies.GetBuiltInProviders.Request - (*GetBuiltInProviders_Response)(nil), // 46: terraform1.dependencies.GetBuiltInProviders.Response - (*GetProviderSchema_Request)(nil), // 47: terraform1.dependencies.GetProviderSchema.Request - (*GetProviderSchema_Response)(nil), // 48: terraform1.dependencies.GetProviderSchema.Response - nil, // 49: terraform1.dependencies.ProviderSchema.ManagedResourceTypesEntry - nil, // 50: terraform1.dependencies.ProviderSchema.DataResourceTypesEntry - (*Schema_Block)(nil), // 51: terraform1.dependencies.Schema.Block - (*Schema_Attribute)(nil), // 52: terraform1.dependencies.Schema.Attribute - (*Schema_NestedBlock)(nil), // 53: terraform1.dependencies.Schema.NestedBlock - (*Schema_Object)(nil), // 54: terraform1.dependencies.Schema.Object - (*Schema_DocString)(nil), // 55: terraform1.dependencies.Schema.DocString - (*terraform1.SourceAddress)(nil), // 56: terraform1.SourceAddress - (*terraform1.Diagnostic)(nil), // 57: terraform1.Diagnostic - (*terraform1.ProviderPackage)(nil), // 58: terraform1.ProviderPackage + (*ActionSchema)(nil), // 17: terraform1.dependencies.ActionSchema + (*Schema)(nil), // 18: terraform1.dependencies.Schema + (*OpenSourceBundle_Request)(nil), // 19: terraform1.dependencies.OpenSourceBundle.Request + (*OpenSourceBundle_Response)(nil), // 20: terraform1.dependencies.OpenSourceBundle.Response + (*CloseSourceBundle_Request)(nil), // 21: terraform1.dependencies.CloseSourceBundle.Request + (*CloseSourceBundle_Response)(nil), // 22: terraform1.dependencies.CloseSourceBundle.Response + (*OpenDependencyLockFile_Request)(nil), // 23: terraform1.dependencies.OpenDependencyLockFile.Request + (*OpenDependencyLockFile_Response)(nil), // 24: terraform1.dependencies.OpenDependencyLockFile.Response + (*CreateDependencyLocks_Request)(nil), // 25: terraform1.dependencies.CreateDependencyLocks.Request + (*CreateDependencyLocks_Response)(nil), // 26: terraform1.dependencies.CreateDependencyLocks.Response + (*CloseDependencyLocks_Request)(nil), // 27: terraform1.dependencies.CloseDependencyLocks.Request + (*CloseDependencyLocks_Response)(nil), // 28: terraform1.dependencies.CloseDependencyLocks.Response + (*GetLockedProviderDependencies_Request)(nil), // 29: terraform1.dependencies.GetLockedProviderDependencies.Request + (*GetLockedProviderDependencies_Response)(nil), // 30: terraform1.dependencies.GetLockedProviderDependencies.Response + (*BuildProviderPluginCache_Request)(nil), // 31: terraform1.dependencies.BuildProviderPluginCache.Request + (*BuildProviderPluginCache_Event)(nil), // 32: terraform1.dependencies.BuildProviderPluginCache.Event + (*BuildProviderPluginCache_Request_InstallMethod)(nil), // 33: terraform1.dependencies.BuildProviderPluginCache.Request.InstallMethod + (*BuildProviderPluginCache_Event_Pending)(nil), // 34: terraform1.dependencies.BuildProviderPluginCache.Event.Pending + (*BuildProviderPluginCache_Event_ProviderConstraints)(nil), // 35: terraform1.dependencies.BuildProviderPluginCache.Event.ProviderConstraints + (*BuildProviderPluginCache_Event_ProviderVersion)(nil), // 36: terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion + (*BuildProviderPluginCache_Event_ProviderWarnings)(nil), // 37: terraform1.dependencies.BuildProviderPluginCache.Event.ProviderWarnings + (*BuildProviderPluginCache_Event_FetchBegin)(nil), // 38: terraform1.dependencies.BuildProviderPluginCache.Event.FetchBegin + (*BuildProviderPluginCache_Event_FetchComplete)(nil), // 39: terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete + (*OpenProviderPluginCache_Request)(nil), // 40: terraform1.dependencies.OpenProviderPluginCache.Request + (*OpenProviderPluginCache_Response)(nil), // 41: terraform1.dependencies.OpenProviderPluginCache.Response + (*CloseProviderPluginCache_Request)(nil), // 42: terraform1.dependencies.CloseProviderPluginCache.Request + (*CloseProviderPluginCache_Response)(nil), // 43: terraform1.dependencies.CloseProviderPluginCache.Response + (*GetCachedProviders_Request)(nil), // 44: terraform1.dependencies.GetCachedProviders.Request + (*GetCachedProviders_Response)(nil), // 45: terraform1.dependencies.GetCachedProviders.Response + (*GetBuiltInProviders_Request)(nil), // 46: terraform1.dependencies.GetBuiltInProviders.Request + (*GetBuiltInProviders_Response)(nil), // 47: terraform1.dependencies.GetBuiltInProviders.Response + (*GetProviderSchema_Request)(nil), // 48: terraform1.dependencies.GetProviderSchema.Request + (*GetProviderSchema_Response)(nil), // 49: terraform1.dependencies.GetProviderSchema.Response + nil, // 50: terraform1.dependencies.ProviderSchema.ManagedResourceTypesEntry + nil, // 51: terraform1.dependencies.ProviderSchema.DataResourceTypesEntry + nil, // 52: terraform1.dependencies.ProviderSchema.ActionTypesEntry + (*Schema_Block)(nil), // 53: terraform1.dependencies.Schema.Block + (*Schema_Attribute)(nil), // 54: terraform1.dependencies.Schema.Attribute + (*Schema_NestedBlock)(nil), // 55: terraform1.dependencies.Schema.NestedBlock + (*Schema_Object)(nil), // 56: terraform1.dependencies.Schema.Object + (*Schema_DocString)(nil), // 57: terraform1.dependencies.Schema.DocString + (*terraform1.SourceAddress)(nil), // 58: terraform1.SourceAddress + (*terraform1.Diagnostic)(nil), // 59: terraform1.Diagnostic + (*terraform1.ProviderPackage)(nil), // 60: terraform1.ProviderPackage } var file_dependencies_proto_depIdxs = []int32{ - 17, // 0: terraform1.dependencies.ProviderSchema.provider_config:type_name -> terraform1.dependencies.Schema - 49, // 1: terraform1.dependencies.ProviderSchema.managed_resource_types:type_name -> terraform1.dependencies.ProviderSchema.ManagedResourceTypesEntry - 50, // 2: terraform1.dependencies.ProviderSchema.data_resource_types:type_name -> terraform1.dependencies.ProviderSchema.DataResourceTypesEntry - 51, // 3: terraform1.dependencies.Schema.block:type_name -> terraform1.dependencies.Schema.Block - 56, // 4: terraform1.dependencies.OpenDependencyLockFile.Request.source_address:type_name -> terraform1.SourceAddress - 57, // 5: terraform1.dependencies.OpenDependencyLockFile.Response.diagnostics:type_name -> terraform1.Diagnostic - 58, // 6: terraform1.dependencies.CreateDependencyLocks.Request.provider_selections:type_name -> terraform1.ProviderPackage - 58, // 7: terraform1.dependencies.GetLockedProviderDependencies.Response.selected_providers:type_name -> terraform1.ProviderPackage - 32, // 8: terraform1.dependencies.BuildProviderPluginCache.Request.installation_methods:type_name -> terraform1.dependencies.BuildProviderPluginCache.Request.InstallMethod - 33, // 9: terraform1.dependencies.BuildProviderPluginCache.Event.pending:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.Pending - 35, // 10: terraform1.dependencies.BuildProviderPluginCache.Event.already_installed:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion - 35, // 11: terraform1.dependencies.BuildProviderPluginCache.Event.built_in:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion - 34, // 12: terraform1.dependencies.BuildProviderPluginCache.Event.query_begin:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderConstraints - 35, // 13: terraform1.dependencies.BuildProviderPluginCache.Event.query_success:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion - 36, // 14: terraform1.dependencies.BuildProviderPluginCache.Event.query_warnings:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderWarnings - 37, // 15: terraform1.dependencies.BuildProviderPluginCache.Event.fetch_begin:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.FetchBegin - 38, // 16: terraform1.dependencies.BuildProviderPluginCache.Event.fetch_complete:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete - 57, // 17: terraform1.dependencies.BuildProviderPluginCache.Event.diagnostic:type_name -> terraform1.Diagnostic - 34, // 18: terraform1.dependencies.BuildProviderPluginCache.Event.Pending.expected:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderConstraints - 35, // 19: terraform1.dependencies.BuildProviderPluginCache.Event.FetchBegin.provider_version:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion - 35, // 20: terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete.provider_version:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion - 0, // 21: terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete.auth_result:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete.AuthResult - 58, // 22: terraform1.dependencies.GetCachedProviders.Response.available_providers:type_name -> terraform1.ProviderPackage - 58, // 23: terraform1.dependencies.GetBuiltInProviders.Response.available_providers:type_name -> terraform1.ProviderPackage - 16, // 24: terraform1.dependencies.GetProviderSchema.Response.schema:type_name -> terraform1.dependencies.ProviderSchema - 17, // 25: terraform1.dependencies.ProviderSchema.ManagedResourceTypesEntry.value:type_name -> terraform1.dependencies.Schema - 17, // 26: terraform1.dependencies.ProviderSchema.DataResourceTypesEntry.value:type_name -> terraform1.dependencies.Schema - 52, // 27: terraform1.dependencies.Schema.Block.attributes:type_name -> terraform1.dependencies.Schema.Attribute - 53, // 28: terraform1.dependencies.Schema.Block.block_types:type_name -> terraform1.dependencies.Schema.NestedBlock - 55, // 29: terraform1.dependencies.Schema.Block.description:type_name -> terraform1.dependencies.Schema.DocString - 54, // 30: terraform1.dependencies.Schema.Attribute.nested_type:type_name -> terraform1.dependencies.Schema.Object - 55, // 31: terraform1.dependencies.Schema.Attribute.description:type_name -> terraform1.dependencies.Schema.DocString - 51, // 32: terraform1.dependencies.Schema.NestedBlock.block:type_name -> terraform1.dependencies.Schema.Block - 1, // 33: terraform1.dependencies.Schema.NestedBlock.nesting:type_name -> terraform1.dependencies.Schema.NestedBlock.NestingMode - 52, // 34: terraform1.dependencies.Schema.Object.attributes:type_name -> terraform1.dependencies.Schema.Attribute - 2, // 35: terraform1.dependencies.Schema.Object.nesting:type_name -> terraform1.dependencies.Schema.Object.NestingMode - 3, // 36: terraform1.dependencies.Schema.DocString.format:type_name -> terraform1.dependencies.Schema.DocString.Format - 18, // 37: terraform1.dependencies.Dependencies.OpenSourceBundle:input_type -> terraform1.dependencies.OpenSourceBundle.Request - 20, // 38: terraform1.dependencies.Dependencies.CloseSourceBundle:input_type -> terraform1.dependencies.CloseSourceBundle.Request - 22, // 39: terraform1.dependencies.Dependencies.OpenDependencyLockFile:input_type -> terraform1.dependencies.OpenDependencyLockFile.Request - 24, // 40: terraform1.dependencies.Dependencies.CreateDependencyLocks:input_type -> terraform1.dependencies.CreateDependencyLocks.Request - 26, // 41: terraform1.dependencies.Dependencies.CloseDependencyLocks:input_type -> terraform1.dependencies.CloseDependencyLocks.Request - 28, // 42: terraform1.dependencies.Dependencies.GetLockedProviderDependencies:input_type -> terraform1.dependencies.GetLockedProviderDependencies.Request - 30, // 43: terraform1.dependencies.Dependencies.BuildProviderPluginCache:input_type -> terraform1.dependencies.BuildProviderPluginCache.Request - 39, // 44: terraform1.dependencies.Dependencies.OpenProviderPluginCache:input_type -> terraform1.dependencies.OpenProviderPluginCache.Request - 41, // 45: terraform1.dependencies.Dependencies.CloseProviderPluginCache:input_type -> terraform1.dependencies.CloseProviderPluginCache.Request - 43, // 46: terraform1.dependencies.Dependencies.GetCachedProviders:input_type -> terraform1.dependencies.GetCachedProviders.Request - 45, // 47: terraform1.dependencies.Dependencies.GetBuiltInProviders:input_type -> terraform1.dependencies.GetBuiltInProviders.Request - 47, // 48: terraform1.dependencies.Dependencies.GetProviderSchema:input_type -> terraform1.dependencies.GetProviderSchema.Request - 19, // 49: terraform1.dependencies.Dependencies.OpenSourceBundle:output_type -> terraform1.dependencies.OpenSourceBundle.Response - 21, // 50: terraform1.dependencies.Dependencies.CloseSourceBundle:output_type -> terraform1.dependencies.CloseSourceBundle.Response - 23, // 51: terraform1.dependencies.Dependencies.OpenDependencyLockFile:output_type -> terraform1.dependencies.OpenDependencyLockFile.Response - 25, // 52: terraform1.dependencies.Dependencies.CreateDependencyLocks:output_type -> terraform1.dependencies.CreateDependencyLocks.Response - 27, // 53: terraform1.dependencies.Dependencies.CloseDependencyLocks:output_type -> terraform1.dependencies.CloseDependencyLocks.Response - 29, // 54: terraform1.dependencies.Dependencies.GetLockedProviderDependencies:output_type -> terraform1.dependencies.GetLockedProviderDependencies.Response - 31, // 55: terraform1.dependencies.Dependencies.BuildProviderPluginCache:output_type -> terraform1.dependencies.BuildProviderPluginCache.Event - 40, // 56: terraform1.dependencies.Dependencies.OpenProviderPluginCache:output_type -> terraform1.dependencies.OpenProviderPluginCache.Response - 42, // 57: terraform1.dependencies.Dependencies.CloseProviderPluginCache:output_type -> terraform1.dependencies.CloseProviderPluginCache.Response - 44, // 58: terraform1.dependencies.Dependencies.GetCachedProviders:output_type -> terraform1.dependencies.GetCachedProviders.Response - 46, // 59: terraform1.dependencies.Dependencies.GetBuiltInProviders:output_type -> terraform1.dependencies.GetBuiltInProviders.Response - 48, // 60: terraform1.dependencies.Dependencies.GetProviderSchema:output_type -> terraform1.dependencies.GetProviderSchema.Response - 49, // [49:61] is the sub-list for method output_type - 37, // [37:49] is the sub-list for method input_type - 37, // [37:37] is the sub-list for extension type_name - 37, // [37:37] is the sub-list for extension extendee - 0, // [0:37] is the sub-list for field type_name + 18, // 0: terraform1.dependencies.ProviderSchema.provider_config:type_name -> terraform1.dependencies.Schema + 50, // 1: terraform1.dependencies.ProviderSchema.managed_resource_types:type_name -> terraform1.dependencies.ProviderSchema.ManagedResourceTypesEntry + 51, // 2: terraform1.dependencies.ProviderSchema.data_resource_types:type_name -> terraform1.dependencies.ProviderSchema.DataResourceTypesEntry + 52, // 3: terraform1.dependencies.ProviderSchema.action_types:type_name -> terraform1.dependencies.ProviderSchema.ActionTypesEntry + 18, // 4: terraform1.dependencies.ActionSchema.schema:type_name -> terraform1.dependencies.Schema + 53, // 5: terraform1.dependencies.Schema.block:type_name -> terraform1.dependencies.Schema.Block + 58, // 6: terraform1.dependencies.OpenDependencyLockFile.Request.source_address:type_name -> terraform1.SourceAddress + 59, // 7: terraform1.dependencies.OpenDependencyLockFile.Response.diagnostics:type_name -> terraform1.Diagnostic + 60, // 8: terraform1.dependencies.CreateDependencyLocks.Request.provider_selections:type_name -> terraform1.ProviderPackage + 60, // 9: terraform1.dependencies.GetLockedProviderDependencies.Response.selected_providers:type_name -> terraform1.ProviderPackage + 33, // 10: terraform1.dependencies.BuildProviderPluginCache.Request.installation_methods:type_name -> terraform1.dependencies.BuildProviderPluginCache.Request.InstallMethod + 34, // 11: terraform1.dependencies.BuildProviderPluginCache.Event.pending:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.Pending + 36, // 12: terraform1.dependencies.BuildProviderPluginCache.Event.already_installed:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion + 36, // 13: terraform1.dependencies.BuildProviderPluginCache.Event.built_in:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion + 35, // 14: terraform1.dependencies.BuildProviderPluginCache.Event.query_begin:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderConstraints + 36, // 15: terraform1.dependencies.BuildProviderPluginCache.Event.query_success:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion + 37, // 16: terraform1.dependencies.BuildProviderPluginCache.Event.query_warnings:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderWarnings + 38, // 17: terraform1.dependencies.BuildProviderPluginCache.Event.fetch_begin:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.FetchBegin + 39, // 18: terraform1.dependencies.BuildProviderPluginCache.Event.fetch_complete:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete + 59, // 19: terraform1.dependencies.BuildProviderPluginCache.Event.diagnostic:type_name -> terraform1.Diagnostic + 35, // 20: terraform1.dependencies.BuildProviderPluginCache.Event.Pending.expected:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderConstraints + 36, // 21: terraform1.dependencies.BuildProviderPluginCache.Event.FetchBegin.provider_version:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion + 36, // 22: terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete.provider_version:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.ProviderVersion + 0, // 23: terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete.auth_result:type_name -> terraform1.dependencies.BuildProviderPluginCache.Event.FetchComplete.AuthResult + 60, // 24: terraform1.dependencies.GetCachedProviders.Response.available_providers:type_name -> terraform1.ProviderPackage + 60, // 25: terraform1.dependencies.GetBuiltInProviders.Response.available_providers:type_name -> terraform1.ProviderPackage + 16, // 26: terraform1.dependencies.GetProviderSchema.Response.schema:type_name -> terraform1.dependencies.ProviderSchema + 18, // 27: terraform1.dependencies.ProviderSchema.ManagedResourceTypesEntry.value:type_name -> terraform1.dependencies.Schema + 18, // 28: terraform1.dependencies.ProviderSchema.DataResourceTypesEntry.value:type_name -> terraform1.dependencies.Schema + 17, // 29: terraform1.dependencies.ProviderSchema.ActionTypesEntry.value:type_name -> terraform1.dependencies.ActionSchema + 54, // 30: terraform1.dependencies.Schema.Block.attributes:type_name -> terraform1.dependencies.Schema.Attribute + 55, // 31: terraform1.dependencies.Schema.Block.block_types:type_name -> terraform1.dependencies.Schema.NestedBlock + 57, // 32: terraform1.dependencies.Schema.Block.description:type_name -> terraform1.dependencies.Schema.DocString + 56, // 33: terraform1.dependencies.Schema.Attribute.nested_type:type_name -> terraform1.dependencies.Schema.Object + 57, // 34: terraform1.dependencies.Schema.Attribute.description:type_name -> terraform1.dependencies.Schema.DocString + 53, // 35: terraform1.dependencies.Schema.NestedBlock.block:type_name -> terraform1.dependencies.Schema.Block + 1, // 36: terraform1.dependencies.Schema.NestedBlock.nesting:type_name -> terraform1.dependencies.Schema.NestedBlock.NestingMode + 54, // 37: terraform1.dependencies.Schema.Object.attributes:type_name -> terraform1.dependencies.Schema.Attribute + 2, // 38: terraform1.dependencies.Schema.Object.nesting:type_name -> terraform1.dependencies.Schema.Object.NestingMode + 3, // 39: terraform1.dependencies.Schema.DocString.format:type_name -> terraform1.dependencies.Schema.DocString.Format + 19, // 40: terraform1.dependencies.Dependencies.OpenSourceBundle:input_type -> terraform1.dependencies.OpenSourceBundle.Request + 21, // 41: terraform1.dependencies.Dependencies.CloseSourceBundle:input_type -> terraform1.dependencies.CloseSourceBundle.Request + 23, // 42: terraform1.dependencies.Dependencies.OpenDependencyLockFile:input_type -> terraform1.dependencies.OpenDependencyLockFile.Request + 25, // 43: terraform1.dependencies.Dependencies.CreateDependencyLocks:input_type -> terraform1.dependencies.CreateDependencyLocks.Request + 27, // 44: terraform1.dependencies.Dependencies.CloseDependencyLocks:input_type -> terraform1.dependencies.CloseDependencyLocks.Request + 29, // 45: terraform1.dependencies.Dependencies.GetLockedProviderDependencies:input_type -> terraform1.dependencies.GetLockedProviderDependencies.Request + 31, // 46: terraform1.dependencies.Dependencies.BuildProviderPluginCache:input_type -> terraform1.dependencies.BuildProviderPluginCache.Request + 40, // 47: terraform1.dependencies.Dependencies.OpenProviderPluginCache:input_type -> terraform1.dependencies.OpenProviderPluginCache.Request + 42, // 48: terraform1.dependencies.Dependencies.CloseProviderPluginCache:input_type -> terraform1.dependencies.CloseProviderPluginCache.Request + 44, // 49: terraform1.dependencies.Dependencies.GetCachedProviders:input_type -> terraform1.dependencies.GetCachedProviders.Request + 46, // 50: terraform1.dependencies.Dependencies.GetBuiltInProviders:input_type -> terraform1.dependencies.GetBuiltInProviders.Request + 48, // 51: terraform1.dependencies.Dependencies.GetProviderSchema:input_type -> terraform1.dependencies.GetProviderSchema.Request + 20, // 52: terraform1.dependencies.Dependencies.OpenSourceBundle:output_type -> terraform1.dependencies.OpenSourceBundle.Response + 22, // 53: terraform1.dependencies.Dependencies.CloseSourceBundle:output_type -> terraform1.dependencies.CloseSourceBundle.Response + 24, // 54: terraform1.dependencies.Dependencies.OpenDependencyLockFile:output_type -> terraform1.dependencies.OpenDependencyLockFile.Response + 26, // 55: terraform1.dependencies.Dependencies.CreateDependencyLocks:output_type -> terraform1.dependencies.CreateDependencyLocks.Response + 28, // 56: terraform1.dependencies.Dependencies.CloseDependencyLocks:output_type -> terraform1.dependencies.CloseDependencyLocks.Response + 30, // 57: terraform1.dependencies.Dependencies.GetLockedProviderDependencies:output_type -> terraform1.dependencies.GetLockedProviderDependencies.Response + 32, // 58: terraform1.dependencies.Dependencies.BuildProviderPluginCache:output_type -> terraform1.dependencies.BuildProviderPluginCache.Event + 41, // 59: terraform1.dependencies.Dependencies.OpenProviderPluginCache:output_type -> terraform1.dependencies.OpenProviderPluginCache.Response + 43, // 60: terraform1.dependencies.Dependencies.CloseProviderPluginCache:output_type -> terraform1.dependencies.CloseProviderPluginCache.Response + 45, // 61: terraform1.dependencies.Dependencies.GetCachedProviders:output_type -> terraform1.dependencies.GetCachedProviders.Response + 47, // 62: terraform1.dependencies.Dependencies.GetBuiltInProviders:output_type -> terraform1.dependencies.GetBuiltInProviders.Response + 49, // 63: terraform1.dependencies.Dependencies.GetProviderSchema:output_type -> terraform1.dependencies.GetProviderSchema.Response + 52, // [52:64] is the sub-list for method output_type + 40, // [40:52] is the sub-list for method input_type + 40, // [40:40] is the sub-list for extension type_name + 40, // [40:40] is the sub-list for extension extendee + 0, // [0:40] is the sub-list for field type_name } func init() { file_dependencies_proto_init() } @@ -3194,7 +3259,7 @@ func file_dependencies_proto_init() { if File_dependencies_proto != nil { return } - file_dependencies_proto_msgTypes[27].OneofWrappers = []any{ + file_dependencies_proto_msgTypes[28].OneofWrappers = []any{ (*BuildProviderPluginCache_Event_Pending_)(nil), (*BuildProviderPluginCache_Event_AlreadyInstalled)(nil), (*BuildProviderPluginCache_Event_BuiltIn)(nil), @@ -3205,7 +3270,7 @@ func file_dependencies_proto_init() { (*BuildProviderPluginCache_Event_FetchComplete_)(nil), (*BuildProviderPluginCache_Event_Diagnostic)(nil), } - file_dependencies_proto_msgTypes[28].OneofWrappers = []any{ + file_dependencies_proto_msgTypes[29].OneofWrappers = []any{ (*BuildProviderPluginCache_Request_InstallMethod_Direct)(nil), (*BuildProviderPluginCache_Request_InstallMethod_LocalMirrorDir)(nil), (*BuildProviderPluginCache_Request_InstallMethod_NetworkMirrorUrl)(nil), @@ -3216,7 +3281,7 @@ func file_dependencies_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_dependencies_proto_rawDesc), len(file_dependencies_proto_rawDesc)), NumEnums: 4, - NumMessages: 52, + NumMessages: 54, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/rpcapi/terraform1/dependencies/dependencies.proto b/internal/rpcapi/terraform1/dependencies/dependencies.proto index 5190b07d89..484bf944af 100644 --- a/internal/rpcapi/terraform1/dependencies/dependencies.proto +++ b/internal/rpcapi/terraform1/dependencies/dependencies.proto @@ -312,6 +312,13 @@ message ProviderSchema { Schema provider_config = 1; map managed_resource_types = 2; map data_resource_types = 3; + map action_types = 4; +} + +// ActionSchema defines the schema for an action that can be invoked by +// Terraform. +message ActionSchema { + Schema schema = 1; // of the action itself } // Schema describes a schema for an instance of a particular object, such as diff --git a/internal/rpcapi/terraform1/stacks/conversion.go b/internal/rpcapi/terraform1/stacks/conversion.go index d7c6be22bf..9a3728fc57 100644 --- a/internal/rpcapi/terraform1/stacks/conversion.go +++ b/internal/rpcapi/terraform1/stacks/conversion.go @@ -177,3 +177,10 @@ func NewResourceInstanceObjectInStackAddr(addr stackaddrs.AbsResourceInstanceObj DeposedKey: addr.Item.DeposedKey.String(), } } + +func NewActionInvocationInStackAddr(addr stackaddrs.AbsActionInvocationInstance) *ActionInvocationInstanceInStackAddr { + return &ActionInvocationInstanceInStackAddr{ + ComponentInstanceAddr: addr.Component.String(), + ActionInvocationInstanceAddr: addr.Item.String(), + } +} diff --git a/internal/rpcapi/terraform1/stacks/conversion_test.go b/internal/rpcapi/terraform1/stacks/conversion_test.go new file mode 100644 index 0000000000..667f036795 --- /dev/null +++ b/internal/rpcapi/terraform1/stacks/conversion_test.go @@ -0,0 +1,165 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package stacks + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "google.golang.org/protobuf/testing/protocmp" + + "github.com/hashicorp/terraform/internal/addrs" + "github.com/hashicorp/terraform/internal/stacks/stackaddrs" +) + +func TestNewActionInvocationInStackAddr(t *testing.T) { + tests := []struct { + name string + addr stackaddrs.AbsActionInvocationInstance + want *ActionInvocationInstanceInStackAddr + }{ + { + name: "simple action in root component", + addr: stackaddrs.AbsActionInvocationInstance{ + Component: stackaddrs.AbsComponentInstance{ + Stack: stackaddrs.RootStackInstance, + Item: stackaddrs.ComponentInstance{ + Component: stackaddrs.Component{Name: "foo"}, + }, + }, + Item: addrs.AbsActionInstance{ + Module: addrs.RootModuleInstance, + Action: addrs.ActionInstance{ + Action: addrs.Action{ + Type: "example", + Name: "test", + }, + Key: addrs.NoKey, + }, + }, + }, + want: &ActionInvocationInstanceInStackAddr{ + ComponentInstanceAddr: "component.foo", + ActionInvocationInstanceAddr: "action.example.test", + }, + }, + { + name: "action with count index", + addr: stackaddrs.AbsActionInvocationInstance{ + Component: stackaddrs.AbsComponentInstance{ + Stack: stackaddrs.RootStackInstance, + Item: stackaddrs.ComponentInstance{ + Component: stackaddrs.Component{Name: "bar"}, + }, + }, + Item: addrs.AbsActionInstance{ + Module: addrs.RootModuleInstance, + Action: addrs.ActionInstance{ + Action: addrs.Action{ + Type: "webhook", + Name: "notify", + }, + Key: addrs.IntKey(2), + }, + }, + }, + want: &ActionInvocationInstanceInStackAddr{ + ComponentInstanceAddr: "component.bar", + ActionInvocationInstanceAddr: "action.webhook.notify[2]", + }, + }, + { + name: "action with for_each key", + addr: stackaddrs.AbsActionInvocationInstance{ + Component: stackaddrs.AbsComponentInstance{ + Stack: stackaddrs.RootStackInstance, + Item: stackaddrs.ComponentInstance{ + Component: stackaddrs.Component{Name: "baz"}, + Key: addrs.StringKey("prod"), + }, + }, + Item: addrs.AbsActionInstance{ + Module: addrs.RootModuleInstance, + Action: addrs.ActionInstance{ + Action: addrs.Action{ + Type: "slack", + Name: "alert", + }, + Key: addrs.StringKey("critical"), + }, + }, + }, + want: &ActionInvocationInstanceInStackAddr{ + ComponentInstanceAddr: `component.baz["prod"]`, + ActionInvocationInstanceAddr: `action.slack.alert["critical"]`, + }, + }, + { + name: "action in child module", + addr: stackaddrs.AbsActionInvocationInstance{ + Component: stackaddrs.AbsComponentInstance{ + Stack: stackaddrs.RootStackInstance, + Item: stackaddrs.ComponentInstance{ + Component: stackaddrs.Component{Name: "network"}, + }, + }, + Item: addrs.AbsActionInstance{ + Module: addrs.RootModuleInstance.Child("vpc", addrs.NoKey), + Action: addrs.ActionInstance{ + Action: addrs.Action{ + Type: "aws_lambda", + Name: "cleanup", + }, + Key: addrs.NoKey, + }, + }, + }, + want: &ActionInvocationInstanceInStackAddr{ + ComponentInstanceAddr: "component.network", + ActionInvocationInstanceAddr: "module.vpc.action.aws_lambda.cleanup", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := NewActionInvocationInStackAddr(tt.addr) + if diff := cmp.Diff(tt.want, got, protocmp.Transform()); diff != "" { + t.Errorf("NewActionInvocationInStackAddr() mismatch (-want +got):\n%s", diff) + } + }) + } +} + +func TestNewActionInvocationInStackAddr_RoundTrip(t *testing.T) { + // Test that the string representation is stable and meaningful + addr := stackaddrs.AbsActionInvocationInstance{ + Component: stackaddrs.AbsComponentInstance{ + Stack: stackaddrs.RootStackInstance, + Item: stackaddrs.ComponentInstance{ + Component: stackaddrs.Component{Name: "mycomp"}, + }, + }, + Item: addrs.AbsActionInstance{ + Module: addrs.RootModuleInstance, + Action: addrs.ActionInstance{ + Action: addrs.Action{ + Type: "http", + Name: "webhook", + }, + Key: addrs.NoKey, + }, + }, + } + + proto := NewActionInvocationInStackAddr(addr) + + // Verify the strings match what we expect + if proto.ComponentInstanceAddr != "component.mycomp" { + t.Errorf("unexpected component address: %q", proto.ComponentInstanceAddr) + } + if proto.ActionInvocationInstanceAddr != "action.http.webhook" { + t.Errorf("unexpected action address: %q", proto.ActionInvocationInstanceAddr) + } +} diff --git a/internal/rpcapi/terraform1/stacks/stacks.pb.go b/internal/rpcapi/terraform1/stacks/stacks.pb.go index 62d04b8757..8383d79a08 100644 --- a/internal/rpcapi/terraform1/stacks/stacks.pb.go +++ b/internal/rpcapi/terraform1/stacks/stacks.pb.go @@ -231,6 +231,71 @@ func (FindStackConfigurationComponents_Instances) EnumDescriptor() ([]byte, []in return file_stacks_proto_rawDescGZIP(), []int{6, 0} } +// ActionTriggerEvent describes the reason an action was triggered +type PlannedChange_ActionTriggerEvent int32 + +const ( + PlannedChange_INVALID_EVENT PlannedChange_ActionTriggerEvent = 0 + PlannedChange_BEFORE_CREATE PlannedChange_ActionTriggerEvent = 1 + PlannedChange_AFTER_CREATE PlannedChange_ActionTriggerEvent = 2 + PlannedChange_BEFORE_UPDATE PlannedChange_ActionTriggerEvent = 3 + PlannedChange_AFTER_UPDATE PlannedChange_ActionTriggerEvent = 4 + PlannedChange_BEFORE_DESTROY PlannedChange_ActionTriggerEvent = 5 + PlannedChange_AFTER_DESTROY PlannedChange_ActionTriggerEvent = 6 + PlannedChange_INVOKE PlannedChange_ActionTriggerEvent = 7 +) + +// Enum value maps for PlannedChange_ActionTriggerEvent. +var ( + PlannedChange_ActionTriggerEvent_name = map[int32]string{ + 0: "INVALID_EVENT", + 1: "BEFORE_CREATE", + 2: "AFTER_CREATE", + 3: "BEFORE_UPDATE", + 4: "AFTER_UPDATE", + 5: "BEFORE_DESTROY", + 6: "AFTER_DESTROY", + 7: "INVOKE", + } + PlannedChange_ActionTriggerEvent_value = map[string]int32{ + "INVALID_EVENT": 0, + "BEFORE_CREATE": 1, + "AFTER_CREATE": 2, + "BEFORE_UPDATE": 3, + "AFTER_UPDATE": 4, + "BEFORE_DESTROY": 5, + "AFTER_DESTROY": 6, + "INVOKE": 7, + } +) + +func (x PlannedChange_ActionTriggerEvent) Enum() *PlannedChange_ActionTriggerEvent { + p := new(PlannedChange_ActionTriggerEvent) + *p = x + return p +} + +func (x PlannedChange_ActionTriggerEvent) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PlannedChange_ActionTriggerEvent) Descriptor() protoreflect.EnumDescriptor { + return file_stacks_proto_enumTypes[4].Descriptor() +} + +func (PlannedChange_ActionTriggerEvent) Type() protoreflect.EnumType { + return &file_stacks_proto_enumTypes[4] +} + +func (x PlannedChange_ActionTriggerEvent) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PlannedChange_ActionTriggerEvent.Descriptor instead. +func (PlannedChange_ActionTriggerEvent) EnumDescriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{23, 0} +} + // Reason describes the reason why a resource instance change was // deferred. type Deferred_Reason int32 @@ -275,11 +340,11 @@ func (x Deferred_Reason) String() string { } func (Deferred_Reason) Descriptor() protoreflect.EnumDescriptor { - return file_stacks_proto_enumTypes[4].Descriptor() + return file_stacks_proto_enumTypes[5].Descriptor() } func (Deferred_Reason) Type() protoreflect.EnumType { - return &file_stacks_proto_enumTypes[4] + return &file_stacks_proto_enumTypes[5] } func (x Deferred_Reason) Number() protoreflect.EnumNumber { @@ -288,7 +353,72 @@ func (x Deferred_Reason) Number() protoreflect.EnumNumber { // Deprecated: Use Deferred_Reason.Descriptor instead. func (Deferred_Reason) EnumDescriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{23, 0} + return file_stacks_proto_rawDescGZIP(), []int{24, 0} +} + +// ActionTriggerEvent describes the reason an action was triggered +type StackChangeProgress_ActionTriggerEvent int32 + +const ( + StackChangeProgress_INVALID_EVENT StackChangeProgress_ActionTriggerEvent = 0 + StackChangeProgress_BEFORE_CREATE StackChangeProgress_ActionTriggerEvent = 1 + StackChangeProgress_AFTER_CREATE StackChangeProgress_ActionTriggerEvent = 2 + StackChangeProgress_BEFORE_UPDATE StackChangeProgress_ActionTriggerEvent = 3 + StackChangeProgress_AFTER_UPDATE StackChangeProgress_ActionTriggerEvent = 4 + StackChangeProgress_BEFORE_DESTROY StackChangeProgress_ActionTriggerEvent = 5 + StackChangeProgress_AFTER_DESTROY StackChangeProgress_ActionTriggerEvent = 6 + StackChangeProgress_INVOKE StackChangeProgress_ActionTriggerEvent = 7 +) + +// Enum value maps for StackChangeProgress_ActionTriggerEvent. +var ( + StackChangeProgress_ActionTriggerEvent_name = map[int32]string{ + 0: "INVALID_EVENT", + 1: "BEFORE_CREATE", + 2: "AFTER_CREATE", + 3: "BEFORE_UPDATE", + 4: "AFTER_UPDATE", + 5: "BEFORE_DESTROY", + 6: "AFTER_DESTROY", + 7: "INVOKE", + } + StackChangeProgress_ActionTriggerEvent_value = map[string]int32{ + "INVALID_EVENT": 0, + "BEFORE_CREATE": 1, + "AFTER_CREATE": 2, + "BEFORE_UPDATE": 3, + "AFTER_UPDATE": 4, + "BEFORE_DESTROY": 5, + "AFTER_DESTROY": 6, + "INVOKE": 7, + } +) + +func (x StackChangeProgress_ActionTriggerEvent) Enum() *StackChangeProgress_ActionTriggerEvent { + p := new(StackChangeProgress_ActionTriggerEvent) + *p = x + return p +} + +func (x StackChangeProgress_ActionTriggerEvent) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (StackChangeProgress_ActionTriggerEvent) Descriptor() protoreflect.EnumDescriptor { + return file_stacks_proto_enumTypes[6].Descriptor() +} + +func (StackChangeProgress_ActionTriggerEvent) Type() protoreflect.EnumType { + return &file_stacks_proto_enumTypes[6] +} + +func (x StackChangeProgress_ActionTriggerEvent) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use StackChangeProgress_ActionTriggerEvent.Descriptor instead. +func (StackChangeProgress_ActionTriggerEvent) EnumDescriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{26, 0} } type StackChangeProgress_ComponentInstanceStatus_Status int32 @@ -339,11 +469,11 @@ func (x StackChangeProgress_ComponentInstanceStatus_Status) String() string { } func (StackChangeProgress_ComponentInstanceStatus_Status) Descriptor() protoreflect.EnumDescriptor { - return file_stacks_proto_enumTypes[5].Descriptor() + return file_stacks_proto_enumTypes[7].Descriptor() } func (StackChangeProgress_ComponentInstanceStatus_Status) Type() protoreflect.EnumType { - return &file_stacks_proto_enumTypes[5] + return &file_stacks_proto_enumTypes[7] } func (x StackChangeProgress_ComponentInstanceStatus_Status) Number() protoreflect.EnumNumber { @@ -352,7 +482,7 @@ func (x StackChangeProgress_ComponentInstanceStatus_Status) Number() protoreflec // Deprecated: Use StackChangeProgress_ComponentInstanceStatus_Status.Descriptor instead. func (StackChangeProgress_ComponentInstanceStatus_Status) EnumDescriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 0, 0} + return file_stacks_proto_rawDescGZIP(), []int{26, 0, 0} } type StackChangeProgress_ResourceInstanceStatus_Status int32 @@ -406,11 +536,11 @@ func (x StackChangeProgress_ResourceInstanceStatus_Status) String() string { } func (StackChangeProgress_ResourceInstanceStatus_Status) Descriptor() protoreflect.EnumDescriptor { - return file_stacks_proto_enumTypes[6].Descriptor() + return file_stacks_proto_enumTypes[8].Descriptor() } func (StackChangeProgress_ResourceInstanceStatus_Status) Type() protoreflect.EnumType { - return &file_stacks_proto_enumTypes[6] + return &file_stacks_proto_enumTypes[8] } func (x StackChangeProgress_ResourceInstanceStatus_Status) Number() protoreflect.EnumNumber { @@ -419,7 +549,7 @@ func (x StackChangeProgress_ResourceInstanceStatus_Status) Number() protoreflect // Deprecated: Use StackChangeProgress_ResourceInstanceStatus_Status.Descriptor instead. func (StackChangeProgress_ResourceInstanceStatus_Status) EnumDescriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 1, 0} + return file_stacks_proto_rawDescGZIP(), []int{26, 1, 0} } type StackChangeProgress_ProvisionerStatus_Status int32 @@ -458,11 +588,11 @@ func (x StackChangeProgress_ProvisionerStatus_Status) String() string { } func (StackChangeProgress_ProvisionerStatus_Status) Descriptor() protoreflect.EnumDescriptor { - return file_stacks_proto_enumTypes[7].Descriptor() + return file_stacks_proto_enumTypes[9].Descriptor() } func (StackChangeProgress_ProvisionerStatus_Status) Type() protoreflect.EnumType { - return &file_stacks_proto_enumTypes[7] + return &file_stacks_proto_enumTypes[9] } func (x StackChangeProgress_ProvisionerStatus_Status) Number() protoreflect.EnumNumber { @@ -471,7 +601,7 @@ func (x StackChangeProgress_ProvisionerStatus_Status) Number() protoreflect.Enum // Deprecated: Use StackChangeProgress_ProvisionerStatus_Status.Descriptor instead. func (StackChangeProgress_ProvisionerStatus_Status) EnumDescriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 4, 0} + return file_stacks_proto_rawDescGZIP(), []int{26, 7, 0} } // OpenTerraformState opens a previously-saved Terraform state, returning a @@ -1291,6 +1421,66 @@ func (x *ComponentInstanceInStackAddr) GetComponentInstanceAddr() string { return "" } +// Represents the address of a specific action inside a specific +// component instance within the containing stack. +type ActionInvocationInstanceInStackAddr struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Unique address of the component instance that this action instance + // belongs to. + ComponentInstanceAddr string `protobuf:"bytes,1,opt,name=component_instance_addr,json=componentInstanceAddr,proto3" json:"component_instance_addr,omitempty"` + // Unique address of the action instance within the given component + // instance. Each component instance has a separate namespace of + // action instance addresses, so callers must take both fields together + // to produce a key that's unique throughout the entire plan. + ActionInvocationInstanceAddr string `protobuf:"bytes,2,opt,name=action_invocation_instance_addr,json=actionInvocationInstanceAddr,proto3" json:"action_invocation_instance_addr,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ActionInvocationInstanceInStackAddr) Reset() { + *x = ActionInvocationInstanceInStackAddr{} + mi := &file_stacks_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ActionInvocationInstanceInStackAddr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActionInvocationInstanceInStackAddr) ProtoMessage() {} + +func (x *ActionInvocationInstanceInStackAddr) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActionInvocationInstanceInStackAddr.ProtoReflect.Descriptor instead. +func (*ActionInvocationInstanceInStackAddr) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{20} +} + +func (x *ActionInvocationInstanceInStackAddr) GetComponentInstanceAddr() string { + if x != nil { + return x.ComponentInstanceAddr + } + return "" +} + +func (x *ActionInvocationInstanceInStackAddr) GetActionInvocationInstanceAddr() string { + if x != nil { + return x.ActionInvocationInstanceAddr + } + return "" +} + // Represents the address of a specific resource instance inside a specific // component instance within the containing stack. type ResourceInstanceInStackAddr struct { @@ -1309,7 +1499,7 @@ type ResourceInstanceInStackAddr struct { func (x *ResourceInstanceInStackAddr) Reset() { *x = ResourceInstanceInStackAddr{} - mi := &file_stacks_proto_msgTypes[20] + mi := &file_stacks_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1321,7 +1511,7 @@ func (x *ResourceInstanceInStackAddr) String() string { func (*ResourceInstanceInStackAddr) ProtoMessage() {} func (x *ResourceInstanceInStackAddr) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[20] + mi := &file_stacks_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1334,7 +1524,7 @@ func (x *ResourceInstanceInStackAddr) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceInstanceInStackAddr.ProtoReflect.Descriptor instead. func (*ResourceInstanceInStackAddr) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{20} + return file_stacks_proto_rawDescGZIP(), []int{21} } func (x *ResourceInstanceInStackAddr) GetComponentInstanceAddr() string { @@ -1374,7 +1564,7 @@ type ResourceInstanceObjectInStackAddr struct { func (x *ResourceInstanceObjectInStackAddr) Reset() { *x = ResourceInstanceObjectInStackAddr{} - mi := &file_stacks_proto_msgTypes[21] + mi := &file_stacks_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1386,7 +1576,7 @@ func (x *ResourceInstanceObjectInStackAddr) String() string { func (*ResourceInstanceObjectInStackAddr) ProtoMessage() {} func (x *ResourceInstanceObjectInStackAddr) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[21] + mi := &file_stacks_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1399,7 +1589,7 @@ func (x *ResourceInstanceObjectInStackAddr) ProtoReflect() protoreflect.Message // Deprecated: Use ResourceInstanceObjectInStackAddr.ProtoReflect.Descriptor instead. func (*ResourceInstanceObjectInStackAddr) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{21} + return file_stacks_proto_rawDescGZIP(), []int{22} } func (x *ResourceInstanceObjectInStackAddr) GetComponentInstanceAddr() string { @@ -1467,7 +1657,7 @@ type PlannedChange struct { func (x *PlannedChange) Reset() { *x = PlannedChange{} - mi := &file_stacks_proto_msgTypes[22] + mi := &file_stacks_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1479,7 +1669,7 @@ func (x *PlannedChange) String() string { func (*PlannedChange) ProtoMessage() {} func (x *PlannedChange) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[22] + mi := &file_stacks_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1492,7 +1682,7 @@ func (x *PlannedChange) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedChange.ProtoReflect.Descriptor instead. func (*PlannedChange) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22} + return file_stacks_proto_rawDescGZIP(), []int{23} } func (x *PlannedChange) GetRaw() []*anypb.Any { @@ -1520,7 +1710,7 @@ type Deferred struct { func (x *Deferred) Reset() { *x = Deferred{} - mi := &file_stacks_proto_msgTypes[23] + mi := &file_stacks_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1532,7 +1722,7 @@ func (x *Deferred) String() string { func (*Deferred) ProtoMessage() {} func (x *Deferred) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[23] + mi := &file_stacks_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1545,7 +1735,7 @@ func (x *Deferred) ProtoReflect() protoreflect.Message { // Deprecated: Use Deferred.ProtoReflect.Descriptor instead. func (*Deferred) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{23} + return file_stacks_proto_rawDescGZIP(), []int{24} } func (x *Deferred) GetReason() Deferred_Reason { @@ -1627,7 +1817,7 @@ type AppliedChange struct { func (x *AppliedChange) Reset() { *x = AppliedChange{} - mi := &file_stacks_proto_msgTypes[24] + mi := &file_stacks_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1639,7 +1829,7 @@ func (x *AppliedChange) String() string { func (*AppliedChange) ProtoMessage() {} func (x *AppliedChange) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[24] + mi := &file_stacks_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1652,7 +1842,7 @@ func (x *AppliedChange) ProtoReflect() protoreflect.Message { // Deprecated: Use AppliedChange.ProtoReflect.Descriptor instead. func (*AppliedChange) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{24} + return file_stacks_proto_rawDescGZIP(), []int{25} } func (x *AppliedChange) GetRaw() []*AppliedChange_RawChange { @@ -1688,6 +1878,7 @@ type StackChangeProgress struct { // *StackChangeProgress_ComponentInstanceChanges_ // *StackChangeProgress_ComponentInstances_ // *StackChangeProgress_DeferredResourceInstancePlannedChange_ + // *StackChangeProgress_ActionInvocationPlanned_ Event isStackChangeProgress_Event `protobuf_oneof:"event"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1695,7 +1886,7 @@ type StackChangeProgress struct { func (x *StackChangeProgress) Reset() { *x = StackChangeProgress{} - mi := &file_stacks_proto_msgTypes[25] + mi := &file_stacks_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1707,7 +1898,7 @@ func (x *StackChangeProgress) String() string { func (*StackChangeProgress) ProtoMessage() {} func (x *StackChangeProgress) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[25] + mi := &file_stacks_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1720,7 +1911,7 @@ func (x *StackChangeProgress) ProtoReflect() protoreflect.Message { // Deprecated: Use StackChangeProgress.ProtoReflect.Descriptor instead. func (*StackChangeProgress) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25} + return file_stacks_proto_rawDescGZIP(), []int{26} } func (x *StackChangeProgress) GetEvent() isStackChangeProgress_Event { @@ -1802,6 +1993,15 @@ func (x *StackChangeProgress) GetDeferredResourceInstancePlannedChange() *StackC return nil } +func (x *StackChangeProgress) GetActionInvocationPlanned() *StackChangeProgress_ActionInvocationPlanned { + if x != nil { + if x, ok := x.Event.(*StackChangeProgress_ActionInvocationPlanned_); ok { + return x.ActionInvocationPlanned + } + } + return nil +} + type isStackChangeProgress_Event interface { isStackChangeProgress_Event() } @@ -1838,6 +2038,10 @@ type StackChangeProgress_DeferredResourceInstancePlannedChange_ struct { DeferredResourceInstancePlannedChange *StackChangeProgress_DeferredResourceInstancePlannedChange `protobuf:"bytes,8,opt,name=deferred_resource_instance_planned_change,json=deferredResourceInstancePlannedChange,proto3,oneof"` } +type StackChangeProgress_ActionInvocationPlanned_ struct { + ActionInvocationPlanned *StackChangeProgress_ActionInvocationPlanned `protobuf:"bytes,9,opt,name=action_invocation_planned,json=actionInvocationPlanned,proto3,oneof"` +} + func (*StackChangeProgress_ComponentInstanceStatus_) isStackChangeProgress_Event() {} func (*StackChangeProgress_ResourceInstanceStatus_) isStackChangeProgress_Event() {} @@ -1854,6 +2058,8 @@ func (*StackChangeProgress_ComponentInstances_) isStackChangeProgress_Event() {} func (*StackChangeProgress_DeferredResourceInstancePlannedChange_) isStackChangeProgress_Event() {} +func (*StackChangeProgress_ActionInvocationPlanned_) isStackChangeProgress_Event() {} + type ListResourceIdentities struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -1862,7 +2068,7 @@ type ListResourceIdentities struct { func (x *ListResourceIdentities) Reset() { *x = ListResourceIdentities{} - mi := &file_stacks_proto_msgTypes[26] + mi := &file_stacks_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1874,7 +2080,7 @@ func (x *ListResourceIdentities) String() string { func (*ListResourceIdentities) ProtoMessage() {} func (x *ListResourceIdentities) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[26] + mi := &file_stacks_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1887,7 +2093,7 @@ func (x *ListResourceIdentities) ProtoReflect() protoreflect.Message { // Deprecated: Use ListResourceIdentities.ProtoReflect.Descriptor instead. func (*ListResourceIdentities) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26} + return file_stacks_proto_rawDescGZIP(), []int{27} } type OpenTerraformState_Request struct { @@ -1903,7 +2109,7 @@ type OpenTerraformState_Request struct { func (x *OpenTerraformState_Request) Reset() { *x = OpenTerraformState_Request{} - mi := &file_stacks_proto_msgTypes[27] + mi := &file_stacks_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1915,7 +2121,7 @@ func (x *OpenTerraformState_Request) String() string { func (*OpenTerraformState_Request) ProtoMessage() {} func (x *OpenTerraformState_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[27] + mi := &file_stacks_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1984,7 +2190,7 @@ type OpenTerraformState_Response struct { func (x *OpenTerraformState_Response) Reset() { *x = OpenTerraformState_Response{} - mi := &file_stacks_proto_msgTypes[28] + mi := &file_stacks_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1996,7 +2202,7 @@ func (x *OpenTerraformState_Response) String() string { func (*OpenTerraformState_Response) ProtoMessage() {} func (x *OpenTerraformState_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[28] + mi := &file_stacks_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2035,7 +2241,7 @@ type CloseTerraformState_Request struct { func (x *CloseTerraformState_Request) Reset() { *x = CloseTerraformState_Request{} - mi := &file_stacks_proto_msgTypes[29] + mi := &file_stacks_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2047,7 +2253,7 @@ func (x *CloseTerraformState_Request) String() string { func (*CloseTerraformState_Request) ProtoMessage() {} func (x *CloseTerraformState_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[29] + mi := &file_stacks_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2078,7 +2284,7 @@ type CloseTerraformState_Response struct { func (x *CloseTerraformState_Response) Reset() { *x = CloseTerraformState_Response{} - mi := &file_stacks_proto_msgTypes[30] + mi := &file_stacks_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2090,7 +2296,7 @@ func (x *CloseTerraformState_Response) String() string { func (*CloseTerraformState_Response) ProtoMessage() {} func (x *CloseTerraformState_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[30] + mi := &file_stacks_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2122,7 +2328,7 @@ type MigrateTerraformState_Request struct { func (x *MigrateTerraformState_Request) Reset() { *x = MigrateTerraformState_Request{} - mi := &file_stacks_proto_msgTypes[31] + mi := &file_stacks_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2134,7 +2340,7 @@ func (x *MigrateTerraformState_Request) String() string { func (*MigrateTerraformState_Request) ProtoMessage() {} func (x *MigrateTerraformState_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[31] + mi := &file_stacks_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2218,7 +2424,7 @@ type MigrateTerraformState_Event struct { func (x *MigrateTerraformState_Event) Reset() { *x = MigrateTerraformState_Event{} - mi := &file_stacks_proto_msgTypes[32] + mi := &file_stacks_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2230,7 +2436,7 @@ func (x *MigrateTerraformState_Event) String() string { func (*MigrateTerraformState_Event) ProtoMessage() {} func (x *MigrateTerraformState_Event) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[32] + mi := &file_stacks_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2318,7 +2524,7 @@ type MigrateTerraformState_Request_Mapping struct { func (x *MigrateTerraformState_Request_Mapping) Reset() { *x = MigrateTerraformState_Request_Mapping{} - mi := &file_stacks_proto_msgTypes[33] + mi := &file_stacks_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2330,7 +2536,7 @@ func (x *MigrateTerraformState_Request_Mapping) String() string { func (*MigrateTerraformState_Request_Mapping) ProtoMessage() {} func (x *MigrateTerraformState_Request_Mapping) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[33] + mi := &file_stacks_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2370,7 +2576,7 @@ type OpenStackConfiguration_Request struct { func (x *OpenStackConfiguration_Request) Reset() { *x = OpenStackConfiguration_Request{} - mi := &file_stacks_proto_msgTypes[36] + mi := &file_stacks_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2382,7 +2588,7 @@ func (x *OpenStackConfiguration_Request) String() string { func (*OpenStackConfiguration_Request) ProtoMessage() {} func (x *OpenStackConfiguration_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[36] + mi := &file_stacks_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2422,7 +2628,7 @@ type OpenStackConfiguration_Response struct { func (x *OpenStackConfiguration_Response) Reset() { *x = OpenStackConfiguration_Response{} - mi := &file_stacks_proto_msgTypes[37] + mi := &file_stacks_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2434,7 +2640,7 @@ func (x *OpenStackConfiguration_Response) String() string { func (*OpenStackConfiguration_Response) ProtoMessage() {} func (x *OpenStackConfiguration_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[37] + mi := &file_stacks_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2473,7 +2679,7 @@ type CloseStackConfiguration_Request struct { func (x *CloseStackConfiguration_Request) Reset() { *x = CloseStackConfiguration_Request{} - mi := &file_stacks_proto_msgTypes[38] + mi := &file_stacks_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2485,7 +2691,7 @@ func (x *CloseStackConfiguration_Request) String() string { func (*CloseStackConfiguration_Request) ProtoMessage() {} func (x *CloseStackConfiguration_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[38] + mi := &file_stacks_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2516,7 +2722,7 @@ type CloseStackConfiguration_Response struct { func (x *CloseStackConfiguration_Response) Reset() { *x = CloseStackConfiguration_Response{} - mi := &file_stacks_proto_msgTypes[39] + mi := &file_stacks_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2528,7 +2734,7 @@ func (x *CloseStackConfiguration_Response) String() string { func (*CloseStackConfiguration_Response) ProtoMessage() {} func (x *CloseStackConfiguration_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[39] + mi := &file_stacks_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2555,7 +2761,7 @@ type ValidateStackConfiguration_Request struct { func (x *ValidateStackConfiguration_Request) Reset() { *x = ValidateStackConfiguration_Request{} - mi := &file_stacks_proto_msgTypes[40] + mi := &file_stacks_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2567,7 +2773,7 @@ func (x *ValidateStackConfiguration_Request) String() string { func (*ValidateStackConfiguration_Request) ProtoMessage() {} func (x *ValidateStackConfiguration_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[40] + mi := &file_stacks_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2613,7 +2819,7 @@ type ValidateStackConfiguration_Response struct { func (x *ValidateStackConfiguration_Response) Reset() { *x = ValidateStackConfiguration_Response{} - mi := &file_stacks_proto_msgTypes[41] + mi := &file_stacks_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2625,7 +2831,7 @@ func (x *ValidateStackConfiguration_Response) String() string { func (*ValidateStackConfiguration_Response) ProtoMessage() {} func (x *ValidateStackConfiguration_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[41] + mi := &file_stacks_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2657,7 +2863,7 @@ type FindStackConfigurationComponents_Request struct { func (x *FindStackConfigurationComponents_Request) Reset() { *x = FindStackConfigurationComponents_Request{} - mi := &file_stacks_proto_msgTypes[42] + mi := &file_stacks_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2669,7 +2875,7 @@ func (x *FindStackConfigurationComponents_Request) String() string { func (*FindStackConfigurationComponents_Request) ProtoMessage() {} func (x *FindStackConfigurationComponents_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[42] + mi := &file_stacks_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2701,7 +2907,7 @@ type FindStackConfigurationComponents_Response struct { func (x *FindStackConfigurationComponents_Response) Reset() { *x = FindStackConfigurationComponents_Response{} - mi := &file_stacks_proto_msgTypes[43] + mi := &file_stacks_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2713,7 +2919,7 @@ func (x *FindStackConfigurationComponents_Response) String() string { func (*FindStackConfigurationComponents_Response) ProtoMessage() {} func (x *FindStackConfigurationComponents_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[43] + mi := &file_stacks_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2749,7 +2955,7 @@ type FindStackConfigurationComponents_StackConfig struct { func (x *FindStackConfigurationComponents_StackConfig) Reset() { *x = FindStackConfigurationComponents_StackConfig{} - mi := &file_stacks_proto_msgTypes[44] + mi := &file_stacks_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2761,7 +2967,7 @@ func (x *FindStackConfigurationComponents_StackConfig) String() string { func (*FindStackConfigurationComponents_StackConfig) ProtoMessage() {} func (x *FindStackConfigurationComponents_StackConfig) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[44] + mi := &file_stacks_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2823,7 +3029,7 @@ type FindStackConfigurationComponents_EmbeddedStack struct { func (x *FindStackConfigurationComponents_EmbeddedStack) Reset() { *x = FindStackConfigurationComponents_EmbeddedStack{} - mi := &file_stacks_proto_msgTypes[45] + mi := &file_stacks_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2835,7 +3041,7 @@ func (x *FindStackConfigurationComponents_EmbeddedStack) String() string { func (*FindStackConfigurationComponents_EmbeddedStack) ProtoMessage() {} func (x *FindStackConfigurationComponents_EmbeddedStack) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[45] + mi := &file_stacks_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2883,7 +3089,7 @@ type FindStackConfigurationComponents_Component struct { func (x *FindStackConfigurationComponents_Component) Reset() { *x = FindStackConfigurationComponents_Component{} - mi := &file_stacks_proto_msgTypes[46] + mi := &file_stacks_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2895,7 +3101,7 @@ func (x *FindStackConfigurationComponents_Component) String() string { func (*FindStackConfigurationComponents_Component) ProtoMessage() {} func (x *FindStackConfigurationComponents_Component) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[46] + mi := &file_stacks_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2949,7 +3155,7 @@ type FindStackConfigurationComponents_Removed struct { func (x *FindStackConfigurationComponents_Removed) Reset() { *x = FindStackConfigurationComponents_Removed{} - mi := &file_stacks_proto_msgTypes[47] + mi := &file_stacks_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2961,7 +3167,7 @@ func (x *FindStackConfigurationComponents_Removed) String() string { func (*FindStackConfigurationComponents_Removed) ProtoMessage() {} func (x *FindStackConfigurationComponents_Removed) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[47] + mi := &file_stacks_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3027,7 +3233,7 @@ type FindStackConfigurationComponents_InputVariable struct { func (x *FindStackConfigurationComponents_InputVariable) Reset() { *x = FindStackConfigurationComponents_InputVariable{} - mi := &file_stacks_proto_msgTypes[48] + mi := &file_stacks_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3039,7 +3245,7 @@ func (x *FindStackConfigurationComponents_InputVariable) String() string { func (*FindStackConfigurationComponents_InputVariable) ProtoMessage() {} func (x *FindStackConfigurationComponents_InputVariable) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[48] + mi := &file_stacks_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3086,7 +3292,7 @@ type FindStackConfigurationComponents_OutputValue struct { func (x *FindStackConfigurationComponents_OutputValue) Reset() { *x = FindStackConfigurationComponents_OutputValue{} - mi := &file_stacks_proto_msgTypes[49] + mi := &file_stacks_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3098,7 +3304,7 @@ func (x *FindStackConfigurationComponents_OutputValue) String() string { func (*FindStackConfigurationComponents_OutputValue) ProtoMessage() {} func (x *FindStackConfigurationComponents_OutputValue) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[49] + mi := &file_stacks_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3140,7 +3346,7 @@ type FindStackConfigurationComponents_Removed_Block struct { func (x *FindStackConfigurationComponents_Removed_Block) Reset() { *x = FindStackConfigurationComponents_Removed_Block{} - mi := &file_stacks_proto_msgTypes[55] + mi := &file_stacks_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3152,7 +3358,7 @@ func (x *FindStackConfigurationComponents_Removed_Block) String() string { func (*FindStackConfigurationComponents_Removed_Block) ProtoMessage() {} func (x *FindStackConfigurationComponents_Removed_Block) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[55] + mi := &file_stacks_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3205,7 +3411,7 @@ type OpenStackState_RequestItem struct { func (x *OpenStackState_RequestItem) Reset() { *x = OpenStackState_RequestItem{} - mi := &file_stacks_proto_msgTypes[56] + mi := &file_stacks_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3217,7 +3423,7 @@ func (x *OpenStackState_RequestItem) String() string { func (*OpenStackState_RequestItem) ProtoMessage() {} func (x *OpenStackState_RequestItem) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[56] + mi := &file_stacks_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3249,7 +3455,7 @@ type OpenStackState_Response struct { func (x *OpenStackState_Response) Reset() { *x = OpenStackState_Response{} - mi := &file_stacks_proto_msgTypes[57] + mi := &file_stacks_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3261,7 +3467,7 @@ func (x *OpenStackState_Response) String() string { func (*OpenStackState_Response) ProtoMessage() {} func (x *OpenStackState_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[57] + mi := &file_stacks_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3293,7 +3499,7 @@ type CloseStackState_Request struct { func (x *CloseStackState_Request) Reset() { *x = CloseStackState_Request{} - mi := &file_stacks_proto_msgTypes[58] + mi := &file_stacks_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3305,7 +3511,7 @@ func (x *CloseStackState_Request) String() string { func (*CloseStackState_Request) ProtoMessage() {} func (x *CloseStackState_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[58] + mi := &file_stacks_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3336,7 +3542,7 @@ type CloseStackState_Response struct { func (x *CloseStackState_Response) Reset() { *x = CloseStackState_Response{} - mi := &file_stacks_proto_msgTypes[59] + mi := &file_stacks_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3348,7 +3554,7 @@ func (x *CloseStackState_Response) String() string { func (*CloseStackState_Response) ProtoMessage() {} func (x *CloseStackState_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[59] + mi := &file_stacks_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3380,7 +3586,7 @@ type PlanStackChanges_Request struct { func (x *PlanStackChanges_Request) Reset() { *x = PlanStackChanges_Request{} - mi := &file_stacks_proto_msgTypes[60] + mi := &file_stacks_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3392,7 +3598,7 @@ func (x *PlanStackChanges_Request) String() string { func (*PlanStackChanges_Request) ProtoMessage() {} func (x *PlanStackChanges_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[60] + mi := &file_stacks_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3472,7 +3678,7 @@ type PlanStackChanges_Event struct { func (x *PlanStackChanges_Event) Reset() { *x = PlanStackChanges_Event{} - mi := &file_stacks_proto_msgTypes[61] + mi := &file_stacks_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3484,7 +3690,7 @@ func (x *PlanStackChanges_Event) String() string { func (*PlanStackChanges_Event) ProtoMessage() {} func (x *PlanStackChanges_Event) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[61] + mi := &file_stacks_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3565,7 +3771,7 @@ type OpenStackPlan_RequestItem struct { func (x *OpenStackPlan_RequestItem) Reset() { *x = OpenStackPlan_RequestItem{} - mi := &file_stacks_proto_msgTypes[64] + mi := &file_stacks_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3577,7 +3783,7 @@ func (x *OpenStackPlan_RequestItem) String() string { func (*OpenStackPlan_RequestItem) ProtoMessage() {} func (x *OpenStackPlan_RequestItem) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[64] + mi := &file_stacks_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3609,7 +3815,7 @@ type OpenStackPlan_Response struct { func (x *OpenStackPlan_Response) Reset() { *x = OpenStackPlan_Response{} - mi := &file_stacks_proto_msgTypes[65] + mi := &file_stacks_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3621,7 +3827,7 @@ func (x *OpenStackPlan_Response) String() string { func (*OpenStackPlan_Response) ProtoMessage() {} func (x *OpenStackPlan_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[65] + mi := &file_stacks_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3653,7 +3859,7 @@ type CloseStackPlan_Request struct { func (x *CloseStackPlan_Request) Reset() { *x = CloseStackPlan_Request{} - mi := &file_stacks_proto_msgTypes[66] + mi := &file_stacks_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3665,7 +3871,7 @@ func (x *CloseStackPlan_Request) String() string { func (*CloseStackPlan_Request) ProtoMessage() {} func (x *CloseStackPlan_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[66] + mi := &file_stacks_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3696,7 +3902,7 @@ type CloseStackPlan_Response struct { func (x *CloseStackPlan_Response) Reset() { *x = CloseStackPlan_Response{} - mi := &file_stacks_proto_msgTypes[67] + mi := &file_stacks_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3708,7 +3914,7 @@ func (x *CloseStackPlan_Response) String() string { func (*CloseStackPlan_Response) ProtoMessage() {} func (x *CloseStackPlan_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[67] + mi := &file_stacks_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3769,7 +3975,7 @@ type ApplyStackChanges_Request struct { func (x *ApplyStackChanges_Request) Reset() { *x = ApplyStackChanges_Request{} - mi := &file_stacks_proto_msgTypes[68] + mi := &file_stacks_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3781,7 +3987,7 @@ func (x *ApplyStackChanges_Request) String() string { func (*ApplyStackChanges_Request) ProtoMessage() {} func (x *ApplyStackChanges_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[68] + mi := &file_stacks_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3861,7 +4067,7 @@ type ApplyStackChanges_Event struct { func (x *ApplyStackChanges_Event) Reset() { *x = ApplyStackChanges_Event{} - mi := &file_stacks_proto_msgTypes[69] + mi := &file_stacks_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3873,7 +4079,7 @@ func (x *ApplyStackChanges_Event) String() string { func (*ApplyStackChanges_Event) ProtoMessage() {} func (x *ApplyStackChanges_Event) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[69] + mi := &file_stacks_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3958,7 +4164,7 @@ type OpenStackInspector_Request struct { func (x *OpenStackInspector_Request) Reset() { *x = OpenStackInspector_Request{} - mi := &file_stacks_proto_msgTypes[71] + mi := &file_stacks_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3970,7 +4176,7 @@ func (x *OpenStackInspector_Request) String() string { func (*OpenStackInspector_Request) ProtoMessage() {} func (x *OpenStackInspector_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[71] + mi := &file_stacks_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4031,7 +4237,7 @@ type OpenStackInspector_Response struct { func (x *OpenStackInspector_Response) Reset() { *x = OpenStackInspector_Response{} - mi := &file_stacks_proto_msgTypes[72] + mi := &file_stacks_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4043,7 +4249,7 @@ func (x *OpenStackInspector_Response) String() string { func (*OpenStackInspector_Response) ProtoMessage() {} func (x *OpenStackInspector_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[72] + mi := &file_stacks_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4084,7 +4290,7 @@ type InspectExpressionResult_Request struct { func (x *InspectExpressionResult_Request) Reset() { *x = InspectExpressionResult_Request{} - mi := &file_stacks_proto_msgTypes[75] + mi := &file_stacks_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4096,7 +4302,7 @@ func (x *InspectExpressionResult_Request) String() string { func (*InspectExpressionResult_Request) ProtoMessage() {} func (x *InspectExpressionResult_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[75] + mi := &file_stacks_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4149,7 +4355,7 @@ type InspectExpressionResult_Response struct { func (x *InspectExpressionResult_Response) Reset() { *x = InspectExpressionResult_Response{} - mi := &file_stacks_proto_msgTypes[76] + mi := &file_stacks_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4161,7 +4367,7 @@ func (x *InspectExpressionResult_Response) String() string { func (*InspectExpressionResult_Response) ProtoMessage() {} func (x *InspectExpressionResult_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[76] + mi := &file_stacks_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4205,7 +4411,7 @@ type AttributePath_Step struct { func (x *AttributePath_Step) Reset() { *x = AttributePath_Step{} - mi := &file_stacks_proto_msgTypes[77] + mi := &file_stacks_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4217,7 +4423,7 @@ func (x *AttributePath_Step) String() string { func (*AttributePath_Step) ProtoMessage() {} func (x *AttributePath_Step) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[77] + mi := &file_stacks_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4311,6 +4517,8 @@ type PlannedChange_ChangeDescription struct { // *PlannedChange_ChangeDescription_PlanApplyable // *PlannedChange_ChangeDescription_ResourceInstanceDeferred // *PlannedChange_ChangeDescription_InputVariablePlanned + // *PlannedChange_ChangeDescription_ActionInvocationPlanned + // *PlannedChange_ChangeDescription_ActionInvocationDeferred Description isPlannedChange_ChangeDescription_Description `protobuf_oneof:"description"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -4318,7 +4526,7 @@ type PlannedChange_ChangeDescription struct { func (x *PlannedChange_ChangeDescription) Reset() { *x = PlannedChange_ChangeDescription{} - mi := &file_stacks_proto_msgTypes[78] + mi := &file_stacks_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4330,7 +4538,7 @@ func (x *PlannedChange_ChangeDescription) String() string { func (*PlannedChange_ChangeDescription) ProtoMessage() {} func (x *PlannedChange_ChangeDescription) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[78] + mi := &file_stacks_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4343,7 +4551,7 @@ func (x *PlannedChange_ChangeDescription) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedChange_ChangeDescription.ProtoReflect.Descriptor instead. func (*PlannedChange_ChangeDescription) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22, 0} + return file_stacks_proto_rawDescGZIP(), []int{23, 0} } func (x *PlannedChange_ChangeDescription) GetDescription() isPlannedChange_ChangeDescription_Description { @@ -4407,6 +4615,24 @@ func (x *PlannedChange_ChangeDescription) GetInputVariablePlanned() *PlannedChan return nil } +func (x *PlannedChange_ChangeDescription) GetActionInvocationPlanned() *PlannedChange_ActionInvocationInstance { + if x != nil { + if x, ok := x.Description.(*PlannedChange_ChangeDescription_ActionInvocationPlanned); ok { + return x.ActionInvocationPlanned + } + } + return nil +} + +func (x *PlannedChange_ChangeDescription) GetActionInvocationDeferred() *PlannedChange_ActionInvocationDeferred { + if x != nil { + if x, ok := x.Description.(*PlannedChange_ChangeDescription_ActionInvocationDeferred); ok { + return x.ActionInvocationDeferred + } + } + return nil +} + type isPlannedChange_ChangeDescription_Description interface { isPlannedChange_ChangeDescription_Description() } @@ -4435,6 +4661,14 @@ type PlannedChange_ChangeDescription_InputVariablePlanned struct { InputVariablePlanned *PlannedChange_InputVariable `protobuf:"bytes,6,opt,name=input_variable_planned,json=inputVariablePlanned,proto3,oneof"` } +type PlannedChange_ChangeDescription_ActionInvocationPlanned struct { + ActionInvocationPlanned *PlannedChange_ActionInvocationInstance `protobuf:"bytes,7,opt,name=action_invocation_planned,json=actionInvocationPlanned,proto3,oneof"` +} + +type PlannedChange_ChangeDescription_ActionInvocationDeferred struct { + ActionInvocationDeferred *PlannedChange_ActionInvocationDeferred `protobuf:"bytes,8,opt,name=action_invocation_deferred,json=actionInvocationDeferred,proto3,oneof"` +} + func (*PlannedChange_ChangeDescription_ComponentInstancePlanned) isPlannedChange_ChangeDescription_Description() { } @@ -4453,6 +4687,12 @@ func (*PlannedChange_ChangeDescription_ResourceInstanceDeferred) isPlannedChange func (*PlannedChange_ChangeDescription_InputVariablePlanned) isPlannedChange_ChangeDescription_Description() { } +func (*PlannedChange_ChangeDescription_ActionInvocationPlanned) isPlannedChange_ChangeDescription_Description() { +} + +func (*PlannedChange_ChangeDescription_ActionInvocationDeferred) isPlannedChange_ChangeDescription_Description() { +} + // Reports the existence of a particular instance of a component, // once Terraform has resolved arguments such as "for_each" that // might make the set of instances dynamic. @@ -4482,7 +4722,7 @@ type PlannedChange_ComponentInstance struct { func (x *PlannedChange_ComponentInstance) Reset() { *x = PlannedChange_ComponentInstance{} - mi := &file_stacks_proto_msgTypes[79] + mi := &file_stacks_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4494,7 +4734,7 @@ func (x *PlannedChange_ComponentInstance) String() string { func (*PlannedChange_ComponentInstance) ProtoMessage() {} func (x *PlannedChange_ComponentInstance) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[79] + mi := &file_stacks_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4507,7 +4747,7 @@ func (x *PlannedChange_ComponentInstance) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedChange_ComponentInstance.ProtoReflect.Descriptor instead. func (*PlannedChange_ComponentInstance) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22, 1} + return file_stacks_proto_rawDescGZIP(), []int{23, 1} } func (x *PlannedChange_ComponentInstance) GetAddr() *ComponentInstanceInStackAddr { @@ -4572,7 +4812,7 @@ type PlannedChange_ResourceInstance struct { func (x *PlannedChange_ResourceInstance) Reset() { *x = PlannedChange_ResourceInstance{} - mi := &file_stacks_proto_msgTypes[80] + mi := &file_stacks_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4584,7 +4824,7 @@ func (x *PlannedChange_ResourceInstance) String() string { func (*PlannedChange_ResourceInstance) ProtoMessage() {} func (x *PlannedChange_ResourceInstance) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[80] + mi := &file_stacks_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4597,7 +4837,7 @@ func (x *PlannedChange_ResourceInstance) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedChange_ResourceInstance.ProtoReflect.Descriptor instead. func (*PlannedChange_ResourceInstance) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22, 2} + return file_stacks_proto_rawDescGZIP(), []int{23, 2} } func (x *PlannedChange_ResourceInstance) GetAddr() *ResourceInstanceObjectInStackAddr { @@ -4719,7 +4959,7 @@ type PlannedChange_OutputValue struct { func (x *PlannedChange_OutputValue) Reset() { *x = PlannedChange_OutputValue{} - mi := &file_stacks_proto_msgTypes[81] + mi := &file_stacks_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4731,7 +4971,7 @@ func (x *PlannedChange_OutputValue) String() string { func (*PlannedChange_OutputValue) ProtoMessage() {} func (x *PlannedChange_OutputValue) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[81] + mi := &file_stacks_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4744,7 +4984,7 @@ func (x *PlannedChange_OutputValue) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedChange_OutputValue.ProtoReflect.Descriptor instead. func (*PlannedChange_OutputValue) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22, 3} + return file_stacks_proto_rawDescGZIP(), []int{23, 3} } func (x *PlannedChange_OutputValue) GetName() string { @@ -4778,7 +5018,7 @@ type PlannedChange_ResourceInstanceDeferred struct { func (x *PlannedChange_ResourceInstanceDeferred) Reset() { *x = PlannedChange_ResourceInstanceDeferred{} - mi := &file_stacks_proto_msgTypes[82] + mi := &file_stacks_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4790,7 +5030,7 @@ func (x *PlannedChange_ResourceInstanceDeferred) String() string { func (*PlannedChange_ResourceInstanceDeferred) ProtoMessage() {} func (x *PlannedChange_ResourceInstanceDeferred) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[82] + mi := &file_stacks_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4803,7 +5043,7 @@ func (x *PlannedChange_ResourceInstanceDeferred) ProtoReflect() protoreflect.Mes // Deprecated: Use PlannedChange_ResourceInstanceDeferred.ProtoReflect.Descriptor instead. func (*PlannedChange_ResourceInstanceDeferred) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22, 4} + return file_stacks_proto_rawDescGZIP(), []int{23, 4} } func (x *PlannedChange_ResourceInstanceDeferred) GetResourceInstance() *PlannedChange_ResourceInstance { @@ -4835,7 +5075,7 @@ type PlannedChange_InputVariable struct { func (x *PlannedChange_InputVariable) Reset() { *x = PlannedChange_InputVariable{} - mi := &file_stacks_proto_msgTypes[83] + mi := &file_stacks_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4847,7 +5087,7 @@ func (x *PlannedChange_InputVariable) String() string { func (*PlannedChange_InputVariable) ProtoMessage() {} func (x *PlannedChange_InputVariable) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[83] + mi := &file_stacks_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4860,7 +5100,7 @@ func (x *PlannedChange_InputVariable) ProtoReflect() protoreflect.Message { // Deprecated: Use PlannedChange_InputVariable.ProtoReflect.Descriptor instead. func (*PlannedChange_InputVariable) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22, 5} + return file_stacks_proto_rawDescGZIP(), []int{23, 5} } func (x *PlannedChange_InputVariable) GetName() string { @@ -4891,6 +5131,293 @@ func (x *PlannedChange_InputVariable) GetRequiredDuringApply() bool { return false } +// ActionInvocationInstance contains a planned action invocation and any embedded ResourceInstanceActionChanges +type PlannedChange_ActionInvocationInstance struct { + state protoimpl.MessageState `protogen:"open.v1"` + Addr *ActionInvocationInstanceInStackAddr `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` + // provider is the address of the provider configuration that this change + // was planned with, and thus the configuration that must be used to + // apply it. + ProviderAddr string `protobuf:"bytes,2,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + // The type of the action used to extract schema information + ActionType string `protobuf:"bytes,3,opt,name=action_type,json=actionType,proto3" json:"action_type,omitempty"` + ConfigValue *DynamicValue `protobuf:"bytes,4,opt,name=config_value,json=configValue,proto3" json:"config_value,omitempty"` + // Types that are valid to be assigned to ActionTrigger: + // + // *PlannedChange_ActionInvocationInstance_LifecycleActionTrigger + // *PlannedChange_ActionInvocationInstance_InvokeActionTrigger + ActionTrigger isPlannedChange_ActionInvocationInstance_ActionTrigger `protobuf_oneof:"action_trigger"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PlannedChange_ActionInvocationInstance) Reset() { + *x = PlannedChange_ActionInvocationInstance{} + mi := &file_stacks_proto_msgTypes[85] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PlannedChange_ActionInvocationInstance) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlannedChange_ActionInvocationInstance) ProtoMessage() {} + +func (x *PlannedChange_ActionInvocationInstance) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[85] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlannedChange_ActionInvocationInstance.ProtoReflect.Descriptor instead. +func (*PlannedChange_ActionInvocationInstance) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{23, 6} +} + +func (x *PlannedChange_ActionInvocationInstance) GetAddr() *ActionInvocationInstanceInStackAddr { + if x != nil { + return x.Addr + } + return nil +} + +func (x *PlannedChange_ActionInvocationInstance) GetProviderAddr() string { + if x != nil { + return x.ProviderAddr + } + return "" +} + +func (x *PlannedChange_ActionInvocationInstance) GetActionType() string { + if x != nil { + return x.ActionType + } + return "" +} + +func (x *PlannedChange_ActionInvocationInstance) GetConfigValue() *DynamicValue { + if x != nil { + return x.ConfigValue + } + return nil +} + +func (x *PlannedChange_ActionInvocationInstance) GetActionTrigger() isPlannedChange_ActionInvocationInstance_ActionTrigger { + if x != nil { + return x.ActionTrigger + } + return nil +} + +func (x *PlannedChange_ActionInvocationInstance) GetLifecycleActionTrigger() *PlannedChange_LifecycleActionTrigger { + if x != nil { + if x, ok := x.ActionTrigger.(*PlannedChange_ActionInvocationInstance_LifecycleActionTrigger); ok { + return x.LifecycleActionTrigger + } + } + return nil +} + +func (x *PlannedChange_ActionInvocationInstance) GetInvokeActionTrigger() *PlannedChange_InvokeActionTrigger { + if x != nil { + if x, ok := x.ActionTrigger.(*PlannedChange_ActionInvocationInstance_InvokeActionTrigger); ok { + return x.InvokeActionTrigger + } + } + return nil +} + +type isPlannedChange_ActionInvocationInstance_ActionTrigger interface { + isPlannedChange_ActionInvocationInstance_ActionTrigger() +} + +type PlannedChange_ActionInvocationInstance_LifecycleActionTrigger struct { + LifecycleActionTrigger *PlannedChange_LifecycleActionTrigger `protobuf:"bytes,6,opt,name=lifecycle_action_trigger,json=lifecycleActionTrigger,proto3,oneof"` +} + +type PlannedChange_ActionInvocationInstance_InvokeActionTrigger struct { + InvokeActionTrigger *PlannedChange_InvokeActionTrigger `protobuf:"bytes,7,opt,name=invoke_action_trigger,json=invokeActionTrigger,proto3,oneof"` +} + +func (*PlannedChange_ActionInvocationInstance_LifecycleActionTrigger) isPlannedChange_ActionInvocationInstance_ActionTrigger() { +} + +func (*PlannedChange_ActionInvocationInstance_InvokeActionTrigger) isPlannedChange_ActionInvocationInstance_ActionTrigger() { +} + +// ActionInvocationDeferred represents an action invocation that +// was deferred for some reason. +// It contains the original action invocation that was deferred, along with the reason +// why it was deferred. +type PlannedChange_ActionInvocationDeferred struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The reason why it was deferred + Deferred *Deferred `protobuf:"bytes,1,opt,name=deferred,proto3" json:"deferred,omitempty"` + // The original action invocation that was deferred + ActionInvocation *PlannedChange_ActionInvocationInstance `protobuf:"bytes,2,opt,name=action_invocation,json=actionInvocation,proto3" json:"action_invocation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PlannedChange_ActionInvocationDeferred) Reset() { + *x = PlannedChange_ActionInvocationDeferred{} + mi := &file_stacks_proto_msgTypes[86] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PlannedChange_ActionInvocationDeferred) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlannedChange_ActionInvocationDeferred) ProtoMessage() {} + +func (x *PlannedChange_ActionInvocationDeferred) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[86] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlannedChange_ActionInvocationDeferred.ProtoReflect.Descriptor instead. +func (*PlannedChange_ActionInvocationDeferred) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{23, 7} +} + +func (x *PlannedChange_ActionInvocationDeferred) GetDeferred() *Deferred { + if x != nil { + return x.Deferred + } + return nil +} + +func (x *PlannedChange_ActionInvocationDeferred) GetActionInvocation() *PlannedChange_ActionInvocationInstance { + if x != nil { + return x.ActionInvocation + } + return nil +} + +// LifecycleActionTrigger contains details on the conditions that led to the +// triggering of an action. +type PlannedChange_LifecycleActionTrigger struct { + state protoimpl.MessageState `protogen:"open.v1"` + TriggeringResourceAddress *ResourceInstanceInStackAddr `protobuf:"bytes,1,opt,name=triggering_resource_address,json=triggeringResourceAddress,proto3" json:"triggering_resource_address,omitempty"` + TriggerEvent PlannedChange_ActionTriggerEvent `protobuf:"varint,2,opt,name=trigger_event,json=triggerEvent,proto3,enum=terraform1.stacks.PlannedChange_ActionTriggerEvent" json:"trigger_event,omitempty"` + ActionTriggerBlockIndex int64 `protobuf:"varint,3,opt,name=action_trigger_block_index,json=actionTriggerBlockIndex,proto3" json:"action_trigger_block_index,omitempty"` + ActionsListIndex int64 `protobuf:"varint,4,opt,name=actions_list_index,json=actionsListIndex,proto3" json:"actions_list_index,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PlannedChange_LifecycleActionTrigger) Reset() { + *x = PlannedChange_LifecycleActionTrigger{} + mi := &file_stacks_proto_msgTypes[87] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PlannedChange_LifecycleActionTrigger) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlannedChange_LifecycleActionTrigger) ProtoMessage() {} + +func (x *PlannedChange_LifecycleActionTrigger) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[87] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlannedChange_LifecycleActionTrigger.ProtoReflect.Descriptor instead. +func (*PlannedChange_LifecycleActionTrigger) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{23, 8} +} + +func (x *PlannedChange_LifecycleActionTrigger) GetTriggeringResourceAddress() *ResourceInstanceInStackAddr { + if x != nil { + return x.TriggeringResourceAddress + } + return nil +} + +func (x *PlannedChange_LifecycleActionTrigger) GetTriggerEvent() PlannedChange_ActionTriggerEvent { + if x != nil { + return x.TriggerEvent + } + return PlannedChange_INVALID_EVENT +} + +func (x *PlannedChange_LifecycleActionTrigger) GetActionTriggerBlockIndex() int64 { + if x != nil { + return x.ActionTriggerBlockIndex + } + return 0 +} + +func (x *PlannedChange_LifecycleActionTrigger) GetActionsListIndex() int64 { + if x != nil { + return x.ActionsListIndex + } + return 0 +} + +// InvokeActionTrigger indicates the action was triggered by the invoke command +// on the CLI. +type PlannedChange_InvokeActionTrigger struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PlannedChange_InvokeActionTrigger) Reset() { + *x = PlannedChange_InvokeActionTrigger{} + mi := &file_stacks_proto_msgTypes[88] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PlannedChange_InvokeActionTrigger) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlannedChange_InvokeActionTrigger) ProtoMessage() {} + +func (x *PlannedChange_InvokeActionTrigger) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[88] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlannedChange_InvokeActionTrigger.ProtoReflect.Descriptor instead. +func (*PlannedChange_InvokeActionTrigger) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{23, 9} +} + type PlannedChange_ResourceInstance_Index struct { state protoimpl.MessageState `protogen:"open.v1"` Value *DynamicValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` @@ -4901,7 +5428,7 @@ type PlannedChange_ResourceInstance_Index struct { func (x *PlannedChange_ResourceInstance_Index) Reset() { *x = PlannedChange_ResourceInstance_Index{} - mi := &file_stacks_proto_msgTypes[84] + mi := &file_stacks_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4913,7 +5440,7 @@ func (x *PlannedChange_ResourceInstance_Index) String() string { func (*PlannedChange_ResourceInstance_Index) ProtoMessage() {} func (x *PlannedChange_ResourceInstance_Index) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[84] + mi := &file_stacks_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4926,7 +5453,7 @@ func (x *PlannedChange_ResourceInstance_Index) ProtoReflect() protoreflect.Messa // Deprecated: Use PlannedChange_ResourceInstance_Index.ProtoReflect.Descriptor instead. func (*PlannedChange_ResourceInstance_Index) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22, 2, 0} + return file_stacks_proto_rawDescGZIP(), []int{23, 2, 0} } func (x *PlannedChange_ResourceInstance_Index) GetValue() *DynamicValue { @@ -4952,7 +5479,7 @@ type PlannedChange_ResourceInstance_Moved struct { func (x *PlannedChange_ResourceInstance_Moved) Reset() { *x = PlannedChange_ResourceInstance_Moved{} - mi := &file_stacks_proto_msgTypes[85] + mi := &file_stacks_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4964,7 +5491,7 @@ func (x *PlannedChange_ResourceInstance_Moved) String() string { func (*PlannedChange_ResourceInstance_Moved) ProtoMessage() {} func (x *PlannedChange_ResourceInstance_Moved) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[85] + mi := &file_stacks_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4977,7 +5504,7 @@ func (x *PlannedChange_ResourceInstance_Moved) ProtoReflect() protoreflect.Messa // Deprecated: Use PlannedChange_ResourceInstance_Moved.ProtoReflect.Descriptor instead. func (*PlannedChange_ResourceInstance_Moved) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22, 2, 1} + return file_stacks_proto_rawDescGZIP(), []int{23, 2, 1} } func (x *PlannedChange_ResourceInstance_Moved) GetPrevAddr() *ResourceInstanceInStackAddr { @@ -4998,7 +5525,7 @@ type PlannedChange_ResourceInstance_Imported struct { func (x *PlannedChange_ResourceInstance_Imported) Reset() { *x = PlannedChange_ResourceInstance_Imported{} - mi := &file_stacks_proto_msgTypes[86] + mi := &file_stacks_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5010,7 +5537,7 @@ func (x *PlannedChange_ResourceInstance_Imported) String() string { func (*PlannedChange_ResourceInstance_Imported) ProtoMessage() {} func (x *PlannedChange_ResourceInstance_Imported) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[86] + mi := &file_stacks_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5023,7 +5550,7 @@ func (x *PlannedChange_ResourceInstance_Imported) ProtoReflect() protoreflect.Me // Deprecated: Use PlannedChange_ResourceInstance_Imported.ProtoReflect.Descriptor instead. func (*PlannedChange_ResourceInstance_Imported) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{22, 2, 2} + return file_stacks_proto_rawDescGZIP(), []int{23, 2, 2} } func (x *PlannedChange_ResourceInstance_Imported) GetImportId() string { @@ -5057,7 +5584,7 @@ type AppliedChange_RawChange struct { func (x *AppliedChange_RawChange) Reset() { *x = AppliedChange_RawChange{} - mi := &file_stacks_proto_msgTypes[87] + mi := &file_stacks_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5069,7 +5596,7 @@ func (x *AppliedChange_RawChange) String() string { func (*AppliedChange_RawChange) ProtoMessage() {} func (x *AppliedChange_RawChange) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[87] + mi := &file_stacks_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5082,7 +5609,7 @@ func (x *AppliedChange_RawChange) ProtoReflect() protoreflect.Message { // Deprecated: Use AppliedChange_RawChange.ProtoReflect.Descriptor instead. func (*AppliedChange_RawChange) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{24, 0} + return file_stacks_proto_rawDescGZIP(), []int{25, 0} } func (x *AppliedChange_RawChange) GetKey() string { @@ -5117,7 +5644,7 @@ type AppliedChange_ChangeDescription struct { func (x *AppliedChange_ChangeDescription) Reset() { *x = AppliedChange_ChangeDescription{} - mi := &file_stacks_proto_msgTypes[88] + mi := &file_stacks_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5129,7 +5656,7 @@ func (x *AppliedChange_ChangeDescription) String() string { func (*AppliedChange_ChangeDescription) ProtoMessage() {} func (x *AppliedChange_ChangeDescription) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[88] + mi := &file_stacks_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5142,7 +5669,7 @@ func (x *AppliedChange_ChangeDescription) ProtoReflect() protoreflect.Message { // Deprecated: Use AppliedChange_ChangeDescription.ProtoReflect.Descriptor instead. func (*AppliedChange_ChangeDescription) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{24, 1} + return file_stacks_proto_rawDescGZIP(), []int{25, 1} } func (x *AppliedChange_ChangeDescription) GetKey() string { @@ -5291,7 +5818,7 @@ type AppliedChange_ResourceInstance struct { func (x *AppliedChange_ResourceInstance) Reset() { *x = AppliedChange_ResourceInstance{} - mi := &file_stacks_proto_msgTypes[89] + mi := &file_stacks_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5303,7 +5830,7 @@ func (x *AppliedChange_ResourceInstance) String() string { func (*AppliedChange_ResourceInstance) ProtoMessage() {} func (x *AppliedChange_ResourceInstance) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[89] + mi := &file_stacks_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5316,7 +5843,7 @@ func (x *AppliedChange_ResourceInstance) ProtoReflect() protoreflect.Message { // Deprecated: Use AppliedChange_ResourceInstance.ProtoReflect.Descriptor instead. func (*AppliedChange_ResourceInstance) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{24, 2} + return file_stacks_proto_rawDescGZIP(), []int{25, 2} } func (x *AppliedChange_ResourceInstance) GetAddr() *ResourceInstanceObjectInStackAddr { @@ -5372,7 +5899,7 @@ type AppliedChange_ComponentInstance struct { func (x *AppliedChange_ComponentInstance) Reset() { *x = AppliedChange_ComponentInstance{} - mi := &file_stacks_proto_msgTypes[90] + mi := &file_stacks_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5384,7 +5911,7 @@ func (x *AppliedChange_ComponentInstance) String() string { func (*AppliedChange_ComponentInstance) ProtoMessage() {} func (x *AppliedChange_ComponentInstance) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[90] + mi := &file_stacks_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5397,7 +5924,7 @@ func (x *AppliedChange_ComponentInstance) ProtoReflect() protoreflect.Message { // Deprecated: Use AppliedChange_ComponentInstance.ProtoReflect.Descriptor instead. func (*AppliedChange_ComponentInstance) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{24, 3} + return file_stacks_proto_rawDescGZIP(), []int{25, 3} } func (x *AppliedChange_ComponentInstance) GetComponentAddr() string { @@ -5431,7 +5958,7 @@ type AppliedChange_OutputValue struct { func (x *AppliedChange_OutputValue) Reset() { *x = AppliedChange_OutputValue{} - mi := &file_stacks_proto_msgTypes[91] + mi := &file_stacks_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5443,7 +5970,7 @@ func (x *AppliedChange_OutputValue) String() string { func (*AppliedChange_OutputValue) ProtoMessage() {} func (x *AppliedChange_OutputValue) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[91] + mi := &file_stacks_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5456,7 +5983,7 @@ func (x *AppliedChange_OutputValue) ProtoReflect() protoreflect.Message { // Deprecated: Use AppliedChange_OutputValue.ProtoReflect.Descriptor instead. func (*AppliedChange_OutputValue) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{24, 4} + return file_stacks_proto_rawDescGZIP(), []int{25, 4} } func (x *AppliedChange_OutputValue) GetName() string { @@ -5483,7 +6010,7 @@ type AppliedChange_InputVariable struct { func (x *AppliedChange_InputVariable) Reset() { *x = AppliedChange_InputVariable{} - mi := &file_stacks_proto_msgTypes[92] + mi := &file_stacks_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5495,7 +6022,7 @@ func (x *AppliedChange_InputVariable) String() string { func (*AppliedChange_InputVariable) ProtoMessage() {} func (x *AppliedChange_InputVariable) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[92] + mi := &file_stacks_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5508,7 +6035,7 @@ func (x *AppliedChange_InputVariable) ProtoReflect() protoreflect.Message { // Deprecated: Use AppliedChange_InputVariable.ProtoReflect.Descriptor instead. func (*AppliedChange_InputVariable) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{24, 5} + return file_stacks_proto_rawDescGZIP(), []int{25, 5} } func (x *AppliedChange_InputVariable) GetName() string { @@ -5533,7 +6060,7 @@ type AppliedChange_Nothing struct { func (x *AppliedChange_Nothing) Reset() { *x = AppliedChange_Nothing{} - mi := &file_stacks_proto_msgTypes[93] + mi := &file_stacks_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5545,7 +6072,7 @@ func (x *AppliedChange_Nothing) String() string { func (*AppliedChange_Nothing) ProtoMessage() {} func (x *AppliedChange_Nothing) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[93] + mi := &file_stacks_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5558,7 +6085,7 @@ func (x *AppliedChange_Nothing) ProtoReflect() protoreflect.Message { // Deprecated: Use AppliedChange_Nothing.ProtoReflect.Descriptor instead. func (*AppliedChange_Nothing) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{24, 6} + return file_stacks_proto_rawDescGZIP(), []int{25, 6} } // ComponentInstanceStatus describes the current status of a component instance @@ -5573,7 +6100,7 @@ type StackChangeProgress_ComponentInstanceStatus struct { func (x *StackChangeProgress_ComponentInstanceStatus) Reset() { *x = StackChangeProgress_ComponentInstanceStatus{} - mi := &file_stacks_proto_msgTypes[95] + mi := &file_stacks_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5585,7 +6112,7 @@ func (x *StackChangeProgress_ComponentInstanceStatus) String() string { func (*StackChangeProgress_ComponentInstanceStatus) ProtoMessage() {} func (x *StackChangeProgress_ComponentInstanceStatus) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[95] + mi := &file_stacks_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5598,7 +6125,7 @@ func (x *StackChangeProgress_ComponentInstanceStatus) ProtoReflect() protoreflec // Deprecated: Use StackChangeProgress_ComponentInstanceStatus.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ComponentInstanceStatus) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 0} + return file_stacks_proto_rawDescGZIP(), []int{26, 0} } func (x *StackChangeProgress_ComponentInstanceStatus) GetAddr() *ComponentInstanceInStackAddr { @@ -5628,7 +6155,7 @@ type StackChangeProgress_ResourceInstanceStatus struct { func (x *StackChangeProgress_ResourceInstanceStatus) Reset() { *x = StackChangeProgress_ResourceInstanceStatus{} - mi := &file_stacks_proto_msgTypes[96] + mi := &file_stacks_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5640,7 +6167,7 @@ func (x *StackChangeProgress_ResourceInstanceStatus) String() string { func (*StackChangeProgress_ResourceInstanceStatus) ProtoMessage() {} func (x *StackChangeProgress_ResourceInstanceStatus) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[96] + mi := &file_stacks_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5653,7 +6180,7 @@ func (x *StackChangeProgress_ResourceInstanceStatus) ProtoReflect() protoreflect // Deprecated: Use StackChangeProgress_ResourceInstanceStatus.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ResourceInstanceStatus) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 1} + return file_stacks_proto_rawDescGZIP(), []int{26, 1} } func (x *StackChangeProgress_ResourceInstanceStatus) GetAddr() *ResourceInstanceObjectInStackAddr { @@ -5695,7 +6222,7 @@ type StackChangeProgress_ResourceInstancePlannedChange struct { func (x *StackChangeProgress_ResourceInstancePlannedChange) Reset() { *x = StackChangeProgress_ResourceInstancePlannedChange{} - mi := &file_stacks_proto_msgTypes[97] + mi := &file_stacks_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5707,7 +6234,7 @@ func (x *StackChangeProgress_ResourceInstancePlannedChange) String() string { func (*StackChangeProgress_ResourceInstancePlannedChange) ProtoMessage() {} func (x *StackChangeProgress_ResourceInstancePlannedChange) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[97] + mi := &file_stacks_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5720,7 +6247,7 @@ func (x *StackChangeProgress_ResourceInstancePlannedChange) ProtoReflect() proto // Deprecated: Use StackChangeProgress_ResourceInstancePlannedChange.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ResourceInstancePlannedChange) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 2} + return file_stacks_proto_rawDescGZIP(), []int{26, 2} } func (x *StackChangeProgress_ResourceInstancePlannedChange) GetAddr() *ResourceInstanceObjectInStackAddr { @@ -5770,7 +6297,7 @@ type StackChangeProgress_DeferredResourceInstancePlannedChange struct { func (x *StackChangeProgress_DeferredResourceInstancePlannedChange) Reset() { *x = StackChangeProgress_DeferredResourceInstancePlannedChange{} - mi := &file_stacks_proto_msgTypes[98] + mi := &file_stacks_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5782,7 +6309,7 @@ func (x *StackChangeProgress_DeferredResourceInstancePlannedChange) String() str func (*StackChangeProgress_DeferredResourceInstancePlannedChange) ProtoMessage() {} func (x *StackChangeProgress_DeferredResourceInstancePlannedChange) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[98] + mi := &file_stacks_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5795,7 +6322,7 @@ func (x *StackChangeProgress_DeferredResourceInstancePlannedChange) ProtoReflect // Deprecated: Use StackChangeProgress_DeferredResourceInstancePlannedChange.ProtoReflect.Descriptor instead. func (*StackChangeProgress_DeferredResourceInstancePlannedChange) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 3} + return file_stacks_proto_rawDescGZIP(), []int{26, 3} } func (x *StackChangeProgress_DeferredResourceInstancePlannedChange) GetDeferred() *Deferred { @@ -5812,6 +6339,214 @@ func (x *StackChangeProgress_DeferredResourceInstancePlannedChange) GetChange() return nil } +type StackChangeProgress_ActionInvocationPlanned struct { + state protoimpl.MessageState `protogen:"open.v1"` + Addr *ActionInvocationInstanceInStackAddr `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` + ProviderAddr string `protobuf:"bytes,2,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + // Types that are valid to be assigned to ActionTrigger: + // + // *StackChangeProgress_ActionInvocationPlanned_LifecycleActionTrigger + // *StackChangeProgress_ActionInvocationPlanned_InvokeActionTrigger + ActionTrigger isStackChangeProgress_ActionInvocationPlanned_ActionTrigger `protobuf_oneof:"action_trigger"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StackChangeProgress_ActionInvocationPlanned) Reset() { + *x = StackChangeProgress_ActionInvocationPlanned{} + mi := &file_stacks_proto_msgTypes[104] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StackChangeProgress_ActionInvocationPlanned) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackChangeProgress_ActionInvocationPlanned) ProtoMessage() {} + +func (x *StackChangeProgress_ActionInvocationPlanned) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[104] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackChangeProgress_ActionInvocationPlanned.ProtoReflect.Descriptor instead. +func (*StackChangeProgress_ActionInvocationPlanned) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{26, 4} +} + +func (x *StackChangeProgress_ActionInvocationPlanned) GetAddr() *ActionInvocationInstanceInStackAddr { + if x != nil { + return x.Addr + } + return nil +} + +func (x *StackChangeProgress_ActionInvocationPlanned) GetProviderAddr() string { + if x != nil { + return x.ProviderAddr + } + return "" +} + +func (x *StackChangeProgress_ActionInvocationPlanned) GetActionTrigger() isStackChangeProgress_ActionInvocationPlanned_ActionTrigger { + if x != nil { + return x.ActionTrigger + } + return nil +} + +func (x *StackChangeProgress_ActionInvocationPlanned) GetLifecycleActionTrigger() *StackChangeProgress_LifecycleActionTrigger { + if x != nil { + if x, ok := x.ActionTrigger.(*StackChangeProgress_ActionInvocationPlanned_LifecycleActionTrigger); ok { + return x.LifecycleActionTrigger + } + } + return nil +} + +func (x *StackChangeProgress_ActionInvocationPlanned) GetInvokeActionTrigger() *StackChangeProgress_InvokeActionTrigger { + if x != nil { + if x, ok := x.ActionTrigger.(*StackChangeProgress_ActionInvocationPlanned_InvokeActionTrigger); ok { + return x.InvokeActionTrigger + } + } + return nil +} + +type isStackChangeProgress_ActionInvocationPlanned_ActionTrigger interface { + isStackChangeProgress_ActionInvocationPlanned_ActionTrigger() +} + +type StackChangeProgress_ActionInvocationPlanned_LifecycleActionTrigger struct { + LifecycleActionTrigger *StackChangeProgress_LifecycleActionTrigger `protobuf:"bytes,3,opt,name=lifecycle_action_trigger,json=lifecycleActionTrigger,proto3,oneof"` +} + +type StackChangeProgress_ActionInvocationPlanned_InvokeActionTrigger struct { + InvokeActionTrigger *StackChangeProgress_InvokeActionTrigger `protobuf:"bytes,4,opt,name=invoke_action_trigger,json=invokeActionTrigger,proto3,oneof"` +} + +func (*StackChangeProgress_ActionInvocationPlanned_LifecycleActionTrigger) isStackChangeProgress_ActionInvocationPlanned_ActionTrigger() { +} + +func (*StackChangeProgress_ActionInvocationPlanned_InvokeActionTrigger) isStackChangeProgress_ActionInvocationPlanned_ActionTrigger() { +} + +// LifecycleActionTrigger contains details on the conditions that led to the +// triggering of an action. +type StackChangeProgress_LifecycleActionTrigger struct { + state protoimpl.MessageState `protogen:"open.v1"` + TriggeringResourceAddress *ResourceInstanceInStackAddr `protobuf:"bytes,1,opt,name=triggering_resource_address,json=triggeringResourceAddress,proto3" json:"triggering_resource_address,omitempty"` + TriggerEvent StackChangeProgress_ActionTriggerEvent `protobuf:"varint,2,opt,name=trigger_event,json=triggerEvent,proto3,enum=terraform1.stacks.StackChangeProgress_ActionTriggerEvent" json:"trigger_event,omitempty"` + ActionTriggerBlockIndex int64 `protobuf:"varint,3,opt,name=action_trigger_block_index,json=actionTriggerBlockIndex,proto3" json:"action_trigger_block_index,omitempty"` + ActionsListIndex int64 `protobuf:"varint,4,opt,name=actions_list_index,json=actionsListIndex,proto3" json:"actions_list_index,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StackChangeProgress_LifecycleActionTrigger) Reset() { + *x = StackChangeProgress_LifecycleActionTrigger{} + mi := &file_stacks_proto_msgTypes[105] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StackChangeProgress_LifecycleActionTrigger) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackChangeProgress_LifecycleActionTrigger) ProtoMessage() {} + +func (x *StackChangeProgress_LifecycleActionTrigger) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[105] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackChangeProgress_LifecycleActionTrigger.ProtoReflect.Descriptor instead. +func (*StackChangeProgress_LifecycleActionTrigger) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{26, 5} +} + +func (x *StackChangeProgress_LifecycleActionTrigger) GetTriggeringResourceAddress() *ResourceInstanceInStackAddr { + if x != nil { + return x.TriggeringResourceAddress + } + return nil +} + +func (x *StackChangeProgress_LifecycleActionTrigger) GetTriggerEvent() StackChangeProgress_ActionTriggerEvent { + if x != nil { + return x.TriggerEvent + } + return StackChangeProgress_INVALID_EVENT +} + +func (x *StackChangeProgress_LifecycleActionTrigger) GetActionTriggerBlockIndex() int64 { + if x != nil { + return x.ActionTriggerBlockIndex + } + return 0 +} + +func (x *StackChangeProgress_LifecycleActionTrigger) GetActionsListIndex() int64 { + if x != nil { + return x.ActionsListIndex + } + return 0 +} + +// InvokeActionTrigger indicates the action was triggered by the invoke command +// on the CLI. +type StackChangeProgress_InvokeActionTrigger struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StackChangeProgress_InvokeActionTrigger) Reset() { + *x = StackChangeProgress_InvokeActionTrigger{} + mi := &file_stacks_proto_msgTypes[106] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StackChangeProgress_InvokeActionTrigger) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackChangeProgress_InvokeActionTrigger) ProtoMessage() {} + +func (x *StackChangeProgress_InvokeActionTrigger) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[106] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackChangeProgress_InvokeActionTrigger.ProtoReflect.Descriptor instead. +func (*StackChangeProgress_InvokeActionTrigger) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{26, 6} +} + // ProvisionerStatus represents the progress of a given provisioner during its // resource instance's apply operation. type StackChangeProgress_ProvisionerStatus struct { @@ -5825,7 +6560,7 @@ type StackChangeProgress_ProvisionerStatus struct { func (x *StackChangeProgress_ProvisionerStatus) Reset() { *x = StackChangeProgress_ProvisionerStatus{} - mi := &file_stacks_proto_msgTypes[99] + mi := &file_stacks_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5837,7 +6572,7 @@ func (x *StackChangeProgress_ProvisionerStatus) String() string { func (*StackChangeProgress_ProvisionerStatus) ProtoMessage() {} func (x *StackChangeProgress_ProvisionerStatus) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[99] + mi := &file_stacks_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5850,7 +6585,7 @@ func (x *StackChangeProgress_ProvisionerStatus) ProtoReflect() protoreflect.Mess // Deprecated: Use StackChangeProgress_ProvisionerStatus.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ProvisionerStatus) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 4} + return file_stacks_proto_rawDescGZIP(), []int{26, 7} } func (x *StackChangeProgress_ProvisionerStatus) GetAddr() *ResourceInstanceObjectInStackAddr { @@ -5887,7 +6622,7 @@ type StackChangeProgress_ProvisionerOutput struct { func (x *StackChangeProgress_ProvisionerOutput) Reset() { *x = StackChangeProgress_ProvisionerOutput{} - mi := &file_stacks_proto_msgTypes[100] + mi := &file_stacks_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5899,7 +6634,7 @@ func (x *StackChangeProgress_ProvisionerOutput) String() string { func (*StackChangeProgress_ProvisionerOutput) ProtoMessage() {} func (x *StackChangeProgress_ProvisionerOutput) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[100] + mi := &file_stacks_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5912,7 +6647,7 @@ func (x *StackChangeProgress_ProvisionerOutput) ProtoReflect() protoreflect.Mess // Deprecated: Use StackChangeProgress_ProvisionerOutput.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ProvisionerOutput) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 5} + return file_stacks_proto_rawDescGZIP(), []int{26, 8} } func (x *StackChangeProgress_ProvisionerOutput) GetAddr() *ResourceInstanceObjectInStackAddr { @@ -5962,7 +6697,7 @@ type StackChangeProgress_ComponentInstanceChanges struct { func (x *StackChangeProgress_ComponentInstanceChanges) Reset() { *x = StackChangeProgress_ComponentInstanceChanges{} - mi := &file_stacks_proto_msgTypes[101] + mi := &file_stacks_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5974,7 +6709,7 @@ func (x *StackChangeProgress_ComponentInstanceChanges) String() string { func (*StackChangeProgress_ComponentInstanceChanges) ProtoMessage() {} func (x *StackChangeProgress_ComponentInstanceChanges) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[101] + mi := &file_stacks_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5987,7 +6722,7 @@ func (x *StackChangeProgress_ComponentInstanceChanges) ProtoReflect() protorefle // Deprecated: Use StackChangeProgress_ComponentInstanceChanges.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ComponentInstanceChanges) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 6} + return file_stacks_proto_rawDescGZIP(), []int{26, 9} } func (x *StackChangeProgress_ComponentInstanceChanges) GetAddr() *ComponentInstanceInStackAddr { @@ -6065,7 +6800,7 @@ type StackChangeProgress_ComponentInstances struct { func (x *StackChangeProgress_ComponentInstances) Reset() { *x = StackChangeProgress_ComponentInstances{} - mi := &file_stacks_proto_msgTypes[102] + mi := &file_stacks_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6077,7 +6812,7 @@ func (x *StackChangeProgress_ComponentInstances) String() string { func (*StackChangeProgress_ComponentInstances) ProtoMessage() {} func (x *StackChangeProgress_ComponentInstances) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[102] + mi := &file_stacks_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6090,7 +6825,7 @@ func (x *StackChangeProgress_ComponentInstances) ProtoReflect() protoreflect.Mes // Deprecated: Use StackChangeProgress_ComponentInstances.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ComponentInstances) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 7} + return file_stacks_proto_rawDescGZIP(), []int{26, 10} } func (x *StackChangeProgress_ComponentInstances) GetComponentAddr() string { @@ -6116,7 +6851,7 @@ type StackChangeProgress_ResourceInstancePlannedChange_Moved struct { func (x *StackChangeProgress_ResourceInstancePlannedChange_Moved) Reset() { *x = StackChangeProgress_ResourceInstancePlannedChange_Moved{} - mi := &file_stacks_proto_msgTypes[103] + mi := &file_stacks_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6128,7 +6863,7 @@ func (x *StackChangeProgress_ResourceInstancePlannedChange_Moved) String() strin func (*StackChangeProgress_ResourceInstancePlannedChange_Moved) ProtoMessage() {} func (x *StackChangeProgress_ResourceInstancePlannedChange_Moved) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[103] + mi := &file_stacks_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6141,7 +6876,7 @@ func (x *StackChangeProgress_ResourceInstancePlannedChange_Moved) ProtoReflect() // Deprecated: Use StackChangeProgress_ResourceInstancePlannedChange_Moved.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ResourceInstancePlannedChange_Moved) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 2, 0} + return file_stacks_proto_rawDescGZIP(), []int{26, 2, 0} } func (x *StackChangeProgress_ResourceInstancePlannedChange_Moved) GetPrevAddr() *ResourceInstanceInStackAddr { @@ -6161,7 +6896,7 @@ type StackChangeProgress_ResourceInstancePlannedChange_Imported struct { func (x *StackChangeProgress_ResourceInstancePlannedChange_Imported) Reset() { *x = StackChangeProgress_ResourceInstancePlannedChange_Imported{} - mi := &file_stacks_proto_msgTypes[104] + mi := &file_stacks_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6173,7 +6908,7 @@ func (x *StackChangeProgress_ResourceInstancePlannedChange_Imported) String() st func (*StackChangeProgress_ResourceInstancePlannedChange_Imported) ProtoMessage() {} func (x *StackChangeProgress_ResourceInstancePlannedChange_Imported) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[104] + mi := &file_stacks_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6186,7 +6921,7 @@ func (x *StackChangeProgress_ResourceInstancePlannedChange_Imported) ProtoReflec // Deprecated: Use StackChangeProgress_ResourceInstancePlannedChange_Imported.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ResourceInstancePlannedChange_Imported) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{25, 2, 1} + return file_stacks_proto_rawDescGZIP(), []int{26, 2, 1} } func (x *StackChangeProgress_ResourceInstancePlannedChange_Imported) GetImportId() string { @@ -6214,7 +6949,7 @@ type ListResourceIdentities_Request struct { func (x *ListResourceIdentities_Request) Reset() { *x = ListResourceIdentities_Request{} - mi := &file_stacks_proto_msgTypes[105] + mi := &file_stacks_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6226,7 +6961,7 @@ func (x *ListResourceIdentities_Request) String() string { func (*ListResourceIdentities_Request) ProtoMessage() {} func (x *ListResourceIdentities_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[105] + mi := &file_stacks_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6239,7 +6974,7 @@ func (x *ListResourceIdentities_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use ListResourceIdentities_Request.ProtoReflect.Descriptor instead. func (*ListResourceIdentities_Request) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 0} + return file_stacks_proto_rawDescGZIP(), []int{27, 0} } func (x *ListResourceIdentities_Request) GetStateHandle() int64 { @@ -6272,7 +7007,7 @@ type ListResourceIdentities_Response struct { func (x *ListResourceIdentities_Response) Reset() { *x = ListResourceIdentities_Response{} - mi := &file_stacks_proto_msgTypes[106] + mi := &file_stacks_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6284,7 +7019,7 @@ func (x *ListResourceIdentities_Response) String() string { func (*ListResourceIdentities_Response) ProtoMessage() {} func (x *ListResourceIdentities_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[106] + mi := &file_stacks_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6297,7 +7032,7 @@ func (x *ListResourceIdentities_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use ListResourceIdentities_Response.ProtoReflect.Descriptor instead. func (*ListResourceIdentities_Response) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 1} + return file_stacks_proto_rawDescGZIP(), []int{27, 1} } func (x *ListResourceIdentities_Response) GetResource() []*ListResourceIdentities_Resource { @@ -6323,7 +7058,7 @@ type ListResourceIdentities_Resource struct { func (x *ListResourceIdentities_Resource) Reset() { *x = ListResourceIdentities_Resource{} - mi := &file_stacks_proto_msgTypes[107] + mi := &file_stacks_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6335,7 +7070,7 @@ func (x *ListResourceIdentities_Resource) String() string { func (*ListResourceIdentities_Resource) ProtoMessage() {} func (x *ListResourceIdentities_Resource) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[107] + mi := &file_stacks_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6348,7 +7083,7 @@ func (x *ListResourceIdentities_Resource) ProtoReflect() protoreflect.Message { // Deprecated: Use ListResourceIdentities_Resource.ProtoReflect.Descriptor instead. func (*ListResourceIdentities_Resource) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 2} + return file_stacks_proto_rawDescGZIP(), []int{27, 2} } func (x *ListResourceIdentities_Resource) GetComponentAddr() string { @@ -6614,7 +7349,10 @@ const file_stacks_proto_rawDesc = "" + "\bselector\"}\n" + "\x1cComponentInstanceInStackAddr\x12%\n" + "\x0ecomponent_addr\x18\x01 \x01(\tR\rcomponentAddr\x126\n" + - "\x17component_instance_addr\x18\x02 \x01(\tR\x15componentInstanceAddr\"\x8b\x01\n" + + "\x17component_instance_addr\x18\x02 \x01(\tR\x15componentInstanceAddr\"\xa4\x01\n" + + "#ActionInvocationInstanceInStackAddr\x126\n" + + "\x17component_instance_addr\x18\x01 \x01(\tR\x15componentInstanceAddr\x12E\n" + + "\x1faction_invocation_instance_addr\x18\x02 \x01(\tR\x1cactionInvocationInstanceAddr\"\x8b\x01\n" + "\x1bResourceInstanceInStackAddr\x126\n" + "\x17component_instance_addr\x18\x01 \x01(\tR\x15componentInstanceAddr\x124\n" + "\x16resource_instance_addr\x18\x02 \x01(\tR\x14resourceInstanceAddr\"\xb2\x01\n" + @@ -6622,17 +7360,19 @@ const file_stacks_proto_rawDesc = "" + "\x17component_instance_addr\x18\x01 \x01(\tR\x15componentInstanceAddr\x124\n" + "\x16resource_instance_addr\x18\x02 \x01(\tR\x14resourceInstanceAddr\x12\x1f\n" + "\vdeposed_key\x18\x03 \x01(\tR\n" + - "deposedKey\"\x9c\x15\n" + + "deposedKey\"\xc2 \n" + "\rPlannedChange\x12&\n" + "\x03raw\x18\x01 \x03(\v2\x14.google.protobuf.AnyR\x03raw\x12V\n" + - "\fdescriptions\x18\x02 \x03(\v22.terraform1.stacks.PlannedChange.ChangeDescriptionR\fdescriptions\x1a\xf5\x04\n" + + "\fdescriptions\x18\x02 \x03(\v22.terraform1.stacks.PlannedChange.ChangeDescriptionR\fdescriptions\x1a\xe9\x06\n" + "\x11ChangeDescription\x12r\n" + "\x1acomponent_instance_planned\x18\x01 \x01(\v22.terraform1.stacks.PlannedChange.ComponentInstanceH\x00R\x18componentInstancePlanned\x12o\n" + "\x19resource_instance_planned\x18\x02 \x01(\v21.terraform1.stacks.PlannedChange.ResourceInstanceH\x00R\x17resourceInstancePlanned\x12`\n" + "\x14output_value_planned\x18\x03 \x01(\v2,.terraform1.stacks.PlannedChange.OutputValueH\x00R\x12outputValuePlanned\x12'\n" + "\x0eplan_applyable\x18\x04 \x01(\bH\x00R\rplanApplyable\x12y\n" + "\x1aresource_instance_deferred\x18\x05 \x01(\v29.terraform1.stacks.PlannedChange.ResourceInstanceDeferredH\x00R\x18resourceInstanceDeferred\x12f\n" + - "\x16input_variable_planned\x18\x06 \x01(\v2..terraform1.stacks.PlannedChange.InputVariableH\x00R\x14inputVariablePlannedB\r\n" + + "\x16input_variable_planned\x18\x06 \x01(\v2..terraform1.stacks.PlannedChange.InputVariableH\x00R\x14inputVariablePlanned\x12w\n" + + "\x19action_invocation_planned\x18\a \x01(\v29.terraform1.stacks.PlannedChange.ActionInvocationInstanceH\x00R\x17actionInvocationPlanned\x12y\n" + + "\x1aaction_invocation_deferred\x18\b \x01(\v29.terraform1.stacks.PlannedChange.ActionInvocationDeferredH\x00R\x18actionInvocationDeferredB\r\n" + "\vdescription\x1a\xb6\x01\n" + "\x11ComponentInstance\x12C\n" + "\x04addr\x18\x01 \x01(\v2/.terraform1.stacks.ComponentInstanceInStackAddrR\x04addr\x127\n" + @@ -6676,7 +7416,35 @@ const file_stacks_proto_rawDesc = "" + "\x04name\x18\x01 \x01(\tR\x04name\x127\n" + "\aactions\x18\x02 \x03(\x0e2\x1d.terraform1.stacks.ChangeTypeR\aactions\x12=\n" + "\x06values\x18\x03 \x01(\v2%.terraform1.stacks.DynamicValueChangeR\x06values\x122\n" + - "\x15required_during_apply\x18\x04 \x01(\bR\x13requiredDuringApplyJ\x04\b\x03\x10\a\"\xdc\x01\n" + + "\x15required_during_apply\x18\x04 \x01(\bR\x13requiredDuringApply\x1a\xe3\x03\n" + + "\x18ActionInvocationInstance\x12J\n" + + "\x04addr\x18\x01 \x01(\v26.terraform1.stacks.ActionInvocationInstanceInStackAddrR\x04addr\x12#\n" + + "\rprovider_addr\x18\x02 \x01(\tR\fproviderAddr\x12\x1f\n" + + "\vaction_type\x18\x03 \x01(\tR\n" + + "actionType\x12B\n" + + "\fconfig_value\x18\x04 \x01(\v2\x1f.terraform1.stacks.DynamicValueR\vconfigValue\x12s\n" + + "\x18lifecycle_action_trigger\x18\x06 \x01(\v27.terraform1.stacks.PlannedChange.LifecycleActionTriggerH\x00R\x16lifecycleActionTrigger\x12j\n" + + "\x15invoke_action_trigger\x18\a \x01(\v24.terraform1.stacks.PlannedChange.InvokeActionTriggerH\x00R\x13invokeActionTriggerB\x10\n" + + "\x0eaction_trigger\x1a\xbb\x01\n" + + "\x18ActionInvocationDeferred\x127\n" + + "\bdeferred\x18\x01 \x01(\v2\x1b.terraform1.stacks.DeferredR\bdeferred\x12f\n" + + "\x11action_invocation\x18\x02 \x01(\v29.terraform1.stacks.PlannedChange.ActionInvocationInstanceR\x10actionInvocation\x1a\xcd\x02\n" + + "\x16LifecycleActionTrigger\x12n\n" + + "\x1btriggering_resource_address\x18\x01 \x01(\v2..terraform1.stacks.ResourceInstanceInStackAddrR\x19triggeringResourceAddress\x12X\n" + + "\rtrigger_event\x18\x02 \x01(\x0e23.terraform1.stacks.PlannedChange.ActionTriggerEventR\ftriggerEvent\x12;\n" + + "\x1aaction_trigger_block_index\x18\x03 \x01(\x03R\x17actionTriggerBlockIndex\x12,\n" + + "\x12actions_list_index\x18\x04 \x01(\x03R\x10actionsListIndex\x1a\x15\n" + + "\x13InvokeActionTrigger\"\xa4\x01\n" + + "\x12ActionTriggerEvent\x12\x11\n" + + "\rINVALID_EVENT\x10\x00\x12\x11\n" + + "\rBEFORE_CREATE\x10\x01\x12\x10\n" + + "\fAFTER_CREATE\x10\x02\x12\x11\n" + + "\rBEFORE_UPDATE\x10\x03\x12\x10\n" + + "\fAFTER_UPDATE\x10\x04\x12\x12\n" + + "\x0eBEFORE_DESTROY\x10\x05\x12\x11\n" + + "\rAFTER_DESTROY\x10\x06\x12\n" + + "\n" + + "\x06INVOKE\x10\aJ\x04\b\x03\x10\a\"\xdc\x01\n" + "\bDeferred\x12:\n" + "\x06reason\x18\x01 \x01(\x0e2\".terraform1.stacks.Deferred.ReasonR\x06reason\"\x93\x01\n" + "\x06Reason\x12\v\n" + @@ -6721,7 +7489,7 @@ const file_stacks_proto_rawDesc = "" + "\rInputVariable\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12<\n" + "\tnew_value\x18\x02 \x01(\v2\x1f.terraform1.stacks.DynamicValueR\bnewValue\x1a\t\n" + - "\aNothing\"\xbf\x19\n" + + "\aNothing\"\xdd!\n" + "\x13StackChangeProgress\x12|\n" + "\x19component_instance_status\x18\x01 \x01(\v2>.terraform1.stacks.StackChangeProgress.ComponentInstanceStatusH\x00R\x17componentInstanceStatus\x12y\n" + "\x18resource_instance_status\x18\x02 \x01(\v2=.terraform1.stacks.StackChangeProgress.ResourceInstanceStatusH\x00R\x16resourceInstanceStatus\x12\x8f\x01\n" + @@ -6730,7 +7498,8 @@ const file_stacks_proto_rawDesc = "" + "\x12provisioner_output\x18\x05 \x01(\v28.terraform1.stacks.StackChangeProgress.ProvisionerOutputH\x00R\x11provisionerOutput\x12\x7f\n" + "\x1acomponent_instance_changes\x18\x06 \x01(\v2?.terraform1.stacks.StackChangeProgress.ComponentInstanceChangesH\x00R\x18componentInstanceChanges\x12l\n" + "\x13component_instances\x18\a \x01(\v29.terraform1.stacks.StackChangeProgress.ComponentInstancesH\x00R\x12componentInstances\x12\xa8\x01\n" + - ")deferred_resource_instance_planned_change\x18\b \x01(\v2L.terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChangeH\x00R%deferredResourceInstancePlannedChange\x1a\xb2\x02\n" + + ")deferred_resource_instance_planned_change\x18\b \x01(\v2L.terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChangeH\x00R%deferredResourceInstancePlannedChange\x12|\n" + + "\x19action_invocation_planned\x18\t \x01(\v2>.terraform1.stacks.StackChangeProgress.ActionInvocationPlannedH\x00R\x17actionInvocationPlanned\x1a\xb2\x02\n" + "\x17ComponentInstanceStatus\x12C\n" + "\x04addr\x18\x01 \x01(\v2/.terraform1.stacks.ComponentInstanceInStackAddrR\x04addr\x12]\n" + "\x06status\x18\x02 \x01(\x0e2E.terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.StatusR\x06status\"s\n" + @@ -6771,7 +7540,19 @@ const file_stacks_proto_rawDesc = "" + "\aunknown\x18\x02 \x01(\bR\aunknown\x1a\xbe\x01\n" + "%DeferredResourceInstancePlannedChange\x127\n" + "\bdeferred\x18\x01 \x01(\v2\x1b.terraform1.stacks.DeferredR\bdeferred\x12\\\n" + - "\x06change\x18\x02 \x01(\v2D.terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChangeR\x06change\x1a\x8a\x02\n" + + "\x06change\x18\x02 \x01(\v2D.terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChangeR\x06change\x1a\x89\x03\n" + + "\x17ActionInvocationPlanned\x12J\n" + + "\x04addr\x18\x01 \x01(\v26.terraform1.stacks.ActionInvocationInstanceInStackAddrR\x04addr\x12#\n" + + "\rprovider_addr\x18\x02 \x01(\tR\fproviderAddr\x12y\n" + + "\x18lifecycle_action_trigger\x18\x03 \x01(\v2=.terraform1.stacks.StackChangeProgress.LifecycleActionTriggerH\x00R\x16lifecycleActionTrigger\x12p\n" + + "\x15invoke_action_trigger\x18\x04 \x01(\v2:.terraform1.stacks.StackChangeProgress.InvokeActionTriggerH\x00R\x13invokeActionTriggerB\x10\n" + + "\x0eaction_trigger\x1a\xd3\x02\n" + + "\x16LifecycleActionTrigger\x12n\n" + + "\x1btriggering_resource_address\x18\x01 \x01(\v2..terraform1.stacks.ResourceInstanceInStackAddrR\x19triggeringResourceAddress\x12^\n" + + "\rtrigger_event\x18\x02 \x01(\x0e29.terraform1.stacks.StackChangeProgress.ActionTriggerEventR\ftriggerEvent\x12;\n" + + "\x1aaction_trigger_block_index\x18\x03 \x01(\x03R\x17actionTriggerBlockIndex\x12,\n" + + "\x12actions_list_index\x18\x04 \x01(\x03R\x10actionsListIndex\x1a\x15\n" + + "\x13InvokeActionTrigger\x1a\x8a\x02\n" + "\x11ProvisionerStatus\x12H\n" + "\x04addr\x18\x01 \x01(\v24.terraform1.stacks.ResourceInstanceObjectInStackAddrR\x04addr\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12P\n" + @@ -6797,7 +7578,17 @@ const file_stacks_proto_rawDesc = "" + "\x06forget\x18\t \x01(\x05R\x06forget\x1ab\n" + "\x12ComponentInstances\x12%\n" + "\x0ecomponent_addr\x18\x01 \x01(\tR\rcomponentAddr\x12%\n" + - "\x0einstance_addrs\x18\x02 \x03(\tR\rinstanceAddrsB\a\n" + + "\x0einstance_addrs\x18\x02 \x03(\tR\rinstanceAddrs\"\xa4\x01\n" + + "\x12ActionTriggerEvent\x12\x11\n" + + "\rINVALID_EVENT\x10\x00\x12\x11\n" + + "\rBEFORE_CREATE\x10\x01\x12\x10\n" + + "\fAFTER_CREATE\x10\x02\x12\x11\n" + + "\rBEFORE_UPDATE\x10\x03\x12\x10\n" + + "\fAFTER_UPDATE\x10\x04\x12\x12\n" + + "\x0eBEFORE_DESTROY\x10\x05\x12\x11\n" + + "\rAFTER_DESTROY\x10\x06\x12\n" + + "\n" + + "\x06INVOKE\x10\aB\a\n" + "\x05event\"\xff\x03\n" + "\x16ListResourceIdentities\x1a\x98\x01\n" + "\aRequest\x12!\n" + @@ -6863,291 +7654,317 @@ func file_stacks_proto_rawDescGZIP() []byte { return file_stacks_proto_rawDescData } -var file_stacks_proto_enumTypes = make([]protoimpl.EnumInfo, 8) -var file_stacks_proto_msgTypes = make([]protoimpl.MessageInfo, 108) +var file_stacks_proto_enumTypes = make([]protoimpl.EnumInfo, 10) +var file_stacks_proto_msgTypes = make([]protoimpl.MessageInfo, 116) var file_stacks_proto_goTypes = []any{ (ResourceMode)(0), // 0: terraform1.stacks.ResourceMode (PlanMode)(0), // 1: terraform1.stacks.PlanMode (ChangeType)(0), // 2: terraform1.stacks.ChangeType (FindStackConfigurationComponents_Instances)(0), // 3: terraform1.stacks.FindStackConfigurationComponents.Instances - (Deferred_Reason)(0), // 4: terraform1.stacks.Deferred.Reason - (StackChangeProgress_ComponentInstanceStatus_Status)(0), // 5: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.Status - (StackChangeProgress_ResourceInstanceStatus_Status)(0), // 6: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.Status - (StackChangeProgress_ProvisionerStatus_Status)(0), // 7: terraform1.stacks.StackChangeProgress.ProvisionerStatus.Status - (*OpenTerraformState)(nil), // 8: terraform1.stacks.OpenTerraformState - (*CloseTerraformState)(nil), // 9: terraform1.stacks.CloseTerraformState - (*MigrateTerraformState)(nil), // 10: terraform1.stacks.MigrateTerraformState - (*OpenStackConfiguration)(nil), // 11: terraform1.stacks.OpenStackConfiguration - (*CloseStackConfiguration)(nil), // 12: terraform1.stacks.CloseStackConfiguration - (*ValidateStackConfiguration)(nil), // 13: terraform1.stacks.ValidateStackConfiguration - (*FindStackConfigurationComponents)(nil), // 14: terraform1.stacks.FindStackConfigurationComponents - (*OpenStackState)(nil), // 15: terraform1.stacks.OpenStackState - (*CloseStackState)(nil), // 16: terraform1.stacks.CloseStackState - (*PlanStackChanges)(nil), // 17: terraform1.stacks.PlanStackChanges - (*OpenStackPlan)(nil), // 18: terraform1.stacks.OpenStackPlan - (*CloseStackPlan)(nil), // 19: terraform1.stacks.CloseStackPlan - (*ApplyStackChanges)(nil), // 20: terraform1.stacks.ApplyStackChanges - (*OpenStackInspector)(nil), // 21: terraform1.stacks.OpenStackInspector - (*InspectExpressionResult)(nil), // 22: terraform1.stacks.InspectExpressionResult - (*DynamicValue)(nil), // 23: terraform1.stacks.DynamicValue - (*DynamicValueChange)(nil), // 24: terraform1.stacks.DynamicValueChange - (*DynamicValueWithSource)(nil), // 25: terraform1.stacks.DynamicValueWithSource - (*AttributePath)(nil), // 26: terraform1.stacks.AttributePath - (*ComponentInstanceInStackAddr)(nil), // 27: terraform1.stacks.ComponentInstanceInStackAddr - (*ResourceInstanceInStackAddr)(nil), // 28: terraform1.stacks.ResourceInstanceInStackAddr - (*ResourceInstanceObjectInStackAddr)(nil), // 29: terraform1.stacks.ResourceInstanceObjectInStackAddr - (*PlannedChange)(nil), // 30: terraform1.stacks.PlannedChange - (*Deferred)(nil), // 31: terraform1.stacks.Deferred - (*AppliedChange)(nil), // 32: terraform1.stacks.AppliedChange - (*StackChangeProgress)(nil), // 33: terraform1.stacks.StackChangeProgress - (*ListResourceIdentities)(nil), // 34: terraform1.stacks.ListResourceIdentities - (*OpenTerraformState_Request)(nil), // 35: terraform1.stacks.OpenTerraformState.Request - (*OpenTerraformState_Response)(nil), // 36: terraform1.stacks.OpenTerraformState.Response - (*CloseTerraformState_Request)(nil), // 37: terraform1.stacks.CloseTerraformState.Request - (*CloseTerraformState_Response)(nil), // 38: terraform1.stacks.CloseTerraformState.Response - (*MigrateTerraformState_Request)(nil), // 39: terraform1.stacks.MigrateTerraformState.Request - (*MigrateTerraformState_Event)(nil), // 40: terraform1.stacks.MigrateTerraformState.Event - (*MigrateTerraformState_Request_Mapping)(nil), // 41: terraform1.stacks.MigrateTerraformState.Request.Mapping - nil, // 42: terraform1.stacks.MigrateTerraformState.Request.Mapping.ResourceAddressMapEntry - nil, // 43: terraform1.stacks.MigrateTerraformState.Request.Mapping.ModuleAddressMapEntry - (*OpenStackConfiguration_Request)(nil), // 44: terraform1.stacks.OpenStackConfiguration.Request - (*OpenStackConfiguration_Response)(nil), // 45: terraform1.stacks.OpenStackConfiguration.Response - (*CloseStackConfiguration_Request)(nil), // 46: terraform1.stacks.CloseStackConfiguration.Request - (*CloseStackConfiguration_Response)(nil), // 47: terraform1.stacks.CloseStackConfiguration.Response - (*ValidateStackConfiguration_Request)(nil), // 48: terraform1.stacks.ValidateStackConfiguration.Request - (*ValidateStackConfiguration_Response)(nil), // 49: terraform1.stacks.ValidateStackConfiguration.Response - (*FindStackConfigurationComponents_Request)(nil), // 50: terraform1.stacks.FindStackConfigurationComponents.Request - (*FindStackConfigurationComponents_Response)(nil), // 51: terraform1.stacks.FindStackConfigurationComponents.Response - (*FindStackConfigurationComponents_StackConfig)(nil), // 52: terraform1.stacks.FindStackConfigurationComponents.StackConfig - (*FindStackConfigurationComponents_EmbeddedStack)(nil), // 53: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack - (*FindStackConfigurationComponents_Component)(nil), // 54: terraform1.stacks.FindStackConfigurationComponents.Component - (*FindStackConfigurationComponents_Removed)(nil), // 55: terraform1.stacks.FindStackConfigurationComponents.Removed - (*FindStackConfigurationComponents_InputVariable)(nil), // 56: terraform1.stacks.FindStackConfigurationComponents.InputVariable - (*FindStackConfigurationComponents_OutputValue)(nil), // 57: terraform1.stacks.FindStackConfigurationComponents.OutputValue - nil, // 58: terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry - nil, // 59: terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry - nil, // 60: terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry - nil, // 61: terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry - nil, // 62: terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry - (*FindStackConfigurationComponents_Removed_Block)(nil), // 63: terraform1.stacks.FindStackConfigurationComponents.Removed.Block - (*OpenStackState_RequestItem)(nil), // 64: terraform1.stacks.OpenStackState.RequestItem - (*OpenStackState_Response)(nil), // 65: terraform1.stacks.OpenStackState.Response - (*CloseStackState_Request)(nil), // 66: terraform1.stacks.CloseStackState.Request - (*CloseStackState_Response)(nil), // 67: terraform1.stacks.CloseStackState.Response - (*PlanStackChanges_Request)(nil), // 68: terraform1.stacks.PlanStackChanges.Request - (*PlanStackChanges_Event)(nil), // 69: terraform1.stacks.PlanStackChanges.Event - nil, // 70: terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry - nil, // 71: terraform1.stacks.PlanStackChanges.Request.InputValuesEntry - (*OpenStackPlan_RequestItem)(nil), // 72: terraform1.stacks.OpenStackPlan.RequestItem - (*OpenStackPlan_Response)(nil), // 73: terraform1.stacks.OpenStackPlan.Response - (*CloseStackPlan_Request)(nil), // 74: terraform1.stacks.CloseStackPlan.Request - (*CloseStackPlan_Response)(nil), // 75: terraform1.stacks.CloseStackPlan.Response - (*ApplyStackChanges_Request)(nil), // 76: terraform1.stacks.ApplyStackChanges.Request - (*ApplyStackChanges_Event)(nil), // 77: terraform1.stacks.ApplyStackChanges.Event - nil, // 78: terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry - (*OpenStackInspector_Request)(nil), // 79: terraform1.stacks.OpenStackInspector.Request - (*OpenStackInspector_Response)(nil), // 80: terraform1.stacks.OpenStackInspector.Response - nil, // 81: terraform1.stacks.OpenStackInspector.Request.StateEntry - nil, // 82: terraform1.stacks.OpenStackInspector.Request.InputValuesEntry - (*InspectExpressionResult_Request)(nil), // 83: terraform1.stacks.InspectExpressionResult.Request - (*InspectExpressionResult_Response)(nil), // 84: terraform1.stacks.InspectExpressionResult.Response - (*AttributePath_Step)(nil), // 85: terraform1.stacks.AttributePath.Step - (*PlannedChange_ChangeDescription)(nil), // 86: terraform1.stacks.PlannedChange.ChangeDescription - (*PlannedChange_ComponentInstance)(nil), // 87: terraform1.stacks.PlannedChange.ComponentInstance - (*PlannedChange_ResourceInstance)(nil), // 88: terraform1.stacks.PlannedChange.ResourceInstance - (*PlannedChange_OutputValue)(nil), // 89: terraform1.stacks.PlannedChange.OutputValue - (*PlannedChange_ResourceInstanceDeferred)(nil), // 90: terraform1.stacks.PlannedChange.ResourceInstanceDeferred - (*PlannedChange_InputVariable)(nil), // 91: terraform1.stacks.PlannedChange.InputVariable - (*PlannedChange_ResourceInstance_Index)(nil), // 92: terraform1.stacks.PlannedChange.ResourceInstance.Index - (*PlannedChange_ResourceInstance_Moved)(nil), // 93: terraform1.stacks.PlannedChange.ResourceInstance.Moved - (*PlannedChange_ResourceInstance_Imported)(nil), // 94: terraform1.stacks.PlannedChange.ResourceInstance.Imported - (*AppliedChange_RawChange)(nil), // 95: terraform1.stacks.AppliedChange.RawChange - (*AppliedChange_ChangeDescription)(nil), // 96: terraform1.stacks.AppliedChange.ChangeDescription - (*AppliedChange_ResourceInstance)(nil), // 97: terraform1.stacks.AppliedChange.ResourceInstance - (*AppliedChange_ComponentInstance)(nil), // 98: terraform1.stacks.AppliedChange.ComponentInstance - (*AppliedChange_OutputValue)(nil), // 99: terraform1.stacks.AppliedChange.OutputValue - (*AppliedChange_InputVariable)(nil), // 100: terraform1.stacks.AppliedChange.InputVariable - (*AppliedChange_Nothing)(nil), // 101: terraform1.stacks.AppliedChange.Nothing - nil, // 102: terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry - (*StackChangeProgress_ComponentInstanceStatus)(nil), // 103: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus - (*StackChangeProgress_ResourceInstanceStatus)(nil), // 104: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus - (*StackChangeProgress_ResourceInstancePlannedChange)(nil), // 105: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange - (*StackChangeProgress_DeferredResourceInstancePlannedChange)(nil), // 106: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange - (*StackChangeProgress_ProvisionerStatus)(nil), // 107: terraform1.stacks.StackChangeProgress.ProvisionerStatus - (*StackChangeProgress_ProvisionerOutput)(nil), // 108: terraform1.stacks.StackChangeProgress.ProvisionerOutput - (*StackChangeProgress_ComponentInstanceChanges)(nil), // 109: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges - (*StackChangeProgress_ComponentInstances)(nil), // 110: terraform1.stacks.StackChangeProgress.ComponentInstances - (*StackChangeProgress_ResourceInstancePlannedChange_Moved)(nil), // 111: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved - (*StackChangeProgress_ResourceInstancePlannedChange_Imported)(nil), // 112: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Imported - (*ListResourceIdentities_Request)(nil), // 113: terraform1.stacks.ListResourceIdentities.Request - (*ListResourceIdentities_Response)(nil), // 114: terraform1.stacks.ListResourceIdentities.Response - (*ListResourceIdentities_Resource)(nil), // 115: terraform1.stacks.ListResourceIdentities.Resource - (*terraform1.SourceRange)(nil), // 116: terraform1.SourceRange - (*anypb.Any)(nil), // 117: google.protobuf.Any - (*terraform1.Diagnostic)(nil), // 118: terraform1.Diagnostic - (*terraform1.SourceAddress)(nil), // 119: terraform1.SourceAddress + (PlannedChange_ActionTriggerEvent)(0), // 4: terraform1.stacks.PlannedChange.ActionTriggerEvent + (Deferred_Reason)(0), // 5: terraform1.stacks.Deferred.Reason + (StackChangeProgress_ActionTriggerEvent)(0), // 6: terraform1.stacks.StackChangeProgress.ActionTriggerEvent + (StackChangeProgress_ComponentInstanceStatus_Status)(0), // 7: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.Status + (StackChangeProgress_ResourceInstanceStatus_Status)(0), // 8: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.Status + (StackChangeProgress_ProvisionerStatus_Status)(0), // 9: terraform1.stacks.StackChangeProgress.ProvisionerStatus.Status + (*OpenTerraformState)(nil), // 10: terraform1.stacks.OpenTerraformState + (*CloseTerraformState)(nil), // 11: terraform1.stacks.CloseTerraformState + (*MigrateTerraformState)(nil), // 12: terraform1.stacks.MigrateTerraformState + (*OpenStackConfiguration)(nil), // 13: terraform1.stacks.OpenStackConfiguration + (*CloseStackConfiguration)(nil), // 14: terraform1.stacks.CloseStackConfiguration + (*ValidateStackConfiguration)(nil), // 15: terraform1.stacks.ValidateStackConfiguration + (*FindStackConfigurationComponents)(nil), // 16: terraform1.stacks.FindStackConfigurationComponents + (*OpenStackState)(nil), // 17: terraform1.stacks.OpenStackState + (*CloseStackState)(nil), // 18: terraform1.stacks.CloseStackState + (*PlanStackChanges)(nil), // 19: terraform1.stacks.PlanStackChanges + (*OpenStackPlan)(nil), // 20: terraform1.stacks.OpenStackPlan + (*CloseStackPlan)(nil), // 21: terraform1.stacks.CloseStackPlan + (*ApplyStackChanges)(nil), // 22: terraform1.stacks.ApplyStackChanges + (*OpenStackInspector)(nil), // 23: terraform1.stacks.OpenStackInspector + (*InspectExpressionResult)(nil), // 24: terraform1.stacks.InspectExpressionResult + (*DynamicValue)(nil), // 25: terraform1.stacks.DynamicValue + (*DynamicValueChange)(nil), // 26: terraform1.stacks.DynamicValueChange + (*DynamicValueWithSource)(nil), // 27: terraform1.stacks.DynamicValueWithSource + (*AttributePath)(nil), // 28: terraform1.stacks.AttributePath + (*ComponentInstanceInStackAddr)(nil), // 29: terraform1.stacks.ComponentInstanceInStackAddr + (*ActionInvocationInstanceInStackAddr)(nil), // 30: terraform1.stacks.ActionInvocationInstanceInStackAddr + (*ResourceInstanceInStackAddr)(nil), // 31: terraform1.stacks.ResourceInstanceInStackAddr + (*ResourceInstanceObjectInStackAddr)(nil), // 32: terraform1.stacks.ResourceInstanceObjectInStackAddr + (*PlannedChange)(nil), // 33: terraform1.stacks.PlannedChange + (*Deferred)(nil), // 34: terraform1.stacks.Deferred + (*AppliedChange)(nil), // 35: terraform1.stacks.AppliedChange + (*StackChangeProgress)(nil), // 36: terraform1.stacks.StackChangeProgress + (*ListResourceIdentities)(nil), // 37: terraform1.stacks.ListResourceIdentities + (*OpenTerraformState_Request)(nil), // 38: terraform1.stacks.OpenTerraformState.Request + (*OpenTerraformState_Response)(nil), // 39: terraform1.stacks.OpenTerraformState.Response + (*CloseTerraformState_Request)(nil), // 40: terraform1.stacks.CloseTerraformState.Request + (*CloseTerraformState_Response)(nil), // 41: terraform1.stacks.CloseTerraformState.Response + (*MigrateTerraformState_Request)(nil), // 42: terraform1.stacks.MigrateTerraformState.Request + (*MigrateTerraformState_Event)(nil), // 43: terraform1.stacks.MigrateTerraformState.Event + (*MigrateTerraformState_Request_Mapping)(nil), // 44: terraform1.stacks.MigrateTerraformState.Request.Mapping + nil, // 45: terraform1.stacks.MigrateTerraformState.Request.Mapping.ResourceAddressMapEntry + nil, // 46: terraform1.stacks.MigrateTerraformState.Request.Mapping.ModuleAddressMapEntry + (*OpenStackConfiguration_Request)(nil), // 47: terraform1.stacks.OpenStackConfiguration.Request + (*OpenStackConfiguration_Response)(nil), // 48: terraform1.stacks.OpenStackConfiguration.Response + (*CloseStackConfiguration_Request)(nil), // 49: terraform1.stacks.CloseStackConfiguration.Request + (*CloseStackConfiguration_Response)(nil), // 50: terraform1.stacks.CloseStackConfiguration.Response + (*ValidateStackConfiguration_Request)(nil), // 51: terraform1.stacks.ValidateStackConfiguration.Request + (*ValidateStackConfiguration_Response)(nil), // 52: terraform1.stacks.ValidateStackConfiguration.Response + (*FindStackConfigurationComponents_Request)(nil), // 53: terraform1.stacks.FindStackConfigurationComponents.Request + (*FindStackConfigurationComponents_Response)(nil), // 54: terraform1.stacks.FindStackConfigurationComponents.Response + (*FindStackConfigurationComponents_StackConfig)(nil), // 55: terraform1.stacks.FindStackConfigurationComponents.StackConfig + (*FindStackConfigurationComponents_EmbeddedStack)(nil), // 56: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack + (*FindStackConfigurationComponents_Component)(nil), // 57: terraform1.stacks.FindStackConfigurationComponents.Component + (*FindStackConfigurationComponents_Removed)(nil), // 58: terraform1.stacks.FindStackConfigurationComponents.Removed + (*FindStackConfigurationComponents_InputVariable)(nil), // 59: terraform1.stacks.FindStackConfigurationComponents.InputVariable + (*FindStackConfigurationComponents_OutputValue)(nil), // 60: terraform1.stacks.FindStackConfigurationComponents.OutputValue + nil, // 61: terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry + nil, // 62: terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry + nil, // 63: terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry + nil, // 64: terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry + nil, // 65: terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry + (*FindStackConfigurationComponents_Removed_Block)(nil), // 66: terraform1.stacks.FindStackConfigurationComponents.Removed.Block + (*OpenStackState_RequestItem)(nil), // 67: terraform1.stacks.OpenStackState.RequestItem + (*OpenStackState_Response)(nil), // 68: terraform1.stacks.OpenStackState.Response + (*CloseStackState_Request)(nil), // 69: terraform1.stacks.CloseStackState.Request + (*CloseStackState_Response)(nil), // 70: terraform1.stacks.CloseStackState.Response + (*PlanStackChanges_Request)(nil), // 71: terraform1.stacks.PlanStackChanges.Request + (*PlanStackChanges_Event)(nil), // 72: terraform1.stacks.PlanStackChanges.Event + nil, // 73: terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry + nil, // 74: terraform1.stacks.PlanStackChanges.Request.InputValuesEntry + (*OpenStackPlan_RequestItem)(nil), // 75: terraform1.stacks.OpenStackPlan.RequestItem + (*OpenStackPlan_Response)(nil), // 76: terraform1.stacks.OpenStackPlan.Response + (*CloseStackPlan_Request)(nil), // 77: terraform1.stacks.CloseStackPlan.Request + (*CloseStackPlan_Response)(nil), // 78: terraform1.stacks.CloseStackPlan.Response + (*ApplyStackChanges_Request)(nil), // 79: terraform1.stacks.ApplyStackChanges.Request + (*ApplyStackChanges_Event)(nil), // 80: terraform1.stacks.ApplyStackChanges.Event + nil, // 81: terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry + (*OpenStackInspector_Request)(nil), // 82: terraform1.stacks.OpenStackInspector.Request + (*OpenStackInspector_Response)(nil), // 83: terraform1.stacks.OpenStackInspector.Response + nil, // 84: terraform1.stacks.OpenStackInspector.Request.StateEntry + nil, // 85: terraform1.stacks.OpenStackInspector.Request.InputValuesEntry + (*InspectExpressionResult_Request)(nil), // 86: terraform1.stacks.InspectExpressionResult.Request + (*InspectExpressionResult_Response)(nil), // 87: terraform1.stacks.InspectExpressionResult.Response + (*AttributePath_Step)(nil), // 88: terraform1.stacks.AttributePath.Step + (*PlannedChange_ChangeDescription)(nil), // 89: terraform1.stacks.PlannedChange.ChangeDescription + (*PlannedChange_ComponentInstance)(nil), // 90: terraform1.stacks.PlannedChange.ComponentInstance + (*PlannedChange_ResourceInstance)(nil), // 91: terraform1.stacks.PlannedChange.ResourceInstance + (*PlannedChange_OutputValue)(nil), // 92: terraform1.stacks.PlannedChange.OutputValue + (*PlannedChange_ResourceInstanceDeferred)(nil), // 93: terraform1.stacks.PlannedChange.ResourceInstanceDeferred + (*PlannedChange_InputVariable)(nil), // 94: terraform1.stacks.PlannedChange.InputVariable + (*PlannedChange_ActionInvocationInstance)(nil), // 95: terraform1.stacks.PlannedChange.ActionInvocationInstance + (*PlannedChange_ActionInvocationDeferred)(nil), // 96: terraform1.stacks.PlannedChange.ActionInvocationDeferred + (*PlannedChange_LifecycleActionTrigger)(nil), // 97: terraform1.stacks.PlannedChange.LifecycleActionTrigger + (*PlannedChange_InvokeActionTrigger)(nil), // 98: terraform1.stacks.PlannedChange.InvokeActionTrigger + (*PlannedChange_ResourceInstance_Index)(nil), // 99: terraform1.stacks.PlannedChange.ResourceInstance.Index + (*PlannedChange_ResourceInstance_Moved)(nil), // 100: terraform1.stacks.PlannedChange.ResourceInstance.Moved + (*PlannedChange_ResourceInstance_Imported)(nil), // 101: terraform1.stacks.PlannedChange.ResourceInstance.Imported + (*AppliedChange_RawChange)(nil), // 102: terraform1.stacks.AppliedChange.RawChange + (*AppliedChange_ChangeDescription)(nil), // 103: terraform1.stacks.AppliedChange.ChangeDescription + (*AppliedChange_ResourceInstance)(nil), // 104: terraform1.stacks.AppliedChange.ResourceInstance + (*AppliedChange_ComponentInstance)(nil), // 105: terraform1.stacks.AppliedChange.ComponentInstance + (*AppliedChange_OutputValue)(nil), // 106: terraform1.stacks.AppliedChange.OutputValue + (*AppliedChange_InputVariable)(nil), // 107: terraform1.stacks.AppliedChange.InputVariable + (*AppliedChange_Nothing)(nil), // 108: terraform1.stacks.AppliedChange.Nothing + nil, // 109: terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry + (*StackChangeProgress_ComponentInstanceStatus)(nil), // 110: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus + (*StackChangeProgress_ResourceInstanceStatus)(nil), // 111: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus + (*StackChangeProgress_ResourceInstancePlannedChange)(nil), // 112: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange + (*StackChangeProgress_DeferredResourceInstancePlannedChange)(nil), // 113: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange + (*StackChangeProgress_ActionInvocationPlanned)(nil), // 114: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned + (*StackChangeProgress_LifecycleActionTrigger)(nil), // 115: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger + (*StackChangeProgress_InvokeActionTrigger)(nil), // 116: terraform1.stacks.StackChangeProgress.InvokeActionTrigger + (*StackChangeProgress_ProvisionerStatus)(nil), // 117: terraform1.stacks.StackChangeProgress.ProvisionerStatus + (*StackChangeProgress_ProvisionerOutput)(nil), // 118: terraform1.stacks.StackChangeProgress.ProvisionerOutput + (*StackChangeProgress_ComponentInstanceChanges)(nil), // 119: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges + (*StackChangeProgress_ComponentInstances)(nil), // 120: terraform1.stacks.StackChangeProgress.ComponentInstances + (*StackChangeProgress_ResourceInstancePlannedChange_Moved)(nil), // 121: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved + (*StackChangeProgress_ResourceInstancePlannedChange_Imported)(nil), // 122: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Imported + (*ListResourceIdentities_Request)(nil), // 123: terraform1.stacks.ListResourceIdentities.Request + (*ListResourceIdentities_Response)(nil), // 124: terraform1.stacks.ListResourceIdentities.Response + (*ListResourceIdentities_Resource)(nil), // 125: terraform1.stacks.ListResourceIdentities.Resource + (*terraform1.SourceRange)(nil), // 126: terraform1.SourceRange + (*anypb.Any)(nil), // 127: google.protobuf.Any + (*terraform1.Diagnostic)(nil), // 128: terraform1.Diagnostic + (*terraform1.SourceAddress)(nil), // 129: terraform1.SourceAddress } var file_stacks_proto_depIdxs = []int32{ - 26, // 0: terraform1.stacks.DynamicValue.sensitive:type_name -> terraform1.stacks.AttributePath - 23, // 1: terraform1.stacks.DynamicValueChange.old:type_name -> terraform1.stacks.DynamicValue - 23, // 2: terraform1.stacks.DynamicValueChange.new:type_name -> terraform1.stacks.DynamicValue - 23, // 3: terraform1.stacks.DynamicValueWithSource.value:type_name -> terraform1.stacks.DynamicValue - 116, // 4: terraform1.stacks.DynamicValueWithSource.source_range:type_name -> terraform1.SourceRange - 85, // 5: terraform1.stacks.AttributePath.steps:type_name -> terraform1.stacks.AttributePath.Step - 117, // 6: terraform1.stacks.PlannedChange.raw:type_name -> google.protobuf.Any - 86, // 7: terraform1.stacks.PlannedChange.descriptions:type_name -> terraform1.stacks.PlannedChange.ChangeDescription - 4, // 8: terraform1.stacks.Deferred.reason:type_name -> terraform1.stacks.Deferred.Reason - 95, // 9: terraform1.stacks.AppliedChange.raw:type_name -> terraform1.stacks.AppliedChange.RawChange - 96, // 10: terraform1.stacks.AppliedChange.descriptions:type_name -> terraform1.stacks.AppliedChange.ChangeDescription - 103, // 11: terraform1.stacks.StackChangeProgress.component_instance_status:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceStatus - 104, // 12: terraform1.stacks.StackChangeProgress.resource_instance_status:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstanceStatus - 105, // 13: terraform1.stacks.StackChangeProgress.resource_instance_planned_change:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange - 107, // 14: terraform1.stacks.StackChangeProgress.provisioner_status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus - 108, // 15: terraform1.stacks.StackChangeProgress.provisioner_output:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerOutput - 109, // 16: terraform1.stacks.StackChangeProgress.component_instance_changes:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceChanges - 110, // 17: terraform1.stacks.StackChangeProgress.component_instances:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstances - 106, // 18: terraform1.stacks.StackChangeProgress.deferred_resource_instance_planned_change:type_name -> terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange - 118, // 19: terraform1.stacks.OpenTerraformState.Response.diagnostics:type_name -> terraform1.Diagnostic - 41, // 20: terraform1.stacks.MigrateTerraformState.Request.simple:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping - 118, // 21: terraform1.stacks.MigrateTerraformState.Event.diagnostic:type_name -> terraform1.Diagnostic - 32, // 22: terraform1.stacks.MigrateTerraformState.Event.applied_change:type_name -> terraform1.stacks.AppliedChange - 42, // 23: terraform1.stacks.MigrateTerraformState.Request.Mapping.resource_address_map:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping.ResourceAddressMapEntry - 43, // 24: terraform1.stacks.MigrateTerraformState.Request.Mapping.module_address_map:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping.ModuleAddressMapEntry - 119, // 25: terraform1.stacks.OpenStackConfiguration.Request.source_address:type_name -> terraform1.SourceAddress - 118, // 26: terraform1.stacks.OpenStackConfiguration.Response.diagnostics:type_name -> terraform1.Diagnostic - 118, // 27: terraform1.stacks.ValidateStackConfiguration.Response.diagnostics:type_name -> terraform1.Diagnostic - 52, // 28: terraform1.stacks.FindStackConfigurationComponents.Response.config:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig - 58, // 29: terraform1.stacks.FindStackConfigurationComponents.StackConfig.components:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry - 59, // 30: terraform1.stacks.FindStackConfigurationComponents.StackConfig.embedded_stacks:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry - 60, // 31: terraform1.stacks.FindStackConfigurationComponents.StackConfig.input_variables:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry - 61, // 32: terraform1.stacks.FindStackConfigurationComponents.StackConfig.output_values:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry - 62, // 33: terraform1.stacks.FindStackConfigurationComponents.StackConfig.removed:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry - 3, // 34: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances - 52, // 35: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack.config:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig - 3, // 36: terraform1.stacks.FindStackConfigurationComponents.Component.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances - 3, // 37: terraform1.stacks.FindStackConfigurationComponents.Removed.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances - 63, // 38: terraform1.stacks.FindStackConfigurationComponents.Removed.blocks:type_name -> terraform1.stacks.FindStackConfigurationComponents.Removed.Block - 54, // 39: terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.Component - 53, // 40: terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack - 56, // 41: terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.InputVariable - 57, // 42: terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.OutputValue - 55, // 43: terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.Removed - 3, // 44: terraform1.stacks.FindStackConfigurationComponents.Removed.Block.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances - 95, // 45: terraform1.stacks.OpenStackState.RequestItem.raw:type_name -> terraform1.stacks.AppliedChange.RawChange - 1, // 46: terraform1.stacks.PlanStackChanges.Request.plan_mode:type_name -> terraform1.stacks.PlanMode - 70, // 47: terraform1.stacks.PlanStackChanges.Request.previous_state:type_name -> terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry - 71, // 48: terraform1.stacks.PlanStackChanges.Request.input_values:type_name -> terraform1.stacks.PlanStackChanges.Request.InputValuesEntry - 30, // 49: terraform1.stacks.PlanStackChanges.Event.planned_change:type_name -> terraform1.stacks.PlannedChange - 118, // 50: terraform1.stacks.PlanStackChanges.Event.diagnostic:type_name -> terraform1.Diagnostic - 33, // 51: terraform1.stacks.PlanStackChanges.Event.progress:type_name -> terraform1.stacks.StackChangeProgress - 117, // 52: terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry.value:type_name -> google.protobuf.Any - 25, // 53: terraform1.stacks.PlanStackChanges.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource - 117, // 54: terraform1.stacks.OpenStackPlan.RequestItem.raw:type_name -> google.protobuf.Any - 117, // 55: terraform1.stacks.ApplyStackChanges.Request.planned_changes:type_name -> google.protobuf.Any - 78, // 56: terraform1.stacks.ApplyStackChanges.Request.input_values:type_name -> terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry - 32, // 57: terraform1.stacks.ApplyStackChanges.Event.applied_change:type_name -> terraform1.stacks.AppliedChange - 118, // 58: terraform1.stacks.ApplyStackChanges.Event.diagnostic:type_name -> terraform1.Diagnostic - 33, // 59: terraform1.stacks.ApplyStackChanges.Event.progress:type_name -> terraform1.stacks.StackChangeProgress - 25, // 60: terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource - 81, // 61: terraform1.stacks.OpenStackInspector.Request.state:type_name -> terraform1.stacks.OpenStackInspector.Request.StateEntry - 82, // 62: terraform1.stacks.OpenStackInspector.Request.input_values:type_name -> terraform1.stacks.OpenStackInspector.Request.InputValuesEntry - 118, // 63: terraform1.stacks.OpenStackInspector.Response.diagnostics:type_name -> terraform1.Diagnostic - 117, // 64: terraform1.stacks.OpenStackInspector.Request.StateEntry.value:type_name -> google.protobuf.Any - 25, // 65: terraform1.stacks.OpenStackInspector.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource - 23, // 66: terraform1.stacks.InspectExpressionResult.Response.result:type_name -> terraform1.stacks.DynamicValue - 118, // 67: terraform1.stacks.InspectExpressionResult.Response.diagnostics:type_name -> terraform1.Diagnostic - 87, // 68: terraform1.stacks.PlannedChange.ChangeDescription.component_instance_planned:type_name -> terraform1.stacks.PlannedChange.ComponentInstance - 88, // 69: terraform1.stacks.PlannedChange.ChangeDescription.resource_instance_planned:type_name -> terraform1.stacks.PlannedChange.ResourceInstance - 89, // 70: terraform1.stacks.PlannedChange.ChangeDescription.output_value_planned:type_name -> terraform1.stacks.PlannedChange.OutputValue - 90, // 71: terraform1.stacks.PlannedChange.ChangeDescription.resource_instance_deferred:type_name -> terraform1.stacks.PlannedChange.ResourceInstanceDeferred - 91, // 72: terraform1.stacks.PlannedChange.ChangeDescription.input_variable_planned:type_name -> terraform1.stacks.PlannedChange.InputVariable - 27, // 73: terraform1.stacks.PlannedChange.ComponentInstance.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr - 2, // 74: terraform1.stacks.PlannedChange.ComponentInstance.actions:type_name -> terraform1.stacks.ChangeType - 29, // 75: terraform1.stacks.PlannedChange.ResourceInstance.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 2, // 76: terraform1.stacks.PlannedChange.ResourceInstance.actions:type_name -> terraform1.stacks.ChangeType - 24, // 77: terraform1.stacks.PlannedChange.ResourceInstance.values:type_name -> terraform1.stacks.DynamicValueChange - 93, // 78: terraform1.stacks.PlannedChange.ResourceInstance.moved:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Moved - 94, // 79: terraform1.stacks.PlannedChange.ResourceInstance.imported:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Imported - 0, // 80: terraform1.stacks.PlannedChange.ResourceInstance.resource_mode:type_name -> terraform1.stacks.ResourceMode - 23, // 81: terraform1.stacks.PlannedChange.ResourceInstance.previous_run_value:type_name -> terraform1.stacks.DynamicValue - 26, // 82: terraform1.stacks.PlannedChange.ResourceInstance.replace_paths:type_name -> terraform1.stacks.AttributePath - 92, // 83: terraform1.stacks.PlannedChange.ResourceInstance.index:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Index - 2, // 84: terraform1.stacks.PlannedChange.OutputValue.actions:type_name -> terraform1.stacks.ChangeType - 24, // 85: terraform1.stacks.PlannedChange.OutputValue.values:type_name -> terraform1.stacks.DynamicValueChange - 88, // 86: terraform1.stacks.PlannedChange.ResourceInstanceDeferred.resource_instance:type_name -> terraform1.stacks.PlannedChange.ResourceInstance - 31, // 87: terraform1.stacks.PlannedChange.ResourceInstanceDeferred.deferred:type_name -> terraform1.stacks.Deferred - 2, // 88: terraform1.stacks.PlannedChange.InputVariable.actions:type_name -> terraform1.stacks.ChangeType - 24, // 89: terraform1.stacks.PlannedChange.InputVariable.values:type_name -> terraform1.stacks.DynamicValueChange - 23, // 90: terraform1.stacks.PlannedChange.ResourceInstance.Index.value:type_name -> terraform1.stacks.DynamicValue - 28, // 91: terraform1.stacks.PlannedChange.ResourceInstance.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr - 117, // 92: terraform1.stacks.AppliedChange.RawChange.value:type_name -> google.protobuf.Any - 101, // 93: terraform1.stacks.AppliedChange.ChangeDescription.deleted:type_name -> terraform1.stacks.AppliedChange.Nothing - 101, // 94: terraform1.stacks.AppliedChange.ChangeDescription.moved:type_name -> terraform1.stacks.AppliedChange.Nothing - 97, // 95: terraform1.stacks.AppliedChange.ChangeDescription.resource_instance:type_name -> terraform1.stacks.AppliedChange.ResourceInstance - 99, // 96: terraform1.stacks.AppliedChange.ChangeDescription.output_value:type_name -> terraform1.stacks.AppliedChange.OutputValue - 100, // 97: terraform1.stacks.AppliedChange.ChangeDescription.input_variable:type_name -> terraform1.stacks.AppliedChange.InputVariable - 98, // 98: terraform1.stacks.AppliedChange.ChangeDescription.component_instance:type_name -> terraform1.stacks.AppliedChange.ComponentInstance - 29, // 99: terraform1.stacks.AppliedChange.ResourceInstance.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 23, // 100: terraform1.stacks.AppliedChange.ResourceInstance.new_value:type_name -> terraform1.stacks.DynamicValue - 0, // 101: terraform1.stacks.AppliedChange.ResourceInstance.resource_mode:type_name -> terraform1.stacks.ResourceMode - 102, // 102: terraform1.stacks.AppliedChange.ComponentInstance.output_values:type_name -> terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry - 23, // 103: terraform1.stacks.AppliedChange.OutputValue.new_value:type_name -> terraform1.stacks.DynamicValue - 23, // 104: terraform1.stacks.AppliedChange.InputVariable.new_value:type_name -> terraform1.stacks.DynamicValue - 23, // 105: terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry.value:type_name -> terraform1.stacks.DynamicValue - 27, // 106: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr - 5, // 107: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.Status - 29, // 108: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 6, // 109: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.Status - 29, // 110: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 2, // 111: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.actions:type_name -> terraform1.stacks.ChangeType - 111, // 112: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.moved:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved - 112, // 113: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.imported:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Imported - 31, // 114: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange.deferred:type_name -> terraform1.stacks.Deferred - 105, // 115: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange.change:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange - 29, // 116: terraform1.stacks.StackChangeProgress.ProvisionerStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 107, // 117: terraform1.stacks.StackChangeProgress.ProvisionerStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus - 29, // 118: terraform1.stacks.StackChangeProgress.ProvisionerOutput.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 27, // 119: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr - 28, // 120: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr - 115, // 121: terraform1.stacks.ListResourceIdentities.Response.resource:type_name -> terraform1.stacks.ListResourceIdentities.Resource - 23, // 122: terraform1.stacks.ListResourceIdentities.Resource.resource_identity:type_name -> terraform1.stacks.DynamicValue - 44, // 123: terraform1.stacks.Stacks.OpenStackConfiguration:input_type -> terraform1.stacks.OpenStackConfiguration.Request - 46, // 124: terraform1.stacks.Stacks.CloseStackConfiguration:input_type -> terraform1.stacks.CloseStackConfiguration.Request - 48, // 125: terraform1.stacks.Stacks.ValidateStackConfiguration:input_type -> terraform1.stacks.ValidateStackConfiguration.Request - 50, // 126: terraform1.stacks.Stacks.FindStackConfigurationComponents:input_type -> terraform1.stacks.FindStackConfigurationComponents.Request - 64, // 127: terraform1.stacks.Stacks.OpenState:input_type -> terraform1.stacks.OpenStackState.RequestItem - 66, // 128: terraform1.stacks.Stacks.CloseState:input_type -> terraform1.stacks.CloseStackState.Request - 68, // 129: terraform1.stacks.Stacks.PlanStackChanges:input_type -> terraform1.stacks.PlanStackChanges.Request - 72, // 130: terraform1.stacks.Stacks.OpenPlan:input_type -> terraform1.stacks.OpenStackPlan.RequestItem - 74, // 131: terraform1.stacks.Stacks.ClosePlan:input_type -> terraform1.stacks.CloseStackPlan.Request - 76, // 132: terraform1.stacks.Stacks.ApplyStackChanges:input_type -> terraform1.stacks.ApplyStackChanges.Request - 79, // 133: terraform1.stacks.Stacks.OpenStackInspector:input_type -> terraform1.stacks.OpenStackInspector.Request - 83, // 134: terraform1.stacks.Stacks.InspectExpressionResult:input_type -> terraform1.stacks.InspectExpressionResult.Request - 35, // 135: terraform1.stacks.Stacks.OpenTerraformState:input_type -> terraform1.stacks.OpenTerraformState.Request - 37, // 136: terraform1.stacks.Stacks.CloseTerraformState:input_type -> terraform1.stacks.CloseTerraformState.Request - 39, // 137: terraform1.stacks.Stacks.MigrateTerraformState:input_type -> terraform1.stacks.MigrateTerraformState.Request - 113, // 138: terraform1.stacks.Stacks.ListResourceIdentities:input_type -> terraform1.stacks.ListResourceIdentities.Request - 45, // 139: terraform1.stacks.Stacks.OpenStackConfiguration:output_type -> terraform1.stacks.OpenStackConfiguration.Response - 47, // 140: terraform1.stacks.Stacks.CloseStackConfiguration:output_type -> terraform1.stacks.CloseStackConfiguration.Response - 49, // 141: terraform1.stacks.Stacks.ValidateStackConfiguration:output_type -> terraform1.stacks.ValidateStackConfiguration.Response - 51, // 142: terraform1.stacks.Stacks.FindStackConfigurationComponents:output_type -> terraform1.stacks.FindStackConfigurationComponents.Response - 65, // 143: terraform1.stacks.Stacks.OpenState:output_type -> terraform1.stacks.OpenStackState.Response - 67, // 144: terraform1.stacks.Stacks.CloseState:output_type -> terraform1.stacks.CloseStackState.Response - 69, // 145: terraform1.stacks.Stacks.PlanStackChanges:output_type -> terraform1.stacks.PlanStackChanges.Event - 73, // 146: terraform1.stacks.Stacks.OpenPlan:output_type -> terraform1.stacks.OpenStackPlan.Response - 75, // 147: terraform1.stacks.Stacks.ClosePlan:output_type -> terraform1.stacks.CloseStackPlan.Response - 77, // 148: terraform1.stacks.Stacks.ApplyStackChanges:output_type -> terraform1.stacks.ApplyStackChanges.Event - 80, // 149: terraform1.stacks.Stacks.OpenStackInspector:output_type -> terraform1.stacks.OpenStackInspector.Response - 84, // 150: terraform1.stacks.Stacks.InspectExpressionResult:output_type -> terraform1.stacks.InspectExpressionResult.Response - 36, // 151: terraform1.stacks.Stacks.OpenTerraformState:output_type -> terraform1.stacks.OpenTerraformState.Response - 38, // 152: terraform1.stacks.Stacks.CloseTerraformState:output_type -> terraform1.stacks.CloseTerraformState.Response - 40, // 153: terraform1.stacks.Stacks.MigrateTerraformState:output_type -> terraform1.stacks.MigrateTerraformState.Event - 114, // 154: terraform1.stacks.Stacks.ListResourceIdentities:output_type -> terraform1.stacks.ListResourceIdentities.Response - 139, // [139:155] is the sub-list for method output_type - 123, // [123:139] is the sub-list for method input_type - 123, // [123:123] is the sub-list for extension type_name - 123, // [123:123] is the sub-list for extension extendee - 0, // [0:123] is the sub-list for field type_name + 28, // 0: terraform1.stacks.DynamicValue.sensitive:type_name -> terraform1.stacks.AttributePath + 25, // 1: terraform1.stacks.DynamicValueChange.old:type_name -> terraform1.stacks.DynamicValue + 25, // 2: terraform1.stacks.DynamicValueChange.new:type_name -> terraform1.stacks.DynamicValue + 25, // 3: terraform1.stacks.DynamicValueWithSource.value:type_name -> terraform1.stacks.DynamicValue + 126, // 4: terraform1.stacks.DynamicValueWithSource.source_range:type_name -> terraform1.SourceRange + 88, // 5: terraform1.stacks.AttributePath.steps:type_name -> terraform1.stacks.AttributePath.Step + 127, // 6: terraform1.stacks.PlannedChange.raw:type_name -> google.protobuf.Any + 89, // 7: terraform1.stacks.PlannedChange.descriptions:type_name -> terraform1.stacks.PlannedChange.ChangeDescription + 5, // 8: terraform1.stacks.Deferred.reason:type_name -> terraform1.stacks.Deferred.Reason + 102, // 9: terraform1.stacks.AppliedChange.raw:type_name -> terraform1.stacks.AppliedChange.RawChange + 103, // 10: terraform1.stacks.AppliedChange.descriptions:type_name -> terraform1.stacks.AppliedChange.ChangeDescription + 110, // 11: terraform1.stacks.StackChangeProgress.component_instance_status:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceStatus + 111, // 12: terraform1.stacks.StackChangeProgress.resource_instance_status:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstanceStatus + 112, // 13: terraform1.stacks.StackChangeProgress.resource_instance_planned_change:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange + 117, // 14: terraform1.stacks.StackChangeProgress.provisioner_status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus + 118, // 15: terraform1.stacks.StackChangeProgress.provisioner_output:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerOutput + 119, // 16: terraform1.stacks.StackChangeProgress.component_instance_changes:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceChanges + 120, // 17: terraform1.stacks.StackChangeProgress.component_instances:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstances + 113, // 18: terraform1.stacks.StackChangeProgress.deferred_resource_instance_planned_change:type_name -> terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange + 114, // 19: terraform1.stacks.StackChangeProgress.action_invocation_planned:type_name -> terraform1.stacks.StackChangeProgress.ActionInvocationPlanned + 128, // 20: terraform1.stacks.OpenTerraformState.Response.diagnostics:type_name -> terraform1.Diagnostic + 44, // 21: terraform1.stacks.MigrateTerraformState.Request.simple:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping + 128, // 22: terraform1.stacks.MigrateTerraformState.Event.diagnostic:type_name -> terraform1.Diagnostic + 35, // 23: terraform1.stacks.MigrateTerraformState.Event.applied_change:type_name -> terraform1.stacks.AppliedChange + 45, // 24: terraform1.stacks.MigrateTerraformState.Request.Mapping.resource_address_map:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping.ResourceAddressMapEntry + 46, // 25: terraform1.stacks.MigrateTerraformState.Request.Mapping.module_address_map:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping.ModuleAddressMapEntry + 129, // 26: terraform1.stacks.OpenStackConfiguration.Request.source_address:type_name -> terraform1.SourceAddress + 128, // 27: terraform1.stacks.OpenStackConfiguration.Response.diagnostics:type_name -> terraform1.Diagnostic + 128, // 28: terraform1.stacks.ValidateStackConfiguration.Response.diagnostics:type_name -> terraform1.Diagnostic + 55, // 29: terraform1.stacks.FindStackConfigurationComponents.Response.config:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig + 61, // 30: terraform1.stacks.FindStackConfigurationComponents.StackConfig.components:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry + 62, // 31: terraform1.stacks.FindStackConfigurationComponents.StackConfig.embedded_stacks:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry + 63, // 32: terraform1.stacks.FindStackConfigurationComponents.StackConfig.input_variables:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry + 64, // 33: terraform1.stacks.FindStackConfigurationComponents.StackConfig.output_values:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry + 65, // 34: terraform1.stacks.FindStackConfigurationComponents.StackConfig.removed:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry + 3, // 35: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances + 55, // 36: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack.config:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig + 3, // 37: terraform1.stacks.FindStackConfigurationComponents.Component.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances + 3, // 38: terraform1.stacks.FindStackConfigurationComponents.Removed.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances + 66, // 39: terraform1.stacks.FindStackConfigurationComponents.Removed.blocks:type_name -> terraform1.stacks.FindStackConfigurationComponents.Removed.Block + 57, // 40: terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.Component + 56, // 41: terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack + 59, // 42: terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.InputVariable + 60, // 43: terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.OutputValue + 58, // 44: terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.Removed + 3, // 45: terraform1.stacks.FindStackConfigurationComponents.Removed.Block.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances + 102, // 46: terraform1.stacks.OpenStackState.RequestItem.raw:type_name -> terraform1.stacks.AppliedChange.RawChange + 1, // 47: terraform1.stacks.PlanStackChanges.Request.plan_mode:type_name -> terraform1.stacks.PlanMode + 73, // 48: terraform1.stacks.PlanStackChanges.Request.previous_state:type_name -> terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry + 74, // 49: terraform1.stacks.PlanStackChanges.Request.input_values:type_name -> terraform1.stacks.PlanStackChanges.Request.InputValuesEntry + 33, // 50: terraform1.stacks.PlanStackChanges.Event.planned_change:type_name -> terraform1.stacks.PlannedChange + 128, // 51: terraform1.stacks.PlanStackChanges.Event.diagnostic:type_name -> terraform1.Diagnostic + 36, // 52: terraform1.stacks.PlanStackChanges.Event.progress:type_name -> terraform1.stacks.StackChangeProgress + 127, // 53: terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry.value:type_name -> google.protobuf.Any + 27, // 54: terraform1.stacks.PlanStackChanges.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource + 127, // 55: terraform1.stacks.OpenStackPlan.RequestItem.raw:type_name -> google.protobuf.Any + 127, // 56: terraform1.stacks.ApplyStackChanges.Request.planned_changes:type_name -> google.protobuf.Any + 81, // 57: terraform1.stacks.ApplyStackChanges.Request.input_values:type_name -> terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry + 35, // 58: terraform1.stacks.ApplyStackChanges.Event.applied_change:type_name -> terraform1.stacks.AppliedChange + 128, // 59: terraform1.stacks.ApplyStackChanges.Event.diagnostic:type_name -> terraform1.Diagnostic + 36, // 60: terraform1.stacks.ApplyStackChanges.Event.progress:type_name -> terraform1.stacks.StackChangeProgress + 27, // 61: terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource + 84, // 62: terraform1.stacks.OpenStackInspector.Request.state:type_name -> terraform1.stacks.OpenStackInspector.Request.StateEntry + 85, // 63: terraform1.stacks.OpenStackInspector.Request.input_values:type_name -> terraform1.stacks.OpenStackInspector.Request.InputValuesEntry + 128, // 64: terraform1.stacks.OpenStackInspector.Response.diagnostics:type_name -> terraform1.Diagnostic + 127, // 65: terraform1.stacks.OpenStackInspector.Request.StateEntry.value:type_name -> google.protobuf.Any + 27, // 66: terraform1.stacks.OpenStackInspector.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource + 25, // 67: terraform1.stacks.InspectExpressionResult.Response.result:type_name -> terraform1.stacks.DynamicValue + 128, // 68: terraform1.stacks.InspectExpressionResult.Response.diagnostics:type_name -> terraform1.Diagnostic + 90, // 69: terraform1.stacks.PlannedChange.ChangeDescription.component_instance_planned:type_name -> terraform1.stacks.PlannedChange.ComponentInstance + 91, // 70: terraform1.stacks.PlannedChange.ChangeDescription.resource_instance_planned:type_name -> terraform1.stacks.PlannedChange.ResourceInstance + 92, // 71: terraform1.stacks.PlannedChange.ChangeDescription.output_value_planned:type_name -> terraform1.stacks.PlannedChange.OutputValue + 93, // 72: terraform1.stacks.PlannedChange.ChangeDescription.resource_instance_deferred:type_name -> terraform1.stacks.PlannedChange.ResourceInstanceDeferred + 94, // 73: terraform1.stacks.PlannedChange.ChangeDescription.input_variable_planned:type_name -> terraform1.stacks.PlannedChange.InputVariable + 95, // 74: terraform1.stacks.PlannedChange.ChangeDescription.action_invocation_planned:type_name -> terraform1.stacks.PlannedChange.ActionInvocationInstance + 96, // 75: terraform1.stacks.PlannedChange.ChangeDescription.action_invocation_deferred:type_name -> terraform1.stacks.PlannedChange.ActionInvocationDeferred + 29, // 76: terraform1.stacks.PlannedChange.ComponentInstance.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr + 2, // 77: terraform1.stacks.PlannedChange.ComponentInstance.actions:type_name -> terraform1.stacks.ChangeType + 32, // 78: terraform1.stacks.PlannedChange.ResourceInstance.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 2, // 79: terraform1.stacks.PlannedChange.ResourceInstance.actions:type_name -> terraform1.stacks.ChangeType + 26, // 80: terraform1.stacks.PlannedChange.ResourceInstance.values:type_name -> terraform1.stacks.DynamicValueChange + 100, // 81: terraform1.stacks.PlannedChange.ResourceInstance.moved:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Moved + 101, // 82: terraform1.stacks.PlannedChange.ResourceInstance.imported:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Imported + 0, // 83: terraform1.stacks.PlannedChange.ResourceInstance.resource_mode:type_name -> terraform1.stacks.ResourceMode + 25, // 84: terraform1.stacks.PlannedChange.ResourceInstance.previous_run_value:type_name -> terraform1.stacks.DynamicValue + 28, // 85: terraform1.stacks.PlannedChange.ResourceInstance.replace_paths:type_name -> terraform1.stacks.AttributePath + 99, // 86: terraform1.stacks.PlannedChange.ResourceInstance.index:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Index + 2, // 87: terraform1.stacks.PlannedChange.OutputValue.actions:type_name -> terraform1.stacks.ChangeType + 26, // 88: terraform1.stacks.PlannedChange.OutputValue.values:type_name -> terraform1.stacks.DynamicValueChange + 91, // 89: terraform1.stacks.PlannedChange.ResourceInstanceDeferred.resource_instance:type_name -> terraform1.stacks.PlannedChange.ResourceInstance + 34, // 90: terraform1.stacks.PlannedChange.ResourceInstanceDeferred.deferred:type_name -> terraform1.stacks.Deferred + 2, // 91: terraform1.stacks.PlannedChange.InputVariable.actions:type_name -> terraform1.stacks.ChangeType + 26, // 92: terraform1.stacks.PlannedChange.InputVariable.values:type_name -> terraform1.stacks.DynamicValueChange + 30, // 93: terraform1.stacks.PlannedChange.ActionInvocationInstance.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr + 25, // 94: terraform1.stacks.PlannedChange.ActionInvocationInstance.config_value:type_name -> terraform1.stacks.DynamicValue + 97, // 95: terraform1.stacks.PlannedChange.ActionInvocationInstance.lifecycle_action_trigger:type_name -> terraform1.stacks.PlannedChange.LifecycleActionTrigger + 98, // 96: terraform1.stacks.PlannedChange.ActionInvocationInstance.invoke_action_trigger:type_name -> terraform1.stacks.PlannedChange.InvokeActionTrigger + 34, // 97: terraform1.stacks.PlannedChange.ActionInvocationDeferred.deferred:type_name -> terraform1.stacks.Deferred + 95, // 98: terraform1.stacks.PlannedChange.ActionInvocationDeferred.action_invocation:type_name -> terraform1.stacks.PlannedChange.ActionInvocationInstance + 31, // 99: terraform1.stacks.PlannedChange.LifecycleActionTrigger.triggering_resource_address:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 4, // 100: terraform1.stacks.PlannedChange.LifecycleActionTrigger.trigger_event:type_name -> terraform1.stacks.PlannedChange.ActionTriggerEvent + 25, // 101: terraform1.stacks.PlannedChange.ResourceInstance.Index.value:type_name -> terraform1.stacks.DynamicValue + 31, // 102: terraform1.stacks.PlannedChange.ResourceInstance.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 127, // 103: terraform1.stacks.AppliedChange.RawChange.value:type_name -> google.protobuf.Any + 108, // 104: terraform1.stacks.AppliedChange.ChangeDescription.deleted:type_name -> terraform1.stacks.AppliedChange.Nothing + 108, // 105: terraform1.stacks.AppliedChange.ChangeDescription.moved:type_name -> terraform1.stacks.AppliedChange.Nothing + 104, // 106: terraform1.stacks.AppliedChange.ChangeDescription.resource_instance:type_name -> terraform1.stacks.AppliedChange.ResourceInstance + 106, // 107: terraform1.stacks.AppliedChange.ChangeDescription.output_value:type_name -> terraform1.stacks.AppliedChange.OutputValue + 107, // 108: terraform1.stacks.AppliedChange.ChangeDescription.input_variable:type_name -> terraform1.stacks.AppliedChange.InputVariable + 105, // 109: terraform1.stacks.AppliedChange.ChangeDescription.component_instance:type_name -> terraform1.stacks.AppliedChange.ComponentInstance + 32, // 110: terraform1.stacks.AppliedChange.ResourceInstance.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 25, // 111: terraform1.stacks.AppliedChange.ResourceInstance.new_value:type_name -> terraform1.stacks.DynamicValue + 0, // 112: terraform1.stacks.AppliedChange.ResourceInstance.resource_mode:type_name -> terraform1.stacks.ResourceMode + 109, // 113: terraform1.stacks.AppliedChange.ComponentInstance.output_values:type_name -> terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry + 25, // 114: terraform1.stacks.AppliedChange.OutputValue.new_value:type_name -> terraform1.stacks.DynamicValue + 25, // 115: terraform1.stacks.AppliedChange.InputVariable.new_value:type_name -> terraform1.stacks.DynamicValue + 25, // 116: terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry.value:type_name -> terraform1.stacks.DynamicValue + 29, // 117: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr + 7, // 118: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.Status + 32, // 119: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 8, // 120: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.Status + 32, // 121: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 2, // 122: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.actions:type_name -> terraform1.stacks.ChangeType + 121, // 123: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.moved:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved + 122, // 124: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.imported:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Imported + 34, // 125: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange.deferred:type_name -> terraform1.stacks.Deferred + 112, // 126: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange.change:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange + 30, // 127: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr + 115, // 128: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.lifecycle_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.LifecycleActionTrigger + 116, // 129: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.invoke_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.InvokeActionTrigger + 31, // 130: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.triggering_resource_address:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 6, // 131: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.trigger_event:type_name -> terraform1.stacks.StackChangeProgress.ActionTriggerEvent + 32, // 132: terraform1.stacks.StackChangeProgress.ProvisionerStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 117, // 133: terraform1.stacks.StackChangeProgress.ProvisionerStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus + 32, // 134: terraform1.stacks.StackChangeProgress.ProvisionerOutput.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 29, // 135: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr + 31, // 136: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 125, // 137: terraform1.stacks.ListResourceIdentities.Response.resource:type_name -> terraform1.stacks.ListResourceIdentities.Resource + 25, // 138: terraform1.stacks.ListResourceIdentities.Resource.resource_identity:type_name -> terraform1.stacks.DynamicValue + 47, // 139: terraform1.stacks.Stacks.OpenStackConfiguration:input_type -> terraform1.stacks.OpenStackConfiguration.Request + 49, // 140: terraform1.stacks.Stacks.CloseStackConfiguration:input_type -> terraform1.stacks.CloseStackConfiguration.Request + 51, // 141: terraform1.stacks.Stacks.ValidateStackConfiguration:input_type -> terraform1.stacks.ValidateStackConfiguration.Request + 53, // 142: terraform1.stacks.Stacks.FindStackConfigurationComponents:input_type -> terraform1.stacks.FindStackConfigurationComponents.Request + 67, // 143: terraform1.stacks.Stacks.OpenState:input_type -> terraform1.stacks.OpenStackState.RequestItem + 69, // 144: terraform1.stacks.Stacks.CloseState:input_type -> terraform1.stacks.CloseStackState.Request + 71, // 145: terraform1.stacks.Stacks.PlanStackChanges:input_type -> terraform1.stacks.PlanStackChanges.Request + 75, // 146: terraform1.stacks.Stacks.OpenPlan:input_type -> terraform1.stacks.OpenStackPlan.RequestItem + 77, // 147: terraform1.stacks.Stacks.ClosePlan:input_type -> terraform1.stacks.CloseStackPlan.Request + 79, // 148: terraform1.stacks.Stacks.ApplyStackChanges:input_type -> terraform1.stacks.ApplyStackChanges.Request + 82, // 149: terraform1.stacks.Stacks.OpenStackInspector:input_type -> terraform1.stacks.OpenStackInspector.Request + 86, // 150: terraform1.stacks.Stacks.InspectExpressionResult:input_type -> terraform1.stacks.InspectExpressionResult.Request + 38, // 151: terraform1.stacks.Stacks.OpenTerraformState:input_type -> terraform1.stacks.OpenTerraformState.Request + 40, // 152: terraform1.stacks.Stacks.CloseTerraformState:input_type -> terraform1.stacks.CloseTerraformState.Request + 42, // 153: terraform1.stacks.Stacks.MigrateTerraformState:input_type -> terraform1.stacks.MigrateTerraformState.Request + 123, // 154: terraform1.stacks.Stacks.ListResourceIdentities:input_type -> terraform1.stacks.ListResourceIdentities.Request + 48, // 155: terraform1.stacks.Stacks.OpenStackConfiguration:output_type -> terraform1.stacks.OpenStackConfiguration.Response + 50, // 156: terraform1.stacks.Stacks.CloseStackConfiguration:output_type -> terraform1.stacks.CloseStackConfiguration.Response + 52, // 157: terraform1.stacks.Stacks.ValidateStackConfiguration:output_type -> terraform1.stacks.ValidateStackConfiguration.Response + 54, // 158: terraform1.stacks.Stacks.FindStackConfigurationComponents:output_type -> terraform1.stacks.FindStackConfigurationComponents.Response + 68, // 159: terraform1.stacks.Stacks.OpenState:output_type -> terraform1.stacks.OpenStackState.Response + 70, // 160: terraform1.stacks.Stacks.CloseState:output_type -> terraform1.stacks.CloseStackState.Response + 72, // 161: terraform1.stacks.Stacks.PlanStackChanges:output_type -> terraform1.stacks.PlanStackChanges.Event + 76, // 162: terraform1.stacks.Stacks.OpenPlan:output_type -> terraform1.stacks.OpenStackPlan.Response + 78, // 163: terraform1.stacks.Stacks.ClosePlan:output_type -> terraform1.stacks.CloseStackPlan.Response + 80, // 164: terraform1.stacks.Stacks.ApplyStackChanges:output_type -> terraform1.stacks.ApplyStackChanges.Event + 83, // 165: terraform1.stacks.Stacks.OpenStackInspector:output_type -> terraform1.stacks.OpenStackInspector.Response + 87, // 166: terraform1.stacks.Stacks.InspectExpressionResult:output_type -> terraform1.stacks.InspectExpressionResult.Response + 39, // 167: terraform1.stacks.Stacks.OpenTerraformState:output_type -> terraform1.stacks.OpenTerraformState.Response + 41, // 168: terraform1.stacks.Stacks.CloseTerraformState:output_type -> terraform1.stacks.CloseTerraformState.Response + 43, // 169: terraform1.stacks.Stacks.MigrateTerraformState:output_type -> terraform1.stacks.MigrateTerraformState.Event + 124, // 170: terraform1.stacks.Stacks.ListResourceIdentities:output_type -> terraform1.stacks.ListResourceIdentities.Response + 155, // [155:171] is the sub-list for method output_type + 139, // [139:155] is the sub-list for method input_type + 139, // [139:139] is the sub-list for extension type_name + 139, // [139:139] is the sub-list for extension extendee + 0, // [0:139] is the sub-list for field type_name } func init() { file_stacks_proto_init() } @@ -7155,7 +7972,7 @@ func file_stacks_proto_init() { if File_stacks_proto != nil { return } - file_stacks_proto_msgTypes[25].OneofWrappers = []any{ + file_stacks_proto_msgTypes[26].OneofWrappers = []any{ (*StackChangeProgress_ComponentInstanceStatus_)(nil), (*StackChangeProgress_ResourceInstanceStatus_)(nil), (*StackChangeProgress_ResourceInstancePlannedChange_)(nil), @@ -7164,42 +7981,49 @@ func file_stacks_proto_init() { (*StackChangeProgress_ComponentInstanceChanges_)(nil), (*StackChangeProgress_ComponentInstances_)(nil), (*StackChangeProgress_DeferredResourceInstancePlannedChange_)(nil), + (*StackChangeProgress_ActionInvocationPlanned_)(nil), } - file_stacks_proto_msgTypes[27].OneofWrappers = []any{ + file_stacks_proto_msgTypes[28].OneofWrappers = []any{ (*OpenTerraformState_Request_ConfigPath)(nil), (*OpenTerraformState_Request_Raw)(nil), } - file_stacks_proto_msgTypes[31].OneofWrappers = []any{ + file_stacks_proto_msgTypes[32].OneofWrappers = []any{ (*MigrateTerraformState_Request_Simple)(nil), } - file_stacks_proto_msgTypes[32].OneofWrappers = []any{ + file_stacks_proto_msgTypes[33].OneofWrappers = []any{ (*MigrateTerraformState_Event_Diagnostic)(nil), (*MigrateTerraformState_Event_AppliedChange)(nil), } - file_stacks_proto_msgTypes[61].OneofWrappers = []any{ + file_stacks_proto_msgTypes[62].OneofWrappers = []any{ (*PlanStackChanges_Event_PlannedChange)(nil), (*PlanStackChanges_Event_Diagnostic)(nil), (*PlanStackChanges_Event_Progress)(nil), } - file_stacks_proto_msgTypes[69].OneofWrappers = []any{ + file_stacks_proto_msgTypes[70].OneofWrappers = []any{ (*ApplyStackChanges_Event_AppliedChange)(nil), (*ApplyStackChanges_Event_Diagnostic)(nil), (*ApplyStackChanges_Event_Progress)(nil), } - file_stacks_proto_msgTypes[77].OneofWrappers = []any{ + file_stacks_proto_msgTypes[78].OneofWrappers = []any{ (*AttributePath_Step_AttributeName)(nil), (*AttributePath_Step_ElementKeyString)(nil), (*AttributePath_Step_ElementKeyInt)(nil), } - file_stacks_proto_msgTypes[78].OneofWrappers = []any{ + file_stacks_proto_msgTypes[79].OneofWrappers = []any{ (*PlannedChange_ChangeDescription_ComponentInstancePlanned)(nil), (*PlannedChange_ChangeDescription_ResourceInstancePlanned)(nil), (*PlannedChange_ChangeDescription_OutputValuePlanned)(nil), (*PlannedChange_ChangeDescription_PlanApplyable)(nil), (*PlannedChange_ChangeDescription_ResourceInstanceDeferred)(nil), (*PlannedChange_ChangeDescription_InputVariablePlanned)(nil), + (*PlannedChange_ChangeDescription_ActionInvocationPlanned)(nil), + (*PlannedChange_ChangeDescription_ActionInvocationDeferred)(nil), } - file_stacks_proto_msgTypes[88].OneofWrappers = []any{ + file_stacks_proto_msgTypes[85].OneofWrappers = []any{ + (*PlannedChange_ActionInvocationInstance_LifecycleActionTrigger)(nil), + (*PlannedChange_ActionInvocationInstance_InvokeActionTrigger)(nil), + } + file_stacks_proto_msgTypes[93].OneofWrappers = []any{ (*AppliedChange_ChangeDescription_Deleted)(nil), (*AppliedChange_ChangeDescription_Moved)(nil), (*AppliedChange_ChangeDescription_ResourceInstance)(nil), @@ -7207,13 +8031,17 @@ func file_stacks_proto_init() { (*AppliedChange_ChangeDescription_InputVariable)(nil), (*AppliedChange_ChangeDescription_ComponentInstance)(nil), } + file_stacks_proto_msgTypes[104].OneofWrappers = []any{ + (*StackChangeProgress_ActionInvocationPlanned_LifecycleActionTrigger)(nil), + (*StackChangeProgress_ActionInvocationPlanned_InvokeActionTrigger)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_stacks_proto_rawDesc), len(file_stacks_proto_rawDesc)), - NumEnums: 8, - NumMessages: 108, + NumEnums: 10, + NumMessages: 116, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/rpcapi/terraform1/stacks/stacks.proto b/internal/rpcapi/terraform1/stacks/stacks.proto index 80bcc8ae40..6ed0c98a20 100644 --- a/internal/rpcapi/terraform1/stacks/stacks.proto +++ b/internal/rpcapi/terraform1/stacks/stacks.proto @@ -417,6 +417,19 @@ message ComponentInstanceInStackAddr { string component_instance_addr = 2; } +// Represents the address of a specific action inside a specific +// component instance within the containing stack. +message ActionInvocationInstanceInStackAddr { + // Unique address of the component instance that this action instance + // belongs to. + string component_instance_addr = 1; + // Unique address of the action instance within the given component + // instance. Each component instance has a separate namespace of + // action instance addresses, so callers must take both fields together + // to produce a key that's unique throughout the entire plan. + string action_invocation_instance_addr = 2; +} + // Represents the address of a specific resource instance inside a specific // component instance within the containing stack. message ResourceInstanceInStackAddr { @@ -525,6 +538,8 @@ message PlannedChange { bool plan_applyable = 4; ResourceInstanceDeferred resource_instance_deferred = 5; InputVariable input_variable_planned = 6; + ActionInvocationInstance action_invocation_planned = 7; + ActionInvocationDeferred action_invocation_deferred = 8; } } @@ -627,6 +642,63 @@ message PlannedChange { DynamicValueChange values = 3; bool required_during_apply = 4; } + + // ActionTriggerEvent describes the reason an action was triggered + enum ActionTriggerEvent { + INVALID_EVENT = 0; + BEFORE_CREATE = 1; + AFTER_CREATE = 2; + BEFORE_UPDATE = 3; + AFTER_UPDATE = 4; + BEFORE_DESTROY = 5; + AFTER_DESTROY = 6; + INVOKE = 7; + } + + // ActionInvocationInstance contains a planned action invocation and any embedded ResourceInstanceActionChanges + message ActionInvocationInstance { + ActionInvocationInstanceInStackAddr addr = 1; + + // provider is the address of the provider configuration that this change + // was planned with, and thus the configuration that must be used to + // apply it. + string provider_addr = 2; + + // The type of the action used to extract schema information + string action_type = 3; + + DynamicValue config_value = 4; + + oneof action_trigger { + LifecycleActionTrigger lifecycle_action_trigger = 6; + InvokeActionTrigger invoke_action_trigger = 7; + } + } + + // ActionInvocationDeferred represents an action invocation that + // was deferred for some reason. + // It contains the original action invocation that was deferred, along with the reason + // why it was deferred. + message ActionInvocationDeferred { + // The reason why it was deferred + Deferred deferred = 1; + + // The original action invocation that was deferred + ActionInvocationInstance action_invocation = 2; + } + + // LifecycleActionTrigger contains details on the conditions that led to the + // triggering of an action. + message LifecycleActionTrigger { + ResourceInstanceInStackAddr triggering_resource_address = 1; + ActionTriggerEvent trigger_event = 2; + int64 action_trigger_block_index = 3; + int64 actions_list_index = 4; + } + + // InvokeActionTrigger indicates the action was triggered by the invoke command + // on the CLI. + message InvokeActionTrigger {} } // Deferred contains all the metadata about a the deferral of a resource @@ -793,6 +865,7 @@ message StackChangeProgress { ComponentInstanceChanges component_instance_changes = 6; ComponentInstances component_instances = 7; DeferredResourceInstancePlannedChange deferred_resource_instance_planned_change = 8; + ActionInvocationPlanned action_invocation_planned = 9; } // ComponentInstanceStatus describes the current status of a component instance @@ -861,6 +934,40 @@ message StackChangeProgress { ResourceInstancePlannedChange change = 2; } + message ActionInvocationPlanned { + ActionInvocationInstanceInStackAddr addr = 1; + string provider_addr = 2; + oneof action_trigger { + LifecycleActionTrigger lifecycle_action_trigger = 3; + InvokeActionTrigger invoke_action_trigger = 4; + } + } + + // LifecycleActionTrigger contains details on the conditions that led to the + // triggering of an action. + message LifecycleActionTrigger { + ResourceInstanceInStackAddr triggering_resource_address = 1; + ActionTriggerEvent trigger_event = 2; + int64 action_trigger_block_index = 3; + int64 actions_list_index = 4; + } + + // InvokeActionTrigger indicates the action was triggered by the invoke command + // on the CLI. + message InvokeActionTrigger {} + + // ActionTriggerEvent describes the reason an action was triggered + enum ActionTriggerEvent { + INVALID_EVENT = 0; + BEFORE_CREATE = 1; + AFTER_CREATE = 2; + BEFORE_UPDATE = 3; + AFTER_UPDATE = 4; + BEFORE_DESTROY = 5; + AFTER_DESTROY = 6; + INVOKE = 7; + } + // ProvisionerStatus represents the progress of a given provisioner during its // resource instance's apply operation. message ProvisionerStatus { diff --git a/internal/stacks/stackaddrs/in_component.go b/internal/stacks/stackaddrs/in_component.go index 0daf29c123..7283720efe 100644 --- a/internal/stacks/stackaddrs/in_component.go +++ b/internal/stacks/stackaddrs/in_component.go @@ -87,6 +87,10 @@ type AbsResourceInstance = InAbsComponentInstance[addrs.AbsResourceInstance] // of a resource from inside a particular component instance. type AbsResourceInstanceObject = InAbsComponentInstance[addrs.AbsResourceInstanceObject] +// AbsActionInvocationInstance represents an instance of an action from inside a +// particular component instance. +type AbsActionInvocationInstance = InAbsComponentInstance[addrs.AbsActionInstance] + // AbsModuleInstance represents an instance of a module from inside a // particular component instance. // diff --git a/internal/stacks/tfstackdata1/tfstackdata1.pb.go b/internal/stacks/tfstackdata1/tfstackdata1.pb.go index b2020138f3..983859af93 100644 --- a/internal/stacks/tfstackdata1/tfstackdata1.pb.go +++ b/internal/stacks/tfstackdata1/tfstackdata1.pb.go @@ -72,7 +72,7 @@ func (x StateResourceInstanceObjectV1_Status) Number() protoreflect.EnumNumber { // Deprecated: Use StateResourceInstanceObjectV1_Status.Descriptor instead. func (StateResourceInstanceObjectV1_Status) EnumDescriptor() ([]byte, []int) { - return file_tfstackdata1_proto_rawDescGZIP(), []int{14, 0} + return file_tfstackdata1_proto_rawDescGZIP(), []int{16, 0} } // Appears early in a raw plan sequence to capture some metadata that we need @@ -898,6 +898,134 @@ func (x *PlanDeferredResourceInstanceChange) GetChange() *PlanResourceInstanceCh return nil } +type PlanActionInvocationPlanned struct { + state protoimpl.MessageState `protogen:"open.v1"` + // 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"` + ActionInvocationAddr string `protobuf:"bytes,3,opt,name=action_invocation_addr,json=actionInvocationAddr,proto3" json:"action_invocation_addr,omitempty"` + // The address of the provider configuration that planned this change, + // or that produced the prior state for messages where "change" is + // unpopulated. This is a module-centric view relative to the root module + // of the component identified in component_instance_addr. + ProviderConfigAddr string `protobuf:"bytes,4,opt,name=provider_config_addr,json=providerConfigAddr,proto3" json:"provider_config_addr,omitempty"` + Invocation *planproto.ActionInvocationInstance `protobuf:"bytes,2,opt,name=invocation,proto3" json:"invocation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PlanActionInvocationPlanned) Reset() { + *x = PlanActionInvocationPlanned{} + mi := &file_tfstackdata1_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PlanActionInvocationPlanned) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanActionInvocationPlanned) ProtoMessage() {} + +func (x *PlanActionInvocationPlanned) ProtoReflect() protoreflect.Message { + mi := &file_tfstackdata1_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlanActionInvocationPlanned.ProtoReflect.Descriptor instead. +func (*PlanActionInvocationPlanned) Descriptor() ([]byte, []int) { + return file_tfstackdata1_proto_rawDescGZIP(), []int{12} +} + +func (x *PlanActionInvocationPlanned) GetComponentInstanceAddr() string { + if x != nil { + return x.ComponentInstanceAddr + } + return "" +} + +func (x *PlanActionInvocationPlanned) GetActionInvocationAddr() string { + if x != nil { + return x.ActionInvocationAddr + } + return "" +} + +func (x *PlanActionInvocationPlanned) GetProviderConfigAddr() string { + if x != nil { + return x.ProviderConfigAddr + } + return "" +} + +func (x *PlanActionInvocationPlanned) GetInvocation() *planproto.ActionInvocationInstance { + if x != nil { + return x.Invocation + } + return nil +} + +// Represents a deferred change to a particular action invocation within a +// particular component instance. +type PlanDeferredActionInvocation struct { + state protoimpl.MessageState `protogen:"open.v1"` + Deferred *planproto.Deferred `protobuf:"bytes,1,opt,name=deferred,proto3" json:"deferred,omitempty"` + Invocation *PlanActionInvocationPlanned `protobuf:"bytes,2,opt,name=invocation,proto3" json:"invocation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PlanDeferredActionInvocation) Reset() { + *x = PlanDeferredActionInvocation{} + mi := &file_tfstackdata1_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PlanDeferredActionInvocation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanDeferredActionInvocation) ProtoMessage() {} + +func (x *PlanDeferredActionInvocation) ProtoReflect() protoreflect.Message { + mi := &file_tfstackdata1_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlanDeferredActionInvocation.ProtoReflect.Descriptor instead. +func (*PlanDeferredActionInvocation) Descriptor() ([]byte, []int) { + return file_tfstackdata1_proto_rawDescGZIP(), []int{13} +} + +func (x *PlanDeferredActionInvocation) GetDeferred() *planproto.Deferred { + if x != nil { + return x.Deferred + } + return nil +} + +func (x *PlanDeferredActionInvocation) GetInvocation() *PlanActionInvocationPlanned { + if x != nil { + return x.Invocation + } + return nil +} + // Represents that we need to emit "delete" requests for one or more raw // state and/or state description objects during the apply phase. // @@ -918,7 +1046,7 @@ type PlanDiscardStateMapKeys struct { func (x *PlanDiscardStateMapKeys) Reset() { *x = PlanDiscardStateMapKeys{} - mi := &file_tfstackdata1_proto_msgTypes[12] + mi := &file_tfstackdata1_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -930,7 +1058,7 @@ func (x *PlanDiscardStateMapKeys) String() string { func (*PlanDiscardStateMapKeys) ProtoMessage() {} func (x *PlanDiscardStateMapKeys) ProtoReflect() protoreflect.Message { - mi := &file_tfstackdata1_proto_msgTypes[12] + mi := &file_tfstackdata1_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -943,7 +1071,7 @@ func (x *PlanDiscardStateMapKeys) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanDiscardStateMapKeys.ProtoReflect.Descriptor instead. func (*PlanDiscardStateMapKeys) Descriptor() ([]byte, []int) { - return file_tfstackdata1_proto_rawDescGZIP(), []int{12} + return file_tfstackdata1_proto_rawDescGZIP(), []int{14} } func (x *PlanDiscardStateMapKeys) GetRawStateKeys() []string { @@ -1004,7 +1132,7 @@ type StateComponentInstanceV1 struct { func (x *StateComponentInstanceV1) Reset() { *x = StateComponentInstanceV1{} - mi := &file_tfstackdata1_proto_msgTypes[13] + mi := &file_tfstackdata1_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1016,7 +1144,7 @@ func (x *StateComponentInstanceV1) String() string { func (*StateComponentInstanceV1) ProtoMessage() {} func (x *StateComponentInstanceV1) ProtoReflect() protoreflect.Message { - mi := &file_tfstackdata1_proto_msgTypes[13] + mi := &file_tfstackdata1_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1029,7 +1157,7 @@ func (x *StateComponentInstanceV1) ProtoReflect() protoreflect.Message { // Deprecated: Use StateComponentInstanceV1.ProtoReflect.Descriptor instead. func (*StateComponentInstanceV1) Descriptor() ([]byte, []int) { - return file_tfstackdata1_proto_rawDescGZIP(), []int{13} + return file_tfstackdata1_proto_rawDescGZIP(), []int{15} } func (x *StateComponentInstanceV1) GetOutputValues() map[string]*DynamicValue { @@ -1100,7 +1228,7 @@ type StateResourceInstanceObjectV1 struct { func (x *StateResourceInstanceObjectV1) Reset() { *x = StateResourceInstanceObjectV1{} - mi := &file_tfstackdata1_proto_msgTypes[14] + mi := &file_tfstackdata1_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1112,7 +1240,7 @@ func (x *StateResourceInstanceObjectV1) String() string { func (*StateResourceInstanceObjectV1) ProtoMessage() {} func (x *StateResourceInstanceObjectV1) ProtoReflect() protoreflect.Message { - mi := &file_tfstackdata1_proto_msgTypes[14] + mi := &file_tfstackdata1_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1125,7 +1253,7 @@ func (x *StateResourceInstanceObjectV1) ProtoReflect() protoreflect.Message { // Deprecated: Use StateResourceInstanceObjectV1.ProtoReflect.Descriptor instead. func (*StateResourceInstanceObjectV1) Descriptor() ([]byte, []int) { - return file_tfstackdata1_proto_rawDescGZIP(), []int{14} + return file_tfstackdata1_proto_rawDescGZIP(), []int{16} } func (x *StateResourceInstanceObjectV1) GetValueJson() []byte { @@ -1194,7 +1322,7 @@ type DynamicValue struct { func (x *DynamicValue) Reset() { *x = DynamicValue{} - mi := &file_tfstackdata1_proto_msgTypes[15] + mi := &file_tfstackdata1_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1206,7 +1334,7 @@ func (x *DynamicValue) String() string { func (*DynamicValue) ProtoMessage() {} func (x *DynamicValue) ProtoReflect() protoreflect.Message { - mi := &file_tfstackdata1_proto_msgTypes[15] + mi := &file_tfstackdata1_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1219,7 +1347,7 @@ func (x *DynamicValue) ProtoReflect() protoreflect.Message { // Deprecated: Use DynamicValue.ProtoReflect.Descriptor instead. func (*DynamicValue) Descriptor() ([]byte, []int) { - return file_tfstackdata1_proto_rawDescGZIP(), []int{15} + return file_tfstackdata1_proto_rawDescGZIP(), []int{17} } func (x *DynamicValue) GetValue() *planproto.DynamicValue { @@ -1293,7 +1421,19 @@ const file_tfstackdata1_proto_rawDesc = "" + "priorState\"\x9b\x01\n" + "\"PlanDeferredResourceInstanceChange\x12,\n" + "\bdeferred\x18\x01 \x01(\v2\x10.tfplan.DeferredR\bdeferred\x12G\n" + - "\x06change\x18\x02 \x01(\v2/.tfstackdata1.PlanResourceInstanceChangePlannedR\x06change\"j\n" + + "\x06change\x18\x02 \x01(\v2/.tfstackdata1.PlanResourceInstanceChangePlannedR\x06change\"\xff\x01\n" + + "\x1bPlanActionInvocationPlanned\x126\n" + + "\x17component_instance_addr\x18\x01 \x01(\tR\x15componentInstanceAddr\x124\n" + + "\x16action_invocation_addr\x18\x03 \x01(\tR\x14actionInvocationAddr\x120\n" + + "\x14provider_config_addr\x18\x04 \x01(\tR\x12providerConfigAddr\x12@\n" + + "\n" + + "invocation\x18\x02 \x01(\v2 .tfplan.ActionInvocationInstanceR\n" + + "invocation\"\x97\x01\n" + + "\x1cPlanDeferredActionInvocation\x12,\n" + + "\bdeferred\x18\x01 \x01(\v2\x10.tfplan.DeferredR\bdeferred\x12I\n" + + "\n" + + "invocation\x18\x02 \x01(\v2).tfstackdata1.PlanActionInvocationPlannedR\n" + + "invocation\"j\n" + "\x17PlanDiscardStateMapKeys\x12$\n" + "\x0eraw_state_keys\x18\x01 \x03(\tR\frawStateKeys\x12)\n" + "\x10description_keys\x18\x02 \x03(\tR\x0fdescriptionKeys\"\xee\x03\n" + @@ -1339,7 +1479,7 @@ func file_tfstackdata1_proto_rawDescGZIP() []byte { } var file_tfstackdata1_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_tfstackdata1_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_tfstackdata1_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_tfstackdata1_proto_goTypes = []any{ (StateResourceInstanceObjectV1_Status)(0), // 0: tfstackdata1.StateResourceInstanceObjectV1.Status (*PlanHeader)(nil), // 1: tfstackdata1.PlanHeader @@ -1354,53 +1494,59 @@ var file_tfstackdata1_proto_goTypes = []any{ (*PlanComponentInstance)(nil), // 10: tfstackdata1.PlanComponentInstance (*PlanResourceInstanceChangePlanned)(nil), // 11: tfstackdata1.PlanResourceInstanceChangePlanned (*PlanDeferredResourceInstanceChange)(nil), // 12: tfstackdata1.PlanDeferredResourceInstanceChange - (*PlanDiscardStateMapKeys)(nil), // 13: tfstackdata1.PlanDiscardStateMapKeys - (*StateComponentInstanceV1)(nil), // 14: tfstackdata1.StateComponentInstanceV1 - (*StateResourceInstanceObjectV1)(nil), // 15: tfstackdata1.StateResourceInstanceObjectV1 - (*DynamicValue)(nil), // 16: tfstackdata1.DynamicValue - nil, // 17: tfstackdata1.PlanComponentInstance.PlannedInputValuesEntry - nil, // 18: tfstackdata1.PlanComponentInstance.PlannedOutputValuesEntry - nil, // 19: tfstackdata1.StateComponentInstanceV1.OutputValuesEntry - nil, // 20: tfstackdata1.StateComponentInstanceV1.InputVariablesEntry - (*anypb.Any)(nil), // 21: google.protobuf.Any - (*planproto.FunctionCallHash)(nil), // 22: tfplan.FunctionCallHash - (planproto.Action)(0), // 23: tfplan.Action - (planproto.Mode)(0), // 24: tfplan.Mode - (*planproto.CheckResults)(nil), // 25: tfplan.CheckResults - (*planproto.ResourceInstanceChange)(nil), // 26: tfplan.ResourceInstanceChange - (*planproto.Deferred)(nil), // 27: tfplan.Deferred - (*planproto.Path)(nil), // 28: tfplan.Path - (*planproto.DynamicValue)(nil), // 29: tfplan.DynamicValue + (*PlanActionInvocationPlanned)(nil), // 13: tfstackdata1.PlanActionInvocationPlanned + (*PlanDeferredActionInvocation)(nil), // 14: tfstackdata1.PlanDeferredActionInvocation + (*PlanDiscardStateMapKeys)(nil), // 15: tfstackdata1.PlanDiscardStateMapKeys + (*StateComponentInstanceV1)(nil), // 16: tfstackdata1.StateComponentInstanceV1 + (*StateResourceInstanceObjectV1)(nil), // 17: tfstackdata1.StateResourceInstanceObjectV1 + (*DynamicValue)(nil), // 18: tfstackdata1.DynamicValue + nil, // 19: tfstackdata1.PlanComponentInstance.PlannedInputValuesEntry + nil, // 20: tfstackdata1.PlanComponentInstance.PlannedOutputValuesEntry + nil, // 21: tfstackdata1.StateComponentInstanceV1.OutputValuesEntry + nil, // 22: tfstackdata1.StateComponentInstanceV1.InputVariablesEntry + (*anypb.Any)(nil), // 23: google.protobuf.Any + (*planproto.FunctionCallHash)(nil), // 24: tfplan.FunctionCallHash + (planproto.Action)(0), // 25: tfplan.Action + (planproto.Mode)(0), // 26: tfplan.Mode + (*planproto.CheckResults)(nil), // 27: tfplan.CheckResults + (*planproto.ResourceInstanceChange)(nil), // 28: tfplan.ResourceInstanceChange + (*planproto.Deferred)(nil), // 29: tfplan.Deferred + (*planproto.ActionInvocationInstance)(nil), // 30: tfplan.ActionInvocationInstance + (*planproto.Path)(nil), // 31: tfplan.Path + (*planproto.DynamicValue)(nil), // 32: tfplan.DynamicValue } var file_tfstackdata1_proto_depIdxs = []int32{ - 21, // 0: tfstackdata1.PlanPriorStateElem.raw:type_name -> google.protobuf.Any - 16, // 1: tfstackdata1.PlanRootInputValue.value:type_name -> tfstackdata1.DynamicValue - 22, // 2: tfstackdata1.FunctionResults.function_results:type_name -> tfplan.FunctionCallHash - 17, // 3: tfstackdata1.PlanComponentInstance.planned_input_values:type_name -> tfstackdata1.PlanComponentInstance.PlannedInputValuesEntry - 23, // 4: tfstackdata1.PlanComponentInstance.planned_action:type_name -> tfplan.Action - 24, // 5: tfstackdata1.PlanComponentInstance.mode:type_name -> tfplan.Mode - 18, // 6: tfstackdata1.PlanComponentInstance.planned_output_values:type_name -> tfstackdata1.PlanComponentInstance.PlannedOutputValuesEntry - 25, // 7: tfstackdata1.PlanComponentInstance.planned_check_results:type_name -> tfplan.CheckResults - 22, // 8: tfstackdata1.PlanComponentInstance.function_results:type_name -> tfplan.FunctionCallHash - 26, // 9: tfstackdata1.PlanResourceInstanceChangePlanned.change:type_name -> tfplan.ResourceInstanceChange - 15, // 10: tfstackdata1.PlanResourceInstanceChangePlanned.prior_state:type_name -> tfstackdata1.StateResourceInstanceObjectV1 - 27, // 11: tfstackdata1.PlanDeferredResourceInstanceChange.deferred:type_name -> tfplan.Deferred + 23, // 0: tfstackdata1.PlanPriorStateElem.raw:type_name -> google.protobuf.Any + 18, // 1: tfstackdata1.PlanRootInputValue.value:type_name -> tfstackdata1.DynamicValue + 24, // 2: tfstackdata1.FunctionResults.function_results:type_name -> tfplan.FunctionCallHash + 19, // 3: tfstackdata1.PlanComponentInstance.planned_input_values:type_name -> tfstackdata1.PlanComponentInstance.PlannedInputValuesEntry + 25, // 4: tfstackdata1.PlanComponentInstance.planned_action:type_name -> tfplan.Action + 26, // 5: tfstackdata1.PlanComponentInstance.mode:type_name -> tfplan.Mode + 20, // 6: tfstackdata1.PlanComponentInstance.planned_output_values:type_name -> tfstackdata1.PlanComponentInstance.PlannedOutputValuesEntry + 27, // 7: tfstackdata1.PlanComponentInstance.planned_check_results:type_name -> tfplan.CheckResults + 24, // 8: tfstackdata1.PlanComponentInstance.function_results:type_name -> tfplan.FunctionCallHash + 28, // 9: tfstackdata1.PlanResourceInstanceChangePlanned.change:type_name -> tfplan.ResourceInstanceChange + 17, // 10: tfstackdata1.PlanResourceInstanceChangePlanned.prior_state:type_name -> tfstackdata1.StateResourceInstanceObjectV1 + 29, // 11: tfstackdata1.PlanDeferredResourceInstanceChange.deferred:type_name -> tfplan.Deferred 11, // 12: tfstackdata1.PlanDeferredResourceInstanceChange.change:type_name -> tfstackdata1.PlanResourceInstanceChangePlanned - 19, // 13: tfstackdata1.StateComponentInstanceV1.output_values:type_name -> tfstackdata1.StateComponentInstanceV1.OutputValuesEntry - 20, // 14: tfstackdata1.StateComponentInstanceV1.input_variables:type_name -> tfstackdata1.StateComponentInstanceV1.InputVariablesEntry - 28, // 15: tfstackdata1.StateResourceInstanceObjectV1.sensitive_paths:type_name -> tfplan.Path - 0, // 16: tfstackdata1.StateResourceInstanceObjectV1.status:type_name -> tfstackdata1.StateResourceInstanceObjectV1.Status - 29, // 17: tfstackdata1.DynamicValue.value:type_name -> tfplan.DynamicValue - 28, // 18: tfstackdata1.DynamicValue.sensitive_paths:type_name -> tfplan.Path - 16, // 19: tfstackdata1.PlanComponentInstance.PlannedInputValuesEntry.value:type_name -> tfstackdata1.DynamicValue - 16, // 20: tfstackdata1.PlanComponentInstance.PlannedOutputValuesEntry.value:type_name -> tfstackdata1.DynamicValue - 16, // 21: tfstackdata1.StateComponentInstanceV1.OutputValuesEntry.value:type_name -> tfstackdata1.DynamicValue - 16, // 22: tfstackdata1.StateComponentInstanceV1.InputVariablesEntry.value:type_name -> tfstackdata1.DynamicValue - 23, // [23:23] is the sub-list for method output_type - 23, // [23:23] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name + 30, // 13: tfstackdata1.PlanActionInvocationPlanned.invocation:type_name -> tfplan.ActionInvocationInstance + 29, // 14: tfstackdata1.PlanDeferredActionInvocation.deferred:type_name -> tfplan.Deferred + 13, // 15: tfstackdata1.PlanDeferredActionInvocation.invocation:type_name -> tfstackdata1.PlanActionInvocationPlanned + 21, // 16: tfstackdata1.StateComponentInstanceV1.output_values:type_name -> tfstackdata1.StateComponentInstanceV1.OutputValuesEntry + 22, // 17: tfstackdata1.StateComponentInstanceV1.input_variables:type_name -> tfstackdata1.StateComponentInstanceV1.InputVariablesEntry + 31, // 18: tfstackdata1.StateResourceInstanceObjectV1.sensitive_paths:type_name -> tfplan.Path + 0, // 19: tfstackdata1.StateResourceInstanceObjectV1.status:type_name -> tfstackdata1.StateResourceInstanceObjectV1.Status + 32, // 20: tfstackdata1.DynamicValue.value:type_name -> tfplan.DynamicValue + 31, // 21: tfstackdata1.DynamicValue.sensitive_paths:type_name -> tfplan.Path + 18, // 22: tfstackdata1.PlanComponentInstance.PlannedInputValuesEntry.value:type_name -> tfstackdata1.DynamicValue + 18, // 23: tfstackdata1.PlanComponentInstance.PlannedOutputValuesEntry.value:type_name -> tfstackdata1.DynamicValue + 18, // 24: tfstackdata1.StateComponentInstanceV1.OutputValuesEntry.value:type_name -> tfstackdata1.DynamicValue + 18, // 25: tfstackdata1.StateComponentInstanceV1.InputVariablesEntry.value:type_name -> tfstackdata1.DynamicValue + 26, // [26:26] is the sub-list for method output_type + 26, // [26:26] is the sub-list for method input_type + 26, // [26:26] is the sub-list for extension type_name + 26, // [26:26] is the sub-list for extension extendee + 0, // [0:26] is the sub-list for field type_name } func init() { file_tfstackdata1_proto_init() } @@ -1414,7 +1560,7 @@ func file_tfstackdata1_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_tfstackdata1_proto_rawDesc), len(file_tfstackdata1_proto_rawDesc)), NumEnums: 1, - NumMessages: 20, + NumMessages: 22, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/stacks/tfstackdata1/tfstackdata1.proto b/internal/stacks/tfstackdata1/tfstackdata1.proto index d016b6dcec..475f81f504 100644 --- a/internal/stacks/tfstackdata1/tfstackdata1.proto +++ b/internal/stacks/tfstackdata1/tfstackdata1.proto @@ -254,6 +254,28 @@ message PlanDeferredResourceInstanceChange { PlanResourceInstanceChangePlanned change = 2; } +message PlanActionInvocationPlanned { + // The same string must previously have been announced with a + // PlanComponentInstance message, or the overall plan sequence is invalid. + string component_instance_addr = 1; + string action_invocation_addr = 3; + + // The address of the provider configuration that planned this change, + // or that produced the prior state for messages where "change" is + // unpopulated. This is a module-centric view relative to the root module + // of the component identified in component_instance_addr. + string provider_config_addr = 4; + + tfplan.ActionInvocationInstance invocation = 2; +} + +// Represents a deferred change to a particular action invocation within a +// particular component instance. +message PlanDeferredActionInvocation { + tfplan.Deferred deferred = 1; + PlanActionInvocationPlanned invocation = 2; +} + // Represents that we need to emit "delete" requests for one or more raw // state and/or state description objects during the apply phase. // From a38c47ae724934e8985a03947c4c39d8cbe29d99 Mon Sep 17 00:00:00 2001 From: Roniece Date: Mon, 26 Jan 2026 12:21:07 -0500 Subject: [PATCH 02/24] Add ActionInvocationStatus, ActionInvocationProgress messages --- .../rpcapi/terraform1/stacks/stacks.pb.go | 902 +++++++++++------- .../rpcapi/terraform1/stacks/stacks.proto | 22 + 2 files changed, 590 insertions(+), 334 deletions(-) diff --git a/internal/rpcapi/terraform1/stacks/stacks.pb.go b/internal/rpcapi/terraform1/stacks/stacks.pb.go index 8383d79a08..bbf0e72025 100644 --- a/internal/rpcapi/terraform1/stacks/stacks.pb.go +++ b/internal/rpcapi/terraform1/stacks/stacks.pb.go @@ -552,6 +552,61 @@ func (StackChangeProgress_ResourceInstanceStatus_Status) EnumDescriptor() ([]byt return file_stacks_proto_rawDescGZIP(), []int{26, 1, 0} } +type StackChangeProgress_ActionInvocationStatus_Status int32 + +const ( + StackChangeProgress_ActionInvocationStatus_INVALID StackChangeProgress_ActionInvocationStatus_Status = 0 + StackChangeProgress_ActionInvocationStatus_PENDING StackChangeProgress_ActionInvocationStatus_Status = 1 + StackChangeProgress_ActionInvocationStatus_RUNNING StackChangeProgress_ActionInvocationStatus_Status = 2 + StackChangeProgress_ActionInvocationStatus_COMPLETED StackChangeProgress_ActionInvocationStatus_Status = 3 + StackChangeProgress_ActionInvocationStatus_ERRORED StackChangeProgress_ActionInvocationStatus_Status = 4 +) + +// Enum value maps for StackChangeProgress_ActionInvocationStatus_Status. +var ( + StackChangeProgress_ActionInvocationStatus_Status_name = map[int32]string{ + 0: "INVALID", + 1: "PENDING", + 2: "RUNNING", + 3: "COMPLETED", + 4: "ERRORED", + } + StackChangeProgress_ActionInvocationStatus_Status_value = map[string]int32{ + "INVALID": 0, + "PENDING": 1, + "RUNNING": 2, + "COMPLETED": 3, + "ERRORED": 4, + } +) + +func (x StackChangeProgress_ActionInvocationStatus_Status) Enum() *StackChangeProgress_ActionInvocationStatus_Status { + p := new(StackChangeProgress_ActionInvocationStatus_Status) + *p = x + return p +} + +func (x StackChangeProgress_ActionInvocationStatus_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (StackChangeProgress_ActionInvocationStatus_Status) Descriptor() protoreflect.EnumDescriptor { + return file_stacks_proto_enumTypes[9].Descriptor() +} + +func (StackChangeProgress_ActionInvocationStatus_Status) Type() protoreflect.EnumType { + return &file_stacks_proto_enumTypes[9] +} + +func (x StackChangeProgress_ActionInvocationStatus_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use StackChangeProgress_ActionInvocationStatus_Status.Descriptor instead. +func (StackChangeProgress_ActionInvocationStatus_Status) EnumDescriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{26, 5, 0} +} + type StackChangeProgress_ProvisionerStatus_Status int32 const ( @@ -588,11 +643,11 @@ func (x StackChangeProgress_ProvisionerStatus_Status) String() string { } func (StackChangeProgress_ProvisionerStatus_Status) Descriptor() protoreflect.EnumDescriptor { - return file_stacks_proto_enumTypes[9].Descriptor() + return file_stacks_proto_enumTypes[10].Descriptor() } func (StackChangeProgress_ProvisionerStatus_Status) Type() protoreflect.EnumType { - return &file_stacks_proto_enumTypes[9] + return &file_stacks_proto_enumTypes[10] } func (x StackChangeProgress_ProvisionerStatus_Status) Number() protoreflect.EnumNumber { @@ -601,7 +656,7 @@ func (x StackChangeProgress_ProvisionerStatus_Status) Number() protoreflect.Enum // Deprecated: Use StackChangeProgress_ProvisionerStatus_Status.Descriptor instead. func (StackChangeProgress_ProvisionerStatus_Status) EnumDescriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 7, 0} + return file_stacks_proto_rawDescGZIP(), []int{26, 9, 0} } // OpenTerraformState opens a previously-saved Terraform state, returning a @@ -1879,6 +1934,8 @@ type StackChangeProgress struct { // *StackChangeProgress_ComponentInstances_ // *StackChangeProgress_DeferredResourceInstancePlannedChange_ // *StackChangeProgress_ActionInvocationPlanned_ + // *StackChangeProgress_ActionInvocationStatus_ + // *StackChangeProgress_ActionInvocationProgress_ Event isStackChangeProgress_Event `protobuf_oneof:"event"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -2002,6 +2059,24 @@ func (x *StackChangeProgress) GetActionInvocationPlanned() *StackChangeProgress_ return nil } +func (x *StackChangeProgress) GetActionInvocationStatus() *StackChangeProgress_ActionInvocationStatus { + if x != nil { + if x, ok := x.Event.(*StackChangeProgress_ActionInvocationStatus_); ok { + return x.ActionInvocationStatus + } + } + return nil +} + +func (x *StackChangeProgress) GetActionInvocationProgress() *StackChangeProgress_ActionInvocationProgress { + if x != nil { + if x, ok := x.Event.(*StackChangeProgress_ActionInvocationProgress_); ok { + return x.ActionInvocationProgress + } + } + return nil +} + type isStackChangeProgress_Event interface { isStackChangeProgress_Event() } @@ -2042,6 +2117,14 @@ type StackChangeProgress_ActionInvocationPlanned_ struct { ActionInvocationPlanned *StackChangeProgress_ActionInvocationPlanned `protobuf:"bytes,9,opt,name=action_invocation_planned,json=actionInvocationPlanned,proto3,oneof"` } +type StackChangeProgress_ActionInvocationStatus_ struct { + ActionInvocationStatus *StackChangeProgress_ActionInvocationStatus `protobuf:"bytes,10,opt,name=action_invocation_status,json=actionInvocationStatus,proto3,oneof"` +} + +type StackChangeProgress_ActionInvocationProgress_ struct { + ActionInvocationProgress *StackChangeProgress_ActionInvocationProgress `protobuf:"bytes,11,opt,name=action_invocation_progress,json=actionInvocationProgress,proto3,oneof"` +} + func (*StackChangeProgress_ComponentInstanceStatus_) isStackChangeProgress_Event() {} func (*StackChangeProgress_ResourceInstanceStatus_) isStackChangeProgress_Event() {} @@ -2060,6 +2143,10 @@ func (*StackChangeProgress_DeferredResourceInstancePlannedChange_) isStackChange func (*StackChangeProgress_ActionInvocationPlanned_) isStackChangeProgress_Event() {} +func (*StackChangeProgress_ActionInvocationStatus_) isStackChangeProgress_Event() {} + +func (*StackChangeProgress_ActionInvocationProgress_) isStackChangeProgress_Event() {} + type ListResourceIdentities struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -6439,6 +6526,126 @@ func (*StackChangeProgress_ActionInvocationPlanned_LifecycleActionTrigger) isSta func (*StackChangeProgress_ActionInvocationPlanned_InvokeActionTrigger) isStackChangeProgress_ActionInvocationPlanned_ActionTrigger() { } +type StackChangeProgress_ActionInvocationStatus struct { + state protoimpl.MessageState `protogen:"open.v1"` + Addr *ActionInvocationInstanceInStackAddr `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` + Status StackChangeProgress_ActionInvocationStatus_Status `protobuf:"varint,2,opt,name=status,proto3,enum=terraform1.stacks.StackChangeProgress_ActionInvocationStatus_Status" json:"status,omitempty"` + ProviderAddr string `protobuf:"bytes,3,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StackChangeProgress_ActionInvocationStatus) Reset() { + *x = StackChangeProgress_ActionInvocationStatus{} + mi := &file_stacks_proto_msgTypes[105] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StackChangeProgress_ActionInvocationStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackChangeProgress_ActionInvocationStatus) ProtoMessage() {} + +func (x *StackChangeProgress_ActionInvocationStatus) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[105] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackChangeProgress_ActionInvocationStatus.ProtoReflect.Descriptor instead. +func (*StackChangeProgress_ActionInvocationStatus) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{26, 5} +} + +func (x *StackChangeProgress_ActionInvocationStatus) GetAddr() *ActionInvocationInstanceInStackAddr { + if x != nil { + return x.Addr + } + return nil +} + +func (x *StackChangeProgress_ActionInvocationStatus) GetStatus() StackChangeProgress_ActionInvocationStatus_Status { + if x != nil { + return x.Status + } + return StackChangeProgress_ActionInvocationStatus_INVALID +} + +func (x *StackChangeProgress_ActionInvocationStatus) GetProviderAddr() string { + if x != nil { + return x.ProviderAddr + } + return "" +} + +type StackChangeProgress_ActionInvocationProgress struct { + state protoimpl.MessageState `protogen:"open.v1"` + Addr *ActionInvocationInstanceInStackAddr `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + ProviderAddr string `protobuf:"bytes,3,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StackChangeProgress_ActionInvocationProgress) Reset() { + *x = StackChangeProgress_ActionInvocationProgress{} + mi := &file_stacks_proto_msgTypes[106] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StackChangeProgress_ActionInvocationProgress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StackChangeProgress_ActionInvocationProgress) ProtoMessage() {} + +func (x *StackChangeProgress_ActionInvocationProgress) ProtoReflect() protoreflect.Message { + mi := &file_stacks_proto_msgTypes[106] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StackChangeProgress_ActionInvocationProgress.ProtoReflect.Descriptor instead. +func (*StackChangeProgress_ActionInvocationProgress) Descriptor() ([]byte, []int) { + return file_stacks_proto_rawDescGZIP(), []int{26, 6} +} + +func (x *StackChangeProgress_ActionInvocationProgress) GetAddr() *ActionInvocationInstanceInStackAddr { + if x != nil { + return x.Addr + } + return nil +} + +func (x *StackChangeProgress_ActionInvocationProgress) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *StackChangeProgress_ActionInvocationProgress) GetProviderAddr() string { + if x != nil { + return x.ProviderAddr + } + return "" +} + // LifecycleActionTrigger contains details on the conditions that led to the // triggering of an action. type StackChangeProgress_LifecycleActionTrigger struct { @@ -6453,7 +6660,7 @@ type StackChangeProgress_LifecycleActionTrigger struct { func (x *StackChangeProgress_LifecycleActionTrigger) Reset() { *x = StackChangeProgress_LifecycleActionTrigger{} - mi := &file_stacks_proto_msgTypes[105] + mi := &file_stacks_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6465,7 +6672,7 @@ func (x *StackChangeProgress_LifecycleActionTrigger) String() string { func (*StackChangeProgress_LifecycleActionTrigger) ProtoMessage() {} func (x *StackChangeProgress_LifecycleActionTrigger) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[105] + mi := &file_stacks_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6478,7 +6685,7 @@ func (x *StackChangeProgress_LifecycleActionTrigger) ProtoReflect() protoreflect // Deprecated: Use StackChangeProgress_LifecycleActionTrigger.ProtoReflect.Descriptor instead. func (*StackChangeProgress_LifecycleActionTrigger) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 5} + return file_stacks_proto_rawDescGZIP(), []int{26, 7} } func (x *StackChangeProgress_LifecycleActionTrigger) GetTriggeringResourceAddress() *ResourceInstanceInStackAddr { @@ -6519,7 +6726,7 @@ type StackChangeProgress_InvokeActionTrigger struct { func (x *StackChangeProgress_InvokeActionTrigger) Reset() { *x = StackChangeProgress_InvokeActionTrigger{} - mi := &file_stacks_proto_msgTypes[106] + mi := &file_stacks_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6531,7 +6738,7 @@ func (x *StackChangeProgress_InvokeActionTrigger) String() string { func (*StackChangeProgress_InvokeActionTrigger) ProtoMessage() {} func (x *StackChangeProgress_InvokeActionTrigger) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[106] + mi := &file_stacks_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6544,7 +6751,7 @@ func (x *StackChangeProgress_InvokeActionTrigger) ProtoReflect() protoreflect.Me // Deprecated: Use StackChangeProgress_InvokeActionTrigger.ProtoReflect.Descriptor instead. func (*StackChangeProgress_InvokeActionTrigger) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 6} + return file_stacks_proto_rawDescGZIP(), []int{26, 8} } // ProvisionerStatus represents the progress of a given provisioner during its @@ -6560,7 +6767,7 @@ type StackChangeProgress_ProvisionerStatus struct { func (x *StackChangeProgress_ProvisionerStatus) Reset() { *x = StackChangeProgress_ProvisionerStatus{} - mi := &file_stacks_proto_msgTypes[107] + mi := &file_stacks_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6572,7 +6779,7 @@ func (x *StackChangeProgress_ProvisionerStatus) String() string { func (*StackChangeProgress_ProvisionerStatus) ProtoMessage() {} func (x *StackChangeProgress_ProvisionerStatus) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[107] + mi := &file_stacks_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6585,7 +6792,7 @@ func (x *StackChangeProgress_ProvisionerStatus) ProtoReflect() protoreflect.Mess // Deprecated: Use StackChangeProgress_ProvisionerStatus.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ProvisionerStatus) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 7} + return file_stacks_proto_rawDescGZIP(), []int{26, 9} } func (x *StackChangeProgress_ProvisionerStatus) GetAddr() *ResourceInstanceObjectInStackAddr { @@ -6622,7 +6829,7 @@ type StackChangeProgress_ProvisionerOutput struct { func (x *StackChangeProgress_ProvisionerOutput) Reset() { *x = StackChangeProgress_ProvisionerOutput{} - mi := &file_stacks_proto_msgTypes[108] + mi := &file_stacks_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6634,7 +6841,7 @@ func (x *StackChangeProgress_ProvisionerOutput) String() string { func (*StackChangeProgress_ProvisionerOutput) ProtoMessage() {} func (x *StackChangeProgress_ProvisionerOutput) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[108] + mi := &file_stacks_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6647,7 +6854,7 @@ func (x *StackChangeProgress_ProvisionerOutput) ProtoReflect() protoreflect.Mess // Deprecated: Use StackChangeProgress_ProvisionerOutput.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ProvisionerOutput) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 8} + return file_stacks_proto_rawDescGZIP(), []int{26, 10} } func (x *StackChangeProgress_ProvisionerOutput) GetAddr() *ResourceInstanceObjectInStackAddr { @@ -6697,7 +6904,7 @@ type StackChangeProgress_ComponentInstanceChanges struct { func (x *StackChangeProgress_ComponentInstanceChanges) Reset() { *x = StackChangeProgress_ComponentInstanceChanges{} - mi := &file_stacks_proto_msgTypes[109] + mi := &file_stacks_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6709,7 +6916,7 @@ func (x *StackChangeProgress_ComponentInstanceChanges) String() string { func (*StackChangeProgress_ComponentInstanceChanges) ProtoMessage() {} func (x *StackChangeProgress_ComponentInstanceChanges) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[109] + mi := &file_stacks_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6722,7 +6929,7 @@ func (x *StackChangeProgress_ComponentInstanceChanges) ProtoReflect() protorefle // Deprecated: Use StackChangeProgress_ComponentInstanceChanges.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ComponentInstanceChanges) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 9} + return file_stacks_proto_rawDescGZIP(), []int{26, 11} } func (x *StackChangeProgress_ComponentInstanceChanges) GetAddr() *ComponentInstanceInStackAddr { @@ -6800,7 +7007,7 @@ type StackChangeProgress_ComponentInstances struct { func (x *StackChangeProgress_ComponentInstances) Reset() { *x = StackChangeProgress_ComponentInstances{} - mi := &file_stacks_proto_msgTypes[110] + mi := &file_stacks_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6812,7 +7019,7 @@ func (x *StackChangeProgress_ComponentInstances) String() string { func (*StackChangeProgress_ComponentInstances) ProtoMessage() {} func (x *StackChangeProgress_ComponentInstances) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[110] + mi := &file_stacks_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6825,7 +7032,7 @@ func (x *StackChangeProgress_ComponentInstances) ProtoReflect() protoreflect.Mes // Deprecated: Use StackChangeProgress_ComponentInstances.ProtoReflect.Descriptor instead. func (*StackChangeProgress_ComponentInstances) Descriptor() ([]byte, []int) { - return file_stacks_proto_rawDescGZIP(), []int{26, 10} + return file_stacks_proto_rawDescGZIP(), []int{26, 12} } func (x *StackChangeProgress_ComponentInstances) GetComponentAddr() string { @@ -6851,7 +7058,7 @@ type StackChangeProgress_ResourceInstancePlannedChange_Moved struct { func (x *StackChangeProgress_ResourceInstancePlannedChange_Moved) Reset() { *x = StackChangeProgress_ResourceInstancePlannedChange_Moved{} - mi := &file_stacks_proto_msgTypes[111] + mi := &file_stacks_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6863,7 +7070,7 @@ func (x *StackChangeProgress_ResourceInstancePlannedChange_Moved) String() strin func (*StackChangeProgress_ResourceInstancePlannedChange_Moved) ProtoMessage() {} func (x *StackChangeProgress_ResourceInstancePlannedChange_Moved) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[111] + mi := &file_stacks_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6896,7 +7103,7 @@ type StackChangeProgress_ResourceInstancePlannedChange_Imported struct { func (x *StackChangeProgress_ResourceInstancePlannedChange_Imported) Reset() { *x = StackChangeProgress_ResourceInstancePlannedChange_Imported{} - mi := &file_stacks_proto_msgTypes[112] + mi := &file_stacks_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6908,7 +7115,7 @@ func (x *StackChangeProgress_ResourceInstancePlannedChange_Imported) String() st func (*StackChangeProgress_ResourceInstancePlannedChange_Imported) ProtoMessage() {} func (x *StackChangeProgress_ResourceInstancePlannedChange_Imported) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[112] + mi := &file_stacks_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6949,7 +7156,7 @@ type ListResourceIdentities_Request struct { func (x *ListResourceIdentities_Request) Reset() { *x = ListResourceIdentities_Request{} - mi := &file_stacks_proto_msgTypes[113] + mi := &file_stacks_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6961,7 +7168,7 @@ func (x *ListResourceIdentities_Request) String() string { func (*ListResourceIdentities_Request) ProtoMessage() {} func (x *ListResourceIdentities_Request) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[113] + mi := &file_stacks_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7007,7 +7214,7 @@ type ListResourceIdentities_Response struct { func (x *ListResourceIdentities_Response) Reset() { *x = ListResourceIdentities_Response{} - mi := &file_stacks_proto_msgTypes[114] + mi := &file_stacks_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7019,7 +7226,7 @@ func (x *ListResourceIdentities_Response) String() string { func (*ListResourceIdentities_Response) ProtoMessage() {} func (x *ListResourceIdentities_Response) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[114] + mi := &file_stacks_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7058,7 +7265,7 @@ type ListResourceIdentities_Resource struct { func (x *ListResourceIdentities_Resource) Reset() { *x = ListResourceIdentities_Resource{} - mi := &file_stacks_proto_msgTypes[115] + mi := &file_stacks_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7070,7 +7277,7 @@ func (x *ListResourceIdentities_Resource) String() string { func (*ListResourceIdentities_Resource) ProtoMessage() {} func (x *ListResourceIdentities_Resource) ProtoReflect() protoreflect.Message { - mi := &file_stacks_proto_msgTypes[115] + mi := &file_stacks_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7489,7 +7696,7 @@ const file_stacks_proto_rawDesc = "" + "\rInputVariable\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12<\n" + "\tnew_value\x18\x02 \x01(\v2\x1f.terraform1.stacks.DynamicValueR\bnewValue\x1a\t\n" + - "\aNothing\"\xdd!\n" + + "\aNothing\"\xb8'\n" + "\x13StackChangeProgress\x12|\n" + "\x19component_instance_status\x18\x01 \x01(\v2>.terraform1.stacks.StackChangeProgress.ComponentInstanceStatusH\x00R\x17componentInstanceStatus\x12y\n" + "\x18resource_instance_status\x18\x02 \x01(\v2=.terraform1.stacks.StackChangeProgress.ResourceInstanceStatusH\x00R\x16resourceInstanceStatus\x12\x8f\x01\n" + @@ -7499,7 +7706,10 @@ const file_stacks_proto_rawDesc = "" + "\x1acomponent_instance_changes\x18\x06 \x01(\v2?.terraform1.stacks.StackChangeProgress.ComponentInstanceChangesH\x00R\x18componentInstanceChanges\x12l\n" + "\x13component_instances\x18\a \x01(\v29.terraform1.stacks.StackChangeProgress.ComponentInstancesH\x00R\x12componentInstances\x12\xa8\x01\n" + ")deferred_resource_instance_planned_change\x18\b \x01(\v2L.terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChangeH\x00R%deferredResourceInstancePlannedChange\x12|\n" + - "\x19action_invocation_planned\x18\t \x01(\v2>.terraform1.stacks.StackChangeProgress.ActionInvocationPlannedH\x00R\x17actionInvocationPlanned\x1a\xb2\x02\n" + + "\x19action_invocation_planned\x18\t \x01(\v2>.terraform1.stacks.StackChangeProgress.ActionInvocationPlannedH\x00R\x17actionInvocationPlanned\x12y\n" + + "\x18action_invocation_status\x18\n" + + " \x01(\v2=.terraform1.stacks.StackChangeProgress.ActionInvocationStatusH\x00R\x16actionInvocationStatus\x12\x7f\n" + + "\x1aaction_invocation_progress\x18\v \x01(\v2?.terraform1.stacks.StackChangeProgress.ActionInvocationProgressH\x00R\x18actionInvocationProgress\x1a\xb2\x02\n" + "\x17ComponentInstanceStatus\x12C\n" + "\x04addr\x18\x01 \x01(\v2/.terraform1.stacks.ComponentInstanceInStackAddrR\x04addr\x12]\n" + "\x06status\x18\x02 \x01(\x0e2E.terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.StatusR\x06status\"s\n" + @@ -7546,7 +7756,21 @@ const file_stacks_proto_rawDesc = "" + "\rprovider_addr\x18\x02 \x01(\tR\fproviderAddr\x12y\n" + "\x18lifecycle_action_trigger\x18\x03 \x01(\v2=.terraform1.stacks.StackChangeProgress.LifecycleActionTriggerH\x00R\x16lifecycleActionTrigger\x12p\n" + "\x15invoke_action_trigger\x18\x04 \x01(\v2:.terraform1.stacks.StackChangeProgress.InvokeActionTriggerH\x00R\x13invokeActionTriggerB\x10\n" + - "\x0eaction_trigger\x1a\xd3\x02\n" + + "\x0eaction_trigger\x1a\xb4\x02\n" + + "\x16ActionInvocationStatus\x12J\n" + + "\x04addr\x18\x01 \x01(\v26.terraform1.stacks.ActionInvocationInstanceInStackAddrR\x04addr\x12\\\n" + + "\x06status\x18\x02 \x01(\x0e2D.terraform1.stacks.StackChangeProgress.ActionInvocationStatus.StatusR\x06status\x12#\n" + + "\rprovider_addr\x18\x03 \x01(\tR\fproviderAddr\"K\n" + + "\x06Status\x12\v\n" + + "\aINVALID\x10\x00\x12\v\n" + + "\aPENDING\x10\x01\x12\v\n" + + "\aRUNNING\x10\x02\x12\r\n" + + "\tCOMPLETED\x10\x03\x12\v\n" + + "\aERRORED\x10\x04\x1a\xa5\x01\n" + + "\x18ActionInvocationProgress\x12J\n" + + "\x04addr\x18\x01 \x01(\v26.terraform1.stacks.ActionInvocationInstanceInStackAddrR\x04addr\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\x12#\n" + + "\rprovider_addr\x18\x03 \x01(\tR\fproviderAddr\x1a\xd3\x02\n" + "\x16LifecycleActionTrigger\x12n\n" + "\x1btriggering_resource_address\x18\x01 \x01(\v2..terraform1.stacks.ResourceInstanceInStackAddrR\x19triggeringResourceAddress\x12^\n" + "\rtrigger_event\x18\x02 \x01(\x0e29.terraform1.stacks.StackChangeProgress.ActionTriggerEventR\ftriggerEvent\x12;\n" + @@ -7654,8 +7878,8 @@ func file_stacks_proto_rawDescGZIP() []byte { return file_stacks_proto_rawDescData } -var file_stacks_proto_enumTypes = make([]protoimpl.EnumInfo, 10) -var file_stacks_proto_msgTypes = make([]protoimpl.MessageInfo, 116) +var file_stacks_proto_enumTypes = make([]protoimpl.EnumInfo, 11) +var file_stacks_proto_msgTypes = make([]protoimpl.MessageInfo, 118) var file_stacks_proto_goTypes = []any{ (ResourceMode)(0), // 0: terraform1.stacks.ResourceMode (PlanMode)(0), // 1: terraform1.stacks.PlanMode @@ -7666,305 +7890,313 @@ var file_stacks_proto_goTypes = []any{ (StackChangeProgress_ActionTriggerEvent)(0), // 6: terraform1.stacks.StackChangeProgress.ActionTriggerEvent (StackChangeProgress_ComponentInstanceStatus_Status)(0), // 7: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.Status (StackChangeProgress_ResourceInstanceStatus_Status)(0), // 8: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.Status - (StackChangeProgress_ProvisionerStatus_Status)(0), // 9: terraform1.stacks.StackChangeProgress.ProvisionerStatus.Status - (*OpenTerraformState)(nil), // 10: terraform1.stacks.OpenTerraformState - (*CloseTerraformState)(nil), // 11: terraform1.stacks.CloseTerraformState - (*MigrateTerraformState)(nil), // 12: terraform1.stacks.MigrateTerraformState - (*OpenStackConfiguration)(nil), // 13: terraform1.stacks.OpenStackConfiguration - (*CloseStackConfiguration)(nil), // 14: terraform1.stacks.CloseStackConfiguration - (*ValidateStackConfiguration)(nil), // 15: terraform1.stacks.ValidateStackConfiguration - (*FindStackConfigurationComponents)(nil), // 16: terraform1.stacks.FindStackConfigurationComponents - (*OpenStackState)(nil), // 17: terraform1.stacks.OpenStackState - (*CloseStackState)(nil), // 18: terraform1.stacks.CloseStackState - (*PlanStackChanges)(nil), // 19: terraform1.stacks.PlanStackChanges - (*OpenStackPlan)(nil), // 20: terraform1.stacks.OpenStackPlan - (*CloseStackPlan)(nil), // 21: terraform1.stacks.CloseStackPlan - (*ApplyStackChanges)(nil), // 22: terraform1.stacks.ApplyStackChanges - (*OpenStackInspector)(nil), // 23: terraform1.stacks.OpenStackInspector - (*InspectExpressionResult)(nil), // 24: terraform1.stacks.InspectExpressionResult - (*DynamicValue)(nil), // 25: terraform1.stacks.DynamicValue - (*DynamicValueChange)(nil), // 26: terraform1.stacks.DynamicValueChange - (*DynamicValueWithSource)(nil), // 27: terraform1.stacks.DynamicValueWithSource - (*AttributePath)(nil), // 28: terraform1.stacks.AttributePath - (*ComponentInstanceInStackAddr)(nil), // 29: terraform1.stacks.ComponentInstanceInStackAddr - (*ActionInvocationInstanceInStackAddr)(nil), // 30: terraform1.stacks.ActionInvocationInstanceInStackAddr - (*ResourceInstanceInStackAddr)(nil), // 31: terraform1.stacks.ResourceInstanceInStackAddr - (*ResourceInstanceObjectInStackAddr)(nil), // 32: terraform1.stacks.ResourceInstanceObjectInStackAddr - (*PlannedChange)(nil), // 33: terraform1.stacks.PlannedChange - (*Deferred)(nil), // 34: terraform1.stacks.Deferred - (*AppliedChange)(nil), // 35: terraform1.stacks.AppliedChange - (*StackChangeProgress)(nil), // 36: terraform1.stacks.StackChangeProgress - (*ListResourceIdentities)(nil), // 37: terraform1.stacks.ListResourceIdentities - (*OpenTerraformState_Request)(nil), // 38: terraform1.stacks.OpenTerraformState.Request - (*OpenTerraformState_Response)(nil), // 39: terraform1.stacks.OpenTerraformState.Response - (*CloseTerraformState_Request)(nil), // 40: terraform1.stacks.CloseTerraformState.Request - (*CloseTerraformState_Response)(nil), // 41: terraform1.stacks.CloseTerraformState.Response - (*MigrateTerraformState_Request)(nil), // 42: terraform1.stacks.MigrateTerraformState.Request - (*MigrateTerraformState_Event)(nil), // 43: terraform1.stacks.MigrateTerraformState.Event - (*MigrateTerraformState_Request_Mapping)(nil), // 44: terraform1.stacks.MigrateTerraformState.Request.Mapping - nil, // 45: terraform1.stacks.MigrateTerraformState.Request.Mapping.ResourceAddressMapEntry - nil, // 46: terraform1.stacks.MigrateTerraformState.Request.Mapping.ModuleAddressMapEntry - (*OpenStackConfiguration_Request)(nil), // 47: terraform1.stacks.OpenStackConfiguration.Request - (*OpenStackConfiguration_Response)(nil), // 48: terraform1.stacks.OpenStackConfiguration.Response - (*CloseStackConfiguration_Request)(nil), // 49: terraform1.stacks.CloseStackConfiguration.Request - (*CloseStackConfiguration_Response)(nil), // 50: terraform1.stacks.CloseStackConfiguration.Response - (*ValidateStackConfiguration_Request)(nil), // 51: terraform1.stacks.ValidateStackConfiguration.Request - (*ValidateStackConfiguration_Response)(nil), // 52: terraform1.stacks.ValidateStackConfiguration.Response - (*FindStackConfigurationComponents_Request)(nil), // 53: terraform1.stacks.FindStackConfigurationComponents.Request - (*FindStackConfigurationComponents_Response)(nil), // 54: terraform1.stacks.FindStackConfigurationComponents.Response - (*FindStackConfigurationComponents_StackConfig)(nil), // 55: terraform1.stacks.FindStackConfigurationComponents.StackConfig - (*FindStackConfigurationComponents_EmbeddedStack)(nil), // 56: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack - (*FindStackConfigurationComponents_Component)(nil), // 57: terraform1.stacks.FindStackConfigurationComponents.Component - (*FindStackConfigurationComponents_Removed)(nil), // 58: terraform1.stacks.FindStackConfigurationComponents.Removed - (*FindStackConfigurationComponents_InputVariable)(nil), // 59: terraform1.stacks.FindStackConfigurationComponents.InputVariable - (*FindStackConfigurationComponents_OutputValue)(nil), // 60: terraform1.stacks.FindStackConfigurationComponents.OutputValue - nil, // 61: terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry - nil, // 62: terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry - nil, // 63: terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry - nil, // 64: terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry - nil, // 65: terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry - (*FindStackConfigurationComponents_Removed_Block)(nil), // 66: terraform1.stacks.FindStackConfigurationComponents.Removed.Block - (*OpenStackState_RequestItem)(nil), // 67: terraform1.stacks.OpenStackState.RequestItem - (*OpenStackState_Response)(nil), // 68: terraform1.stacks.OpenStackState.Response - (*CloseStackState_Request)(nil), // 69: terraform1.stacks.CloseStackState.Request - (*CloseStackState_Response)(nil), // 70: terraform1.stacks.CloseStackState.Response - (*PlanStackChanges_Request)(nil), // 71: terraform1.stacks.PlanStackChanges.Request - (*PlanStackChanges_Event)(nil), // 72: terraform1.stacks.PlanStackChanges.Event - nil, // 73: terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry - nil, // 74: terraform1.stacks.PlanStackChanges.Request.InputValuesEntry - (*OpenStackPlan_RequestItem)(nil), // 75: terraform1.stacks.OpenStackPlan.RequestItem - (*OpenStackPlan_Response)(nil), // 76: terraform1.stacks.OpenStackPlan.Response - (*CloseStackPlan_Request)(nil), // 77: terraform1.stacks.CloseStackPlan.Request - (*CloseStackPlan_Response)(nil), // 78: terraform1.stacks.CloseStackPlan.Response - (*ApplyStackChanges_Request)(nil), // 79: terraform1.stacks.ApplyStackChanges.Request - (*ApplyStackChanges_Event)(nil), // 80: terraform1.stacks.ApplyStackChanges.Event - nil, // 81: terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry - (*OpenStackInspector_Request)(nil), // 82: terraform1.stacks.OpenStackInspector.Request - (*OpenStackInspector_Response)(nil), // 83: terraform1.stacks.OpenStackInspector.Response - nil, // 84: terraform1.stacks.OpenStackInspector.Request.StateEntry - nil, // 85: terraform1.stacks.OpenStackInspector.Request.InputValuesEntry - (*InspectExpressionResult_Request)(nil), // 86: terraform1.stacks.InspectExpressionResult.Request - (*InspectExpressionResult_Response)(nil), // 87: terraform1.stacks.InspectExpressionResult.Response - (*AttributePath_Step)(nil), // 88: terraform1.stacks.AttributePath.Step - (*PlannedChange_ChangeDescription)(nil), // 89: terraform1.stacks.PlannedChange.ChangeDescription - (*PlannedChange_ComponentInstance)(nil), // 90: terraform1.stacks.PlannedChange.ComponentInstance - (*PlannedChange_ResourceInstance)(nil), // 91: terraform1.stacks.PlannedChange.ResourceInstance - (*PlannedChange_OutputValue)(nil), // 92: terraform1.stacks.PlannedChange.OutputValue - (*PlannedChange_ResourceInstanceDeferred)(nil), // 93: terraform1.stacks.PlannedChange.ResourceInstanceDeferred - (*PlannedChange_InputVariable)(nil), // 94: terraform1.stacks.PlannedChange.InputVariable - (*PlannedChange_ActionInvocationInstance)(nil), // 95: terraform1.stacks.PlannedChange.ActionInvocationInstance - (*PlannedChange_ActionInvocationDeferred)(nil), // 96: terraform1.stacks.PlannedChange.ActionInvocationDeferred - (*PlannedChange_LifecycleActionTrigger)(nil), // 97: terraform1.stacks.PlannedChange.LifecycleActionTrigger - (*PlannedChange_InvokeActionTrigger)(nil), // 98: terraform1.stacks.PlannedChange.InvokeActionTrigger - (*PlannedChange_ResourceInstance_Index)(nil), // 99: terraform1.stacks.PlannedChange.ResourceInstance.Index - (*PlannedChange_ResourceInstance_Moved)(nil), // 100: terraform1.stacks.PlannedChange.ResourceInstance.Moved - (*PlannedChange_ResourceInstance_Imported)(nil), // 101: terraform1.stacks.PlannedChange.ResourceInstance.Imported - (*AppliedChange_RawChange)(nil), // 102: terraform1.stacks.AppliedChange.RawChange - (*AppliedChange_ChangeDescription)(nil), // 103: terraform1.stacks.AppliedChange.ChangeDescription - (*AppliedChange_ResourceInstance)(nil), // 104: terraform1.stacks.AppliedChange.ResourceInstance - (*AppliedChange_ComponentInstance)(nil), // 105: terraform1.stacks.AppliedChange.ComponentInstance - (*AppliedChange_OutputValue)(nil), // 106: terraform1.stacks.AppliedChange.OutputValue - (*AppliedChange_InputVariable)(nil), // 107: terraform1.stacks.AppliedChange.InputVariable - (*AppliedChange_Nothing)(nil), // 108: terraform1.stacks.AppliedChange.Nothing - nil, // 109: terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry - (*StackChangeProgress_ComponentInstanceStatus)(nil), // 110: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus - (*StackChangeProgress_ResourceInstanceStatus)(nil), // 111: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus - (*StackChangeProgress_ResourceInstancePlannedChange)(nil), // 112: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange - (*StackChangeProgress_DeferredResourceInstancePlannedChange)(nil), // 113: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange - (*StackChangeProgress_ActionInvocationPlanned)(nil), // 114: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned - (*StackChangeProgress_LifecycleActionTrigger)(nil), // 115: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger - (*StackChangeProgress_InvokeActionTrigger)(nil), // 116: terraform1.stacks.StackChangeProgress.InvokeActionTrigger - (*StackChangeProgress_ProvisionerStatus)(nil), // 117: terraform1.stacks.StackChangeProgress.ProvisionerStatus - (*StackChangeProgress_ProvisionerOutput)(nil), // 118: terraform1.stacks.StackChangeProgress.ProvisionerOutput - (*StackChangeProgress_ComponentInstanceChanges)(nil), // 119: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges - (*StackChangeProgress_ComponentInstances)(nil), // 120: terraform1.stacks.StackChangeProgress.ComponentInstances - (*StackChangeProgress_ResourceInstancePlannedChange_Moved)(nil), // 121: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved - (*StackChangeProgress_ResourceInstancePlannedChange_Imported)(nil), // 122: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Imported - (*ListResourceIdentities_Request)(nil), // 123: terraform1.stacks.ListResourceIdentities.Request - (*ListResourceIdentities_Response)(nil), // 124: terraform1.stacks.ListResourceIdentities.Response - (*ListResourceIdentities_Resource)(nil), // 125: terraform1.stacks.ListResourceIdentities.Resource - (*terraform1.SourceRange)(nil), // 126: terraform1.SourceRange - (*anypb.Any)(nil), // 127: google.protobuf.Any - (*terraform1.Diagnostic)(nil), // 128: terraform1.Diagnostic - (*terraform1.SourceAddress)(nil), // 129: terraform1.SourceAddress + (StackChangeProgress_ActionInvocationStatus_Status)(0), // 9: terraform1.stacks.StackChangeProgress.ActionInvocationStatus.Status + (StackChangeProgress_ProvisionerStatus_Status)(0), // 10: terraform1.stacks.StackChangeProgress.ProvisionerStatus.Status + (*OpenTerraformState)(nil), // 11: terraform1.stacks.OpenTerraformState + (*CloseTerraformState)(nil), // 12: terraform1.stacks.CloseTerraformState + (*MigrateTerraformState)(nil), // 13: terraform1.stacks.MigrateTerraformState + (*OpenStackConfiguration)(nil), // 14: terraform1.stacks.OpenStackConfiguration + (*CloseStackConfiguration)(nil), // 15: terraform1.stacks.CloseStackConfiguration + (*ValidateStackConfiguration)(nil), // 16: terraform1.stacks.ValidateStackConfiguration + (*FindStackConfigurationComponents)(nil), // 17: terraform1.stacks.FindStackConfigurationComponents + (*OpenStackState)(nil), // 18: terraform1.stacks.OpenStackState + (*CloseStackState)(nil), // 19: terraform1.stacks.CloseStackState + (*PlanStackChanges)(nil), // 20: terraform1.stacks.PlanStackChanges + (*OpenStackPlan)(nil), // 21: terraform1.stacks.OpenStackPlan + (*CloseStackPlan)(nil), // 22: terraform1.stacks.CloseStackPlan + (*ApplyStackChanges)(nil), // 23: terraform1.stacks.ApplyStackChanges + (*OpenStackInspector)(nil), // 24: terraform1.stacks.OpenStackInspector + (*InspectExpressionResult)(nil), // 25: terraform1.stacks.InspectExpressionResult + (*DynamicValue)(nil), // 26: terraform1.stacks.DynamicValue + (*DynamicValueChange)(nil), // 27: terraform1.stacks.DynamicValueChange + (*DynamicValueWithSource)(nil), // 28: terraform1.stacks.DynamicValueWithSource + (*AttributePath)(nil), // 29: terraform1.stacks.AttributePath + (*ComponentInstanceInStackAddr)(nil), // 30: terraform1.stacks.ComponentInstanceInStackAddr + (*ActionInvocationInstanceInStackAddr)(nil), // 31: terraform1.stacks.ActionInvocationInstanceInStackAddr + (*ResourceInstanceInStackAddr)(nil), // 32: terraform1.stacks.ResourceInstanceInStackAddr + (*ResourceInstanceObjectInStackAddr)(nil), // 33: terraform1.stacks.ResourceInstanceObjectInStackAddr + (*PlannedChange)(nil), // 34: terraform1.stacks.PlannedChange + (*Deferred)(nil), // 35: terraform1.stacks.Deferred + (*AppliedChange)(nil), // 36: terraform1.stacks.AppliedChange + (*StackChangeProgress)(nil), // 37: terraform1.stacks.StackChangeProgress + (*ListResourceIdentities)(nil), // 38: terraform1.stacks.ListResourceIdentities + (*OpenTerraformState_Request)(nil), // 39: terraform1.stacks.OpenTerraformState.Request + (*OpenTerraformState_Response)(nil), // 40: terraform1.stacks.OpenTerraformState.Response + (*CloseTerraformState_Request)(nil), // 41: terraform1.stacks.CloseTerraformState.Request + (*CloseTerraformState_Response)(nil), // 42: terraform1.stacks.CloseTerraformState.Response + (*MigrateTerraformState_Request)(nil), // 43: terraform1.stacks.MigrateTerraformState.Request + (*MigrateTerraformState_Event)(nil), // 44: terraform1.stacks.MigrateTerraformState.Event + (*MigrateTerraformState_Request_Mapping)(nil), // 45: terraform1.stacks.MigrateTerraformState.Request.Mapping + nil, // 46: terraform1.stacks.MigrateTerraformState.Request.Mapping.ResourceAddressMapEntry + nil, // 47: terraform1.stacks.MigrateTerraformState.Request.Mapping.ModuleAddressMapEntry + (*OpenStackConfiguration_Request)(nil), // 48: terraform1.stacks.OpenStackConfiguration.Request + (*OpenStackConfiguration_Response)(nil), // 49: terraform1.stacks.OpenStackConfiguration.Response + (*CloseStackConfiguration_Request)(nil), // 50: terraform1.stacks.CloseStackConfiguration.Request + (*CloseStackConfiguration_Response)(nil), // 51: terraform1.stacks.CloseStackConfiguration.Response + (*ValidateStackConfiguration_Request)(nil), // 52: terraform1.stacks.ValidateStackConfiguration.Request + (*ValidateStackConfiguration_Response)(nil), // 53: terraform1.stacks.ValidateStackConfiguration.Response + (*FindStackConfigurationComponents_Request)(nil), // 54: terraform1.stacks.FindStackConfigurationComponents.Request + (*FindStackConfigurationComponents_Response)(nil), // 55: terraform1.stacks.FindStackConfigurationComponents.Response + (*FindStackConfigurationComponents_StackConfig)(nil), // 56: terraform1.stacks.FindStackConfigurationComponents.StackConfig + (*FindStackConfigurationComponents_EmbeddedStack)(nil), // 57: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack + (*FindStackConfigurationComponents_Component)(nil), // 58: terraform1.stacks.FindStackConfigurationComponents.Component + (*FindStackConfigurationComponents_Removed)(nil), // 59: terraform1.stacks.FindStackConfigurationComponents.Removed + (*FindStackConfigurationComponents_InputVariable)(nil), // 60: terraform1.stacks.FindStackConfigurationComponents.InputVariable + (*FindStackConfigurationComponents_OutputValue)(nil), // 61: terraform1.stacks.FindStackConfigurationComponents.OutputValue + nil, // 62: terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry + nil, // 63: terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry + nil, // 64: terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry + nil, // 65: terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry + nil, // 66: terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry + (*FindStackConfigurationComponents_Removed_Block)(nil), // 67: terraform1.stacks.FindStackConfigurationComponents.Removed.Block + (*OpenStackState_RequestItem)(nil), // 68: terraform1.stacks.OpenStackState.RequestItem + (*OpenStackState_Response)(nil), // 69: terraform1.stacks.OpenStackState.Response + (*CloseStackState_Request)(nil), // 70: terraform1.stacks.CloseStackState.Request + (*CloseStackState_Response)(nil), // 71: terraform1.stacks.CloseStackState.Response + (*PlanStackChanges_Request)(nil), // 72: terraform1.stacks.PlanStackChanges.Request + (*PlanStackChanges_Event)(nil), // 73: terraform1.stacks.PlanStackChanges.Event + nil, // 74: terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry + nil, // 75: terraform1.stacks.PlanStackChanges.Request.InputValuesEntry + (*OpenStackPlan_RequestItem)(nil), // 76: terraform1.stacks.OpenStackPlan.RequestItem + (*OpenStackPlan_Response)(nil), // 77: terraform1.stacks.OpenStackPlan.Response + (*CloseStackPlan_Request)(nil), // 78: terraform1.stacks.CloseStackPlan.Request + (*CloseStackPlan_Response)(nil), // 79: terraform1.stacks.CloseStackPlan.Response + (*ApplyStackChanges_Request)(nil), // 80: terraform1.stacks.ApplyStackChanges.Request + (*ApplyStackChanges_Event)(nil), // 81: terraform1.stacks.ApplyStackChanges.Event + nil, // 82: terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry + (*OpenStackInspector_Request)(nil), // 83: terraform1.stacks.OpenStackInspector.Request + (*OpenStackInspector_Response)(nil), // 84: terraform1.stacks.OpenStackInspector.Response + nil, // 85: terraform1.stacks.OpenStackInspector.Request.StateEntry + nil, // 86: terraform1.stacks.OpenStackInspector.Request.InputValuesEntry + (*InspectExpressionResult_Request)(nil), // 87: terraform1.stacks.InspectExpressionResult.Request + (*InspectExpressionResult_Response)(nil), // 88: terraform1.stacks.InspectExpressionResult.Response + (*AttributePath_Step)(nil), // 89: terraform1.stacks.AttributePath.Step + (*PlannedChange_ChangeDescription)(nil), // 90: terraform1.stacks.PlannedChange.ChangeDescription + (*PlannedChange_ComponentInstance)(nil), // 91: terraform1.stacks.PlannedChange.ComponentInstance + (*PlannedChange_ResourceInstance)(nil), // 92: terraform1.stacks.PlannedChange.ResourceInstance + (*PlannedChange_OutputValue)(nil), // 93: terraform1.stacks.PlannedChange.OutputValue + (*PlannedChange_ResourceInstanceDeferred)(nil), // 94: terraform1.stacks.PlannedChange.ResourceInstanceDeferred + (*PlannedChange_InputVariable)(nil), // 95: terraform1.stacks.PlannedChange.InputVariable + (*PlannedChange_ActionInvocationInstance)(nil), // 96: terraform1.stacks.PlannedChange.ActionInvocationInstance + (*PlannedChange_ActionInvocationDeferred)(nil), // 97: terraform1.stacks.PlannedChange.ActionInvocationDeferred + (*PlannedChange_LifecycleActionTrigger)(nil), // 98: terraform1.stacks.PlannedChange.LifecycleActionTrigger + (*PlannedChange_InvokeActionTrigger)(nil), // 99: terraform1.stacks.PlannedChange.InvokeActionTrigger + (*PlannedChange_ResourceInstance_Index)(nil), // 100: terraform1.stacks.PlannedChange.ResourceInstance.Index + (*PlannedChange_ResourceInstance_Moved)(nil), // 101: terraform1.stacks.PlannedChange.ResourceInstance.Moved + (*PlannedChange_ResourceInstance_Imported)(nil), // 102: terraform1.stacks.PlannedChange.ResourceInstance.Imported + (*AppliedChange_RawChange)(nil), // 103: terraform1.stacks.AppliedChange.RawChange + (*AppliedChange_ChangeDescription)(nil), // 104: terraform1.stacks.AppliedChange.ChangeDescription + (*AppliedChange_ResourceInstance)(nil), // 105: terraform1.stacks.AppliedChange.ResourceInstance + (*AppliedChange_ComponentInstance)(nil), // 106: terraform1.stacks.AppliedChange.ComponentInstance + (*AppliedChange_OutputValue)(nil), // 107: terraform1.stacks.AppliedChange.OutputValue + (*AppliedChange_InputVariable)(nil), // 108: terraform1.stacks.AppliedChange.InputVariable + (*AppliedChange_Nothing)(nil), // 109: terraform1.stacks.AppliedChange.Nothing + nil, // 110: terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry + (*StackChangeProgress_ComponentInstanceStatus)(nil), // 111: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus + (*StackChangeProgress_ResourceInstanceStatus)(nil), // 112: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus + (*StackChangeProgress_ResourceInstancePlannedChange)(nil), // 113: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange + (*StackChangeProgress_DeferredResourceInstancePlannedChange)(nil), // 114: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange + (*StackChangeProgress_ActionInvocationPlanned)(nil), // 115: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned + (*StackChangeProgress_ActionInvocationStatus)(nil), // 116: terraform1.stacks.StackChangeProgress.ActionInvocationStatus + (*StackChangeProgress_ActionInvocationProgress)(nil), // 117: terraform1.stacks.StackChangeProgress.ActionInvocationProgress + (*StackChangeProgress_LifecycleActionTrigger)(nil), // 118: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger + (*StackChangeProgress_InvokeActionTrigger)(nil), // 119: terraform1.stacks.StackChangeProgress.InvokeActionTrigger + (*StackChangeProgress_ProvisionerStatus)(nil), // 120: terraform1.stacks.StackChangeProgress.ProvisionerStatus + (*StackChangeProgress_ProvisionerOutput)(nil), // 121: terraform1.stacks.StackChangeProgress.ProvisionerOutput + (*StackChangeProgress_ComponentInstanceChanges)(nil), // 122: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges + (*StackChangeProgress_ComponentInstances)(nil), // 123: terraform1.stacks.StackChangeProgress.ComponentInstances + (*StackChangeProgress_ResourceInstancePlannedChange_Moved)(nil), // 124: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved + (*StackChangeProgress_ResourceInstancePlannedChange_Imported)(nil), // 125: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Imported + (*ListResourceIdentities_Request)(nil), // 126: terraform1.stacks.ListResourceIdentities.Request + (*ListResourceIdentities_Response)(nil), // 127: terraform1.stacks.ListResourceIdentities.Response + (*ListResourceIdentities_Resource)(nil), // 128: terraform1.stacks.ListResourceIdentities.Resource + (*terraform1.SourceRange)(nil), // 129: terraform1.SourceRange + (*anypb.Any)(nil), // 130: google.protobuf.Any + (*terraform1.Diagnostic)(nil), // 131: terraform1.Diagnostic + (*terraform1.SourceAddress)(nil), // 132: terraform1.SourceAddress } var file_stacks_proto_depIdxs = []int32{ - 28, // 0: terraform1.stacks.DynamicValue.sensitive:type_name -> terraform1.stacks.AttributePath - 25, // 1: terraform1.stacks.DynamicValueChange.old:type_name -> terraform1.stacks.DynamicValue - 25, // 2: terraform1.stacks.DynamicValueChange.new:type_name -> terraform1.stacks.DynamicValue - 25, // 3: terraform1.stacks.DynamicValueWithSource.value:type_name -> terraform1.stacks.DynamicValue - 126, // 4: terraform1.stacks.DynamicValueWithSource.source_range:type_name -> terraform1.SourceRange - 88, // 5: terraform1.stacks.AttributePath.steps:type_name -> terraform1.stacks.AttributePath.Step - 127, // 6: terraform1.stacks.PlannedChange.raw:type_name -> google.protobuf.Any - 89, // 7: terraform1.stacks.PlannedChange.descriptions:type_name -> terraform1.stacks.PlannedChange.ChangeDescription + 29, // 0: terraform1.stacks.DynamicValue.sensitive:type_name -> terraform1.stacks.AttributePath + 26, // 1: terraform1.stacks.DynamicValueChange.old:type_name -> terraform1.stacks.DynamicValue + 26, // 2: terraform1.stacks.DynamicValueChange.new:type_name -> terraform1.stacks.DynamicValue + 26, // 3: terraform1.stacks.DynamicValueWithSource.value:type_name -> terraform1.stacks.DynamicValue + 129, // 4: terraform1.stacks.DynamicValueWithSource.source_range:type_name -> terraform1.SourceRange + 89, // 5: terraform1.stacks.AttributePath.steps:type_name -> terraform1.stacks.AttributePath.Step + 130, // 6: terraform1.stacks.PlannedChange.raw:type_name -> google.protobuf.Any + 90, // 7: terraform1.stacks.PlannedChange.descriptions:type_name -> terraform1.stacks.PlannedChange.ChangeDescription 5, // 8: terraform1.stacks.Deferred.reason:type_name -> terraform1.stacks.Deferred.Reason - 102, // 9: terraform1.stacks.AppliedChange.raw:type_name -> terraform1.stacks.AppliedChange.RawChange - 103, // 10: terraform1.stacks.AppliedChange.descriptions:type_name -> terraform1.stacks.AppliedChange.ChangeDescription - 110, // 11: terraform1.stacks.StackChangeProgress.component_instance_status:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceStatus - 111, // 12: terraform1.stacks.StackChangeProgress.resource_instance_status:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstanceStatus - 112, // 13: terraform1.stacks.StackChangeProgress.resource_instance_planned_change:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange - 117, // 14: terraform1.stacks.StackChangeProgress.provisioner_status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus - 118, // 15: terraform1.stacks.StackChangeProgress.provisioner_output:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerOutput - 119, // 16: terraform1.stacks.StackChangeProgress.component_instance_changes:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceChanges - 120, // 17: terraform1.stacks.StackChangeProgress.component_instances:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstances - 113, // 18: terraform1.stacks.StackChangeProgress.deferred_resource_instance_planned_change:type_name -> terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange - 114, // 19: terraform1.stacks.StackChangeProgress.action_invocation_planned:type_name -> terraform1.stacks.StackChangeProgress.ActionInvocationPlanned - 128, // 20: terraform1.stacks.OpenTerraformState.Response.diagnostics:type_name -> terraform1.Diagnostic - 44, // 21: terraform1.stacks.MigrateTerraformState.Request.simple:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping - 128, // 22: terraform1.stacks.MigrateTerraformState.Event.diagnostic:type_name -> terraform1.Diagnostic - 35, // 23: terraform1.stacks.MigrateTerraformState.Event.applied_change:type_name -> terraform1.stacks.AppliedChange - 45, // 24: terraform1.stacks.MigrateTerraformState.Request.Mapping.resource_address_map:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping.ResourceAddressMapEntry - 46, // 25: terraform1.stacks.MigrateTerraformState.Request.Mapping.module_address_map:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping.ModuleAddressMapEntry - 129, // 26: terraform1.stacks.OpenStackConfiguration.Request.source_address:type_name -> terraform1.SourceAddress - 128, // 27: terraform1.stacks.OpenStackConfiguration.Response.diagnostics:type_name -> terraform1.Diagnostic - 128, // 28: terraform1.stacks.ValidateStackConfiguration.Response.diagnostics:type_name -> terraform1.Diagnostic - 55, // 29: terraform1.stacks.FindStackConfigurationComponents.Response.config:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig - 61, // 30: terraform1.stacks.FindStackConfigurationComponents.StackConfig.components:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry - 62, // 31: terraform1.stacks.FindStackConfigurationComponents.StackConfig.embedded_stacks:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry - 63, // 32: terraform1.stacks.FindStackConfigurationComponents.StackConfig.input_variables:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry - 64, // 33: terraform1.stacks.FindStackConfigurationComponents.StackConfig.output_values:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry - 65, // 34: terraform1.stacks.FindStackConfigurationComponents.StackConfig.removed:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry - 3, // 35: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances - 55, // 36: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack.config:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig - 3, // 37: terraform1.stacks.FindStackConfigurationComponents.Component.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances - 3, // 38: terraform1.stacks.FindStackConfigurationComponents.Removed.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances - 66, // 39: terraform1.stacks.FindStackConfigurationComponents.Removed.blocks:type_name -> terraform1.stacks.FindStackConfigurationComponents.Removed.Block - 57, // 40: terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.Component - 56, // 41: terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack - 59, // 42: terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.InputVariable - 60, // 43: terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.OutputValue - 58, // 44: terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.Removed - 3, // 45: terraform1.stacks.FindStackConfigurationComponents.Removed.Block.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances - 102, // 46: terraform1.stacks.OpenStackState.RequestItem.raw:type_name -> terraform1.stacks.AppliedChange.RawChange - 1, // 47: terraform1.stacks.PlanStackChanges.Request.plan_mode:type_name -> terraform1.stacks.PlanMode - 73, // 48: terraform1.stacks.PlanStackChanges.Request.previous_state:type_name -> terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry - 74, // 49: terraform1.stacks.PlanStackChanges.Request.input_values:type_name -> terraform1.stacks.PlanStackChanges.Request.InputValuesEntry - 33, // 50: terraform1.stacks.PlanStackChanges.Event.planned_change:type_name -> terraform1.stacks.PlannedChange - 128, // 51: terraform1.stacks.PlanStackChanges.Event.diagnostic:type_name -> terraform1.Diagnostic - 36, // 52: terraform1.stacks.PlanStackChanges.Event.progress:type_name -> terraform1.stacks.StackChangeProgress - 127, // 53: terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry.value:type_name -> google.protobuf.Any - 27, // 54: terraform1.stacks.PlanStackChanges.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource - 127, // 55: terraform1.stacks.OpenStackPlan.RequestItem.raw:type_name -> google.protobuf.Any - 127, // 56: terraform1.stacks.ApplyStackChanges.Request.planned_changes:type_name -> google.protobuf.Any - 81, // 57: terraform1.stacks.ApplyStackChanges.Request.input_values:type_name -> terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry - 35, // 58: terraform1.stacks.ApplyStackChanges.Event.applied_change:type_name -> terraform1.stacks.AppliedChange - 128, // 59: terraform1.stacks.ApplyStackChanges.Event.diagnostic:type_name -> terraform1.Diagnostic - 36, // 60: terraform1.stacks.ApplyStackChanges.Event.progress:type_name -> terraform1.stacks.StackChangeProgress - 27, // 61: terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource - 84, // 62: terraform1.stacks.OpenStackInspector.Request.state:type_name -> terraform1.stacks.OpenStackInspector.Request.StateEntry - 85, // 63: terraform1.stacks.OpenStackInspector.Request.input_values:type_name -> terraform1.stacks.OpenStackInspector.Request.InputValuesEntry - 128, // 64: terraform1.stacks.OpenStackInspector.Response.diagnostics:type_name -> terraform1.Diagnostic - 127, // 65: terraform1.stacks.OpenStackInspector.Request.StateEntry.value:type_name -> google.protobuf.Any - 27, // 66: terraform1.stacks.OpenStackInspector.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource - 25, // 67: terraform1.stacks.InspectExpressionResult.Response.result:type_name -> terraform1.stacks.DynamicValue - 128, // 68: terraform1.stacks.InspectExpressionResult.Response.diagnostics:type_name -> terraform1.Diagnostic - 90, // 69: terraform1.stacks.PlannedChange.ChangeDescription.component_instance_planned:type_name -> terraform1.stacks.PlannedChange.ComponentInstance - 91, // 70: terraform1.stacks.PlannedChange.ChangeDescription.resource_instance_planned:type_name -> terraform1.stacks.PlannedChange.ResourceInstance - 92, // 71: terraform1.stacks.PlannedChange.ChangeDescription.output_value_planned:type_name -> terraform1.stacks.PlannedChange.OutputValue - 93, // 72: terraform1.stacks.PlannedChange.ChangeDescription.resource_instance_deferred:type_name -> terraform1.stacks.PlannedChange.ResourceInstanceDeferred - 94, // 73: terraform1.stacks.PlannedChange.ChangeDescription.input_variable_planned:type_name -> terraform1.stacks.PlannedChange.InputVariable - 95, // 74: terraform1.stacks.PlannedChange.ChangeDescription.action_invocation_planned:type_name -> terraform1.stacks.PlannedChange.ActionInvocationInstance - 96, // 75: terraform1.stacks.PlannedChange.ChangeDescription.action_invocation_deferred:type_name -> terraform1.stacks.PlannedChange.ActionInvocationDeferred - 29, // 76: terraform1.stacks.PlannedChange.ComponentInstance.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr - 2, // 77: terraform1.stacks.PlannedChange.ComponentInstance.actions:type_name -> terraform1.stacks.ChangeType - 32, // 78: terraform1.stacks.PlannedChange.ResourceInstance.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 2, // 79: terraform1.stacks.PlannedChange.ResourceInstance.actions:type_name -> terraform1.stacks.ChangeType - 26, // 80: terraform1.stacks.PlannedChange.ResourceInstance.values:type_name -> terraform1.stacks.DynamicValueChange - 100, // 81: terraform1.stacks.PlannedChange.ResourceInstance.moved:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Moved - 101, // 82: terraform1.stacks.PlannedChange.ResourceInstance.imported:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Imported - 0, // 83: terraform1.stacks.PlannedChange.ResourceInstance.resource_mode:type_name -> terraform1.stacks.ResourceMode - 25, // 84: terraform1.stacks.PlannedChange.ResourceInstance.previous_run_value:type_name -> terraform1.stacks.DynamicValue - 28, // 85: terraform1.stacks.PlannedChange.ResourceInstance.replace_paths:type_name -> terraform1.stacks.AttributePath - 99, // 86: terraform1.stacks.PlannedChange.ResourceInstance.index:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Index - 2, // 87: terraform1.stacks.PlannedChange.OutputValue.actions:type_name -> terraform1.stacks.ChangeType - 26, // 88: terraform1.stacks.PlannedChange.OutputValue.values:type_name -> terraform1.stacks.DynamicValueChange - 91, // 89: terraform1.stacks.PlannedChange.ResourceInstanceDeferred.resource_instance:type_name -> terraform1.stacks.PlannedChange.ResourceInstance - 34, // 90: terraform1.stacks.PlannedChange.ResourceInstanceDeferred.deferred:type_name -> terraform1.stacks.Deferred - 2, // 91: terraform1.stacks.PlannedChange.InputVariable.actions:type_name -> terraform1.stacks.ChangeType - 26, // 92: terraform1.stacks.PlannedChange.InputVariable.values:type_name -> terraform1.stacks.DynamicValueChange - 30, // 93: terraform1.stacks.PlannedChange.ActionInvocationInstance.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr - 25, // 94: terraform1.stacks.PlannedChange.ActionInvocationInstance.config_value:type_name -> terraform1.stacks.DynamicValue - 97, // 95: terraform1.stacks.PlannedChange.ActionInvocationInstance.lifecycle_action_trigger:type_name -> terraform1.stacks.PlannedChange.LifecycleActionTrigger - 98, // 96: terraform1.stacks.PlannedChange.ActionInvocationInstance.invoke_action_trigger:type_name -> terraform1.stacks.PlannedChange.InvokeActionTrigger - 34, // 97: terraform1.stacks.PlannedChange.ActionInvocationDeferred.deferred:type_name -> terraform1.stacks.Deferred - 95, // 98: terraform1.stacks.PlannedChange.ActionInvocationDeferred.action_invocation:type_name -> terraform1.stacks.PlannedChange.ActionInvocationInstance - 31, // 99: terraform1.stacks.PlannedChange.LifecycleActionTrigger.triggering_resource_address:type_name -> terraform1.stacks.ResourceInstanceInStackAddr - 4, // 100: terraform1.stacks.PlannedChange.LifecycleActionTrigger.trigger_event:type_name -> terraform1.stacks.PlannedChange.ActionTriggerEvent - 25, // 101: terraform1.stacks.PlannedChange.ResourceInstance.Index.value:type_name -> terraform1.stacks.DynamicValue - 31, // 102: terraform1.stacks.PlannedChange.ResourceInstance.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr - 127, // 103: terraform1.stacks.AppliedChange.RawChange.value:type_name -> google.protobuf.Any - 108, // 104: terraform1.stacks.AppliedChange.ChangeDescription.deleted:type_name -> terraform1.stacks.AppliedChange.Nothing - 108, // 105: terraform1.stacks.AppliedChange.ChangeDescription.moved:type_name -> terraform1.stacks.AppliedChange.Nothing - 104, // 106: terraform1.stacks.AppliedChange.ChangeDescription.resource_instance:type_name -> terraform1.stacks.AppliedChange.ResourceInstance - 106, // 107: terraform1.stacks.AppliedChange.ChangeDescription.output_value:type_name -> terraform1.stacks.AppliedChange.OutputValue - 107, // 108: terraform1.stacks.AppliedChange.ChangeDescription.input_variable:type_name -> terraform1.stacks.AppliedChange.InputVariable - 105, // 109: terraform1.stacks.AppliedChange.ChangeDescription.component_instance:type_name -> terraform1.stacks.AppliedChange.ComponentInstance - 32, // 110: terraform1.stacks.AppliedChange.ResourceInstance.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 25, // 111: terraform1.stacks.AppliedChange.ResourceInstance.new_value:type_name -> terraform1.stacks.DynamicValue - 0, // 112: terraform1.stacks.AppliedChange.ResourceInstance.resource_mode:type_name -> terraform1.stacks.ResourceMode - 109, // 113: terraform1.stacks.AppliedChange.ComponentInstance.output_values:type_name -> terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry - 25, // 114: terraform1.stacks.AppliedChange.OutputValue.new_value:type_name -> terraform1.stacks.DynamicValue - 25, // 115: terraform1.stacks.AppliedChange.InputVariable.new_value:type_name -> terraform1.stacks.DynamicValue - 25, // 116: terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry.value:type_name -> terraform1.stacks.DynamicValue - 29, // 117: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr - 7, // 118: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.Status - 32, // 119: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 8, // 120: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.Status - 32, // 121: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 2, // 122: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.actions:type_name -> terraform1.stacks.ChangeType - 121, // 123: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.moved:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved - 122, // 124: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.imported:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Imported - 34, // 125: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange.deferred:type_name -> terraform1.stacks.Deferred - 112, // 126: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange.change:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange - 30, // 127: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr - 115, // 128: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.lifecycle_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.LifecycleActionTrigger - 116, // 129: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.invoke_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.InvokeActionTrigger - 31, // 130: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.triggering_resource_address:type_name -> terraform1.stacks.ResourceInstanceInStackAddr - 6, // 131: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.trigger_event:type_name -> terraform1.stacks.StackChangeProgress.ActionTriggerEvent - 32, // 132: terraform1.stacks.StackChangeProgress.ProvisionerStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 117, // 133: terraform1.stacks.StackChangeProgress.ProvisionerStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus - 32, // 134: terraform1.stacks.StackChangeProgress.ProvisionerOutput.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 29, // 135: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr - 31, // 136: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr - 125, // 137: terraform1.stacks.ListResourceIdentities.Response.resource:type_name -> terraform1.stacks.ListResourceIdentities.Resource - 25, // 138: terraform1.stacks.ListResourceIdentities.Resource.resource_identity:type_name -> terraform1.stacks.DynamicValue - 47, // 139: terraform1.stacks.Stacks.OpenStackConfiguration:input_type -> terraform1.stacks.OpenStackConfiguration.Request - 49, // 140: terraform1.stacks.Stacks.CloseStackConfiguration:input_type -> terraform1.stacks.CloseStackConfiguration.Request - 51, // 141: terraform1.stacks.Stacks.ValidateStackConfiguration:input_type -> terraform1.stacks.ValidateStackConfiguration.Request - 53, // 142: terraform1.stacks.Stacks.FindStackConfigurationComponents:input_type -> terraform1.stacks.FindStackConfigurationComponents.Request - 67, // 143: terraform1.stacks.Stacks.OpenState:input_type -> terraform1.stacks.OpenStackState.RequestItem - 69, // 144: terraform1.stacks.Stacks.CloseState:input_type -> terraform1.stacks.CloseStackState.Request - 71, // 145: terraform1.stacks.Stacks.PlanStackChanges:input_type -> terraform1.stacks.PlanStackChanges.Request - 75, // 146: terraform1.stacks.Stacks.OpenPlan:input_type -> terraform1.stacks.OpenStackPlan.RequestItem - 77, // 147: terraform1.stacks.Stacks.ClosePlan:input_type -> terraform1.stacks.CloseStackPlan.Request - 79, // 148: terraform1.stacks.Stacks.ApplyStackChanges:input_type -> terraform1.stacks.ApplyStackChanges.Request - 82, // 149: terraform1.stacks.Stacks.OpenStackInspector:input_type -> terraform1.stacks.OpenStackInspector.Request - 86, // 150: terraform1.stacks.Stacks.InspectExpressionResult:input_type -> terraform1.stacks.InspectExpressionResult.Request - 38, // 151: terraform1.stacks.Stacks.OpenTerraformState:input_type -> terraform1.stacks.OpenTerraformState.Request - 40, // 152: terraform1.stacks.Stacks.CloseTerraformState:input_type -> terraform1.stacks.CloseTerraformState.Request - 42, // 153: terraform1.stacks.Stacks.MigrateTerraformState:input_type -> terraform1.stacks.MigrateTerraformState.Request - 123, // 154: terraform1.stacks.Stacks.ListResourceIdentities:input_type -> terraform1.stacks.ListResourceIdentities.Request - 48, // 155: terraform1.stacks.Stacks.OpenStackConfiguration:output_type -> terraform1.stacks.OpenStackConfiguration.Response - 50, // 156: terraform1.stacks.Stacks.CloseStackConfiguration:output_type -> terraform1.stacks.CloseStackConfiguration.Response - 52, // 157: terraform1.stacks.Stacks.ValidateStackConfiguration:output_type -> terraform1.stacks.ValidateStackConfiguration.Response - 54, // 158: terraform1.stacks.Stacks.FindStackConfigurationComponents:output_type -> terraform1.stacks.FindStackConfigurationComponents.Response - 68, // 159: terraform1.stacks.Stacks.OpenState:output_type -> terraform1.stacks.OpenStackState.Response - 70, // 160: terraform1.stacks.Stacks.CloseState:output_type -> terraform1.stacks.CloseStackState.Response - 72, // 161: terraform1.stacks.Stacks.PlanStackChanges:output_type -> terraform1.stacks.PlanStackChanges.Event - 76, // 162: terraform1.stacks.Stacks.OpenPlan:output_type -> terraform1.stacks.OpenStackPlan.Response - 78, // 163: terraform1.stacks.Stacks.ClosePlan:output_type -> terraform1.stacks.CloseStackPlan.Response - 80, // 164: terraform1.stacks.Stacks.ApplyStackChanges:output_type -> terraform1.stacks.ApplyStackChanges.Event - 83, // 165: terraform1.stacks.Stacks.OpenStackInspector:output_type -> terraform1.stacks.OpenStackInspector.Response - 87, // 166: terraform1.stacks.Stacks.InspectExpressionResult:output_type -> terraform1.stacks.InspectExpressionResult.Response - 39, // 167: terraform1.stacks.Stacks.OpenTerraformState:output_type -> terraform1.stacks.OpenTerraformState.Response - 41, // 168: terraform1.stacks.Stacks.CloseTerraformState:output_type -> terraform1.stacks.CloseTerraformState.Response - 43, // 169: terraform1.stacks.Stacks.MigrateTerraformState:output_type -> terraform1.stacks.MigrateTerraformState.Event - 124, // 170: terraform1.stacks.Stacks.ListResourceIdentities:output_type -> terraform1.stacks.ListResourceIdentities.Response - 155, // [155:171] is the sub-list for method output_type - 139, // [139:155] is the sub-list for method input_type - 139, // [139:139] is the sub-list for extension type_name - 139, // [139:139] is the sub-list for extension extendee - 0, // [0:139] is the sub-list for field type_name + 103, // 9: terraform1.stacks.AppliedChange.raw:type_name -> terraform1.stacks.AppliedChange.RawChange + 104, // 10: terraform1.stacks.AppliedChange.descriptions:type_name -> terraform1.stacks.AppliedChange.ChangeDescription + 111, // 11: terraform1.stacks.StackChangeProgress.component_instance_status:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceStatus + 112, // 12: terraform1.stacks.StackChangeProgress.resource_instance_status:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstanceStatus + 113, // 13: terraform1.stacks.StackChangeProgress.resource_instance_planned_change:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange + 120, // 14: terraform1.stacks.StackChangeProgress.provisioner_status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus + 121, // 15: terraform1.stacks.StackChangeProgress.provisioner_output:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerOutput + 122, // 16: terraform1.stacks.StackChangeProgress.component_instance_changes:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceChanges + 123, // 17: terraform1.stacks.StackChangeProgress.component_instances:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstances + 114, // 18: terraform1.stacks.StackChangeProgress.deferred_resource_instance_planned_change:type_name -> terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange + 115, // 19: terraform1.stacks.StackChangeProgress.action_invocation_planned:type_name -> terraform1.stacks.StackChangeProgress.ActionInvocationPlanned + 116, // 20: terraform1.stacks.StackChangeProgress.action_invocation_status:type_name -> terraform1.stacks.StackChangeProgress.ActionInvocationStatus + 117, // 21: terraform1.stacks.StackChangeProgress.action_invocation_progress:type_name -> terraform1.stacks.StackChangeProgress.ActionInvocationProgress + 131, // 22: terraform1.stacks.OpenTerraformState.Response.diagnostics:type_name -> terraform1.Diagnostic + 45, // 23: terraform1.stacks.MigrateTerraformState.Request.simple:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping + 131, // 24: terraform1.stacks.MigrateTerraformState.Event.diagnostic:type_name -> terraform1.Diagnostic + 36, // 25: terraform1.stacks.MigrateTerraformState.Event.applied_change:type_name -> terraform1.stacks.AppliedChange + 46, // 26: terraform1.stacks.MigrateTerraformState.Request.Mapping.resource_address_map:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping.ResourceAddressMapEntry + 47, // 27: terraform1.stacks.MigrateTerraformState.Request.Mapping.module_address_map:type_name -> terraform1.stacks.MigrateTerraformState.Request.Mapping.ModuleAddressMapEntry + 132, // 28: terraform1.stacks.OpenStackConfiguration.Request.source_address:type_name -> terraform1.SourceAddress + 131, // 29: terraform1.stacks.OpenStackConfiguration.Response.diagnostics:type_name -> terraform1.Diagnostic + 131, // 30: terraform1.stacks.ValidateStackConfiguration.Response.diagnostics:type_name -> terraform1.Diagnostic + 56, // 31: terraform1.stacks.FindStackConfigurationComponents.Response.config:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig + 62, // 32: terraform1.stacks.FindStackConfigurationComponents.StackConfig.components:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry + 63, // 33: terraform1.stacks.FindStackConfigurationComponents.StackConfig.embedded_stacks:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry + 64, // 34: terraform1.stacks.FindStackConfigurationComponents.StackConfig.input_variables:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry + 65, // 35: terraform1.stacks.FindStackConfigurationComponents.StackConfig.output_values:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry + 66, // 36: terraform1.stacks.FindStackConfigurationComponents.StackConfig.removed:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry + 3, // 37: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances + 56, // 38: terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack.config:type_name -> terraform1.stacks.FindStackConfigurationComponents.StackConfig + 3, // 39: terraform1.stacks.FindStackConfigurationComponents.Component.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances + 3, // 40: terraform1.stacks.FindStackConfigurationComponents.Removed.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances + 67, // 41: terraform1.stacks.FindStackConfigurationComponents.Removed.blocks:type_name -> terraform1.stacks.FindStackConfigurationComponents.Removed.Block + 58, // 42: terraform1.stacks.FindStackConfigurationComponents.StackConfig.ComponentsEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.Component + 57, // 43: terraform1.stacks.FindStackConfigurationComponents.StackConfig.EmbeddedStacksEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.EmbeddedStack + 60, // 44: terraform1.stacks.FindStackConfigurationComponents.StackConfig.InputVariablesEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.InputVariable + 61, // 45: terraform1.stacks.FindStackConfigurationComponents.StackConfig.OutputValuesEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.OutputValue + 59, // 46: terraform1.stacks.FindStackConfigurationComponents.StackConfig.RemovedEntry.value:type_name -> terraform1.stacks.FindStackConfigurationComponents.Removed + 3, // 47: terraform1.stacks.FindStackConfigurationComponents.Removed.Block.instances:type_name -> terraform1.stacks.FindStackConfigurationComponents.Instances + 103, // 48: terraform1.stacks.OpenStackState.RequestItem.raw:type_name -> terraform1.stacks.AppliedChange.RawChange + 1, // 49: terraform1.stacks.PlanStackChanges.Request.plan_mode:type_name -> terraform1.stacks.PlanMode + 74, // 50: terraform1.stacks.PlanStackChanges.Request.previous_state:type_name -> terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry + 75, // 51: terraform1.stacks.PlanStackChanges.Request.input_values:type_name -> terraform1.stacks.PlanStackChanges.Request.InputValuesEntry + 34, // 52: terraform1.stacks.PlanStackChanges.Event.planned_change:type_name -> terraform1.stacks.PlannedChange + 131, // 53: terraform1.stacks.PlanStackChanges.Event.diagnostic:type_name -> terraform1.Diagnostic + 37, // 54: terraform1.stacks.PlanStackChanges.Event.progress:type_name -> terraform1.stacks.StackChangeProgress + 130, // 55: terraform1.stacks.PlanStackChanges.Request.PreviousStateEntry.value:type_name -> google.protobuf.Any + 28, // 56: terraform1.stacks.PlanStackChanges.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource + 130, // 57: terraform1.stacks.OpenStackPlan.RequestItem.raw:type_name -> google.protobuf.Any + 130, // 58: terraform1.stacks.ApplyStackChanges.Request.planned_changes:type_name -> google.protobuf.Any + 82, // 59: terraform1.stacks.ApplyStackChanges.Request.input_values:type_name -> terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry + 36, // 60: terraform1.stacks.ApplyStackChanges.Event.applied_change:type_name -> terraform1.stacks.AppliedChange + 131, // 61: terraform1.stacks.ApplyStackChanges.Event.diagnostic:type_name -> terraform1.Diagnostic + 37, // 62: terraform1.stacks.ApplyStackChanges.Event.progress:type_name -> terraform1.stacks.StackChangeProgress + 28, // 63: terraform1.stacks.ApplyStackChanges.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource + 85, // 64: terraform1.stacks.OpenStackInspector.Request.state:type_name -> terraform1.stacks.OpenStackInspector.Request.StateEntry + 86, // 65: terraform1.stacks.OpenStackInspector.Request.input_values:type_name -> terraform1.stacks.OpenStackInspector.Request.InputValuesEntry + 131, // 66: terraform1.stacks.OpenStackInspector.Response.diagnostics:type_name -> terraform1.Diagnostic + 130, // 67: terraform1.stacks.OpenStackInspector.Request.StateEntry.value:type_name -> google.protobuf.Any + 28, // 68: terraform1.stacks.OpenStackInspector.Request.InputValuesEntry.value:type_name -> terraform1.stacks.DynamicValueWithSource + 26, // 69: terraform1.stacks.InspectExpressionResult.Response.result:type_name -> terraform1.stacks.DynamicValue + 131, // 70: terraform1.stacks.InspectExpressionResult.Response.diagnostics:type_name -> terraform1.Diagnostic + 91, // 71: terraform1.stacks.PlannedChange.ChangeDescription.component_instance_planned:type_name -> terraform1.stacks.PlannedChange.ComponentInstance + 92, // 72: terraform1.stacks.PlannedChange.ChangeDescription.resource_instance_planned:type_name -> terraform1.stacks.PlannedChange.ResourceInstance + 93, // 73: terraform1.stacks.PlannedChange.ChangeDescription.output_value_planned:type_name -> terraform1.stacks.PlannedChange.OutputValue + 94, // 74: terraform1.stacks.PlannedChange.ChangeDescription.resource_instance_deferred:type_name -> terraform1.stacks.PlannedChange.ResourceInstanceDeferred + 95, // 75: terraform1.stacks.PlannedChange.ChangeDescription.input_variable_planned:type_name -> terraform1.stacks.PlannedChange.InputVariable + 96, // 76: terraform1.stacks.PlannedChange.ChangeDescription.action_invocation_planned:type_name -> terraform1.stacks.PlannedChange.ActionInvocationInstance + 97, // 77: terraform1.stacks.PlannedChange.ChangeDescription.action_invocation_deferred:type_name -> terraform1.stacks.PlannedChange.ActionInvocationDeferred + 30, // 78: terraform1.stacks.PlannedChange.ComponentInstance.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr + 2, // 79: terraform1.stacks.PlannedChange.ComponentInstance.actions:type_name -> terraform1.stacks.ChangeType + 33, // 80: terraform1.stacks.PlannedChange.ResourceInstance.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 2, // 81: terraform1.stacks.PlannedChange.ResourceInstance.actions:type_name -> terraform1.stacks.ChangeType + 27, // 82: terraform1.stacks.PlannedChange.ResourceInstance.values:type_name -> terraform1.stacks.DynamicValueChange + 101, // 83: terraform1.stacks.PlannedChange.ResourceInstance.moved:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Moved + 102, // 84: terraform1.stacks.PlannedChange.ResourceInstance.imported:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Imported + 0, // 85: terraform1.stacks.PlannedChange.ResourceInstance.resource_mode:type_name -> terraform1.stacks.ResourceMode + 26, // 86: terraform1.stacks.PlannedChange.ResourceInstance.previous_run_value:type_name -> terraform1.stacks.DynamicValue + 29, // 87: terraform1.stacks.PlannedChange.ResourceInstance.replace_paths:type_name -> terraform1.stacks.AttributePath + 100, // 88: terraform1.stacks.PlannedChange.ResourceInstance.index:type_name -> terraform1.stacks.PlannedChange.ResourceInstance.Index + 2, // 89: terraform1.stacks.PlannedChange.OutputValue.actions:type_name -> terraform1.stacks.ChangeType + 27, // 90: terraform1.stacks.PlannedChange.OutputValue.values:type_name -> terraform1.stacks.DynamicValueChange + 92, // 91: terraform1.stacks.PlannedChange.ResourceInstanceDeferred.resource_instance:type_name -> terraform1.stacks.PlannedChange.ResourceInstance + 35, // 92: terraform1.stacks.PlannedChange.ResourceInstanceDeferred.deferred:type_name -> terraform1.stacks.Deferred + 2, // 93: terraform1.stacks.PlannedChange.InputVariable.actions:type_name -> terraform1.stacks.ChangeType + 27, // 94: terraform1.stacks.PlannedChange.InputVariable.values:type_name -> terraform1.stacks.DynamicValueChange + 31, // 95: terraform1.stacks.PlannedChange.ActionInvocationInstance.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr + 26, // 96: terraform1.stacks.PlannedChange.ActionInvocationInstance.config_value:type_name -> terraform1.stacks.DynamicValue + 98, // 97: terraform1.stacks.PlannedChange.ActionInvocationInstance.lifecycle_action_trigger:type_name -> terraform1.stacks.PlannedChange.LifecycleActionTrigger + 99, // 98: terraform1.stacks.PlannedChange.ActionInvocationInstance.invoke_action_trigger:type_name -> terraform1.stacks.PlannedChange.InvokeActionTrigger + 35, // 99: terraform1.stacks.PlannedChange.ActionInvocationDeferred.deferred:type_name -> terraform1.stacks.Deferred + 96, // 100: terraform1.stacks.PlannedChange.ActionInvocationDeferred.action_invocation:type_name -> terraform1.stacks.PlannedChange.ActionInvocationInstance + 32, // 101: terraform1.stacks.PlannedChange.LifecycleActionTrigger.triggering_resource_address:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 4, // 102: terraform1.stacks.PlannedChange.LifecycleActionTrigger.trigger_event:type_name -> terraform1.stacks.PlannedChange.ActionTriggerEvent + 26, // 103: terraform1.stacks.PlannedChange.ResourceInstance.Index.value:type_name -> terraform1.stacks.DynamicValue + 32, // 104: terraform1.stacks.PlannedChange.ResourceInstance.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 130, // 105: terraform1.stacks.AppliedChange.RawChange.value:type_name -> google.protobuf.Any + 109, // 106: terraform1.stacks.AppliedChange.ChangeDescription.deleted:type_name -> terraform1.stacks.AppliedChange.Nothing + 109, // 107: terraform1.stacks.AppliedChange.ChangeDescription.moved:type_name -> terraform1.stacks.AppliedChange.Nothing + 105, // 108: terraform1.stacks.AppliedChange.ChangeDescription.resource_instance:type_name -> terraform1.stacks.AppliedChange.ResourceInstance + 107, // 109: terraform1.stacks.AppliedChange.ChangeDescription.output_value:type_name -> terraform1.stacks.AppliedChange.OutputValue + 108, // 110: terraform1.stacks.AppliedChange.ChangeDescription.input_variable:type_name -> terraform1.stacks.AppliedChange.InputVariable + 106, // 111: terraform1.stacks.AppliedChange.ChangeDescription.component_instance:type_name -> terraform1.stacks.AppliedChange.ComponentInstance + 33, // 112: terraform1.stacks.AppliedChange.ResourceInstance.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 26, // 113: terraform1.stacks.AppliedChange.ResourceInstance.new_value:type_name -> terraform1.stacks.DynamicValue + 0, // 114: terraform1.stacks.AppliedChange.ResourceInstance.resource_mode:type_name -> terraform1.stacks.ResourceMode + 110, // 115: terraform1.stacks.AppliedChange.ComponentInstance.output_values:type_name -> terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry + 26, // 116: terraform1.stacks.AppliedChange.OutputValue.new_value:type_name -> terraform1.stacks.DynamicValue + 26, // 117: terraform1.stacks.AppliedChange.InputVariable.new_value:type_name -> terraform1.stacks.DynamicValue + 26, // 118: terraform1.stacks.AppliedChange.ComponentInstance.OutputValuesEntry.value:type_name -> terraform1.stacks.DynamicValue + 30, // 119: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr + 7, // 120: terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ComponentInstanceStatus.Status + 33, // 121: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 8, // 122: terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstanceStatus.Status + 33, // 123: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 2, // 124: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.actions:type_name -> terraform1.stacks.ChangeType + 124, // 125: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.moved:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved + 125, // 126: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.imported:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Imported + 35, // 127: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange.deferred:type_name -> terraform1.stacks.Deferred + 113, // 128: terraform1.stacks.StackChangeProgress.DeferredResourceInstancePlannedChange.change:type_name -> terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange + 31, // 129: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr + 118, // 130: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.lifecycle_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.LifecycleActionTrigger + 119, // 131: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.invoke_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.InvokeActionTrigger + 31, // 132: terraform1.stacks.StackChangeProgress.ActionInvocationStatus.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr + 9, // 133: terraform1.stacks.StackChangeProgress.ActionInvocationStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ActionInvocationStatus.Status + 31, // 134: terraform1.stacks.StackChangeProgress.ActionInvocationProgress.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr + 32, // 135: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.triggering_resource_address:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 6, // 136: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.trigger_event:type_name -> terraform1.stacks.StackChangeProgress.ActionTriggerEvent + 33, // 137: terraform1.stacks.StackChangeProgress.ProvisionerStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 120, // 138: terraform1.stacks.StackChangeProgress.ProvisionerStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus + 33, // 139: terraform1.stacks.StackChangeProgress.ProvisionerOutput.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 30, // 140: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr + 32, // 141: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 128, // 142: terraform1.stacks.ListResourceIdentities.Response.resource:type_name -> terraform1.stacks.ListResourceIdentities.Resource + 26, // 143: terraform1.stacks.ListResourceIdentities.Resource.resource_identity:type_name -> terraform1.stacks.DynamicValue + 48, // 144: terraform1.stacks.Stacks.OpenStackConfiguration:input_type -> terraform1.stacks.OpenStackConfiguration.Request + 50, // 145: terraform1.stacks.Stacks.CloseStackConfiguration:input_type -> terraform1.stacks.CloseStackConfiguration.Request + 52, // 146: terraform1.stacks.Stacks.ValidateStackConfiguration:input_type -> terraform1.stacks.ValidateStackConfiguration.Request + 54, // 147: terraform1.stacks.Stacks.FindStackConfigurationComponents:input_type -> terraform1.stacks.FindStackConfigurationComponents.Request + 68, // 148: terraform1.stacks.Stacks.OpenState:input_type -> terraform1.stacks.OpenStackState.RequestItem + 70, // 149: terraform1.stacks.Stacks.CloseState:input_type -> terraform1.stacks.CloseStackState.Request + 72, // 150: terraform1.stacks.Stacks.PlanStackChanges:input_type -> terraform1.stacks.PlanStackChanges.Request + 76, // 151: terraform1.stacks.Stacks.OpenPlan:input_type -> terraform1.stacks.OpenStackPlan.RequestItem + 78, // 152: terraform1.stacks.Stacks.ClosePlan:input_type -> terraform1.stacks.CloseStackPlan.Request + 80, // 153: terraform1.stacks.Stacks.ApplyStackChanges:input_type -> terraform1.stacks.ApplyStackChanges.Request + 83, // 154: terraform1.stacks.Stacks.OpenStackInspector:input_type -> terraform1.stacks.OpenStackInspector.Request + 87, // 155: terraform1.stacks.Stacks.InspectExpressionResult:input_type -> terraform1.stacks.InspectExpressionResult.Request + 39, // 156: terraform1.stacks.Stacks.OpenTerraformState:input_type -> terraform1.stacks.OpenTerraformState.Request + 41, // 157: terraform1.stacks.Stacks.CloseTerraformState:input_type -> terraform1.stacks.CloseTerraformState.Request + 43, // 158: terraform1.stacks.Stacks.MigrateTerraformState:input_type -> terraform1.stacks.MigrateTerraformState.Request + 126, // 159: terraform1.stacks.Stacks.ListResourceIdentities:input_type -> terraform1.stacks.ListResourceIdentities.Request + 49, // 160: terraform1.stacks.Stacks.OpenStackConfiguration:output_type -> terraform1.stacks.OpenStackConfiguration.Response + 51, // 161: terraform1.stacks.Stacks.CloseStackConfiguration:output_type -> terraform1.stacks.CloseStackConfiguration.Response + 53, // 162: terraform1.stacks.Stacks.ValidateStackConfiguration:output_type -> terraform1.stacks.ValidateStackConfiguration.Response + 55, // 163: terraform1.stacks.Stacks.FindStackConfigurationComponents:output_type -> terraform1.stacks.FindStackConfigurationComponents.Response + 69, // 164: terraform1.stacks.Stacks.OpenState:output_type -> terraform1.stacks.OpenStackState.Response + 71, // 165: terraform1.stacks.Stacks.CloseState:output_type -> terraform1.stacks.CloseStackState.Response + 73, // 166: terraform1.stacks.Stacks.PlanStackChanges:output_type -> terraform1.stacks.PlanStackChanges.Event + 77, // 167: terraform1.stacks.Stacks.OpenPlan:output_type -> terraform1.stacks.OpenStackPlan.Response + 79, // 168: terraform1.stacks.Stacks.ClosePlan:output_type -> terraform1.stacks.CloseStackPlan.Response + 81, // 169: terraform1.stacks.Stacks.ApplyStackChanges:output_type -> terraform1.stacks.ApplyStackChanges.Event + 84, // 170: terraform1.stacks.Stacks.OpenStackInspector:output_type -> terraform1.stacks.OpenStackInspector.Response + 88, // 171: terraform1.stacks.Stacks.InspectExpressionResult:output_type -> terraform1.stacks.InspectExpressionResult.Response + 40, // 172: terraform1.stacks.Stacks.OpenTerraformState:output_type -> terraform1.stacks.OpenTerraformState.Response + 42, // 173: terraform1.stacks.Stacks.CloseTerraformState:output_type -> terraform1.stacks.CloseTerraformState.Response + 44, // 174: terraform1.stacks.Stacks.MigrateTerraformState:output_type -> terraform1.stacks.MigrateTerraformState.Event + 127, // 175: terraform1.stacks.Stacks.ListResourceIdentities:output_type -> terraform1.stacks.ListResourceIdentities.Response + 160, // [160:176] is the sub-list for method output_type + 144, // [144:160] is the sub-list for method input_type + 144, // [144:144] is the sub-list for extension type_name + 144, // [144:144] is the sub-list for extension extendee + 0, // [0:144] is the sub-list for field type_name } func init() { file_stacks_proto_init() } @@ -7982,6 +8214,8 @@ func file_stacks_proto_init() { (*StackChangeProgress_ComponentInstances_)(nil), (*StackChangeProgress_DeferredResourceInstancePlannedChange_)(nil), (*StackChangeProgress_ActionInvocationPlanned_)(nil), + (*StackChangeProgress_ActionInvocationStatus_)(nil), + (*StackChangeProgress_ActionInvocationProgress_)(nil), } file_stacks_proto_msgTypes[28].OneofWrappers = []any{ (*OpenTerraformState_Request_ConfigPath)(nil), @@ -8040,8 +8274,8 @@ func file_stacks_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_stacks_proto_rawDesc), len(file_stacks_proto_rawDesc)), - NumEnums: 10, - NumMessages: 116, + NumEnums: 11, + NumMessages: 118, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/rpcapi/terraform1/stacks/stacks.proto b/internal/rpcapi/terraform1/stacks/stacks.proto index 6ed0c98a20..dfb26cf7e0 100644 --- a/internal/rpcapi/terraform1/stacks/stacks.proto +++ b/internal/rpcapi/terraform1/stacks/stacks.proto @@ -866,6 +866,8 @@ message StackChangeProgress { ComponentInstances component_instances = 7; DeferredResourceInstancePlannedChange deferred_resource_instance_planned_change = 8; ActionInvocationPlanned action_invocation_planned = 9; + ActionInvocationStatus action_invocation_status = 10; + ActionInvocationProgress action_invocation_progress = 11; } // ComponentInstanceStatus describes the current status of a component instance @@ -943,6 +945,26 @@ message StackChangeProgress { } } + message ActionInvocationStatus { + ActionInvocationInstanceInStackAddr addr = 1; + Status status = 2; + string provider_addr = 3; + + enum Status { + INVALID = 0; + PENDING = 1; + RUNNING = 2; + COMPLETED = 3; + ERRORED = 4; + } + } + + message ActionInvocationProgress { + ActionInvocationInstanceInStackAddr addr = 1; + string message = 2; + string provider_addr = 3; + } + // LifecycleActionTrigger contains details on the conditions that led to the // triggering of an action. message LifecycleActionTrigger { From 551bf420901884b8b72fb14c344cacb0b53c6348 Mon Sep 17 00:00:00 2001 From: Mutahhir Hayat Date: Tue, 3 Feb 2026 12:05:22 +0100 Subject: [PATCH 03/24] Add Action Invocations in ComponenentInstanceChanges --- .../rpcapi/terraform1/stacks/stacks.pb.go | 36 ++++++++++++------- .../rpcapi/terraform1/stacks/stacks.proto | 1 + 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/internal/rpcapi/terraform1/stacks/stacks.pb.go b/internal/rpcapi/terraform1/stacks/stacks.pb.go index bbf0e72025..6b86bf999e 100644 --- a/internal/rpcapi/terraform1/stacks/stacks.pb.go +++ b/internal/rpcapi/terraform1/stacks/stacks.pb.go @@ -6890,16 +6890,17 @@ type StackChangeProgress_ComponentInstanceChanges struct { // difference should be treated as an "other change types" category, // for forward-compatibility when the Terraform Core RPC server is // using a newer version of this protocol than the client. - Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` - Add int32 `protobuf:"varint,3,opt,name=add,proto3" json:"add,omitempty"` - Change int32 `protobuf:"varint,4,opt,name=change,proto3" json:"change,omitempty"` - Import int32 `protobuf:"varint,5,opt,name=import,proto3" json:"import,omitempty"` - Remove int32 `protobuf:"varint,6,opt,name=remove,proto3" json:"remove,omitempty"` - Defer int32 `protobuf:"varint,7,opt,name=defer,proto3" json:"defer,omitempty"` - Move int32 `protobuf:"varint,8,opt,name=move,proto3" json:"move,omitempty"` - Forget int32 `protobuf:"varint,9,opt,name=forget,proto3" json:"forget,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` + Add int32 `protobuf:"varint,3,opt,name=add,proto3" json:"add,omitempty"` + Change int32 `protobuf:"varint,4,opt,name=change,proto3" json:"change,omitempty"` + Import int32 `protobuf:"varint,5,opt,name=import,proto3" json:"import,omitempty"` + Remove int32 `protobuf:"varint,6,opt,name=remove,proto3" json:"remove,omitempty"` + Defer int32 `protobuf:"varint,7,opt,name=defer,proto3" json:"defer,omitempty"` + Move int32 `protobuf:"varint,8,opt,name=move,proto3" json:"move,omitempty"` + Forget int32 `protobuf:"varint,9,opt,name=forget,proto3" json:"forget,omitempty"` + ActionInvocation int32 `protobuf:"varint,10,opt,name=action_invocation,json=actionInvocation,proto3" json:"action_invocation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *StackChangeProgress_ComponentInstanceChanges) Reset() { @@ -6995,6 +6996,13 @@ func (x *StackChangeProgress_ComponentInstanceChanges) GetForget() int32 { return 0 } +func (x *StackChangeProgress_ComponentInstanceChanges) GetActionInvocation() int32 { + if x != nil { + return x.ActionInvocation + } + return 0 +} + // ComponentInstances represents the result of expanding a component into zero // or more instances. type StackChangeProgress_ComponentInstances struct { @@ -7696,7 +7704,7 @@ const file_stacks_proto_rawDesc = "" + "\rInputVariable\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12<\n" + "\tnew_value\x18\x02 \x01(\v2\x1f.terraform1.stacks.DynamicValueR\bnewValue\x1a\t\n" + - "\aNothing\"\xb8'\n" + + "\aNothing\"\xe5'\n" + "\x13StackChangeProgress\x12|\n" + "\x19component_instance_status\x18\x01 \x01(\v2>.terraform1.stacks.StackChangeProgress.ComponentInstanceStatusH\x00R\x17componentInstanceStatus\x12y\n" + "\x18resource_instance_status\x18\x02 \x01(\v2=.terraform1.stacks.StackChangeProgress.ResourceInstanceStatusH\x00R\x16resourceInstanceStatus\x12\x8f\x01\n" + @@ -7789,7 +7797,7 @@ const file_stacks_proto_rawDesc = "" + "\x11ProvisionerOutput\x12H\n" + "\x04addr\x18\x01 \x01(\v24.terraform1.stacks.ResourceInstanceObjectInStackAddrR\x04addr\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x16\n" + - "\x06output\x18\x03 \x01(\tR\x06output\x1a\x91\x02\n" + + "\x06output\x18\x03 \x01(\tR\x06output\x1a\xbe\x02\n" + "\x18ComponentInstanceChanges\x12C\n" + "\x04addr\x18\x01 \x01(\v2/.terraform1.stacks.ComponentInstanceInStackAddrR\x04addr\x12\x14\n" + "\x05total\x18\x02 \x01(\x05R\x05total\x12\x10\n" + @@ -7799,7 +7807,9 @@ const file_stacks_proto_rawDesc = "" + "\x06remove\x18\x06 \x01(\x05R\x06remove\x12\x14\n" + "\x05defer\x18\a \x01(\x05R\x05defer\x12\x12\n" + "\x04move\x18\b \x01(\x05R\x04move\x12\x16\n" + - "\x06forget\x18\t \x01(\x05R\x06forget\x1ab\n" + + "\x06forget\x18\t \x01(\x05R\x06forget\x12+\n" + + "\x11action_invocation\x18\n" + + " \x01(\x05R\x10actionInvocation\x1ab\n" + "\x12ComponentInstances\x12%\n" + "\x0ecomponent_addr\x18\x01 \x01(\tR\rcomponentAddr\x12%\n" + "\x0einstance_addrs\x18\x02 \x03(\tR\rinstanceAddrs\"\xa4\x01\n" + diff --git a/internal/rpcapi/terraform1/stacks/stacks.proto b/internal/rpcapi/terraform1/stacks/stacks.proto index dfb26cf7e0..447f63fec7 100644 --- a/internal/rpcapi/terraform1/stacks/stacks.proto +++ b/internal/rpcapi/terraform1/stacks/stacks.proto @@ -1033,6 +1033,7 @@ message StackChangeProgress { int32 defer = 7; int32 move = 8; int32 forget = 9; + int32 action_invocation = 10; } // ComponentInstances represents the result of expanding a component into zero From 71f0afc644c199da880506ed100a0ae4ec8fe33b Mon Sep 17 00:00:00 2001 From: Mutahhir Hayat Date: Mon, 16 Feb 2026 15:05:18 +0100 Subject: [PATCH 04/24] Include trigger information in progress messages This disambiguates multiple invocations of the same action instance (see this excellent comment by @DanielMSchmidt for a better overview (https://github.com/hashicorp/terraform/pull/38051/changes#r2812460131) --- .../rpcapi/terraform1/stacks/stacks.pb.go | 234 +++++++++++++----- .../rpcapi/terraform1/stacks/stacks.proto | 14 +- 2 files changed, 186 insertions(+), 62 deletions(-) diff --git a/internal/rpcapi/terraform1/stacks/stacks.pb.go b/internal/rpcapi/terraform1/stacks/stacks.pb.go index 6b86bf999e..491d9ae8fb 100644 --- a/internal/rpcapi/terraform1/stacks/stacks.pb.go +++ b/internal/rpcapi/terraform1/stacks/stacks.pb.go @@ -6527,10 +6527,15 @@ func (*StackChangeProgress_ActionInvocationPlanned_InvokeActionTrigger) isStackC } type StackChangeProgress_ActionInvocationStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` - Addr *ActionInvocationInstanceInStackAddr `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` - Status StackChangeProgress_ActionInvocationStatus_Status `protobuf:"varint,2,opt,name=status,proto3,enum=terraform1.stacks.StackChangeProgress_ActionInvocationStatus_Status" json:"status,omitempty"` - ProviderAddr string `protobuf:"bytes,3,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Addr *ActionInvocationInstanceInStackAddr `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` + Status StackChangeProgress_ActionInvocationStatus_Status `protobuf:"varint,2,opt,name=status,proto3,enum=terraform1.stacks.StackChangeProgress_ActionInvocationStatus_Status" json:"status,omitempty"` + ProviderAddr string `protobuf:"bytes,3,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + // Types that are valid to be assigned to ActionTrigger: + // + // *StackChangeProgress_ActionInvocationStatus_LifecycleActionTrigger + // *StackChangeProgress_ActionInvocationStatus_InvokeActionTrigger + ActionTrigger isStackChangeProgress_ActionInvocationStatus_ActionTrigger `protobuf_oneof:"action_trigger"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -6586,11 +6591,59 @@ func (x *StackChangeProgress_ActionInvocationStatus) GetProviderAddr() string { return "" } +func (x *StackChangeProgress_ActionInvocationStatus) GetActionTrigger() isStackChangeProgress_ActionInvocationStatus_ActionTrigger { + if x != nil { + return x.ActionTrigger + } + return nil +} + +func (x *StackChangeProgress_ActionInvocationStatus) GetLifecycleActionTrigger() *StackChangeProgress_LifecycleActionTrigger { + if x != nil { + if x, ok := x.ActionTrigger.(*StackChangeProgress_ActionInvocationStatus_LifecycleActionTrigger); ok { + return x.LifecycleActionTrigger + } + } + return nil +} + +func (x *StackChangeProgress_ActionInvocationStatus) GetInvokeActionTrigger() *StackChangeProgress_InvokeActionTrigger { + if x != nil { + if x, ok := x.ActionTrigger.(*StackChangeProgress_ActionInvocationStatus_InvokeActionTrigger); ok { + return x.InvokeActionTrigger + } + } + return nil +} + +type isStackChangeProgress_ActionInvocationStatus_ActionTrigger interface { + isStackChangeProgress_ActionInvocationStatus_ActionTrigger() +} + +type StackChangeProgress_ActionInvocationStatus_LifecycleActionTrigger struct { + LifecycleActionTrigger *StackChangeProgress_LifecycleActionTrigger `protobuf:"bytes,4,opt,name=lifecycle_action_trigger,json=lifecycleActionTrigger,proto3,oneof"` +} + +type StackChangeProgress_ActionInvocationStatus_InvokeActionTrigger struct { + InvokeActionTrigger *StackChangeProgress_InvokeActionTrigger `protobuf:"bytes,5,opt,name=invoke_action_trigger,json=invokeActionTrigger,proto3,oneof"` +} + +func (*StackChangeProgress_ActionInvocationStatus_LifecycleActionTrigger) isStackChangeProgress_ActionInvocationStatus_ActionTrigger() { +} + +func (*StackChangeProgress_ActionInvocationStatus_InvokeActionTrigger) isStackChangeProgress_ActionInvocationStatus_ActionTrigger() { +} + type StackChangeProgress_ActionInvocationProgress struct { - state protoimpl.MessageState `protogen:"open.v1"` - Addr *ActionInvocationInstanceInStackAddr `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - ProviderAddr string `protobuf:"bytes,3,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Addr *ActionInvocationInstanceInStackAddr `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + ProviderAddr string `protobuf:"bytes,3,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty"` + // Types that are valid to be assigned to ActionTrigger: + // + // *StackChangeProgress_ActionInvocationProgress_LifecycleActionTrigger + // *StackChangeProgress_ActionInvocationProgress_InvokeActionTrigger + ActionTrigger isStackChangeProgress_ActionInvocationProgress_ActionTrigger `protobuf_oneof:"action_trigger"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -6646,6 +6699,49 @@ func (x *StackChangeProgress_ActionInvocationProgress) GetProviderAddr() string return "" } +func (x *StackChangeProgress_ActionInvocationProgress) GetActionTrigger() isStackChangeProgress_ActionInvocationProgress_ActionTrigger { + if x != nil { + return x.ActionTrigger + } + return nil +} + +func (x *StackChangeProgress_ActionInvocationProgress) GetLifecycleActionTrigger() *StackChangeProgress_LifecycleActionTrigger { + if x != nil { + if x, ok := x.ActionTrigger.(*StackChangeProgress_ActionInvocationProgress_LifecycleActionTrigger); ok { + return x.LifecycleActionTrigger + } + } + return nil +} + +func (x *StackChangeProgress_ActionInvocationProgress) GetInvokeActionTrigger() *StackChangeProgress_InvokeActionTrigger { + if x != nil { + if x, ok := x.ActionTrigger.(*StackChangeProgress_ActionInvocationProgress_InvokeActionTrigger); ok { + return x.InvokeActionTrigger + } + } + return nil +} + +type isStackChangeProgress_ActionInvocationProgress_ActionTrigger interface { + isStackChangeProgress_ActionInvocationProgress_ActionTrigger() +} + +type StackChangeProgress_ActionInvocationProgress_LifecycleActionTrigger struct { + LifecycleActionTrigger *StackChangeProgress_LifecycleActionTrigger `protobuf:"bytes,4,opt,name=lifecycle_action_trigger,json=lifecycleActionTrigger,proto3,oneof"` +} + +type StackChangeProgress_ActionInvocationProgress_InvokeActionTrigger struct { + InvokeActionTrigger *StackChangeProgress_InvokeActionTrigger `protobuf:"bytes,5,opt,name=invoke_action_trigger,json=invokeActionTrigger,proto3,oneof"` +} + +func (*StackChangeProgress_ActionInvocationProgress_LifecycleActionTrigger) isStackChangeProgress_ActionInvocationProgress_ActionTrigger() { +} + +func (*StackChangeProgress_ActionInvocationProgress_InvokeActionTrigger) isStackChangeProgress_ActionInvocationProgress_ActionTrigger() { +} + // LifecycleActionTrigger contains details on the conditions that led to the // triggering of an action. type StackChangeProgress_LifecycleActionTrigger struct { @@ -7704,7 +7800,7 @@ const file_stacks_proto_rawDesc = "" + "\rInputVariable\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12<\n" + "\tnew_value\x18\x02 \x01(\v2\x1f.terraform1.stacks.DynamicValueR\bnewValue\x1a\t\n" + - "\aNothing\"\xe5'\n" + + "\aNothing\"\xe3+\n" + "\x13StackChangeProgress\x12|\n" + "\x19component_instance_status\x18\x01 \x01(\v2>.terraform1.stacks.StackChangeProgress.ComponentInstanceStatusH\x00R\x17componentInstanceStatus\x12y\n" + "\x18resource_instance_status\x18\x02 \x01(\v2=.terraform1.stacks.StackChangeProgress.ResourceInstanceStatusH\x00R\x16resourceInstanceStatus\x12\x8f\x01\n" + @@ -7764,21 +7860,27 @@ const file_stacks_proto_rawDesc = "" + "\rprovider_addr\x18\x02 \x01(\tR\fproviderAddr\x12y\n" + "\x18lifecycle_action_trigger\x18\x03 \x01(\v2=.terraform1.stacks.StackChangeProgress.LifecycleActionTriggerH\x00R\x16lifecycleActionTrigger\x12p\n" + "\x15invoke_action_trigger\x18\x04 \x01(\v2:.terraform1.stacks.StackChangeProgress.InvokeActionTriggerH\x00R\x13invokeActionTriggerB\x10\n" + - "\x0eaction_trigger\x1a\xb4\x02\n" + + "\x0eaction_trigger\x1a\xb3\x04\n" + "\x16ActionInvocationStatus\x12J\n" + "\x04addr\x18\x01 \x01(\v26.terraform1.stacks.ActionInvocationInstanceInStackAddrR\x04addr\x12\\\n" + "\x06status\x18\x02 \x01(\x0e2D.terraform1.stacks.StackChangeProgress.ActionInvocationStatus.StatusR\x06status\x12#\n" + - "\rprovider_addr\x18\x03 \x01(\tR\fproviderAddr\"K\n" + + "\rprovider_addr\x18\x03 \x01(\tR\fproviderAddr\x12y\n" + + "\x18lifecycle_action_trigger\x18\x04 \x01(\v2=.terraform1.stacks.StackChangeProgress.LifecycleActionTriggerH\x00R\x16lifecycleActionTrigger\x12p\n" + + "\x15invoke_action_trigger\x18\x05 \x01(\v2:.terraform1.stacks.StackChangeProgress.InvokeActionTriggerH\x00R\x13invokeActionTrigger\"K\n" + "\x06Status\x12\v\n" + "\aINVALID\x10\x00\x12\v\n" + "\aPENDING\x10\x01\x12\v\n" + "\aRUNNING\x10\x02\x12\r\n" + "\tCOMPLETED\x10\x03\x12\v\n" + - "\aERRORED\x10\x04\x1a\xa5\x01\n" + + "\aERRORED\x10\x04B\x10\n" + + "\x0eaction_trigger\x1a\xa4\x03\n" + "\x18ActionInvocationProgress\x12J\n" + "\x04addr\x18\x01 \x01(\v26.terraform1.stacks.ActionInvocationInstanceInStackAddrR\x04addr\x12\x18\n" + "\amessage\x18\x02 \x01(\tR\amessage\x12#\n" + - "\rprovider_addr\x18\x03 \x01(\tR\fproviderAddr\x1a\xd3\x02\n" + + "\rprovider_addr\x18\x03 \x01(\tR\fproviderAddr\x12y\n" + + "\x18lifecycle_action_trigger\x18\x04 \x01(\v2=.terraform1.stacks.StackChangeProgress.LifecycleActionTriggerH\x00R\x16lifecycleActionTrigger\x12p\n" + + "\x15invoke_action_trigger\x18\x05 \x01(\v2:.terraform1.stacks.StackChangeProgress.InvokeActionTriggerH\x00R\x13invokeActionTriggerB\x10\n" + + "\x0eaction_trigger\x1a\xd3\x02\n" + "\x16LifecycleActionTrigger\x12n\n" + "\x1btriggering_resource_address\x18\x01 \x01(\v2..terraform1.stacks.ResourceInstanceInStackAddrR\x19triggeringResourceAddress\x12^\n" + "\rtrigger_event\x18\x02 \x01(\x0e29.terraform1.stacks.StackChangeProgress.ActionTriggerEventR\ftriggerEvent\x12;\n" + @@ -8160,53 +8262,57 @@ var file_stacks_proto_depIdxs = []int32{ 119, // 131: terraform1.stacks.StackChangeProgress.ActionInvocationPlanned.invoke_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.InvokeActionTrigger 31, // 132: terraform1.stacks.StackChangeProgress.ActionInvocationStatus.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr 9, // 133: terraform1.stacks.StackChangeProgress.ActionInvocationStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ActionInvocationStatus.Status - 31, // 134: terraform1.stacks.StackChangeProgress.ActionInvocationProgress.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr - 32, // 135: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.triggering_resource_address:type_name -> terraform1.stacks.ResourceInstanceInStackAddr - 6, // 136: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.trigger_event:type_name -> terraform1.stacks.StackChangeProgress.ActionTriggerEvent - 33, // 137: terraform1.stacks.StackChangeProgress.ProvisionerStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 120, // 138: terraform1.stacks.StackChangeProgress.ProvisionerStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus - 33, // 139: terraform1.stacks.StackChangeProgress.ProvisionerOutput.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr - 30, // 140: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr - 32, // 141: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr - 128, // 142: terraform1.stacks.ListResourceIdentities.Response.resource:type_name -> terraform1.stacks.ListResourceIdentities.Resource - 26, // 143: terraform1.stacks.ListResourceIdentities.Resource.resource_identity:type_name -> terraform1.stacks.DynamicValue - 48, // 144: terraform1.stacks.Stacks.OpenStackConfiguration:input_type -> terraform1.stacks.OpenStackConfiguration.Request - 50, // 145: terraform1.stacks.Stacks.CloseStackConfiguration:input_type -> terraform1.stacks.CloseStackConfiguration.Request - 52, // 146: terraform1.stacks.Stacks.ValidateStackConfiguration:input_type -> terraform1.stacks.ValidateStackConfiguration.Request - 54, // 147: terraform1.stacks.Stacks.FindStackConfigurationComponents:input_type -> terraform1.stacks.FindStackConfigurationComponents.Request - 68, // 148: terraform1.stacks.Stacks.OpenState:input_type -> terraform1.stacks.OpenStackState.RequestItem - 70, // 149: terraform1.stacks.Stacks.CloseState:input_type -> terraform1.stacks.CloseStackState.Request - 72, // 150: terraform1.stacks.Stacks.PlanStackChanges:input_type -> terraform1.stacks.PlanStackChanges.Request - 76, // 151: terraform1.stacks.Stacks.OpenPlan:input_type -> terraform1.stacks.OpenStackPlan.RequestItem - 78, // 152: terraform1.stacks.Stacks.ClosePlan:input_type -> terraform1.stacks.CloseStackPlan.Request - 80, // 153: terraform1.stacks.Stacks.ApplyStackChanges:input_type -> terraform1.stacks.ApplyStackChanges.Request - 83, // 154: terraform1.stacks.Stacks.OpenStackInspector:input_type -> terraform1.stacks.OpenStackInspector.Request - 87, // 155: terraform1.stacks.Stacks.InspectExpressionResult:input_type -> terraform1.stacks.InspectExpressionResult.Request - 39, // 156: terraform1.stacks.Stacks.OpenTerraformState:input_type -> terraform1.stacks.OpenTerraformState.Request - 41, // 157: terraform1.stacks.Stacks.CloseTerraformState:input_type -> terraform1.stacks.CloseTerraformState.Request - 43, // 158: terraform1.stacks.Stacks.MigrateTerraformState:input_type -> terraform1.stacks.MigrateTerraformState.Request - 126, // 159: terraform1.stacks.Stacks.ListResourceIdentities:input_type -> terraform1.stacks.ListResourceIdentities.Request - 49, // 160: terraform1.stacks.Stacks.OpenStackConfiguration:output_type -> terraform1.stacks.OpenStackConfiguration.Response - 51, // 161: terraform1.stacks.Stacks.CloseStackConfiguration:output_type -> terraform1.stacks.CloseStackConfiguration.Response - 53, // 162: terraform1.stacks.Stacks.ValidateStackConfiguration:output_type -> terraform1.stacks.ValidateStackConfiguration.Response - 55, // 163: terraform1.stacks.Stacks.FindStackConfigurationComponents:output_type -> terraform1.stacks.FindStackConfigurationComponents.Response - 69, // 164: terraform1.stacks.Stacks.OpenState:output_type -> terraform1.stacks.OpenStackState.Response - 71, // 165: terraform1.stacks.Stacks.CloseState:output_type -> terraform1.stacks.CloseStackState.Response - 73, // 166: terraform1.stacks.Stacks.PlanStackChanges:output_type -> terraform1.stacks.PlanStackChanges.Event - 77, // 167: terraform1.stacks.Stacks.OpenPlan:output_type -> terraform1.stacks.OpenStackPlan.Response - 79, // 168: terraform1.stacks.Stacks.ClosePlan:output_type -> terraform1.stacks.CloseStackPlan.Response - 81, // 169: terraform1.stacks.Stacks.ApplyStackChanges:output_type -> terraform1.stacks.ApplyStackChanges.Event - 84, // 170: terraform1.stacks.Stacks.OpenStackInspector:output_type -> terraform1.stacks.OpenStackInspector.Response - 88, // 171: terraform1.stacks.Stacks.InspectExpressionResult:output_type -> terraform1.stacks.InspectExpressionResult.Response - 40, // 172: terraform1.stacks.Stacks.OpenTerraformState:output_type -> terraform1.stacks.OpenTerraformState.Response - 42, // 173: terraform1.stacks.Stacks.CloseTerraformState:output_type -> terraform1.stacks.CloseTerraformState.Response - 44, // 174: terraform1.stacks.Stacks.MigrateTerraformState:output_type -> terraform1.stacks.MigrateTerraformState.Event - 127, // 175: terraform1.stacks.Stacks.ListResourceIdentities:output_type -> terraform1.stacks.ListResourceIdentities.Response - 160, // [160:176] is the sub-list for method output_type - 144, // [144:160] is the sub-list for method input_type - 144, // [144:144] is the sub-list for extension type_name - 144, // [144:144] is the sub-list for extension extendee - 0, // [0:144] is the sub-list for field type_name + 118, // 134: terraform1.stacks.StackChangeProgress.ActionInvocationStatus.lifecycle_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.LifecycleActionTrigger + 119, // 135: terraform1.stacks.StackChangeProgress.ActionInvocationStatus.invoke_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.InvokeActionTrigger + 31, // 136: terraform1.stacks.StackChangeProgress.ActionInvocationProgress.addr:type_name -> terraform1.stacks.ActionInvocationInstanceInStackAddr + 118, // 137: terraform1.stacks.StackChangeProgress.ActionInvocationProgress.lifecycle_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.LifecycleActionTrigger + 119, // 138: terraform1.stacks.StackChangeProgress.ActionInvocationProgress.invoke_action_trigger:type_name -> terraform1.stacks.StackChangeProgress.InvokeActionTrigger + 32, // 139: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.triggering_resource_address:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 6, // 140: terraform1.stacks.StackChangeProgress.LifecycleActionTrigger.trigger_event:type_name -> terraform1.stacks.StackChangeProgress.ActionTriggerEvent + 33, // 141: terraform1.stacks.StackChangeProgress.ProvisionerStatus.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 120, // 142: terraform1.stacks.StackChangeProgress.ProvisionerStatus.status:type_name -> terraform1.stacks.StackChangeProgress.ProvisionerStatus + 33, // 143: terraform1.stacks.StackChangeProgress.ProvisionerOutput.addr:type_name -> terraform1.stacks.ResourceInstanceObjectInStackAddr + 30, // 144: terraform1.stacks.StackChangeProgress.ComponentInstanceChanges.addr:type_name -> terraform1.stacks.ComponentInstanceInStackAddr + 32, // 145: terraform1.stacks.StackChangeProgress.ResourceInstancePlannedChange.Moved.prev_addr:type_name -> terraform1.stacks.ResourceInstanceInStackAddr + 128, // 146: terraform1.stacks.ListResourceIdentities.Response.resource:type_name -> terraform1.stacks.ListResourceIdentities.Resource + 26, // 147: terraform1.stacks.ListResourceIdentities.Resource.resource_identity:type_name -> terraform1.stacks.DynamicValue + 48, // 148: terraform1.stacks.Stacks.OpenStackConfiguration:input_type -> terraform1.stacks.OpenStackConfiguration.Request + 50, // 149: terraform1.stacks.Stacks.CloseStackConfiguration:input_type -> terraform1.stacks.CloseStackConfiguration.Request + 52, // 150: terraform1.stacks.Stacks.ValidateStackConfiguration:input_type -> terraform1.stacks.ValidateStackConfiguration.Request + 54, // 151: terraform1.stacks.Stacks.FindStackConfigurationComponents:input_type -> terraform1.stacks.FindStackConfigurationComponents.Request + 68, // 152: terraform1.stacks.Stacks.OpenState:input_type -> terraform1.stacks.OpenStackState.RequestItem + 70, // 153: terraform1.stacks.Stacks.CloseState:input_type -> terraform1.stacks.CloseStackState.Request + 72, // 154: terraform1.stacks.Stacks.PlanStackChanges:input_type -> terraform1.stacks.PlanStackChanges.Request + 76, // 155: terraform1.stacks.Stacks.OpenPlan:input_type -> terraform1.stacks.OpenStackPlan.RequestItem + 78, // 156: terraform1.stacks.Stacks.ClosePlan:input_type -> terraform1.stacks.CloseStackPlan.Request + 80, // 157: terraform1.stacks.Stacks.ApplyStackChanges:input_type -> terraform1.stacks.ApplyStackChanges.Request + 83, // 158: terraform1.stacks.Stacks.OpenStackInspector:input_type -> terraform1.stacks.OpenStackInspector.Request + 87, // 159: terraform1.stacks.Stacks.InspectExpressionResult:input_type -> terraform1.stacks.InspectExpressionResult.Request + 39, // 160: terraform1.stacks.Stacks.OpenTerraformState:input_type -> terraform1.stacks.OpenTerraformState.Request + 41, // 161: terraform1.stacks.Stacks.CloseTerraformState:input_type -> terraform1.stacks.CloseTerraformState.Request + 43, // 162: terraform1.stacks.Stacks.MigrateTerraformState:input_type -> terraform1.stacks.MigrateTerraformState.Request + 126, // 163: terraform1.stacks.Stacks.ListResourceIdentities:input_type -> terraform1.stacks.ListResourceIdentities.Request + 49, // 164: terraform1.stacks.Stacks.OpenStackConfiguration:output_type -> terraform1.stacks.OpenStackConfiguration.Response + 51, // 165: terraform1.stacks.Stacks.CloseStackConfiguration:output_type -> terraform1.stacks.CloseStackConfiguration.Response + 53, // 166: terraform1.stacks.Stacks.ValidateStackConfiguration:output_type -> terraform1.stacks.ValidateStackConfiguration.Response + 55, // 167: terraform1.stacks.Stacks.FindStackConfigurationComponents:output_type -> terraform1.stacks.FindStackConfigurationComponents.Response + 69, // 168: terraform1.stacks.Stacks.OpenState:output_type -> terraform1.stacks.OpenStackState.Response + 71, // 169: terraform1.stacks.Stacks.CloseState:output_type -> terraform1.stacks.CloseStackState.Response + 73, // 170: terraform1.stacks.Stacks.PlanStackChanges:output_type -> terraform1.stacks.PlanStackChanges.Event + 77, // 171: terraform1.stacks.Stacks.OpenPlan:output_type -> terraform1.stacks.OpenStackPlan.Response + 79, // 172: terraform1.stacks.Stacks.ClosePlan:output_type -> terraform1.stacks.CloseStackPlan.Response + 81, // 173: terraform1.stacks.Stacks.ApplyStackChanges:output_type -> terraform1.stacks.ApplyStackChanges.Event + 84, // 174: terraform1.stacks.Stacks.OpenStackInspector:output_type -> terraform1.stacks.OpenStackInspector.Response + 88, // 175: terraform1.stacks.Stacks.InspectExpressionResult:output_type -> terraform1.stacks.InspectExpressionResult.Response + 40, // 176: terraform1.stacks.Stacks.OpenTerraformState:output_type -> terraform1.stacks.OpenTerraformState.Response + 42, // 177: terraform1.stacks.Stacks.CloseTerraformState:output_type -> terraform1.stacks.CloseTerraformState.Response + 44, // 178: terraform1.stacks.Stacks.MigrateTerraformState:output_type -> terraform1.stacks.MigrateTerraformState.Event + 127, // 179: terraform1.stacks.Stacks.ListResourceIdentities:output_type -> terraform1.stacks.ListResourceIdentities.Response + 164, // [164:180] is the sub-list for method output_type + 148, // [148:164] is the sub-list for method input_type + 148, // [148:148] is the sub-list for extension type_name + 148, // [148:148] is the sub-list for extension extendee + 0, // [0:148] is the sub-list for field type_name } func init() { file_stacks_proto_init() } @@ -8279,6 +8385,14 @@ func file_stacks_proto_init() { (*StackChangeProgress_ActionInvocationPlanned_LifecycleActionTrigger)(nil), (*StackChangeProgress_ActionInvocationPlanned_InvokeActionTrigger)(nil), } + file_stacks_proto_msgTypes[105].OneofWrappers = []any{ + (*StackChangeProgress_ActionInvocationStatus_LifecycleActionTrigger)(nil), + (*StackChangeProgress_ActionInvocationStatus_InvokeActionTrigger)(nil), + } + file_stacks_proto_msgTypes[106].OneofWrappers = []any{ + (*StackChangeProgress_ActionInvocationProgress_LifecycleActionTrigger)(nil), + (*StackChangeProgress_ActionInvocationProgress_InvokeActionTrigger)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/internal/rpcapi/terraform1/stacks/stacks.proto b/internal/rpcapi/terraform1/stacks/stacks.proto index 447f63fec7..d7e3b4c673 100644 --- a/internal/rpcapi/terraform1/stacks/stacks.proto +++ b/internal/rpcapi/terraform1/stacks/stacks.proto @@ -940,8 +940,8 @@ message StackChangeProgress { ActionInvocationInstanceInStackAddr addr = 1; string provider_addr = 2; oneof action_trigger { - LifecycleActionTrigger lifecycle_action_trigger = 3; - InvokeActionTrigger invoke_action_trigger = 4; + LifecycleActionTrigger lifecycle_action_trigger = 3; + InvokeActionTrigger invoke_action_trigger = 4; } } @@ -950,6 +950,11 @@ message StackChangeProgress { Status status = 2; string provider_addr = 3; + oneof action_trigger { + LifecycleActionTrigger lifecycle_action_trigger = 4; + InvokeActionTrigger invoke_action_trigger = 5; + } + enum Status { INVALID = 0; PENDING = 1; @@ -963,6 +968,11 @@ message StackChangeProgress { ActionInvocationInstanceInStackAddr addr = 1; string message = 2; string provider_addr = 3; + + oneof action_trigger { + LifecycleActionTrigger lifecycle_action_trigger = 4; + InvokeActionTrigger invoke_action_trigger = 5; + } } // LifecycleActionTrigger contains details on the conditions that led to the From 2bb747222bae588c64c04942040dcf0fd098d6c4 Mon Sep 17 00:00:00 2001 From: Mutahhir Hayat Date: Mon, 2 Mar 2026 16:09:24 +0100 Subject: [PATCH 05/24] Update copyright for conversion_test.go --- internal/rpcapi/terraform1/stacks/conversion_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/rpcapi/terraform1/stacks/conversion_test.go b/internal/rpcapi/terraform1/stacks/conversion_test.go index 667f036795..7c0d89a28e 100644 --- a/internal/rpcapi/terraform1/stacks/conversion_test.go +++ b/internal/rpcapi/terraform1/stacks/conversion_test.go @@ -1,4 +1,4 @@ -// Copyright (c) HashiCorp, Inc. +// Copyright IBM Corp. 2014, 2026 // SPDX-License-Identifier: BUSL-1.1 package stacks From 07b3e3b8006d157438110f0bce429f8a09ffc574 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 4 Mar 2026 08:40:42 +0000 Subject: [PATCH 06/24] command/init: Merge duplicated PSS logic back into existing codepath (#38227) --- .changes/v1.15/NOTES-20260303-115443.yaml | 5 + internal/backend/init/init.go | 7 + internal/command/init.go | 680 +++++------------- internal/command/init_run.go | 182 +++-- internal/command/init_run_experiment.go | 527 -------------- .../command/testdata/init-get/output.jsonlog | 4 +- internal/command/views/init.go | 43 +- internal/command/views/init_test.go | 16 +- 8 files changed, 317 insertions(+), 1147 deletions(-) create mode 100644 .changes/v1.15/NOTES-20260303-115443.yaml delete mode 100644 internal/command/init_run_experiment.go diff --git a/.changes/v1.15/NOTES-20260303-115443.yaml b/.changes/v1.15/NOTES-20260303-115443.yaml new file mode 100644 index 0000000000..2b8be19f29 --- /dev/null +++ b/.changes/v1.15/NOTES-20260303-115443.yaml @@ -0,0 +1,5 @@ +kind: NOTES +body: 'command/init: Provider installation was refactored to enable future enhancements in the area. This results in different order of operations during init and 2 new log messages replacing one (`initializing_provider_plugin_message`). The change should not have any end-user impact aside from the `init` command output.' +time: 2026-03-03T11:54:43.732353Z +custom: + Issue: "38227" diff --git a/internal/backend/init/init.go b/internal/backend/init/init.go index 24f4c5787b..5b1549edea 100644 --- a/internal/backend/init/init.go +++ b/internal/backend/init/init.go @@ -93,6 +93,13 @@ func Backend(name string) backend.InitFn { return backends[name] } +func BackendExists(name string) bool { + backendsLock.Lock() + defer backendsLock.Unlock() + _, ok := backends[name] + return ok +} + // Set sets a new backend in the list of backends. If f is nil then the // backend will be removed from the map. If this backend already exists // then it will be overwritten. diff --git a/internal/command/init.go b/internal/command/init.go index 6bf73c9cf1..f8a56dc403 100644 --- a/internal/command/init.go +++ b/internal/command/init.go @@ -7,7 +7,9 @@ import ( "context" "fmt" "log" + "maps" "reflect" + "slices" "sort" "strings" @@ -26,6 +28,7 @@ import ( "github.com/hashicorp/terraform/internal/configs" "github.com/hashicorp/terraform/internal/configs/configschema" "github.com/hashicorp/terraform/internal/depsfile" + "github.com/hashicorp/terraform/internal/didyoumean" "github.com/hashicorp/terraform/internal/getproviders" "github.com/hashicorp/terraform/internal/getproviders/providerreqs" "github.com/hashicorp/terraform/internal/providercache" @@ -55,17 +58,7 @@ func (c *InitCommand) Run(args []string) int { return 1 } - // The else condition below invokes the original logic of the init command. - // An experimental version of the init code will be used if: - // > The user uses an experimental version of TF (alpha or built from source) - // > Either the flag -enable-pluggable-state-storage-experiment is passed to the init command. - // > Or, the environment variable TF_ENABLE_PLUGGABLE_STATE_STORAGE is set to any value. - if c.Meta.AllowExperimentalFeatures && initArgs.EnablePssExperiment { - // TODO(SarahFrench/radeksimko): Remove forked init logic once feature is no longer experimental - return c.runPssInit(initArgs, view) - } else { - return c.run(initArgs, view) - } + return c.run(initArgs, view) } func (c *InitCommand) getModules(ctx context.Context, path, testsDir string, earlyRoot *configs.Module, upgrade bool, view views.Init) (output bool, abort bool, diags tfdiags.Diagnostics) { @@ -152,16 +145,145 @@ func (c *InitCommand) initCloud(ctx context.Context, root *configs.Module, extra return back, true, diags } -func (c *InitCommand) initBackend(ctx context.Context, root *configs.Module, extraConfig arguments.FlagNameValueSlice, viewType arguments.ViewType, view views.Init) (be backend.Backend, output bool, diags tfdiags.Diagnostics) { +func (c *InitCommand) initBackend(ctx context.Context, root *configs.Module, initArgs *arguments.Init, configLocks *depsfile.Locks, view views.Init) (be backend.Backend, output bool, diags tfdiags.Diagnostics) { ctx, span := tracer.Start(ctx, "initialize backend") _ = ctx // prevent staticcheck from complaining to avoid a maintenance hazard of having the wrong ctx in scope here defer span.End() - view.Output(views.InitializingBackendMessage) + if root.StateStore != nil { + view.Output(views.InitializingStateStoreMessage) + } else { + view.Output(views.InitializingBackendMessage) + } - var backendConfig *configs.Backend - var backendConfigOverride hcl.Body - if root.Backend != nil { + var opts *BackendOpts + switch { + case root.StateStore != nil: + // state_store config present + factory, fDiags := c.Meta.StateStoreProviderFactoryFromConfig(root.StateStore, configLocks) + diags = diags.Append(fDiags) + if fDiags.HasErrors() { + return nil, true, diags + } + + // If overrides supplied by -backend-config CLI flag, process them + var configOverride hcl.Body + if !initArgs.BackendConfig.Empty() { + // We need to launch an instance of the provider to get the config of the state store for processing any overrides. + provider, err := factory() + defer provider.Close() // Stop the child process once we're done with it here. + if err != nil { + diags = diags.Append(fmt.Errorf("error when obtaining provider instance during state store initialization: %w", err)) + return nil, true, diags + } + + resp := provider.GetProviderSchema() + + if len(resp.StateStores) == 0 { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Provider does not support pluggable state storage", + Detail: fmt.Sprintf("There are no state stores implemented by provider %s (%q)", + root.StateStore.Provider.Name, + root.StateStore.ProviderAddr), + Subject: &root.StateStore.DeclRange, + }) + return nil, true, diags + } + + stateStoreSchema, exists := resp.StateStores[root.StateStore.Type] + if !exists { + suggestions := slices.Sorted(maps.Keys(resp.StateStores)) + suggestion := didyoumean.NameSuggestion(root.StateStore.Type, suggestions) + if suggestion != "" { + suggestion = fmt.Sprintf(" Did you mean %q?", suggestion) + } + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "State store not implemented by the provider", + Detail: fmt.Sprintf("State store %q is not implemented by provider %s (%q)%s", + root.StateStore.Type, root.StateStore.Provider.Name, + root.StateStore.ProviderAddr, suggestion), + Subject: &root.StateStore.DeclRange, + }) + return nil, true, diags + } + + // Handle any overrides supplied via -backend-config CLI flags + var overrideDiags tfdiags.Diagnostics + configOverride, overrideDiags = c.backendConfigOverrideBody(initArgs.BackendConfig, stateStoreSchema.Body) + diags = diags.Append(overrideDiags) + if overrideDiags.HasErrors() { + return nil, true, diags + } + } + + opts = &BackendOpts{ + StateStoreConfig: root.StateStore, + Locks: configLocks, + CreateDefaultWorkspace: initArgs.CreateDefaultWorkspace, + ConfigOverride: configOverride, + Init: true, + ViewType: initArgs.ViewType, + } + + case root.Backend != nil: + // backend config present + backendType := root.Backend.Type + bf := backendInit.Backend(backendType) + b := bf() + backendSchema := b.ConfigSchema() + backendConfig := root.Backend + + // If overrides supplied by -backend-config CLI flag, process them + var configOverride hcl.Body + if !initArgs.BackendConfig.Empty() { + var overrideDiags tfdiags.Diagnostics + configOverride, overrideDiags = c.backendConfigOverrideBody(initArgs.BackendConfig, backendSchema) + diags = diags.Append(overrideDiags) + if overrideDiags.HasErrors() { + return nil, true, diags + } + } + + opts = &BackendOpts{ + BackendConfig: backendConfig, + Locks: configLocks, + ConfigOverride: configOverride, + Init: true, + ViewType: initArgs.ViewType, + } + + default: + // No config; defaults to local state storage + opts = &BackendOpts{ + Init: true, + Locks: configLocks, + ViewType: initArgs.ViewType, + } + } + + back, backDiags := c.Backend(opts) + diags = diags.Append(backDiags) + return back, true, diags +} + +func (c *InitCommand) earlyValidateBackend(root *configs.Module, initArgs *arguments.Init) (diags tfdiags.Diagnostics) { + switch { + case root.StateStore != nil && root.Backend != nil: + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Conflicting backend and state_store configurations present during init", + Detail: fmt.Sprintf("When initializing the backend there was configuration data present for both backend %q and state store %q. This is a bug in Terraform and should be reported.", + root.Backend.Type, + root.StateStore.Type, + ), + Subject: &root.Backend.TypeRange, + }) + return diags + case root.StateStore != nil: + // validation requires the provider to be installed so cannot be done early + case root.Backend != nil: backendType := root.Backend.Type if backendType == "cloud" { diags = diags.Append(&hcl.Diagnostic{ @@ -170,11 +292,10 @@ func (c *InitCommand) initBackend(ctx context.Context, root *configs.Module, ext Detail: fmt.Sprintf("There is no explicit backend type named %q. To configure HCP Terraform, declare a 'cloud' block instead.", backendType), Subject: &root.Backend.TypeRange, }) - return nil, true, diags + return diags } - bf := backendInit.Backend(backendType) - if bf == nil { + if !backendInit.BackendExists(backendType) { detail := fmt.Sprintf("There is no backend type named %q.", backendType) if msg, removed := backendInit.RemovedBackends[backendType]; removed { detail = msg @@ -186,24 +307,15 @@ func (c *InitCommand) initBackend(ctx context.Context, root *configs.Module, ext Detail: detail, Subject: &root.Backend.TypeRange, }) - return nil, true, diags + return diags } + default: + // No config; defaults to local state storage - b := bf() - backendSchema := b.ConfigSchema() - backendConfig = root.Backend - - var overrideDiags tfdiags.Diagnostics - backendConfigOverride, overrideDiags = c.backendConfigOverrideBody(extraConfig, backendSchema) - diags = diags.Append(overrideDiags) - if overrideDiags.HasErrors() { - return nil, true, diags - } - } else { // If the user supplied a -backend-config on the CLI but no backend // block was found in the configuration, it's likely - but not // necessarily - a mistake. Return a warning. - if !extraConfig.Empty() { + if !initArgs.BackendConfig.Empty() { diags = diags.Append(tfdiags.Sourceless( tfdiags.Warning, "Missing backend configuration", @@ -223,471 +335,7 @@ the backend configuration is present and valid. )) } } - - opts := &BackendOpts{ - BackendConfig: backendConfig, - ConfigOverride: backendConfigOverride, - Init: true, - ViewType: viewType, - } - - back, backDiags := c.Backend(opts) - diags = diags.Append(backDiags) - return back, true, diags -} - -// getProviders determines what providers are required given configuration and state data. The method downloads any missing providers -// and replaces the contents of the dependency lock file if any changes happen. -// The calling code is expected to have loaded the complete module tree and read the state file, and passes that data into this method. -// -// This method outputs to the provided view. The returned `output` boolean lets calling code know if anything has been rendered via the view. -func (c *InitCommand) getProviders(ctx context.Context, config *configs.Config, state *states.State, upgrade bool, pluginDirs []string, flagLockfile string, view views.Init) (output, abort bool, diags tfdiags.Diagnostics) { - ctx, span := tracer.Start(ctx, "install providers") - defer span.End() - - // Dev overrides cause the result of "terraform init" to be irrelevant for - // any overridden providers, so we'll warn about it to avoid later - // confusion when Terraform ends up using a different provider than the - // lock file called for. - diags = diags.Append(c.providerDevOverrideInitWarnings()) - - // First we'll collect all the provider dependencies we can see in the - // configuration and the state. - reqs, hclDiags := config.ProviderRequirements() - diags = diags.Append(hclDiags) - if hclDiags.HasErrors() { - return false, true, diags - } - - reqs = c.removeDevOverrides(reqs) - if state != nil { - stateReqs := state.ProviderRequirements() - reqs = reqs.Merge(stateReqs) - } - for providerAddr := range reqs { - if providerAddr.IsLegacy() { - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Invalid legacy provider address", - fmt.Sprintf( - "This configuration or its associated state refers to the unqualified provider %q.\n\nYou must complete the Terraform 0.13 upgrade process before upgrading to later versions.", - providerAddr.Type, - ), - )) - } - } - - previousLocks, moreDiags := c.lockedDependencies() - diags = diags.Append(moreDiags) - - if diags.HasErrors() { - return false, true, diags - } - - var inst *providercache.Installer - if len(pluginDirs) == 0 { - // By default we use a source that looks for providers in all of the - // standard locations, possibly customized by the user in CLI config. - inst = c.providerInstaller() - } else { - // If the user passes at least one -plugin-dir then that circumvents - // the usual sources and forces Terraform to consult only the given - // directories. Anything not available in one of those directories - // is not available for installation. - source := c.providerCustomLocalDirectorySource(pluginDirs) - inst = c.providerInstallerCustomSource(source) - - // The default (or configured) search paths are logged earlier, in provider_source.go - // Log that those are being overridden by the `-plugin-dir` command line options - log.Println("[DEBUG] init: overriding provider plugin search paths") - log.Printf("[DEBUG] will search for provider plugins in %s", pluginDirs) - } - - // We want to print out a nice warning if we don't manage to pull - // checksums for all our providers. This is tracked via callbacks - // and incomplete providers are stored here for later analysis. - var incompleteProviders []string - - // Because we're currently just streaming a series of events sequentially - // into the terminal, we're showing only a subset of the events to keep - // things relatively concise. Later it'd be nice to have a progress UI - // where statuses update in-place, but we can't do that as long as we - // are shimming our vt100 output to the legacy console API on Windows. - evts := &providercache.InstallerEvents{ - PendingProviders: func(reqs map[addrs.Provider]getproviders.VersionConstraints) { - view.Output(views.InitializingProviderPluginMessage) - }, - ProviderAlreadyInstalled: func(provider addrs.Provider, selectedVersion getproviders.Version) { - view.LogInitMessage(views.ProviderAlreadyInstalledMessage, provider.ForDisplay(), selectedVersion) - }, - BuiltInProviderAvailable: func(provider addrs.Provider) { - view.LogInitMessage(views.BuiltInProviderAvailableMessage, provider.ForDisplay()) - }, - BuiltInProviderFailure: func(provider addrs.Provider, err error) { - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Invalid dependency on built-in provider", - fmt.Sprintf("Cannot use %s: %s.", provider.ForDisplay(), err), - )) - }, - QueryPackagesBegin: func(provider addrs.Provider, versionConstraints getproviders.VersionConstraints, locked bool) { - if locked { - view.LogInitMessage(views.ReusingPreviousVersionInfo, provider.ForDisplay()) - } else { - if len(versionConstraints) > 0 { - view.LogInitMessage(views.FindingMatchingVersionMessage, provider.ForDisplay(), getproviders.VersionConstraintsString(versionConstraints)) - } else { - view.LogInitMessage(views.FindingLatestVersionMessage, provider.ForDisplay()) - } - } - }, - LinkFromCacheBegin: func(provider addrs.Provider, version getproviders.Version, cacheRoot string) { - view.LogInitMessage(views.UsingProviderFromCacheDirInfo, provider.ForDisplay(), version) - }, - FetchPackageBegin: func(provider addrs.Provider, version getproviders.Version, location getproviders.PackageLocation) { - view.LogInitMessage(views.InstallingProviderMessage, provider.ForDisplay(), version) - }, - QueryPackagesFailure: func(provider addrs.Provider, err error) { - switch errorTy := err.(type) { - case getproviders.ErrProviderNotFound: - sources := errorTy.Sources - displaySources := make([]string, len(sources)) - for i, source := range sources { - displaySources[i] = fmt.Sprintf(" - %s", source) - } - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Failed to query available provider packages", - fmt.Sprintf("Could not retrieve the list of available versions for provider %s: %s\n\n%s", - provider.ForDisplay(), err, strings.Join(displaySources, "\n"), - ), - )) - case getproviders.ErrRegistryProviderNotKnown: - // We might be able to suggest an alternative provider to use - // instead of this one. - suggestion := fmt.Sprintf("\n\nAll modules should specify their required_providers so that external consumers will get the correct providers when using a module. To see which modules are currently depending on %s, run the following command:\n terraform providers", provider.ForDisplay()) - alternative := getproviders.MissingProviderSuggestion(ctx, provider, inst.ProviderSource(), reqs) - if alternative != provider { - suggestion = fmt.Sprintf( - "\n\nDid you intend to use %s? If so, you must specify that source address in each module which requires that provider. To see which modules are currently depending on %s, run the following command:\n terraform providers", - alternative.ForDisplay(), provider.ForDisplay(), - ) - } - - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Failed to query available provider packages", - fmt.Sprintf("Could not retrieve the list of available versions for provider %s: %s%s", - provider.ForDisplay(), err, suggestion, - ), - )) - case getproviders.ErrHostNoProviders: - switch { - case errorTy.Hostname == svchost.Hostname("github.com") && !errorTy.HasOtherVersion: - // If a user copies the URL of a GitHub repository into - // the source argument and removes the schema to make it - // provider-address-shaped then that's one way we can end up - // here. We'll use a specialized error message in anticipation - // of that mistake. We only do this if github.com isn't a - // provider registry, to allow for the (admittedly currently - // rather unlikely) possibility that github.com starts being - // a real Terraform provider registry in the future. - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Invalid provider registry host", - fmt.Sprintf("The given source address %q specifies a GitHub repository rather than a Terraform provider. Refer to the documentation of the provider to find the correct source address to use.", - provider.String(), - ), - )) - - case errorTy.HasOtherVersion: - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Invalid provider registry host", - fmt.Sprintf("The host %q given in provider source address %q does not offer a Terraform provider registry that is compatible with this Terraform version, but it may be compatible with a different Terraform version.", - errorTy.Hostname, provider.String(), - ), - )) - - default: - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Invalid provider registry host", - fmt.Sprintf("The host %q given in provider source address %q does not offer a Terraform provider registry.", - errorTy.Hostname, provider.String(), - ), - )) - } - - case getproviders.ErrRequestCanceled: - // We don't attribute cancellation to any particular operation, - // but rather just emit a single general message about it at - // the end, by checking ctx.Err(). - - default: - suggestion := fmt.Sprintf("\n\nTo see which modules are currently depending on %s and what versions are specified, run the following command:\n terraform providers", provider.ForDisplay()) - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Failed to query available provider packages", - fmt.Sprintf("Could not retrieve the list of available versions for provider %s: %s%s", - provider.ForDisplay(), err, suggestion, - ), - )) - } - - }, - QueryPackagesWarning: func(provider addrs.Provider, warnings []string) { - displayWarnings := make([]string, len(warnings)) - for i, warning := range warnings { - displayWarnings[i] = fmt.Sprintf("- %s", warning) - } - - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Warning, - "Additional provider information from registry", - fmt.Sprintf("The remote registry returned warnings for %s:\n%s", - provider.String(), - strings.Join(displayWarnings, "\n"), - ), - )) - }, - LinkFromCacheFailure: func(provider addrs.Provider, version getproviders.Version, err error) { - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Failed to install provider from shared cache", - fmt.Sprintf("Error while importing %s v%s from the shared cache directory: %s.", provider.ForDisplay(), version, err), - )) - }, - FetchPackageFailure: func(provider addrs.Provider, version getproviders.Version, err error) { - const summaryIncompatible = "Incompatible provider version" - switch err := err.(type) { - case getproviders.ErrProtocolNotSupported: - closestAvailable := err.Suggestion - switch { - case closestAvailable == getproviders.UnspecifiedVersion: - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - summaryIncompatible, - fmt.Sprintf(errProviderVersionIncompatible, provider.String()), - )) - case version.GreaterThan(closestAvailable): - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - summaryIncompatible, - fmt.Sprintf(providerProtocolTooNew, provider.ForDisplay(), - version, tfversion.String(), closestAvailable, closestAvailable, - getproviders.VersionConstraintsString(reqs[provider]), - ), - )) - default: // version is less than closestAvailable - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - summaryIncompatible, - fmt.Sprintf(providerProtocolTooOld, provider.ForDisplay(), - version, tfversion.String(), closestAvailable, closestAvailable, - getproviders.VersionConstraintsString(reqs[provider]), - ), - )) - } - case getproviders.ErrPlatformNotSupported: - switch { - case err.MirrorURL != nil: - // If we're installing from a mirror then it may just be - // the mirror lacking the package, rather than it being - // unavailable from upstream. - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - summaryIncompatible, - fmt.Sprintf( - "Your chosen provider mirror at %s does not have a %s v%s package available for your current platform, %s.\n\nProvider releases are separate from Terraform CLI releases, so this provider might not support your current platform. Alternatively, the mirror itself might have only a subset of the plugin packages available in the origin registry, at %s.", - err.MirrorURL, err.Provider, err.Version, err.Platform, - err.Provider.Hostname, - ), - )) - default: - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - summaryIncompatible, - fmt.Sprintf( - "Provider %s v%s does not have a package available for your current platform, %s.\n\nProvider releases are separate from Terraform CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.", - err.Provider, err.Version, err.Platform, - ), - )) - } - - case getproviders.ErrRequestCanceled: - // We don't attribute cancellation to any particular operation, - // but rather just emit a single general message about it at - // the end, by checking ctx.Err(). - - default: - // We can potentially end up in here under cancellation too, - // in spite of our getproviders.ErrRequestCanceled case above, - // because not all of the outgoing requests we do under the - // "fetch package" banner are source metadata requests. - // In that case we will emit a redundant error here about - // the request being cancelled, but we'll still detect it - // as a cancellation after the installer returns and do the - // normal cancellation handling. - - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Failed to install provider", - fmt.Sprintf("Error while installing %s v%s: %s", provider.ForDisplay(), version, err), - )) - } - }, - FetchPackageSuccess: func(provider addrs.Provider, version getproviders.Version, localDir string, authResult *getproviders.PackageAuthenticationResult) { - var keyID string - if authResult != nil && authResult.ThirdPartySigned() { - keyID = authResult.KeyID - } - if keyID != "" { - keyID = view.PrepareMessage(views.KeyID, keyID) - } - - view.LogInitMessage(views.InstalledProviderVersionInfo, provider.ForDisplay(), version, authResult, keyID) - }, - ProvidersLockUpdated: func(provider addrs.Provider, version getproviders.Version, localHashes []getproviders.Hash, signedHashes []getproviders.Hash, priorHashes []getproviders.Hash) { - // We're going to use this opportunity to track if we have any - // "incomplete" installs of providers. An incomplete install is - // when we are only going to write the local hashes into our lock - // file which means a `terraform init` command will fail in future - // when used on machines of a different architecture. - // - // We want to print a warning about this. - - if len(signedHashes) > 0 { - // If we have any signedHashes hashes then we don't worry - as - // we know we retrieved all available hashes for this version - // anyway. - return - } - - // If local hashes and prior hashes are exactly the same then - // it means we didn't record any signed hashes previously, and - // we know we're not adding any extra in now (because we already - // checked the signedHashes), so that's a problem. - // - // In the actual check here, if we have any priorHashes and those - // hashes are not the same as the local hashes then we're going to - // accept that this provider has been configured correctly. - if len(priorHashes) > 0 && !reflect.DeepEqual(localHashes, priorHashes) { - return - } - - // Now, either signedHashes is empty, or priorHashes is exactly the - // same as our localHashes which means we never retrieved the - // signedHashes previously. - // - // Either way, this is bad. Let's complain/warn. - incompleteProviders = append(incompleteProviders, provider.ForDisplay()) - }, - ProvidersFetched: func(authResults map[addrs.Provider]*getproviders.PackageAuthenticationResult) { - thirdPartySigned := false - for _, authResult := range authResults { - if authResult.ThirdPartySigned() { - thirdPartySigned = true - break - } - } - if thirdPartySigned { - view.LogInitMessage(views.PartnerAndCommunityProvidersMessage) - } - }, - } - ctx = evts.OnContext(ctx) - - mode := providercache.InstallNewProvidersOnly - if upgrade { - if flagLockfile == "readonly" { - diags = diags.Append(fmt.Errorf("The -upgrade flag conflicts with -lockfile=readonly.")) - view.Diagnostics(diags) - return true, true, diags - } - - mode = providercache.InstallUpgrades - } - newLocks, err := inst.EnsureProviderVersions(ctx, previousLocks, reqs, mode) - if ctx.Err() == context.Canceled { - diags = diags.Append(fmt.Errorf("Provider installation was canceled by an interrupt signal.")) - view.Diagnostics(diags) - return true, true, diags - } - if err != nil { - // The errors captured in "err" should be redundant with what we - // received via the InstallerEvents callbacks above, so we'll - // just return those as long as we have some. - if !diags.HasErrors() { - diags = diags.Append(err) - } - - return true, true, diags - } - - // If the provider dependencies have changed since the last run then we'll - // say a little about that in case the reader wasn't expecting a change. - // (When we later integrate module dependencies into the lock file we'll - // probably want to refactor this so that we produce one lock-file related - // message for all changes together, but this is here for now just because - // it's the smallest change relative to what came before it, which was - // a hidden JSON file specifically for tracking providers.) - if !newLocks.Equal(previousLocks) { - // if readonly mode - if flagLockfile == "readonly" { - // check if required provider dependencies change - if !newLocks.EqualProviderAddress(previousLocks) { - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - `Provider dependency changes detected`, - `Changes to the required provider dependencies were detected, but the lock file is read-only. To use and record these requirements, run "terraform init" without the "-lockfile=readonly" flag.`, - )) - return true, true, diags - } - - // suppress updating the file to record any new information it learned, - // such as a hash using a new scheme. - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Warning, - `Provider lock file not updated`, - `Changes to the provider selections were detected, but not saved in the .terraform.lock.hcl file. To record these selections, run "terraform init" without the "-lockfile=readonly" flag.`, - )) - return true, false, diags - } - - // Jump in here and add a warning if any of the providers are incomplete. - if len(incompleteProviders) > 0 { - // We don't really care about the order here, we just want the - // output to be deterministic. - sort.Slice(incompleteProviders, func(i, j int) bool { - return incompleteProviders[i] < incompleteProviders[j] - }) - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Warning, - incompleteLockFileInformationHeader, - fmt.Sprintf( - incompleteLockFileInformationBody, - strings.Join(incompleteProviders, "\n - "), - getproviders.CurrentPlatform.String()))) - } - - if previousLocks.Empty() { - // A change from empty to non-empty is special because it suggests - // we're running "terraform init" for the first time against a - // new configuration. In that case we'll take the opportunity to - // say a little about what the dependency lock file is, for new - // users or those who are upgrading from a previous Terraform - // version that didn't have dependency lock files. - view.Output(views.LockInfo) - } else { - view.Output(views.DependenciesLockChangesInfo) - } - - moreDiags = c.replaceLockedDependencies(newLocks) - diags = diags.Append(moreDiags) - } - - return true, false, diags + return diags } // getProvidersFromConfig determines what providers are required by the given configuration data. @@ -711,6 +359,8 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config return false, nil, diags } + reqs = c.removeDevOverrides(reqs) + for providerAddr := range reqs { if providerAddr.IsLegacy() { diags = diags.Append(tfdiags.Sourceless( @@ -746,7 +396,7 @@ func (c *InitCommand) getProvidersFromConfig(ctx context.Context, config *config log.Printf("[DEBUG] will search for provider plugins in %s", pluginDirs) } - evts := c.prepareInstallerEvents(ctx, reqs, diags, inst, view, views.InitializingProviderPluginFromConfigMessage, views.ReusingPreviousVersionInfo) + evts := c.prepareInstallerEvents(ctx, reqs, &diags, inst, view, views.InitializingProviderPluginFromConfigMessage, views.ReusingPreviousVersionInfo) ctx = evts.OnContext(ctx) mode := providercache.InstallNewProvidersOnly @@ -863,7 +513,7 @@ func (c *InitCommand) getProvidersFromState(ctx context.Context, state *states.S // things relatively concise. Later it'd be nice to have a progress UI // where statuses update in-place, but we can't do that as long as we // are shimming our vt100 output to the legacy console API on Windows. - evts := c.prepareInstallerEvents(ctx, reqs, diags, inst, view, views.InitializingProviderPluginFromStateMessage, views.ReusingVersionIdentifiedFromConfig) + evts := c.prepareInstallerEvents(ctx, reqs, &diags, inst, view, views.InitializingProviderPluginFromStateMessage, views.ReusingVersionIdentifiedFromConfig) ctx = evts.OnContext(ctx) mode := providercache.InstallNewProvidersOnly @@ -967,7 +617,7 @@ func (c *InitCommand) saveDependencyLockFile(previousLocks, configLocks, stateLo // prepareInstallerEvents returns an instance of *providercache.InstallerEvents. This struct defines callback functions that will be executed // when a specific type of event occurs during provider installation. // The calling code needs to provide a tfdiags.Diagnostics collection, so that provider installation code returns diags to the calling code using closures -func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerreqs.Requirements, diags tfdiags.Diagnostics, inst *providercache.Installer, view views.Init, initMsg views.InitMessageCode, reuseMsg views.InitMessageCode) *providercache.InstallerEvents { +func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerreqs.Requirements, diags *tfdiags.Diagnostics, inst *providercache.Installer, view views.Init, initMsg views.InitMessageCode, reuseMsg views.InitMessageCode) *providercache.InstallerEvents { // Because we're currently just streaming a series of events sequentially // into the terminal, we're showing only a subset of the events to keep @@ -985,7 +635,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr view.LogInitMessage(views.BuiltInProviderAvailableMessage, provider.ForDisplay()) }, BuiltInProviderFailure: func(provider addrs.Provider, err error) { - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Invalid dependency on built-in provider", fmt.Sprintf("Cannot use %s: %s.", provider.ForDisplay(), err), @@ -1016,7 +666,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr for i, source := range sources { displaySources[i] = fmt.Sprintf(" - %s", source) } - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Failed to query available provider packages", fmt.Sprintf("Could not retrieve the list of available versions for provider %s: %s\n\n%s", @@ -1035,7 +685,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr ) } - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Failed to query available provider packages", fmt.Sprintf("Could not retrieve the list of available versions for provider %s: %s%s", @@ -1053,7 +703,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr // provider registry, to allow for the (admittedly currently // rather unlikely) possibility that github.com starts being // a real Terraform provider registry in the future. - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Invalid provider registry host", fmt.Sprintf("The given source address %q specifies a GitHub repository rather than a Terraform provider. Refer to the documentation of the provider to find the correct source address to use.", @@ -1062,7 +712,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr )) case errorTy.HasOtherVersion: - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Invalid provider registry host", fmt.Sprintf("The host %q given in provider source address %q does not offer a Terraform provider registry that is compatible with this Terraform version, but it may be compatible with a different Terraform version.", @@ -1071,7 +721,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr )) default: - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Invalid provider registry host", fmt.Sprintf("The host %q given in provider source address %q does not offer a Terraform provider registry.", @@ -1087,7 +737,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr default: suggestion := fmt.Sprintf("\n\nTo see which modules are currently depending on %s and what versions are specified, run the following command:\n terraform providers", provider.ForDisplay()) - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Failed to query available provider packages", fmt.Sprintf("Could not retrieve the list of available versions for provider %s: %s%s", @@ -1103,7 +753,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr displayWarnings[i] = fmt.Sprintf("- %s", warning) } - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Warning, "Additional provider information from registry", fmt.Sprintf("The remote registry returned warnings for %s:\n%s", @@ -1113,7 +763,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr )) }, LinkFromCacheFailure: func(provider addrs.Provider, version getproviders.Version, err error) { - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Failed to install provider from shared cache", fmt.Sprintf("Error while importing %s v%s from the shared cache directory: %s.", provider.ForDisplay(), version, err), @@ -1126,13 +776,13 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr closestAvailable := err.Suggestion switch { case closestAvailable == getproviders.UnspecifiedVersion: - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, summaryIncompatible, fmt.Sprintf(errProviderVersionIncompatible, provider.String()), )) case version.GreaterThan(closestAvailable): - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, summaryIncompatible, fmt.Sprintf(providerProtocolTooNew, provider.ForDisplay(), @@ -1141,7 +791,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr ), )) default: // version is less than closestAvailable - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, summaryIncompatible, fmt.Sprintf(providerProtocolTooOld, provider.ForDisplay(), @@ -1156,7 +806,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr // If we're installing from a mirror then it may just be // the mirror lacking the package, rather than it being // unavailable from upstream. - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, summaryIncompatible, fmt.Sprintf( @@ -1166,7 +816,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr ), )) default: - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, summaryIncompatible, fmt.Sprintf( @@ -1191,7 +841,7 @@ func (c *InitCommand) prepareInstallerEvents(ctx context.Context, reqs providerr // as a cancellation after the installer returns and do the // normal cancellation handling. - diags = diags.Append(tfdiags.Sourceless( + *diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Failed to install provider", fmt.Sprintf("Error while installing %s v%s: %s", provider.ForDisplay(), version, err), diff --git a/internal/command/init_run.go b/internal/command/init_run.go index 880b4b6027..d63013f94e 100644 --- a/internal/command/init_run.go +++ b/internal/command/init_run.go @@ -163,18 +163,78 @@ func (c *InitCommand) run(initArgs *arguments.Init, view views.Init) int { return 1 } + if initArgs.Get { + modsOutput, modsAbort, modsDiags := c.getModules(ctx, path, initArgs.TestsDirectory, rootModEarly, initArgs.Upgrade, view) + diags = diags.Append(modsDiags) + if modsAbort || modsDiags.HasErrors() { + view.Diagnostics(diags) + return 1 + } + if modsOutput { + header = true + } + } + + // With all of the modules (hopefully) installed, we can now try to load the + // whole configuration tree. + config, confDiags := c.loadConfigWithTests(path, initArgs.TestsDirectory) + // configDiags will be handled after: + // - the version constraint check has happened + // - and, the backend/state_store is initialised + + // Before we go further, we'll check to make sure none of the modules in + // the configuration declare that they don't support this Terraform + // version, so we can produce a version-related error message rather than + // potentially-confusing downstream errors. + versionDiags := terraform.CheckCoreVersionRequirements(config) + if versionDiags.HasErrors() { + view.Diagnostics(versionDiags) + return 1 + } + + earlyBdiags := c.earlyValidateBackend(rootModEarly, initArgs) + diags = diags.Append(earlyBdiags) + + // We've passed the core version check, now we can show errors from the early configuration. + // This prevents trying to initialise the backend with faulty configuration. + if earlyConfDiags.HasErrors() || earlyBdiags.HasErrors() { + diags = diags.Append(errors.New(view.PrepareMessage(views.InitConfigError)), earlyConfDiags) + view.Diagnostics(diags) + return 1 + } + + // Now the full configuration is loaded, we can download the providers specified in the configuration. + // This is step one of a two-step provider download process + // Providers may be downloaded by this code, but the dependency lock file is only updated later in `init` + // after step two of provider download is complete. + previousLocks, moreDiags := c.lockedDependencies() + diags = diags.Append(moreDiags) + + configProvidersOutput, configLocks, configProviderDiags := c.getProvidersFromConfig(ctx, config, initArgs.Upgrade, initArgs.PluginPath, initArgs.Lockfile, view) + diags = diags.Append(configProviderDiags) + if configProviderDiags.HasErrors() { + view.Diagnostics(diags) + return 1 + } + if configProvidersOutput { + header = true + } + + // If we outputted information, then we need to output a newline + // so that our success message is nicely spaced out from prior text. + if header { + view.Output(views.EmptyMessage) + } + var back backend.Backend - // There may be config errors or backend init errors but these will be shown later _after_ - // checking for core version requirement errors. var backDiags tfdiags.Diagnostics var backendOutput bool - switch { case initArgs.Cloud && rootModEarly.CloudConfig != nil: back, backendOutput, backDiags = c.initCloud(ctx, rootModEarly, initArgs.BackendConfig, initArgs.ViewType, view) case initArgs.Backend: - back, backendOutput, backDiags = c.initBackend(ctx, rootModEarly, initArgs.BackendConfig, initArgs.ViewType, view) + back, backendOutput, backDiags = c.initBackend(ctx, rootModEarly, initArgs, configLocks, view) default: // load the previously-stored backend config back, backDiags = c.Meta.backendFromState(ctx) @@ -182,6 +242,29 @@ func (c *InitCommand) run(initArgs *arguments.Init, view views.Init) int { if backendOutput { header = true } + if header { + // If we outputted information, then we need to output a newline + // so that our success message is nicely spaced out from prior text. + view.Output(views.EmptyMessage) + } + + // Show any errors from initializing the backend. + // No preamble using `InitConfigError` is present, as we expect + // any errors to from configuring the backend itself. + diags = diags.Append(backDiags) + if backDiags.HasErrors() { + view.Diagnostics(diags) + return 1 + } + + // If everything is ok with the core version check and backend/state_store initialization, + // show other errors from loading the full configuration tree. + diags = diags.Append(confDiags) + if confDiags.HasErrors() { + diags = diags.Append(errors.New(view.PrepareMessage(views.InitConfigError))) + view.Diagnostics(diags) + return 1 + } var state *states.State @@ -212,63 +295,37 @@ func (c *InitCommand) run(initArgs *arguments.Init, view views.Init) int { state = sMgr.State() } - if initArgs.Get { - modsOutput, modsAbort, modsDiags := c.getModules(ctx, path, initArgs.TestsDirectory, rootModEarly, initArgs.Upgrade, view) - diags = diags.Append(modsDiags) - if modsAbort || modsDiags.HasErrors() { - view.Diagnostics(diags) - return 1 - } - if modsOutput { - header = true - } - } - - // With all of the modules (hopefully) installed, we can now try to load the - // whole configuration tree. - config, confDiags := c.loadConfigWithTests(path, initArgs.TestsDirectory) - // configDiags will be handled after the version constraint check, since an - // incorrect version of terraform may be producing errors for configuration - // constructs added in later versions. - - // Before we go further, we'll check to make sure none of the modules in - // the configuration declare that they don't support this Terraform - // version, so we can produce a version-related error message rather than - // potentially-confusing downstream errors. - versionDiags := terraform.CheckCoreVersionRequirements(config) - if versionDiags.HasErrors() { - view.Diagnostics(versionDiags) - return 1 - } - - // We've passed the core version check, now we can show errors from the - // configuration and backend initialisation. - - // Now, we can check the diagnostics from the early configuration and the - // backend. - diags = diags.Append(earlyConfDiags) - diags = diags.Append(backDiags) - if earlyConfDiags.HasErrors() { - diags = diags.Append(errors.New(view.PrepareMessage(views.InitConfigError))) + // Now the resource state is loaded, we can download the providers specified in the state but not the configuration. + // This is step two of a two-step provider download process + stateProvidersOutput, stateLocks, stateProvidersDiags := c.getProvidersFromState(ctx, state, configLocks, initArgs.Upgrade, initArgs.PluginPath, initArgs.Lockfile, view) + diags = diags.Append(stateProvidersDiags) + if stateProvidersDiags.HasErrors() { view.Diagnostics(diags) return 1 } + if stateProvidersOutput { + header = true + } + if header { + // If we outputted information, then we need to output a newline + // so that our success message is nicely spaced out from prior text. + view.Output(views.EmptyMessage) + } - // Now, we can show any errors from initializing the backend, but we won't - // show the InitConfigError preamble as we didn't detect problems with - // the early configuration. - if backDiags.HasErrors() { + // Now the two steps of provider download have happened, update the dependency lock file if it has changed. + lockFileOutput, lockFileDiags := c.saveDependencyLockFile(previousLocks, configLocks, stateLocks, initArgs.Lockfile, view) + diags = diags.Append(lockFileDiags) + if lockFileDiags.HasErrors() { view.Diagnostics(diags) return 1 } - - // If everything is ok with the core version check and backend initialization, - // show other errors from loading the full configuration tree. - diags = diags.Append(confDiags) - if confDiags.HasErrors() { - diags = diags.Append(errors.New(view.PrepareMessage(views.InitConfigError))) - view.Diagnostics(diags) - return 1 + if lockFileOutput { + header = true + } + if header { + // If we outputted information, then we need to output a newline + // so that our success message is nicely spaced out from prior text. + view.Output(views.EmptyMessage) } if cb, ok := back.(*cloud.Cloud); ok { @@ -281,23 +338,6 @@ func (c *InitCommand) run(initArgs *arguments.Init, view views.Init) int { } } - // Now that we have loaded all modules, check the module tree for missing providers. - providersOutput, providersAbort, providerDiags := c.getProviders(ctx, config, state, initArgs.Upgrade, initArgs.PluginPath, initArgs.Lockfile, view) - diags = diags.Append(providerDiags) - if providersAbort || providerDiags.HasErrors() { - view.Diagnostics(diags) - return 1 - } - if providersOutput { - header = true - } - - // If we outputted information, then we need to output a newline - // so that our success message is nicely spaced out from prior text. - if header { - view.Output(views.EmptyMessage) - } - // If we accumulated any warnings along the way that weren't accompanied // by errors then we'll output them here so that the success message is // still the final thing shown. diff --git a/internal/command/init_run_experiment.go b/internal/command/init_run_experiment.go deleted file mode 100644 index da6b2e6419..0000000000 --- a/internal/command/init_run_experiment.go +++ /dev/null @@ -1,527 +0,0 @@ -// Copyright IBM Corp. 2014, 2026 -// SPDX-License-Identifier: BUSL-1.1 - -package command - -import ( - "context" - "errors" - "fmt" - "maps" - "slices" - "strings" - - "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/terraform/internal/backend" - backendInit "github.com/hashicorp/terraform/internal/backend/init" - "github.com/hashicorp/terraform/internal/cloud" - "github.com/hashicorp/terraform/internal/command/arguments" - "github.com/hashicorp/terraform/internal/command/views" - "github.com/hashicorp/terraform/internal/configs" - "github.com/hashicorp/terraform/internal/depsfile" - "github.com/hashicorp/terraform/internal/didyoumean" - "github.com/hashicorp/terraform/internal/states" - "github.com/hashicorp/terraform/internal/terraform" - "github.com/hashicorp/terraform/internal/tfdiags" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/trace" -) - -// `runPssInit` is an altered version of the logic in `run` that contains changes -// related to the PSS project. This is used by the (InitCommand.Run method only if Terraform has -// experimental features enabled. -func (c *InitCommand) runPssInit(initArgs *arguments.Init, view views.Init) int { - var diags tfdiags.Diagnostics - - c.forceInitCopy = initArgs.ForceInitCopy - c.Meta.stateLock = initArgs.StateLock - c.Meta.stateLockTimeout = initArgs.StateLockTimeout - c.reconfigure = initArgs.Reconfigure - c.migrateState = initArgs.MigrateState - c.Meta.ignoreRemoteVersion = initArgs.IgnoreRemoteVersion - c.Meta.input = initArgs.InputEnabled - c.Meta.targetFlags = initArgs.TargetFlags - c.Meta.compactWarnings = initArgs.CompactWarnings - - // Copying the state only happens during backend migration, so setting - // -force-copy implies -migrate-state - if c.forceInitCopy { - c.migrateState = true - } - - if len(initArgs.PluginPath) > 0 { - c.pluginPath = initArgs.PluginPath - } - - // Validate the arg count and get the working directory - path, err := ModulePath(initArgs.Args) - if err != nil { - diags = diags.Append(err) - view.Diagnostics(diags) - return 1 - } - - if err := c.storePluginPath(c.pluginPath); err != nil { - diags = diags.Append(fmt.Errorf("Error saving -plugin-dir to workspace directory: %s", err)) - view.Diagnostics(diags) - return 1 - } - - // Initialization can be aborted by interruption signals - ctx, done := c.InterruptibleContext(c.CommandContext()) - defer done() - - // This will track whether we outputted anything so that we know whether - // to output a newline before the success message - var header bool - - if initArgs.FromModule != "" { - src := initArgs.FromModule - - empty, err := configs.IsEmptyDir(path, initArgs.TestsDirectory) - if err != nil { - diags = diags.Append(fmt.Errorf("Error validating destination directory: %s", err)) - view.Diagnostics(diags) - return 1 - } - if !empty { - diags = diags.Append(errors.New(strings.TrimSpace(errInitCopyNotEmpty))) - view.Diagnostics(diags) - return 1 - } - - view.Output(views.CopyingConfigurationMessage, src) - header = true - - hooks := uiModuleInstallHooks{ - Ui: c.Ui, - ShowLocalPaths: false, // since they are in a weird location for init - View: view, - } - - ctx, span := tracer.Start(ctx, "-from-module=...", trace.WithAttributes( - attribute.String("module_source", src), - )) - - initDirFromModuleAbort, initDirFromModuleDiags := c.initDirFromModule(ctx, path, src, hooks) - diags = diags.Append(initDirFromModuleDiags) - if initDirFromModuleAbort || initDirFromModuleDiags.HasErrors() { - view.Diagnostics(diags) - span.SetStatus(codes.Error, "module installation failed") - span.End() - return 1 - } - span.End() - - view.Output(views.EmptyMessage) - } - - // If our directory is empty, then we're done. We can't get or set up - // the backend with an empty directory. - empty, err := configs.IsEmptyDir(path, initArgs.TestsDirectory) - if err != nil { - diags = diags.Append(fmt.Errorf("Error checking configuration: %s", err)) - view.Diagnostics(diags) - return 1 - } - if empty { - view.Output(views.OutputInitEmptyMessage) - return 0 - } - - // Load just the root module to begin backend and module initialization - rootModEarly, earlyConfDiags := c.loadSingleModuleWithTests(path, initArgs.TestsDirectory) - - // There may be parsing errors in config loading but these will be shown later _after_ - // checking for core version requirement errors. Not meeting the version requirement should - // be the first error displayed if that is an issue, but other operations are required - // before being able to check core version requirements. - if rootModEarly == nil { - diags = diags.Append(errors.New(view.PrepareMessage(views.InitConfigError)), earlyConfDiags) - view.Diagnostics(diags) - - return 1 - } - - if initArgs.Get { - modsOutput, modsAbort, modsDiags := c.getModules(ctx, path, initArgs.TestsDirectory, rootModEarly, initArgs.Upgrade, view) - diags = diags.Append(modsDiags) - if modsAbort || modsDiags.HasErrors() { - view.Diagnostics(diags) - return 1 - } - if modsOutput { - header = true - } - } - - // With all of the modules (hopefully) installed, we can now try to load the - // whole configuration tree. - config, confDiags := c.loadConfigWithTests(path, initArgs.TestsDirectory) - // configDiags will be handled after: - // - the version constraint check has happened - // - and, the backend/state_store is initialised - - // Before we go further, we'll check to make sure none of the modules in - // the configuration declare that they don't support this Terraform - // version, so we can produce a version-related error message rather than - // potentially-confusing downstream errors. - versionDiags := terraform.CheckCoreVersionRequirements(config) - if versionDiags.HasErrors() { - view.Diagnostics(versionDiags) - return 1 - } - - // We've passed the core version check, now we can show errors from the early configuration. - // This prevents trying to initialise the backend with faulty configuration. - if earlyConfDiags.HasErrors() { - diags = diags.Append(errors.New(view.PrepareMessage(views.InitConfigError)), earlyConfDiags) - view.Diagnostics(diags) - return 1 - } - - // Now the full configuration is loaded, we can download the providers specified in the configuration. - // This is step one of a two-step provider download process - // Providers may be downloaded by this code, but the dependency lock file is only updated later in `init` - // after step two of provider download is complete. - previousLocks, moreDiags := c.lockedDependencies() - diags = diags.Append(moreDiags) - - configProvidersOutput, configLocks, configProviderDiags := c.getProvidersFromConfig(ctx, config, initArgs.Upgrade, initArgs.PluginPath, initArgs.Lockfile, view) - diags = diags.Append(configProviderDiags) - if configProviderDiags.HasErrors() { - view.Diagnostics(diags) - return 1 - } - if configProvidersOutput { - header = true - } - - // If we outputted information, then we need to output a newline - // so that our success message is nicely spaced out from prior text. - if header { - view.Output(views.EmptyMessage) - } - - var back backend.Backend - - var backDiags tfdiags.Diagnostics - var backendOutput bool - switch { - case initArgs.Cloud && rootModEarly.CloudConfig != nil: - back, backendOutput, backDiags = c.initCloud(ctx, rootModEarly, initArgs.BackendConfig, initArgs.ViewType, view) - case initArgs.Backend: - back, backendOutput, backDiags = c.initPssBackend(ctx, rootModEarly, initArgs, configLocks, view) - default: - // load the previously-stored backend config - back, backDiags = c.Meta.backendFromState(ctx) - } - if backendOutput { - header = true - } - if header { - // If we outputted information, then we need to output a newline - // so that our success message is nicely spaced out from prior text. - view.Output(views.EmptyMessage) - } - - // Show any errors from initializing the backend. - // No preamble using `InitConfigError` is present, as we expect - // any errors to from configuring the backend itself. - diags = diags.Append(backDiags) - if backDiags.HasErrors() { - view.Diagnostics(diags) - return 1 - } - - // If everything is ok with the core version check and backend/state_store initialization, - // show other errors from loading the full configuration tree. - diags = diags.Append(confDiags) - if confDiags.HasErrors() { - diags = diags.Append(errors.New(view.PrepareMessage(views.InitConfigError))) - view.Diagnostics(diags) - return 1 - } - - var state *states.State - - // If we have a functional backend (either just initialized or initialized - // on a previous run) we'll use the current state as a potential source - // of provider dependencies. - if back != nil { - c.ignoreRemoteVersionConflict(back) - workspace, err := c.Workspace() - if err != nil { - diags = diags.Append(fmt.Errorf("Error selecting workspace: %s", err)) - view.Diagnostics(diags) - return 1 - } - sMgr, sDiags := back.StateMgr(workspace) - if sDiags.HasErrors() { - diags = diags.Append(fmt.Errorf("Error loading state: %s", sDiags.Err())) - view.Diagnostics(diags) - return 1 - } - - if err := sMgr.RefreshState(); err != nil { - diags = diags.Append(fmt.Errorf("Error refreshing state: %s", err)) - view.Diagnostics(diags) - return 1 - } - - state = sMgr.State() - } - - // Now the resource state is loaded, we can download the providers specified in the state but not the configuration. - // This is step two of a two-step provider download process - stateProvidersOutput, stateLocks, stateProvidersDiags := c.getProvidersFromState(ctx, state, configLocks, initArgs.Upgrade, initArgs.PluginPath, initArgs.Lockfile, view) - diags = diags.Append(configProviderDiags) - if stateProvidersDiags.HasErrors() { - view.Diagnostics(diags) - return 1 - } - if stateProvidersOutput { - header = true - } - if header { - // If we outputted information, then we need to output a newline - // so that our success message is nicely spaced out from prior text. - view.Output(views.EmptyMessage) - } - - // Now the two steps of provider download have happened, update the dependency lock file if it has changed. - lockFileOutput, lockFileDiags := c.saveDependencyLockFile(previousLocks, configLocks, stateLocks, initArgs.Lockfile, view) - diags = diags.Append(lockFileDiags) - if lockFileDiags.HasErrors() { - view.Diagnostics(diags) - return 1 - } - if lockFileOutput { - header = true - } - if header { - // If we outputted information, then we need to output a newline - // so that our success message is nicely spaced out from prior text. - view.Output(views.EmptyMessage) - } - - if cb, ok := back.(*cloud.Cloud); ok { - if c.RunningInAutomation { - if err := cb.AssertImportCompatible(config); err != nil { - diags = diags.Append(tfdiags.Sourceless(tfdiags.Error, "Compatibility error", err.Error())) - view.Diagnostics(diags) - return 1 - } - } - } - - // If we accumulated any warnings along the way that weren't accompanied - // by errors then we'll output them here so that the success message is - // still the final thing shown. - view.Diagnostics(diags) - _, cloud := back.(*cloud.Cloud) - output := views.OutputInitSuccessMessage - if cloud { - output = views.OutputInitSuccessCloudMessage - } - - view.Output(output) - - if !c.RunningInAutomation { - // If we're not running in an automation wrapper, give the user - // some more detailed next steps that are appropriate for interactive - // shell usage. - output = views.OutputInitSuccessCLIMessage - if cloud { - output = views.OutputInitSuccessCLICloudMessage - } - view.Output(output) - } - return 0 -} - -func (c *InitCommand) initPssBackend(ctx context.Context, root *configs.Module, initArgs *arguments.Init, configLocks *depsfile.Locks, view views.Init) (be backend.Backend, output bool, diags tfdiags.Diagnostics) { - ctx, span := tracer.Start(ctx, "initialize backend") - _ = ctx // prevent staticcheck from complaining to avoid a maintenance hazard of having the wrong ctx in scope here - defer span.End() - - if root.StateStore != nil { - view.Output(views.InitializingStateStoreMessage) - } else { - view.Output(views.InitializingBackendMessage) - } - - var opts *BackendOpts - switch { - case root.StateStore != nil && root.Backend != nil: - // We expect validation during config parsing to prevent mutually exclusive backend and state_store blocks, - // but checking here just in case. - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Conflicting backend and state_store configurations present during init", - Detail: fmt.Sprintf("When initializing the backend there was configuration data present for both backend %q and state store %q. This is a bug in Terraform and should be reported.", - root.Backend.Type, - root.StateStore.Type, - ), - Subject: &root.Backend.TypeRange, - }) - return nil, true, diags - case root.StateStore != nil: - // state_store config present - factory, fDiags := c.Meta.StateStoreProviderFactoryFromConfig(root.StateStore, configLocks) - diags = diags.Append(fDiags) - if fDiags.HasErrors() { - return nil, true, diags - } - - // If overrides supplied by -backend-config CLI flag, process them - var configOverride hcl.Body - if !initArgs.BackendConfig.Empty() { - // We need to launch an instance of the provider to get the config of the state store for processing any overrides. - provider, err := factory() - defer provider.Close() // Stop the child process once we're done with it here. - if err != nil { - diags = diags.Append(fmt.Errorf("error when obtaining provider instance during state store initialization: %w", err)) - return nil, true, diags - } - - resp := provider.GetProviderSchema() - - if len(resp.StateStores) == 0 { - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Provider does not support pluggable state storage", - Detail: fmt.Sprintf("There are no state stores implemented by provider %s (%q)", - root.StateStore.Provider.Name, - root.StateStore.ProviderAddr), - Subject: &root.StateStore.DeclRange, - }) - return nil, true, diags - } - - stateStoreSchema, exists := resp.StateStores[root.StateStore.Type] - if !exists { - suggestions := slices.Sorted(maps.Keys(resp.StateStores)) - suggestion := didyoumean.NameSuggestion(root.StateStore.Type, suggestions) - if suggestion != "" { - suggestion = fmt.Sprintf(" Did you mean %q?", suggestion) - } - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "State store not implemented by the provider", - Detail: fmt.Sprintf("State store %q is not implemented by provider %s (%q)%s", - root.StateStore.Type, root.StateStore.Provider.Name, - root.StateStore.ProviderAddr, suggestion), - Subject: &root.StateStore.DeclRange, - }) - return nil, true, diags - } - - // Handle any overrides supplied via -backend-config CLI flags - var overrideDiags tfdiags.Diagnostics - configOverride, overrideDiags = c.backendConfigOverrideBody(initArgs.BackendConfig, stateStoreSchema.Body) - diags = diags.Append(overrideDiags) - if overrideDiags.HasErrors() { - return nil, true, diags - } - } - - opts = &BackendOpts{ - StateStoreConfig: root.StateStore, - Locks: configLocks, - CreateDefaultWorkspace: initArgs.CreateDefaultWorkspace, - ConfigOverride: configOverride, - Init: true, - ViewType: initArgs.ViewType, - } - - case root.Backend != nil: - // backend config present - backendType := root.Backend.Type - if backendType == "cloud" { - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Unsupported backend type", - Detail: fmt.Sprintf("There is no explicit backend type named %q. To configure HCP Terraform, declare a 'cloud' block instead.", backendType), - Subject: &root.Backend.TypeRange, - }) - return nil, true, diags - } - - bf := backendInit.Backend(backendType) - if bf == nil { - detail := fmt.Sprintf("There is no backend type named %q.", backendType) - if msg, removed := backendInit.RemovedBackends[backendType]; removed { - detail = msg - } - - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Unsupported backend type", - Detail: detail, - Subject: &root.Backend.TypeRange, - }) - return nil, true, diags - } - - b := bf() - backendSchema := b.ConfigSchema() - backendConfig := root.Backend - - // If overrides supplied by -backend-config CLI flag, process them - var configOverride hcl.Body - if !initArgs.BackendConfig.Empty() { - var overrideDiags tfdiags.Diagnostics - configOverride, overrideDiags = c.backendConfigOverrideBody(initArgs.BackendConfig, backendSchema) - diags = diags.Append(overrideDiags) - if overrideDiags.HasErrors() { - return nil, true, diags - } - } - - opts = &BackendOpts{ - BackendConfig: backendConfig, - Locks: configLocks, - ConfigOverride: configOverride, - Init: true, - ViewType: initArgs.ViewType, - } - - default: - // No config; defaults to local state storage - - // If the user supplied a -backend-config on the CLI but no backend - // block was found in the configuration, it's likely - but not - // necessarily - a mistake. Return a warning. - if !initArgs.BackendConfig.Empty() { - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Warning, - "Missing backend configuration", - `-backend-config was used without a "backend" block in the configuration. - -If you intended to override the default local backend configuration, -no action is required, but you may add an explicit backend block to your -configuration to clear this warning: - -terraform { - backend "local" {} -} - -However, if you intended to override a defined backend, please verify that -the backend configuration is present and valid. -`, - )) - } - - opts = &BackendOpts{ - Init: true, - Locks: configLocks, - ViewType: initArgs.ViewType, - } - } - - back, backDiags := c.Backend(opts) - diags = diags.Append(backDiags) - return back, true, diags -} diff --git a/internal/command/testdata/init-get/output.jsonlog b/internal/command/testdata/init-get/output.jsonlog index 88acf532fd..1fe0bb396e 100644 --- a/internal/command/testdata/init-get/output.jsonlog +++ b/internal/command/testdata/init-get/output.jsonlog @@ -1,7 +1,7 @@ {"@level":"info","@message":"Terraform 1.9.0-dev","@module":"terraform.ui","terraform":"1.9.0-dev","type":"version","ui":"1.2"} -{"@level":"info","@message":"Initializing the backend...","@module":"terraform.ui","message_code": "initializing_backend_message","type":"init_output"} {"@level":"info","@message":"Initializing modules...","@module":"terraform.ui","message_code": "initializing_modules_message","type":"init_output"} {"@level":"info","@message":"- foo in foo","@module":"terraform.ui","type":"log"} -{"@level":"info","@message":"Initializing provider plugins...","@module":"terraform.ui","message_code": "initializing_provider_plugin_message","type":"init_output"} +{"@level":"info","@message":"Initializing provider plugins found in the configuration...","@module":"terraform.ui","message_code": "initializing_provider_plugin_from_config_message","type":"init_output"} +{"@level":"info","@message":"Initializing the backend...","@module":"terraform.ui","message_code": "initializing_backend_message","type":"init_output"} {"@level":"info","@message":"Terraform has been successfully initialized!","@module":"terraform.ui","message_code": "output_init_success_message","type":"init_output"} {"@level":"info","@message":"You may now begin working with Terraform. Try running \"terraform plan\" to see\nany changes that are required for your infrastructure. All Terraform commands\nshould now work.\n\nIf you ever set or change modules or backend configuration for Terraform,\nrerun this command to reinitialize your working directory. If you forget, other\ncommands will detect it and remind you to do so if necessary.","@module":"terraform.ui","message_code": "output_init_success_cli_message","type":"init_output"} diff --git a/internal/command/views/init.go b/internal/command/views/init.go index f051425d48..1789c9b645 100644 --- a/internal/command/views/init.go +++ b/internal/command/views/init.go @@ -225,7 +225,7 @@ var MessageRegistry map[InitMessageCode]InitMessage = map[InitMessageCode]InitMe }, "reusing_version_during_state_provider_init": { HumanValue: "- Reusing previous version of %s", - JSONValue: "%s: Reusing previous version of %s", + JSONValue: "Reusing previous version of %s", }, "finding_matching_version_message": { HumanValue: "- Finding %s versions matching %q...", @@ -331,32 +331,27 @@ const ( // Following message codes are used and documented EXTERNALLY // Keep docs/internals/machine-readable-ui.mdx up to date with // this list when making changes here. - CopyingConfigurationMessage InitMessageCode = "copying_configuration_message" - EmptyMessage InitMessageCode = "empty_message" - OutputInitEmptyMessage InitMessageCode = "output_init_empty_message" - OutputInitSuccessMessage InitMessageCode = "output_init_success_message" - OutputInitSuccessCloudMessage InitMessageCode = "output_init_success_cloud_message" - OutputInitSuccessCLIMessage InitMessageCode = "output_init_success_cli_message" - OutputInitSuccessCLICloudMessage InitMessageCode = "output_init_success_cli_cloud_message" - UpgradingModulesMessage InitMessageCode = "upgrading_modules_message" - InitializingTerraformCloudMessage InitMessageCode = "initializing_terraform_cloud_message" - InitializingModulesMessage InitMessageCode = "initializing_modules_message" - InitializingBackendMessage InitMessageCode = "initializing_backend_message" - InitializingStateStoreMessage InitMessageCode = "initializing_state_store_message" - DefaultWorkspaceCreatedMessage InitMessageCode = "default_workspace_created_message" - InitializingProviderPluginMessage InitMessageCode = "initializing_provider_plugin_message" - LockInfo InitMessageCode = "lock_info" - DependenciesLockChangesInfo InitMessageCode = "dependencies_lock_changes_info" + CopyingConfigurationMessage InitMessageCode = "copying_configuration_message" + EmptyMessage InitMessageCode = "empty_message" + OutputInitEmptyMessage InitMessageCode = "output_init_empty_message" + OutputInitSuccessMessage InitMessageCode = "output_init_success_message" + OutputInitSuccessCloudMessage InitMessageCode = "output_init_success_cloud_message" + OutputInitSuccessCLIMessage InitMessageCode = "output_init_success_cli_message" + OutputInitSuccessCLICloudMessage InitMessageCode = "output_init_success_cli_cloud_message" + UpgradingModulesMessage InitMessageCode = "upgrading_modules_message" + InitializingTerraformCloudMessage InitMessageCode = "initializing_terraform_cloud_message" + InitializingModulesMessage InitMessageCode = "initializing_modules_message" + InitializingBackendMessage InitMessageCode = "initializing_backend_message" + InitializingStateStoreMessage InitMessageCode = "initializing_state_store_message" + InitializingProviderPluginFromConfigMessage InitMessageCode = "initializing_provider_plugin_from_config_message" + InitializingProviderPluginFromStateMessage InitMessageCode = "initializing_provider_plugin_from_state_message" + ReusingVersionIdentifiedFromConfig InitMessageCode = "reusing_version_during_state_provider_init" + DefaultWorkspaceCreatedMessage InitMessageCode = "default_workspace_created_message" + LockInfo InitMessageCode = "lock_info" + DependenciesLockChangesInfo InitMessageCode = "dependencies_lock_changes_info" //// Message codes below are ONLY used INTERNALLY (for now) - // InitializingProviderPluginFromConfigMessage indicates the beginning of installing of providers described in configuration - InitializingProviderPluginFromConfigMessage InitMessageCode = "initializing_provider_plugin_from_config_message" - // InitializingProviderPluginFromStateMessage indicates the beginning of installing of providers described in state - InitializingProviderPluginFromStateMessage InitMessageCode = "initializing_provider_plugin_from_state_message" - // DependenciesLockPendingChangesInfo indicates when a provider installation step will reuse a provider from a previous installation step in the current operation - ReusingVersionIdentifiedFromConfig InitMessageCode = "reusing_version_during_state_provider_init" - // InitConfigError indicates problems encountered during initialisation InitConfigError InitMessageCode = "init_config_error" // BackendConfiguredSuccessMessage indicates successful backend configuration diff --git a/internal/command/views/init_test.go b/internal/command/views/init_test.go index 4382564f8a..13847a5068 100644 --- a/internal/command/views/init_test.go +++ b/internal/command/views/init_test.go @@ -129,10 +129,10 @@ func TestNewInit_jsonViewOutput(t *testing.T) { t.Fatalf("unexpected return type %t", newInit) } - newInit.Output(InitializingProviderPluginMessage) + newInit.Output(InitializingProviderPluginFromConfigMessage) version := tfversion.String() - want := []map[string]interface{}{ + want := []map[string]any{ { "@level": "info", "@message": fmt.Sprintf("Terraform %s", version), @@ -143,8 +143,8 @@ func TestNewInit_jsonViewOutput(t *testing.T) { }, { "@level": "info", - "@message": "Initializing provider plugins...", - "message_code": "initializing_provider_plugin_message", + "@message": "Initializing provider plugins found in the configuration...", + "message_code": "initializing_provider_plugin_from_config_message", "@module": "terraform.ui", "type": "init_output", }, @@ -231,7 +231,7 @@ func TestNewInit_jsonViewLog(t *testing.T) { t.Fatalf("unexpected return type %t", newInit) } - newInit.LogInitMessage(InitializingProviderPluginMessage) + newInit.LogInitMessage(InitializingProviderPluginFromConfigMessage) version := tfversion.String() want := []map[string]interface{}{ @@ -245,7 +245,7 @@ func TestNewInit_jsonViewLog(t *testing.T) { }, { "@level": "info", - "@message": "Initializing provider plugins...", + "@message": "Initializing provider plugins found in the configuration...", "@module": "terraform.ui", "type": "log", }, @@ -282,10 +282,10 @@ func TestNewInit_humanViewOutput(t *testing.T) { t.Fatalf("unexpected return type %t", newInit) } - newInit.Output(InitializingProviderPluginMessage) + newInit.Output(InitializingProviderPluginFromConfigMessage) actual := done(t).All() - expected := "Initializing provider plugins..." + expected := "Initializing provider plugins found in the configuration..." if !strings.Contains(actual, expected) { t.Fatalf("expected output to contain: %s, but got %s", expected, actual) } From 7127c76b042e4bb0083d1401b38ef0d1c03866db Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 4 Mar 2026 10:09:21 +0000 Subject: [PATCH 07/24] command/views: Bump UI version to v1.3 (#38231) --- internal/command/query_test.go | 5 +++-- internal/command/views/json_view.go | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/command/query_test.go b/internal/command/query_test.go index 58359e940c..eee626c4b6 100644 --- a/internal/command/query_test.go +++ b/internal/command/query_test.go @@ -13,6 +13,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform/internal/command/views" "github.com/hashicorp/terraform/internal/configs/configschema" "github.com/hashicorp/terraform/internal/providers" testing_provider "github.com/hashicorp/terraform/internal/providers/testing" @@ -848,7 +849,7 @@ func TestQuery_JSON_Raw(t *testing.T) { { name: "basic query", directory: "basic", - expectedOut: `{"@level":"info","@message":"Terraform ` + tfVer + `","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.596469+02:00","terraform":"1.14.0-dev","type":"version","ui":"1.2"} + expectedOut: `{"@level":"info","@message":"Terraform ` + tfVer + `","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.596469+02:00","terraform":"1.14.0-dev","type":"version","ui":"` + views.JSON_UI_VERSION + `"} {"@level":"info","@message":"list.test_instance.example: Starting query...","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.600609+02:00","list_start":{"address":"list.test_instance.example","resource_type":"test_instance","input_config":{"ami":"ami-12345","foo":null}},"type":"list_start"} {"@level":"info","@message":"list.test_instance.example: Result found","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.600729+02:00","list_resource_found":{"address":"list.test_instance.example","display_name":"Test Instance 1","identity":{"id":"test-instance-1"},"identity_version":1,"resource_type":"test_instance","resource_object":{"ami":"ami-12345","id":"test-instance-1"}},"type":"list_resource_found"} {"@level":"info","@message":"list.test_instance.example: Result found","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.600759+02:00","list_resource_found":{"address":"list.test_instance.example","display_name":"Test Instance 2","identity":{"id":"test-instance-2"},"identity_version":1,"resource_type":"test_instance","resource_object":{"ami":"ami-67890","id":"test-instance-2"}},"type":"list_resource_found"} @@ -858,7 +859,7 @@ func TestQuery_JSON_Raw(t *testing.T) { { name: "empty result", directory: "empty-result", - expectedOut: `{"@level":"info","@message":"Terraform ` + tfVer + `","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.596469+02:00","terraform":"1.14.0-dev","type":"version","ui":"1.2"} + expectedOut: `{"@level":"info","@message":"Terraform ` + tfVer + `","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.596469+02:00","terraform":"1.14.0-dev","type":"version","ui":"` + views.JSON_UI_VERSION + `"} {"@level":"info","@message":"list.test_instance.example: Starting query...","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.600609+02:00","list_start":{"address":"list.test_instance.example","resource_type":"test_instance","input_config":{"ami":"ami-12345","foo":null}},"type":"list_start"} {"@level":"info","@message":"list.test_instance.example: Result found","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.600729+02:00","list_resource_found":{"address":"list.test_instance.example","display_name":"Test Instance 1","identity":{"id":"test-instance-1"},"identity_version":1,"resource_type":"test_instance","resource_object":{"ami":"ami-12345","id":"test-instance-1"}},"type":"list_resource_found"} {"@level":"info","@message":"list.test_instance.example: Result found","@module":"terraform.ui","@timestamp":"2025-09-12T16:52:57.600759+02:00","list_resource_found":{"address":"list.test_instance.example","display_name":"Test Instance 2","identity":{"id":"test-instance-2"},"identity_version":1,"resource_type":"test_instance","resource_object":{"ami":"ami-67890","id":"test-instance-2"}},"type":"list_resource_found"} diff --git a/internal/command/views/json_view.go b/internal/command/views/json_view.go index f7d1a2bba2..7bb878fc83 100644 --- a/internal/command/views/json_view.go +++ b/internal/command/views/json_view.go @@ -17,7 +17,7 @@ import ( // This version describes the schema of JSON UI messages. This version must be // updated after making any changes to this view, the jsonHook, or any of the // command/views/json package. -const JSON_UI_VERSION = "1.2" +const JSON_UI_VERSION = "1.3" func NewJSONView(view *View) *JSONView { log := hclog.New(&hclog.LoggerOptions{ From 28b76c110569789cbff77a0e3207929bad7daeb3 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 16:20:42 +0100 Subject: [PATCH 08/24] Introduce a new init graph The new init graph builder creates a small graph that can be used to install or load module configuration. It reuses different walkers to either install modules or validate the manifest during configuration loading. The new module install node dynamically expands the graph after module installation with a subgraph for the installed module. --- internal/terraform/config_graph_build.go | 42 ++ internal/terraform/context_init.go | 60 ++ internal/terraform/context_init_test.go | 712 ++++++++++++++++++ internal/terraform/graph_builder_init.go | 83 ++ internal/terraform/graph_walk_operation.go | 1 + internal/terraform/node_module_install.go | 392 ++++++++++ internal/terraform/node_module_variable.go | 31 +- internal/terraform/node_root_variable.go | 48 +- internal/terraform/transform_filter.go | 42 ++ internal/terraform/transform_filter_test.go | 386 ++++++++++ .../terraform/transform_module_install.go | 48 ++ .../terraform/transform_module_variable.go | 10 +- internal/terraform/walkoperation_string.go | 5 +- 13 files changed, 1840 insertions(+), 20 deletions(-) create mode 100644 internal/terraform/config_graph_build.go create mode 100644 internal/terraform/context_init.go create mode 100644 internal/terraform/context_init_test.go create mode 100644 internal/terraform/graph_builder_init.go create mode 100644 internal/terraform/node_module_install.go create mode 100644 internal/terraform/transform_filter.go create mode 100644 internal/terraform/transform_filter_test.go create mode 100644 internal/terraform/transform_module_install.go diff --git a/internal/terraform/config_graph_build.go b/internal/terraform/config_graph_build.go new file mode 100644 index 0000000000..e8451f238f --- /dev/null +++ b/internal/terraform/config_graph_build.go @@ -0,0 +1,42 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package terraform + +import ( + "github.com/hashicorp/terraform/internal/configs" + "github.com/hashicorp/terraform/internal/tfdiags" +) + +// BuildConfigWithGraph builds a configuration tree using the init graph so +// that module sources and versions can be resolved with full expression +// evaluation before loading descendant modules. +func BuildConfigWithGraph(rootMod *configs.Module, walker configs.ModuleWalker, vars InputValues, loader configs.MockDataLoader) (*configs.Config, tfdiags.Diagnostics) { + var diags tfdiags.Diagnostics + + ctx, ctxDiags := NewContext(&ContextOpts{ + Parallelism: 1, + }) + diags = diags.Append(ctxDiags) + if ctxDiags.HasErrors() { + return nil, diags + } + + cfg, initDiags := ctx.Init(rootMod, InitOpts{ + Walker: walker, + SetVariables: vars, + }) + diags = diags.Append(initDiags) + if diags.HasErrors() { + if cfg == nil && rootMod != nil { + cfg = &configs.Config{Module: rootMod} + cfg.Root = cfg + } + return cfg, diags + } + + finalDiags := configs.FinalizeConfig(cfg, walker, loader) + diags = diags.Append(finalDiags) + + return cfg, diags +} diff --git a/internal/terraform/context_init.go b/internal/terraform/context_init.go new file mode 100644 index 0000000000..e84a4b2f5e --- /dev/null +++ b/internal/terraform/context_init.go @@ -0,0 +1,60 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package terraform + +import ( + "github.com/hashicorp/terraform/internal/addrs" + "github.com/hashicorp/terraform/internal/configs" + "github.com/hashicorp/terraform/internal/tfdiags" +) + +type InitOpts struct { + Walker configs.ModuleWalker + + // SetVariables are the raw values for root module variables as provided + // by the user who is requesting the run, prior to any normalization or + // substitution of defaults. See the documentation for the InputValue + // type for more information on how to correctly populate this. + SetVariables InputValues +} + +func (c *Context) Init(rootMod *configs.Module, initOpts InitOpts) (*configs.Config, tfdiags.Diagnostics) { + return c.init(rootMod, initOpts) +} + +func (c *Context) init(rootMod *configs.Module, initOpts InitOpts) (*configs.Config, tfdiags.Diagnostics) { + defer c.acquireRun("init")() + var diags tfdiags.Diagnostics + + config := &configs.Config{ + Module: rootMod, + Path: addrs.RootModule, + Children: map[string]*configs.Config{}, + } + config.Root = config + + graph, moreDiags := c.initGraph(config, initOpts) + diags = diags.Append(moreDiags) + if diags.HasErrors() { + return nil, diags + } + + walker, walkDiags := c.walk(graph, walkInit, &graphWalkOpts{ + Config: config, + }) + diags = diags.Append(walker.NonFatalDiagnostics) + diags = diags.Append(walkDiags) + + return config, diags +} + +func (c *Context) initGraph(config *configs.Config, initOpts InitOpts) (*Graph, tfdiags.Diagnostics) { + graph, diags := (&InitGraphBuilder{ + Config: config, + RootVariableValues: initOpts.SetVariables, + Walker: initOpts.Walker, + }).Build(addrs.RootModuleInstance) + + return graph, diags +} diff --git a/internal/terraform/context_init_test.go b/internal/terraform/context_init_test.go new file mode 100644 index 0000000000..c9f7f59fd7 --- /dev/null +++ b/internal/terraform/context_init_test.go @@ -0,0 +1,712 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package terraform + +import ( + "path/filepath" + "strings" + "testing" + + version "github.com/hashicorp/go-version" + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/terraform/internal/addrs" + "github.com/hashicorp/terraform/internal/configs" + "github.com/hashicorp/terraform/internal/getmodules/moduleaddrs" + "github.com/hashicorp/terraform/internal/tfdiags" + "github.com/zclconf/go-cty/cty" +) + +var _ configs.ModuleWalker = (*MockModuleWalker)(nil) + +type MockModuleWalker struct { + Calls []*configs.ModuleRequest + DefaultModule *configs.Module + // the string key refers to ModuleSource.String() + MockedCalls map[string]*configs.Module +} + +func (m *MockModuleWalker) LoadModule(req *configs.ModuleRequest) (*configs.Module, *version.Version, hcl.Diagnostics) { + m.Calls = append(m.Calls, req) + + if mod, ok := m.MockedCalls[req.SourceAddr.String()]; ok { + return mod, nil, nil + } + + return m.DefaultModule, nil, nil +} + +func (m *MockModuleWalker) MockModuleCalls(t *testing.T, calls map[string]*configs.Module) { + t.Helper() + if m.MockedCalls == nil { + m.MockedCalls = make(map[string]*configs.Module) + } + for k, v := range calls { + // Make sure we can parse the module source + ms := mustModuleSource(t, k) + m.MockedCalls[ms.String()] = v + } +} + +func TestInit(t *testing.T) { + for name, tc := range map[string]struct { + module map[string]string + vars InputValues + mockedLoadModuleCalls map[string]map[string]string + // m -> root module + // mc -> module calls + expectDiags func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics + expectLoadModuleCalls []*configs.ModuleRequest + }{ + "empty config": { + module: map[string]string{"main.tf": ``}, + }, + "local - no variables": { + module: map[string]string{ + "main.tf": ` +module "example" { + source = "./modules/example" +} +`, + }, + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "./modules/example"), + }}, + }, + + "remote - no variables": { + module: map[string]string{ + "main.tf": ` +module "example" { + source = "terraform-aws-modules/vpc/aws" + version = "6.6.0" +} + +module "example2" { + source = "terraform-iaac/cert-manager/kubernetes" +} + `, + }, + + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "terraform-iaac/cert-manager/kubernetes"), + }, { + SourceAddr: mustModuleSource(t, "terraform-aws-modules/vpc/aws"), + VersionConstraint: mustVersionContraint(t, "= 6.6.0"), + }}, + }, + + "local - with variables": { + module: map[string]string{ + "main.tf": ` +variable "name" { + type = string + const = true +} +module "example" { + source = "./modules/${var.name}" +} +`, + }, + vars: InputValues{ + "name": &InputValue{Value: cty.StringVal("example"), SourceType: ValueFromCLIArg}, + }, + + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "./modules/example"), + }}, + }, + + "local with non-static variables": { + module: map[string]string{ + "main.tf": ` +variable "name" { + type = string +} +module "example" { + source = "./modules/${var.name}" +} +`, + }, + vars: InputValues{ + "name": &InputValue{Value: cty.StringVal("example"), SourceType: ValueFromCLIArg}, + }, + + expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { + // TODO: We should try to somehow add an "extra" into the diagnostics to indicate + // that this may be caused by a non-static variable used during init. + return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: `Invalid module source`, + Detail: `The value of a reference in the module source is unknown.`, + Subject: &hcl.Range{ + Filename: filepath.Join(m.SourceDir, "main.tf"), + Start: hcl.Pos{Line: 6, Column: 27, Byte: 82}, + End: hcl.Pos{Line: 6, Column: 35, Byte: 90}, + }, + }) + }, + }, + + "remote - with variable in source": { + module: map[string]string{ + "main.tf": ` +variable "name" { + type = string + const = true +} +module "example2" { + source = "terraform-iaac/${var.name}/kubernetes" +} +`, + }, + vars: InputValues{ + "name": &InputValue{Value: cty.StringVal("cert-manager"), SourceType: ValueFromCLIArg}, + }, + + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "terraform-iaac/cert-manager/kubernetes"), + }}, + }, + "remote - with variable in constraint": { + module: map[string]string{ + "main.tf": ` +variable "name" { + type = string + const = true +} +module "example2" { + source = "terraform-iaac/cert-manager/kubernetes" + version = ">= ${var.name}" +} +`, + }, + vars: InputValues{ + "name": &InputValue{Value: cty.StringVal("1.2.3"), SourceType: ValueFromCLIArg}, + }, + + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "terraform-iaac/cert-manager/kubernetes"), + VersionConstraint: mustVersionContraint(t, ">= 1.2.3"), + }}, + }, + + "locals in module sources": { + module: map[string]string{ + "main.tf": ` +variable "name" { + type = string + const = true +} + +locals { + org_and_repo = "terraform-iaac/${var.name}" +} + +module "example2" { + source = "${local.org_and_repo}/kubernetes" +} +`, + }, + vars: InputValues{ + "name": &InputValue{Value: cty.StringVal("cert-manager"), SourceType: ValueFromCLIArg}, + }, + + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "terraform-iaac/cert-manager/kubernetes"), + VersionConstraint: mustVersionContraint(t, ">= 1.2.3"), + }}, + }, + + "each in module sources": { + module: map[string]string{ + "main.tf": ` +module "example" { + for_each = toset(["cert-manager", "helm"]) + source = "terraform-iaac/${each.key}/kubernetes" +} +`, + }, + vars: InputValues{ + "name": &InputValue{Value: cty.StringVal("cert-manager"), SourceType: ValueFromCLIArg}, + }, + + expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { + return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: `Invalid module source`, + Detail: `The module source can only reference input variables and local values.`, + Subject: &hcl.Range{ + Filename: filepath.Join(m.SourceDir, "main.tf"), + Start: hcl.Pos{Line: 4, Column: 31, Byte: 95}, + End: hcl.Pos{Line: 4, Column: 39, Byte: 103}, + }, + }) + }, + }, + + "module variables in source": { + module: map[string]string{ + "main.tf": ` +module "mod" { + source = "./mod" + name = "cert-manager" +} +`, + }, + vars: InputValues{ + "name": &InputValue{Value: cty.StringVal("cert-manager"), SourceType: ValueFromCLIArg}, + }, + mockedLoadModuleCalls: map[string]map[string]string{ + "./mod": { + "main.tf": ` +variable "name" { + type = string + const = true +} +module "example" { + source = "terraform-iaac/${var.name}/kubernetes" +} + `, + }, + }, + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "./mod"), + }, { + SourceAddr: mustModuleSource(t, "terraform-iaac/cert-manager/kubernetes"), + }}, + }, + + "undefined variable in module source": { + module: map[string]string{ + "main.tf": ` +variable "name" { + type = string + const = true +} +module "example2" { + source = "terraform-iaac/${var.name}/kubernetes" +} +`, + }, + expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { + return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Required variable not set", + Detail: `The variable "name" is required, but is not set.`, + Subject: &hcl.Range{ + Filename: filepath.Join(m.SourceDir, "main.tf"), + Start: hcl.Pos{Line: 2, Column: 1, Byte: 1}, + End: hcl.Pos{Line: 2, Column: 16, Byte: 16}, + }, + }) + }, + }, + + "resource reference in module source": { + module: map[string]string{ + "main.tf": ` +resource "null_resource" "example" {} + +module "example" { + source = "terraform-iaac/${null_resource.example.id}/kubernetes" +} +`, + }, + expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { + return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source", + Detail: "The module source can only reference input variables and local values.", + Subject: &hcl.Range{ + Filename: filepath.Join(m.SourceDir, "main.tf"), + Start: hcl.Pos{Line: 5, Column: 33, Byte: 91}, + End: hcl.Pos{Line: 5, Column: 54, Byte: 112}, + }, + }) + }, + }, + "resource reference in module call": { + module: map[string]string{ + "main.tf": ` +variable "name" { + type = string + default = "aws" + const = true +} +resource "null_resource" "example" {} + +module "example" { + source = "./${var.name}" + + name = var.name + this_should_be_unknown_and_not_cause_error = null_resource.example.id +} +`, + }, + mockedLoadModuleCalls: map[string]map[string]string{ + "./aws": { + "main.tf": ` +variable "name" { + type = string + const = true +} + +variable "this_should_be_unknown_and_not_cause_error" { + type = string +} + +module "example" { + source = "terraform-iaac/${var.name}/kubernetes" +} + + +output "foo" { + value = var.this_should_be_unknown_and_not_cause_error +} + `, + }, + }, + + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "terraform-iaac/aws/kubernetes"), + }, { + SourceAddr: mustModuleSource(t, "./aws"), + }}, + }, + + "module output reference in module source": { + module: map[string]string{ + "main.tf": ` +module "example" { + source = "./module/example" +} + +module "example2" { + source = "terraform-iaac/${module.example.id}/kubernetes" +} + `, + }, + mockedLoadModuleCalls: map[string]map[string]string{ + "./module/example": { + "main.tf": ` +output "id" { + value = "example-id" +} + `, + }}, + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "./module/example"), + }}, + expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { + return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source", + Detail: "The module source can only reference input variables and local values.", + Subject: &hcl.Range{ + Filename: filepath.Join(m.SourceDir, "main.tf"), + Start: hcl.Pos{Line: 7, Column: 33, Byte: 107}, + End: hcl.Pos{Line: 7, Column: 50, Byte: 124}, + }, + }) + }, + }, + + "nested module loading - no variables": { + module: map[string]string{ + "main.tf": ` +module "parent" { + source = "hashicorp/parent/aws" +} +`, + }, + mockedLoadModuleCalls: map[string]map[string]string{ + "hashicorp/parent/aws": { + "main.tf": ` +module "child" { + source = "hashicorp/child/aws" +} + `, + }, + }, + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "hashicorp/parent/aws"), + }, { + SourceAddr: mustModuleSource(t, "hashicorp/child/aws"), + }}, + }, + + "nested module loading - with variables": { + module: map[string]string{ + "main.tf": ` +module "parent" { + source = "hashicorp/parent/aws" + name = "child" +} +`, + }, + mockedLoadModuleCalls: map[string]map[string]string{ + "hashicorp/parent/aws": { + "main.tf": ` +variable "name" { + type = string + const = true +} +module "child" { + source = "hashicorp/${var.name}/aws" + name = "grand${var.name}" +} + `, + }, + "hashicorp/child/aws": { + "main.tf": ` +variable "name" { + type = string + const = true +} +module "grandchild" { + source = "hashicorp/${var.name}/aws" +} + `, + }, + }, + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "hashicorp/parent/aws"), + }, { + SourceAddr: mustModuleSource(t, "hashicorp/child/aws"), + }, { + SourceAddr: mustModuleSource(t, "hashicorp/grandchild/aws"), + }}, + }, + "module nested expansion": { + module: map[string]string{ + "main.tf": ` +module "fromdisk" { + source = "./mod" + namespace = "terraform-iaac" +} +`, + }, + mockedLoadModuleCalls: map[string]map[string]string{ + "./mod": { + "main.tf": ` +locals { + source = var.namespace +} +variable "namespace" { + type = string + const = true +} +module "terraform" { + source = "${var.namespace}/helm/kubernetes" +} +output "name" { + value = "fooo" +} +`, + }, + }, + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "./mod"), + }, { + SourceAddr: mustModuleSource(t, "terraform-iaac/helm/kubernetes"), + }}, + }, + + "static variable with no value and no default": { + module: map[string]string{"main.tf": ` +variable "name" { + type = string + const = true +} +module "example" { + source = "./modules/${var.name}" +} +`, + }, + expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { + return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: `Required variable not set`, + Detail: `The variable "name" is required, but is not set.`, + Subject: &hcl.Range{ + Filename: filepath.Join(m.SourceDir, "main.tf"), + Start: hcl.Pos{Line: 2, Column: 1, Byte: 1}, + End: hcl.Pos{Line: 2, Column: 16, Byte: 16}, + }, + }) + }, + }, + + "static variable with default": { + module: map[string]string{"main.tf": ` +variable "name" { + type = string + const = true + default = "example" +} +module "example" { + source = "./modules/${var.name}" +} +`, + }, + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "./modules/example"), + }}, + }, + + "non-static variable passed into static module variable": { + module: map[string]string{"main.tf": ` +variable "name" { + type = string + default = "example" +} +module "example" { + source = "./modules/example" + name = "./modules/${var.name}2" +} +`, + }, + mockedLoadModuleCalls: map[string]map[string]string{ + "./modules/example": { + "main.tf": ` +variable "name" { + type = string + const = true +} + `, + }, + }, + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "./modules/example"), + }}, + expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { + return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: `Static variables must be known`, + Detail: `Only a static value can be passed into a static module variable.`, + Subject: &hcl.Range{ + Filename: filepath.Join(m.SourceDir, "main.tf"), + Start: hcl.Pos{Line: 8, Column: 10, Byte: 118}, + End: hcl.Pos{Line: 8, Column: 34, Byte: 142}, + }, + }) + }, + }, + + "non-static module variable used as static": { + module: map[string]string{"main.tf": ` +module "example" { + source = "./modules/example" + + name = "foo" +} +`, + }, + mockedLoadModuleCalls: map[string]map[string]string{ + "./modules/example": { + "main.tf": ` +variable "name" { + type = string +} + +module "nested" { + source = "./modules/${var.name}" +} + `, + }, + }, + expectLoadModuleCalls: []*configs.ModuleRequest{{ + SourceAddr: mustModuleSource(t, "./modules/example"), + }}, + expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { + // TODO: We should try to somehow add an "extra" into the diagnostics to indicate + // that this may be caused by a non-static variable used during init. + return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: `Invalid module source`, + Detail: `The value of a reference in the module source is unknown.`, + Subject: &hcl.Range{ + Filename: filepath.Join(mc["./modules/example"].SourceDir, "main.tf"), + Start: hcl.Pos{Line: 7, Column: 27, Byte: 82}, + End: hcl.Pos{Line: 7, Column: 35, Byte: 90}, + }, + }) + }, + }, + } { + t.Run(name, func(t *testing.T) { + m := testRootModuleInline(t, tc.module) + + ctx := testContext2(t, &ContextOpts{ + Parallelism: 1, + }) + moduleWalker := MockModuleWalker{ + DefaultModule: testRootModuleInline(t, map[string]string{"main.tf": `// empty`}), + } + mockedModules := make(map[string]*configs.Module) + if tc.mockedLoadModuleCalls != nil { + for k, v := range tc.mockedLoadModuleCalls { + mockedModules[k] = testRootModuleInline(t, v) + } + moduleWalker.MockModuleCalls(t, mockedModules) + } + _, diags := ctx.Init(m, InitOpts{ + SetVariables: tc.vars, + Walker: &moduleWalker, + }) + if tc.expectDiags != nil { + tfdiags.AssertDiagnosticsMatch(t, diags, tc.expectDiags(m, mockedModules)) + } else { + tfdiags.AssertNoDiagnostics(t, diags) + } + + if len(moduleWalker.Calls) != len(tc.expectLoadModuleCalls) { + t.Fatalf("expected %d LoadModule calls, got %d", len(tc.expectLoadModuleCalls), len(moduleWalker.Calls)) + } + + // Create a map of expected sources for easier comparison + expectedSources := make(map[string]bool) + foundSources := []string{} + for _, expected := range tc.expectLoadModuleCalls { + expectedSources[expected.SourceAddr.String()] = false + } + + // Mark sources as found + for _, call := range moduleWalker.Calls { + source := call.SourceAddr.String() + foundSources = append(foundSources, source) + if _, exists := expectedSources[source]; !exists { + t.Errorf("unexpected LoadModule call for source %q", source) + } else { + expectedSources[source] = true + } + } + + // Check all expected sources were called + for source, found := range expectedSources { + if !found { + t.Errorf("expected LoadModule call for source %q but it was not called. Calls that were made: \n %s", source, strings.Join(foundSources, ", ")) + } + } + }) + } +} + +func mustModuleSource(t *testing.T, rawStr string) addrs.ModuleSource { + src, err := moduleaddrs.ParseModuleSource(rawStr) + if err != nil { + t.Fatalf("failed to parse module source %q: %s", rawStr, err) + } + return src +} + +func mustVersionContraint(t *testing.T, rawStr string) configs.VersionConstraint { + constraints, err := version.NewConstraint(rawStr) + if err != nil { + t.Fatalf("failed to parse version constraint %q: %s", rawStr, err) + } + return configs.VersionConstraint{ + Required: constraints, + } +} diff --git a/internal/terraform/graph_builder_init.go b/internal/terraform/graph_builder_init.go new file mode 100644 index 0000000000..da985bae72 --- /dev/null +++ b/internal/terraform/graph_builder_init.go @@ -0,0 +1,83 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package terraform + +import ( + "log" + + "github.com/hashicorp/terraform/internal/addrs" + "github.com/hashicorp/terraform/internal/configs" + "github.com/hashicorp/terraform/internal/dag" + "github.com/hashicorp/terraform/internal/tfdiags" +) + +type InitGraphBuilder struct { + // A config derived from the root module + Config *configs.Config + + RootVariableValues InputValues + + Walker configs.ModuleWalker +} + +// See GraphBuilder +func (b *InitGraphBuilder) Build(path addrs.ModuleInstance) (*Graph, tfdiags.Diagnostics) { + log.Printf("[TRACE] building graph for terraform dependencies") + return (&BasicGraphBuilder{ + Steps: b.Steps(), + Name: "InitGraphBuilder", + }).Build(path) +} + +// See GraphBuilder +func (b *InitGraphBuilder) Steps() []GraphTransformer { + steps := []GraphTransformer{} + + if b.Config.Parent == nil { + steps = append(steps, &RootVariableTransformer{ + Config: b.Config, + RawValues: b.RootVariableValues, + }) + } else { + steps = append(steps, &ModuleVariableTransformer{ + Config: b.Config, + ModuleOnly: true, + }) + } + + steps = append(steps, []GraphTransformer{ + &ModuleTransformer{ + Config: b.Config, + Walker: b.Walker, + }, + + &LocalTransformer{ + Config: b.Config, + }, + + &ReferenceTransformer{}, + + // Filters out any vertices that aren't relevant to the init graph + &TransformFilter{ + Keep: func(v dag.Vertex) bool { + switch n := v.(type) { + case *nodeInstallModule: + return true + case *NodeRootVariable: + return n.Config.Const + case *nodeExpandModuleVariable: + return n.Config.Const + default: + return false + } + }, + }, + + &RootTransformer{}, + + &TransitiveReductionTransformer{}, + }...) + + return steps +} diff --git a/internal/terraform/graph_walk_operation.go b/internal/terraform/graph_walk_operation.go index a408f78465..fcfc23bfae 100644 --- a/internal/terraform/graph_walk_operation.go +++ b/internal/terraform/graph_walk_operation.go @@ -17,4 +17,5 @@ const ( walkDestroy walkImport walkEval // used just to prepare EvalContext for expression evaluation, with no other actions + walkInit ) diff --git a/internal/terraform/node_module_install.go b/internal/terraform/node_module_install.go new file mode 100644 index 0000000000..9692c8cb56 --- /dev/null +++ b/internal/terraform/node_module_install.go @@ -0,0 +1,392 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package terraform + +import ( + "fmt" + + "github.com/hashicorp/go-version" + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/hclsyntax" + "github.com/zclconf/go-cty/cty" + + "github.com/hashicorp/terraform/internal/addrs" + "github.com/hashicorp/terraform/internal/configs" + "github.com/hashicorp/terraform/internal/getmodules/moduleaddrs" + "github.com/hashicorp/terraform/internal/lang/langrefs" + "github.com/hashicorp/terraform/internal/tfdiags" +) + +type nodeInstallModule struct { + // We're using a ModuleInstance here, + // because the downstream graph builder requires it. + // But it was constructed with addrs.NoKey + Addr addrs.ModuleInstance + ModuleCall *configs.ModuleCall + Parent *configs.Config + Walker configs.ModuleWalker + + // Stores the configuration of the installed module + Config *configs.Config + // Stores the version of the installed module + Version *version.Version +} + +var ( + _ GraphNodeExecutable = (*nodeInstallModule)(nil) + _ GraphNodeReferencer = (*nodeInstallModule)(nil) + _ GraphNodeDynamicExpandable = (*nodeInstallModule)(nil) + _ GraphNodeModuleInstance = (*nodeInstallModule)(nil) +) + +func (n *nodeInstallModule) Path() addrs.ModuleInstance { + return n.Addr.Parent() +} + +func (n *nodeInstallModule) Name() string { + return n.Addr.String() +} + +func (n *nodeInstallModule) ModulePath() addrs.Module { + return n.Addr.Module().Parent() +} + +func (n *nodeInstallModule) References() []*addrs.Reference { + var refs []*addrs.Reference + + sourceRefs, _ := langrefs.ReferencesInExpr(addrs.ParseRef, n.ModuleCall.SourceExpr) + refs = append(refs, sourceRefs...) + versionRefs, _ := langrefs.ReferencesInExpr(addrs.ParseRef, n.ModuleCall.VersionExpr) + refs = append(refs, versionRefs...) + + // We need to resolve all module inputs as well, because some might be used + // in the module as a constant variable to build a nested module source + attrs, _ := n.ModuleCall.Config.JustAttributes() + for _, attr := range attrs { + inputRefs, _ := langrefs.ReferencesInExpr(addrs.ParseRef, attr.Expr) + refs = append(refs, inputRefs...) + } + + return refs +} + +func (n *nodeInstallModule) Execute(ctx EvalContext, walkOp walkOperation) tfdiags.Diagnostics { + var diags tfdiags.Diagnostics + + var version configs.VersionConstraint + if n.ModuleCall.VersionExpr != nil { + var versionDiags tfdiags.Diagnostics + version, versionDiags = decodeVersionConstraint(n.ModuleCall.VersionExpr, ctx) + diags = diags.Append(versionDiags) + if diags.HasErrors() { + return diags + } + } + + hasVersion := n.ModuleCall.VersionExpr != nil + source, sourceDiags := decodeSource(n.ModuleCall.SourceExpr, hasVersion, ctx) + diags = diags.Append(sourceDiags) + if diags.HasErrors() { + return diags + } + + req := &configs.ModuleRequest{ + Name: n.ModuleCall.Name, + Path: n.Addr.Module(), + SourceAddr: source, + SourceAddrRange: n.ModuleCall.SourceExpr.Range(), + VersionConstraint: version, + Parent: n.Parent, + CallRange: n.ModuleCall.DeclRange, + } + + cfg, v, modDiags := n.Walker.LoadModule(req) + diags = diags.Append(modDiags) + if diags.HasErrors() { + return diags + } + + config := &configs.Config{ + Module: cfg, + Parent: n.Parent, + Path: n.Addr.Module(), + Root: n.Parent.Root, + Children: map[string]*configs.Config{}, + CallRange: n.ModuleCall.DeclRange, + SourceAddr: source, + SourceAddrRange: n.ModuleCall.SourceExpr.Range(), + Version: v, + VersionConstraint: version, + } + + // Insert the installed module into the children of the current module + currentModuleKey := n.Addr[len(n.Addr)-1].Name + n.Parent.Children[currentModuleKey] = config + + n.Config = config + n.Version = v + + return nil +} + +func (n *nodeInstallModule) DynamicExpand(ctx EvalContext) (*Graph, tfdiags.Diagnostics) { + var g Graph + var diags tfdiags.Diagnostics + + expander := ctx.InstanceExpander() + _, call := n.Addr.Call() + expander.SetModuleSingle(n.Path(), call) + + graph, graphDiags := (&InitGraphBuilder{ + Config: n.Config, + Walker: n.Walker, + }).Build(n.Addr) + diags = diags.Append(graphDiags) + if graphDiags.HasErrors() { + return nil, diags + } + g.Subsume(&graph.AcyclicGraph.Graph) + + addRootNodeToGraph(&g) + + return &g, nil +} + +func decodeSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) (addrs.ModuleSource, tfdiags.Diagnostics) { + var diags tfdiags.Diagnostics + var addr addrs.ModuleSource + var err error + + refs, refsDiags := langrefs.ReferencesInExpr(addrs.ParseRef, sourceExpr) + diags = diags.Append(refsDiags) + if diags.HasErrors() { + return nil, diags + } + + for _, ref := range refs { + switch ref.Subject.(type) { + case addrs.InputVariable, addrs.LocalValue: + // These are allowed + default: + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source", + Detail: "The module source can only reference input variables and local values.", + Subject: ref.SourceRange.ToHCL().Ptr(), + }) + return nil, diags + } + } + + value, valueDiags := ctx.EvaluateExpr(sourceExpr, cty.String, nil) + diags = diags.Append(valueDiags) + if diags.HasErrors() { + return nil, diags + } + + if !value.IsWhollyKnown() { + tExpr, ok := sourceExpr.(*hclsyntax.TemplateExpr) + if !ok { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source", + Detail: "The module source contains a reference that is unknown during init.", + Subject: sourceExpr.Range().Ptr(), + }) + return nil, diags + } + for _, part := range tExpr.Parts { + partVal, partDiags := ctx.EvaluateExpr(part, cty.DynamicPseudoType, nil) + diags = diags.Append(partDiags) + if diags.HasErrors() { + return nil, diags + } + + scope := ctx.EvaluationScope(nil, nil, EvalDataForNoInstanceKey) + hclCtx, evalDiags := scope.EvalContext(refs) + diags = diags.Append(evalDiags) + if diags.HasErrors() { + return nil, diags + } + if !partVal.IsKnown() { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source", + Detail: "The value of a reference in the module source is unknown.", + Subject: part.Range().Ptr(), + Expression: part, + EvalContext: hclCtx, + Extra: diagnosticCausedByUnknown(true), + }) + return nil, diags + } + } + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source", + Detail: "The module source contains a reference that is unknown.", + Subject: sourceExpr.Range().Ptr(), + }) + return nil, diags + } + + if hasVersion { + addr, err = moduleaddrs.ParseModuleSourceRegistry(value.AsString()) + } else { + addr, err = moduleaddrs.ParseModuleSource(value.AsString()) + } + if err != nil { + // NOTE: We leave add as nil for any situation where the + // source attribute is invalid, so any code which tries to carefully + // use the partial result of a failed config decode must be + // resilient to that. + addr = nil + + // NOTE: In practice it's actually very unlikely to end up here, + // because our source address parser can turn just about any string + // into some sort of remote package address, and so for most errors + // we'll detect them only during module installation. There are + // still a _few_ purely-syntax errors we can catch at parsing time, + // though, mostly related to remote package sub-paths and local + // paths. + switch err := err.(type) { + case *moduleaddrs.MaybeRelativePathErr: + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source address", + Detail: fmt.Sprintf( + "Terraform failed to determine your intended installation method for remote module package %q.\n\nIf you intended this as a path relative to the current module, use \"./%s\" instead. The \"./\" prefix indicates that the address is a relative filesystem path.", + err.Addr, err.Addr, + ), + Subject: sourceExpr.Range().Ptr(), + }) + default: + if hasVersion { + // In this case we'll include some extra context that + // we assumed a registry source address due to the + // version argument. + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid registry module source address", + Detail: fmt.Sprintf("Failed to parse module registry address: %s.\n\nTerraform assumed that you intended a module registry source address because you also set the argument \"version\", which applies only to registry modules.", err), + Subject: sourceExpr.Range().Ptr(), + }) + } else { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source address", + Detail: fmt.Sprintf("Failed to parse module source address: %s.", err), + Subject: sourceExpr.Range().Ptr(), + }) + } + } + } + + return addr, diags +} + +func decodeVersionConstraint(versionExpr hcl.Expression, ctx EvalContext) (configs.VersionConstraint, tfdiags.Diagnostics) { + var diags tfdiags.Diagnostics + rng := versionExpr.Range() + + ret := configs.VersionConstraint{ + DeclRange: rng, + } + + refs, refsDiags := langrefs.ReferencesInExpr(addrs.ParseRef, versionExpr) + diags = diags.Append(refsDiags) + if diags.HasErrors() { + return ret, diags + } + + for _, ref := range refs { + switch ref.Subject.(type) { + case addrs.InputVariable, addrs.LocalValue: + // These are allowed + default: + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module version", + Detail: "The module version can only reference input variables and local values.", + Subject: ref.SourceRange.ToHCL().Ptr(), + }) + return ret, diags + } + } + + value, valueDiags := ctx.EvaluateExpr(versionExpr, cty.String, nil) + diags = diags.Append(valueDiags) + if diags.HasErrors() { + return ret, diags + } + + if value.IsNull() { + // A null version constraint is strange, but we'll just treat it + // like an empty constraint set. + return ret, diags + } + + if !value.IsWhollyKnown() { + tExpr, ok := versionExpr.(*hclsyntax.TemplateExpr) + if !ok { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module version", + Detail: "The module version contains a reference that is unknown during init.", + Subject: versionExpr.Range().Ptr(), + }) + return ret, diags + } + for _, part := range tExpr.Parts { + partVal, partDiags := ctx.EvaluateExpr(part, cty.DynamicPseudoType, nil) + diags = diags.Append(partDiags) + if diags.HasErrors() { + return ret, diags + } + + scope := ctx.EvaluationScope(nil, nil, EvalDataForNoInstanceKey) + hclCtx, evalDiags := scope.EvalContext(refs) + diags = diags.Append(evalDiags) + if diags.HasErrors() { + return ret, diags + } + if !partVal.IsKnown() { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module version", + Detail: "The value of a reference in the module version is unknown.", + Subject: part.Range().Ptr(), + Expression: part, + EvalContext: hclCtx, + Extra: diagnosticCausedByUnknown(true), + }) + return ret, diags + } + } + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module version", + Detail: "The module version contains a reference that is unknown.", + Subject: versionExpr.Range().Ptr(), + }) + return ret, diags + } + + constraintStr := value.AsString() + constraints, err := version.NewConstraint(constraintStr) + if err != nil { + // NewConstraint doesn't return user-friendly errors, so we'll just + // ignore the provided error and produce our own generic one. + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid version constraint", + Detail: "This string does not use correct version constraint syntax.", // Not very actionable :( + Subject: rng.Ptr(), + }) + return ret, diags + } + + ret.Required = constraints + return ret, diags +} diff --git a/internal/terraform/node_module_variable.go b/internal/terraform/node_module_variable.go index a458af0990..7672906851 100644 --- a/internal/terraform/node_module_variable.go +++ b/internal/terraform/node_module_variable.go @@ -217,14 +217,26 @@ func (n *nodeModuleVariable) Execute(ctx EvalContext, op walkOperation) (diags t log.Printf("[TRACE] nodeModuleVariable: evaluating %s", n.Addr) var val cty.Value + var errSourceRange tfdiags.SourceRange var err error switch op { case walkValidate: - val, err = n.evalModuleVariable(ctx, true) + val, errSourceRange, err = n.evalModuleVariable(ctx, true) diags = diags.Append(err) + case walkInit: + // During init we only want to record the value if it's static; + // otherwise we record it as dynamic to prevent its use in + // static contexts. + // We still evaluate it fully here to catch any errors early. + if n.Config.Const { + val, errSourceRange, err = n.evalModuleVariable(ctx, false) + diags = diags.Append(err) + } else { + val = cty.DynamicVal + } default: - val, err = n.evalModuleVariable(ctx, false) + val, errSourceRange, err = n.evalModuleVariable(ctx, false) diags = diags.Append(err) } if diags.HasErrors() { @@ -236,6 +248,15 @@ func (n *nodeModuleVariable) Execute(ctx EvalContext, op walkOperation) (diags t diags = diags.Append(deprecationDiags) } + if op == walkInit && n.Config.Const && !val.IsWhollyKnown() { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Static variables must be known", + Detail: "Only a static value can be passed into a static module variable.", + Subject: errSourceRange.ToHCL().Ptr(), + }) + } + // Set values for arguments of a child module call, for later retrieval // during expression evaluation. ctx.NamedValues().SetInputVariableValue(n.Addr, val) @@ -263,7 +284,7 @@ func (n *nodeModuleVariable) DotNode(name string, opts *dag.DotOpts) *dag.DotNod // validateOnly indicates that this evaluation is only for config // validation, and we will not have any expansion module instance // repetition data. -func (n *nodeModuleVariable) evalModuleVariable(ctx EvalContext, validateOnly bool) (cty.Value, error) { +func (n *nodeModuleVariable) evalModuleVariable(ctx EvalContext, validateOnly bool) (cty.Value, tfdiags.SourceRange, error) { var diags tfdiags.Diagnostics var givenVal cty.Value var errSourceRange tfdiags.SourceRange @@ -289,7 +310,7 @@ func (n *nodeModuleVariable) evalModuleVariable(ctx EvalContext, validateOnly bo val, moreDiags := scope.EvalExpr(expr, cty.DynamicPseudoType) diags = diags.Append(moreDiags) if moreDiags.HasErrors() { - return cty.DynamicVal, diags.ErrWithWarnings() + return cty.DynamicVal, errSourceRange, diags.ErrWithWarnings() } givenVal = val errSourceRange = tfdiags.SourceRangeFromHCL(expr.Range()) @@ -320,7 +341,7 @@ func (n *nodeModuleVariable) evalModuleVariable(ctx EvalContext, validateOnly bo }) } - return finalVal, diags.ErrWithWarnings() + return finalVal, errSourceRange, diags.ErrWithWarnings() } // nodeModuleVariableInPartialModule represents an infinite set of possible diff --git a/internal/terraform/node_root_variable.go b/internal/terraform/node_root_variable.go index c05c0c9ba0..694a65a0a7 100644 --- a/internal/terraform/node_root_variable.go +++ b/internal/terraform/node_root_variable.go @@ -110,19 +110,43 @@ func (n *NodeRootVariable) Execute(ctx EvalContext, op walkOperation) tfdiags.Di } } - finalVal, moreDiags := PrepareFinalInputVariableValue( - addr, - givenVal, - n.Config, - ) - diags = diags.Append(moreDiags) - if moreDiags.HasErrors() { - // No point in proceeding to validations then, because they'll - // probably fail trying to work with a value of the wrong type. - return diags - } + // During init we only want to prepare the final value for static variables. + if op == walkInit { + var finalVal cty.Value + if n.Config.Const { + var moreDiags tfdiags.Diagnostics + finalVal, moreDiags = PrepareFinalInputVariableValue( + addr, + givenVal, + n.Config, + ) + diags = diags.Append(moreDiags) + if moreDiags.HasErrors() { + // No point in proceeding to validations then, because they'll + // probably fail trying to work with a value of the wrong type. + return diags + } + } else { + // All non-static variables are unknown during init. + finalVal = cty.UnknownVal(n.Config.Type) + } + ctx.NamedValues().SetInputVariableValue(addr, finalVal) - ctx.NamedValues().SetInputVariableValue(addr, finalVal) + } else { + finalVal, moreDiags := PrepareFinalInputVariableValue( + addr, + givenVal, + n.Config, + ) + diags = diags.Append(moreDiags) + if moreDiags.HasErrors() { + // No point in proceeding to validations then, because they'll + // probably fail trying to work with a value of the wrong type. + return diags + } + + ctx.NamedValues().SetInputVariableValue(addr, finalVal) + } // Custom validation rules are handled by a separate graph node of type // nodeVariableValidation, added by variableValidationTransformer. diff --git a/internal/terraform/transform_filter.go b/internal/terraform/transform_filter.go new file mode 100644 index 0000000000..2feb115ac2 --- /dev/null +++ b/internal/terraform/transform_filter.go @@ -0,0 +1,42 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package terraform + +import ( + "github.com/hashicorp/terraform/internal/dag" +) + +// TransformFilter is a GraphTransformer that filters out nodes from the graph based on a provided function. The Keep function should return true for nodes that should be kept in the graph, and false for nodes that should be removed. The transformer will mark all nodes that the node to keep depends on as well, ensuring that the resulting graph is still valid. +type TransformFilter struct { + Keep func(node dag.Vertex) bool +} + +var _ GraphTransformer = (*TransformFilter)(nil) + +func (t *TransformFilter) Transform(g *Graph) error { + // Partition vertices into kept and candidates for removal. + var kept []dag.Vertex + var removalCandidates []dag.Vertex + for _, v := range g.Vertices() { + if t.Keep(v) { + kept = append(kept, v) + } else { + removalCandidates = append(removalCandidates, v) + } + } + + // Also keep all ancestors (transitive dependencies) of the kept + // nodes so the resulting graph stays valid. + ancestors := g.Ancestors(kept...) + + // Remove every vertex that isn't explicitly kept and isn't an + // ancestor of a kept node. + for _, v := range removalCandidates { + if !ancestors.Include(v) { + g.Remove(v) + } + } + + return nil +} diff --git a/internal/terraform/transform_filter_test.go b/internal/terraform/transform_filter_test.go new file mode 100644 index 0000000000..6fff7182aa --- /dev/null +++ b/internal/terraform/transform_filter_test.go @@ -0,0 +1,386 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package terraform + +import ( + "strings" + "testing" + + "github.com/hashicorp/terraform/internal/dag" +) + +func TestTransformFilter(t *testing.T) { + t.Run("empty graph", func(t *testing.T) { + var g Graph + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return true + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + if actual != "" { + t.Fatalf("expected empty graph, got:\n%s", actual) + } + }) + + t.Run("keep all", func(t *testing.T) { + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Connect(dag.BasicEdge("a", "b")) + g.Connect(dag.BasicEdge("b", "c")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return true + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(` +a + b +b + c +c +`) + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("remove all", func(t *testing.T) { + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Connect(dag.BasicEdge("a", "b")) + g.Connect(dag.BasicEdge("b", "c")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return false + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + if actual != "" { + t.Fatalf("expected empty graph, got:\n%s", actual) + } + }) + + t.Run("keep node preserves its dependencies", func(t *testing.T) { + // a -> b -> c + // Keep only "a"; "b" and "c" should be preserved as ancestors. + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Connect(dag.BasicEdge("a", "b")) + g.Connect(dag.BasicEdge("b", "c")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return v.(string) == "a" + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(` +a + b +b + c +c +`) + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("keep leaf removes dependents", func(t *testing.T) { + // a -> b -> c + // Keep only "c"; "a" and "b" are not ancestors of "c" so they + // should be removed. + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Connect(dag.BasicEdge("a", "b")) + g.Connect(dag.BasicEdge("b", "c")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return v.(string) == "c" + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := "c" + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("keep middle preserves dependencies and removes dependents", func(t *testing.T) { + // a -> b -> c + // Keep "b"; "c" is an ancestor and stays, "a" depends on "b" + // but is not an ancestor so it is removed. + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Connect(dag.BasicEdge("a", "b")) + g.Connect(dag.BasicEdge("b", "c")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return v.(string) == "b" + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(` +b + c +c +`) + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("diamond keep root preserves all", func(t *testing.T) { + // a -> b -> d + // a -> c -> d + // Keep "a"; everything is an ancestor of "a" so nothing is removed. + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Add("d") + g.Connect(dag.BasicEdge("a", "b")) + g.Connect(dag.BasicEdge("a", "c")) + g.Connect(dag.BasicEdge("b", "d")) + g.Connect(dag.BasicEdge("c", "d")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return v.(string) == "a" + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(` +a + b + c +b + d +c + d +d +`) + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("diamond keep one branch", func(t *testing.T) { + // a -> b -> d + // a -> c -> d + // Keep "b"; "d" is an ancestor of "b" so it stays. "a" and "c" + // are not ancestors of "b" so they are removed. + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Add("d") + g.Connect(dag.BasicEdge("a", "b")) + g.Connect(dag.BasicEdge("a", "c")) + g.Connect(dag.BasicEdge("b", "d")) + g.Connect(dag.BasicEdge("c", "d")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return v.(string) == "b" + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(` +b + d +d +`) + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("disconnected nodes are removed", func(t *testing.T) { + // a -> b, c (standalone) + // Keep "a"; "b" is preserved as ancestor, "c" has no connection + // and is removed. + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Connect(dag.BasicEdge("a", "b")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return v.(string) == "a" + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(` +a + b +b +`) + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("multiple kept nodes merge their ancestors", func(t *testing.T) { + // a -> b -> d + // c -> d + // Keep "a" and "c"; their combined ancestors are "b" and "d", + // so the entire graph is preserved. + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Add("d") + g.Connect(dag.BasicEdge("a", "b")) + g.Connect(dag.BasicEdge("b", "d")) + g.Connect(dag.BasicEdge("c", "d")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + s := v.(string) + return s == "a" || s == "c" + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(` +a + b +b + d +c + d +d +`) + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("shared dependency kept through one branch", func(t *testing.T) { + // a -> c + // b -> c + // Keep "a"; "c" is an ancestor and stays, "b" is removed. + var g Graph + g.Add("a") + g.Add("b") + g.Add("c") + g.Connect(dag.BasicEdge("a", "c")) + g.Connect(dag.BasicEdge("b", "c")) + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return v.(string) == "a" + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(` +a + c +c +`) + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("single node kept", func(t *testing.T) { + var g Graph + g.Add("a") + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return true + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := "a" + if actual != expected { + t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + } + }) + + t.Run("single node removed", func(t *testing.T) { + var g Graph + g.Add("a") + + tf := &TransformFilter{ + Keep: func(v dag.Vertex) bool { + return false + }, + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + if actual != "" { + t.Fatalf("expected empty graph, got:\n%s", actual) + } + }) +} diff --git a/internal/terraform/transform_module_install.go b/internal/terraform/transform_module_install.go new file mode 100644 index 0000000000..175ebc8574 --- /dev/null +++ b/internal/terraform/transform_module_install.go @@ -0,0 +1,48 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package terraform + +import ( + "log" + + "github.com/hashicorp/terraform/internal/addrs" + "github.com/hashicorp/terraform/internal/configs" + "github.com/hashicorp/terraform/internal/dag" +) + +type ModuleTransformer struct { + Config *configs.Config + Walker configs.ModuleWalker +} + +func (t *ModuleTransformer) Transform(graph *Graph) error { + if t.Config == nil { + return nil + } + + for _, call := range t.Config.Module.ModuleCalls { + instancePath := graph.Path.Child(call.Name, addrs.NoKey) + + err := t.transform(graph, t.Config, instancePath, call) + if err != nil { + return err + } + } + + return nil +} + +func (t *ModuleTransformer) transform(graph *Graph, cfg *configs.Config, path addrs.ModuleInstance, modCall *configs.ModuleCall) error { + n := &nodeInstallModule{ + Addr: path, + ModuleCall: modCall, + Parent: cfg, + Walker: t.Walker, + } + var installNode dag.Vertex = n + graph.Add(installNode) + log.Printf("[TRACE] ModuleTransformer: Added %s as %T", path, installNode) + + return nil +} diff --git a/internal/terraform/transform_module_variable.go b/internal/terraform/transform_module_variable.go index 0dc19eb122..e09b9d6baf 100644 --- a/internal/terraform/transform_module_variable.go +++ b/internal/terraform/transform_module_variable.go @@ -29,6 +29,10 @@ import ( type ModuleVariableTransformer struct { Config *configs.Config + // ModuleOnly, if true, makes the transformer only process the + // variables in the current module, skipping any child modules. + ModuleOnly bool + // Planning must be set to true when building a planning graph, and must be // false when building an apply graph. Planning bool @@ -39,7 +43,11 @@ type ModuleVariableTransformer struct { } func (t *ModuleVariableTransformer) Transform(g *Graph) error { - return t.transform(g, nil, t.Config) + if t.ModuleOnly && t.Config.Parent != nil { + return t.transformSingle(g, t.Config.Parent, t.Config) + } else { + return t.transform(g, nil, t.Config) + } } func (t *ModuleVariableTransformer) transform(g *Graph, parent, c *configs.Config) error { diff --git a/internal/terraform/walkoperation_string.go b/internal/terraform/walkoperation_string.go index 20a8220844..5500ba0817 100644 --- a/internal/terraform/walkoperation_string.go +++ b/internal/terraform/walkoperation_string.go @@ -16,11 +16,12 @@ func _() { _ = x[walkDestroy-5] _ = x[walkImport-6] _ = x[walkEval-7] + _ = x[walkInit-8] } -const _walkOperation_name = "walkInvalidwalkApplywalkPlanwalkPlanDestroywalkValidatewalkDestroywalkImportwalkEval" +const _walkOperation_name = "walkInvalidwalkApplywalkPlanwalkPlanDestroywalkValidatewalkDestroywalkImportwalkEvalwalkInit" -var _walkOperation_index = [...]uint8{0, 11, 20, 28, 43, 55, 66, 76, 84} +var _walkOperation_index = [...]uint8{0, 11, 20, 28, 43, 55, 66, 76, 84, 92} func (i walkOperation) String() string { idx := int(i) - 0 From 11d819048af8290cced683027d383bf410143dbd Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 16:31:32 +0100 Subject: [PATCH 09/24] Store module source and version expressions Instead of evaluating and parsing a module source and version on configuration loading, we now simply store the expression. Decoding is now done during the graph-based configuration loading in the module install node. --- internal/configs/module_call.go | 78 ++----------------------- internal/configs/module_call_test.go | 49 +++++----------- internal/configs/module_merge.go | 11 ++-- internal/configs/module_merge_test.go | 23 ++------ internal/configs/provider_validation.go | 15 ++--- 5 files changed, 36 insertions(+), 140 deletions(-) diff --git a/internal/configs/module_call.go b/internal/configs/module_call.go index f1064b359c..e01b584cd0 100644 --- a/internal/configs/module_call.go +++ b/internal/configs/module_call.go @@ -7,26 +7,19 @@ import ( "fmt" "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/hcl/v2/gohcl" "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/zclconf/go-cty/cty" - - "github.com/hashicorp/terraform/internal/addrs" - "github.com/hashicorp/terraform/internal/getmodules/moduleaddrs" ) // ModuleCall represents a "module" block in a module or file. type ModuleCall struct { Name string - SourceAddr addrs.ModuleSource - SourceAddrRaw string - SourceAddrRange hcl.Range - SourceSet bool + SourceExpr hcl.Expression Config hcl.Body - Version VersionConstraint + VersionExpr hcl.Expression Count hcl.Expression ForEach hcl.Expression @@ -66,75 +59,12 @@ func decodeModuleBlock(block *hcl.Block, override bool) (*ModuleCall, hcl.Diagno }) } - haveVersionArg := false if attr, exists := content.Attributes["version"]; exists { - var versionDiags hcl.Diagnostics - mc.Version, versionDiags = decodeVersionConstraint(attr) - diags = append(diags, versionDiags...) - haveVersionArg = true + mc.VersionExpr = attr.Expr } if attr, exists := content.Attributes["source"]; exists { - mc.SourceSet = true - mc.SourceAddrRange = attr.Expr.Range() - valDiags := gohcl.DecodeExpression(attr.Expr, nil, &mc.SourceAddrRaw) - diags = append(diags, valDiags...) - if !valDiags.HasErrors() { - var addr addrs.ModuleSource - var err error - if haveVersionArg { - addr, err = moduleaddrs.ParseModuleSourceRegistry(mc.SourceAddrRaw) - } else { - addr, err = moduleaddrs.ParseModuleSource(mc.SourceAddrRaw) - } - mc.SourceAddr = addr - if err != nil { - // NOTE: We leave mc.SourceAddr as nil for any situation where the - // source attribute is invalid, so any code which tries to carefully - // use the partial result of a failed config decode must be - // resilient to that. - mc.SourceAddr = nil - - // NOTE: In practice it's actually very unlikely to end up here, - // because our source address parser can turn just about any string - // into some sort of remote package address, and so for most errors - // we'll detect them only during module installation. There are - // still a _few_ purely-syntax errors we can catch at parsing time, - // though, mostly related to remote package sub-paths and local - // paths. - switch err := err.(type) { - case *moduleaddrs.MaybeRelativePathErr: - diags = append(diags, &hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Invalid module source address", - Detail: fmt.Sprintf( - "Terraform failed to determine your intended installation method for remote module package %q.\n\nIf you intended this as a path relative to the current module, use \"./%s\" instead. The \"./\" prefix indicates that the address is a relative filesystem path.", - err.Addr, err.Addr, - ), - Subject: mc.SourceAddrRange.Ptr(), - }) - default: - if haveVersionArg { - // In this case we'll include some extra context that - // we assumed a registry source address due to the - // version argument. - diags = append(diags, &hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Invalid registry module source address", - Detail: fmt.Sprintf("Failed to parse module registry address: %s.\n\nTerraform assumed that you intended a module registry source address because you also set the argument \"version\", which applies only to registry modules.", err), - Subject: mc.SourceAddrRange.Ptr(), - }) - } else { - diags = append(diags, &hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Invalid module source address", - Detail: fmt.Sprintf("Failed to parse module source address: %s.", err), - Subject: mc.SourceAddrRange.Ptr(), - }) - } - } - } - } + mc.SourceExpr = attr.Expr } if attr, exists := content.Attributes["count"]; exists { diff --git a/internal/configs/module_call_test.go b/internal/configs/module_call_test.go index 4e94d00c44..4c865c3622 100644 --- a/internal/configs/module_call_test.go +++ b/internal/configs/module_call_test.go @@ -10,7 +10,7 @@ import ( "github.com/go-test/deep" "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/terraform/internal/addrs" + "github.com/hashicorp/hcl/v2/hclsyntax" ) func TestLoadModuleCall(t *testing.T) { @@ -31,15 +31,11 @@ func TestLoadModuleCall(t *testing.T) { gotModules := file.ModuleCalls wantModules := []*ModuleCall{ { - Name: "foo", - SourceAddr: addrs.ModuleSourceLocal("./foo"), - SourceAddrRaw: "./foo", - SourceSet: true, - SourceAddrRange: hcl.Range{ - Filename: "module-calls.tf", - Start: hcl.Pos{Line: 3, Column: 12, Byte: 27}, - End: hcl.Pos{Line: 3, Column: 19, Byte: 34}, - }, + Name: "foo", + SourceExpr: mustExpr(hclsyntax.ParseExpression( + []byte("\"./foo\""), "module-calls.tf", + hcl.Pos{Line: 3, Column: 12, Byte: 27}, + )), DeclRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 2, Column: 1, Byte: 1}, @@ -48,21 +44,10 @@ func TestLoadModuleCall(t *testing.T) { }, { Name: "bar", - SourceAddr: addrs.ModuleSourceRegistry{ - Package: addrs.ModuleRegistryPackage{ - Host: addrs.DefaultModuleRegistryHost, - Namespace: "hashicorp", - Name: "bar", - TargetSystem: "aws", - }, - }, - SourceAddrRaw: "hashicorp/bar/aws", - SourceSet: true, - SourceAddrRange: hcl.Range{ - Filename: "module-calls.tf", - Start: hcl.Pos{Line: 8, Column: 12, Byte: 113}, - End: hcl.Pos{Line: 8, Column: 31, Byte: 132}, - }, + SourceExpr: mustExpr(hclsyntax.ParseExpression( + []byte("\"hashicorp/bar/aws\""), "module-calls.tf", + hcl.Pos{Line: 8, Column: 12, Byte: 113}, + )), DeclRange: hcl.Range{ Filename: "module-calls.tf", Start: hcl.Pos{Line: 7, Column: 1, Byte: 87}, @@ -71,16 +56,10 @@ func TestLoadModuleCall(t *testing.T) { }, { Name: "baz", - SourceAddr: addrs.ModuleSourceRemote{ - Package: addrs.ModulePackage("git::https://example.com/"), - }, - SourceAddrRaw: "git::https://example.com/", - SourceSet: true, - SourceAddrRange: hcl.Range{ - Filename: "module-calls.tf", - Start: hcl.Pos{Line: 15, Column: 12, Byte: 193}, - End: hcl.Pos{Line: 15, Column: 39, Byte: 220}, - }, + SourceExpr: mustExpr(hclsyntax.ParseExpression( + []byte("\"git::https://example.com/\""), "module-calls.tf", + hcl.Pos{Line: 15, Column: 12, Byte: 193}, + )), DependsOn: []hcl.Traversal{ { hcl.TraverseRoot{ diff --git a/internal/configs/module_merge.go b/internal/configs/module_merge.go index ff27d502e3..d9bc2abcc7 100644 --- a/internal/configs/module_merge.go +++ b/internal/configs/module_merge.go @@ -178,11 +178,8 @@ func (o *Output) merge(oo *Output) hcl.Diagnostics { func (mc *ModuleCall) merge(omc *ModuleCall) hcl.Diagnostics { var diags hcl.Diagnostics - if omc.SourceSet { - mc.SourceAddr = omc.SourceAddr - mc.SourceAddrRaw = omc.SourceAddrRaw - mc.SourceAddrRange = omc.SourceAddrRange - mc.SourceSet = omc.SourceSet + if omc.SourceExpr != nil { + mc.SourceExpr = omc.SourceExpr } if omc.Count != nil { @@ -193,8 +190,8 @@ func (mc *ModuleCall) merge(omc *ModuleCall) hcl.Diagnostics { mc.ForEach = omc.ForEach } - if len(omc.Version.Required) != 0 { - mc.Version = omc.Version + if omc.VersionExpr != nil { + mc.VersionExpr = omc.VersionExpr } mc.Config = MergeBodies(mc.Config, omc.Config) diff --git a/internal/configs/module_merge_test.go b/internal/configs/module_merge_test.go index 78b2825e21..dabed28a8f 100644 --- a/internal/configs/module_merge_test.go +++ b/internal/configs/module_merge_test.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/gohcl" + "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/zclconf/go-cty/cty" "github.com/hashicorp/terraform/internal/addrs" @@ -91,23 +92,11 @@ func TestModuleOverrideModule(t *testing.T) { got := mod.ModuleCalls["example"] want := &ModuleCall{ - Name: "example", - SourceAddr: addrs.ModuleSourceLocal("./example2-a_override"), - SourceAddrRaw: "./example2-a_override", - SourceAddrRange: hcl.Range{ - Filename: "testdata/valid-modules/override-module/a_override.tf", - Start: hcl.Pos{ - Line: 3, - Column: 12, - Byte: 31, - }, - End: hcl.Pos{ - Line: 3, - Column: 35, - Byte: 54, - }, - }, - SourceSet: true, + Name: "example", + SourceExpr: mustExpr(hclsyntax.ParseExpression( + []byte("\"./example2-a_override\""), "testdata/valid-modules/override-module/a_override.tf", + hcl.Pos{Line: 3, Column: 12, Byte: 31}, + )), DeclRange: hcl.Range{ Filename: "testdata/valid-modules/override-module/primary.tf", Start: hcl.Pos{ diff --git a/internal/configs/provider_validation.go b/internal/configs/provider_validation.go index 78adb8cc9a..009f33ed4c 100644 --- a/internal/configs/provider_validation.go +++ b/internal/configs/provider_validation.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/hashicorp/hcl/v2" + "github.com/zclconf/go-cty/cty" "github.com/hashicorp/terraform/internal/addrs" ) @@ -253,14 +254,14 @@ func validateProviderConfigsForTests(cfg *Config) (diags hcl.Diagnostics) { // Let's make a little fake module call that we can use to call // into validateProviderConfigs. + sourceExpr := hcl.StaticExpr(cty.StringVal(run.Module.Source.String()), run.Module.SourceDeclRange) + versionExpr := hcl.StaticExpr(cty.StringVal(run.Module.Version.Required.String()), run.Module.Version.DeclRange) mc := &ModuleCall{ - Name: run.Name, - SourceAddr: run.Module.Source, - SourceAddrRange: run.Module.SourceDeclRange, - SourceSet: true, - Version: run.Module.Version, - Providers: providers, - DeclRange: run.Module.DeclRange, + Name: run.Name, + SourceExpr: sourceExpr, + VersionExpr: versionExpr, + Providers: providers, + DeclRange: run.Module.DeclRange, } diags = append(diags, validateProviderConfigs(mc, run.ConfigUnderTest, nil)...) From fb60c1567085ffed9ec4d7069d8ac10eb5cce5a0 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 16:38:40 +0100 Subject: [PATCH 10/24] Update init to use new graph-based workflow The init command and the module installer are now using the new graph-based workflow to install modules instead of using the recursive BuildConfig. --- internal/command/init.go | 17 ++++++++-- internal/command/meta.go | 4 ++- internal/command/meta_config.go | 16 ++++++++- internal/initwd/from_module.go | 43 +++++++++++++----------- internal/initwd/from_module_test.go | 6 ++-- internal/initwd/module_install.go | 45 +++++++++++++++++-------- internal/initwd/module_install_test.go | 46 +++++++++++++------------- internal/initwd/testing.go | 4 +-- 8 files changed, 117 insertions(+), 64 deletions(-) diff --git a/internal/command/init.go b/internal/command/init.go index f8a56dc403..d5796e92e8 100644 --- a/internal/command/init.go +++ b/internal/command/init.go @@ -49,11 +49,24 @@ func (c *InitCommand) Run(args []string) int { var diags tfdiags.Diagnostics args = c.Meta.process(args) initArgs, initDiags := arguments.ParseInit(args, c.Meta.AllowExperimentalFeatures) + diags = diags.Append(initDiags) view := views.NewInit(initArgs.ViewType, c.View) - if initDiags.HasErrors() { - diags = diags.Append(initDiags) + loader, err := c.initConfigLoader() + if err != nil { + diags = diags.Append(err) + view.Diagnostics(diags) + return 1 + } + + var varDiags tfdiags.Diagnostics + c.VariableValues, varDiags = initArgs.Vars.CollectValues(func(filename string, src []byte) { + loader.Parser().ForceFileSource(filename, src) + }) + diags = diags.Append(varDiags) + + if diags.HasErrors() { view.Diagnostics(diags) return 1 } diff --git a/internal/command/meta.go b/internal/command/meta.go index 6bba97540c..cebd76f7f8 100644 --- a/internal/command/meta.go +++ b/internal/command/meta.go @@ -186,6 +186,8 @@ type Meta struct { // flag is set, to reinforce that experiments are not for production use. AllowExperimentalFeatures bool + VariableValues map[string]arguments.UnparsedVariableValue + //---------------------------------------------------------- // Protected: commands can set these //---------------------------------------------------------- @@ -835,7 +837,7 @@ func (m *Meta) checkRequiredVersion() tfdiags.Diagnostics { return diags } - config, configDiags := loader.LoadConfig(pwd) + config, configDiags := m.loadConfig(pwd) if configDiags.HasErrors() { diags = diags.Append(configDiags) return diags diff --git a/internal/command/meta_config.go b/internal/command/meta_config.go index 6c6e80dbb2..c99898d74f 100644 --- a/internal/command/meta_config.go +++ b/internal/command/meta_config.go @@ -201,7 +201,21 @@ func (m *Meta) installModules(ctx context.Context, rootDir, testsDir string, upg return true, diags } - inst := initwd.NewModuleInstaller(m.modulesDir(), loader, m.registryClient()) + initializer := func(rootMod *configs.Module, walker configs.ModuleWalker) (*configs.Config, tfdiags.Diagnostics) { + variables, diags := backendrun.ParseConstVariableValues(m.VariableValues, rootMod.Variables) + ctx, ctxDiags := terraform.NewContext(&terraform.ContextOpts{ + Parallelism: 1, + }) + diags = diags.Append(ctxDiags) + if diags.HasErrors() { + return nil, diags + } + return ctx.Init(rootMod, terraform.InitOpts{ + Walker: walker, + SetVariables: variables, + }) + } + inst := initwd.NewModuleInstaller(m.modulesDir(), loader, m.registryClient(), initializer) _, moreDiags := inst.InstallModules(ctx, rootDir, testsDir, upgrade, installErrsOnly, hooks) diags = diags.Append(moreDiags) diff --git a/internal/initwd/from_module.go b/internal/initwd/from_module.go index aed383d035..aeb6799664 100644 --- a/internal/initwd/from_module.go +++ b/internal/initwd/from_module.go @@ -6,7 +6,6 @@ package initwd import ( "context" "fmt" - "io/ioutil" "log" "os" "path/filepath" @@ -19,6 +18,7 @@ import ( "github.com/hashicorp/terraform/internal/copy" "github.com/hashicorp/terraform/internal/getmodules" "github.com/hashicorp/terraform/internal/getmodules/moduleaddrs" + "github.com/zclconf/go-cty/cty" version "github.com/hashicorp/go-version" "github.com/hashicorp/terraform/internal/modsdir" @@ -59,7 +59,7 @@ func DirFromModule(ctx context.Context, loader *configload.Loader, rootDir, modu // The target directory must exist but be empty. { - entries, err := ioutil.ReadDir(rootDir) + entries, err := os.ReadDir(rootDir) if err != nil { if os.IsNotExist(err) { diags = diags.Append(tfdiags.Sourceless( @@ -94,7 +94,7 @@ func DirFromModule(ctx context.Context, loader *configload.Loader, rootDir, modu } instDir := filepath.Join(rootDir, ".terraform/init-from-module") - inst := NewModuleInstaller(instDir, loader, reg) + inst := NewModuleInstaller(instDir, loader, reg, nil) log.Printf("[DEBUG] installing modules in %s to initialize working directory from %q", instDir, sourceAddrStr) os.RemoveAll(instDir) // if this fails then we'll fail on MkdirAll below too err := os.MkdirAll(instDir, os.ModePerm) @@ -129,24 +129,17 @@ func DirFromModule(ctx context.Context, loader *configload.Loader, rootDir, modu // Now we need to create an artificial root module that will seed our // installation process. - sourceAddr, err := moduleaddrs.ParseModuleSource(sourceAddrStr) - if err != nil { - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Invalid module source address", - fmt.Sprintf("Failed to parse module source address: %s", err), - )) + fakeRange := hcl.Range{ + Filename: initFromModuleRootFilename, + Start: hcl.InitialPos, + End: hcl.InitialPos, } fakeRootModule := &configs.Module{ ModuleCalls: map[string]*configs.ModuleCall{ initFromModuleRootCallName: { Name: initFromModuleRootCallName, - SourceAddr: sourceAddr, - DeclRange: hcl.Range{ - Filename: initFromModuleRootFilename, - Start: hcl.InitialPos, - End: hcl.InitialPos, - }, + SourceExpr: hcl.StaticExpr(cty.StringVal(sourceAddrStr), fakeRange), + DeclRange: fakeRange, }, }, ProviderRequirements: &configs.RequiredProviders{}, @@ -167,11 +160,20 @@ func DirFromModule(ctx context.Context, loader *configload.Loader, rootDir, modu fetcher := getmodules.NewPackageFetcher() walker := inst.moduleInstallWalker(ctx, instManifest, true, wrapHooks, fetcher) - _, cDiags := inst.installDescendantModules(fakeRootModule, instManifest, walker, true) + _, cDiags := inst.installDescendantModules(fakeRootModule, walker, true) if cDiags.HasErrors() { return diags.Append(cDiags) } + err = instManifest.WriteSnapshotToDir(instDir) + if err != nil { + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Failed to update module manifest", + fmt.Sprintf("Unable to write the module manifest file: %s", err), + )) + } + // If all of that succeeded then we'll now migrate what was installed // into the final directory structure. err = os.MkdirAll(modulesDir, os.ModePerm) @@ -215,9 +217,12 @@ func DirFromModule(ctx context.Context, loader *configload.Loader, rootDir, modu mod, _ := loader.Parser().LoadConfigDir(rootDir) // ignore diagnostics since we're just doing value-add here anyway if mod != nil { for _, mc := range mod.ModuleCalls { - if pathTraversesUp(mc.SourceAddrRaw) { + // TODO improve this + sourceVal, _ := mc.SourceExpr.Value(nil) + sourceRaw := sourceVal.AsString() + if pathTraversesUp(sourceRaw) { packageAddr, givenSubdir := moduleaddrs.SplitPackageSubdir(sourceAddrStr) - newSubdir := filepath.Join(givenSubdir, mc.SourceAddrRaw) + newSubdir := filepath.Join(givenSubdir, sourceRaw) if pathTraversesUp(newSubdir) { // This should never happen in any reasonable // configuration since this suggests a path that diff --git a/internal/initwd/from_module_test.go b/internal/initwd/from_module_test.go index 1b7bd9ce9b..9f57be4de7 100644 --- a/internal/initwd/from_module_test.go +++ b/internal/initwd/from_module_test.go @@ -107,7 +107,7 @@ func TestDirFromModule_registry(t *testing.T) { // Make sure the configuration is loadable now. // (This ensures that correct information is recorded in the manifest.) - config, loadDiags := loader.LoadConfig(".") + config, loadDiags := loader.LoadStaticConfig(".") tfdiags.AssertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags)) wantTraces := map[string]string{ @@ -187,7 +187,7 @@ func TestDirFromModule_submodules(t *testing.T) { // Make sure the configuration is loadable now. // (This ensures that correct information is recorded in the manifest.) - config, loadDiags := loader.LoadConfig(".") + config, loadDiags := loader.LoadStaticConfig(".") tfdiags.AssertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags)) wantTraces := map[string]string{ @@ -312,7 +312,7 @@ func TestDirFromModule_rel_submodules(t *testing.T) { // Make sure the configuration is loadable now. // (This ensures that correct information is recorded in the manifest.) - config, loadDiags := loader.LoadConfig(".") + config, loadDiags := loader.LoadStaticConfig(".") tfdiags.AssertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags)) wantTraces := map[string]string{ diff --git a/internal/initwd/module_install.go b/internal/initwd/module_install.go index a3547e915d..1a4992d42c 100644 --- a/internal/initwd/module_install.go +++ b/internal/initwd/module_install.go @@ -30,6 +30,8 @@ import ( "github.com/hashicorp/terraform/internal/tfdiags" ) +type Initializer func(rootMod *configs.Module, walker configs.ModuleWalker) (*configs.Config, tfdiags.Diagnostics) + type ModuleInstaller struct { modsDir string loader *configload.Loader @@ -42,6 +44,8 @@ type ModuleInstaller struct { // The keys in moduleVersionsUrl are the moduleVersion struct below and // addresses and the values are underlying remote source addresses. registryPackageSources map[moduleVersion]addrs.ModuleSourceRemote + + initializer Initializer } type moduleVersion struct { @@ -49,13 +53,14 @@ type moduleVersion struct { version string } -func NewModuleInstaller(modsDir string, loader *configload.Loader, reg *registry.Client) *ModuleInstaller { +func NewModuleInstaller(modsDir string, loader *configload.Loader, reg *registry.Client, initializer Initializer) *ModuleInstaller { return &ModuleInstaller{ modsDir: modsDir, loader: loader, reg: reg, registryPackageVersions: make(map[addrs.ModuleRegistryPackage]*response.ModuleVersions), registryPackageSources: make(map[moduleVersion]addrs.ModuleSourceRemote), + initializer: initializer, } } @@ -137,8 +142,31 @@ func (i *ModuleInstaller) InstallModules(ctx context.Context, rootDir, testsDir } walker := i.moduleInstallWalker(ctx, manifest, upgrade, hooks, fetcher) - cfg, instDiags := i.installDescendantModules(rootMod, manifest, walker, installErrsOnly) - diags = append(diags, instDiags...) + var cfg *configs.Config + var instDiags tfdiags.Diagnostics + if i.initializer != nil { + cfg, instDiags = i.initializer(rootMod, walker) + diags = diags.Append(instDiags) + } else { + cfg, instDiags = i.installDescendantModules(rootMod, walker, installErrsOnly) + diags = diags.Append(instDiags) + } + + finalDiags := configs.FinalizeConfig(cfg, walker, configs.MockDataLoaderFunc(i.loader.LoadExternalMockData)) + diags = diags.Append(finalDiags) + + if diags.HasErrors() { + return nil, diags + } + + err = manifest.WriteSnapshotToDir(i.modsDir) + if err != nil { + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Failed to update module manifest", + fmt.Sprintf("Unable to write the module manifest file: %s", err), + )) + } return cfg, diags } @@ -292,7 +320,7 @@ func (i *ModuleInstaller) moduleInstallWalker(ctx context.Context, manifest mods ) } -func (i *ModuleInstaller) installDescendantModules(rootMod *configs.Module, manifest modsdir.Manifest, installWalker configs.ModuleWalker, installErrsOnly bool) (*configs.Config, tfdiags.Diagnostics) { +func (i *ModuleInstaller) installDescendantModules(rootMod *configs.Module, installWalker configs.ModuleWalker, installErrsOnly bool) (*configs.Config, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics // When attempting to initialize the current directory with a module @@ -332,15 +360,6 @@ func (i *ModuleInstaller) installDescendantModules(rootMod *configs.Module, mani diags = tfdiags.OverrideAll(diags, tfdiags.Warning, nil) } - err := manifest.WriteSnapshotToDir(i.modsDir) - if err != nil { - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Failed to update module manifest", - fmt.Sprintf("Unable to write the module manifest file: %s", err), - )) - } - return cfg, diags } diff --git a/internal/initwd/module_install_test.go b/internal/initwd/module_install_test.go index 89573ac572..75d66861c1 100644 --- a/internal/initwd/module_install_test.go +++ b/internal/initwd/module_install_test.go @@ -45,7 +45,7 @@ func TestModuleInstaller(t *testing.T) { modulesDir := filepath.Join(dir, ".terraform/modules") loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) tfdiags.AssertNoDiagnostics(t, diags) @@ -77,7 +77,7 @@ func TestModuleInstaller(t *testing.T) { // Make sure the configuration is loadable now. // (This ensures that correct information is recorded in the manifest.) - config, loadDiags := loader.LoadConfig(".") + config, loadDiags := loader.LoadStaticConfig(".") tfdiags.AssertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags)) wantTraces := map[string]string{ @@ -109,7 +109,7 @@ func TestModuleInstaller_error(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) if !diags.HasErrors() { @@ -130,7 +130,7 @@ func TestModuleInstaller_emptyModuleName(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) if !diags.HasErrors() { @@ -151,7 +151,7 @@ func TestModuleInstaller_invalidModuleName(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil)) + inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil), nil) _, diags := inst.InstallModules(context.Background(), dir, "tests", false, false, hooks) if !diags.HasErrors() { @@ -189,7 +189,7 @@ func TestModuleInstaller_packageEscapeError(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) if !diags.HasErrors() { @@ -227,7 +227,7 @@ func TestModuleInstaller_explicitPackageBoundary(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) if diags.HasErrors() { @@ -250,7 +250,7 @@ func TestModuleInstaller_ExactMatchPrerelease(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil)) + inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil), nil) cfg, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) if diags.HasErrors() { @@ -277,7 +277,7 @@ func TestModuleInstaller_PartialMatchPrerelease(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil)) + inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil), nil) cfg, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) if diags.HasErrors() { @@ -300,7 +300,7 @@ func TestModuleInstaller_invalid_version_constraint_error(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) if !diags.HasErrors() { @@ -326,7 +326,7 @@ func TestModuleInstaller_invalidVersionConstraintGetter(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) if !diags.HasErrors() { @@ -352,7 +352,7 @@ func TestModuleInstaller_invalidVersionConstraintLocal(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) if !diags.HasErrors() { @@ -378,7 +378,7 @@ func TestModuleInstaller_symlink(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) tfdiags.AssertNoDiagnostics(t, diags) @@ -410,7 +410,7 @@ func TestModuleInstaller_symlink(t *testing.T) { // Make sure the configuration is loadable now. // (This ensures that correct information is recorded in the manifest.) - config, loadDiags := loader.LoadConfig(".") + config, loadDiags := loader.LoadStaticConfig(".") tfdiags.AssertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags)) wantTraces := map[string]string{ @@ -454,7 +454,7 @@ func TestLoaderInstallModules_invalidRegistry(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil)) + inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil), nil) _, diags := inst.InstallModules(context.Background(), dir, "tests", false, false, hooks) if !diags.HasErrors() { @@ -493,7 +493,7 @@ func TestLoaderInstallModules_registry(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil)) + inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil), nil) _, diags := inst.InstallModules(context.Background(), dir, "tests", false, false, hooks) tfdiags.AssertNoDiagnostics(t, diags) @@ -608,7 +608,7 @@ func TestLoaderInstallModules_registry(t *testing.T) { // Make sure the configuration is loadable now. // (This ensures that correct information is recorded in the manifest.) - config, loadDiags := loader.LoadConfig(".") + config, loadDiags := loader.LoadStaticConfig(".") tfdiags.AssertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags)) wantTraces := map[string]string{ @@ -656,7 +656,7 @@ func TestLoaderInstallModules_goGetter(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil)) + inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil), nil) _, diags := inst.InstallModules(context.Background(), dir, "tests", false, false, hooks) tfdiags.AssertNoDiagnostics(t, diags) @@ -738,7 +738,7 @@ func TestLoaderInstallModules_goGetter(t *testing.T) { // Make sure the configuration is loadable now. // (This ensures that correct information is recorded in the manifest.) - config, loadDiags := loader.LoadConfig(".") + config, loadDiags := loader.LoadStaticConfig(".") tfdiags.AssertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags)) wantTraces := map[string]string{ @@ -774,7 +774,7 @@ func TestModuleInstaller_fromTests(t *testing.T) { modulesDir := filepath.Join(dir, ".terraform/modules") loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, nil) + inst := NewModuleInstaller(modulesDir, loader, nil, nil) _, diags := inst.InstallModules(context.Background(), ".", "tests", false, false, hooks) tfdiags.AssertNoDiagnostics(t, diags) @@ -800,7 +800,7 @@ func TestModuleInstaller_fromTests(t *testing.T) { // Make sure the configuration is loadable now. // (This ensures that correct information is recorded in the manifest.) - config, loadDiags := loader.LoadConfigWithTests(".", "tests") + config, loadDiags := loader.LoadStaticConfigWithTests(".", "tests") tfdiags.AssertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags)) if config.Module.Tests["tests/main.tftest.hcl"].Runs[0].ConfigUnderTest == nil { @@ -831,7 +831,7 @@ func TestLoadInstallModules_registryFromTest(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil)) + inst := NewModuleInstaller(modulesDir, loader, registry.NewClient(nil, nil), nil) _, diags := inst.InstallModules(context.Background(), dir, "tests", false, false, hooks) tfdiags.AssertNoDiagnostics(t, diags) @@ -909,7 +909,7 @@ func TestLoadInstallModules_registryFromTest(t *testing.T) { // Make sure the configuration is loadable now. // (This ensures that correct information is recorded in the manifest.) - config, loadDiags := loader.LoadConfigWithTests(".", "tests") + config, loadDiags := loader.LoadStaticConfigWithTests(".", "tests") tfdiags.AssertNoDiagnostics(t, tfdiags.Diagnostics{}.Append(loadDiags)) if config.Module.Tests["main.tftest.hcl"].Runs[0].ConfigUnderTest == nil { diff --git a/internal/initwd/testing.go b/internal/initwd/testing.go index d2c9f7f5c6..6566ce4e67 100644 --- a/internal/initwd/testing.go +++ b/internal/initwd/testing.go @@ -37,7 +37,7 @@ func LoadConfigForTests(t *testing.T, rootDir string, testsDir string) (*configs var diags tfdiags.Diagnostics loader, cleanup := configload.NewLoaderForTests(t) - inst := NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil)) + inst := NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil), nil) _, moreDiags := inst.InstallModules(context.Background(), rootDir, testsDir, true, false, ModuleInstallHooksImpl{}) diags = diags.Append(moreDiags) @@ -53,7 +53,7 @@ func LoadConfigForTests(t *testing.T, rootDir string, testsDir string) (*configs t.Fatalf("failed to refresh modules after installation: %s", err) } - config, hclDiags := loader.LoadConfigWithTests(rootDir, testsDir) + config, hclDiags := loader.LoadStaticConfigWithTests(rootDir, testsDir) diags = diags.Append(hclDiags) return config, loader, cleanup, diags } From 4ef9684188a79c04405dea52efb8f9be003bcaf0 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 17:33:01 +0100 Subject: [PATCH 11/24] Rework most of the configuration loading We previously used a loader -> BuildConfig flow to load configuration. This commit changes most (but not all yet) flows to use the new graph-based approach. Instead of simply recursively loading the modules, we now need to take a stepped approach: 1. Load the root module 2. Collect the variables and their values 3. Build the configuration with the graph-based approach Because this approach relies on different parts from different packages, it can't easliy be done within the `configload` package. So, now we do most of in the backend or command. --- internal/backend/backendrun/operation.go | 10 -- internal/backend/backendrun/unparsed_value.go | 57 +++++++ internal/backend/local/backend_local.go | 149 +++++++++++------- internal/backend/remote/backend_common.go | 7 +- internal/backend/remote/backend_context.go | 25 ++- internal/checks/state_test.go | 4 +- internal/cloud/backend_common.go | 4 +- internal/cloud/backend_context.go | 27 +++- internal/cloud/test_test.go | 4 +- internal/command/apply.go | 4 +- internal/command/command_test.go | 25 ++- internal/command/graph_test.go | 2 +- internal/command/init2_test.go | 101 ++++++++++++ internal/command/meta.go | 6 - internal/command/meta_config.go | 45 +++++- internal/command/test_test.go | 4 +- .../.terraform/modules/child/empty.tf | 0 .../.terraform/modules/modules.json | 4 +- .../add-version-constraint.tf | 0 .../main.tf} | 2 +- .../local-source-with-version/main.tf} | 2 +- internal/command/validate_test.go | 10 +- internal/configs/config_build.go | 144 ++++++++++++++++- internal/configs/configload/loader.go | 5 + internal/configs/configload/loader_load.go | 14 +- .../configs/configload/loader_load_test.go | 32 +--- .../configs/configload/loader_snapshot.go | 20 +-- .../configload/loader_snapshot_test.go | 145 ----------------- internal/configs/import_test.go | 14 +- .../invalid-files/version-variable.tf | 6 - internal/lang/globalref/analyzer_test.go | 4 +- .../moduletest/graph/eval_context_test.go | 4 +- internal/providercache/installer.go | 9 +- internal/refactoring/move_validate_test.go | 8 +- internal/terraform/terraform_test.go | 84 +++++++++- 35 files changed, 641 insertions(+), 340 deletions(-) create mode 100644 internal/command/init2_test.go rename internal/{configs/configload/testdata => command/testdata/dynamic-module-sources}/add-version-constraint/.terraform/modules/child/empty.tf (100%) rename internal/{configs/configload/testdata => command/testdata/dynamic-module-sources}/add-version-constraint/.terraform/modules/modules.json (61%) rename internal/{configs/configload/testdata => command/testdata/dynamic-module-sources}/add-version-constraint/add-version-constraint.tf (100%) rename internal/{configs/testdata/error-files/module-local-source-with-version.tf => command/testdata/dynamic-module-sources/invalid-registry-source-with-module/main.tf} (57%) rename internal/{configs/testdata/error-files/module-invalid-registry-source-with-module.tf => command/testdata/dynamic-module-sources/local-source-with-version/main.tf} (50%) delete mode 100644 internal/configs/configload/loader_snapshot_test.go delete mode 100644 internal/configs/testdata/invalid-files/version-variable.tf diff --git a/internal/backend/backendrun/operation.go b/internal/backend/backendrun/operation.go index 071f7c7583..4168f7dbc1 100644 --- a/internal/backend/backendrun/operation.go +++ b/internal/backend/backendrun/operation.go @@ -14,7 +14,6 @@ import ( "github.com/hashicorp/terraform/internal/command/arguments" "github.com/hashicorp/terraform/internal/command/clistate" "github.com/hashicorp/terraform/internal/command/views" - "github.com/hashicorp/terraform/internal/configs" "github.com/hashicorp/terraform/internal/configs/configload" "github.com/hashicorp/terraform/internal/depsfile" "github.com/hashicorp/terraform/internal/plans" @@ -175,15 +174,6 @@ func (o *Operation) HasConfig() bool { return o.ConfigLoader.IsConfigDir(o.ConfigDir) } -// Config loads the configuration that the operation applies to, using the -// ConfigDir and ConfigLoader fields within the receiving operation. -func (o *Operation) Config() (*configs.Config, tfdiags.Diagnostics) { - var diags tfdiags.Diagnostics - config, hclDiags := o.ConfigLoader.LoadConfig(o.ConfigDir) - diags = diags.Append(hclDiags) - return config, diags -} - // ReportResult is a helper for the common chore of setting the status of // a running operation and showing any diagnostics produced during that // operation. diff --git a/internal/backend/backendrun/unparsed_value.go b/internal/backend/backendrun/unparsed_value.go index 95d8b3f8d6..bf83dc933e 100644 --- a/internal/backend/backendrun/unparsed_value.go +++ b/internal/backend/backendrun/unparsed_value.go @@ -200,3 +200,60 @@ func ParseVariableValues(vv map[string]arguments.UnparsedVariableValue, decls ma return ret, diags } + +func ParseConstVariableValues(vv map[string]arguments.UnparsedVariableValue, decls map[string]*configs.Variable) (terraform.InputValues, tfdiags.Diagnostics) { + ret, diags := ParseDeclaredVariableValues(vv, decls) + undeclared, diagsUndeclared := ParseUndeclaredVariableValues(vv, decls) + + diags = diags.Append(diagsUndeclared) + + // By this point we should've gathered all of the required root module + // variables from one of the many possible sources. We'll now populate + // any we haven't gathered as unset placeholders which Terraform Core + // can then react to. + for name, vc := range decls { + if isDefinedAny(name, ret, undeclared) { + continue + } + + // This check is redundant with a check made in Terraform Core when + // processing undeclared variables, but allows us to generate a more + // specific error message which mentions -var and -var-file command + // line options, whereas the one in Terraform Core is more general + // due to supporting both root and child module variables. + if vc.Const && vc.Required() { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "No value for required variable", + Detail: fmt.Sprintf("The root module input variable %q is not set, and has no default value. Use a -var or -var-file command line argument to provide a value for this variable.", name), + Subject: vc.DeclRange.Ptr(), + }) + } + + if vc.Required() { + // We'll include a placeholder value anyway, just so that our + // result is complete for any calling code that wants to cautiously + // analyze it for diagnostic purposes. Since our diagnostics now + // includes an error, normal processing will ignore this result. + ret[name] = &terraform.InputValue{ + Value: cty.DynamicVal, + SourceType: terraform.ValueFromConfig, + SourceRange: tfdiags.SourceRangeFromHCL(vc.DeclRange), + } + } else { + // We're still required to put an entry for this variable + // in the mapping to be explicit to Terraform Core that we + // visited it, but its value will be cty.NilVal to represent + // that it wasn't set at all at this layer, and so Terraform Core + // should substitute a default if available, or generate an error + // if not. + ret[name] = &terraform.InputValue{ + Value: cty.NilVal, + SourceType: terraform.ValueFromConfig, + SourceRange: tfdiags.SourceRangeFromHCL(vc.DeclRange), + } + } + } + + return ret, diags +} diff --git a/internal/backend/local/backend_local.go b/internal/backend/local/backend_local.go index a179352aed..768b94355a 100644 --- a/internal/backend/local/backend_local.go +++ b/internal/backend/local/backend_local.go @@ -146,39 +146,11 @@ func (b *Local) localRun(op *backendrun.Operation) (*backendrun.LocalRun, *confi func (b *Local) localRunDirect(op *backendrun.Operation, run *backendrun.LocalRun, coreOpts *terraform.ContextOpts, s statemgr.Full) (*backendrun.LocalRun, *configload.Snapshot, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - // Load the configuration using the caller-provided configuration loader. - config, configSnap, configDiags := op.ConfigLoader.LoadConfigWithSnapshot(op.ConfigDir) + rootMod, configDiags := op.ConfigLoader.LoadRootModule(op.ConfigDir) diags = diags.Append(configDiags) if configDiags.HasErrors() { return nil, nil, diags } - run.Config = config - - if errs := config.VerifyDependencySelections(op.DependencyLocks); len(errs) > 0 { - var buf strings.Builder - for _, err := range errs { - fmt.Fprintf(&buf, "\n - %s", err.Error()) - } - var suggestion string - switch { - case op.DependencyLocks == nil: - // If we get here then it suggests that there's a caller that we - // didn't yet update to populate DependencyLocks, which is a bug. - suggestion = "This run has no dependency lock information provided at all, which is a bug in Terraform; please report it!" - case op.DependencyLocks.Empty(): - suggestion = "To make the initial dependency selections that will initialize the dependency lock file, run:\n terraform init" - default: - suggestion = "To update the locked dependency selections to match a changed configuration, run:\n terraform init -upgrade" - } - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Inconsistent dependency lock file", - fmt.Sprintf( - "The following dependency selections recorded in the lock file are inconsistent with the current configuration:%s\n\n%s", - buf.String(), suggestion, - ), - )) - } var rawVariables map[string]arguments.UnparsedVariableValue if op.AllowUnsetVariables { @@ -186,16 +158,16 @@ func (b *Local) localRunDirect(op *backendrun.Operation, run *backendrun.LocalRu // but unset variables with unknown values to represent that they are // placeholders for values the user would need to provide for other // operations. - rawVariables = b.stubUnsetRequiredVariables(op.Variables, config.Module.Variables) + rawVariables = b.stubUnsetRequiredVariables(op.Variables, rootMod.Variables) } else { // If interactive input is enabled, we might gather some more variable // values through interactive prompts. // TODO: Need to route the operation context through into here, so that // the interactive prompts can be sensitive to its timeouts/etc. - rawVariables = b.interactiveCollectVariables(context.TODO(), op.Variables, config.Module.Variables, op.UIIn) + rawVariables = b.interactiveCollectVariables(context.TODO(), op.Variables, rootMod.Variables, op.UIIn) } - variables, varDiags := backendrun.ParseVariableValues(rawVariables, config.Module.Variables) + variables, varDiags := backendrun.ParseVariableValues(rawVariables, rootMod.Variables) diags = diags.Append(varDiags) if diags.HasErrors() { return nil, nil, diags @@ -224,6 +196,52 @@ func (b *Local) localRunDirect(op *backendrun.Operation, run *backendrun.LocalRu return nil, nil, diags } run.Core = tfCtx + + walkerSnapshot, configSnap := op.ConfigLoader.ModuleWalkerSnapshot() + config, buildDiags := terraform.BuildConfigWithGraph( + rootMod, + walkerSnapshot, + variables, + configs.MockDataLoaderFunc(op.ConfigLoader.LoadExternalMockData), + ) + diags = diags.Append(buildDiags) + if buildDiags.HasErrors() { + return nil, nil, diags + } + run.Config = config + + snapDiags := op.ConfigLoader.AddRootModuleToSnapshot(configSnap, op.ConfigDir) + diags = diags.Append(snapDiags) + if snapDiags.HasErrors() { + return nil, nil, diags + } + + if errs := config.VerifyDependencySelections(op.DependencyLocks); len(errs) > 0 { + var buf strings.Builder + for _, err := range errs { + fmt.Fprintf(&buf, "\n - %s", err.Error()) + } + var suggestion string + switch { + case op.DependencyLocks == nil: + // If we get here then it suggests that there's a caller that we + // didn't yet update to populate DependencyLocks, which is a bug. + suggestion = "This run has no dependency lock information provided at all, which is a bug in Terraform; please report it!" + case op.DependencyLocks.Empty(): + suggestion = "To make the initial dependency selections that will initialize the dependency lock file, run:\n terraform init" + default: + suggestion = "To update the locked dependency selections to match a changed configuration, run:\n terraform init -upgrade" + } + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Inconsistent dependency lock file", + fmt.Sprintf( + "The following dependency selections recorded in the lock file are inconsistent with the current configuration:%s\n\n%s", + buf.String(), suggestion, + ), + )) + } + return run, configSnap, diags } @@ -235,6 +253,7 @@ func (b *Local) localRunForPlanFile(op *backendrun.Operation, pf *planfile.Reade // A plan file has a snapshot of configuration embedded inside it, which // is used instead of whatever configuration might be already present // in the filesystem. + //TODO why not use pf.ReadConfig? snap, err := pf.ReadConfigSnapshot() if err != nil { diags = diags.Append(tfdiags.Sourceless( @@ -246,32 +265,16 @@ func (b *Local) localRunForPlanFile(op *backendrun.Operation, pf *planfile.Reade } loader := configload.NewLoaderFromSnapshot(snap) loader.AllowLanguageExperiments(op.ConfigLoader.AllowsLanguageExperiments()) - config, configDiags := loader.LoadConfig(snap.Modules[""].Dir) - diags = diags.Append(configDiags) - if configDiags.HasErrors() { - return nil, snap, diags + rootMod, rootDiags := loader.LoadRootModule(snap.Modules[""].Dir) + diags = diags.Append(rootDiags) + if rootDiags.HasErrors() { + return nil, nil, diags } - run.Config = config - // NOTE: We're intentionally comparing the current locks with the - // configuration snapshot, rather than the lock snapshot in the plan file, - // because it's the current locks which dictate our plugin selections - // in coreOpts below. However, we'll also separately check that the - // plan file has identical locked plugins below, and thus we're effectively - // checking consistency with both here. - if errs := config.VerifyDependencySelections(op.DependencyLocks); len(errs) > 0 { - var buf strings.Builder - for _, err := range errs { - fmt.Fprintf(&buf, "\n - %s", err.Error()) - } - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Inconsistent dependency lock file", - fmt.Sprintf( - "The following dependency selections recorded in the lock file are inconsistent with the configuration in the saved plan:%s\n\nA saved plan can be applied only to the same configuration it was created from. Create a new plan from the updated configuration.", - buf.String(), - ), - )) + variables, varDiags := backendrun.ParseVariableValues(op.Variables, rootMod.Variables) + diags = diags.Append(varDiags) + if diags.HasErrors() { + return nil, nil, diags } // This check is an important complement to the check above: the locked @@ -359,6 +362,40 @@ func (b *Local) localRunForPlanFile(op *backendrun.Operation, pf *planfile.Reade return nil, nil, diags } run.Core = tfCtx + + config, buildDiags := terraform.BuildConfigWithGraph( + rootMod, + loader.ModuleWalker(), + variables, + configs.MockDataLoaderFunc(loader.LoadExternalMockData), + ) + diags = diags.Append(buildDiags) + if buildDiags.HasErrors() { + return nil, nil, diags + } + run.Config = config + + // NOTE: We're intentionally comparing the current locks with the + // configuration snapshot, rather than the lock snapshot in the plan file, + // because it's the current locks which dictate our plugin selections + // in coreOpts below. However, we'll also separately check that the + // plan file has identical locked plugins below, and thus we're effectively + // checking consistency with both here. + if errs := config.VerifyDependencySelections(op.DependencyLocks); len(errs) > 0 { + var buf strings.Builder + for _, err := range errs { + fmt.Fprintf(&buf, "\n - %s", err.Error()) + } + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Inconsistent dependency lock file", + fmt.Sprintf( + "The following dependency selections recorded in the lock file are inconsistent with the configuration in the saved plan:%s\n\nA saved plan can be applied only to the same configuration it was created from. Create a new plan from the updated configuration.", + buf.String(), + ), + )) + } + return run, snap, diags } diff --git a/internal/backend/remote/backend_common.go b/internal/backend/remote/backend_common.go index 85d42ae879..137c01aa41 100644 --- a/internal/backend/remote/backend_common.go +++ b/internal/backend/remote/backend_common.go @@ -249,11 +249,8 @@ func (b *Remote) waitForRun(stopCtx, cancelCtx context.Context, op *backendrun.O // remote system's responsibility to do final validation of the input. func (b *Remote) hasExplicitVariableValues(op *backendrun.Operation) bool { // Load the configuration using the caller-provided configuration loader. - config, _, configDiags := op.ConfigLoader.LoadConfigWithSnapshot(op.ConfigDir) + config, configDiags := op.ConfigLoader.LoadRootModule(op.ConfigDir) if configDiags.HasErrors() { - // If we can't load the configuration then we'll assume no explicit - // variable values just to let the remote operation start and let - // the remote system return the same set of configuration errors. return false } @@ -262,7 +259,7 @@ func (b *Remote) hasExplicitVariableValues(op *backendrun.Operation) bool { // goal here is just to make a best effort count of how many variable // values are coming from -var or -var-file CLI arguments so that we can // hint the user that those are not supported for remote operations. - variables, _ := backendrun.ParseVariableValues(op.Variables, config.Module.Variables) + variables, _ := backendrun.ParseVariableValues(op.Variables, config.Variables) // Check for explicitly-defined (-var and -var-file) variables, which the // remote backend does not support. All other source types are okay, diff --git a/internal/backend/remote/backend_context.go b/internal/backend/remote/backend_context.go index bf7ec7190d..db72d709ed 100644 --- a/internal/backend/remote/backend_context.go +++ b/internal/backend/remote/backend_context.go @@ -81,19 +81,18 @@ func (b *Remote) LocalRun(op *backendrun.Operation) (*backendrun.LocalRun, state ret.InputState = stateMgr.State() log.Printf("[TRACE] backend/remote: loading configuration for the current working directory") - config, configDiags := op.ConfigLoader.LoadConfig(op.ConfigDir) + rootMod, configDiags := op.ConfigLoader.LoadRootModule(op.ConfigDir) diags = diags.Append(configDiags) if configDiags.HasErrors() { return nil, nil, diags } - ret.Config = config if op.AllowUnsetVariables { // If we're not going to use the variables in an operation we'll be // more lax about them, stubbing out any unset ones as unknown. // This gives us enough information to produce a consistent context, // but not enough information to run a real operation (plan, apply, etc) - ret.PlanOpts.SetVariables = stubAllVariables(op.Variables, config.Module.Variables) + ret.PlanOpts.SetVariables = stubAllVariables(op.Variables, rootMod.Variables) } else { // The underlying API expects us to use the opaque workspace id to request // variables, so we'll need to look that up using our organization name @@ -136,7 +135,7 @@ func (b *Remote) LocalRun(op *backendrun.Operation) (*backendrun.LocalRun, state } if op.Variables != nil { - variables, varDiags := backendrun.ParseVariableValues(op.Variables, config.Module.Variables) + variables, varDiags := backendrun.ParseVariableValues(op.Variables, rootMod.Variables) diags = diags.Append(varDiags) if diags.HasErrors() { return nil, nil, diags @@ -148,6 +147,24 @@ func (b *Remote) LocalRun(op *backendrun.Operation) (*backendrun.LocalRun, state tfCtx, ctxDiags := terraform.NewContext(&opts) diags = diags.Append(ctxDiags) ret.Core = tfCtx + if diags.HasErrors() { + return nil, nil, diags + } + + log.Printf("[TRACE] backend/remote: building configuration for the current working directory") + + config, buildDiags := terraform.BuildConfigWithGraph( + rootMod, + op.ConfigLoader.ModuleWalker(), + ret.PlanOpts.SetVariables, + configs.MockDataLoaderFunc(op.ConfigLoader.LoadExternalMockData), + ) + diags = diags.Append(buildDiags) + if diags.HasErrors() { + return nil, nil, diags + } + + ret.Config = config log.Printf("[TRACE] backend/remote: finished building terraform.Context") diff --git a/internal/checks/state_test.go b/internal/checks/state_test.go index 2e5a30a30d..276f6dc62c 100644 --- a/internal/checks/state_test.go +++ b/internal/checks/state_test.go @@ -18,7 +18,7 @@ func TestChecksHappyPath(t *testing.T) { const fixtureDir = "testdata/happypath" loader, close := configload.NewLoaderForTests(t) defer close() - inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, nil) + inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, nil, nil) _, instDiags := inst.InstallModules(context.Background(), fixtureDir, "tests", true, false, initwd.ModuleInstallHooksImpl{}) if instDiags.HasErrors() { t.Fatal(instDiags.Err()) @@ -29,7 +29,7 @@ func TestChecksHappyPath(t *testing.T) { ///////////////////////////////////////////////////////////////////////// - cfg, hclDiags := loader.LoadConfig(fixtureDir) + cfg, hclDiags := loader.LoadStaticConfig(fixtureDir) if hclDiags.HasErrors() { t.Fatalf("invalid configuration: %s", hclDiags.Error()) } diff --git a/internal/cloud/backend_common.go b/internal/cloud/backend_common.go index 360da2a08b..b4f98ef2d0 100644 --- a/internal/cloud/backend_common.go +++ b/internal/cloud/backend_common.go @@ -654,12 +654,12 @@ in order to capture the filesystem context the remote workspace expects: } func (b *Cloud) parseRunVariables(op *backendrun.Operation) ([]*tfe.RunVariable, error) { - config, _, configDiags := op.ConfigLoader.LoadConfigWithSnapshot(op.ConfigDir) + config, configDiags := op.ConfigLoader.LoadRootModule(op.ConfigDir) if configDiags.HasErrors() { return nil, fmt.Errorf("error loading config with snapshot: %w", configDiags.Errs()[0]) } - variables, varDiags := ParseCloudRunVariables(op.Variables, config.Module.Variables) + variables, varDiags := ParseCloudRunVariables(op.Variables, config.Variables) if varDiags.HasErrors() { return nil, varDiags.Err() diff --git a/internal/cloud/backend_context.go b/internal/cloud/backend_context.go index 36f9ab1e3a..e3fc587a33 100644 --- a/internal/cloud/backend_context.go +++ b/internal/cloud/backend_context.go @@ -79,20 +79,19 @@ func (b *Cloud) LocalRun(op *backendrun.Operation) (*backendrun.LocalRun, statem log.Printf("[TRACE] cloud: retrieving remote state snapshot for workspace %q", remoteWorkspaceName) ret.InputState = stateMgr.State() - log.Printf("[TRACE] cloud: loading configuration for the current working directory") - config, configDiags := op.ConfigLoader.LoadConfig(op.ConfigDir) + log.Printf("[TRACE] cloud: loading root module for the current working directory") + rootMod, configDiags := op.ConfigLoader.LoadRootModule(op.ConfigDir) diags = diags.Append(configDiags) if configDiags.HasErrors() { return nil, nil, diags } - ret.Config = config if op.AllowUnsetVariables { // If we're not going to use the variables in an operation we'll be // more lax about them, stubbing out any unset ones as unknown. // This gives us enough information to produce a consistent context, // but not enough information to run a real operation (plan, apply, etc) - ret.PlanOpts.SetVariables = stubAllVariables(op.Variables, config.Module.Variables) + ret.PlanOpts.SetVariables = stubAllVariables(op.Variables, rootMod.Variables) } else { // The underlying API expects us to use the opaque workspace id to request // variables, so we'll need to look that up using our organization name @@ -136,7 +135,7 @@ func (b *Cloud) LocalRun(op *backendrun.Operation) (*backendrun.LocalRun, statem } if op.Variables != nil { - variables, varDiags := backendrun.ParseVariableValues(op.Variables, config.Module.Variables) + variables, varDiags := backendrun.ParseVariableValues(op.Variables, rootMod.Variables) diags = diags.Append(varDiags) if diags.HasErrors() { return nil, nil, diags @@ -148,6 +147,24 @@ func (b *Cloud) LocalRun(op *backendrun.Operation) (*backendrun.LocalRun, statem tfCtx, ctxDiags := terraform.NewContext(&opts) diags = diags.Append(ctxDiags) ret.Core = tfCtx + if diags.HasErrors() { + return nil, nil, diags + } + + log.Printf("[TRACE] cloud: building configuration for the current working directory") + + config, buildDiags := terraform.BuildConfigWithGraph( + rootMod, + op.ConfigLoader.ModuleWalker(), + ret.PlanOpts.SetVariables, + configs.MockDataLoaderFunc(op.ConfigLoader.LoadExternalMockData), + ) + diags = diags.Append(buildDiags) + if diags.HasErrors() { + return nil, nil, diags + } + + ret.Config = config log.Printf("[TRACE] cloud: finished building terraform.Context") diff --git a/internal/cloud/test_test.go b/internal/cloud/test_test.go index d3a97372bc..ca1971ff7e 100644 --- a/internal/cloud/test_test.go +++ b/internal/cloud/test_test.go @@ -267,7 +267,7 @@ func TestTest_Verbose(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - config, configDiags := loader.LoadConfigWithTests(directory, "tests") + config, configDiags := loader.LoadStaticConfigWithTests(directory, "tests") if configDiags.HasErrors() { t.Fatalf("failed to load config: %v", configDiags.Error()) } @@ -664,7 +664,7 @@ func TestTest_ForceCancel(t *testing.T) { loader, close := configload.NewLoaderForTests(t) defer close() - config, configDiags := loader.LoadConfigWithTests("testdata/test-force-cancel", "tests") + config, configDiags := loader.LoadStaticConfigWithTests("testdata/test-force-cancel", "tests") if configDiags.HasErrors() { t.Fatalf("failed to load config: %v", configDiags.Error()) } diff --git a/internal/command/apply.go b/internal/command/apply.go index 1fa43cf950..29cfb7698e 100644 --- a/internal/command/apply.go +++ b/internal/command/apply.go @@ -359,7 +359,7 @@ Options: Defaults to 10. -replace=resource Terraform will plan to replace this resource instance - instead of doing an update or no-op action. + instead of doing an update or no-op action. -state=path Path to read and save state (unless state-out is specified). Defaults to "terraform.tfstate". @@ -372,7 +372,7 @@ Options: Legacy option for the local backend only. See the local backend's documentation for more information. - + -var 'foo=bar' Set a value for one of the input variables in the root module of the configuration. Use this option more than once to set more than one variable. diff --git a/internal/command/command_test.go b/internal/command/command_test.go index 6be429ba62..8eecaf1ef2 100644 --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -50,6 +50,7 @@ import ( "github.com/hashicorp/terraform/internal/states/statefile" "github.com/hashicorp/terraform/internal/states/statemgr" "github.com/hashicorp/terraform/internal/terminal" + "github.com/hashicorp/terraform/internal/terraform" "github.com/hashicorp/terraform/version" ) @@ -158,15 +159,31 @@ func testModuleWithSnapshot(t *testing.T, name string) (*configs.Config, *config // Test modules usually do not refer to remote sources, and for local // sources only this ultimately just records all of the module paths // in a JSON file so that we can load them below. - inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil)) + inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil), nil) _, instDiags := inst.InstallModules(context.Background(), dir, "tests", true, false, initwd.ModuleInstallHooksImpl{}) if instDiags.HasErrors() { t.Fatal(instDiags.Err()) } - config, snap, diags := loader.LoadConfigWithSnapshot(dir) - if diags.HasErrors() { - t.Fatal(diags.Error()) + rootMod, configDiags := loader.LoadRootModule(dir) + if configDiags.HasErrors() { + t.Fatal(configDiags.Error()) + } + + walkerSnapshot, snap := loader.ModuleWalkerSnapshot() + config, buildDiags := terraform.BuildConfigWithGraph( + rootMod, + walkerSnapshot, + nil, + configs.MockDataLoaderFunc(loader.LoadExternalMockData), + ) + if buildDiags.HasErrors() { + t.Fatal(buildDiags.Err()) + } + + snapDiags := loader.AddRootModuleToSnapshot(snap, dir) + if snapDiags.HasErrors() { + t.Fatal(snapDiags.Error()) } return config, snap diff --git a/internal/command/graph_test.go b/internal/command/graph_test.go index 97bdc78621..9490ed130c 100644 --- a/internal/command/graph_test.go +++ b/internal/command/graph_test.go @@ -224,7 +224,7 @@ func TestGraph_resourcesOnly(t *testing.T) { if err != nil { t.Fatal(err) } - inst := initwd.NewModuleInstaller(".terraform/modules", loader, registry.NewClient(nil, nil)) + inst := initwd.NewModuleInstaller(".terraform/modules", loader, registry.NewClient(nil, nil), nil) _, instDiags := inst.InstallModules(context.Background(), ".", "tests", true, false, initwd.ModuleInstallHooksImpl{}) if instDiags.HasErrors() { t.Fatal(instDiags.Err()) diff --git a/internal/command/init2_test.go b/internal/command/init2_test.go new file mode 100644 index 0000000000..9dcfcf50c4 --- /dev/null +++ b/internal/command/init2_test.go @@ -0,0 +1,101 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package command + +import ( + "path/filepath" + "strings" + "testing" + + "github.com/hashicorp/cli" +) + +func TestInit2_versionConstraintAdded(t *testing.T) { + // This test is for what happens when there is a version constraint added + // to a module that previously didn't have one. + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "add-version-constraint")), td) + t.Chdir(td) + + ui := new(cli.MockUi) + view, done := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } + + args := []string{"-get=false"} + code := c.Run(args) + testOutput := done(t) + if code != 1 { + t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) + } + got := testOutput.All() + + want := "Module version requirements have changed" + if !strings.Contains(got, want) { + t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want) + } +} + +func TestInit2_invalidRegistrySourceWithModule(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "invalid-registry-source-with-module")), td) + t.Chdir(td) + + ui := new(cli.MockUi) + view, done := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } + + args := []string{} + code := c.Run(args) + testOutput := done(t) + if code != 1 { + t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) + } + got := testOutput.All() + + want := "Invalid registry module source address" + if !strings.Contains(got, want) { + t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want) + } +} + +func TestInit2_localSourceWithVersion(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "local-source-with-version")), td) + t.Chdir(td) + + ui := new(cli.MockUi) + view, done := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } + + args := []string{} + code := c.Run(args) + testOutput := done(t) + if code != 1 { + t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) + } + got := testOutput.All() + + want := "Invalid registry module source address" + if !strings.Contains(got, want) { + t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want) + } +} diff --git a/internal/command/meta.go b/internal/command/meta.go index cebd76f7f8..bbdf4ed09f 100644 --- a/internal/command/meta.go +++ b/internal/command/meta.go @@ -825,12 +825,6 @@ func (m *Meta) applyStateArguments(args *arguments.State) { func (m *Meta) checkRequiredVersion() tfdiags.Diagnostics { var diags tfdiags.Diagnostics - loader, err := m.initConfigLoader() - if err != nil { - diags = diags.Append(err) - return diags - } - pwd, err := os.Getwd() if err != nil { diags = diags.Append(fmt.Errorf("Error getting pwd: %s", err)) diff --git a/internal/command/meta_config.go b/internal/command/meta_config.go index c99898d74f..15b56cc2ee 100644 --- a/internal/command/meta_config.go +++ b/internal/command/meta_config.go @@ -17,6 +17,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" + "github.com/hashicorp/terraform/internal/backend/backendrun" "github.com/hashicorp/terraform/internal/configs" "github.com/hashicorp/terraform/internal/configs/configload" "github.com/hashicorp/terraform/internal/configs/configschema" @@ -48,8 +49,28 @@ func (m *Meta) loadConfig(rootDir string) (*configs.Config, tfdiags.Diagnostics) return nil, diags } - config, hclDiags := loader.LoadConfig(rootDir) + rootMod, hclDiags := loader.LoadRootModule(rootDir) diags = diags.Append(hclDiags) + if rootMod == nil || diags.HasErrors() { + cfg := &configs.Config{ + Module: rootMod, + } + cfg.Root = cfg // Root module is self-referential. + return cfg, diags + } + betterVars, parseDiags := backendrun.ParseVariableValues(m.VariableValues, rootMod.Variables) + diags = diags.Append(parseDiags) + if parseDiags.HasErrors() { + return nil, diags + } + config, buildDiags := terraform.BuildConfigWithGraph( + rootMod, + loader.ModuleWalker(), + betterVars, + configs.MockDataLoaderFunc(loader.LoadExternalMockData), + ) + diags = diags.Append(buildDiags) + return config, diags } @@ -65,8 +86,28 @@ func (m *Meta) loadConfigWithTests(rootDir, testDir string) (*configs.Config, tf return nil, diags } - config, hclDiags := loader.LoadConfigWithTests(rootDir, testDir) + rootMod, hclDiags := loader.LoadRootModuleWithTests(rootDir, testDir) diags = diags.Append(hclDiags) + if rootMod == nil || diags.HasErrors() { + cfg := &configs.Config{ + Module: rootMod, + } + cfg.Root = cfg // Root module is self-referential. + return cfg, diags + } + betterVars, parseDiags := backendrun.ParseConstVariableValues(m.VariableValues, rootMod.Variables) + diags = diags.Append(parseDiags) + if parseDiags.HasErrors() { + return nil, diags + } + config, buildDiags := terraform.BuildConfigWithGraph( + rootMod, + loader.ModuleWalker(), + betterVars, + configs.MockDataLoaderFunc(loader.LoadExternalMockData), + ) + diags = diags.Append(buildDiags) + return config, diags } diff --git a/internal/command/test_test.go b/internal/command/test_test.go index 92adc85738..01d3f548de 100644 --- a/internal/command/test_test.go +++ b/internal/command/test_test.go @@ -5707,7 +5707,7 @@ func testModuleInline(t *testing.T, sources map[string]string) (*configs.Config, // Test modules usually do not refer to remote sources, and for local // sources only this ultimately just records all of the module paths // in a JSON file so that we can load them below. - inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil)) + inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil), nil) _, instDiags := inst.InstallModules(context.Background(), cfgPath, "tests", true, false, initwd.ModuleInstallHooksImpl{}) if instDiags.HasErrors() { t.Fatal(instDiags.Err()) @@ -5719,7 +5719,7 @@ func testModuleInline(t *testing.T, sources map[string]string) (*configs.Config, t.Fatalf("failed to refresh modules after installation: %s", err) } - config, diags := loader.LoadConfigWithTests(cfgPath, "tests") + config, diags := loader.LoadStaticConfigWithTests(cfgPath, "tests") if diags.HasErrors() { t.Fatal(diags.Error()) } diff --git a/internal/configs/configload/testdata/add-version-constraint/.terraform/modules/child/empty.tf b/internal/command/testdata/dynamic-module-sources/add-version-constraint/.terraform/modules/child/empty.tf similarity index 100% rename from internal/configs/configload/testdata/add-version-constraint/.terraform/modules/child/empty.tf rename to internal/command/testdata/dynamic-module-sources/add-version-constraint/.terraform/modules/child/empty.tf diff --git a/internal/configs/configload/testdata/add-version-constraint/.terraform/modules/modules.json b/internal/command/testdata/dynamic-module-sources/add-version-constraint/.terraform/modules/modules.json similarity index 61% rename from internal/configs/configload/testdata/add-version-constraint/.terraform/modules/modules.json rename to internal/command/testdata/dynamic-module-sources/add-version-constraint/.terraform/modules/modules.json index c02f40016b..a55de19395 100644 --- a/internal/configs/configload/testdata/add-version-constraint/.terraform/modules/modules.json +++ b/internal/command/testdata/dynamic-module-sources/add-version-constraint/.terraform/modules/modules.json @@ -3,12 +3,12 @@ { "Key": "", "Source": "", - "Dir": "testdata/add-version-constraint" + "Dir": "" }, { "Key": "child", "Source": "hashicorp/module-installer-acctest/aws", - "Dir": "testdata/add-version-constraint/.terraform/modules/child" + "Dir": ".terraform/modules/child" } ] } diff --git a/internal/configs/configload/testdata/add-version-constraint/add-version-constraint.tf b/internal/command/testdata/dynamic-module-sources/add-version-constraint/add-version-constraint.tf similarity index 100% rename from internal/configs/configload/testdata/add-version-constraint/add-version-constraint.tf rename to internal/command/testdata/dynamic-module-sources/add-version-constraint/add-version-constraint.tf diff --git a/internal/configs/testdata/error-files/module-local-source-with-version.tf b/internal/command/testdata/dynamic-module-sources/invalid-registry-source-with-module/main.tf similarity index 57% rename from internal/configs/testdata/error-files/module-local-source-with-version.tf rename to internal/command/testdata/dynamic-module-sources/invalid-registry-source-with-module/main.tf index f570d65fe9..99036006e8 100644 --- a/internal/configs/testdata/error-files/module-local-source-with-version.tf +++ b/internal/command/testdata/dynamic-module-sources/invalid-registry-source-with-module/main.tf @@ -1,5 +1,5 @@ module "test" { - source = "../boop" # ERROR: Invalid registry module source address + source = "---.com/HashiCorp/Consul/aws" version = "1.0.0" # Makes Terraform assume "source" is a module address } diff --git a/internal/configs/testdata/error-files/module-invalid-registry-source-with-module.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-version/main.tf similarity index 50% rename from internal/configs/testdata/error-files/module-invalid-registry-source-with-module.tf rename to internal/command/testdata/dynamic-module-sources/local-source-with-version/main.tf index 0029be8f4a..6ff0bcd606 100644 --- a/internal/configs/testdata/error-files/module-invalid-registry-source-with-module.tf +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-version/main.tf @@ -1,5 +1,5 @@ module "test" { - source = "---.com/HashiCorp/Consul/aws" # ERROR: Invalid registry module source address + source = "../boop" version = "1.0.0" # Makes Terraform assume "source" is a module address } diff --git a/internal/command/validate_test.go b/internal/command/validate_test.go index 9270066ee9..3e4ef667e9 100644 --- a/internal/command/validate_test.go +++ b/internal/command/validate_test.go @@ -5,7 +5,7 @@ package command import ( "encoding/json" - "io/ioutil" + "io" "os" "path" "strings" @@ -190,10 +190,6 @@ func TestModuleWithIncorrectNameShouldFail(t *testing.T) { if !strings.Contains(output.Stderr(), wantError) { t.Fatalf("Missing error string %q\n\n'%s'", wantError, output.Stderr()) } - wantError = `Error: Variables not allowed` - if !strings.Contains(output.Stderr(), wantError) { - t.Fatalf("Missing error string %q\n\n'%s'", wantError, output.Stderr()) - } } func TestWronglyUsedInterpolationShouldFail(t *testing.T) { @@ -406,14 +402,14 @@ func TestValidate_json(t *testing.T) { for _, tc := range tests { t.Run(tc.path, func(t *testing.T) { - var want, got map[string]interface{} + var want, got map[string]any wantFile, err := os.Open(path.Join(testFixturePath(tc.path), "output.json")) if err != nil { t.Fatalf("failed to open output file: %s", err) } defer wantFile.Close() - wantBytes, err := ioutil.ReadAll(wantFile) + wantBytes, err := io.ReadAll(wantFile) if err != nil { t.Fatalf("failed to read output file: %s", err) } diff --git a/internal/configs/config_build.go b/internal/configs/config_build.go index 28e522d226..84abf6df3b 100644 --- a/internal/configs/config_build.go +++ b/internal/configs/config_build.go @@ -12,8 +12,10 @@ import ( version "github.com/hashicorp/go-version" "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/gohcl" "github.com/hashicorp/terraform/internal/addrs" + "github.com/hashicorp/terraform/internal/getmodules/moduleaddrs" ) // BuildConfig constructs a Config from a root module by loading all of its @@ -32,6 +34,20 @@ func BuildConfig(root *Module, walker ModuleWalker, loader MockDataLoader) (*Con } cfg.Root = cfg // Root module is self-referential. cfg.Children, diags = buildChildModules(cfg, walker) + diags = append(diags, FinalizeConfig(cfg, walker, loader)...) + + return cfg, diags +} + +// FinalizeConfig performs the post-load validation and setup steps that are +// shared by different configuration loaders. +// +// Callers must ensure cfg.Root is set correctly before calling this function. +func FinalizeConfig(cfg *Config, walker ModuleWalker, loader MockDataLoader) hcl.Diagnostics { + var diags hcl.Diagnostics + if cfg == nil { + return diags + } diags = append(diags, buildTestModules(cfg, walker)...) // Skip provider resolution if there are any errors, since the provider @@ -42,7 +58,7 @@ func BuildConfig(root *Module, walker ModuleWalker, loader MockDataLoader) (*Con providers := cfg.resolveProviderTypes() cfg.resolveProviderTypesForTests(providers) - if cfg.Module.StateStore != nil { + if cfg.Module != nil && cfg.Module.StateStore != nil { stateProviderDiags := cfg.resolveStateStoreProviderType() diags = append(diags, stateProviderDiags...) } @@ -54,7 +70,7 @@ func BuildConfig(root *Module, walker ModuleWalker, loader MockDataLoader) (*Con // Final step, let's side load any external mock data into our test files. diags = append(diags, installMockDataFiles(cfg, loader)...) - return cfg, diags + return diags } func installMockDataFiles(root *Config, loader MockDataLoader) hcl.Diagnostics { @@ -148,6 +164,108 @@ func buildTestModules(root *Config, walker ModuleWalker) hcl.Diagnostics { return diags } +// legacySourceHelper is used to decode module sources from the old-style +// string-only "source". It assumes that the expression does not contain any +// references and can be decoded without an evaluation context. +// In the long term, we want to get rid of this helper method. +func legacySourceHelper(expr hcl.Expression, haveVersionArg bool) (addrs.ModuleSource, hcl.Diagnostics) { + var diags hcl.Diagnostics + var sourceAddrRaw string + var addr addrs.ModuleSource + + valDiags := gohcl.DecodeExpression(expr, nil, &sourceAddrRaw) + diags = append(diags, valDiags...) + if !valDiags.HasErrors() { + var err error + if haveVersionArg { + addr, err = moduleaddrs.ParseModuleSourceRegistry(sourceAddrRaw) + } else { + addr, err = moduleaddrs.ParseModuleSource(sourceAddrRaw) + } + if err != nil { + // NOTE: We leave addr as nil for any situation where the + // source attribute is invalid, so any code which tries to carefully + // use the partial result of a failed config decode must be + // resilient to that. + addr = nil + + // NOTE: In practice it's actually very unlikely to end up here, + // because our source address parser can turn just about any string + // into some sort of remote package address, and so for most errors + // we'll detect them only during module installation. There are + // still a _few_ purely-syntax errors we can catch at parsing time, + // though, mostly related to remote package sub-paths and local + // paths. + switch err := err.(type) { + case *moduleaddrs.MaybeRelativePathErr: + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source address", + Detail: fmt.Sprintf( + "Terraform failed to determine your intended installation method for remote module package %q.\n\nIf you intended this as a path relative to the current module, use \"./%s\" instead. The \"./\" prefix indicates that the address is a relative filesystem path.", + err.Addr, err.Addr, + ), + Subject: expr.Range().Ptr(), + }) + default: + if haveVersionArg { + // In this case we'll include some extra context that + // we assumed a registry source address due to the + // version argument. + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid registry module source address", + Detail: fmt.Sprintf("Failed to parse module registry address: %s.\n\nTerraform assumed that you intended a module registry source address because you also set the argument \"version\", which applies only to registry modules.", err), + Subject: expr.Range().Ptr(), + }) + } else { + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid module source address", + Detail: fmt.Sprintf("Failed to parse module source address: %s.", err), + Subject: expr.Range().Ptr(), + }) + } + } + } + } + + return addr, diags +} + +// legacyVersionHelper is used to decode version constraints from the old-style +// string-only "version". It assumes that the expression does not contain any +// references and can be decoded without an evaluation context. +// In the long term, we want to get rid of this helper method. +func legacyVersionHelper(expr hcl.Expression) (VersionConstraint, hcl.Diagnostics) { + var diags hcl.Diagnostics + var versionRaw string + + ret := VersionConstraint{ + DeclRange: expr.Range(), + } + + valDiags := gohcl.DecodeExpression(expr, nil, &versionRaw) + diags = append(diags, valDiags...) + if !valDiags.HasErrors() { + constraints, err := version.NewConstraint(versionRaw) + if err != nil { + // NewConstraint doesn't return user-friendly errors, so we'll just + // ignore the provided error and produce our own generic one. + diags = append(diags, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid version constraint", + Detail: "This string does not use correct version constraint syntax.", // Not very actionable :( + Subject: expr.Range().Ptr(), + }) + return ret, diags + } + ret.Required = constraints + } + + return ret, diags +} + func buildChildModules(parent *Config, walker ModuleWalker) (map[string]*Config, hcl.Diagnostics) { var diags hcl.Diagnostics ret := map[string]*Config{} @@ -161,12 +279,28 @@ func buildChildModules(parent *Config, walker ModuleWalker) (map[string]*Config, path := slices.Clone(parent.Path) path = append(path, call.Name) + sourceAddr, sourceDiags := legacySourceHelper(call.SourceExpr, call.VersionExpr != nil) + diags = append(diags, sourceDiags...) + if sourceDiags.HasErrors() { + continue + } + + var versionConstraint VersionConstraint + if call.VersionExpr != nil { + var versionDiags hcl.Diagnostics + versionConstraint, versionDiags = legacyVersionHelper(call.VersionExpr) + diags = append(diags, versionDiags...) + if versionDiags.HasErrors() { + continue + } + } + req := ModuleRequest{ Name: call.Name, Path: path, - SourceAddr: call.SourceAddr, - SourceAddrRange: call.SourceAddrRange, - VersionConstraint: call.Version, + SourceAddr: sourceAddr, + SourceAddrRange: call.SourceExpr.Range(), + VersionConstraint: versionConstraint, Parent: parent, CallRange: call.DeclRange, } diff --git a/internal/configs/configload/loader.go b/internal/configs/configload/loader.go index 11be47b02f..06becad468 100644 --- a/internal/configs/configload/loader.go +++ b/internal/configs/configload/loader.go @@ -187,3 +187,8 @@ func (l *Loader) AllowLanguageExperiments(allowed bool) { func (l *Loader) AllowsLanguageExperiments() bool { return l.parser.AllowsLanguageExperiments() } + +// ModuleWalker returns a walker suitable for loading already-installed modules. +func (l *Loader) ModuleWalker() configs.ModuleWalker { + return configs.ModuleWalkerFunc(l.moduleWalkerLoad) +} diff --git a/internal/configs/configload/loader_load.go b/internal/configs/configload/loader_load.go index 236575dcd2..5fbe017915 100644 --- a/internal/configs/configload/loader_load.go +++ b/internal/configs/configload/loader_load.go @@ -22,16 +22,26 @@ import ( // // LoadConfig performs the basic syntax and uniqueness validations that are // required to process the individual modules -func (l *Loader) LoadConfig(rootDir string) (*configs.Config, hcl.Diagnostics) { +func (l *Loader) LoadStaticConfig(rootDir string) (*configs.Config, hcl.Diagnostics) { return l.loadConfig(l.parser.LoadConfigDir(rootDir, l.parserOpts...)) } // LoadConfigWithTests matches LoadConfig, except the configs.Config contains // any relevant .tftest.hcl files. -func (l *Loader) LoadConfigWithTests(rootDir string, testDir string) (*configs.Config, hcl.Diagnostics) { +func (l *Loader) LoadStaticConfigWithTests(rootDir string, testDir string) (*configs.Config, hcl.Diagnostics) { return l.loadConfig(l.parser.LoadConfigDir(rootDir, append(l.parserOpts, configs.MatchTestFiles(testDir))...)) } +// LoadRootModule reads the root module using the loader's parser options. +func (l *Loader) LoadRootModule(rootDir string) (*configs.Module, hcl.Diagnostics) { + return l.parser.LoadConfigDir(rootDir, l.parserOpts...) +} + +// LoadRootModuleWithTests reads the root module and includes test files from the given directory. +func (l *Loader) LoadRootModuleWithTests(rootDir string, testDir string) (*configs.Module, hcl.Diagnostics) { + return l.parser.LoadConfigDir(rootDir, append(l.parserOpts, configs.MatchTestFiles(testDir))...) +} + func (l *Loader) loadConfig(rootMod *configs.Module, diags hcl.Diagnostics) (*configs.Config, hcl.Diagnostics) { if rootMod == nil || diags.HasErrors() { // Ensure we return any parsed modules here so that required_version diff --git a/internal/configs/configload/loader_load_test.go b/internal/configs/configload/loader_load_test.go index 22fadb6249..b81814960e 100644 --- a/internal/configs/configload/loader_load_test.go +++ b/internal/configs/configload/loader_load_test.go @@ -25,7 +25,7 @@ func TestLoaderLoadConfig_okay(t *testing.T) { t.Fatalf("unexpected error from NewLoader: %s", err) } - cfg, diags := loader.LoadConfig(fixtureDir) + cfg, diags := loader.LoadStaticConfig(fixtureDir) assertNoDiagnostics(t, diags) if cfg == nil { t.Fatalf("config is nil; want non-nil") @@ -62,28 +62,6 @@ func TestLoaderLoadConfig_okay(t *testing.T) { }) } -func TestLoaderLoadConfig_addVersion(t *testing.T) { - // This test is for what happens when there is a version constraint added - // to a module that previously didn't have one. - fixtureDir := filepath.Clean("testdata/add-version-constraint") - loader, err := NewLoader(&Config{ - ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), - }) - if err != nil { - t.Fatalf("unexpected error from NewLoader: %s", err) - } - - _, diags := loader.LoadConfig(fixtureDir) - if !diags.HasErrors() { - t.Fatalf("success; want error") - } - got := diags.Error() - want := "Module version requirements have changed" - if !strings.Contains(got, want) { - t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want) - } -} - func TestLoaderLoadConfig_loadDiags(t *testing.T) { // building a config which didn't load correctly may cause configs to panic fixtureDir := filepath.Clean("testdata/invalid-names") @@ -94,7 +72,7 @@ func TestLoaderLoadConfig_loadDiags(t *testing.T) { t.Fatalf("unexpected error from NewLoader: %s", err) } - cfg, diags := loader.LoadConfig(fixtureDir) + cfg, diags := loader.LoadStaticConfig(fixtureDir) if !diags.HasErrors() { t.Fatal("success; want error") } @@ -118,7 +96,7 @@ func TestLoaderLoadConfig_loadDiagsFromSubmodules(t *testing.T) { t.Fatalf("unexpected error from NewLoader: %s", err) } - cfg, diags := loader.LoadConfig(fixtureDir) + cfg, diags := loader.LoadStaticConfig(fixtureDir) if !diags.HasErrors() { t.Fatalf("loading succeeded; want an error") } @@ -168,7 +146,7 @@ func TestLoaderLoadConfig_childProviderGrandchildCount(t *testing.T) { t.Fatalf("unexpected error from NewLoader: %s", err) } - cfg, diags := loader.LoadConfig(fixtureDir) + cfg, diags := loader.LoadStaticConfig(fixtureDir) assertNoDiagnostics(t, diags) if cfg == nil { t.Fatalf("config is nil; want non-nil") @@ -198,7 +176,7 @@ func TestLoaderLoadConfig_childProviderGrandchildCount(t *testing.T) { t.Fatalf("unexpected error from NewLoader: %s", err) } - _, diags := loader.LoadConfig(fixtureDir) + _, diags := loader.LoadStaticConfig(fixtureDir) if !diags.HasErrors() { t.Fatalf("loading succeeded; want an error") } diff --git a/internal/configs/configload/loader_snapshot.go b/internal/configs/configload/loader_snapshot.go index 5388e8bb1b..ba982527c1 100644 --- a/internal/configs/configload/loader_snapshot.go +++ b/internal/configs/configload/loader_snapshot.go @@ -20,26 +20,16 @@ import ( "github.com/hashicorp/terraform/internal/modsdir" ) -// LoadConfigWithSnapshot is a variant of LoadConfig that also simultaneously -// creates an in-memory snapshot of the configuration files used, which can -// be later used to create a loader that may read only from this snapshot. -func (l *Loader) LoadConfigWithSnapshot(rootDir string) (*configs.Config, *Snapshot, hcl.Diagnostics) { - rootMod, diags := l.parser.LoadConfigDir(rootDir, l.parserOpts...) - if rootMod == nil { - return nil, nil, diags - } - +func (l *Loader) ModuleWalkerSnapshot() (configs.ModuleWalker, *Snapshot) { snap := &Snapshot{ Modules: map[string]*SnapshotModule{}, } - walker := l.makeModuleWalkerSnapshot(snap) - cfg, cDiags := configs.BuildConfig(rootMod, walker, configs.MockDataLoaderFunc(l.LoadExternalMockData)) - diags = append(diags, cDiags...) - addDiags := l.addModuleToSnapshot(snap, "", rootDir, "", nil) - diags = append(diags, addDiags...) + return l.makeModuleWalkerSnapshot(snap), snap +} - return cfg, snap, diags +func (l *Loader) AddRootModuleToSnapshot(snap *Snapshot, rootDir string) hcl.Diagnostics { + return l.addModuleToSnapshot(snap, "", rootDir, "", nil) } // NewLoaderFromSnapshot creates a Loader that reads files only from the diff --git a/internal/configs/configload/loader_snapshot_test.go b/internal/configs/configload/loader_snapshot_test.go deleted file mode 100644 index 00411ecc18..0000000000 --- a/internal/configs/configload/loader_snapshot_test.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright IBM Corp. 2014, 2026 -// SPDX-License-Identifier: BUSL-1.1 - -package configload - -import ( - "os" - "path/filepath" - "reflect" - "testing" - - "github.com/davecgh/go-spew/spew" - "github.com/go-test/deep" -) - -func TestLoadConfigWithSnapshot(t *testing.T) { - fixtureDir := filepath.Clean("testdata/already-installed") - loader, err := NewLoader(&Config{ - ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), - }) - if err != nil { - t.Fatalf("unexpected error from NewLoader: %s", err) - } - - _, got, diags := loader.LoadConfigWithSnapshot(fixtureDir) - assertNoDiagnostics(t, diags) - if got == nil { - t.Fatalf("snapshot is nil; want non-nil") - } - - t.Log(spew.Sdump(got)) - - { - gotModuleDirs := map[string]string{} - for k, m := range got.Modules { - gotModuleDirs[k] = m.Dir - } - wantModuleDirs := map[string]string{ - "": "testdata/already-installed", - "child_a": "testdata/already-installed/.terraform/modules/child_a", - "child_a.child_c": "testdata/already-installed/.terraform/modules/child_a/child_c", - "child_b": "testdata/already-installed/.terraform/modules/child_b", - "child_b.child_d": "testdata/already-installed/.terraform/modules/child_b.child_d", - } - - problems := deep.Equal(wantModuleDirs, gotModuleDirs) - for _, problem := range problems { - t.Error(problem) - } - if len(problems) > 0 { - return - } - } - - gotRoot := got.Modules[""] - wantRoot := &SnapshotModule{ - Dir: "testdata/already-installed", - Files: map[string][]byte{ - "root.tf": []byte(` -module "child_a" { - source = "example.com/foo/bar_a/baz" - version = ">= 1.0.0" -} - -module "child_b" { - source = "example.com/foo/bar_b/baz" - version = ">= 1.0.0" -} -`), - }, - } - if !reflect.DeepEqual(gotRoot, wantRoot) { - t.Errorf("wrong root module snapshot\ngot: %swant: %s", spew.Sdump(gotRoot), spew.Sdump(wantRoot)) - } - -} - -func TestLoadConfigWithSnapshot_invalidSource(t *testing.T) { - fixtureDir := filepath.Clean("testdata/already-installed-now-invalid") - - old, _ := os.Getwd() - os.Chdir(fixtureDir) - defer os.Chdir(old) - - loader, err := NewLoader(&Config{ - ModulesDir: ".terraform/modules", - }) - if err != nil { - t.Fatalf("unexpected error from NewLoader: %s", err) - } - - _, _, diags := loader.LoadConfigWithSnapshot(".") - if !diags.HasErrors() { - t.Error("LoadConfigWithSnapshot succeeded; want errors") - } -} - -func TestSnapshotRoundtrip(t *testing.T) { - fixtureDir := filepath.Clean("testdata/already-installed") - loader, err := NewLoader(&Config{ - ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), - }) - if err != nil { - t.Fatalf("unexpected error from NewLoader: %s", err) - } - - _, snap, diags := loader.LoadConfigWithSnapshot(fixtureDir) - assertNoDiagnostics(t, diags) - if snap == nil { - t.Fatalf("snapshot is nil; want non-nil") - } - - snapLoader := NewLoaderFromSnapshot(snap) - if loader == nil { - t.Fatalf("loader is nil; want non-nil") - } - - config, diags := snapLoader.LoadConfig(fixtureDir) - assertNoDiagnostics(t, diags) - if config == nil { - t.Fatalf("config is nil; want non-nil") - } - if config.Module == nil { - t.Fatalf("config has no root module") - } - if got, want := config.Module.SourceDir, "testdata/already-installed"; got != want { - t.Errorf("wrong root module sourcedir %q; want %q", got, want) - } - if got, want := len(config.Module.ModuleCalls), 2; got != want { - t.Errorf("wrong number of module calls in root module %d; want %d", got, want) - } - childA := config.Children["child_a"] - if childA == nil { - t.Fatalf("child_a config is nil; want non-nil") - } - if childA.Module == nil { - t.Fatalf("child_a config has no module") - } - if got, want := childA.Module.SourceDir, "testdata/already-installed/.terraform/modules/child_a"; got != want { - t.Errorf("wrong child_a sourcedir %q; want %q", got, want) - } - if got, want := len(childA.Module.ModuleCalls), 1; got != want { - t.Errorf("wrong number of module calls in child_a %d; want %d", got, want) - } -} diff --git a/internal/configs/import_test.go b/internal/configs/import_test.go index 659d8f51c4..1d1c383958 100644 --- a/internal/configs/import_test.go +++ b/internal/configs/import_test.go @@ -16,13 +16,6 @@ import ( ) func TestParseConfigResourceFromExpression(t *testing.T) { - mustExpr := func(expr hcl.Expression, diags hcl.Diagnostics) hcl.Expression { - if diags != nil { - panic(diags.Error()) - } - return expr - } - tests := []struct { expr hcl.Expression expect addrs.ConfigResource @@ -280,3 +273,10 @@ func mustAbsResourceInstanceAddr(str string) addrs.AbsResourceInstance { } return addr } + +func mustExpr(expr hcl.Expression, diags hcl.Diagnostics) hcl.Expression { + if diags != nil { + panic(diags.Error()) + } + return expr +} diff --git a/internal/configs/testdata/invalid-files/version-variable.tf b/internal/configs/testdata/invalid-files/version-variable.tf deleted file mode 100644 index 7c871053de..0000000000 --- a/internal/configs/testdata/invalid-files/version-variable.tf +++ /dev/null @@ -1,6 +0,0 @@ -variable "module_version" { default = "v1.0" } - -module "foo" { - source = "./ff" - version = var.module_version -} diff --git a/internal/lang/globalref/analyzer_test.go b/internal/lang/globalref/analyzer_test.go index 7f50e6aca4..416cccce48 100644 --- a/internal/lang/globalref/analyzer_test.go +++ b/internal/lang/globalref/analyzer_test.go @@ -24,7 +24,7 @@ func testAnalyzer(t *testing.T, fixtureName string) *Analyzer { loader, cleanup := configload.NewLoaderForTests(t) defer cleanup() - inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil)) + inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil), nil) _, instDiags := inst.InstallModules(context.Background(), configDir, "tests", true, false, initwd.ModuleInstallHooksImpl{}) if instDiags.HasErrors() { t.Fatalf("unexpected module installation errors: %s", instDiags.Err().Error()) @@ -33,7 +33,7 @@ func testAnalyzer(t *testing.T, fixtureName string) *Analyzer { t.Fatalf("failed to refresh modules after install: %s", err) } - cfg, loadDiags := loader.LoadConfig(configDir) + cfg, loadDiags := loader.LoadStaticConfig(configDir) if loadDiags.HasErrors() { t.Fatalf("unexpected configuration errors: %s", loadDiags.Error()) } diff --git a/internal/moduletest/graph/eval_context_test.go b/internal/moduletest/graph/eval_context_test.go index eec1a08cdc..4b033f771a 100644 --- a/internal/moduletest/graph/eval_context_test.go +++ b/internal/moduletest/graph/eval_context_test.go @@ -835,7 +835,7 @@ func testModuleInline(t *testing.T, sources map[string]string) *configs.Config { // Test modules usually do not refer to remote sources, and for local // sources only this ultimately just records all of the module paths // in a JSON file so that we can load them below. - inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil)) + inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil), nil) _, instDiags := inst.InstallModules(context.Background(), cfgPath, "tests", true, false, initwd.ModuleInstallHooksImpl{}) if instDiags.HasErrors() { t.Fatal(instDiags.Err()) @@ -847,7 +847,7 @@ func testModuleInline(t *testing.T, sources map[string]string) *configs.Config { t.Fatalf("failed to refresh modules after installation: %s", err) } - config, diags := loader.LoadConfigWithTests(cfgPath, "tests") + config, diags := loader.LoadStaticConfigWithTests(cfgPath, "tests") if diags.HasErrors() { t.Fatal(diags.Error()) } diff --git a/internal/providercache/installer.go b/internal/providercache/installer.go index d54652b6d9..d375e90ca5 100644 --- a/internal/providercache/installer.go +++ b/internal/providercache/installer.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "log" + "slices" "sort" "strings" @@ -205,13 +206,7 @@ func (i *Installer) EnsureProviderVersions(ctx context.Context, locks *depsfile. if provider.IsBuiltIn() { // Built in providers do not require installation but we'll still // verify that the requested provider name is valid. - valid := false - for _, name := range i.builtInProviderTypes { - if name == provider.Type { - valid = true - break - } - } + valid := slices.Contains(i.builtInProviderTypes, provider.Type) var err error if valid { if len(versionConstraints) == 0 { diff --git a/internal/refactoring/move_validate_test.go b/internal/refactoring/move_validate_test.go index 9e44da0e58..bc9b66c2db 100644 --- a/internal/refactoring/move_validate_test.go +++ b/internal/refactoring/move_validate_test.go @@ -10,6 +10,8 @@ import ( "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" + "github.com/hashicorp/hcl/v2/hcltest" + "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/gocty" "github.com/hashicorp/terraform/internal/addrs" @@ -519,7 +521,7 @@ func loadRefactoringFixture(t *testing.T, dir string) (*configs.Config, instance loader, cleanup := configload.NewLoaderForTests(t) defer cleanup() - inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil)) + inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil), nil) _, instDiags := inst.InstallModules(context.Background(), dir, "tests", true, false, initwd.ModuleInstallHooksImpl{}) if instDiags.HasErrors() { t.Fatal(instDiags.Err()) @@ -531,7 +533,7 @@ func loadRefactoringFixture(t *testing.T, dir string) (*configs.Config, instance t.Fatalf("failed to refresh modules after installation: %s", err) } - rootCfg, diags := loader.LoadConfig(dir) + rootCfg, diags := loader.LoadStaticConfig(dir) if diags.HasErrors() { t.Fatalf("failed to load root module: %s", diags.Error()) } @@ -565,7 +567,7 @@ func staticPopulateExpanderModule(t *testing.T, rootCfg *configs.Config, moduleA // module to be something that counts as a separate package, // so we can test rules relating to crossing package boundaries // even though we really just loaded the module from a local path. - call.SourceAddr = fakeExternalModuleSource + call.SourceExpr = hcltest.MockExprLiteral(cty.StringVal(fakeExternalModuleSource.String())) } // In order to get a valid, useful set of instances here we're going diff --git a/internal/terraform/terraform_test.go b/internal/terraform/terraform_test.go index 53071437f3..309f4d044e 100644 --- a/internal/terraform/terraform_test.go +++ b/internal/terraform/terraform_test.go @@ -26,6 +26,7 @@ import ( "github.com/hashicorp/terraform/internal/provisioners" "github.com/hashicorp/terraform/internal/registry" "github.com/hashicorp/terraform/internal/states" + "github.com/hashicorp/terraform/internal/tfdiags" _ "github.com/hashicorp/terraform/internal/logging" ) @@ -67,7 +68,7 @@ func testModuleWithSnapshot(t *testing.T, name string) (*configs.Config, *config // Test modules usually do not refer to remote sources, and for local // sources only this ultimately just records all of the module paths // in a JSON file so that we can load them below. - inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil)) + inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil), nil) _, instDiags := inst.InstallModules(context.Background(), dir, "tests", true, false, initwd.ModuleInstallHooksImpl{}) if instDiags.HasErrors() { t.Fatal(instDiags.Err()) @@ -79,14 +80,44 @@ func testModuleWithSnapshot(t *testing.T, name string) (*configs.Config, *config t.Fatalf("failed to refresh modules after installation: %s", err) } - config, snap, diags := loader.LoadConfigWithSnapshot(dir) + config, snap, diags := testLoadWithSnapshot(dir, loader, nil) if diags.HasErrors() { - t.Fatal(diags.Error()) + t.Fatal(diags.Err()) } return config, snap } +func testLoadWithSnapshot(dir string, loader *configload.Loader, vars InputValues) (*configs.Config, *configload.Snapshot, tfdiags.Diagnostics) { + var diags tfdiags.Diagnostics + + rootMod, configDiags := loader.LoadRootModule(dir) + if configDiags.HasErrors() { + diags = diags.Append(configDiags) + return nil, nil, diags + } + + walkerSnapshot, snap := loader.ModuleWalkerSnapshot() + config, buildDiags := BuildConfigWithGraph( + rootMod, + walkerSnapshot, + vars, + configs.MockDataLoaderFunc(loader.LoadExternalMockData), + ) + if buildDiags.HasErrors() { + diags = diags.Append(buildDiags) + return nil, nil, diags + } + + snapDiags := loader.AddRootModuleToSnapshot(snap, dir) + if snapDiags.HasErrors() { + diags = diags.Append(snapDiags) + return nil, nil, diags + } + + return config, snap, nil +} + // testModuleInline takes a map of path -> config strings and yields a config // structure with those files loaded from disk func testModuleInline(t testing.TB, sources map[string]string, parserOpts ...configs.Option) *configs.Config { @@ -127,7 +158,7 @@ func testModuleInline(t testing.TB, sources map[string]string, parserOpts ...con // Test modules usually do not refer to remote sources, and for local // sources only this ultimately just records all of the module paths // in a JSON file so that we can load them below. - inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil)) + inst := initwd.NewModuleInstaller(loader.ModulesDir(), loader, registry.NewClient(nil, nil), nil) _, instDiags := inst.InstallModules(context.Background(), cfgPath, "tests", true, false, initwd.ModuleInstallHooksImpl{}) if instDiags.HasErrors() { t.Fatal(instDiags.Err()) @@ -139,7 +170,7 @@ func testModuleInline(t testing.TB, sources map[string]string, parserOpts ...con t.Fatalf("failed to refresh modules after installation: %s", err) } - config, diags := loader.LoadConfigWithTests(cfgPath, "tests") + config, diags := loader.LoadStaticConfigWithTests(cfgPath, "tests") if diags.HasErrors() { t.Fatal(diags.Error()) } @@ -147,6 +178,49 @@ func testModuleInline(t testing.TB, sources map[string]string, parserOpts ...con return config } +func testRootModuleInline(t testing.TB, sources map[string]string) *configs.Module { + t.Helper() + + cfgPath, err := filepath.EvalSymlinks(t.TempDir()) + if err != nil { + t.Fatal(err) + } + + for path, configStr := range sources { + dir := filepath.Dir(path) + if dir != "." { + err := os.MkdirAll(filepath.Join(cfgPath, dir), os.FileMode(0777)) + if err != nil { + t.Fatalf("Error creating subdir: %s", err) + } + } + // Write the configuration + cfgF, err := os.Create(filepath.Join(cfgPath, path)) + if err != nil { + t.Fatalf("Error creating temporary file for config: %s", err) + } + + _, err = io.Copy(cfgF, strings.NewReader(configStr)) + cfgF.Close() + if err != nil { + t.Fatalf("Error creating temporary file for config: %s", err) + } + } + + loader, cleanup := configload.NewLoaderForTests(t) + defer cleanup() + + // We need to be able to exercise experimental features in our integration tests. + loader.AllowLanguageExperiments(true) + + mod, diags := loader.Parser().LoadConfigDir(cfgPath) + if diags.HasErrors() { + t.Fatal(diags.Error()) + } + + return mod +} + // testSetResourceInstanceCurrent is a helper function for tests that sets a Current, // Ready resource instance for the given module. func testSetResourceInstanceCurrent(module *states.Module, resource, attrsJson, provider string) { From d5d12cdd490ae3fa3e29dd44684a6b13cad4856e Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 17:36:58 +0100 Subject: [PATCH 12/24] Treat most values as dynamic during init walk Since init only really cares about references that are used inside a module source (or version), we can treat all other references as dynamic/unknown and shortcut most of their validation steps. --- internal/terraform/evaluate.go | 35 ++++++++++++++++++++++++++++- internal/terraform/evaluate_data.go | 8 +++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/internal/terraform/evaluate.go b/internal/terraform/evaluate.go index 6842ec8c3c..4c61753711 100644 --- a/internal/terraform/evaluate.go +++ b/internal/terraform/evaluate.go @@ -166,6 +166,10 @@ var _ lang.Data = (*evaluationStateData)(nil) // the evaluator embedded in this data object, using this data object's // static module path. func (d *evaluationStateData) StaticValidateReferences(refs []*addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics { + if d.Operation == walkInit { + // Skip static validation during init walks + return tfdiags.Diagnostics{} + } return d.Evaluator.StaticValidateReferences(refs, d.ModulePath.Module(), self, source) } @@ -174,6 +178,12 @@ func (d *evaluationStateData) GetCountAttr(addr addrs.CountAttr, rng tfdiags.Sou switch addr.Name { case "index": + if d.Operation == walkInit { + // During init walks we don't have any state or prior knowledge + // about resources, so we just return unknown. + return cty.DynamicVal, diags + } + idxVal := d.InstanceKeyData.CountIndex if idxVal == cty.NilVal { diags = diags.Append(&hcl.Diagnostic{ @@ -226,6 +236,12 @@ func (d *evaluationStateData) GetForEachAttr(addr addrs.ForEachAttr, rng tfdiags return cty.DynamicVal, diags } + if d.Operation == walkInit { + // During init walks we don't have any state or prior knowledge + // about resources, so we just return unknown. + return cty.DynamicVal, diags + } + if returnVal == cty.NilVal { diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, @@ -387,6 +403,12 @@ func (d *evaluationStateData) GetModule(addr addrs.ModuleCall, rng tfdiags.Sourc return cty.DynamicVal, diags } + if d.Operation == walkInit { + // During init walks we don't have any state or prior knowledge + // about resources, so we just return unknown. + return cty.DynamicVal, diags + } + // We'll consult the configuration to see what output names we are // expecting, so we can ensure the resulting object is of the expected // type even if our data is incomplete for some reason. @@ -561,6 +583,11 @@ func (d *evaluationStateData) GetResource(addr addrs.Resource, rng tfdiags.Sourc return cty.DynamicVal, diags } + if d.Operation == walkInit { + // During init walks we don't have any state or prior knowledge + // about resources, so we just return unknown. + return cty.DynamicVal, diags + } // Much of this function was written before we had factored out the handling // of instance keys into the separate instance expander model, and so it // does a bunch of instance-related work itself below. @@ -1000,7 +1027,7 @@ func (d *evaluationStateData) getListResource(config *configs.Resource, rng tfdi func (d *evaluationStateData) getEphemeralResource(addr addrs.Resource, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics - if d.Operation == walkValidate || d.Operation == walkEval { + if d.Operation == walkValidate || d.Operation == walkEval || d.Operation == walkInit { // Ephemeral instances are never live during the validate walk. Eval is // similarly offline, and since there is no value stored we can't return // anything other than dynamic. @@ -1120,6 +1147,12 @@ func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAdd func (d *evaluationStateData) GetOutput(addr addrs.OutputValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics + if d.Operation == walkInit { + // During init walks we don't have any state or prior knowledge + // about resources, so we just return unknown. + return cty.DynamicVal, diags + } + // First we'll make sure the requested value is declared in configuration, // so we can produce a nice message if not. moduleConfig := d.Evaluator.Config.DescendantForInstance(d.ModulePath) diff --git a/internal/terraform/evaluate_data.go b/internal/terraform/evaluate_data.go index 3d33b598d8..250e1abc77 100644 --- a/internal/terraform/evaluate_data.go +++ b/internal/terraform/evaluate_data.go @@ -99,6 +99,10 @@ func (d *evaluationData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRang // GetTerraformAttr implements lang.Data. func (d *evaluationData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) { + if d.Evaluator.Operation == walkInit { + return cty.DynamicVal, tfdiags.Diagnostics{} + } + var diags tfdiags.Diagnostics switch addr.Name { @@ -154,6 +158,10 @@ func (d *evaluationData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags. // StaticValidateReferences implements lang.Data. func (d *evaluationData) StaticValidateReferences(refs []*addrs.Reference, self addrs.Referenceable, source addrs.Referenceable) tfdiags.Diagnostics { + if d.Evaluator.Operation == walkInit { + // Skip static validation during init walks + return tfdiags.Diagnostics{} + } return d.Evaluator.StaticValidateReferences(refs, d.Module, self, source) } From 0043e1ce249155370dee0dafc5dd027ebb9f6e4f Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 17:39:04 +0100 Subject: [PATCH 13/24] Update module call configuration storage This turns the string representation of the source and version attribute of a module call into an expression. This leads to a change in the JSON output: `"source": "./foo"` --> `"source": {"constant_value": "./foo"},` --- internal/command/jsonconfig/config.go | 26 +- internal/command/show_test.go | 5 +- .../show-json/module-depends-on/output.json | 162 +++-- .../testdata/show-json/modules/output.json | 584 +++++++++--------- .../show-json/nested-modules/output.json | 8 +- .../provider-aliasing-conflict/output.json | 12 +- .../provider-aliasing-default/output.json | 28 +- .../show-json/provider-aliasing/output.json | 56 +- 8 files changed, 428 insertions(+), 453 deletions(-) diff --git a/internal/command/jsonconfig/config.go b/internal/command/jsonconfig/config.go index b2d794bdf4..d466f44d4b 100644 --- a/internal/command/jsonconfig/config.go +++ b/internal/command/jsonconfig/config.go @@ -49,12 +49,12 @@ type module struct { } type moduleCall struct { - Source string `json:"source,omitempty"` + SourceExpression *expression `json:"source,omitempty"` Expressions map[string]interface{} `json:"expressions,omitempty"` CountExpression *expression `json:"count_expression,omitempty"` ForEachExpression *expression `json:"for_each_expression,omitempty"` Module module `json:"module,omitempty"` - VersionConstraint string `json:"version_constraint,omitempty"` + VersionConstraint *expression `json:"version_constraint,omitempty"` DependsOn []string `json:"depends_on,omitempty"` } @@ -415,16 +415,20 @@ func marshalModuleCall(c *configs.Config, mc *configs.ModuleCall, schemas *terra return moduleCall{} } - ret := moduleCall{ - // We're intentionally echoing back exactly what the user entered - // here, rather than the normalized version in SourceAddr, because - // historically we only _had_ the raw address and thus it would be - // a (admittedly minor) breaking change to start normalizing them - // now, in case consumers of this data are expecting a particular - // non-normalized syntax. - Source: mc.SourceAddrRaw, - VersionConstraint: mc.Version.Required.String(), + ret := moduleCall{} + // We're intentionally echoing back exactly what the user entered + // here, rather than the normalized version in SourceAddr, because + // historically we only _had_ the raw address and thus it would be + // a (admittedly minor) breaking change to start normalizing them + // now, in case consumers of this data are expecting a particular + // non-normalized syntax. + sExp := marshalExpression(mc.SourceExpr) + ret.SourceExpression = &sExp + if mc.VersionExpr != nil { + vExp := marshalExpression(mc.VersionExpr) + ret.VersionConstraint = &vExp } + cExp := marshalExpression(mc.Count) if !cExp.Empty() { ret.CountExpression = &cExp diff --git a/internal/command/show_test.go b/internal/command/show_test.go index 99da480f36..71995d9b90 100644 --- a/internal/command/show_test.go +++ b/internal/command/show_test.go @@ -6,6 +6,7 @@ package command import ( "bytes" "encoding/json" + "io" "io/ioutil" "os" "path/filepath" @@ -533,7 +534,7 @@ func TestShow_state(t *testing.T) { func TestShow_json_output(t *testing.T) { fixtureDir := "testdata/show-json" - testDirs, err := ioutil.ReadDir(fixtureDir) + testDirs, err := os.ReadDir(fixtureDir) if err != nil { t.Fatal(err) } @@ -584,7 +585,7 @@ func TestShow_json_output(t *testing.T) { t.Fatalf("unexpected err: %s", err) } defer wantFile.Close() - byteValue, err := ioutil.ReadAll(wantFile) + byteValue, err := io.ReadAll(wantFile) if err != nil { t.Fatalf("unexpected err: %s", err) } diff --git a/internal/command/testdata/show-json/module-depends-on/output.json b/internal/command/testdata/show-json/module-depends-on/output.json index 59f4a1bce9..e29262037c 100644 --- a/internal/command/testdata/show-json/module-depends-on/output.json +++ b/internal/command/testdata/show-json/module-depends-on/output.json @@ -1,87 +1,85 @@ { - "format_version": "1.0", - "terraform_version": "0.13.1-dev", - "applyable": true, - "complete": true, - "planned_values": { - "root_module": { - "resources": [ - { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "foo-bar" - }, - "sensitive_values": {} - } - ] - } - }, - "resource_changes": [ + "format_version": "1.0", + "terraform_version": "0.13.1-dev", + "applyable": true, + "complete": true, + "planned_values": { + "root_module": { + "resources": [ { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_name": "registry.terraform.io/hashicorp/test", - "change": { - "actions": [ - "create" - ], - "before": null, - "after": { - "ami": "foo-bar" - }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - } - ], - "configuration": { - "provider_config": { - "test": { - "name": "test", - "full_name": "registry.terraform.io/hashicorp/test" - } - }, - "root_module": { - "resources": [ - { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_config_key": "test", - "expressions": { - "ami": { - "constant_value": "foo-bar" - } - }, - "schema_version": 0 - } - ], - "module_calls": { - "foo": { - "depends_on": [ - "test_instance.test" - ], - "source": "./foo", - "module": { - "variables": { - "test_var": { - "default": "foo-var" - } - } - } - } - } + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "foo-bar" + }, + "sensitive_values": {} } + ] } + }, + "resource_changes": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "change": { + "actions": ["create"], + "before": null, + "after": { + "ami": "foo-bar" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false + } + } + ], + "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, + "root_module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "test", + "expressions": { + "ami": { + "constant_value": "foo-bar" + } + }, + "schema_version": 0 + } + ], + "module_calls": { + "foo": { + "depends_on": ["test_instance.test"], + "source": { + "constant_value": "./foo" + }, + "module": { + "variables": { + "test_var": { + "default": "foo-var" + } + } + } + } + } + } + } } diff --git a/internal/command/testdata/show-json/modules/output.json b/internal/command/testdata/show-json/modules/output.json index 96a5f490a6..db9cb2f9a9 100644 --- a/internal/command/testdata/show-json/modules/output.json +++ b/internal/command/testdata/show-json/modules/output.json @@ -1,308 +1,292 @@ { - "format_version": "1.0", - "applyable": true, - "complete": true, - "planned_values": { - "outputs": { - "test": { - "sensitive": false, - "type": "string", - "value": "baz" - } - }, - "root_module": { - "child_modules": [ - { - "resources": [ - { - "address": "module.module_test_bar.test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "bar-var" - }, - "sensitive_values": {} - } - ], - "address": "module.module_test_bar" - }, - { - "resources": [ - { - "address": "module.module_test_foo.test_instance.test[0]", - "mode": "managed", - "type": "test_instance", - "name": "test", - "index": 0, - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "baz" - }, - "sensitive_values": {} - }, - { - "address": "module.module_test_foo.test_instance.test[1]", - "mode": "managed", - "type": "test_instance", - "name": "test", - "index": 1, - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "baz" - }, - "sensitive_values": {} - }, - { - "address": "module.module_test_foo.test_instance.test[2]", - "mode": "managed", - "type": "test_instance", - "name": "test", - "index": 2, - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "baz" - }, - "sensitive_values": {} - } - ], - "address": "module.module_test_foo" - } - ] - } + "format_version": "1.0", + "applyable": true, + "complete": true, + "planned_values": { + "outputs": { + "test": { + "sensitive": false, + "type": "string", + "value": "baz" + } }, - "prior_state": { - "format_version": "1.0", - "values": { - "outputs": { - "test": { - "sensitive": false, - "type": "string", - "value": "baz" - } + "root_module": { + "child_modules": [ + { + "resources": [ + { + "address": "module.module_test_bar.test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "bar-var" + }, + "sensitive_values": {} + } + ], + "address": "module.module_test_bar" + }, + { + "resources": [ + { + "address": "module.module_test_foo.test_instance.test[0]", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 0, + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "baz" + }, + "sensitive_values": {} }, - "root_module": {} - } - }, - "resource_changes": [ - { - "address": "module.module_test_bar.test_instance.test", - "module_address": "module.module_test_bar", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_name": "registry.terraform.io/hashicorp/test", - "change": { - "actions": [ - "create" - ], - "before": null, - "after": { - "ami": "bar-var" - }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - }, - { - "address": "module.module_test_foo.test_instance.test[0]", - "module_address": "module.module_test_foo", - "mode": "managed", - "type": "test_instance", - "provider_name": "registry.terraform.io/hashicorp/test", - "name": "test", - "index": 0, - "change": { - "actions": [ - "create" - ], - "before": null, - "after": { - "ami": "baz" - }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - }, - { - "address": "module.module_test_foo.test_instance.test[1]", - "module_address": "module.module_test_foo", - "mode": "managed", - "type": "test_instance", - "provider_name": "registry.terraform.io/hashicorp/test", - "name": "test", - "index": 1, - "change": { - "actions": [ - "create" - ], - "before": null, - "after": { - "ami": "baz" - }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - }, - { - "address": "module.module_test_foo.test_instance.test[2]", - "module_address": "module.module_test_foo", - "mode": "managed", - "type": "test_instance", - "provider_name": "registry.terraform.io/hashicorp/test", - "name": "test", - "index": 2, - "change": { - "actions": [ - "create" - ], - "before": null, - "after": { - "ami": "baz" - }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - } - ], - "output_changes": { - "test": { - "actions": [ - "create" - ], - "before": null, - "after": "baz", - "after_unknown": false, - "before_sensitive": false, - "after_sensitive": false - } - }, - "configuration": { - "root_module": { - "outputs": { - "test": { - "expression": { - "references": [ - "module.module_test_foo.test", - "module.module_test_foo" - ] - }, - "depends_on": [ - "module.module_test_foo" - ] - } + { + "address": "module.module_test_foo.test_instance.test[1]", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 1, + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "baz" + }, + "sensitive_values": {} }, - "module_calls": { - "module_test_bar": { - "source": "./bar", - "module": { - "outputs": { - "test": { - "expression": { - "references": [ - "var.test_var" - ] - } - } - }, - "resources": [ - { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_config_key": "module.module_test_bar:test", - "expressions": { - "ami": { - "references": [ - "var.test_var" - ] - } - }, - "schema_version": 0 - } - ], - "variables": { - "test_var": { - "default": "bar-var" - } - } - } - }, - "module_test_foo": { - "source": "./foo", - "expressions": { - "test_var": { - "constant_value": "baz" - } - }, - "module": { - "outputs": { - "test": { - "expression": { - "references": [ - "var.test_var" - ] - } - } - }, - "resources": [ - { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_config_key": "module.module_test_foo:test", - "expressions": { - "ami": { - "references": [ - "var.test_var" - ] - } - }, - "schema_version": 0, - "count_expression": { - "constant_value": 3 - } - } - ], - "variables": { - "test_var": { - "default": "foo-var" - } - } - } - } - } - }, - "provider_config": { - "module.module_test_foo:test": { - "module_address": "module.module_test_foo", - "name": "test", - "full_name": "registry.terraform.io/hashicorp/test" - }, - "module.module_test_bar:test": { - "module_address": "module.module_test_bar", - "name": "test", - "full_name": "registry.terraform.io/hashicorp/test" + { + "address": "module.module_test_foo.test_instance.test[2]", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 2, + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "baz" + }, + "sensitive_values": {} } + ], + "address": "module.module_test_foo" } + ] } + }, + "prior_state": { + "format_version": "1.0", + "values": { + "outputs": { + "test": { + "sensitive": false, + "type": "string", + "value": "baz" + } + }, + "root_module": {} + } + }, + "resource_changes": [ + { + "address": "module.module_test_bar.test_instance.test", + "module_address": "module.module_test_bar", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "change": { + "actions": ["create"], + "before": null, + "after": { + "ami": "bar-var" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false + } + }, + { + "address": "module.module_test_foo.test_instance.test[0]", + "module_address": "module.module_test_foo", + "mode": "managed", + "type": "test_instance", + "provider_name": "registry.terraform.io/hashicorp/test", + "name": "test", + "index": 0, + "change": { + "actions": ["create"], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false + } + }, + { + "address": "module.module_test_foo.test_instance.test[1]", + "module_address": "module.module_test_foo", + "mode": "managed", + "type": "test_instance", + "provider_name": "registry.terraform.io/hashicorp/test", + "name": "test", + "index": 1, + "change": { + "actions": ["create"], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false + } + }, + { + "address": "module.module_test_foo.test_instance.test[2]", + "module_address": "module.module_test_foo", + "mode": "managed", + "type": "test_instance", + "provider_name": "registry.terraform.io/hashicorp/test", + "name": "test", + "index": 2, + "change": { + "actions": ["create"], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false + } + } + ], + "output_changes": { + "test": { + "actions": ["create"], + "before": null, + "after": "baz", + "after_unknown": false, + "before_sensitive": false, + "after_sensitive": false + } + }, + "configuration": { + "root_module": { + "outputs": { + "test": { + "expression": { + "references": [ + "module.module_test_foo.test", + "module.module_test_foo" + ] + }, + "depends_on": ["module.module_test_foo"] + } + }, + "module_calls": { + "module_test_bar": { + "source": { + "constant_value": "./bar" + }, + "module": { + "outputs": { + "test": { + "expression": { + "references": ["var.test_var"] + } + } + }, + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "module.module_test_bar:test", + "expressions": { + "ami": { + "references": ["var.test_var"] + } + }, + "schema_version": 0 + } + ], + "variables": { + "test_var": { + "default": "bar-var" + } + } + } + }, + "module_test_foo": { + "source": { + "constant_value": "./foo" + }, + "expressions": { + "test_var": { + "constant_value": "baz" + } + }, + "module": { + "outputs": { + "test": { + "expression": { + "references": ["var.test_var"] + } + } + }, + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "module.module_test_foo:test", + "expressions": { + "ami": { + "references": ["var.test_var"] + } + }, + "schema_version": 0, + "count_expression": { + "constant_value": 3 + } + } + ], + "variables": { + "test_var": { + "default": "foo-var" + } + } + } + } + } + }, + "provider_config": { + "module.module_test_foo:test": { + "module_address": "module.module_test_foo", + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + }, + "module.module_test_bar:test": { + "module_address": "module.module_test_bar", + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + } + } } diff --git a/internal/command/testdata/show-json/nested-modules/output.json b/internal/command/testdata/show-json/nested-modules/output.json index f96a24484d..cd2d6d9a0c 100644 --- a/internal/command/testdata/show-json/nested-modules/output.json +++ b/internal/command/testdata/show-json/nested-modules/output.json @@ -63,11 +63,15 @@ "root_module": { "module_calls": { "my_module": { - "source": "./modules", + "source": { + "constant_value": "./modules" + }, "module": { "module_calls": { "more": { - "source": "./more-modules", + "source": { + "constant_value": "./more-modules" + }, "module": { "resources": [ { diff --git a/internal/command/testdata/show-json/provider-aliasing-conflict/output.json b/internal/command/testdata/show-json/provider-aliasing-conflict/output.json index b516a4a564..c30f2774c9 100644 --- a/internal/command/testdata/show-json/provider-aliasing-conflict/output.json +++ b/internal/command/testdata/show-json/provider-aliasing-conflict/output.json @@ -48,9 +48,7 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "foo" @@ -70,9 +68,7 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp2/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "bar" @@ -120,7 +116,9 @@ ], "module_calls": { "child": { - "source": "./child", + "source": { + "constant_value": "./child" + }, "module": { "resources": [ { diff --git a/internal/command/testdata/show-json/provider-aliasing-default/output.json b/internal/command/testdata/show-json/provider-aliasing-default/output.json index f2639da510..5ccdc089b6 100644 --- a/internal/command/testdata/show-json/provider-aliasing-default/output.json +++ b/internal/command/testdata/show-json/provider-aliasing-default/output.json @@ -84,9 +84,7 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "foo" @@ -106,9 +104,7 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "bar" @@ -128,9 +124,7 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "qux" @@ -150,9 +144,7 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "baz" @@ -205,7 +197,9 @@ ], "module_calls": { "child": { - "source": "./child", + "source": { + "constant_value": "./child" + }, "module": { "resources": [ { @@ -224,7 +218,9 @@ ], "module_calls": { "no_requirements": { - "source": "./nested-no-requirements", + "source": { + "constant_value": "./nested-no-requirements" + }, "module": { "resources": [ { @@ -244,7 +240,9 @@ } }, "with_requirement": { - "source": "./nested", + "source": { + "constant_value": "./nested" + }, "depends_on": ["module.no_requirements"], "module": { "resources": [ diff --git a/internal/command/testdata/show-json/provider-aliasing/output.json b/internal/command/testdata/show-json/provider-aliasing/output.json index 9f5675036e..bb6429adc8 100755 --- a/internal/command/testdata/show-json/provider-aliasing/output.json +++ b/internal/command/testdata/show-json/provider-aliasing/output.json @@ -163,9 +163,7 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "foo" @@ -184,9 +182,7 @@ "name": "test_backup", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "foo-backup" @@ -206,9 +202,7 @@ "name": "test_primary", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "primary" @@ -228,9 +222,7 @@ "name": "test_secondary", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "secondary" @@ -250,9 +242,7 @@ "name": "test_primary", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "primary" @@ -272,9 +262,7 @@ "name": "test_secondary", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "secondary" @@ -294,9 +282,7 @@ "name": "test_alternate", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "secondary" @@ -316,9 +302,7 @@ "name": "test_main", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "main" @@ -338,9 +322,7 @@ "name": "test_alternate", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "secondary" @@ -360,9 +342,7 @@ "name": "test_main", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": [ - "create" - ], + "actions": ["create"], "before": null, "after": { "ami": "main" @@ -428,7 +408,9 @@ ], "module_calls": { "child": { - "source": "./child", + "source": { + "constant_value": "./child" + }, "module": { "resources": [ { @@ -460,7 +442,9 @@ ], "module_calls": { "grandchild": { - "source": "./nested", + "source": { + "constant_value": "./nested" + }, "module": { "resources": [ { @@ -496,7 +480,9 @@ } }, "sibling": { - "source": "./child", + "source": { + "constant_value": "./child" + }, "module": { "resources": [ { @@ -528,7 +514,9 @@ ], "module_calls": { "grandchild": { - "source": "./nested", + "source": { + "constant_value": "./nested" + }, "module": { "resources": [ { From 297ebd989e773f8e1acf3c5a4d6db4b0fe9e5818 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 17:43:16 +0100 Subject: [PATCH 14/24] Move some planfile tests To be able to read and build the configuration in planfile related tests, we need methods from the `terraform` package. This commit moves the test into that package to make testing easier. --- internal/plans/planfile/config_snapshot.go | 6 +++--- internal/plans/planfile/reader.go | 5 +++-- internal/plans/planfile/writer.go | 2 +- .../config_snapshot_test.go | 13 +++++++------ .../planfile => terraform}/planfile_test.go | 19 ++++++++++--------- .../testdata/planfile}/cloudplan.json | 0 .../.terraform/modules/child_a/child_a.tf | 0 .../modules/child_a/child_c/child_c.tf | 0 .../modules/child_b.child_d/child_d.tf | 0 .../.terraform/modules/child_b/child_b.tf | 0 .../.terraform/modules/modules.json | 10 +++++----- .../testdata/planfile}/test-config/root.tf | 0 12 files changed, 29 insertions(+), 26 deletions(-) rename internal/{plans/planfile => terraform}/config_snapshot_test.go (74%) rename internal/{plans/planfile => terraform}/planfile_test.go (91%) rename internal/{plans/planfile/testdata => terraform/testdata/planfile}/cloudplan.json (100%) rename internal/{plans/planfile/testdata => terraform/testdata/planfile}/test-config/.terraform/modules/child_a/child_a.tf (100%) rename internal/{plans/planfile/testdata => terraform/testdata/planfile}/test-config/.terraform/modules/child_a/child_c/child_c.tf (100%) rename internal/{plans/planfile/testdata => terraform/testdata/planfile}/test-config/.terraform/modules/child_b.child_d/child_d.tf (100%) rename internal/{plans/planfile/testdata => terraform/testdata/planfile}/test-config/.terraform/modules/child_b/child_b.tf (100%) rename internal/{plans/planfile/testdata => terraform/testdata/planfile}/test-config/.terraform/modules/modules.json (57%) rename internal/{plans/planfile/testdata => terraform/testdata/planfile}/test-config/root.tf (100%) diff --git a/internal/plans/planfile/config_snapshot.go b/internal/plans/planfile/config_snapshot.go index 25c8c2843d..925cce08c1 100644 --- a/internal/plans/planfile/config_snapshot.go +++ b/internal/plans/planfile/config_snapshot.go @@ -30,7 +30,7 @@ type configSnapshotModuleRecord struct { } type configSnapshotModuleManifest []configSnapshotModuleRecord -func readConfigSnapshot(z *zip.Reader) (*configload.Snapshot, error) { +func ReadConfigSnapshot(z *zip.Reader) (*configload.Snapshot, error) { // Errors from this function are expected to be reported with some // additional prefix context about them being in a config snapshot, // so they should not themselves refer to the config snapshot. @@ -145,13 +145,13 @@ func readConfigSnapshot(z *zip.Reader) (*configload.Snapshot, error) { return snap, nil } -// writeConfigSnapshot adds to the given zip.Writer one or more files +// WriteConfigSnapshot adds to the given zip.Writer one or more files // representing the given snapshot. // // This file creates new files in the writer, so any already-open writer // for the file will be invalidated by this call. The writer remains open // when this function returns. -func writeConfigSnapshot(snap *configload.Snapshot, z *zip.Writer) error { +func WriteConfigSnapshot(snap *configload.Snapshot, z *zip.Writer) error { // Errors from this function are expected to be reported with some // additional prefix context about them being in a config snapshot, // so they should not themselves refer to the config snapshot. diff --git a/internal/plans/planfile/reader.go b/internal/plans/planfile/reader.go index 3bb0f439b8..2a54187d1b 100644 --- a/internal/plans/planfile/reader.go +++ b/internal/plans/planfile/reader.go @@ -188,7 +188,7 @@ func (r *Reader) ReadPrevStateFile() (*statefile.File, error) { // This is a lower-level alternative to ReadConfig that just extracts the // source files, without attempting to parse them. func (r *Reader) ReadConfigSnapshot() (*configload.Snapshot, error) { - return readConfigSnapshot(&r.zip.Reader) + return ReadConfigSnapshot(&r.zip.Reader) } // ReadConfig reads the configuration embedded in the plan file. @@ -196,6 +196,7 @@ func (r *Reader) ReadConfigSnapshot() (*configload.Snapshot, error) { // Internally this function delegates to the configs/configload package to // parse the embedded configuration and so it returns diagnostics (rather than // a native Go error as with other methods on Reader). +// TODO remove? func (r *Reader) ReadConfig(allowLanguageExperiments bool) (*configs.Config, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics @@ -212,7 +213,7 @@ func (r *Reader) ReadConfig(allowLanguageExperiments bool) (*configs.Config, tfd loader := configload.NewLoaderFromSnapshot(snap) loader.AllowLanguageExperiments(allowLanguageExperiments) rootDir := snap.Modules[""].Dir // Root module base directory - config, configDiags := loader.LoadConfig(rootDir) + config, configDiags := loader.LoadStaticConfig(rootDir) diags = diags.Append(configDiags) return config, diags diff --git a/internal/plans/planfile/writer.go b/internal/plans/planfile/writer.go index 7781700584..a4db0b3fff 100644 --- a/internal/plans/planfile/writer.go +++ b/internal/plans/planfile/writer.go @@ -111,7 +111,7 @@ func Create(filename string, args CreateArgs) error { // tfconfig directory { - err := writeConfigSnapshot(args.ConfigSnapshot, zw) + err := WriteConfigSnapshot(args.ConfigSnapshot, zw) if err != nil { return fmt.Errorf("failed to write config snapshot: %s", err) } diff --git a/internal/plans/planfile/config_snapshot_test.go b/internal/terraform/config_snapshot_test.go similarity index 74% rename from internal/plans/planfile/config_snapshot_test.go rename to internal/terraform/config_snapshot_test.go index 39344e0dcf..fbc1dcfcbc 100644 --- a/internal/plans/planfile/config_snapshot_test.go +++ b/internal/terraform/config_snapshot_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2014, 2026 // SPDX-License-Identifier: BUSL-1.1 -package planfile +package terraform import ( "archive/zip" @@ -13,10 +13,11 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/hashicorp/terraform/internal/configs/configload" + "github.com/hashicorp/terraform/internal/plans/planfile" ) func TestConfigSnapshotRoundtrip(t *testing.T) { - fixtureDir := filepath.Join("testdata", "test-config") + fixtureDir := filepath.Join("testdata", "planfile", "test-config") loader, err := configload.NewLoader(&configload.Config{ ModulesDir: filepath.Join(fixtureDir, ".terraform", "modules"), }) @@ -24,14 +25,14 @@ func TestConfigSnapshotRoundtrip(t *testing.T) { t.Fatal(err) } - _, snapIn, diags := loader.LoadConfigWithSnapshot(fixtureDir) + _, snapIn, diags := testLoadWithSnapshot(fixtureDir, loader, nil) if diags.HasErrors() { - t.Fatal(diags.Error()) + t.Fatal(diags.Err()) } var buf bytes.Buffer zw := zip.NewWriter(&buf) - err = writeConfigSnapshot(snapIn, zw) + err = planfile.WriteConfigSnapshot(snapIn, zw) if err != nil { t.Fatalf("failed to write snapshot: %s", err) } @@ -44,7 +45,7 @@ func TestConfigSnapshotRoundtrip(t *testing.T) { t.Fatal(err) } - snapOut, err := readConfigSnapshot(zr) + snapOut, err := planfile.ReadConfigSnapshot(zr) if err != nil { t.Fatalf("failed to read snapshot: %s", err) } diff --git a/internal/plans/planfile/planfile_test.go b/internal/terraform/planfile_test.go similarity index 91% rename from internal/plans/planfile/planfile_test.go rename to internal/terraform/planfile_test.go index 2342f9404a..b3fe65fe5c 100644 --- a/internal/plans/planfile/planfile_test.go +++ b/internal/terraform/planfile_test.go @@ -1,7 +1,7 @@ // Copyright IBM Corp. 2014, 2026 // SPDX-License-Identifier: BUSL-1.1 -package planfile +package terraform import ( "path/filepath" @@ -16,13 +16,14 @@ import ( "github.com/hashicorp/terraform/internal/depsfile" "github.com/hashicorp/terraform/internal/getproviders/providerreqs" "github.com/hashicorp/terraform/internal/plans" + "github.com/hashicorp/terraform/internal/plans/planfile" "github.com/hashicorp/terraform/internal/states" "github.com/hashicorp/terraform/internal/states/statefile" tfversion "github.com/hashicorp/terraform/version" ) func TestRoundtrip(t *testing.T) { - fixtureDir := filepath.Join("testdata", "test-config") + fixtureDir := filepath.Join("testdata", "planfile", "test-config") loader, err := configload.NewLoader(&configload.Config{ ModulesDir: filepath.Join(fixtureDir, ".terraform", "modules"), }) @@ -30,9 +31,9 @@ func TestRoundtrip(t *testing.T) { t.Fatal(err) } - _, snapIn, diags := loader.LoadConfigWithSnapshot(fixtureDir) + _, snapIn, diags := testLoadWithSnapshot(fixtureDir, loader, nil) if diags.HasErrors() { - t.Fatal(diags.Error()) + t.Fatal(diags.Err()) } // Just a minimal state file so we can test that it comes out again at all. @@ -92,7 +93,7 @@ func TestRoundtrip(t *testing.T) { planFn := filepath.Join(t.TempDir(), "tfplan") - err = Create(planFn, CreateArgs{ + err = planfile.Create(planFn, planfile.CreateArgs{ ConfigSnapshot: snapIn, PreviousRunStateFile: prevStateFileIn, StateFile: stateFileIn, @@ -103,7 +104,7 @@ func TestRoundtrip(t *testing.T) { t.Fatalf("failed to create plan file: %s", err) } - wpf, err := OpenWrapped(planFn) + wpf, err := planfile.OpenWrapped(planFn) if err != nil { t.Fatalf("failed to open plan file for reading: %s", err) } @@ -181,14 +182,14 @@ func TestRoundtrip(t *testing.T) { func TestWrappedError(t *testing.T) { // Open something that isn't a cloud or local planfile: should error wrongFile := "not a valid zip file" - _, err := OpenWrapped(filepath.Join("testdata", "test-config", "root.tf")) + _, err := planfile.OpenWrapped(filepath.Join("testdata", "planfile", "test-config", "root.tf")) if !strings.Contains(err.Error(), wrongFile) { t.Fatalf("expected %q, got %q", wrongFile, err) } // Open something that doesn't exist: should error missingFile := "no such file or directory" - _, err = OpenWrapped(filepath.Join("testdata", "absent.tfplan")) + _, err = planfile.OpenWrapped(filepath.Join("testdata", "planfile", "absent.tfplan")) if !strings.Contains(err.Error(), missingFile) { t.Fatalf("expected %q, got %q", missingFile, err) } @@ -196,7 +197,7 @@ func TestWrappedError(t *testing.T) { func TestWrappedCloud(t *testing.T) { // Loading valid cloud plan results in a wrapped cloud plan - wpf, err := OpenWrapped(filepath.Join("testdata", "cloudplan.json")) + wpf, err := planfile.OpenWrapped(filepath.Join("testdata", "planfile", "cloudplan.json")) if err != nil { t.Fatalf("failed to open valid cloud plan: %s", err) } diff --git a/internal/plans/planfile/testdata/cloudplan.json b/internal/terraform/testdata/planfile/cloudplan.json similarity index 100% rename from internal/plans/planfile/testdata/cloudplan.json rename to internal/terraform/testdata/planfile/cloudplan.json diff --git a/internal/plans/planfile/testdata/test-config/.terraform/modules/child_a/child_a.tf b/internal/terraform/testdata/planfile/test-config/.terraform/modules/child_a/child_a.tf similarity index 100% rename from internal/plans/planfile/testdata/test-config/.terraform/modules/child_a/child_a.tf rename to internal/terraform/testdata/planfile/test-config/.terraform/modules/child_a/child_a.tf diff --git a/internal/plans/planfile/testdata/test-config/.terraform/modules/child_a/child_c/child_c.tf b/internal/terraform/testdata/planfile/test-config/.terraform/modules/child_a/child_c/child_c.tf similarity index 100% rename from internal/plans/planfile/testdata/test-config/.terraform/modules/child_a/child_c/child_c.tf rename to internal/terraform/testdata/planfile/test-config/.terraform/modules/child_a/child_c/child_c.tf diff --git a/internal/plans/planfile/testdata/test-config/.terraform/modules/child_b.child_d/child_d.tf b/internal/terraform/testdata/planfile/test-config/.terraform/modules/child_b.child_d/child_d.tf similarity index 100% rename from internal/plans/planfile/testdata/test-config/.terraform/modules/child_b.child_d/child_d.tf rename to internal/terraform/testdata/planfile/test-config/.terraform/modules/child_b.child_d/child_d.tf diff --git a/internal/plans/planfile/testdata/test-config/.terraform/modules/child_b/child_b.tf b/internal/terraform/testdata/planfile/test-config/.terraform/modules/child_b/child_b.tf similarity index 100% rename from internal/plans/planfile/testdata/test-config/.terraform/modules/child_b/child_b.tf rename to internal/terraform/testdata/planfile/test-config/.terraform/modules/child_b/child_b.tf diff --git a/internal/plans/planfile/testdata/test-config/.terraform/modules/modules.json b/internal/terraform/testdata/planfile/test-config/.terraform/modules/modules.json similarity index 57% rename from internal/plans/planfile/testdata/test-config/.terraform/modules/modules.json rename to internal/terraform/testdata/planfile/test-config/.terraform/modules/modules.json index ba691877ff..ebd4f0f778 100644 --- a/internal/plans/planfile/testdata/test-config/.terraform/modules/modules.json +++ b/internal/terraform/testdata/planfile/test-config/.terraform/modules/modules.json @@ -3,30 +3,30 @@ { "Key": "", "Source": "", - "Dir": "testdata/test-config" + "Dir": "testdata/planfile/test-config" }, { "Key": "child_a", "Source": "example.com/foo/bar_a/baz", "Version": "1.0.1", - "Dir": "testdata/test-config/.terraform/modules/child_a" + "Dir": "testdata/planfile/test-config/.terraform/modules/child_a" }, { "Key": "child_b", "Source": "example.com/foo/bar_b/baz", "Version": "1.0.0", - "Dir": "testdata/test-config/.terraform/modules/child_b" + "Dir": "testdata/planfile/test-config/.terraform/modules/child_b" }, { "Key": "child_a.child_c", "Source": "./child_c", - "Dir": "testdata/test-config/.terraform/modules/child_a/child_c" + "Dir": "testdata/planfile/test-config/.terraform/modules/child_a/child_c" }, { "Key": "child_b.child_d", "Source": "example.com/foo/bar_d/baz", "Version": "1.2.0", - "Dir": "testdata/test-config/.terraform/modules/child_b.child_d" + "Dir": "testdata/planfile/test-config/.terraform/modules/child_b.child_d" } ] } diff --git a/internal/plans/planfile/testdata/test-config/root.tf b/internal/terraform/testdata/planfile/test-config/root.tf similarity index 100% rename from internal/plans/planfile/testdata/test-config/root.tf rename to internal/terraform/testdata/planfile/test-config/root.tf From 5a70c424b3cf3d5d5abdacc332f38aaf7d2875b8 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 17:45:03 +0100 Subject: [PATCH 15/24] Fix import and show command This commit moves some code around to fix configuration loading during the (legacy) import command. And add vars to the show command. --- internal/command/arguments/show.go | 5 +- internal/command/arguments/show_test.go | 21 ++++- internal/command/import.go | 94 ++++++++++--------- internal/command/show.go | 63 ++++++++++++- .../incorrectmodulename/output.json | 54 +---------- 5 files changed, 128 insertions(+), 109 deletions(-) diff --git a/internal/command/arguments/show.go b/internal/command/arguments/show.go index ebadf64cf8..03f9b029a1 100644 --- a/internal/command/arguments/show.go +++ b/internal/command/arguments/show.go @@ -15,6 +15,8 @@ type Show struct { // ViewType specifies which output format to use: human, JSON, or "raw". ViewType ViewType + + Vars *Vars } // ParseShow processes CLI arguments, returning a Show value and errors. @@ -24,10 +26,11 @@ func ParseShow(args []string) (*Show, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics show := &Show{ Path: "", + Vars: &Vars{}, } var jsonOutput bool - cmdFlags := defaultFlagSet("show") + cmdFlags := extendedFlagSet("show", nil, nil, show.Vars) cmdFlags.BoolVar(&jsonOutput, "json", false, "json") if err := cmdFlags.Parse(args); err != nil { diff --git a/internal/command/arguments/show_test.go b/internal/command/arguments/show_test.go index 4cee25ab20..6104e69e44 100644 --- a/internal/command/arguments/show_test.go +++ b/internal/command/arguments/show_test.go @@ -6,6 +6,8 @@ package arguments import ( "testing" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/hashicorp/terraform/internal/tfdiags" ) @@ -19,6 +21,7 @@ func TestParseShow_valid(t *testing.T) { &Show{ Path: "", ViewType: ViewHuman, + Vars: &Vars{}, }, }, "json": { @@ -26,6 +29,7 @@ func TestParseShow_valid(t *testing.T) { &Show{ Path: "", ViewType: ViewJSON, + Vars: &Vars{}, }, }, "path": { @@ -33,18 +37,21 @@ func TestParseShow_valid(t *testing.T) { &Show{ Path: "foo", ViewType: ViewJSON, + Vars: &Vars{}, }, }, } + cmpOpts := cmpopts.IgnoreUnexported(Operation{}, Vars{}, State{}) + for name, tc := range testCases { t.Run(name, func(t *testing.T) { got, diags := ParseShow(tc.args) - if len(diags) > 0 { + if len(diags) > 0 && diags.HasErrors() { t.Fatalf("unexpected diags: %v", diags) } - if *got != *tc.want { - t.Fatalf("unexpected result\n got: %#v\nwant: %#v", got, tc.want) + if diff := cmp.Diff(tc.want, got, cmpOpts); diff != "" { + t.Errorf("unexpected result\n%s", diff) } }) } @@ -61,6 +68,7 @@ func TestParseShow_invalid(t *testing.T) { &Show{ Path: "", ViewType: ViewHuman, + Vars: &Vars{}, }, tfdiags.Diagnostics{ tfdiags.Sourceless( @@ -75,6 +83,7 @@ func TestParseShow_invalid(t *testing.T) { &Show{ Path: "bar", ViewType: ViewJSON, + Vars: &Vars{}, }, tfdiags.Diagnostics{ tfdiags.Sourceless( @@ -86,11 +95,13 @@ func TestParseShow_invalid(t *testing.T) { }, } + cmpOpts := cmpopts.IgnoreUnexported(Operation{}, Vars{}, State{}) + for name, tc := range testCases { t.Run(name, func(t *testing.T) { got, gotDiags := ParseShow(tc.args) - if *got != *tc.want { - t.Fatalf("unexpected result\n got: %#v\nwant: %#v", got, tc.want) + if diff := cmp.Diff(tc.want, got, cmpOpts); diff != "" { + t.Errorf("unexpected result\n%s", diff) } tfdiags.AssertDiagnosticsMatch(t, gotDiags, tc.wantDiags) }) diff --git a/internal/command/import.go b/internal/command/import.go index dfc0e2c7d4..f733fa2ae8 100644 --- a/internal/command/import.go +++ b/internal/command/import.go @@ -86,6 +86,54 @@ func (c *ImportCommand) Run(args []string) int { return 1 } + // Load the backend + b, backendDiags := c.backend(".", arguments.ViewHuman) + diags = diags.Append(backendDiags) + if backendDiags.HasErrors() { + c.showDiagnostics(diags) + return 1 + } + + // We require a backendrun.Local to build a context. + // This isn't necessarily a "local.Local" backend, which provides local + // operations, however that is the only current implementation. A + // "local.Local" backend also doesn't necessarily provide local state, as + // that may be delegated to a "remotestate.Backend". + local, ok := b.(backendrun.Local) + if !ok { + c.Ui.Error(ErrUnsupportedLocalOp) + return 1 + } + + // Build the operation + var err error + opReq := c.Operation(b, arguments.ViewHuman) + opReq.ConfigDir = parsedArgs.ConfigPath + opReq.ConfigLoader, err = c.initConfigLoader() + if err != nil { + diags = diags.Append(err) + c.showDiagnostics(diags) + return 1 + } + opReq.Hooks = []terraform.Hook{c.uiHook()} + + { + // Collect variable value and add them to the operation request + var varDiags tfdiags.Diagnostics + opReq.Variables, varDiags = parsedArgs.Vars.CollectValues(func(filename string, src []byte) { + opReq.ConfigLoader.Parser().ForceFileSource(filename, src) + }) + diags = diags.Append(varDiags) + + if varDiags.HasErrors() { + c.showDiagnostics(diags) + return 1 + } + + c.VariableValues = opReq.Variables + } + opReq.View = views.NewOperation(arguments.ViewHuman, c.RunningInAutomation, c.View) + // Load the full config, so we can verify that the target resource is // already configured. config, configDiags := c.loadConfig(parsedArgs.ConfigPath) @@ -144,57 +192,11 @@ func (c *ImportCommand) Run(args []string) int { } // Check for user-supplied plugin path - var err error if c.pluginPath, err = c.loadPluginPath(); err != nil { c.Ui.Error(fmt.Sprintf("Error loading plugin path: %s", err)) return 1 } - // Load the backend - b, backendDiags := c.backend(".", arguments.ViewHuman) - diags = diags.Append(backendDiags) - if backendDiags.HasErrors() { - c.showDiagnostics(diags) - return 1 - } - - // We require a backendrun.Local to build a context. - // This isn't necessarily a "local.Local" backend, which provides local - // operations, however that is the only current implementation. A - // "local.Local" backend also doesn't necessarily provide local state, as - // that may be delegated to a "remotestate.Backend". - local, ok := b.(backendrun.Local) - if !ok { - c.Ui.Error(ErrUnsupportedLocalOp) - return 1 - } - - // Build the operation - opReq := c.Operation(b, arguments.ViewHuman) - opReq.ConfigDir = parsedArgs.ConfigPath - opReq.ConfigLoader, err = c.initConfigLoader() - if err != nil { - diags = diags.Append(err) - c.showDiagnostics(diags) - return 1 - } - opReq.Hooks = []terraform.Hook{c.uiHook()} - - { - // Collect variable value and add them to the operation request - var varDiags tfdiags.Diagnostics - opReq.Variables, varDiags = parsedArgs.Vars.CollectValues(func(filename string, src []byte) { - opReq.ConfigLoader.Parser().ForceFileSource(filename, src) - }) - diags = diags.Append(varDiags) - - if varDiags.HasErrors() { - c.showDiagnostics(diags) - return 1 - } - } - opReq.View = views.NewOperation(arguments.ViewHuman, c.RunningInAutomation, c.View) - // Check remote Terraform version is compatible remoteVersionDiags := c.remoteVersionCheck(b, opReq.Workspace) diags = diags.Append(remoteVersionDiags) diff --git a/internal/command/show.go b/internal/command/show.go index 19a829dfd2..eb7aed4422 100644 --- a/internal/command/show.go +++ b/internal/command/show.go @@ -11,11 +11,13 @@ import ( "strings" "github.com/hashicorp/terraform/internal/backend" + "github.com/hashicorp/terraform/internal/backend/backendrun" "github.com/hashicorp/terraform/internal/cloud" "github.com/hashicorp/terraform/internal/cloud/cloudplan" "github.com/hashicorp/terraform/internal/command/arguments" "github.com/hashicorp/terraform/internal/command/views" "github.com/hashicorp/terraform/internal/configs" + "github.com/hashicorp/terraform/internal/configs/configload" "github.com/hashicorp/terraform/internal/plans" "github.com/hashicorp/terraform/internal/plans/planfile" "github.com/hashicorp/terraform/internal/states/statefile" @@ -66,8 +68,20 @@ func (c *ShowCommand) Run(rawArgs []string) int { // Set up view view := views.NewShow(args.ViewType, c.View) + loader, err := c.initConfigLoader() + if err != nil { + diags = diags.Append(err) + view.Diagnostics(diags) + return 1 + } + + var varDiags tfdiags.Diagnostics + c.VariableValues, varDiags = args.Vars.CollectValues(func(filename string, src []byte) { + loader.Parser().ForceFileSource(filename, src) + }) + diags = diags.Append(varDiags) + // Check for user-supplied plugin path - var err error if c.pluginPath, err = c.loadPluginPath(); err != nil { diags = diags.Append(fmt.Errorf("error loading plugin path: %s", err)) view.Diagnostics(diags) @@ -267,7 +281,7 @@ func (c *ShowCommand) getPlanFromPath(path string) (*plans.Plan, *cloudplan.Remo } if lp, ok := pf.Local(); ok { - plan, stateFile, config, err = getDataFromPlanfileReader(lp, c.Meta.AllowExperimentalFeatures) + plan, stateFile, config, err = getDataFromPlanfileReader(lp, c.Meta.AllowExperimentalFeatures, c.Meta.VariableValues) } else if cp, ok := pf.Cloud(); ok { redacted := c.viewType != arguments.ViewJSON jsonPlan, err = c.getDataFromCloudPlan(cp, redacted) @@ -297,7 +311,7 @@ func (c *ShowCommand) getDataFromCloudPlan(plan *cloudplan.SavedPlanBookmark, re } // getDataFromPlanfileReader returns a plan, statefile, and config, extracted from a local plan file. -func getDataFromPlanfileReader(planReader *planfile.Reader, allowLanguageExperiments bool) (*plans.Plan, *statefile.File, *configs.Config, error) { +func getDataFromPlanfileReader(planReader *planfile.Reader, allowLanguageExperiments bool, variableValues map[string]arguments.UnparsedVariableValue) (*plans.Plan, *statefile.File, *configs.Config, error) { // Get plan plan, err := planReader.ReadPlan() if err != nil { @@ -311,7 +325,7 @@ func getDataFromPlanfileReader(planReader *planfile.Reader, allowLanguageExperim } // Get config - config, diags := planReader.ReadConfig(allowLanguageExperiments) + config, diags := readConfig(planReader, allowLanguageExperiments, variableValues) if diags.HasErrors() { return nil, nil, nil, errUnusable(diags.Err(), "local plan") } @@ -319,6 +333,47 @@ func getDataFromPlanfileReader(planReader *planfile.Reader, allowLanguageExperim return plan, stateFile, config, err } +func readConfig(r *planfile.Reader, allowLanguageExperiments bool, variableValues map[string]arguments.UnparsedVariableValue) (*configs.Config, tfdiags.Diagnostics) { + var diags tfdiags.Diagnostics + + snap, err := r.ReadConfigSnapshot() + if err != nil { + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Failed to read configuration from plan file", + fmt.Sprintf("The configuration file snapshot in the plan file could not be read: %s.", err), + )) + return nil, diags + } + + loader := configload.NewLoaderFromSnapshot(snap) + loader.AllowLanguageExperiments(allowLanguageExperiments) + rootMod, rootDiags := loader.LoadRootModule(snap.Modules[""].Dir) + diags = diags.Append(rootDiags) + if rootDiags.HasErrors() { + return nil, diags + } + + variables, varDiags := backendrun.ParseVariableValues(variableValues, rootMod.Variables) + diags = diags.Append(varDiags) + if diags.HasErrors() { + return nil, diags + } + + config, buildDiags := terraform.BuildConfigWithGraph( + rootMod, + loader.ModuleWalker(), + variables, + configs.MockDataLoaderFunc(loader.LoadExternalMockData), + ) + diags = diags.Append(buildDiags) + if buildDiags.HasErrors() { + return nil, diags + } + + return config, diags +} + // getStateFromPath returns a statefile if the user-supplied path points to a statefile. func getStateFromPath(path string) (*statefile.File, error) { file, err := os.Open(path) diff --git a/internal/command/testdata/validate-invalid/incorrectmodulename/output.json b/internal/command/testdata/validate-invalid/incorrectmodulename/output.json index f144313fa4..d167b1b142 100644 --- a/internal/command/testdata/validate-invalid/incorrectmodulename/output.json +++ b/internal/command/testdata/validate-invalid/incorrectmodulename/output.json @@ -1,7 +1,7 @@ { "format_version": "1.0", "valid": false, - "error_count": 4, + "error_count": 2, "warning_count": 0, "diagnostics": [ { @@ -55,58 +55,6 @@ "highlight_end_offset": 21, "values": [] } - }, - { - "severity": "error", - "summary": "Variables not allowed", - "detail": "Variables may not be used here.", - "range": { - "filename": "testdata/validate-invalid/incorrectmodulename/main.tf", - "start": { - "line": 5, - "column": 12, - "byte": 55 - }, - "end": { - "line": 5, - "column": 15, - "byte": 58 - } - }, - "snippet": { - "context": "module \"super\"", - "code": " source = var.modulename", - "start_line": 5, - "highlight_start_offset": 11, - "highlight_end_offset": 14, - "values": [] - } - }, - { - "severity": "error", - "summary": "Unsuitable value type", - "detail": "Unsuitable value: value must be known", - "range": { - "filename": "testdata/validate-invalid/incorrectmodulename/main.tf", - "start": { - "line": 5, - "column": 12, - "byte": 55 - }, - "end": { - "line": 5, - "column": 26, - "byte": 69 - } - }, - "snippet": { - "context": "module \"super\"", - "code": " source = var.modulename", - "start_line": 5, - "highlight_start_offset": 11, - "highlight_end_offset": 25, - "values": [] - } } ] } From 834c2f4c21cb2671a13e7847ef1f837b5b519ab9 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 17:45:59 +0100 Subject: [PATCH 16/24] Fix modules command To be able to show version constraint from modules, we now store them during configuration loading. --- internal/configs/config.go | 7 +++++++ internal/moduleref/resolver.go | 6 ++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/configs/config.go b/internal/configs/config.go index 150af76314..a258f94173 100644 --- a/internal/configs/config.go +++ b/internal/configs/config.go @@ -87,6 +87,13 @@ type Config struct { // This field is meaningless for the root module, where it will always // be nil. Version *version.Version + + // VersionConstraint is the version constraint that was specified for this module. + // This field is nil if no version constraint was specified. + // + // This field is meaningless for the root module, where it will always + // be nil. + VersionConstraint VersionConstraint } // ModuleRequirements represents the provider requirements for an individual diff --git a/internal/moduleref/resolver.go b/internal/moduleref/resolver.go index 8871abc49a..081579dcee 100644 --- a/internal/moduleref/resolver.go +++ b/internal/moduleref/resolver.go @@ -56,12 +56,10 @@ func (r *Resolver) findAndTrimReferencedEntries(cfg *configs.Config, parentRecor var name string var versionConstraints version.Constraints if parentKey != nil { - for key := range cfg.Parent.Children { + for key, child := range cfg.Parent.Children { if key == *parentKey { name = key - if cfg.Parent.Module.ModuleCalls[key] != nil { - versionConstraints = cfg.Parent.Module.ModuleCalls[key].Version.Required - } + versionConstraints = child.VersionConstraint.Required break } } From 65c7a3b9f390ee142219424b79476e5759df81dd Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Thu, 26 Feb 2026 17:54:36 +0100 Subject: [PATCH 17/24] Add changelog --- .changes/v1.15/NEW FEATURES-20260226-175431.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/v1.15/NEW FEATURES-20260226-175431.yaml diff --git a/.changes/v1.15/NEW FEATURES-20260226-175431.yaml b/.changes/v1.15/NEW FEATURES-20260226-175431.yaml new file mode 100644 index 0000000000..73de4ec6c7 --- /dev/null +++ b/.changes/v1.15/NEW FEATURES-20260226-175431.yaml @@ -0,0 +1,5 @@ +kind: NEW FEATURES +body: Terraform now supports variables and locals in module source and version attributes +time: 2026-02-26T17:54:31.157412+01:00 +custom: + Issue: "38217" From 55198eb2219c063aad8c53b2a495282dcba91873 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Mon, 2 Mar 2026 13:03:55 +0100 Subject: [PATCH 18/24] Feedback: Rename remaining static -> const --- internal/command/meta_config.go | 8 ++++---- internal/terraform/context_init_test.go | 16 ++++++++-------- internal/terraform/node_module_variable.go | 4 ++-- internal/terraform/node_root_variable.go | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/command/meta_config.go b/internal/command/meta_config.go index 15b56cc2ee..02f0b8415f 100644 --- a/internal/command/meta_config.go +++ b/internal/command/meta_config.go @@ -58,7 +58,7 @@ func (m *Meta) loadConfig(rootDir string) (*configs.Config, tfdiags.Diagnostics) cfg.Root = cfg // Root module is self-referential. return cfg, diags } - betterVars, parseDiags := backendrun.ParseVariableValues(m.VariableValues, rootMod.Variables) + vars, parseDiags := backendrun.ParseVariableValues(m.VariableValues, rootMod.Variables) diags = diags.Append(parseDiags) if parseDiags.HasErrors() { return nil, diags @@ -66,7 +66,7 @@ func (m *Meta) loadConfig(rootDir string) (*configs.Config, tfdiags.Diagnostics) config, buildDiags := terraform.BuildConfigWithGraph( rootMod, loader.ModuleWalker(), - betterVars, + vars, configs.MockDataLoaderFunc(loader.LoadExternalMockData), ) diags = diags.Append(buildDiags) @@ -95,7 +95,7 @@ func (m *Meta) loadConfigWithTests(rootDir, testDir string) (*configs.Config, tf cfg.Root = cfg // Root module is self-referential. return cfg, diags } - betterVars, parseDiags := backendrun.ParseConstVariableValues(m.VariableValues, rootMod.Variables) + vars, parseDiags := backendrun.ParseConstVariableValues(m.VariableValues, rootMod.Variables) diags = diags.Append(parseDiags) if parseDiags.HasErrors() { return nil, diags @@ -103,7 +103,7 @@ func (m *Meta) loadConfigWithTests(rootDir, testDir string) (*configs.Config, tf config, buildDiags := terraform.BuildConfigWithGraph( rootMod, loader.ModuleWalker(), - betterVars, + vars, configs.MockDataLoaderFunc(loader.LoadExternalMockData), ) diags = diags.Append(buildDiags) diff --git a/internal/terraform/context_init_test.go b/internal/terraform/context_init_test.go index c9f7f59fd7..5e532dff3b 100644 --- a/internal/terraform/context_init_test.go +++ b/internal/terraform/context_init_test.go @@ -117,7 +117,7 @@ module "example" { }}, }, - "local with non-static variables": { + "local with non-const variables": { module: map[string]string{ "main.tf": ` variable "name" { @@ -134,7 +134,7 @@ module "example" { expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { // TODO: We should try to somehow add an "extra" into the diagnostics to indicate - // that this may be caused by a non-static variable used during init. + // that this may be caused by a non-const variable used during init. return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: `Invalid module source`, @@ -513,7 +513,7 @@ output "name" { }}, }, - "static variable with no value and no default": { + "const variable with no value and no default": { module: map[string]string{"main.tf": ` variable "name" { type = string @@ -538,7 +538,7 @@ module "example" { }, }, - "static variable with default": { + "const variable with default": { module: map[string]string{"main.tf": ` variable "name" { type = string @@ -555,7 +555,7 @@ module "example" { }}, }, - "non-static variable passed into static module variable": { + "non-const variable passed into const module variable": { module: map[string]string{"main.tf": ` variable "name" { type = string @@ -583,8 +583,8 @@ variable "name" { expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: `Static variables must be known`, - Detail: `Only a static value can be passed into a static module variable.`, + Summary: `Const variables must be known`, + Detail: `Only a constant value can be passed into a constant module variable.`, Subject: &hcl.Range{ Filename: filepath.Join(m.SourceDir, "main.tf"), Start: hcl.Pos{Line: 8, Column: 10, Byte: 118}, @@ -621,7 +621,7 @@ module "nested" { }}, expectDiags: func(m *configs.Module, mc map[string]*configs.Module) tfdiags.Diagnostics { // TODO: We should try to somehow add an "extra" into the diagnostics to indicate - // that this may be caused by a non-static variable used during init. + // that this may be caused by a non-const variable used during init. return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: `Invalid module source`, diff --git a/internal/terraform/node_module_variable.go b/internal/terraform/node_module_variable.go index 7672906851..7458fd4173 100644 --- a/internal/terraform/node_module_variable.go +++ b/internal/terraform/node_module_variable.go @@ -251,8 +251,8 @@ func (n *nodeModuleVariable) Execute(ctx EvalContext, op walkOperation) (diags t if op == walkInit && n.Config.Const && !val.IsWhollyKnown() { diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Static variables must be known", - Detail: "Only a static value can be passed into a static module variable.", + Summary: "Const variables must be known", + Detail: "Only a constant value can be passed into a constant module variable.", Subject: errSourceRange.ToHCL().Ptr(), }) } diff --git a/internal/terraform/node_root_variable.go b/internal/terraform/node_root_variable.go index 694a65a0a7..5bf530a86f 100644 --- a/internal/terraform/node_root_variable.go +++ b/internal/terraform/node_root_variable.go @@ -110,7 +110,7 @@ func (n *NodeRootVariable) Execute(ctx EvalContext, op walkOperation) tfdiags.Di } } - // During init we only want to prepare the final value for static variables. + // During init we only want to prepare the final value for const variables. if op == walkInit { var finalVal cty.Value if n.Config.Const { @@ -127,7 +127,7 @@ func (n *NodeRootVariable) Execute(ctx EvalContext, op walkOperation) tfdiags.Di return diags } } else { - // All non-static variables are unknown during init. + // All non-const variables are unknown during init. finalVal = cty.UnknownVal(n.Config.Type) } ctx.NamedValues().SetInputVariableValue(addr, finalVal) From b6804e2edd1a858c557f5737878162ded339c858 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Mon, 2 Mar 2026 14:26:46 +0100 Subject: [PATCH 19/24] Use configuration values for jsonconfig Instead of outputting the raw values from the ModuleCall, we're now using the evaluated values from the Config. This should keep the JSON output unchanged, we just need to make sure to persist the values in `Config` when loading the configuration. --- internal/command/jsonconfig/config.go | 25 +- .../show-json/module-depends-on/output.json | 152 ++--- .../testdata/show-json/modules/output.json | 584 +++++++++--------- .../show-json/nested-modules/output.json | 8 +- .../provider-aliasing-conflict/output.json | 12 +- .../provider-aliasing-default/output.json | 28 +- .../show-json/provider-aliasing/output.json | 56 +- internal/terraform/node_module_install.go | 32 +- 8 files changed, 463 insertions(+), 434 deletions(-) diff --git a/internal/command/jsonconfig/config.go b/internal/command/jsonconfig/config.go index d466f44d4b..3338fb336a 100644 --- a/internal/command/jsonconfig/config.go +++ b/internal/command/jsonconfig/config.go @@ -49,12 +49,12 @@ type module struct { } type moduleCall struct { - SourceExpression *expression `json:"source,omitempty"` + Source string `json:"source,omitempty"` Expressions map[string]interface{} `json:"expressions,omitempty"` CountExpression *expression `json:"count_expression,omitempty"` ForEachExpression *expression `json:"for_each_expression,omitempty"` Module module `json:"module,omitempty"` - VersionConstraint *expression `json:"version_constraint,omitempty"` + VersionConstraint string `json:"version_constraint,omitempty"` DependsOn []string `json:"depends_on,omitempty"` } @@ -415,18 +415,15 @@ func marshalModuleCall(c *configs.Config, mc *configs.ModuleCall, schemas *terra return moduleCall{} } - ret := moduleCall{} - // We're intentionally echoing back exactly what the user entered - // here, rather than the normalized version in SourceAddr, because - // historically we only _had_ the raw address and thus it would be - // a (admittedly minor) breaking change to start normalizing them - // now, in case consumers of this data are expecting a particular - // non-normalized syntax. - sExp := marshalExpression(mc.SourceExpr) - ret.SourceExpression = &sExp - if mc.VersionExpr != nil { - vExp := marshalExpression(mc.VersionExpr) - ret.VersionConstraint = &vExp + ret := moduleCall{ + // We're intentionally echoing back exactly what the user entered + // here, rather than the normalized version in SourceAddr, because + // historically we only _had_ the raw address and thus it would be + // a (admittedly minor) breaking change to start normalizing them + // now, in case consumers of this data are expecting a particular + // non-normalized syntax. + Source: c.SourceAddrRaw, + VersionConstraint: c.VersionConstraint.Required.String(), } cExp := marshalExpression(mc.Count) diff --git a/internal/command/testdata/show-json/module-depends-on/output.json b/internal/command/testdata/show-json/module-depends-on/output.json index e29262037c..59f4a1bce9 100644 --- a/internal/command/testdata/show-json/module-depends-on/output.json +++ b/internal/command/testdata/show-json/module-depends-on/output.json @@ -1,85 +1,87 @@ { - "format_version": "1.0", - "terraform_version": "0.13.1-dev", - "applyable": true, - "complete": true, - "planned_values": { - "root_module": { - "resources": [ - { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "foo-bar" - }, - "sensitive_values": {} + "format_version": "1.0", + "terraform_version": "0.13.1-dev", + "applyable": true, + "complete": true, + "planned_values": { + "root_module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "foo-bar" + }, + "sensitive_values": {} + } + ] } - ] - } - }, - "resource_changes": [ - { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_name": "registry.terraform.io/hashicorp/test", - "change": { - "actions": ["create"], - "before": null, - "after": { - "ami": "foo-bar" - }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - } - ], - "configuration": { - "provider_config": { - "test": { - "name": "test", - "full_name": "registry.terraform.io/hashicorp/test" - } }, - "root_module": { - "resources": [ + "resource_changes": [ { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_config_key": "test", - "expressions": { - "ami": { - "constant_value": "foo-bar" + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "foo-bar" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false } - }, - "schema_version": 0 } - ], - "module_calls": { - "foo": { - "depends_on": ["test_instance.test"], - "source": { - "constant_value": "./foo" - }, - "module": { - "variables": { - "test_var": { - "default": "foo-var" - } + ], + "configuration": { + "provider_config": { + "test": { + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + }, + "root_module": { + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "test", + "expressions": { + "ami": { + "constant_value": "foo-bar" + } + }, + "schema_version": 0 + } + ], + "module_calls": { + "foo": { + "depends_on": [ + "test_instance.test" + ], + "source": "./foo", + "module": { + "variables": { + "test_var": { + "default": "foo-var" + } + } + } + } } - } } - } } - } } diff --git a/internal/command/testdata/show-json/modules/output.json b/internal/command/testdata/show-json/modules/output.json index db9cb2f9a9..96a5f490a6 100644 --- a/internal/command/testdata/show-json/modules/output.json +++ b/internal/command/testdata/show-json/modules/output.json @@ -1,292 +1,308 @@ { - "format_version": "1.0", - "applyable": true, - "complete": true, - "planned_values": { - "outputs": { - "test": { - "sensitive": false, - "type": "string", - "value": "baz" - } - }, - "root_module": { - "child_modules": [ - { - "resources": [ - { - "address": "module.module_test_bar.test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "bar-var" - }, - "sensitive_values": {} - } - ], - "address": "module.module_test_bar" - }, - { - "resources": [ - { - "address": "module.module_test_foo.test_instance.test[0]", - "mode": "managed", - "type": "test_instance", - "name": "test", - "index": 0, - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "baz" - }, - "sensitive_values": {} - }, - { - "address": "module.module_test_foo.test_instance.test[1]", - "mode": "managed", - "type": "test_instance", - "name": "test", - "index": 1, - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "baz" - }, - "sensitive_values": {} - }, - { - "address": "module.module_test_foo.test_instance.test[2]", - "mode": "managed", - "type": "test_instance", - "name": "test", - "index": 2, - "provider_name": "registry.terraform.io/hashicorp/test", - "schema_version": 0, - "values": { - "ami": "baz" - }, - "sensitive_values": {} - } - ], - "address": "module.module_test_foo" - } - ] - } - }, - "prior_state": { "format_version": "1.0", - "values": { - "outputs": { - "test": { - "sensitive": false, - "type": "string", - "value": "baz" - } - }, - "root_module": {} - } - }, - "resource_changes": [ - { - "address": "module.module_test_bar.test_instance.test", - "module_address": "module.module_test_bar", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_name": "registry.terraform.io/hashicorp/test", - "change": { - "actions": ["create"], - "before": null, - "after": { - "ami": "bar-var" + "applyable": true, + "complete": true, + "planned_values": { + "outputs": { + "test": { + "sensitive": false, + "type": "string", + "value": "baz" + } }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - }, - { - "address": "module.module_test_foo.test_instance.test[0]", - "module_address": "module.module_test_foo", - "mode": "managed", - "type": "test_instance", - "provider_name": "registry.terraform.io/hashicorp/test", - "name": "test", - "index": 0, - "change": { - "actions": ["create"], - "before": null, - "after": { - "ami": "baz" - }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - }, - { - "address": "module.module_test_foo.test_instance.test[1]", - "module_address": "module.module_test_foo", - "mode": "managed", - "type": "test_instance", - "provider_name": "registry.terraform.io/hashicorp/test", - "name": "test", - "index": 1, - "change": { - "actions": ["create"], - "before": null, - "after": { - "ami": "baz" - }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - }, - { - "address": "module.module_test_foo.test_instance.test[2]", - "module_address": "module.module_test_foo", - "mode": "managed", - "type": "test_instance", - "provider_name": "registry.terraform.io/hashicorp/test", - "name": "test", - "index": 2, - "change": { - "actions": ["create"], - "before": null, - "after": { - "ami": "baz" - }, - "after_unknown": { - "id": true - }, - "after_sensitive": {}, - "before_sensitive": false - } - } - ], - "output_changes": { - "test": { - "actions": ["create"], - "before": null, - "after": "baz", - "after_unknown": false, - "before_sensitive": false, - "after_sensitive": false - } - }, - "configuration": { - "root_module": { - "outputs": { - "test": { - "expression": { - "references": [ - "module.module_test_foo.test", - "module.module_test_foo" + "root_module": { + "child_modules": [ + { + "resources": [ + { + "address": "module.module_test_bar.test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "bar-var" + }, + "sensitive_values": {} + } + ], + "address": "module.module_test_bar" + }, + { + "resources": [ + { + "address": "module.module_test_foo.test_instance.test[0]", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 0, + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "baz" + }, + "sensitive_values": {} + }, + { + "address": "module.module_test_foo.test_instance.test[1]", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 1, + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "baz" + }, + "sensitive_values": {} + }, + { + "address": "module.module_test_foo.test_instance.test[2]", + "mode": "managed", + "type": "test_instance", + "name": "test", + "index": 2, + "provider_name": "registry.terraform.io/hashicorp/test", + "schema_version": 0, + "values": { + "ami": "baz" + }, + "sensitive_values": {} + } + ], + "address": "module.module_test_foo" + } ] - }, - "depends_on": ["module.module_test_foo"] } - }, - "module_calls": { - "module_test_bar": { - "source": { - "constant_value": "./bar" - }, - "module": { - "outputs": { - "test": { - "expression": { - "references": ["var.test_var"] - } - } - }, - "resources": [ - { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_config_key": "module.module_test_bar:test", - "expressions": { - "ami": { - "references": ["var.test_var"] - } - }, - "schema_version": 0 - } - ], - "variables": { - "test_var": { - "default": "bar-var" - } - } - } - }, - "module_test_foo": { - "source": { - "constant_value": "./foo" - }, - "expressions": { - "test_var": { - "constant_value": "baz" - } - }, - "module": { - "outputs": { - "test": { - "expression": { - "references": ["var.test_var"] - } - } - }, - "resources": [ - { - "address": "test_instance.test", - "mode": "managed", - "type": "test_instance", - "name": "test", - "provider_config_key": "module.module_test_foo:test", - "expressions": { - "ami": { - "references": ["var.test_var"] - } - }, - "schema_version": 0, - "count_expression": { - "constant_value": 3 - } - } - ], - "variables": { - "test_var": { - "default": "foo-var" - } - } - } - } - } }, - "provider_config": { - "module.module_test_foo:test": { - "module_address": "module.module_test_foo", - "name": "test", - "full_name": "registry.terraform.io/hashicorp/test" - }, - "module.module_test_bar:test": { - "module_address": "module.module_test_bar", - "name": "test", - "full_name": "registry.terraform.io/hashicorp/test" - } + "prior_state": { + "format_version": "1.0", + "values": { + "outputs": { + "test": { + "sensitive": false, + "type": "string", + "value": "baz" + } + }, + "root_module": {} + } + }, + "resource_changes": [ + { + "address": "module.module_test_bar.test_instance.test", + "module_address": "module.module_test_bar", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/test", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "bar-var" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false + } + }, + { + "address": "module.module_test_foo.test_instance.test[0]", + "module_address": "module.module_test_foo", + "mode": "managed", + "type": "test_instance", + "provider_name": "registry.terraform.io/hashicorp/test", + "name": "test", + "index": 0, + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false + } + }, + { + "address": "module.module_test_foo.test_instance.test[1]", + "module_address": "module.module_test_foo", + "mode": "managed", + "type": "test_instance", + "provider_name": "registry.terraform.io/hashicorp/test", + "name": "test", + "index": 1, + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false + } + }, + { + "address": "module.module_test_foo.test_instance.test[2]", + "module_address": "module.module_test_foo", + "mode": "managed", + "type": "test_instance", + "provider_name": "registry.terraform.io/hashicorp/test", + "name": "test", + "index": 2, + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "ami": "baz" + }, + "after_unknown": { + "id": true + }, + "after_sensitive": {}, + "before_sensitive": false + } + } + ], + "output_changes": { + "test": { + "actions": [ + "create" + ], + "before": null, + "after": "baz", + "after_unknown": false, + "before_sensitive": false, + "after_sensitive": false + } + }, + "configuration": { + "root_module": { + "outputs": { + "test": { + "expression": { + "references": [ + "module.module_test_foo.test", + "module.module_test_foo" + ] + }, + "depends_on": [ + "module.module_test_foo" + ] + } + }, + "module_calls": { + "module_test_bar": { + "source": "./bar", + "module": { + "outputs": { + "test": { + "expression": { + "references": [ + "var.test_var" + ] + } + } + }, + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "module.module_test_bar:test", + "expressions": { + "ami": { + "references": [ + "var.test_var" + ] + } + }, + "schema_version": 0 + } + ], + "variables": { + "test_var": { + "default": "bar-var" + } + } + } + }, + "module_test_foo": { + "source": "./foo", + "expressions": { + "test_var": { + "constant_value": "baz" + } + }, + "module": { + "outputs": { + "test": { + "expression": { + "references": [ + "var.test_var" + ] + } + } + }, + "resources": [ + { + "address": "test_instance.test", + "mode": "managed", + "type": "test_instance", + "name": "test", + "provider_config_key": "module.module_test_foo:test", + "expressions": { + "ami": { + "references": [ + "var.test_var" + ] + } + }, + "schema_version": 0, + "count_expression": { + "constant_value": 3 + } + } + ], + "variables": { + "test_var": { + "default": "foo-var" + } + } + } + } + } + }, + "provider_config": { + "module.module_test_foo:test": { + "module_address": "module.module_test_foo", + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + }, + "module.module_test_bar:test": { + "module_address": "module.module_test_bar", + "name": "test", + "full_name": "registry.terraform.io/hashicorp/test" + } + } } - } } diff --git a/internal/command/testdata/show-json/nested-modules/output.json b/internal/command/testdata/show-json/nested-modules/output.json index cd2d6d9a0c..f96a24484d 100644 --- a/internal/command/testdata/show-json/nested-modules/output.json +++ b/internal/command/testdata/show-json/nested-modules/output.json @@ -63,15 +63,11 @@ "root_module": { "module_calls": { "my_module": { - "source": { - "constant_value": "./modules" - }, + "source": "./modules", "module": { "module_calls": { "more": { - "source": { - "constant_value": "./more-modules" - }, + "source": "./more-modules", "module": { "resources": [ { diff --git a/internal/command/testdata/show-json/provider-aliasing-conflict/output.json b/internal/command/testdata/show-json/provider-aliasing-conflict/output.json index c30f2774c9..b516a4a564 100644 --- a/internal/command/testdata/show-json/provider-aliasing-conflict/output.json +++ b/internal/command/testdata/show-json/provider-aliasing-conflict/output.json @@ -48,7 +48,9 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "foo" @@ -68,7 +70,9 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp2/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "bar" @@ -116,9 +120,7 @@ ], "module_calls": { "child": { - "source": { - "constant_value": "./child" - }, + "source": "./child", "module": { "resources": [ { diff --git a/internal/command/testdata/show-json/provider-aliasing-default/output.json b/internal/command/testdata/show-json/provider-aliasing-default/output.json index 5ccdc089b6..f2639da510 100644 --- a/internal/command/testdata/show-json/provider-aliasing-default/output.json +++ b/internal/command/testdata/show-json/provider-aliasing-default/output.json @@ -84,7 +84,9 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "foo" @@ -104,7 +106,9 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "bar" @@ -124,7 +128,9 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "qux" @@ -144,7 +150,9 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "baz" @@ -197,9 +205,7 @@ ], "module_calls": { "child": { - "source": { - "constant_value": "./child" - }, + "source": "./child", "module": { "resources": [ { @@ -218,9 +224,7 @@ ], "module_calls": { "no_requirements": { - "source": { - "constant_value": "./nested-no-requirements" - }, + "source": "./nested-no-requirements", "module": { "resources": [ { @@ -240,9 +244,7 @@ } }, "with_requirement": { - "source": { - "constant_value": "./nested" - }, + "source": "./nested", "depends_on": ["module.no_requirements"], "module": { "resources": [ diff --git a/internal/command/testdata/show-json/provider-aliasing/output.json b/internal/command/testdata/show-json/provider-aliasing/output.json index bb6429adc8..9f5675036e 100755 --- a/internal/command/testdata/show-json/provider-aliasing/output.json +++ b/internal/command/testdata/show-json/provider-aliasing/output.json @@ -163,7 +163,9 @@ "name": "test", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "foo" @@ -182,7 +184,9 @@ "name": "test_backup", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "foo-backup" @@ -202,7 +206,9 @@ "name": "test_primary", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "primary" @@ -222,7 +228,9 @@ "name": "test_secondary", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "secondary" @@ -242,7 +250,9 @@ "name": "test_primary", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "primary" @@ -262,7 +272,9 @@ "name": "test_secondary", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "secondary" @@ -282,7 +294,9 @@ "name": "test_alternate", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "secondary" @@ -302,7 +316,9 @@ "name": "test_main", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "main" @@ -322,7 +338,9 @@ "name": "test_alternate", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "secondary" @@ -342,7 +360,9 @@ "name": "test_main", "provider_name": "registry.terraform.io/hashicorp/test", "change": { - "actions": ["create"], + "actions": [ + "create" + ], "before": null, "after": { "ami": "main" @@ -408,9 +428,7 @@ ], "module_calls": { "child": { - "source": { - "constant_value": "./child" - }, + "source": "./child", "module": { "resources": [ { @@ -442,9 +460,7 @@ ], "module_calls": { "grandchild": { - "source": { - "constant_value": "./nested" - }, + "source": "./nested", "module": { "resources": [ { @@ -480,9 +496,7 @@ } }, "sibling": { - "source": { - "constant_value": "./child" - }, + "source": "./child", "module": { "resources": [ { @@ -514,9 +528,7 @@ ], "module_calls": { "grandchild": { - "source": { - "constant_value": "./nested" - }, + "source": "./nested", "module": { "resources": [ { diff --git a/internal/terraform/node_module_install.go b/internal/terraform/node_module_install.go index 9692c8cb56..a14b417165 100644 --- a/internal/terraform/node_module_install.go +++ b/internal/terraform/node_module_install.go @@ -77,7 +77,7 @@ func (n *nodeInstallModule) Execute(ctx EvalContext, walkOp walkOperation) tfdia var version configs.VersionConstraint if n.ModuleCall.VersionExpr != nil { var versionDiags tfdiags.Diagnostics - version, versionDiags = decodeVersionConstraint(n.ModuleCall.VersionExpr, ctx) + version, versionDiags = evalVersionConstraint(n.ModuleCall.VersionExpr, ctx) diags = diags.Append(versionDiags) if diags.HasErrors() { return diags @@ -85,7 +85,7 @@ func (n *nodeInstallModule) Execute(ctx EvalContext, walkOp walkOperation) tfdia } hasVersion := n.ModuleCall.VersionExpr != nil - source, sourceDiags := decodeSource(n.ModuleCall.SourceExpr, hasVersion, ctx) + source, sourceRaw, sourceDiags := evalSource(n.ModuleCall.SourceExpr, hasVersion, ctx) diags = diags.Append(sourceDiags) if diags.HasErrors() { return diags @@ -115,6 +115,7 @@ func (n *nodeInstallModule) Execute(ctx EvalContext, walkOp walkOperation) tfdia Children: map[string]*configs.Config{}, CallRange: n.ModuleCall.DeclRange, SourceAddr: source, + SourceAddrRaw: sourceRaw, SourceAddrRange: n.ModuleCall.SourceExpr.Range(), Version: v, VersionConstraint: version, @@ -153,7 +154,7 @@ func (n *nodeInstallModule) DynamicExpand(ctx EvalContext) (*Graph, tfdiags.Diag return &g, nil } -func decodeSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) (addrs.ModuleSource, tfdiags.Diagnostics) { +func evalSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) (addrs.ModuleSource, string, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics var addr addrs.ModuleSource var err error @@ -161,7 +162,7 @@ func decodeSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) ( refs, refsDiags := langrefs.ReferencesInExpr(addrs.ParseRef, sourceExpr) diags = diags.Append(refsDiags) if diags.HasErrors() { - return nil, diags + return nil, "", diags } for _, ref := range refs { @@ -175,14 +176,14 @@ func decodeSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) ( Detail: "The module source can only reference input variables and local values.", Subject: ref.SourceRange.ToHCL().Ptr(), }) - return nil, diags + return nil, "", diags } } value, valueDiags := ctx.EvaluateExpr(sourceExpr, cty.String, nil) diags = diags.Append(valueDiags) if diags.HasErrors() { - return nil, diags + return nil, "", diags } if !value.IsWhollyKnown() { @@ -194,20 +195,20 @@ func decodeSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) ( Detail: "The module source contains a reference that is unknown during init.", Subject: sourceExpr.Range().Ptr(), }) - return nil, diags + return nil, "", diags } for _, part := range tExpr.Parts { partVal, partDiags := ctx.EvaluateExpr(part, cty.DynamicPseudoType, nil) diags = diags.Append(partDiags) if diags.HasErrors() { - return nil, diags + return nil, "", diags } scope := ctx.EvaluationScope(nil, nil, EvalDataForNoInstanceKey) hclCtx, evalDiags := scope.EvalContext(refs) diags = diags.Append(evalDiags) if diags.HasErrors() { - return nil, diags + return nil, "", diags } if !partVal.IsKnown() { diags = diags.Append(&hcl.Diagnostic{ @@ -219,7 +220,7 @@ func decodeSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) ( EvalContext: hclCtx, Extra: diagnosticCausedByUnknown(true), }) - return nil, diags + return nil, "", diags } } diags = diags.Append(&hcl.Diagnostic{ @@ -228,13 +229,14 @@ func decodeSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) ( Detail: "The module source contains a reference that is unknown.", Subject: sourceExpr.Range().Ptr(), }) - return nil, diags + return nil, "", diags } + rawSource := value.AsString() if hasVersion { - addr, err = moduleaddrs.ParseModuleSourceRegistry(value.AsString()) + addr, err = moduleaddrs.ParseModuleSourceRegistry(rawSource) } else { - addr, err = moduleaddrs.ParseModuleSource(value.AsString()) + addr, err = moduleaddrs.ParseModuleSource(rawSource) } if err != nil { // NOTE: We leave add as nil for any situation where the @@ -283,10 +285,10 @@ func decodeSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) ( } } - return addr, diags + return addr, rawSource, diags } -func decodeVersionConstraint(versionExpr hcl.Expression, ctx EvalContext) (configs.VersionConstraint, tfdiags.Diagnostics) { +func evalVersionConstraint(versionExpr hcl.Expression, ctx EvalContext) (configs.VersionConstraint, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics rng := versionExpr.Range() From 45ba6796ba96278d590459715768cd566fa2c9db Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Fri, 27 Feb 2026 16:43:11 +0100 Subject: [PATCH 20/24] Add more dynamic module sources tests --- internal/command/init2_test.go | 700 ++++++++++++++++-- .../apply-plan-with-dynamic-source/main.tf | 9 + .../modules/example/main.tf | 3 + .../apply-with-dynamic-source/main.tf | 8 + .../modules/example/main.tf | 3 + .../count-in-module-source/main.tf | 4 + .../each-in-module-source/main.tf | 4 + .../source-module/main.tf | 8 + .../get-false-with-dynamic-source/main.tf | 8 + .../modules/example/empty.tf | 1 + .../local-source-with-local-value/main.tf | 12 + .../modules/example/empty.tf | 1 + .../main.tf | 7 + .../main.tf | 9 + .../modules/alternate/empty.tf | 0 .../modules/example/empty.tf | 1 + .../local-source-with-variable/main.tf | 8 + .../modules/example/empty.tf | 1 + .../local-source-with-varsfile/main.tf | 8 + .../modules/example/empty.tf | 1 + .../local-source-with-varsfile/test.tfvars | 1 + .../module-with-count/main.tf | 10 + .../module-with-count/modules/example/main.tf | 7 + .../module-with-for-each/main.tf | 10 + .../modules/example/main.tf | 7 + .../main.tf | 9 + .../modules/child/main.tf | 1 + .../modules/parent/main.tf | 8 + .../path-attr-in-module-source/main.tf | 3 + .../modules/example/empty.tf | 1 + .../plan-with-dynamic-source/main.tf | 8 + .../modules/example/main.tf | 3 + .../.terraform/modules/child/empty.tf | 1 + .../.terraform/modules/modules.json | 15 + .../plan-with-version-mismatch/main.tf | 15 + .../main.tf | 7 + .../modules/example/main.tf | 3 + .../source-with-resource-reference/main.tf | 5 + .../terraform-attr-in-module-source/main.tf | 3 + internal/terraform/node_module_install.go | 2 +- 40 files changed, 850 insertions(+), 65 deletions(-) create mode 100644 internal/command/testdata/dynamic-module-sources/apply-plan-with-dynamic-source/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/apply-plan-with-dynamic-source/modules/example/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/apply-with-dynamic-source/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/apply-with-dynamic-source/modules/example/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/count-in-module-source/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/each-in-module-source/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/from-module-with-dynamic-source/source-module/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/get-false-with-dynamic-source/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/get-false-with-dynamic-source/modules/example/empty.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-local-value/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-local-value/modules/example/empty.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-non-const-variable/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/modules/alternate/empty.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/modules/example/empty.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-variable/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-variable/modules/example/empty.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/modules/example/empty.tf create mode 100644 internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/test.tfvars create mode 100644 internal/command/testdata/dynamic-module-sources/module-with-count/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/module-with-count/modules/example/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/module-with-for-each/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/module-with-for-each/modules/example/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/modules/child/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/modules/parent/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/path-attr-in-module-source/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/path-attr-in-module-source/modules/example/empty.tf create mode 100644 internal/command/testdata/dynamic-module-sources/plan-with-dynamic-source/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/plan-with-dynamic-source/modules/example/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/.terraform/modules/child/empty.tf create mode 100644 internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/.terraform/modules/modules.json create mode 100644 internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/source-with-module-output-reference/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/source-with-module-output-reference/modules/example/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/source-with-resource-reference/main.tf create mode 100644 internal/command/testdata/dynamic-module-sources/terraform-attr-in-module-source/main.tf diff --git a/internal/command/init2_test.go b/internal/command/init2_test.go index 9dcfcf50c4..5efc70ce3b 100644 --- a/internal/command/init2_test.go +++ b/internal/command/init2_test.go @@ -4,6 +4,7 @@ package command import ( + "os" "path/filepath" "strings" "testing" @@ -11,11 +12,197 @@ import ( "github.com/hashicorp/cli" ) -func TestInit2_versionConstraintAdded(t *testing.T) { - // This test is for what happens when there is a version constraint added - // to a module that previously didn't have one. +func TestInit2_dynamicSourceErrors(t *testing.T) { + tests := map[string]struct { + fixture string + args []string + wantError string + }{ + "version constraint added to previously unversioned module": { + fixture: "add-version-constraint", + args: []string{"-get=false"}, + wantError: "Module version requirements have changed", + }, + "invalid registry source with version argument": { + fixture: "invalid-registry-source-with-module", + wantError: "Invalid registry module source address", + }, + "local source with version argument": { + fixture: "local-source-with-version", + wantError: "Invalid registry module source address", + }, + "non-const variable in module source": { + fixture: "local-source-with-non-const-variable", + args: []string{"-var", "module_name=example"}, + wantError: "Invalid module source", + }, + "resource reference in module source": { + fixture: "source-with-resource-reference", + wantError: "Invalid module source", + }, + "module output reference in module source": { + fixture: "source-with-module-output-reference", + wantError: "Invalid module source", + }, + "each.key in module source": { + fixture: "each-in-module-source", + wantError: "Invalid module source", + }, + "count.index in module source": { + fixture: "count-in-module-source", + wantError: "Invalid module source", + }, + "terraform.workspace in module source": { + fixture: "terraform-attr-in-module-source", + wantError: "Invalid module source", + }, + "required const variable not set": { + fixture: "local-source-with-variable", + wantError: "No value for required variable", + }, + "override default with nonexistent module": { + fixture: "local-source-with-variable-default", + args: []string{"-var", "module_name=nonexistent"}, + wantError: "", // any error; the module directory doesn't exist + }, + "version mismatch with dynamic constraint": { + fixture: "plan-with-version-mismatch", + args: []string{"-get=false", "-var", "module_version=0.0.2"}, + wantError: "Module version requirements have changed", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", tc.fixture)), td) + t.Chdir(td) + + ui := new(cli.MockUi) + view, done := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } + + code := c.Run(tc.args) + testOutput := done(t) + if code != 1 { + t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) + } + + if tc.wantError != "" { + got := testOutput.All() + if !strings.Contains(got, tc.wantError) { + t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, tc.wantError) + } + } + }) + } +} + +func TestInit2_dynamicSourceSuccess(t *testing.T) { + tests := map[string]struct { + fixture string + args []string + }{ + "const variable via -var": { + fixture: "local-source-with-variable", + args: []string{"-var", "module_name=example"}, + }, + "const variable with default value": { + fixture: "local-source-with-variable-default", + }, + "local value referencing const variable": { + fixture: "local-source-with-local-value", + args: []string{"-var", "module_name=example"}, + }, + "nested module with variable passed through parent": { + fixture: "nested-module-with-variable-source", + args: []string{"-var", "child_name=child"}, + }, + "const variable from tfvars file": { + fixture: "local-source-with-varsfile", + args: []string{"-var-file", "test.tfvars"}, + }, + "path.module in module source": { + fixture: "path-attr-in-module-source", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", tc.fixture)), td) + t.Chdir(td) + + ui := new(cli.MockUi) + view, done := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } + + code := c.Run(tc.args) + testOutput := done(t) + if code != 0 { + t.Fatalf("got exit status %d; want 0\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) + } + }) + } +} + +func TestInit2_getFalseWithDynamicSource(t *testing.T) { td := t.TempDir() - testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "add-version-constraint")), td) + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "get-false-with-dynamic-source")), td) + t.Chdir(td) + + // First, run init normally to install the module + ui := new(cli.MockUi) + view, done := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } + + args := []string{"-var", "module_name=example"} + code := c.Run(args) + testOutput := done(t) + if code != 0 { + t.Fatalf("first init failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) + } + + // Now run init with -get=false; should succeed since modules are already installed + ui2 := new(cli.MockUi) + view2, done2 := testView(t) + c2 := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui2, + View: view2, + }, + } + + args2 := []string{"-get=false", "-var", "module_name=example"} + code = c2.Run(args2) + testOutput2 := done2(t) + if code != 0 { + t.Fatalf("init -get=false failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", code, testOutput2.Stderr(), testOutput2.Stdout()) + } +} + +func TestInit2_getFalseWithDynamicSourceNotInstalled(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "get-false-with-dynamic-source")), td) t.Chdir(td) ui := new(cli.MockUi) @@ -28,74 +215,459 @@ func TestInit2_versionConstraintAdded(t *testing.T) { }, } - args := []string{"-get=false"} + // Run init with -get=false without having installed modules first + args := []string{"-get=false", "-var", "module_name=example"} code := c.Run(args) testOutput := done(t) if code != 1 { t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) } - got := testOutput.All() +} + +func TestInit2_reinitWithDifferentVariable(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "local-source-with-variable-default")), td) + t.Chdir(td) + + // First init with default variable (example) + ui := new(cli.MockUi) + view, done := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } + + code := c.Run([]string{}) + testOutput := done(t) + if code != 0 { + t.Fatalf("first init failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) + } + + // Re-init with different variable + ui2 := new(cli.MockUi) + view2, done2 := testView(t) + c2 := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui2, + View: view2, + }, + } + + code = c2.Run([]string{"-var", "module_name=alternate"}) + testOutput2 := done2(t) + if code != 0 { + t.Fatalf("second init failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", code, testOutput2.Stderr(), testOutput2.Stdout()) + } +} + +func TestInit2_fromModuleWithDynamicSource(t *testing.T) { + // TODO: -from-module currently panics when the copied configuration + // contains a dynamic module source (e.g. "./modules/${var.module_name}"). + t.Skip("skipping: -from-module panics on dynamic module sources (see TODO in from_module.go)") + + // Create an empty target directory for -from-module to copy into + td := t.TempDir() + t.Chdir(td) + + ui := new(cli.MockUi) + view, done := testView(t) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + View: view, + }, + } + + // Use -from-module to copy the source module (which has a dynamic source) + // into the empty working directory. This should copy the files but the + // nested dynamic module won't be resolved by -from-module itself. + srcDir := testFixturePath(filepath.Join("dynamic-module-sources", "from-module-with-dynamic-source", "source-module")) + args := []string{"-from-module=" + srcDir} + code := c.Run(args) + testOutput := done(t) + + // -from-module should succeed in copying. The dynamic module source + // within the copied configuration won't be resolved yet — that requires + // a separate init with the variable value. + if code != 0 { + t.Fatalf("init -from-module failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) + } + + // Verify the main.tf was copied + if _, err := os.Stat(filepath.Join(td, "main.tf")); os.IsNotExist(err) { + t.Fatal("main.tf was not copied from the source module") + } +} + +func TestPlan_dynamicModuleSource(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "plan-with-dynamic-source")), td) + t.Chdir(td) + + p := planFixtureProvider() + providerSource, close := newMockProviderSource(t, map[string][]string{ + "hashicorp/test": {"1.0.0"}, + }) + defer close() + + args := []string{"-var", "module_name=example"} + + initUi := new(cli.MockUi) + initView, initDone := testView(t) + initCmd := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: initUi, + View: initView, + ProviderSource: providerSource, + }, + } + + initCode := initCmd.Run(args) + initOutput := initDone(t) + if initCode != 0 { + t.Fatalf("init failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", initCode, initOutput.Stderr(), initOutput.Stdout()) + } + + // Now run plan + planUi := new(cli.MockUi) + planView, planDone := testView(t) + planCmd := &PlanCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: planUi, + View: planView, + }, + } + + planCode := planCmd.Run(args) + planOutput := planDone(t) + if planCode != 0 { + t.Fatalf("plan failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", planCode, planOutput.Stderr(), planOutput.Stdout()) + } + + output := planOutput.Stdout() + if !strings.Contains(output, "1 to add") { + t.Fatalf("expected plan to show 1 resource to add, got:\n%s", output) + } +} + +func TestPlan_dynamicModuleSourceMismatch(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "plan-with-dynamic-source")), td) + t.Chdir(td) + + p := planFixtureProvider() + providerSource, close := newMockProviderSource(t, map[string][]string{ + "hashicorp/test": {"1.0.0"}, + }) + defer close() + args := []string{"-var", "module_name=example"} + + initUi := new(cli.MockUi) + initView, initDone := testView(t) + initCmd := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: initUi, + View: initView, + ProviderSource: providerSource, + }, + } + + initCode := initCmd.Run(args) + initOutput := initDone(t) + if initCode != 0 { + t.Fatalf("init failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", initCode, initOutput.Stderr(), initOutput.Stdout()) + } + + // Now run plan with a different variable value + planUi := new(cli.MockUi) + planView, planDone := testView(t) + planCmd := &PlanCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: planUi, + View: planView, + }, + } + + planArgs := []string{"-var", "module_name=nonexistent"} + code := planCmd.Run(planArgs) + planOutput := planDone(t) + if code == 0 { + t.Fatalf("expected plan to fail, but got exit status 0\nstdout:\n%s", planOutput.Stdout()) + } +} + +func TestApply_dynamicModuleSource(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "apply-with-dynamic-source")), td) + t.Chdir(td) + + p := planFixtureProvider() + providerSource, close := newMockProviderSource(t, map[string][]string{ + "hashicorp/test": {"1.0.0"}, + }) + defer close() + args := []string{"-var", "module_name=example"} + + initUi := new(cli.MockUi) + initView, initDone := testView(t) + initCmd := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: initUi, + View: initView, + ProviderSource: providerSource, + }, + } + + initCode := initCmd.Run(args) + initOutput := initDone(t) + if initCode != 0 { + t.Fatalf("init failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", initCode, initOutput.Stderr(), initOutput.Stdout()) + } + + applyUi := new(cli.MockUi) + applyView, applyDone := testView(t) + applyCmd := &ApplyCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: applyUi, + View: applyView, + }, + } + + applyArgs := []string{"-auto-approve", "-var", "module_name=example"} + code := applyCmd.Run(applyArgs) + applyOutput := applyDone(t) + if code != 0 { + t.Fatalf("apply failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", code, applyOutput.Stderr(), applyOutput.Stdout()) + } + + output := applyOutput.Stdout() + if !strings.Contains(output, "Apply complete!") { + t.Fatalf("expected apply to succeed, got:\n%s", output) + } +} + +func TestApply_dynamicModuleSourceWithDefaultPlanFile(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "apply-plan-with-dynamic-source")), td) + t.Chdir(td) + + p := planFixtureProvider() + providerSource, close := newMockProviderSource(t, map[string][]string{ + "hashicorp/test": {"1.0.0"}, + }) + defer close() + + initUi := new(cli.MockUi) + initView, initDone := testView(t) + initCmd := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: initUi, + View: initView, + ProviderSource: providerSource, + }, + } + + initCode := initCmd.Run([]string{}) + initOutput := initDone(t) + if initCode != 0 { + t.Fatalf("init failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", initCode, initOutput.Stderr(), initOutput.Stdout()) + } + + // Run plan with -out + planPath := filepath.Join(td, "saved.plan") + planUi := new(cli.MockUi) + planView, planDone := testView(t) + planCmd := &PlanCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: planUi, + View: planView, + }, + } + + planArgs := []string{"-out", planPath} + code := planCmd.Run(planArgs) + planOutput := planDone(t) + if code != 0 { + t.Fatalf("plan failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", code, planOutput.Stderr(), planOutput.Stdout()) + } + + // Verify the plan file was created + if _, err := os.Stat(planPath); os.IsNotExist(err) { + t.Fatalf("plan file was not created at %s", planPath) + } + + // Apply the saved plan + applyUi := new(cli.MockUi) + applyView, applyDone := testView(t) + applyCmd := &ApplyCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: applyUi, + View: applyView, + }, + } + + applyArgs := []string{planPath} + code = applyCmd.Run(applyArgs) + applyOutput := applyDone(t) + if code != 0 { + t.Fatalf("apply failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", code, applyOutput.Stderr(), applyOutput.Stdout()) + } + + output := applyOutput.Stdout() + if !strings.Contains(output, "Apply complete!") { + t.Fatalf("expected apply to succeed, got:\n%s", output) + } +} + +func TestPlan_dynamicModuleSourceWithCount(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "module-with-count")), td) + t.Chdir(td) + + p := planFixtureProvider() + providerSource, close := newMockProviderSource(t, map[string][]string{ + "hashicorp/test": {"1.0.0"}, + }) + defer close() + + args := []string{"-var", "module_name=example"} + + initUi := new(cli.MockUi) + initView, initDone := testView(t) + initCmd := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: initUi, + View: initView, + ProviderSource: providerSource, + }, + } + + initCode := initCmd.Run(args) + initOutput := initDone(t) + if initCode != 0 { + t.Fatalf("init failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", initCode, initOutput.Stderr(), initOutput.Stdout()) + } + + // Now run plan + planUi := new(cli.MockUi) + planView, planDone := testView(t) + planCmd := &PlanCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: planUi, + View: planView, + }, + } + + planCode := planCmd.Run(args) + planOutput := planDone(t) + if planCode != 0 { + t.Fatalf("plan failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", planCode, planOutput.Stderr(), planOutput.Stdout()) + } + + output := planOutput.Stdout() + if !strings.Contains(output, "2 to add") { + t.Fatalf("expected plan to show 2 resources to add, got:\n%s", output) + } +} + +func TestPlan_dynamicModuleSourceWithForEach(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "module-with-for-each")), td) + t.Chdir(td) + + p := planFixtureProvider() + providerSource, close := newMockProviderSource(t, map[string][]string{ + "hashicorp/test": {"1.0.0"}, + }) + defer close() + + args := []string{"-var", "module_name=example"} + + initUi := new(cli.MockUi) + initView, initDone := testView(t) + initCmd := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: initUi, + View: initView, + ProviderSource: providerSource, + }, + } + + initCode := initCmd.Run(args) + initOutput := initDone(t) + if initCode != 0 { + t.Fatalf("init failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", initCode, initOutput.Stderr(), initOutput.Stdout()) + } + + // Now run plan + planUi := new(cli.MockUi) + planView, planDone := testView(t) + planCmd := &PlanCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: planUi, + View: planView, + }, + } + + planCode := planCmd.Run(args) + planOutput := planDone(t) + if planCode != 0 { + t.Fatalf("plan failed with exit status %d\nstderr:\n%s\n\nstdout:\n%s", planCode, planOutput.Stderr(), planOutput.Stdout()) + } + + output := planOutput.Stdout() + if !strings.Contains(output, "2 to add") { + t.Fatalf("expected plan to show 2 resources to add, got:\n%s", output) + } +} + +func TestPlan_dynamicModuleVersionMismatch(t *testing.T) { + td := t.TempDir() + testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "plan-with-version-mismatch")), td) + t.Chdir(td) + + p := planFixtureProvider() + + // Plan should fail because the installed module version (0.0.1 in + // modules.json) doesn't satisfy the constraint we provide. + planUi := new(cli.MockUi) + planView, planDone := testView(t) + planCmd := &PlanCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: planUi, + View: planView, + }, + } + + planArgs := []string{"-var", "module_version=0.0.2"} + code := planCmd.Run(planArgs) + planOutput := planDone(t) + if code == 0 { + t.Fatalf("expected plan to fail, but got exit status 0\nstdout:\n%s", planOutput.Stdout()) + } + got := planOutput.All() want := "Module version requirements have changed" if !strings.Contains(got, want) { t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want) } } - -func TestInit2_invalidRegistrySourceWithModule(t *testing.T) { - td := t.TempDir() - testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "invalid-registry-source-with-module")), td) - t.Chdir(td) - - ui := new(cli.MockUi) - view, done := testView(t) - c := &InitCommand{ - Meta: Meta{ - testingOverrides: metaOverridesForProvider(testProvider()), - Ui: ui, - View: view, - }, - } - - args := []string{} - code := c.Run(args) - testOutput := done(t) - if code != 1 { - t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) - } - got := testOutput.All() - - want := "Invalid registry module source address" - if !strings.Contains(got, want) { - t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want) - } -} - -func TestInit2_localSourceWithVersion(t *testing.T) { - td := t.TempDir() - testCopyDir(t, testFixturePath(filepath.Join("dynamic-module-sources", "local-source-with-version")), td) - t.Chdir(td) - - ui := new(cli.MockUi) - view, done := testView(t) - c := &InitCommand{ - Meta: Meta{ - testingOverrides: metaOverridesForProvider(testProvider()), - Ui: ui, - View: view, - }, - } - - args := []string{} - code := c.Run(args) - testOutput := done(t) - if code != 1 { - t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, testOutput.Stderr(), testOutput.Stdout()) - } - got := testOutput.All() - - want := "Invalid registry module source address" - if !strings.Contains(got, want) { - t.Fatalf("wrong error\ngot:\n%s\n\nwant: containing %q", got, want) - } -} diff --git a/internal/command/testdata/dynamic-module-sources/apply-plan-with-dynamic-source/main.tf b/internal/command/testdata/dynamic-module-sources/apply-plan-with-dynamic-source/main.tf new file mode 100644 index 0000000000..98de3a2672 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/apply-plan-with-dynamic-source/main.tf @@ -0,0 +1,9 @@ +variable "module_name" { + type = string + const = true + default = "example" +} + +module "example" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/apply-plan-with-dynamic-source/modules/example/main.tf b/internal/command/testdata/dynamic-module-sources/apply-plan-with-dynamic-source/modules/example/main.tf new file mode 100644 index 0000000000..11bc1e75a5 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/apply-plan-with-dynamic-source/modules/example/main.tf @@ -0,0 +1,3 @@ +resource "test_instance" "example" { + ami = "bar" +} diff --git a/internal/command/testdata/dynamic-module-sources/apply-with-dynamic-source/main.tf b/internal/command/testdata/dynamic-module-sources/apply-with-dynamic-source/main.tf new file mode 100644 index 0000000000..9b60651f81 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/apply-with-dynamic-source/main.tf @@ -0,0 +1,8 @@ +variable "module_name" { + type = string + const = true +} + +module "example" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/apply-with-dynamic-source/modules/example/main.tf b/internal/command/testdata/dynamic-module-sources/apply-with-dynamic-source/modules/example/main.tf new file mode 100644 index 0000000000..11bc1e75a5 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/apply-with-dynamic-source/modules/example/main.tf @@ -0,0 +1,3 @@ +resource "test_instance" "example" { + ami = "bar" +} diff --git a/internal/command/testdata/dynamic-module-sources/count-in-module-source/main.tf b/internal/command/testdata/dynamic-module-sources/count-in-module-source/main.tf new file mode 100644 index 0000000000..50f77309dc --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/count-in-module-source/main.tf @@ -0,0 +1,4 @@ +module "example" { + count = 2 + source = "./modules/${count.index}" +} diff --git a/internal/command/testdata/dynamic-module-sources/each-in-module-source/main.tf b/internal/command/testdata/dynamic-module-sources/each-in-module-source/main.tf new file mode 100644 index 0000000000..53616a849c --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/each-in-module-source/main.tf @@ -0,0 +1,4 @@ +module "example" { + for_each = toset(["one", "two"]) + source = "./modules/${each.key}" +} diff --git a/internal/command/testdata/dynamic-module-sources/from-module-with-dynamic-source/source-module/main.tf b/internal/command/testdata/dynamic-module-sources/from-module-with-dynamic-source/source-module/main.tf new file mode 100644 index 0000000000..9b60651f81 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/from-module-with-dynamic-source/source-module/main.tf @@ -0,0 +1,8 @@ +variable "module_name" { + type = string + const = true +} + +module "example" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/get-false-with-dynamic-source/main.tf b/internal/command/testdata/dynamic-module-sources/get-false-with-dynamic-source/main.tf new file mode 100644 index 0000000000..9b60651f81 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/get-false-with-dynamic-source/main.tf @@ -0,0 +1,8 @@ +variable "module_name" { + type = string + const = true +} + +module "example" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/get-false-with-dynamic-source/modules/example/empty.tf b/internal/command/testdata/dynamic-module-sources/get-false-with-dynamic-source/modules/example/empty.tf new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/get-false-with-dynamic-source/modules/example/empty.tf @@ -0,0 +1 @@ + diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-local-value/main.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-local-value/main.tf new file mode 100644 index 0000000000..a4278dae8c --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-local-value/main.tf @@ -0,0 +1,12 @@ +variable "module_name" { + type = string + const = true +} + +locals { + module_path = "./modules/${var.module_name}" +} + +module "example" { + source = local.module_path +} diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-local-value/modules/example/empty.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-local-value/modules/example/empty.tf new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-local-value/modules/example/empty.tf @@ -0,0 +1 @@ + diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-non-const-variable/main.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-non-const-variable/main.tf new file mode 100644 index 0000000000..836e88c627 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-non-const-variable/main.tf @@ -0,0 +1,7 @@ +variable "module_name" { + type = string +} + +module "example" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/main.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/main.tf new file mode 100644 index 0000000000..98de3a2672 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/main.tf @@ -0,0 +1,9 @@ +variable "module_name" { + type = string + const = true + default = "example" +} + +module "example" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/modules/alternate/empty.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/modules/alternate/empty.tf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/modules/example/empty.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/modules/example/empty.tf new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-variable-default/modules/example/empty.tf @@ -0,0 +1 @@ + diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-variable/main.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-variable/main.tf new file mode 100644 index 0000000000..9b60651f81 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-variable/main.tf @@ -0,0 +1,8 @@ +variable "module_name" { + type = string + const = true +} + +module "example" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-variable/modules/example/empty.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-variable/modules/example/empty.tf new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-variable/modules/example/empty.tf @@ -0,0 +1 @@ + diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/main.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/main.tf new file mode 100644 index 0000000000..9b60651f81 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/main.tf @@ -0,0 +1,8 @@ +variable "module_name" { + type = string + const = true +} + +module "example" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/modules/example/empty.tf b/internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/modules/example/empty.tf new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/modules/example/empty.tf @@ -0,0 +1 @@ + diff --git a/internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/test.tfvars b/internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/test.tfvars new file mode 100644 index 0000000000..ae980f90f1 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/local-source-with-varsfile/test.tfvars @@ -0,0 +1 @@ +module_name = "example" diff --git a/internal/command/testdata/dynamic-module-sources/module-with-count/main.tf b/internal/command/testdata/dynamic-module-sources/module-with-count/main.tf new file mode 100644 index 0000000000..ccec44c408 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/module-with-count/main.tf @@ -0,0 +1,10 @@ +variable "module_name" { + type = string + const = true +} + +module "example" { + source = "./modules/${var.module_name}" + count = 2 + number = count.index +} diff --git a/internal/command/testdata/dynamic-module-sources/module-with-count/modules/example/main.tf b/internal/command/testdata/dynamic-module-sources/module-with-count/modules/example/main.tf new file mode 100644 index 0000000000..1855478473 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/module-with-count/modules/example/main.tf @@ -0,0 +1,7 @@ +resource "test_instance" "example" { + ami = "bar" +} + +variable "number" { + type = number +} diff --git a/internal/command/testdata/dynamic-module-sources/module-with-for-each/main.tf b/internal/command/testdata/dynamic-module-sources/module-with-for-each/main.tf new file mode 100644 index 0000000000..d50cd6e85b --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/module-with-for-each/main.tf @@ -0,0 +1,10 @@ +variable "module_name" { + type = string + const = true +} + +module "example" { + source = "./modules/${var.module_name}" + for_each = toset(["a", "b"]) + letter = each.value +} diff --git a/internal/command/testdata/dynamic-module-sources/module-with-for-each/modules/example/main.tf b/internal/command/testdata/dynamic-module-sources/module-with-for-each/modules/example/main.tf new file mode 100644 index 0000000000..9dbbae2569 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/module-with-for-each/modules/example/main.tf @@ -0,0 +1,7 @@ +resource "test_instance" "example" { + ami = "bar" +} + +variable "letter" { + type = string +} diff --git a/internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/main.tf b/internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/main.tf new file mode 100644 index 0000000000..b0db6a9f5e --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/main.tf @@ -0,0 +1,9 @@ +variable "child_name" { + type = string + const = true +} + +module "parent" { + source = "./modules/parent" + child_name = var.child_name +} diff --git a/internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/modules/child/main.tf b/internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/modules/child/main.tf new file mode 100644 index 0000000000..048ba194cc --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/modules/child/main.tf @@ -0,0 +1 @@ +# Empty child module used by dynamic-module-sources tests diff --git a/internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/modules/parent/main.tf b/internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/modules/parent/main.tf new file mode 100644 index 0000000000..6a81115838 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/nested-module-with-variable-source/modules/parent/main.tf @@ -0,0 +1,8 @@ +variable "child_name" { + type = string + const = true +} + +module "child" { + source = "../${var.child_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/path-attr-in-module-source/main.tf b/internal/command/testdata/dynamic-module-sources/path-attr-in-module-source/main.tf new file mode 100644 index 0000000000..855ccd0aef --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/path-attr-in-module-source/main.tf @@ -0,0 +1,3 @@ +module "example" { + source = "${path.module}/modules/example" +} diff --git a/internal/command/testdata/dynamic-module-sources/path-attr-in-module-source/modules/example/empty.tf b/internal/command/testdata/dynamic-module-sources/path-attr-in-module-source/modules/example/empty.tf new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/path-attr-in-module-source/modules/example/empty.tf @@ -0,0 +1 @@ + diff --git a/internal/command/testdata/dynamic-module-sources/plan-with-dynamic-source/main.tf b/internal/command/testdata/dynamic-module-sources/plan-with-dynamic-source/main.tf new file mode 100644 index 0000000000..9b60651f81 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/plan-with-dynamic-source/main.tf @@ -0,0 +1,8 @@ +variable "module_name" { + type = string + const = true +} + +module "example" { + source = "./modules/${var.module_name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/plan-with-dynamic-source/modules/example/main.tf b/internal/command/testdata/dynamic-module-sources/plan-with-dynamic-source/modules/example/main.tf new file mode 100644 index 0000000000..11bc1e75a5 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/plan-with-dynamic-source/modules/example/main.tf @@ -0,0 +1,3 @@ +resource "test_instance" "example" { + ami = "bar" +} diff --git a/internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/.terraform/modules/child/empty.tf b/internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/.terraform/modules/child/empty.tf new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/.terraform/modules/child/empty.tf @@ -0,0 +1 @@ + diff --git a/internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/.terraform/modules/modules.json b/internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/.terraform/modules/modules.json new file mode 100644 index 0000000000..6b52e103bc --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/.terraform/modules/modules.json @@ -0,0 +1,15 @@ +{ + "Modules": [ + { + "Key": "", + "Source": "", + "Dir": "" + }, + { + "Key": "child", + "Source": "hashicorp/module-installer-acctest/aws", + "Version": "0.0.1", + "Dir": ".terraform/modules/child" + } + ] +} diff --git a/internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/main.tf b/internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/main.tf new file mode 100644 index 0000000000..766cf9987f --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/plan-with-version-mismatch/main.tf @@ -0,0 +1,15 @@ +# This fixture tests that plan detects a version mismatch when the dynamic +# version constraint changes between init and plan. +# +# The pre-populated .terraform/modules/modules.json records version 0.0.1 +# but the configuration requires a version determined by the const variable. + +variable "module_version" { + type = string + const = true +} + +module "child" { + source = "hashicorp/module-installer-acctest/aws" + version = var.module_version +} diff --git a/internal/command/testdata/dynamic-module-sources/source-with-module-output-reference/main.tf b/internal/command/testdata/dynamic-module-sources/source-with-module-output-reference/main.tf new file mode 100644 index 0000000000..355f9c1001 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/source-with-module-output-reference/main.tf @@ -0,0 +1,7 @@ +module "example" { + source = "./modules/example" +} + +module "example2" { + source = "./modules/${module.example.name}" +} diff --git a/internal/command/testdata/dynamic-module-sources/source-with-module-output-reference/modules/example/main.tf b/internal/command/testdata/dynamic-module-sources/source-with-module-output-reference/modules/example/main.tf new file mode 100644 index 0000000000..a3e6a00391 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/source-with-module-output-reference/modules/example/main.tf @@ -0,0 +1,3 @@ +output "name" { + value = "example" +} diff --git a/internal/command/testdata/dynamic-module-sources/source-with-resource-reference/main.tf b/internal/command/testdata/dynamic-module-sources/source-with-resource-reference/main.tf new file mode 100644 index 0000000000..113df8bd34 --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/source-with-resource-reference/main.tf @@ -0,0 +1,5 @@ +resource "test_instance" "example" {} + +module "example" { + source = "./modules/${test_instance.example.id}" +} diff --git a/internal/command/testdata/dynamic-module-sources/terraform-attr-in-module-source/main.tf b/internal/command/testdata/dynamic-module-sources/terraform-attr-in-module-source/main.tf new file mode 100644 index 0000000000..8757a3094e --- /dev/null +++ b/internal/command/testdata/dynamic-module-sources/terraform-attr-in-module-source/main.tf @@ -0,0 +1,3 @@ +module "example" { + source = "./modules/${terraform.workspace}" +} diff --git a/internal/terraform/node_module_install.go b/internal/terraform/node_module_install.go index a14b417165..59982538c7 100644 --- a/internal/terraform/node_module_install.go +++ b/internal/terraform/node_module_install.go @@ -167,7 +167,7 @@ func evalSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) (ad for _, ref := range refs { switch ref.Subject.(type) { - case addrs.InputVariable, addrs.LocalValue: + case addrs.InputVariable, addrs.LocalValue, addrs.PathAttr: // These are allowed default: diags = diags.Append(&hcl.Diagnostic{ From ee8f7abc040224e1997b7575b89a87a99f656732 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Tue, 3 Mar 2026 16:45:22 +0100 Subject: [PATCH 21/24] Add snapshot-related test for the new graph-based config loader This ensures we test snapshot related configuration loading. These tests previously lived in the `configload` package. --- internal/terraform/config_graph_build_test.go | 166 ++++++++++++++++++ .../.terraform/modules/modules.json | 7 + .../foo/bar/main.tf | 3 + .../already-installed-now-invalid/foo/main.tf | 3 + .../already-installed-now-invalid/root.tf | 3 + .../.terraform/modules/child_a/child_a.tf | 4 + .../modules/child_a/child_c/child_c.tf | 4 + .../modules/child_b.child_d/child_d.tf | 4 + .../.terraform/modules/child_b/child_b.tf | 5 + .../.terraform/modules/modules.json | 32 ++++ .../config-graph/already-installed/root.tf | 10 ++ 11 files changed, 241 insertions(+) create mode 100644 internal/terraform/config_graph_build_test.go create mode 100644 internal/terraform/testdata/config-graph/already-installed-now-invalid/.terraform/modules/modules.json create mode 100644 internal/terraform/testdata/config-graph/already-installed-now-invalid/foo/bar/main.tf create mode 100644 internal/terraform/testdata/config-graph/already-installed-now-invalid/foo/main.tf create mode 100644 internal/terraform/testdata/config-graph/already-installed-now-invalid/root.tf create mode 100644 internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_a/child_a.tf create mode 100644 internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_a/child_c/child_c.tf create mode 100644 internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_b.child_d/child_d.tf create mode 100644 internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_b/child_b.tf create mode 100644 internal/terraform/testdata/config-graph/already-installed/.terraform/modules/modules.json create mode 100644 internal/terraform/testdata/config-graph/already-installed/root.tf diff --git a/internal/terraform/config_graph_build_test.go b/internal/terraform/config_graph_build_test.go new file mode 100644 index 0000000000..1853ba3e5a --- /dev/null +++ b/internal/terraform/config_graph_build_test.go @@ -0,0 +1,166 @@ +// Copyright IBM Corp. 2014, 2026 +// SPDX-License-Identifier: BUSL-1.1 + +package terraform + +import ( + "os" + "path/filepath" + "reflect" + "testing" + + "github.com/davecgh/go-spew/spew" + "github.com/go-test/deep" + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/terraform/internal/configs" + "github.com/hashicorp/terraform/internal/configs/configload" + "github.com/hashicorp/terraform/internal/tfdiags" +) + +func TestLoadConfigWithSnapshot(t *testing.T) { + fixtureDir := filepath.Clean("testdata/config-graph/already-installed") + loader, err := configload.NewLoader(&configload.Config{ + ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), + }) + if err != nil { + t.Fatalf("unexpected error from NewLoader: %s", err) + } + + _, got, diags := testLoadWithSnapshot(fixtureDir, loader, nil) + assertNoDiagnostics(t, diags) + if got == nil { + t.Fatalf("snapshot is nil; want non-nil") + } + + t.Log(spew.Sdump(got)) + + { + gotModuleDirs := map[string]string{} + for k, m := range got.Modules { + gotModuleDirs[k] = m.Dir + } + wantModuleDirs := map[string]string{ + "": "testdata/config-graph/already-installed", + "child_a": "testdata/config-graph/already-installed/.terraform/modules/child_a", + "child_a.child_c": "testdata/config-graph/already-installed/.terraform/modules/child_a/child_c", + "child_b": "testdata/config-graph/already-installed/.terraform/modules/child_b", + "child_b.child_d": "testdata/config-graph/already-installed/.terraform/modules/child_b.child_d", + } + + problems := deep.Equal(wantModuleDirs, gotModuleDirs) + for _, problem := range problems { + t.Error(problem) + } + if len(problems) > 0 { + return + } + } + + gotRoot := got.Modules[""] + wantRoot := &configload.SnapshotModule{ + Dir: "testdata/config-graph/already-installed", + Files: map[string][]byte{ + "root.tf": []byte(` +module "child_a" { + source = "example.com/foo/bar_a/baz" + version = ">= 1.0.0" +} + +module "child_b" { + source = "example.com/foo/bar_b/baz" + version = ">= 1.0.0" +} +`), + }, + } + if !reflect.DeepEqual(gotRoot, wantRoot) { + t.Errorf("wrong root module snapshot\ngot: %swant: %s", spew.Sdump(gotRoot), spew.Sdump(wantRoot)) + } + +} + +func TestLoadConfigWithSnapshot_invalidSource(t *testing.T) { + fixtureDir := filepath.Clean("testdata/config-graph/already-installed-now-invalid") + + old, _ := os.Getwd() + os.Chdir(fixtureDir) + defer os.Chdir(old) + + loader, err := configload.NewLoader(&configload.Config{ + ModulesDir: ".terraform/modules", + }) + if err != nil { + t.Fatalf("unexpected error from NewLoader: %s", err) + } + + _, _, diags := testLoadWithSnapshot(".", loader, nil) + if !diags.HasErrors() { + t.Error("LoadConfigWithSnapshot succeeded; want errors") + } +} + +func TestSnapshotRoundtrip(t *testing.T) { + fixtureDir := filepath.Clean("testdata/config-graph/already-installed") + loader, err := configload.NewLoader(&configload.Config{ + ModulesDir: filepath.Join(fixtureDir, ".terraform/modules"), + }) + if err != nil { + t.Fatalf("unexpected error from NewLoader: %s", err) + } + + _, snap, diags := testLoadWithSnapshot(fixtureDir, loader, nil) + assertNoDiagnostics(t, diags) + if snap == nil { + t.Fatalf("snapshot is nil; want non-nil") + } + + snapLoader := configload.NewLoaderFromSnapshot(snap) + if loader == nil { + t.Fatalf("loader is nil; want non-nil") + } + rootMod, rootDiags := snapLoader.LoadRootModule(snap.Modules[""].Dir) + assertNoDiagnostics(t, rootDiags) + + config, diags := BuildConfigWithGraph( + rootMod, + snapLoader.ModuleWalker(), + nil, + configs.MockDataLoaderFunc(snapLoader.LoadExternalMockData), + ) + assertNoDiagnostics(t, diags) + if config == nil { + t.Fatalf("config is nil; want non-nil") + } + if config.Module == nil { + t.Fatalf("config has no root module") + } + if got, want := config.Module.SourceDir, "testdata/config-graph/already-installed"; got != want { + t.Errorf("wrong root module sourcedir %q; want %q", got, want) + } + if got, want := len(config.Module.ModuleCalls), 2; got != want { + t.Errorf("wrong number of module calls in root module %d; want %d", got, want) + } + childA := config.Children["child_a"] + if childA == nil { + t.Fatalf("child_a config is nil; want non-nil") + } + if childA.Module == nil { + t.Fatalf("child_a config has no module") + } + if got, want := childA.Module.SourceDir, "testdata/config-graph/already-installed/.terraform/modules/child_a"; got != want { + t.Errorf("wrong child_a sourcedir %q; want %q", got, want) + } + if got, want := len(childA.Module.ModuleCalls), 1; got != want { + t.Errorf("wrong number of module calls in child_a %d; want %d", got, want) + } +} + +func assertNoDiagnostics[D hcl.Diagnostics | tfdiags.Diagnostics](t *testing.T, diags D) bool { + t.Helper() + + if len(diags) != 0 { + t.Errorf("wrong number of diagnostics %d; want %d", len(diags), 0) + return true + } + return false +} diff --git a/internal/terraform/testdata/config-graph/already-installed-now-invalid/.terraform/modules/modules.json b/internal/terraform/testdata/config-graph/already-installed-now-invalid/.terraform/modules/modules.json new file mode 100644 index 0000000000..a09a3f4826 --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed-now-invalid/.terraform/modules/modules.json @@ -0,0 +1,7 @@ +{ + "Modules": [ + { "Key": "", "Source": "", "Dir": "." }, + { "Key": "foo", "Source": "./foo", "Dir": "foo" }, + { "Key": "foo.bar", "Source": "./bar", "Dir": "foo/bar" } + ] +} diff --git a/internal/terraform/testdata/config-graph/already-installed-now-invalid/foo/bar/main.tf b/internal/terraform/testdata/config-graph/already-installed-now-invalid/foo/bar/main.tf new file mode 100644 index 0000000000..48b5e2e067 --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed-now-invalid/foo/bar/main.tf @@ -0,0 +1,3 @@ +output "hello" { + value = "Hello from foo/bar" +} diff --git a/internal/terraform/testdata/config-graph/already-installed-now-invalid/foo/main.tf b/internal/terraform/testdata/config-graph/already-installed-now-invalid/foo/main.tf new file mode 100644 index 0000000000..9fba57235c --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed-now-invalid/foo/main.tf @@ -0,0 +1,3 @@ +module "bar" { + source = "${path.module}/bar" +} diff --git a/internal/terraform/testdata/config-graph/already-installed-now-invalid/root.tf b/internal/terraform/testdata/config-graph/already-installed-now-invalid/root.tf new file mode 100644 index 0000000000..020494e84d --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed-now-invalid/root.tf @@ -0,0 +1,3 @@ +module "foo" { + source = "./foo" +} diff --git a/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_a/child_a.tf b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_a/child_a.tf new file mode 100644 index 0000000000..2f4d0f1a0b --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_a/child_a.tf @@ -0,0 +1,4 @@ + +module "child_c" { + source = "./child_c" +} diff --git a/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_a/child_c/child_c.tf b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_a/child_c/child_c.tf new file mode 100644 index 0000000000..785d98d98a --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_a/child_c/child_c.tf @@ -0,0 +1,4 @@ + +output "hello" { + value = "Hello from child_c" +} diff --git a/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_b.child_d/child_d.tf b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_b.child_d/child_d.tf new file mode 100644 index 0000000000..145576a365 --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_b.child_d/child_d.tf @@ -0,0 +1,4 @@ + +output "hello" { + value = "Hello from child_d" +} diff --git a/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_b/child_b.tf b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_b/child_b.tf new file mode 100644 index 0000000000..4a1b247d39 --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/child_b/child_b.tf @@ -0,0 +1,5 @@ + +module "child_d" { + source = "example.com/foo/bar_d/baz" + # Intentionally no version here +} diff --git a/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/modules.json b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/modules.json new file mode 100644 index 0000000000..957a8aebed --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed/.terraform/modules/modules.json @@ -0,0 +1,32 @@ +{ + "Modules": [ + { + "Key": "", + "Source": "", + "Dir": "testdata/config-graph/already-installed" + }, + { + "Key": "child_a", + "Source": "example.com/foo/bar_a/baz", + "Version": "1.0.1", + "Dir": "testdata/config-graph/already-installed/.terraform/modules/child_a" + }, + { + "Key": "child_b", + "Source": "example.com/foo/bar_b/baz", + "Version": "1.0.0", + "Dir": "testdata/config-graph/already-installed/.terraform/modules/child_b" + }, + { + "Key": "child_a.child_c", + "Source": "./child_c", + "Dir": "testdata/config-graph/already-installed/.terraform/modules/child_a/child_c" + }, + { + "Key": "child_b.child_d", + "Source": "example.com/foo/bar_d/baz", + "Version": "1.2.0", + "Dir": "testdata/config-graph/already-installed/.terraform/modules/child_b.child_d" + } + ] +} diff --git a/internal/terraform/testdata/config-graph/already-installed/root.tf b/internal/terraform/testdata/config-graph/already-installed/root.tf new file mode 100644 index 0000000000..8a4473942d --- /dev/null +++ b/internal/terraform/testdata/config-graph/already-installed/root.tf @@ -0,0 +1,10 @@ + +module "child_a" { + source = "example.com/foo/bar_a/baz" + version = ">= 1.0.0" +} + +module "child_b" { + source = "example.com/foo/bar_b/baz" + version = ">= 1.0.0" +} From 6f8592eee472ff4cb9f7c40ddf77712c4ef6c531 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Tue, 3 Mar 2026 16:52:38 +0100 Subject: [PATCH 22/24] Make dynamic reference error message more precise --- internal/terraform/context_init_test.go | 6 +++--- internal/terraform/node_module_install.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/terraform/context_init_test.go b/internal/terraform/context_init_test.go index 5e532dff3b..9bf78943be 100644 --- a/internal/terraform/context_init_test.go +++ b/internal/terraform/context_init_test.go @@ -235,7 +235,7 @@ module "example" { return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: `Invalid module source`, - Detail: `The module source can only reference input variables and local values.`, + Detail: `The module source can only reference constant input variables and local values.`, Subject: &hcl.Range{ Filename: filepath.Join(m.SourceDir, "main.tf"), Start: hcl.Pos{Line: 4, Column: 31, Byte: 95}, @@ -317,7 +317,7 @@ module "example" { return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid module source", - Detail: "The module source can only reference input variables and local values.", + Detail: "The module source can only reference constant input variables and local values.", Subject: &hcl.Range{ Filename: filepath.Join(m.SourceDir, "main.tf"), Start: hcl.Pos{Line: 5, Column: 33, Byte: 91}, @@ -402,7 +402,7 @@ output "id" { return tfdiags.Diagnostics{}.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid module source", - Detail: "The module source can only reference input variables and local values.", + Detail: "The module source can only reference constant input variables and local values.", Subject: &hcl.Range{ Filename: filepath.Join(m.SourceDir, "main.tf"), Start: hcl.Pos{Line: 7, Column: 33, Byte: 107}, diff --git a/internal/terraform/node_module_install.go b/internal/terraform/node_module_install.go index 59982538c7..be5c5cc9a1 100644 --- a/internal/terraform/node_module_install.go +++ b/internal/terraform/node_module_install.go @@ -173,7 +173,7 @@ func evalSource(sourceExpr hcl.Expression, hasVersion bool, ctx EvalContext) (ad diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid module source", - Detail: "The module source can only reference input variables and local values.", + Detail: "The module source can only reference constant input variables and local values.", Subject: ref.SourceRange.ToHCL().Ptr(), }) return nil, "", diags @@ -310,7 +310,7 @@ func evalVersionConstraint(versionExpr hcl.Expression, ctx EvalContext) (configs diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid module version", - Detail: "The module version can only reference input variables and local values.", + Detail: "The module version can only reference constant input variables and local values.", Subject: ref.SourceRange.ToHCL().Ptr(), }) return ret, diags From 07b244b711efd1623232edb410c126c7ded1543f Mon Sep 17 00:00:00 2001 From: hc-github-team-tf-core <82990137+hc-github-team-tf-core@users.noreply.github.com> Date: Wed, 4 Mar 2026 12:08:25 +0000 Subject: [PATCH 23/24] Prepare before 1.15.0-alpha20260304 release (#38232) --- CHANGELOG.md | 17 +++++++++++++++-- version/VERSION | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbab117451..294db16e85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.15.0 (Unreleased) +## 1.15.0-alpha20260304 (March 04, 2026) NEW FEATURES: @@ -7,10 +7,14 @@ NEW FEATURES: * You can set a `deprecated` attribute on variable and output blocks to indicate that they are deprecated. This will produce warnings when passing in a value for a deprecated variable or when referencing a deprecated output. ([#38001](https://github.com/hashicorp/terraform/issues/38001)) -* backend/s3: Support authentication via `aws login` ([#37967](https://github.com/hashicorp/terraform/issues/37967)) +* backend/s3: Support authentication via `aws login` ([#37976](https://github.com/hashicorp/terraform/issues/37976)) * validate: The validate command now checks the `backend` block. This ensures the backend type exists, that all required attributes are present, and that the backend's own validation logic passes. ([#38021](https://github.com/hashicorp/terraform/issues/38021)) +* `convert` function, which allows for precise inline type conversions ([#38160](https://github.com/hashicorp/terraform/issues/38160)) + +* Terraform now supports variables and locals in module source and version attributes ([#38217](https://github.com/hashicorp/terraform/issues/38217)) + ENHANCEMENTS: @@ -24,6 +28,10 @@ ENHANCEMENTS: * improve detection of deprecated resource attributes / blocks ([#38077](https://github.com/hashicorp/terraform/issues/38077)) +* Deprecation messages providers set on resources / blocks / attributes are now part of the deprecation warning ([#38135](https://github.com/hashicorp/terraform/issues/38135)) + +* Include which attribute paths are marked as sensitive in list_start JSON logs ([#38197](https://github.com/hashicorp/terraform/issues/38197)) + BUG FIXES: @@ -52,6 +60,11 @@ BUG FIXES: * states: fixed a bug that caused Terraform to be unable to identify when two states had different output values. This may have caused issues in specific circumstances like backend migrations. ([#38181](https://github.com/hashicorp/terraform/issues/38181)) +NOTES: + +* command/init: Provider installation was refactored to enable future enhancements in the area. This results in different order of operations during init and 2 new log messages replacing one (`initializing_provider_plugin_message`). The change should not have any end-user impact aside from the `init` command output. ([#38227](https://github.com/hashicorp/terraform/issues/38227)) + + UPGRADE NOTES: * backend/s3: The `AWS_USE_FIPS_ENDPOINT` and `AWS_USE_DUALSTACK_ENDPOINT` environment variables now only respect `true` or `false` values, aligning with the AWS SDK for Go. This replaces the previous behavior which treated any non-empty value as `true`. ([#37601](https://github.com/hashicorp/terraform/issues/37601)) diff --git a/version/VERSION b/version/VERSION index 9a4866bbce..8065d7dd87 100644 --- a/version/VERSION +++ b/version/VERSION @@ -1 +1 @@ -1.15.0-dev +1.15.0-alpha20260304 From c0b0e1e0ef5704bdde1500a28402e7f07726be59 Mon Sep 17 00:00:00 2001 From: hc-github-team-tf-core <82990137+hc-github-team-tf-core@users.noreply.github.com> Date: Wed, 4 Mar 2026 18:27:26 +0000 Subject: [PATCH 24/24] Cleanup after 1.15.0-alpha20260304 release (#38234) --- CHANGELOG.md | 2 +- version/VERSION | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 294db16e85..3400550920 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.15.0-alpha20260304 (March 04, 2026) +## 1.15.0 (Unreleased) NEW FEATURES: diff --git a/version/VERSION b/version/VERSION index 8065d7dd87..9a4866bbce 100644 --- a/version/VERSION +++ b/version/VERSION @@ -1 +1 @@ -1.15.0-alpha20260304 +1.15.0-dev