From f3a057eb3567eee0d51c185fc0a7922852b2e060 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Fri, 5 Feb 2021 13:19:55 -0500 Subject: [PATCH 1/8] plugin-protocol v6 This is the first commit for plugin protocol v6. This is currently unused (dead) code; future commits will add the necessary conversion packages, extend configschema, and modify the providers.Interface. The new plugin protocol includes the following changes: - A new field has been added to Attribute: NestedType. This will be the key new feature in plugin protocol v6 - Several massages were renamed for consistency with the verb-noun pattern seen in _most_ messages. - The prepared_config has been removed from PrepareProviderConfig (renamed ValidateProviderConfig), as it has never been used. - The provisioner service has been removed entirely. This has no impact on built-in provisioners. 3rd party provisioners are not supported by the SDK and are not included in this protocol at all. --- docs/plugin-protocol/tfplugin6.0.proto | 321 ++ internal/tfplugin6/generate.sh | 16 + internal/tfplugin6/tfplugin6.pb.go | 4610 ++++++++++++++++++++++++ internal/tfplugin6/tfplugin6.proto | 1 + 4 files changed, 4948 insertions(+) create mode 100644 docs/plugin-protocol/tfplugin6.0.proto create mode 100644 internal/tfplugin6/generate.sh create mode 100644 internal/tfplugin6/tfplugin6.pb.go create mode 120000 internal/tfplugin6/tfplugin6.proto diff --git a/docs/plugin-protocol/tfplugin6.0.proto b/docs/plugin-protocol/tfplugin6.0.proto new file mode 100644 index 000000000000..9b492356b05c --- /dev/null +++ b/docs/plugin-protocol/tfplugin6.0.proto @@ -0,0 +1,321 @@ +// Terraform Plugin RPC protocol version 6.0 +// +// This file defines version 6.0 of the RPC protocol. To implement a plugin +// against this protocol, copy this definition into your own codebase and +// use protoc to generate stubs for your target language. +// +// This file will not be updated. Any minor versions of protocol 6 to follow +// should copy this file and modify the copy while maintaing backwards +// compatibility. Breaking changes, if any are required, will come +// in a subsequent major version with its own separate proto definition. +// +// Note that only the proto files included in a release tag of Terraform are +// official protocol releases. Proto files taken from other commits may include +// incomplete changes or features that did not make it into a final release. +// In all reasonable cases, plugin developers should take the proto file from +// the tag of the most recent release of Terraform, and not from the master +// branch or any other development branch. +// +syntax = "proto3"; +option go_package = "github.com/hashicorp/terraform/internal/tfplugin6"; + +package tfplugin6; + +// DynamicValue is an opaque encoding of terraform data, with the field name +// indicating the encoding scheme used. +message DynamicValue { + bytes msgpack = 1; + bytes json = 2; +} + +message Diagnostic { + enum Severity { + INVALID = 0; + ERROR = 1; + WARNING = 2; + } + Severity severity = 1; + string summary = 2; + string detail = 3; + AttributePath attribute = 4; +} + +message AttributePath { + message Step { + oneof selector { + // Set "attribute_name" to represent looking up an attribute + // in the current object value. + string attribute_name = 1; + // Set "element_key_*" to represent looking up an element in + // an indexable collection type. + string element_key_string = 2; + int64 element_key_int = 3; + } + } + repeated Step steps = 1; +} + +message StopProvider { + message Request { + } + message Response { + string Error = 1; + } +} + +// RawState holds the stored state for a resource to be upgraded by the +// provider. It can be in one of two formats, the current json encoded format +// in bytes, or the legacy flatmap format as a map of strings. +message RawState { + bytes json = 1; + map flatmap = 2; +} + +enum StringKind { + PLAIN = 0; + MARKDOWN = 1; +} + +// Schema is the configuration schema for a Resource or Provider. +message Schema { + message Block { + int64 version = 1; + repeated Attribute attributes = 2; + repeated NestedBlock block_types = 3; + string description = 4; + StringKind description_kind = 5; + bool deprecated = 6; + } + + message Attribute { + string name = 1; + bytes type = 2; + Object nested_type = 10; + string description = 3; + bool required = 4; + bool optional = 5; + bool computed = 6; + bool sensitive = 7; + StringKind description_kind = 8; + bool deprecated = 9; + } + + message NestedBlock { + enum NestingMode { + INVALID = 0; + SINGLE = 1; + LIST = 2; + SET = 3; + MAP = 4; + GROUP = 5; + } + + string type_name = 1; + Block block = 2; + NestingMode nesting = 3; + int64 min_items = 4; + int64 max_items = 5; + } + + message Object { + enum NestingMode { + INVALID = 0; + SINGLE = 1; + LIST = 2; + SET = 3; + MAP = 4; + } + + repeated Attribute attributes = 1; + NestingMode nesting = 3; + int64 min_items = 4; + int64 max_items = 5; + } + + // The version of the schema. + // Schemas are versioned, so that providers can upgrade a saved resource + // state when the schema is changed. + int64 version = 1; + + // Block is the top level configuration block for this schema. + Block block = 2; +} + +service Provider { + //////// Information about what a provider supports/expects + rpc GetProviderSchema(GetProviderSchema.Request) returns (GetProviderSchema.Response); + rpc ValidateProviderConfig(ValidateProviderConfig.Request) returns (ValidateProviderConfig.Response); + rpc ValidateResourceConfig(ValidateResourceConfig.Request) returns (ValidateResourceConfig.Response); + rpc ValidateDataSourceConfig(ValidateDataSourceConfig.Request) returns (ValidateDataSourceConfig.Response); + rpc UpgradeResourceState(UpgradeResourceState.Request) returns (UpgradeResourceState.Response); + + //////// One-time initialization, called before other functions below + rpc ConfigureProvider(ConfigureProvider.Request) returns (ConfigureProvider.Response); + + //////// Managed Resource Lifecycle + rpc ReadResource(ReadResource.Request) returns (ReadResource.Response); + rpc PlanResourceChange(PlanResourceChange.Request) returns (PlanResourceChange.Response); + rpc ApplyResourceChange(ApplyResourceChange.Request) returns (ApplyResourceChange.Response); + rpc ImportResourceState(ImportResourceState.Request) returns (ImportResourceState.Response); + + rpc ReadDataSource(ReadDataSource.Request) returns (ReadDataSource.Response); + + //////// Graceful Shutdown + rpc StopProvider(StopProvider.Request) returns (StopProvider.Response); +} + +message GetProviderSchema { + message Request { + } + message Response { + Schema provider = 1; + map resource_schemas = 2; + map data_source_schemas = 3; + repeated Diagnostic diagnostics = 4; + Schema provider_meta = 5; + } +} + +message ValidateProviderConfig { + message Request { + DynamicValue config = 1; + } + message Response { + repeated Diagnostic diagnostics = 2; + } +} + +message UpgradeResourceState { + message Request { + string type_name = 1; + + // version is the schema_version number recorded in the state file + int64 version = 2; + + // raw_state is the raw states as stored for the resource. Core does + // not have access to the schema of prior_version, so it's the + // provider's responsibility to interpret this value using the + // appropriate older schema. The raw_state will be the json encoded + // state, or a legacy flat-mapped format. + RawState raw_state = 3; + } + message Response { + // new_state is a msgpack-encoded data structure that, when interpreted with + // the _current_ schema for this resource type, is functionally equivalent to + // that which was given in prior_state_raw. + DynamicValue upgraded_state = 1; + + // diagnostics describes any errors encountered during migration that could not + // be safely resolved, and warnings about any possibly-risky assumptions made + // in the upgrade process. + repeated Diagnostic diagnostics = 2; + } +} + +message ValidateResourceConfig { + message Request { + string type_name = 1; + DynamicValue config = 2; + } + message Response { + repeated Diagnostic diagnostics = 1; + } +} + +message ValidateDataSourceConfig { + message Request { + string type_name = 1; + DynamicValue config = 2; + } + message Response { + repeated Diagnostic diagnostics = 1; + } +} + +message ConfigureProvider { + message Request { + string terraform_version = 1; + DynamicValue config = 2; + } + message Response { + repeated Diagnostic diagnostics = 1; + } +} + +message ReadResource { + message Request { + string type_name = 1; + DynamicValue current_state = 2; + bytes private = 3; + DynamicValue provider_meta = 4; + } + message Response { + DynamicValue new_state = 1; + repeated Diagnostic diagnostics = 2; + bytes private = 3; + } +} + +message PlanResourceChange { + message Request { + string type_name = 1; + DynamicValue prior_state = 2; + DynamicValue proposed_new_state = 3; + DynamicValue config = 4; + bytes prior_private = 5; + DynamicValue provider_meta = 6; + } + + message Response { + DynamicValue planned_state = 1; + repeated AttributePath requires_replace = 2; + bytes planned_private = 3; + repeated Diagnostic diagnostics = 4; + } +} + +message ApplyResourceChange { + message Request { + string type_name = 1; + DynamicValue prior_state = 2; + DynamicValue planned_state = 3; + DynamicValue config = 4; + bytes planned_private = 5; + DynamicValue provider_meta = 6; + } + message Response { + DynamicValue new_state = 1; + bytes private = 2; + repeated Diagnostic diagnostics = 3; + } +} + +message ImportResourceState { + message Request { + string type_name = 1; + string id = 2; + } + + message ImportedResource { + string type_name = 1; + DynamicValue state = 2; + bytes private = 3; + } + + message Response { + repeated ImportedResource imported_resources = 1; + repeated Diagnostic diagnostics = 2; + } +} + +message ReadDataSource { + message Request { + string type_name = 1; + DynamicValue config = 2; + DynamicValue provider_meta = 3; + } + message Response { + DynamicValue state = 1; + repeated Diagnostic diagnostics = 2; + } +} diff --git a/internal/tfplugin6/generate.sh b/internal/tfplugin6/generate.sh new file mode 100644 index 000000000000..0dca95b2bb8f --- /dev/null +++ b/internal/tfplugin6/generate.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# We do not run protoc under go:generate because we want to ensure that all +# dependencies of go:generate are "go get"-able for general dev environment +# usability. To compile all protobuf files in this repository, run +# "make protobuf" at the top-level. + +set -eu + +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done +DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + +cd "$DIR" + +protoc --go_out=paths=source_relative,plugins=grpc:. ./tfplugin6.proto diff --git a/internal/tfplugin6/tfplugin6.pb.go b/internal/tfplugin6/tfplugin6.pb.go new file mode 100644 index 000000000000..14bb7d0e1bdc --- /dev/null +++ b/internal/tfplugin6/tfplugin6.pb.go @@ -0,0 +1,4610 @@ +// Terraform Plugin RPC protocol version 6.0 +// +// This file defines version 6.0 of the RPC protocol. To implement a plugin +// against this protocol, copy this definition into your own codebase and +// use protoc to generate stubs for your target language. +// +// This file will not be updated. Any minor versions of protocol 6 to follow +// should copy this file and modify the copy while maintaing backwards +// compatibility. Breaking changes, if any are required, will come +// in a subsequent major version with its own separate proto definition. +// +// Note that only the proto files included in a release tag of Terraform are +// official protocol releases. Proto files taken from other commits may include +// incomplete changes or features that did not make it into a final release. +// In all reasonable cases, plugin developers should take the proto file from +// the tag of the most recent release of Terraform, and not from the master +// branch or any other development branch. +// + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.23.0 +// protoc v3.13.0 +// source: tfplugin6.proto + +package tfplugin6 + +import ( + context "context" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type StringKind int32 + +const ( + StringKind_PLAIN StringKind = 0 + StringKind_MARKDOWN StringKind = 1 +) + +// Enum value maps for StringKind. +var ( + StringKind_name = map[int32]string{ + 0: "PLAIN", + 1: "MARKDOWN", + } + StringKind_value = map[string]int32{ + "PLAIN": 0, + "MARKDOWN": 1, + } +) + +func (x StringKind) Enum() *StringKind { + p := new(StringKind) + *p = x + return p +} + +func (x StringKind) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (StringKind) Descriptor() protoreflect.EnumDescriptor { + return file_tfplugin6_proto_enumTypes[0].Descriptor() +} + +func (StringKind) Type() protoreflect.EnumType { + return &file_tfplugin6_proto_enumTypes[0] +} + +func (x StringKind) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use StringKind.Descriptor instead. +func (StringKind) EnumDescriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{0} +} + +type Diagnostic_Severity int32 + +const ( + Diagnostic_INVALID Diagnostic_Severity = 0 + Diagnostic_ERROR Diagnostic_Severity = 1 + Diagnostic_WARNING Diagnostic_Severity = 2 +) + +// Enum value maps for Diagnostic_Severity. +var ( + Diagnostic_Severity_name = map[int32]string{ + 0: "INVALID", + 1: "ERROR", + 2: "WARNING", + } + Diagnostic_Severity_value = map[string]int32{ + "INVALID": 0, + "ERROR": 1, + "WARNING": 2, + } +) + +func (x Diagnostic_Severity) Enum() *Diagnostic_Severity { + p := new(Diagnostic_Severity) + *p = x + return p +} + +func (x Diagnostic_Severity) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Diagnostic_Severity) Descriptor() protoreflect.EnumDescriptor { + return file_tfplugin6_proto_enumTypes[1].Descriptor() +} + +func (Diagnostic_Severity) Type() protoreflect.EnumType { + return &file_tfplugin6_proto_enumTypes[1] +} + +func (x Diagnostic_Severity) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Diagnostic_Severity.Descriptor instead. +func (Diagnostic_Severity) EnumDescriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{1, 0} +} + +type Schema_NestedBlock_NestingMode int32 + +const ( + Schema_NestedBlock_INVALID Schema_NestedBlock_NestingMode = 0 + Schema_NestedBlock_SINGLE Schema_NestedBlock_NestingMode = 1 + Schema_NestedBlock_LIST Schema_NestedBlock_NestingMode = 2 + Schema_NestedBlock_SET Schema_NestedBlock_NestingMode = 3 + Schema_NestedBlock_MAP Schema_NestedBlock_NestingMode = 4 + Schema_NestedBlock_GROUP Schema_NestedBlock_NestingMode = 5 +) + +// Enum value maps for Schema_NestedBlock_NestingMode. +var ( + Schema_NestedBlock_NestingMode_name = map[int32]string{ + 0: "INVALID", + 1: "SINGLE", + 2: "LIST", + 3: "SET", + 4: "MAP", + 5: "GROUP", + } + Schema_NestedBlock_NestingMode_value = map[string]int32{ + "INVALID": 0, + "SINGLE": 1, + "LIST": 2, + "SET": 3, + "MAP": 4, + "GROUP": 5, + } +) + +func (x Schema_NestedBlock_NestingMode) Enum() *Schema_NestedBlock_NestingMode { + p := new(Schema_NestedBlock_NestingMode) + *p = x + return p +} + +func (x Schema_NestedBlock_NestingMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Schema_NestedBlock_NestingMode) Descriptor() protoreflect.EnumDescriptor { + return file_tfplugin6_proto_enumTypes[2].Descriptor() +} + +func (Schema_NestedBlock_NestingMode) Type() protoreflect.EnumType { + return &file_tfplugin6_proto_enumTypes[2] +} + +func (x Schema_NestedBlock_NestingMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Schema_NestedBlock_NestingMode.Descriptor instead. +func (Schema_NestedBlock_NestingMode) EnumDescriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{5, 2, 0} +} + +type Schema_Object_NestingMode int32 + +const ( + Schema_Object_INVALID Schema_Object_NestingMode = 0 + Schema_Object_SINGLE Schema_Object_NestingMode = 1 + Schema_Object_LIST Schema_Object_NestingMode = 2 + Schema_Object_SET Schema_Object_NestingMode = 3 + Schema_Object_MAP Schema_Object_NestingMode = 4 +) + +// Enum value maps for Schema_Object_NestingMode. +var ( + Schema_Object_NestingMode_name = map[int32]string{ + 0: "INVALID", + 1: "SINGLE", + 2: "LIST", + 3: "SET", + 4: "MAP", + } + Schema_Object_NestingMode_value = map[string]int32{ + "INVALID": 0, + "SINGLE": 1, + "LIST": 2, + "SET": 3, + "MAP": 4, + } +) + +func (x Schema_Object_NestingMode) Enum() *Schema_Object_NestingMode { + p := new(Schema_Object_NestingMode) + *p = x + return p +} + +func (x Schema_Object_NestingMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Schema_Object_NestingMode) Descriptor() protoreflect.EnumDescriptor { + return file_tfplugin6_proto_enumTypes[3].Descriptor() +} + +func (Schema_Object_NestingMode) Type() protoreflect.EnumType { + return &file_tfplugin6_proto_enumTypes[3] +} + +func (x Schema_Object_NestingMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Schema_Object_NestingMode.Descriptor instead. +func (Schema_Object_NestingMode) EnumDescriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{5, 3, 0} +} + +// DynamicValue is an opaque encoding of terraform data, with the field name +// indicating the encoding scheme used. +type DynamicValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Msgpack []byte `protobuf:"bytes,1,opt,name=msgpack,proto3" json:"msgpack,omitempty"` + Json []byte `protobuf:"bytes,2,opt,name=json,proto3" json:"json,omitempty"` +} + +func (x *DynamicValue) Reset() { + *x = DynamicValue{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DynamicValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DynamicValue) ProtoMessage() {} + +func (x *DynamicValue) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DynamicValue.ProtoReflect.Descriptor instead. +func (*DynamicValue) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{0} +} + +func (x *DynamicValue) GetMsgpack() []byte { + if x != nil { + return x.Msgpack + } + return nil +} + +func (x *DynamicValue) GetJson() []byte { + if x != nil { + return x.Json + } + return nil +} + +type Diagnostic struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Severity Diagnostic_Severity `protobuf:"varint,1,opt,name=severity,proto3,enum=tfplugin6.Diagnostic_Severity" json:"severity,omitempty"` + Summary string `protobuf:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"` + Detail string `protobuf:"bytes,3,opt,name=detail,proto3" json:"detail,omitempty"` + Attribute *AttributePath `protobuf:"bytes,4,opt,name=attribute,proto3" json:"attribute,omitempty"` +} + +func (x *Diagnostic) Reset() { + *x = Diagnostic{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Diagnostic) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Diagnostic) ProtoMessage() {} + +func (x *Diagnostic) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Diagnostic.ProtoReflect.Descriptor instead. +func (*Diagnostic) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{1} +} + +func (x *Diagnostic) GetSeverity() Diagnostic_Severity { + if x != nil { + return x.Severity + } + return Diagnostic_INVALID +} + +func (x *Diagnostic) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} + +func (x *Diagnostic) GetDetail() string { + if x != nil { + return x.Detail + } + return "" +} + +func (x *Diagnostic) GetAttribute() *AttributePath { + if x != nil { + return x.Attribute + } + return nil +} + +type AttributePath struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Steps []*AttributePath_Step `protobuf:"bytes,1,rep,name=steps,proto3" json:"steps,omitempty"` +} + +func (x *AttributePath) Reset() { + *x = AttributePath{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AttributePath) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AttributePath) ProtoMessage() {} + +func (x *AttributePath) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AttributePath.ProtoReflect.Descriptor instead. +func (*AttributePath) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{2} +} + +func (x *AttributePath) GetSteps() []*AttributePath_Step { + if x != nil { + return x.Steps + } + return nil +} + +type StopProvider struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *StopProvider) Reset() { + *x = StopProvider{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StopProvider) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StopProvider) ProtoMessage() {} + +func (x *StopProvider) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StopProvider.ProtoReflect.Descriptor instead. +func (*StopProvider) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{3} +} + +// RawState holds the stored state for a resource to be upgraded by the +// provider. It can be in one of two formats, the current json encoded format +// in bytes, or the legacy flatmap format as a map of strings. +type RawState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Json []byte `protobuf:"bytes,1,opt,name=json,proto3" json:"json,omitempty"` + Flatmap map[string]string `protobuf:"bytes,2,rep,name=flatmap,proto3" json:"flatmap,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *RawState) Reset() { + *x = RawState{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RawState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RawState) ProtoMessage() {} + +func (x *RawState) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RawState.ProtoReflect.Descriptor instead. +func (*RawState) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{4} +} + +func (x *RawState) GetJson() []byte { + if x != nil { + return x.Json + } + return nil +} + +func (x *RawState) GetFlatmap() map[string]string { + if x != nil { + return x.Flatmap + } + return nil +} + +// Schema is the configuration schema for a Resource or Provider. +type Schema struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The version of the schema. + // Schemas are versioned, so that providers can upgrade a saved resource + // state when the schema is changed. + Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + // Block is the top level configuration block for this schema. + Block *Schema_Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"` +} + +func (x *Schema) Reset() { + *x = Schema{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema) ProtoMessage() {} + +func (x *Schema) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Schema.ProtoReflect.Descriptor instead. +func (*Schema) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{5} +} + +func (x *Schema) GetVersion() int64 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *Schema) GetBlock() *Schema_Block { + if x != nil { + return x.Block + } + return nil +} + +type GetProviderSchema struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetProviderSchema) Reset() { + *x = GetProviderSchema{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProviderSchema) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProviderSchema) ProtoMessage() {} + +func (x *GetProviderSchema) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProviderSchema.ProtoReflect.Descriptor instead. +func (*GetProviderSchema) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{6} +} + +type ValidateProviderConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ValidateProviderConfig) Reset() { + *x = ValidateProviderConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateProviderConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateProviderConfig) ProtoMessage() {} + +func (x *ValidateProviderConfig) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateProviderConfig.ProtoReflect.Descriptor instead. +func (*ValidateProviderConfig) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{7} +} + +type UpgradeResourceState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UpgradeResourceState) Reset() { + *x = UpgradeResourceState{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpgradeResourceState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpgradeResourceState) ProtoMessage() {} + +func (x *UpgradeResourceState) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpgradeResourceState.ProtoReflect.Descriptor instead. +func (*UpgradeResourceState) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{8} +} + +type ValidateResourceConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ValidateResourceConfig) Reset() { + *x = ValidateResourceConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateResourceConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateResourceConfig) ProtoMessage() {} + +func (x *ValidateResourceConfig) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateResourceConfig.ProtoReflect.Descriptor instead. +func (*ValidateResourceConfig) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{9} +} + +type ValidateDataSourceConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ValidateDataSourceConfig) Reset() { + *x = ValidateDataSourceConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateDataSourceConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateDataSourceConfig) ProtoMessage() {} + +func (x *ValidateDataSourceConfig) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateDataSourceConfig.ProtoReflect.Descriptor instead. +func (*ValidateDataSourceConfig) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{10} +} + +type ConfigureProvider struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ConfigureProvider) Reset() { + *x = ConfigureProvider{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigureProvider) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigureProvider) ProtoMessage() {} + +func (x *ConfigureProvider) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigureProvider.ProtoReflect.Descriptor instead. +func (*ConfigureProvider) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{11} +} + +type ReadResource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReadResource) Reset() { + *x = ReadResource{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadResource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadResource) ProtoMessage() {} + +func (x *ReadResource) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadResource.ProtoReflect.Descriptor instead. +func (*ReadResource) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{12} +} + +type PlanResourceChange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PlanResourceChange) Reset() { + *x = PlanResourceChange{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlanResourceChange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanResourceChange) ProtoMessage() {} + +func (x *PlanResourceChange) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlanResourceChange.ProtoReflect.Descriptor instead. +func (*PlanResourceChange) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{13} +} + +type ApplyResourceChange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ApplyResourceChange) Reset() { + *x = ApplyResourceChange{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyResourceChange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyResourceChange) ProtoMessage() {} + +func (x *ApplyResourceChange) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyResourceChange.ProtoReflect.Descriptor instead. +func (*ApplyResourceChange) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{14} +} + +type ImportResourceState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ImportResourceState) Reset() { + *x = ImportResourceState{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImportResourceState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportResourceState) ProtoMessage() {} + +func (x *ImportResourceState) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportResourceState.ProtoReflect.Descriptor instead. +func (*ImportResourceState) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{15} +} + +type ReadDataSource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReadDataSource) Reset() { + *x = ReadDataSource{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadDataSource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadDataSource) ProtoMessage() {} + +func (x *ReadDataSource) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadDataSource.ProtoReflect.Descriptor instead. +func (*ReadDataSource) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{16} +} + +type AttributePath_Step struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Selector: + // *AttributePath_Step_AttributeName + // *AttributePath_Step_ElementKeyString + // *AttributePath_Step_ElementKeyInt + Selector isAttributePath_Step_Selector `protobuf_oneof:"selector"` +} + +func (x *AttributePath_Step) Reset() { + *x = AttributePath_Step{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AttributePath_Step) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AttributePath_Step) ProtoMessage() {} + +func (x *AttributePath_Step) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AttributePath_Step.ProtoReflect.Descriptor instead. +func (*AttributePath_Step) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{2, 0} +} + +func (m *AttributePath_Step) GetSelector() isAttributePath_Step_Selector { + if m != nil { + return m.Selector + } + return nil +} + +func (x *AttributePath_Step) GetAttributeName() string { + if x, ok := x.GetSelector().(*AttributePath_Step_AttributeName); ok { + return x.AttributeName + } + return "" +} + +func (x *AttributePath_Step) GetElementKeyString() string { + if x, ok := x.GetSelector().(*AttributePath_Step_ElementKeyString); ok { + return x.ElementKeyString + } + return "" +} + +func (x *AttributePath_Step) GetElementKeyInt() int64 { + if x, ok := x.GetSelector().(*AttributePath_Step_ElementKeyInt); ok { + return x.ElementKeyInt + } + return 0 +} + +type isAttributePath_Step_Selector interface { + isAttributePath_Step_Selector() +} + +type AttributePath_Step_AttributeName struct { + // Set "attribute_name" to represent looking up an attribute + // in the current object value. + AttributeName string `protobuf:"bytes,1,opt,name=attribute_name,json=attributeName,proto3,oneof"` +} + +type AttributePath_Step_ElementKeyString struct { + // Set "element_key_*" to represent looking up an element in + // an indexable collection type. + ElementKeyString string `protobuf:"bytes,2,opt,name=element_key_string,json=elementKeyString,proto3,oneof"` +} + +type AttributePath_Step_ElementKeyInt struct { + ElementKeyInt int64 `protobuf:"varint,3,opt,name=element_key_int,json=elementKeyInt,proto3,oneof"` +} + +func (*AttributePath_Step_AttributeName) isAttributePath_Step_Selector() {} + +func (*AttributePath_Step_ElementKeyString) isAttributePath_Step_Selector() {} + +func (*AttributePath_Step_ElementKeyInt) isAttributePath_Step_Selector() {} + +type StopProvider_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *StopProvider_Request) Reset() { + *x = StopProvider_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StopProvider_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StopProvider_Request) ProtoMessage() {} + +func (x *StopProvider_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StopProvider_Request.ProtoReflect.Descriptor instead. +func (*StopProvider_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{3, 0} +} + +type StopProvider_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Error string `protobuf:"bytes,1,opt,name=Error,proto3" json:"Error,omitempty"` +} + +func (x *StopProvider_Response) Reset() { + *x = StopProvider_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StopProvider_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StopProvider_Response) ProtoMessage() {} + +func (x *StopProvider_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StopProvider_Response.ProtoReflect.Descriptor instead. +func (*StopProvider_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{3, 1} +} + +func (x *StopProvider_Response) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +type Schema_Block struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + Attributes []*Schema_Attribute `protobuf:"bytes,2,rep,name=attributes,proto3" json:"attributes,omitempty"` + BlockTypes []*Schema_NestedBlock `protobuf:"bytes,3,rep,name=block_types,json=blockTypes,proto3" json:"block_types,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + DescriptionKind StringKind `protobuf:"varint,5,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin6.StringKind" json:"description_kind,omitempty"` + Deprecated bool `protobuf:"varint,6,opt,name=deprecated,proto3" json:"deprecated,omitempty"` +} + +func (x *Schema_Block) Reset() { + *x = Schema_Block{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema_Block) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema_Block) ProtoMessage() {} + +func (x *Schema_Block) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Schema_Block.ProtoReflect.Descriptor instead. +func (*Schema_Block) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{5, 0} +} + +func (x *Schema_Block) GetVersion() int64 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *Schema_Block) GetAttributes() []*Schema_Attribute { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *Schema_Block) GetBlockTypes() []*Schema_NestedBlock { + if x != nil { + return x.BlockTypes + } + return nil +} + +func (x *Schema_Block) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Schema_Block) GetDescriptionKind() StringKind { + if x != nil { + return x.DescriptionKind + } + return StringKind_PLAIN +} + +func (x *Schema_Block) GetDeprecated() bool { + if x != nil { + return x.Deprecated + } + return false +} + +type Schema_Attribute struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type []byte `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + NestedType *Schema_Object `protobuf:"bytes,10,opt,name=nested_type,json=nestedType,proto3" json:"nested_type,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Required bool `protobuf:"varint,4,opt,name=required,proto3" json:"required,omitempty"` + Optional bool `protobuf:"varint,5,opt,name=optional,proto3" json:"optional,omitempty"` + Computed bool `protobuf:"varint,6,opt,name=computed,proto3" json:"computed,omitempty"` + Sensitive bool `protobuf:"varint,7,opt,name=sensitive,proto3" json:"sensitive,omitempty"` + DescriptionKind StringKind `protobuf:"varint,8,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin6.StringKind" json:"description_kind,omitempty"` + Deprecated bool `protobuf:"varint,9,opt,name=deprecated,proto3" json:"deprecated,omitempty"` +} + +func (x *Schema_Attribute) Reset() { + *x = Schema_Attribute{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema_Attribute) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema_Attribute) ProtoMessage() {} + +func (x *Schema_Attribute) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Schema_Attribute.ProtoReflect.Descriptor instead. +func (*Schema_Attribute) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{5, 1} +} + +func (x *Schema_Attribute) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Schema_Attribute) GetType() []byte { + if x != nil { + return x.Type + } + return nil +} + +func (x *Schema_Attribute) GetNestedType() *Schema_Object { + if x != nil { + return x.NestedType + } + return nil +} + +func (x *Schema_Attribute) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Schema_Attribute) GetRequired() bool { + if x != nil { + return x.Required + } + return false +} + +func (x *Schema_Attribute) GetOptional() bool { + if x != nil { + return x.Optional + } + return false +} + +func (x *Schema_Attribute) GetComputed() bool { + if x != nil { + return x.Computed + } + return false +} + +func (x *Schema_Attribute) GetSensitive() bool { + if x != nil { + return x.Sensitive + } + return false +} + +func (x *Schema_Attribute) GetDescriptionKind() StringKind { + if x != nil { + return x.DescriptionKind + } + return StringKind_PLAIN +} + +func (x *Schema_Attribute) GetDeprecated() bool { + if x != nil { + return x.Deprecated + } + return false +} + +type Schema_NestedBlock struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Block *Schema_Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"` + Nesting Schema_NestedBlock_NestingMode `protobuf:"varint,3,opt,name=nesting,proto3,enum=tfplugin6.Schema_NestedBlock_NestingMode" json:"nesting,omitempty"` + MinItems int64 `protobuf:"varint,4,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"` + MaxItems int64 `protobuf:"varint,5,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"` +} + +func (x *Schema_NestedBlock) Reset() { + *x = Schema_NestedBlock{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema_NestedBlock) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema_NestedBlock) ProtoMessage() {} + +func (x *Schema_NestedBlock) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Schema_NestedBlock.ProtoReflect.Descriptor instead. +func (*Schema_NestedBlock) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{5, 2} +} + +func (x *Schema_NestedBlock) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *Schema_NestedBlock) GetBlock() *Schema_Block { + if x != nil { + return x.Block + } + return nil +} + +func (x *Schema_NestedBlock) GetNesting() Schema_NestedBlock_NestingMode { + if x != nil { + return x.Nesting + } + return Schema_NestedBlock_INVALID +} + +func (x *Schema_NestedBlock) GetMinItems() int64 { + if x != nil { + return x.MinItems + } + return 0 +} + +func (x *Schema_NestedBlock) GetMaxItems() int64 { + if x != nil { + return x.MaxItems + } + return 0 +} + +type Schema_Object struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Attributes []*Schema_Attribute `protobuf:"bytes,1,rep,name=attributes,proto3" json:"attributes,omitempty"` + Nesting Schema_Object_NestingMode `protobuf:"varint,3,opt,name=nesting,proto3,enum=tfplugin6.Schema_Object_NestingMode" json:"nesting,omitempty"` + MinItems int64 `protobuf:"varint,4,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"` + MaxItems int64 `protobuf:"varint,5,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"` +} + +func (x *Schema_Object) Reset() { + *x = Schema_Object{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Schema_Object) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Schema_Object) ProtoMessage() {} + +func (x *Schema_Object) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Schema_Object.ProtoReflect.Descriptor instead. +func (*Schema_Object) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{5, 3} +} + +func (x *Schema_Object) GetAttributes() []*Schema_Attribute { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *Schema_Object) GetNesting() Schema_Object_NestingMode { + if x != nil { + return x.Nesting + } + return Schema_Object_INVALID +} + +func (x *Schema_Object) GetMinItems() int64 { + if x != nil { + return x.MinItems + } + return 0 +} + +func (x *Schema_Object) GetMaxItems() int64 { + if x != nil { + return x.MaxItems + } + return 0 +} + +type GetProviderSchema_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetProviderSchema_Request) Reset() { + *x = GetProviderSchema_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProviderSchema_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProviderSchema_Request) ProtoMessage() {} + +func (x *GetProviderSchema_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProviderSchema_Request.ProtoReflect.Descriptor instead. +func (*GetProviderSchema_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{6, 0} +} + +type GetProviderSchema_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Provider *Schema `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` + ResourceSchemas map[string]*Schema `protobuf:"bytes,2,rep,name=resource_schemas,json=resourceSchemas,proto3" json:"resource_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + DataSourceSchemas map[string]*Schema `protobuf:"bytes,3,rep,name=data_source_schemas,json=dataSourceSchemas,proto3" json:"data_source_schemas,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Diagnostics []*Diagnostic `protobuf:"bytes,4,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + ProviderMeta *Schema `protobuf:"bytes,5,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` +} + +func (x *GetProviderSchema_Response) Reset() { + *x = GetProviderSchema_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetProviderSchema_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetProviderSchema_Response) ProtoMessage() {} + +func (x *GetProviderSchema_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetProviderSchema_Response.ProtoReflect.Descriptor instead. +func (*GetProviderSchema_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{6, 1} +} + +func (x *GetProviderSchema_Response) GetProvider() *Schema { + if x != nil { + return x.Provider + } + return nil +} + +func (x *GetProviderSchema_Response) GetResourceSchemas() map[string]*Schema { + if x != nil { + return x.ResourceSchemas + } + return nil +} + +func (x *GetProviderSchema_Response) GetDataSourceSchemas() map[string]*Schema { + if x != nil { + return x.DataSourceSchemas + } + return nil +} + +func (x *GetProviderSchema_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +func (x *GetProviderSchema_Response) GetProviderMeta() *Schema { + if x != nil { + return x.ProviderMeta + } + return nil +} + +type ValidateProviderConfig_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Config *DynamicValue `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` +} + +func (x *ValidateProviderConfig_Request) Reset() { + *x = ValidateProviderConfig_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateProviderConfig_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateProviderConfig_Request) ProtoMessage() {} + +func (x *ValidateProviderConfig_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateProviderConfig_Request.ProtoReflect.Descriptor instead. +func (*ValidateProviderConfig_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{7, 0} +} + +func (x *ValidateProviderConfig_Request) GetConfig() *DynamicValue { + if x != nil { + return x.Config + } + return nil +} + +type ValidateProviderConfig_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ValidateProviderConfig_Response) Reset() { + *x = ValidateProviderConfig_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateProviderConfig_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateProviderConfig_Response) ProtoMessage() {} + +func (x *ValidateProviderConfig_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateProviderConfig_Response.ProtoReflect.Descriptor instead. +func (*ValidateProviderConfig_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{7, 1} +} + +func (x *ValidateProviderConfig_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type UpgradeResourceState_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + // version is the schema_version number recorded in the state file + Version int64 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` + // raw_state is the raw states as stored for the resource. Core does + // not have access to the schema of prior_version, so it's the + // provider's responsibility to interpret this value using the + // appropriate older schema. The raw_state will be the json encoded + // state, or a legacy flat-mapped format. + RawState *RawState `protobuf:"bytes,3,opt,name=raw_state,json=rawState,proto3" json:"raw_state,omitempty"` +} + +func (x *UpgradeResourceState_Request) Reset() { + *x = UpgradeResourceState_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpgradeResourceState_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpgradeResourceState_Request) ProtoMessage() {} + +func (x *UpgradeResourceState_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpgradeResourceState_Request.ProtoReflect.Descriptor instead. +func (*UpgradeResourceState_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{8, 0} +} + +func (x *UpgradeResourceState_Request) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *UpgradeResourceState_Request) GetVersion() int64 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *UpgradeResourceState_Request) GetRawState() *RawState { + if x != nil { + return x.RawState + } + return nil +} + +type UpgradeResourceState_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // new_state is a msgpack-encoded data structure that, when interpreted with + // the _current_ schema for this resource type, is functionally equivalent to + // that which was given in prior_state_raw. + UpgradedState *DynamicValue `protobuf:"bytes,1,opt,name=upgraded_state,json=upgradedState,proto3" json:"upgraded_state,omitempty"` + // diagnostics describes any errors encountered during migration that could not + // be safely resolved, and warnings about any possibly-risky assumptions made + // in the upgrade process. + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *UpgradeResourceState_Response) Reset() { + *x = UpgradeResourceState_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpgradeResourceState_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpgradeResourceState_Response) ProtoMessage() {} + +func (x *UpgradeResourceState_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpgradeResourceState_Response.ProtoReflect.Descriptor instead. +func (*UpgradeResourceState_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{8, 1} +} + +func (x *UpgradeResourceState_Response) GetUpgradedState() *DynamicValue { + if x != nil { + return x.UpgradedState + } + return nil +} + +func (x *UpgradeResourceState_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ValidateResourceConfig_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` +} + +func (x *ValidateResourceConfig_Request) Reset() { + *x = ValidateResourceConfig_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateResourceConfig_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateResourceConfig_Request) ProtoMessage() {} + +func (x *ValidateResourceConfig_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateResourceConfig_Request.ProtoReflect.Descriptor instead. +func (*ValidateResourceConfig_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{9, 0} +} + +func (x *ValidateResourceConfig_Request) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ValidateResourceConfig_Request) GetConfig() *DynamicValue { + if x != nil { + return x.Config + } + return nil +} + +type ValidateResourceConfig_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ValidateResourceConfig_Response) Reset() { + *x = ValidateResourceConfig_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateResourceConfig_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateResourceConfig_Response) ProtoMessage() {} + +func (x *ValidateResourceConfig_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateResourceConfig_Response.ProtoReflect.Descriptor instead. +func (*ValidateResourceConfig_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{9, 1} +} + +func (x *ValidateResourceConfig_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ValidateDataSourceConfig_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` +} + +func (x *ValidateDataSourceConfig_Request) Reset() { + *x = ValidateDataSourceConfig_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateDataSourceConfig_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateDataSourceConfig_Request) ProtoMessage() {} + +func (x *ValidateDataSourceConfig_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateDataSourceConfig_Request.ProtoReflect.Descriptor instead. +func (*ValidateDataSourceConfig_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{10, 0} +} + +func (x *ValidateDataSourceConfig_Request) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ValidateDataSourceConfig_Request) GetConfig() *DynamicValue { + if x != nil { + return x.Config + } + return nil +} + +type ValidateDataSourceConfig_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ValidateDataSourceConfig_Response) Reset() { + *x = ValidateDataSourceConfig_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidateDataSourceConfig_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidateDataSourceConfig_Response) ProtoMessage() {} + +func (x *ValidateDataSourceConfig_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidateDataSourceConfig_Response.ProtoReflect.Descriptor instead. +func (*ValidateDataSourceConfig_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{10, 1} +} + +func (x *ValidateDataSourceConfig_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ConfigureProvider_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TerraformVersion string `protobuf:"bytes,1,opt,name=terraform_version,json=terraformVersion,proto3" json:"terraform_version,omitempty"` + Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` +} + +func (x *ConfigureProvider_Request) Reset() { + *x = ConfigureProvider_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigureProvider_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigureProvider_Request) ProtoMessage() {} + +func (x *ConfigureProvider_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigureProvider_Request.ProtoReflect.Descriptor instead. +func (*ConfigureProvider_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{11, 0} +} + +func (x *ConfigureProvider_Request) GetTerraformVersion() string { + if x != nil { + return x.TerraformVersion + } + return "" +} + +func (x *ConfigureProvider_Request) GetConfig() *DynamicValue { + if x != nil { + return x.Config + } + return nil +} + +type ConfigureProvider_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Diagnostics []*Diagnostic `protobuf:"bytes,1,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ConfigureProvider_Response) Reset() { + *x = ConfigureProvider_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigureProvider_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigureProvider_Response) ProtoMessage() {} + +func (x *ConfigureProvider_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigureProvider_Response.ProtoReflect.Descriptor instead. +func (*ConfigureProvider_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{11, 1} +} + +func (x *ConfigureProvider_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ReadResource_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + CurrentState *DynamicValue `protobuf:"bytes,2,opt,name=current_state,json=currentState,proto3" json:"current_state,omitempty"` + Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` + ProviderMeta *DynamicValue `protobuf:"bytes,4,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` +} + +func (x *ReadResource_Request) Reset() { + *x = ReadResource_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadResource_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadResource_Request) ProtoMessage() {} + +func (x *ReadResource_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadResource_Request.ProtoReflect.Descriptor instead. +func (*ReadResource_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{12, 0} +} + +func (x *ReadResource_Request) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ReadResource_Request) GetCurrentState() *DynamicValue { + if x != nil { + return x.CurrentState + } + return nil +} + +func (x *ReadResource_Request) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +func (x *ReadResource_Request) GetProviderMeta() *DynamicValue { + if x != nil { + return x.ProviderMeta + } + return nil +} + +type ReadResource_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NewState *DynamicValue `protobuf:"bytes,1,opt,name=new_state,json=newState,proto3" json:"new_state,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` + Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` +} + +func (x *ReadResource_Response) Reset() { + *x = ReadResource_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadResource_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadResource_Response) ProtoMessage() {} + +func (x *ReadResource_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadResource_Response.ProtoReflect.Descriptor instead. +func (*ReadResource_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{12, 1} +} + +func (x *ReadResource_Response) GetNewState() *DynamicValue { + if x != nil { + return x.NewState + } + return nil +} + +func (x *ReadResource_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +func (x *ReadResource_Response) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +type PlanResourceChange_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + PriorState *DynamicValue `protobuf:"bytes,2,opt,name=prior_state,json=priorState,proto3" json:"prior_state,omitempty"` + ProposedNewState *DynamicValue `protobuf:"bytes,3,opt,name=proposed_new_state,json=proposedNewState,proto3" json:"proposed_new_state,omitempty"` + Config *DynamicValue `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` + PriorPrivate []byte `protobuf:"bytes,5,opt,name=prior_private,json=priorPrivate,proto3" json:"prior_private,omitempty"` + ProviderMeta *DynamicValue `protobuf:"bytes,6,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` +} + +func (x *PlanResourceChange_Request) Reset() { + *x = PlanResourceChange_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlanResourceChange_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanResourceChange_Request) ProtoMessage() {} + +func (x *PlanResourceChange_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlanResourceChange_Request.ProtoReflect.Descriptor instead. +func (*PlanResourceChange_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{13, 0} +} + +func (x *PlanResourceChange_Request) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *PlanResourceChange_Request) GetPriorState() *DynamicValue { + if x != nil { + return x.PriorState + } + return nil +} + +func (x *PlanResourceChange_Request) GetProposedNewState() *DynamicValue { + if x != nil { + return x.ProposedNewState + } + return nil +} + +func (x *PlanResourceChange_Request) GetConfig() *DynamicValue { + if x != nil { + return x.Config + } + return nil +} + +func (x *PlanResourceChange_Request) GetPriorPrivate() []byte { + if x != nil { + return x.PriorPrivate + } + return nil +} + +func (x *PlanResourceChange_Request) GetProviderMeta() *DynamicValue { + if x != nil { + return x.ProviderMeta + } + return nil +} + +type PlanResourceChange_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PlannedState *DynamicValue `protobuf:"bytes,1,opt,name=planned_state,json=plannedState,proto3" json:"planned_state,omitempty"` + RequiresReplace []*AttributePath `protobuf:"bytes,2,rep,name=requires_replace,json=requiresReplace,proto3" json:"requires_replace,omitempty"` + PlannedPrivate []byte `protobuf:"bytes,3,opt,name=planned_private,json=plannedPrivate,proto3" json:"planned_private,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,4,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *PlanResourceChange_Response) Reset() { + *x = PlanResourceChange_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PlanResourceChange_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlanResourceChange_Response) ProtoMessage() {} + +func (x *PlanResourceChange_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PlanResourceChange_Response.ProtoReflect.Descriptor instead. +func (*PlanResourceChange_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{13, 1} +} + +func (x *PlanResourceChange_Response) GetPlannedState() *DynamicValue { + if x != nil { + return x.PlannedState + } + return nil +} + +func (x *PlanResourceChange_Response) GetRequiresReplace() []*AttributePath { + if x != nil { + return x.RequiresReplace + } + return nil +} + +func (x *PlanResourceChange_Response) GetPlannedPrivate() []byte { + if x != nil { + return x.PlannedPrivate + } + return nil +} + +func (x *PlanResourceChange_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ApplyResourceChange_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + PriorState *DynamicValue `protobuf:"bytes,2,opt,name=prior_state,json=priorState,proto3" json:"prior_state,omitempty"` + PlannedState *DynamicValue `protobuf:"bytes,3,opt,name=planned_state,json=plannedState,proto3" json:"planned_state,omitempty"` + Config *DynamicValue `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` + PlannedPrivate []byte `protobuf:"bytes,5,opt,name=planned_private,json=plannedPrivate,proto3" json:"planned_private,omitempty"` + ProviderMeta *DynamicValue `protobuf:"bytes,6,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` +} + +func (x *ApplyResourceChange_Request) Reset() { + *x = ApplyResourceChange_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyResourceChange_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyResourceChange_Request) ProtoMessage() {} + +func (x *ApplyResourceChange_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyResourceChange_Request.ProtoReflect.Descriptor instead. +func (*ApplyResourceChange_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{14, 0} +} + +func (x *ApplyResourceChange_Request) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ApplyResourceChange_Request) GetPriorState() *DynamicValue { + if x != nil { + return x.PriorState + } + return nil +} + +func (x *ApplyResourceChange_Request) GetPlannedState() *DynamicValue { + if x != nil { + return x.PlannedState + } + return nil +} + +func (x *ApplyResourceChange_Request) GetConfig() *DynamicValue { + if x != nil { + return x.Config + } + return nil +} + +func (x *ApplyResourceChange_Request) GetPlannedPrivate() []byte { + if x != nil { + return x.PlannedPrivate + } + return nil +} + +func (x *ApplyResourceChange_Request) GetProviderMeta() *DynamicValue { + if x != nil { + return x.ProviderMeta + } + return nil +} + +type ApplyResourceChange_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NewState *DynamicValue `protobuf:"bytes,1,opt,name=new_state,json=newState,proto3" json:"new_state,omitempty"` + Private []byte `protobuf:"bytes,2,opt,name=private,proto3" json:"private,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,3,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ApplyResourceChange_Response) Reset() { + *x = ApplyResourceChange_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyResourceChange_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyResourceChange_Response) ProtoMessage() {} + +func (x *ApplyResourceChange_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyResourceChange_Response.ProtoReflect.Descriptor instead. +func (*ApplyResourceChange_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{14, 1} +} + +func (x *ApplyResourceChange_Response) GetNewState() *DynamicValue { + if x != nil { + return x.NewState + } + return nil +} + +func (x *ApplyResourceChange_Response) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +func (x *ApplyResourceChange_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ImportResourceState_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ImportResourceState_Request) Reset() { + *x = ImportResourceState_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImportResourceState_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportResourceState_Request) ProtoMessage() {} + +func (x *ImportResourceState_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportResourceState_Request.ProtoReflect.Descriptor instead. +func (*ImportResourceState_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{15, 0} +} + +func (x *ImportResourceState_Request) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ImportResourceState_Request) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type ImportResourceState_ImportedResource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + State *DynamicValue `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` + Private []byte `protobuf:"bytes,3,opt,name=private,proto3" json:"private,omitempty"` +} + +func (x *ImportResourceState_ImportedResource) Reset() { + *x = ImportResourceState_ImportedResource{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImportResourceState_ImportedResource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportResourceState_ImportedResource) ProtoMessage() {} + +func (x *ImportResourceState_ImportedResource) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportResourceState_ImportedResource.ProtoReflect.Descriptor instead. +func (*ImportResourceState_ImportedResource) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{15, 1} +} + +func (x *ImportResourceState_ImportedResource) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ImportResourceState_ImportedResource) GetState() *DynamicValue { + if x != nil { + return x.State + } + return nil +} + +func (x *ImportResourceState_ImportedResource) GetPrivate() []byte { + if x != nil { + return x.Private + } + return nil +} + +type ImportResourceState_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ImportedResources []*ImportResourceState_ImportedResource `protobuf:"bytes,1,rep,name=imported_resources,json=importedResources,proto3" json:"imported_resources,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ImportResourceState_Response) Reset() { + *x = ImportResourceState_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImportResourceState_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportResourceState_Response) ProtoMessage() {} + +func (x *ImportResourceState_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[47] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportResourceState_Response.ProtoReflect.Descriptor instead. +func (*ImportResourceState_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{15, 2} +} + +func (x *ImportResourceState_Response) GetImportedResources() []*ImportResourceState_ImportedResource { + if x != nil { + return x.ImportedResources + } + return nil +} + +func (x *ImportResourceState_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +type ReadDataSource_Request struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"` + Config *DynamicValue `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` + ProviderMeta *DynamicValue `protobuf:"bytes,3,opt,name=provider_meta,json=providerMeta,proto3" json:"provider_meta,omitempty"` +} + +func (x *ReadDataSource_Request) Reset() { + *x = ReadDataSource_Request{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadDataSource_Request) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadDataSource_Request) ProtoMessage() {} + +func (x *ReadDataSource_Request) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadDataSource_Request.ProtoReflect.Descriptor instead. +func (*ReadDataSource_Request) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{16, 0} +} + +func (x *ReadDataSource_Request) GetTypeName() string { + if x != nil { + return x.TypeName + } + return "" +} + +func (x *ReadDataSource_Request) GetConfig() *DynamicValue { + if x != nil { + return x.Config + } + return nil +} + +func (x *ReadDataSource_Request) GetProviderMeta() *DynamicValue { + if x != nil { + return x.ProviderMeta + } + return nil +} + +type ReadDataSource_Response struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + State *DynamicValue `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` + Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"` +} + +func (x *ReadDataSource_Response) Reset() { + *x = ReadDataSource_Response{} + if protoimpl.UnsafeEnabled { + mi := &file_tfplugin6_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadDataSource_Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadDataSource_Response) ProtoMessage() {} + +func (x *ReadDataSource_Response) ProtoReflect() protoreflect.Message { + mi := &file_tfplugin6_proto_msgTypes[49] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReadDataSource_Response.ProtoReflect.Descriptor instead. +func (*ReadDataSource_Response) Descriptor() ([]byte, []int) { + return file_tfplugin6_proto_rawDescGZIP(), []int{16, 1} +} + +func (x *ReadDataSource_Response) GetState() *DynamicValue { + if x != nil { + return x.State + } + return nil +} + +func (x *ReadDataSource_Response) GetDiagnostics() []*Diagnostic { + if x != nil { + return x.Diagnostics + } + return nil +} + +var File_tfplugin6_proto protoreflect.FileDescriptor + +var file_tfplugin6_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x09, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x22, 0x3c, 0x0a, 0x0c, + 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, + 0x73, 0x67, 0x70, 0x61, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0xe3, 0x01, 0x0a, 0x0a, 0x44, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x65, 0x76, + 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, + 0x69, 0x63, 0x2e, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, 0x73, 0x65, 0x76, + 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, + 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, + 0x2f, 0x0a, 0x08, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x02, + 0x22, 0xdc, 0x01, 0x0a, 0x0d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x33, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, + 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x95, 0x01, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, + 0x12, 0x27, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x65, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x4b, 0x65, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, + 0x49, 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, + 0x3b, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x1a, + 0x09, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x0a, 0x08, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x96, 0x01, 0x0a, + 0x08, 0x52, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, + 0x07, 0x66, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x61, 0x77, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x2e, 0x46, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x07, 0x66, 0x6c, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x1a, 0x3a, 0x0a, 0x0c, 0x46, 0x6c, 0x61, + 0x74, 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8d, 0x0a, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x05, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x1a, 0xa2, 0x02, 0x0a, 0x05, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, + 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0b, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x0a, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x10, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1e, + 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x1a, 0xe4, + 0x02, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x0a, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, + 0x70, 0x75, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, + 0x70, 0x75, 0x74, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, + 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x76, 0x65, 0x12, 0x40, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, + 0x74, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x1a, 0xa7, 0x02, 0x0a, 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x12, 0x43, 0x0a, 0x07, 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x07, 0x6e, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, 0x74, + 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x22, 0x4d, 0x0a, 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, + 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, + 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x53, 0x54, + 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x4d, + 0x41, 0x50, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x05, 0x1a, + 0x83, 0x02, 0x0a, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x07, 0x6e, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x07, + 0x6e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x22, 0x42, 0x0a, 0x0b, 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, + 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, + 0x06, 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x53, + 0x54, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, + 0x4d, 0x41, 0x50, 0x10, 0x04, 0x22, 0xd0, 0x04, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, 0x09, 0x0a, 0x07, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0xaf, 0x04, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x12, 0x65, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, 0x6c, 0x0a, 0x13, 0x64, 0x61, 0x74, + 0x61, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, + 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x55, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, + 0x57, 0x0a, 0x16, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x99, 0x01, 0x0a, 0x16, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x1a, 0x3a, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, + 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, + 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, + 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, + 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x22, 0x90, 0x02, 0x0a, 0x14, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x72, 0x0a, + 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x30, 0x0a, 0x09, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, + 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x72, 0x61, 0x77, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x1a, 0x83, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, + 0x0a, 0x0e, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x0d, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, + 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, + 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, + 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xb6, 0x01, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x1a, 0x57, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, + 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x22, 0xb8, 0x01, 0x0a, 0x18, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, + 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x57, 0x0a, + 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, + 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xc1, 0x01, 0x0a, 0x11, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x1a, 0x67, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x11, + 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, + 0x72, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x43, 0x0a, 0x08, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, + 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, + 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, + 0xe3, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x1a, 0xbc, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, + 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, + 0x93, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, + 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, + 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x22, 0xc4, 0x04, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x1a, 0xbb, 0x02, 0x0a, + 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x45, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x6e, 0x65, 0x77, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x64, 0x4e, 0x65, + 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6f, 0x72, + 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, + 0x70, 0x72, 0x69, 0x6f, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, + 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0xef, 0x01, 0x0a, 0x08, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x6e, 0x6e, + 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6c, + 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, + 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, + 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xe4, 0x03, 0x0a, + 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x1a, 0xb6, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, + 0x0b, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x70, 0x72, 0x69, + 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x6e, 0x6e, + 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, + 0x64, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0e, 0x70, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, + 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x93, 0x01, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x6e, 0x65, + 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, + 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, + 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, + 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, + 0x69, 0x63, 0x73, 0x22, 0xed, 0x02, 0x0a, 0x13, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x36, 0x0a, 0x07, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x1a, 0x78, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, + 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x1a, 0xa3, 0x01, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x12, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, + 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, + 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, + 0x69, 0x63, 0x73, 0x22, 0x9c, 0x02, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x95, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x72, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x64, 0x69, 0x61, + 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x44, 0x69, 0x61, 0x67, 0x6e, + 0x6f, 0x73, 0x74, 0x69, 0x63, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, + 0x63, 0x73, 0x2a, 0x25, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4b, 0x69, 0x6e, 0x64, + 0x12, 0x09, 0x0a, 0x05, 0x50, 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, + 0x41, 0x52, 0x4b, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x01, 0x32, 0xc6, 0x09, 0x0a, 0x08, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x60, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x24, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x47, 0x65, + 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x16, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x29, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x16, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x29, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x18, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x36, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x69, 0x0a, 0x14, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x27, 0x2e, 0x74, 0x66, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x55, + 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x11, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x12, 0x24, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, + 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1f, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x65, 0x61, 0x64, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x63, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x25, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x36, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, + 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x26, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x36, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, + 0x0a, 0x13, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x36, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, + 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, + 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x21, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x44, 0x61, 0x74, 0x61, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x51, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, + 0x1f, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x6f, 0x70, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x20, 0x2e, 0x74, 0x66, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x2e, 0x53, 0x74, 0x6f, + 0x70, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x74, 0x65, 0x72, 0x72, 0x61, + 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x66, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x36, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_tfplugin6_proto_rawDescOnce sync.Once + file_tfplugin6_proto_rawDescData = file_tfplugin6_proto_rawDesc +) + +func file_tfplugin6_proto_rawDescGZIP() []byte { + file_tfplugin6_proto_rawDescOnce.Do(func() { + file_tfplugin6_proto_rawDescData = protoimpl.X.CompressGZIP(file_tfplugin6_proto_rawDescData) + }) + return file_tfplugin6_proto_rawDescData +} + +var file_tfplugin6_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_tfplugin6_proto_msgTypes = make([]protoimpl.MessageInfo, 50) +var file_tfplugin6_proto_goTypes = []interface{}{ + (StringKind)(0), // 0: tfplugin6.StringKind + (Diagnostic_Severity)(0), // 1: tfplugin6.Diagnostic.Severity + (Schema_NestedBlock_NestingMode)(0), // 2: tfplugin6.Schema.NestedBlock.NestingMode + (Schema_Object_NestingMode)(0), // 3: tfplugin6.Schema.Object.NestingMode + (*DynamicValue)(nil), // 4: tfplugin6.DynamicValue + (*Diagnostic)(nil), // 5: tfplugin6.Diagnostic + (*AttributePath)(nil), // 6: tfplugin6.AttributePath + (*StopProvider)(nil), // 7: tfplugin6.StopProvider + (*RawState)(nil), // 8: tfplugin6.RawState + (*Schema)(nil), // 9: tfplugin6.Schema + (*GetProviderSchema)(nil), // 10: tfplugin6.GetProviderSchema + (*ValidateProviderConfig)(nil), // 11: tfplugin6.ValidateProviderConfig + (*UpgradeResourceState)(nil), // 12: tfplugin6.UpgradeResourceState + (*ValidateResourceConfig)(nil), // 13: tfplugin6.ValidateResourceConfig + (*ValidateDataSourceConfig)(nil), // 14: tfplugin6.ValidateDataSourceConfig + (*ConfigureProvider)(nil), // 15: tfplugin6.ConfigureProvider + (*ReadResource)(nil), // 16: tfplugin6.ReadResource + (*PlanResourceChange)(nil), // 17: tfplugin6.PlanResourceChange + (*ApplyResourceChange)(nil), // 18: tfplugin6.ApplyResourceChange + (*ImportResourceState)(nil), // 19: tfplugin6.ImportResourceState + (*ReadDataSource)(nil), // 20: tfplugin6.ReadDataSource + (*AttributePath_Step)(nil), // 21: tfplugin6.AttributePath.Step + (*StopProvider_Request)(nil), // 22: tfplugin6.StopProvider.Request + (*StopProvider_Response)(nil), // 23: tfplugin6.StopProvider.Response + nil, // 24: tfplugin6.RawState.FlatmapEntry + (*Schema_Block)(nil), // 25: tfplugin6.Schema.Block + (*Schema_Attribute)(nil), // 26: tfplugin6.Schema.Attribute + (*Schema_NestedBlock)(nil), // 27: tfplugin6.Schema.NestedBlock + (*Schema_Object)(nil), // 28: tfplugin6.Schema.Object + (*GetProviderSchema_Request)(nil), // 29: tfplugin6.GetProviderSchema.Request + (*GetProviderSchema_Response)(nil), // 30: tfplugin6.GetProviderSchema.Response + nil, // 31: tfplugin6.GetProviderSchema.Response.ResourceSchemasEntry + nil, // 32: tfplugin6.GetProviderSchema.Response.DataSourceSchemasEntry + (*ValidateProviderConfig_Request)(nil), // 33: tfplugin6.ValidateProviderConfig.Request + (*ValidateProviderConfig_Response)(nil), // 34: tfplugin6.ValidateProviderConfig.Response + (*UpgradeResourceState_Request)(nil), // 35: tfplugin6.UpgradeResourceState.Request + (*UpgradeResourceState_Response)(nil), // 36: tfplugin6.UpgradeResourceState.Response + (*ValidateResourceConfig_Request)(nil), // 37: tfplugin6.ValidateResourceConfig.Request + (*ValidateResourceConfig_Response)(nil), // 38: tfplugin6.ValidateResourceConfig.Response + (*ValidateDataSourceConfig_Request)(nil), // 39: tfplugin6.ValidateDataSourceConfig.Request + (*ValidateDataSourceConfig_Response)(nil), // 40: tfplugin6.ValidateDataSourceConfig.Response + (*ConfigureProvider_Request)(nil), // 41: tfplugin6.ConfigureProvider.Request + (*ConfigureProvider_Response)(nil), // 42: tfplugin6.ConfigureProvider.Response + (*ReadResource_Request)(nil), // 43: tfplugin6.ReadResource.Request + (*ReadResource_Response)(nil), // 44: tfplugin6.ReadResource.Response + (*PlanResourceChange_Request)(nil), // 45: tfplugin6.PlanResourceChange.Request + (*PlanResourceChange_Response)(nil), // 46: tfplugin6.PlanResourceChange.Response + (*ApplyResourceChange_Request)(nil), // 47: tfplugin6.ApplyResourceChange.Request + (*ApplyResourceChange_Response)(nil), // 48: tfplugin6.ApplyResourceChange.Response + (*ImportResourceState_Request)(nil), // 49: tfplugin6.ImportResourceState.Request + (*ImportResourceState_ImportedResource)(nil), // 50: tfplugin6.ImportResourceState.ImportedResource + (*ImportResourceState_Response)(nil), // 51: tfplugin6.ImportResourceState.Response + (*ReadDataSource_Request)(nil), // 52: tfplugin6.ReadDataSource.Request + (*ReadDataSource_Response)(nil), // 53: tfplugin6.ReadDataSource.Response +} +var file_tfplugin6_proto_depIdxs = []int32{ + 1, // 0: tfplugin6.Diagnostic.severity:type_name -> tfplugin6.Diagnostic.Severity + 6, // 1: tfplugin6.Diagnostic.attribute:type_name -> tfplugin6.AttributePath + 21, // 2: tfplugin6.AttributePath.steps:type_name -> tfplugin6.AttributePath.Step + 24, // 3: tfplugin6.RawState.flatmap:type_name -> tfplugin6.RawState.FlatmapEntry + 25, // 4: tfplugin6.Schema.block:type_name -> tfplugin6.Schema.Block + 26, // 5: tfplugin6.Schema.Block.attributes:type_name -> tfplugin6.Schema.Attribute + 27, // 6: tfplugin6.Schema.Block.block_types:type_name -> tfplugin6.Schema.NestedBlock + 0, // 7: tfplugin6.Schema.Block.description_kind:type_name -> tfplugin6.StringKind + 28, // 8: tfplugin6.Schema.Attribute.nested_type:type_name -> tfplugin6.Schema.Object + 0, // 9: tfplugin6.Schema.Attribute.description_kind:type_name -> tfplugin6.StringKind + 25, // 10: tfplugin6.Schema.NestedBlock.block:type_name -> tfplugin6.Schema.Block + 2, // 11: tfplugin6.Schema.NestedBlock.nesting:type_name -> tfplugin6.Schema.NestedBlock.NestingMode + 26, // 12: tfplugin6.Schema.Object.attributes:type_name -> tfplugin6.Schema.Attribute + 3, // 13: tfplugin6.Schema.Object.nesting:type_name -> tfplugin6.Schema.Object.NestingMode + 9, // 14: tfplugin6.GetProviderSchema.Response.provider:type_name -> tfplugin6.Schema + 31, // 15: tfplugin6.GetProviderSchema.Response.resource_schemas:type_name -> tfplugin6.GetProviderSchema.Response.ResourceSchemasEntry + 32, // 16: tfplugin6.GetProviderSchema.Response.data_source_schemas:type_name -> tfplugin6.GetProviderSchema.Response.DataSourceSchemasEntry + 5, // 17: tfplugin6.GetProviderSchema.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 9, // 18: tfplugin6.GetProviderSchema.Response.provider_meta:type_name -> tfplugin6.Schema + 9, // 19: tfplugin6.GetProviderSchema.Response.ResourceSchemasEntry.value:type_name -> tfplugin6.Schema + 9, // 20: tfplugin6.GetProviderSchema.Response.DataSourceSchemasEntry.value:type_name -> tfplugin6.Schema + 4, // 21: tfplugin6.ValidateProviderConfig.Request.config:type_name -> tfplugin6.DynamicValue + 5, // 22: tfplugin6.ValidateProviderConfig.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 8, // 23: tfplugin6.UpgradeResourceState.Request.raw_state:type_name -> tfplugin6.RawState + 4, // 24: tfplugin6.UpgradeResourceState.Response.upgraded_state:type_name -> tfplugin6.DynamicValue + 5, // 25: tfplugin6.UpgradeResourceState.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 26: tfplugin6.ValidateResourceConfig.Request.config:type_name -> tfplugin6.DynamicValue + 5, // 27: tfplugin6.ValidateResourceConfig.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 28: tfplugin6.ValidateDataSourceConfig.Request.config:type_name -> tfplugin6.DynamicValue + 5, // 29: tfplugin6.ValidateDataSourceConfig.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 30: tfplugin6.ConfigureProvider.Request.config:type_name -> tfplugin6.DynamicValue + 5, // 31: tfplugin6.ConfigureProvider.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 32: tfplugin6.ReadResource.Request.current_state:type_name -> tfplugin6.DynamicValue + 4, // 33: tfplugin6.ReadResource.Request.provider_meta:type_name -> tfplugin6.DynamicValue + 4, // 34: tfplugin6.ReadResource.Response.new_state:type_name -> tfplugin6.DynamicValue + 5, // 35: tfplugin6.ReadResource.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 36: tfplugin6.PlanResourceChange.Request.prior_state:type_name -> tfplugin6.DynamicValue + 4, // 37: tfplugin6.PlanResourceChange.Request.proposed_new_state:type_name -> tfplugin6.DynamicValue + 4, // 38: tfplugin6.PlanResourceChange.Request.config:type_name -> tfplugin6.DynamicValue + 4, // 39: tfplugin6.PlanResourceChange.Request.provider_meta:type_name -> tfplugin6.DynamicValue + 4, // 40: tfplugin6.PlanResourceChange.Response.planned_state:type_name -> tfplugin6.DynamicValue + 6, // 41: tfplugin6.PlanResourceChange.Response.requires_replace:type_name -> tfplugin6.AttributePath + 5, // 42: tfplugin6.PlanResourceChange.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 43: tfplugin6.ApplyResourceChange.Request.prior_state:type_name -> tfplugin6.DynamicValue + 4, // 44: tfplugin6.ApplyResourceChange.Request.planned_state:type_name -> tfplugin6.DynamicValue + 4, // 45: tfplugin6.ApplyResourceChange.Request.config:type_name -> tfplugin6.DynamicValue + 4, // 46: tfplugin6.ApplyResourceChange.Request.provider_meta:type_name -> tfplugin6.DynamicValue + 4, // 47: tfplugin6.ApplyResourceChange.Response.new_state:type_name -> tfplugin6.DynamicValue + 5, // 48: tfplugin6.ApplyResourceChange.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 49: tfplugin6.ImportResourceState.ImportedResource.state:type_name -> tfplugin6.DynamicValue + 50, // 50: tfplugin6.ImportResourceState.Response.imported_resources:type_name -> tfplugin6.ImportResourceState.ImportedResource + 5, // 51: tfplugin6.ImportResourceState.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 4, // 52: tfplugin6.ReadDataSource.Request.config:type_name -> tfplugin6.DynamicValue + 4, // 53: tfplugin6.ReadDataSource.Request.provider_meta:type_name -> tfplugin6.DynamicValue + 4, // 54: tfplugin6.ReadDataSource.Response.state:type_name -> tfplugin6.DynamicValue + 5, // 55: tfplugin6.ReadDataSource.Response.diagnostics:type_name -> tfplugin6.Diagnostic + 29, // 56: tfplugin6.Provider.GetProviderSchema:input_type -> tfplugin6.GetProviderSchema.Request + 33, // 57: tfplugin6.Provider.ValidateProviderConfig:input_type -> tfplugin6.ValidateProviderConfig.Request + 37, // 58: tfplugin6.Provider.ValidateResourceConfig:input_type -> tfplugin6.ValidateResourceConfig.Request + 39, // 59: tfplugin6.Provider.ValidateDataSourceConfig:input_type -> tfplugin6.ValidateDataSourceConfig.Request + 35, // 60: tfplugin6.Provider.UpgradeResourceState:input_type -> tfplugin6.UpgradeResourceState.Request + 41, // 61: tfplugin6.Provider.ConfigureProvider:input_type -> tfplugin6.ConfigureProvider.Request + 43, // 62: tfplugin6.Provider.ReadResource:input_type -> tfplugin6.ReadResource.Request + 45, // 63: tfplugin6.Provider.PlanResourceChange:input_type -> tfplugin6.PlanResourceChange.Request + 47, // 64: tfplugin6.Provider.ApplyResourceChange:input_type -> tfplugin6.ApplyResourceChange.Request + 49, // 65: tfplugin6.Provider.ImportResourceState:input_type -> tfplugin6.ImportResourceState.Request + 52, // 66: tfplugin6.Provider.ReadDataSource:input_type -> tfplugin6.ReadDataSource.Request + 22, // 67: tfplugin6.Provider.StopProvider:input_type -> tfplugin6.StopProvider.Request + 30, // 68: tfplugin6.Provider.GetProviderSchema:output_type -> tfplugin6.GetProviderSchema.Response + 34, // 69: tfplugin6.Provider.ValidateProviderConfig:output_type -> tfplugin6.ValidateProviderConfig.Response + 38, // 70: tfplugin6.Provider.ValidateResourceConfig:output_type -> tfplugin6.ValidateResourceConfig.Response + 40, // 71: tfplugin6.Provider.ValidateDataSourceConfig:output_type -> tfplugin6.ValidateDataSourceConfig.Response + 36, // 72: tfplugin6.Provider.UpgradeResourceState:output_type -> tfplugin6.UpgradeResourceState.Response + 42, // 73: tfplugin6.Provider.ConfigureProvider:output_type -> tfplugin6.ConfigureProvider.Response + 44, // 74: tfplugin6.Provider.ReadResource:output_type -> tfplugin6.ReadResource.Response + 46, // 75: tfplugin6.Provider.PlanResourceChange:output_type -> tfplugin6.PlanResourceChange.Response + 48, // 76: tfplugin6.Provider.ApplyResourceChange:output_type -> tfplugin6.ApplyResourceChange.Response + 51, // 77: tfplugin6.Provider.ImportResourceState:output_type -> tfplugin6.ImportResourceState.Response + 53, // 78: tfplugin6.Provider.ReadDataSource:output_type -> tfplugin6.ReadDataSource.Response + 23, // 79: tfplugin6.Provider.StopProvider:output_type -> tfplugin6.StopProvider.Response + 68, // [68:80] is the sub-list for method output_type + 56, // [56:68] is the sub-list for method input_type + 56, // [56:56] is the sub-list for extension type_name + 56, // [56:56] is the sub-list for extension extendee + 0, // [0:56] is the sub-list for field type_name +} + +func init() { file_tfplugin6_proto_init() } +func file_tfplugin6_proto_init() { + if File_tfplugin6_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_tfplugin6_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DynamicValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Diagnostic); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AttributePath); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StopProvider); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RawState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Schema); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProviderSchema); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateProviderConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpgradeResourceState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateResourceConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateDataSourceConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfigureProvider); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadResource); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlanResourceChange); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyResourceChange); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImportResourceState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadDataSource); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AttributePath_Step); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StopProvider_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StopProvider_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Schema_Block); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Schema_Attribute); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Schema_NestedBlock); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Schema_Object); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProviderSchema_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProviderSchema_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateProviderConfig_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateProviderConfig_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpgradeResourceState_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpgradeResourceState_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateResourceConfig_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateResourceConfig_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateDataSourceConfig_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidateDataSourceConfig_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfigureProvider_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfigureProvider_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadResource_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadResource_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlanResourceChange_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlanResourceChange_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyResourceChange_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyResourceChange_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImportResourceState_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImportResourceState_ImportedResource); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImportResourceState_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadDataSource_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tfplugin6_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadDataSource_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_tfplugin6_proto_msgTypes[17].OneofWrappers = []interface{}{ + (*AttributePath_Step_AttributeName)(nil), + (*AttributePath_Step_ElementKeyString)(nil), + (*AttributePath_Step_ElementKeyInt)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_tfplugin6_proto_rawDesc, + NumEnums: 4, + NumMessages: 50, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_tfplugin6_proto_goTypes, + DependencyIndexes: file_tfplugin6_proto_depIdxs, + EnumInfos: file_tfplugin6_proto_enumTypes, + MessageInfos: file_tfplugin6_proto_msgTypes, + }.Build() + File_tfplugin6_proto = out.File + file_tfplugin6_proto_rawDesc = nil + file_tfplugin6_proto_goTypes = nil + file_tfplugin6_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// ProviderClient is the client API for Provider service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ProviderClient interface { + //////// Information about what a provider supports/expects + GetProviderSchema(ctx context.Context, in *GetProviderSchema_Request, opts ...grpc.CallOption) (*GetProviderSchema_Response, error) + ValidateProviderConfig(ctx context.Context, in *ValidateProviderConfig_Request, opts ...grpc.CallOption) (*ValidateProviderConfig_Response, error) + ValidateResourceConfig(ctx context.Context, in *ValidateResourceConfig_Request, opts ...grpc.CallOption) (*ValidateResourceConfig_Response, error) + ValidateDataSourceConfig(ctx context.Context, in *ValidateDataSourceConfig_Request, opts ...grpc.CallOption) (*ValidateDataSourceConfig_Response, error) + UpgradeResourceState(ctx context.Context, in *UpgradeResourceState_Request, opts ...grpc.CallOption) (*UpgradeResourceState_Response, error) + //////// One-time initialization, called before other functions below + ConfigureProvider(ctx context.Context, in *ConfigureProvider_Request, opts ...grpc.CallOption) (*ConfigureProvider_Response, error) + //////// Managed Resource Lifecycle + ReadResource(ctx context.Context, in *ReadResource_Request, opts ...grpc.CallOption) (*ReadResource_Response, error) + PlanResourceChange(ctx context.Context, in *PlanResourceChange_Request, opts ...grpc.CallOption) (*PlanResourceChange_Response, error) + ApplyResourceChange(ctx context.Context, in *ApplyResourceChange_Request, opts ...grpc.CallOption) (*ApplyResourceChange_Response, error) + ImportResourceState(ctx context.Context, in *ImportResourceState_Request, opts ...grpc.CallOption) (*ImportResourceState_Response, error) + ReadDataSource(ctx context.Context, in *ReadDataSource_Request, opts ...grpc.CallOption) (*ReadDataSource_Response, error) + //////// Graceful Shutdown + StopProvider(ctx context.Context, in *StopProvider_Request, opts ...grpc.CallOption) (*StopProvider_Response, error) +} + +type providerClient struct { + cc grpc.ClientConnInterface +} + +func NewProviderClient(cc grpc.ClientConnInterface) ProviderClient { + return &providerClient{cc} +} + +func (c *providerClient) GetProviderSchema(ctx context.Context, in *GetProviderSchema_Request, opts ...grpc.CallOption) (*GetProviderSchema_Response, error) { + out := new(GetProviderSchema_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/GetProviderSchema", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) ValidateProviderConfig(ctx context.Context, in *ValidateProviderConfig_Request, opts ...grpc.CallOption) (*ValidateProviderConfig_Response, error) { + out := new(ValidateProviderConfig_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/ValidateProviderConfig", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) ValidateResourceConfig(ctx context.Context, in *ValidateResourceConfig_Request, opts ...grpc.CallOption) (*ValidateResourceConfig_Response, error) { + out := new(ValidateResourceConfig_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/ValidateResourceConfig", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) ValidateDataSourceConfig(ctx context.Context, in *ValidateDataSourceConfig_Request, opts ...grpc.CallOption) (*ValidateDataSourceConfig_Response, error) { + out := new(ValidateDataSourceConfig_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/ValidateDataSourceConfig", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) UpgradeResourceState(ctx context.Context, in *UpgradeResourceState_Request, opts ...grpc.CallOption) (*UpgradeResourceState_Response, error) { + out := new(UpgradeResourceState_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/UpgradeResourceState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) ConfigureProvider(ctx context.Context, in *ConfigureProvider_Request, opts ...grpc.CallOption) (*ConfigureProvider_Response, error) { + out := new(ConfigureProvider_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/ConfigureProvider", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) ReadResource(ctx context.Context, in *ReadResource_Request, opts ...grpc.CallOption) (*ReadResource_Response, error) { + out := new(ReadResource_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/ReadResource", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) PlanResourceChange(ctx context.Context, in *PlanResourceChange_Request, opts ...grpc.CallOption) (*PlanResourceChange_Response, error) { + out := new(PlanResourceChange_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/PlanResourceChange", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) ApplyResourceChange(ctx context.Context, in *ApplyResourceChange_Request, opts ...grpc.CallOption) (*ApplyResourceChange_Response, error) { + out := new(ApplyResourceChange_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/ApplyResourceChange", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) ImportResourceState(ctx context.Context, in *ImportResourceState_Request, opts ...grpc.CallOption) (*ImportResourceState_Response, error) { + out := new(ImportResourceState_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/ImportResourceState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) ReadDataSource(ctx context.Context, in *ReadDataSource_Request, opts ...grpc.CallOption) (*ReadDataSource_Response, error) { + out := new(ReadDataSource_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/ReadDataSource", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerClient) StopProvider(ctx context.Context, in *StopProvider_Request, opts ...grpc.CallOption) (*StopProvider_Response, error) { + out := new(StopProvider_Response) + err := c.cc.Invoke(ctx, "/tfplugin6.Provider/StopProvider", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ProviderServer is the server API for Provider service. +type ProviderServer interface { + //////// Information about what a provider supports/expects + GetProviderSchema(context.Context, *GetProviderSchema_Request) (*GetProviderSchema_Response, error) + ValidateProviderConfig(context.Context, *ValidateProviderConfig_Request) (*ValidateProviderConfig_Response, error) + ValidateResourceConfig(context.Context, *ValidateResourceConfig_Request) (*ValidateResourceConfig_Response, error) + ValidateDataSourceConfig(context.Context, *ValidateDataSourceConfig_Request) (*ValidateDataSourceConfig_Response, error) + UpgradeResourceState(context.Context, *UpgradeResourceState_Request) (*UpgradeResourceState_Response, error) + //////// One-time initialization, called before other functions below + ConfigureProvider(context.Context, *ConfigureProvider_Request) (*ConfigureProvider_Response, error) + //////// Managed Resource Lifecycle + ReadResource(context.Context, *ReadResource_Request) (*ReadResource_Response, error) + PlanResourceChange(context.Context, *PlanResourceChange_Request) (*PlanResourceChange_Response, error) + ApplyResourceChange(context.Context, *ApplyResourceChange_Request) (*ApplyResourceChange_Response, error) + ImportResourceState(context.Context, *ImportResourceState_Request) (*ImportResourceState_Response, error) + ReadDataSource(context.Context, *ReadDataSource_Request) (*ReadDataSource_Response, error) + //////// Graceful Shutdown + StopProvider(context.Context, *StopProvider_Request) (*StopProvider_Response, error) +} + +// UnimplementedProviderServer can be embedded to have forward compatible implementations. +type UnimplementedProviderServer struct { +} + +func (*UnimplementedProviderServer) GetProviderSchema(context.Context, *GetProviderSchema_Request) (*GetProviderSchema_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetProviderSchema not implemented") +} +func (*UnimplementedProviderServer) ValidateProviderConfig(context.Context, *ValidateProviderConfig_Request) (*ValidateProviderConfig_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidateProviderConfig not implemented") +} +func (*UnimplementedProviderServer) ValidateResourceConfig(context.Context, *ValidateResourceConfig_Request) (*ValidateResourceConfig_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidateResourceConfig not implemented") +} +func (*UnimplementedProviderServer) ValidateDataSourceConfig(context.Context, *ValidateDataSourceConfig_Request) (*ValidateDataSourceConfig_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidateDataSourceConfig not implemented") +} +func (*UnimplementedProviderServer) UpgradeResourceState(context.Context, *UpgradeResourceState_Request) (*UpgradeResourceState_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpgradeResourceState not implemented") +} +func (*UnimplementedProviderServer) ConfigureProvider(context.Context, *ConfigureProvider_Request) (*ConfigureProvider_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfigureProvider not implemented") +} +func (*UnimplementedProviderServer) ReadResource(context.Context, *ReadResource_Request) (*ReadResource_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReadResource not implemented") +} +func (*UnimplementedProviderServer) PlanResourceChange(context.Context, *PlanResourceChange_Request) (*PlanResourceChange_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method PlanResourceChange not implemented") +} +func (*UnimplementedProviderServer) ApplyResourceChange(context.Context, *ApplyResourceChange_Request) (*ApplyResourceChange_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method ApplyResourceChange not implemented") +} +func (*UnimplementedProviderServer) ImportResourceState(context.Context, *ImportResourceState_Request) (*ImportResourceState_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImportResourceState not implemented") +} +func (*UnimplementedProviderServer) ReadDataSource(context.Context, *ReadDataSource_Request) (*ReadDataSource_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReadDataSource not implemented") +} +func (*UnimplementedProviderServer) StopProvider(context.Context, *StopProvider_Request) (*StopProvider_Response, error) { + return nil, status.Errorf(codes.Unimplemented, "method StopProvider not implemented") +} + +func RegisterProviderServer(s *grpc.Server, srv ProviderServer) { + s.RegisterService(&_Provider_serviceDesc, srv) +} + +func _Provider_GetProviderSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetProviderSchema_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).GetProviderSchema(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/GetProviderSchema", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).GetProviderSchema(ctx, req.(*GetProviderSchema_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_ValidateProviderConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ValidateProviderConfig_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).ValidateProviderConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/ValidateProviderConfig", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).ValidateProviderConfig(ctx, req.(*ValidateProviderConfig_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_ValidateResourceConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ValidateResourceConfig_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).ValidateResourceConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/ValidateResourceConfig", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).ValidateResourceConfig(ctx, req.(*ValidateResourceConfig_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_ValidateDataSourceConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ValidateDataSourceConfig_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).ValidateDataSourceConfig(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/ValidateDataSourceConfig", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).ValidateDataSourceConfig(ctx, req.(*ValidateDataSourceConfig_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_UpgradeResourceState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpgradeResourceState_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).UpgradeResourceState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/UpgradeResourceState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).UpgradeResourceState(ctx, req.(*UpgradeResourceState_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_ConfigureProvider_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfigureProvider_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).ConfigureProvider(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/ConfigureProvider", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).ConfigureProvider(ctx, req.(*ConfigureProvider_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_ReadResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReadResource_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).ReadResource(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/ReadResource", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).ReadResource(ctx, req.(*ReadResource_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_PlanResourceChange_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PlanResourceChange_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).PlanResourceChange(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/PlanResourceChange", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).PlanResourceChange(ctx, req.(*PlanResourceChange_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_ApplyResourceChange_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ApplyResourceChange_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).ApplyResourceChange(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/ApplyResourceChange", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).ApplyResourceChange(ctx, req.(*ApplyResourceChange_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_ImportResourceState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImportResourceState_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).ImportResourceState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/ImportResourceState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).ImportResourceState(ctx, req.(*ImportResourceState_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_ReadDataSource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReadDataSource_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).ReadDataSource(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/ReadDataSource", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).ReadDataSource(ctx, req.(*ReadDataSource_Request)) + } + return interceptor(ctx, in, info, handler) +} + +func _Provider_StopProvider_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StopProvider_Request) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderServer).StopProvider(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tfplugin6.Provider/StopProvider", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderServer).StopProvider(ctx, req.(*StopProvider_Request)) + } + return interceptor(ctx, in, info, handler) +} + +var _Provider_serviceDesc = grpc.ServiceDesc{ + ServiceName: "tfplugin6.Provider", + HandlerType: (*ProviderServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetProviderSchema", + Handler: _Provider_GetProviderSchema_Handler, + }, + { + MethodName: "ValidateProviderConfig", + Handler: _Provider_ValidateProviderConfig_Handler, + }, + { + MethodName: "ValidateResourceConfig", + Handler: _Provider_ValidateResourceConfig_Handler, + }, + { + MethodName: "ValidateDataSourceConfig", + Handler: _Provider_ValidateDataSourceConfig_Handler, + }, + { + MethodName: "UpgradeResourceState", + Handler: _Provider_UpgradeResourceState_Handler, + }, + { + MethodName: "ConfigureProvider", + Handler: _Provider_ConfigureProvider_Handler, + }, + { + MethodName: "ReadResource", + Handler: _Provider_ReadResource_Handler, + }, + { + MethodName: "PlanResourceChange", + Handler: _Provider_PlanResourceChange_Handler, + }, + { + MethodName: "ApplyResourceChange", + Handler: _Provider_ApplyResourceChange_Handler, + }, + { + MethodName: "ImportResourceState", + Handler: _Provider_ImportResourceState_Handler, + }, + { + MethodName: "ReadDataSource", + Handler: _Provider_ReadDataSource_Handler, + }, + { + MethodName: "StopProvider", + Handler: _Provider_StopProvider_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "tfplugin6.proto", +} diff --git a/internal/tfplugin6/tfplugin6.proto b/internal/tfplugin6/tfplugin6.proto new file mode 120000 index 000000000000..ae47060038b5 --- /dev/null +++ b/internal/tfplugin6/tfplugin6.proto @@ -0,0 +1 @@ +../../docs/plugin-protocol/tfplugin6.0.proto \ No newline at end of file From 3ad720e9dca5503ff3be9def0d0e33ab9ef7fb33 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Fri, 5 Feb 2021 13:34:55 -0500 Subject: [PATCH 2/8] configs/configschema: add new NestedType to attribute This commit adds a new field, NestedType, to the Attribute schema, and extends the current Attribute decoderSpec to account for the new type. The codepaths are mostly unused and included in a separate commit to verify that the included changes do not impact any other tests yet. --- configs/configschema/decoder_spec.go | 48 ++- configs/configschema/decoder_spec_test.go | 360 ++++++++++++++++++++++ configs/configschema/empty_value.go | 12 + configs/configschema/empty_value_test.go | 113 +++++++ configs/configschema/implied_type.go | 34 ++ configs/configschema/implied_type_test.go | 56 ++++ configs/configschema/schema.go | 26 ++ 7 files changed, 645 insertions(+), 4 deletions(-) diff --git a/configs/configschema/decoder_spec.go b/configs/configschema/decoder_spec.go index f7193ec075c8..8325eaf60255 100644 --- a/configs/configschema/decoder_spec.go +++ b/configs/configschema/decoder_spec.go @@ -6,6 +6,7 @@ import ( "unsafe" "github.com/hashicorp/hcl/v2/hcldec" + "github.com/zclconf/go-cty/cty" ) var mapLabelNames = []string{"key"} @@ -183,9 +184,48 @@ func (b *Block) DecoderSpec() hcldec.Spec { } func (a *Attribute) decoderSpec(name string) hcldec.Spec { - return &hcldec.AttrSpec{ - Name: name, - Type: a.Type, - Required: a.Required, + ret := &hcldec.AttrSpec{Name: name} + if a == nil { + return ret + } + + if a.NestedType != nil { + // FIXME: a panic() is a bad UX. Fix this, probably by extending + // InternalValidate() to check Attribute schemas as well and calling it + // when we get the schema from the provider in Context(). + if a.Type != cty.NilType { + panic("Invalid attribute schema: NestedType and Type cannot both be set. This is a bug in the provider.") + } + + var optAttrs []string + optAttrs = listOptionalAttrsFromObject(a.NestedType, optAttrs) + ty := a.NestedType.ImpliedType() + + switch a.NestedType.Nesting { + case NestingList: + ret.Type = cty.List(ty) + case NestingSet: + ret.Type = cty.Set(ty) + case NestingMap: + ret.Type = cty.Map(ty) + default: // NestingSingle, NestingGroup, or no NestingMode + ret.Type = ty + } + ret.Required = a.NestedType.MinItems > 0 + return ret } + + ret.Type = a.Type + ret.Required = a.Required + return ret +} + +func listOptionalAttrsFromObject(o *Object, optAttrs []string) []string { + for name, attr := range o.Attributes { + if attr.Optional == true { + optAttrs = append(optAttrs, name) + } + } + + return optAttrs } diff --git a/configs/configschema/decoder_spec_test.go b/configs/configschema/decoder_spec_test.go index 492ee5dad85e..1f3691ed2237 100644 --- a/configs/configschema/decoder_spec_test.go +++ b/configs/configschema/decoder_spec_test.go @@ -426,3 +426,363 @@ func TestBlockDecoderSpec(t *testing.T) { }) } } + +func TestAttributeDecoderSpec(t *testing.T) { + tests := map[string]struct { + Schema *Attribute + TestBody hcl.Body + Want cty.Value + DiagCount int + }{ + "empty": { + &Attribute{}, + hcl.EmptyBody(), + cty.NilVal, + 0, + }, + "nil": { + nil, + hcl.EmptyBody(), + cty.NilVal, + 0, + }, + "optional string (null)": { + &Attribute{ + Type: cty.String, + Optional: true, + }, + hcl.EmptyBody(), + cty.NullVal(cty.String), + 0, + }, + "optional string": { + &Attribute{ + Type: cty.String, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.StringVal("bar")), + }, + }, + }), + cty.StringVal("bar"), + 0, + }, + "NestedType with required string": { + &Attribute{ + NestedType: &Object{ + Attributes: map[string]*Attribute{ + "foo": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.ObjectVal(map[string]cty.Value{ + "foo": cty.StringVal("bar"), + })), + }, + }, + }), + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.StringVal("bar"), + }), + 0, + }, + "NestedType with optional attributes": { + &Attribute{ + NestedType: &Object{ + Attributes: map[string]*Attribute{ + "foo": { + Type: cty.String, + Optional: true, + }, + "bar": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.ObjectVal(map[string]cty.Value{ + "foo": cty.StringVal("bar"), + })), + }, + }, + }), + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.StringVal("bar"), + "bar": cty.NullVal(cty.String), + }), + 0, + }, + "NestedType with missing required string": { + &Attribute{ + NestedType: &Object{ + Attributes: map[string]*Attribute{ + "foo": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.EmptyObjectVal), + }, + }, + }), + cty.UnknownVal(cty.Object(map[string]cty.Type{ + "foo": cty.String, + })), + 1, + }, + // NestedModes + "NestedType NestingModeList valid": { + &Attribute{ + NestedType: &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "foo": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + // "foo" should be a string, not a list + "foo": cty.StringVal("bar"), + }), + cty.ObjectVal(map[string]cty.Value{ + // "foo" should be a string, not a list + "foo": cty.StringVal("baz"), + }), + })), + }, + }, + }), + cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("bar")}), + cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("baz")}), + }), + 0, + }, + "NestedType NestingModeList invalid": { + &Attribute{ + NestedType: &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "foo": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.ListVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{ + // "foo" should be a string, not a list + "foo": cty.ListVal([]cty.Value{cty.StringVal("bar"), cty.StringVal("baz")}), + })})), + }, + }, + }), + cty.UnknownVal(cty.List(cty.Object(map[string]cty.Type{"foo": cty.String}))), + 1, + }, + "NestedType NestingModeSet valid": { + &Attribute{ + NestedType: &Object{ + Nesting: NestingSet, + Attributes: map[string]*Attribute{ + "foo": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + // "foo" should be a string, not a list + "foo": cty.StringVal("bar"), + }), + cty.ObjectVal(map[string]cty.Value{ + // "foo" should be a string, not a list + "foo": cty.StringVal("baz"), + }), + })), + }, + }, + }), + cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("bar")}), + cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("baz")}), + }), + 0, + }, + "NestedType NestingModeSet invalid": { + &Attribute{ + NestedType: &Object{ + Nesting: NestingSet, + Attributes: map[string]*Attribute{ + "foo": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.SetVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{ + // "foo" should be a string, not a list + "foo": cty.ListVal([]cty.Value{cty.StringVal("bar"), cty.StringVal("baz")}), + })})), + }, + }, + }), + cty.UnknownVal(cty.Set(cty.Object(map[string]cty.Type{"foo": cty.String}))), + 1, + }, + "NestedType NestingModeMap valid": { + &Attribute{ + NestedType: &Object{ + Nesting: NestingMap, + Attributes: map[string]*Attribute{ + "foo": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.MapVal(map[string]cty.Value{ + "one": cty.ObjectVal(map[string]cty.Value{ + // "foo" should be a string, not a list + "foo": cty.StringVal("bar"), + }), + "two": cty.ObjectVal(map[string]cty.Value{ + // "foo" should be a string, not a list + "foo": cty.StringVal("baz"), + }), + })), + }, + }, + }), + cty.MapVal(map[string]cty.Value{ + "one": cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("bar")}), + "two": cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("baz")}), + }), + 0, + }, + "NestedType NestingModeMap invalid": { + &Attribute{ + NestedType: &Object{ + Nesting: NestingMap, + Attributes: map[string]*Attribute{ + "foo": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.MapVal(map[string]cty.Value{ + "one": cty.ObjectVal(map[string]cty.Value{ + // "foo" should be a string, not a list + "foo": cty.ListVal([]cty.Value{cty.StringVal("bar"), cty.StringVal("baz")}), + }), + })), + }, + }, + }), + cty.UnknownVal(cty.Map(cty.Object(map[string]cty.Type{"foo": cty.String}))), + 1, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + spec := test.Schema.decoderSpec("attr") + got, diags := hcldec.Decode(test.TestBody, spec, nil) + if len(diags) != test.DiagCount { + t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.DiagCount) + for _, diag := range diags { + t.Logf("- %s", diag.Error()) + } + } + + if !got.RawEquals(test.Want) { + t.Logf("[INFO] implied schema is %s", spew.Sdump(hcldec.ImpliedSchema(spec))) + t.Errorf("wrong result\ngot: %s\nwant: %s", dump.Value(got), dump.Value(test.Want)) + } + }) + } + +} + +// TestAttributeDecodeSpec_panic is a temporary test which verifies that +// decoderSpec panics when an invalid Attribute schema is encountered. It will +// be removed when InternalValidate() is extended to validate Attribute specs +// (and is used). See the #FIXME in decoderSpec. +func TestAttributeDecoderSpec_panic(t *testing.T) { + attrS := &Attribute{ + Type: cty.Object(map[string]cty.Type{ + "nested_attribute": cty.String, + }), + NestedType: &Object{}, + Optional: true, + } + + defer func() { recover() }() + attrS.decoderSpec("attr") + t.Errorf("expected panic") +} diff --git a/configs/configschema/empty_value.go b/configs/configschema/empty_value.go index 005da56bf5e8..a5146849476f 100644 --- a/configs/configschema/empty_value.go +++ b/configs/configschema/empty_value.go @@ -26,6 +26,18 @@ func (b *Block) EmptyValue() cty.Value { // the value that would be returned if there were no definition of the attribute // at all, ignoring any required constraint. func (a *Attribute) EmptyValue() cty.Value { + if a.NestedType != nil { + switch a.NestedType.Nesting { + case NestingList: + return cty.NullVal(cty.List(a.NestedType.ImpliedType())) + case NestingSet: + return cty.NullVal(cty.Set(a.NestedType.ImpliedType())) + case NestingMap: + return cty.NullVal(cty.Map(a.NestedType.ImpliedType())) + default: // NestingSingle, NestingGroup, or no NestingMode + return cty.NullVal(a.NestedType.ImpliedType()) + } + } return cty.NullVal(a.Type) } diff --git a/configs/configschema/empty_value_test.go b/configs/configschema/empty_value_test.go index 44d27fe71f38..a11ab4cdbf5c 100644 --- a/configs/configschema/empty_value_test.go +++ b/configs/configschema/empty_value_test.go @@ -168,3 +168,116 @@ func TestBlockEmptyValue(t *testing.T) { }) } } + +// Attribute EmptyValue() is well covered by the Block tests above; these tests +// focus on the behavior with NestedType field inside an Attribute +func TestAttributeEmptyValue(t *testing.T) { + tests := []struct { + Schema *Attribute + Want cty.Value + }{ + { + &Attribute{}, + cty.NilVal, + }, + { + &Attribute{ + Type: cty.String, + }, + cty.NullVal(cty.String), + }, + { + &Attribute{ + NestedType: &Object{ + // no Nesting set should behave the same as NestingSingle + Attributes: map[string]*Attribute{ + "str": {Type: cty.String, Required: true}, + }, + }, + }, + cty.NullVal(cty.Object(map[string]cty.Type{ + "str": cty.String, + })), + }, + { + &Attribute{ + NestedType: &Object{ + Nesting: NestingSingle, + Attributes: map[string]*Attribute{ + "str": {Type: cty.String, Required: true}, + }, + }, + }, + cty.NullVal(cty.Object(map[string]cty.Type{ + "str": cty.String, + })), + }, + { + &Attribute{ + NestedType: &Object{ + Nesting: NestingGroup, // functionally equivalent to NestingSingle in a NestedType + Attributes: map[string]*Attribute{ + "str": {Type: cty.String, Required: true}, + }, + }, + }, + cty.NullVal(cty.Object(map[string]cty.Type{ + "str": cty.String, + })), + }, + { + &Attribute{ + NestedType: &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "str": {Type: cty.String, Required: true}, + }, + }, + }, + cty.NullVal(cty.List( + cty.Object(map[string]cty.Type{ + "str": cty.String, + }), + )), + }, + { + &Attribute{ + NestedType: &Object{ + Nesting: NestingMap, + Attributes: map[string]*Attribute{ + "str": {Type: cty.String, Required: true}, + }, + }, + }, + cty.NullVal(cty.Map( + cty.Object(map[string]cty.Type{ + "str": cty.String, + }), + )), + }, + { + &Attribute{ + NestedType: &Object{ + Nesting: NestingSet, + Attributes: map[string]*Attribute{ + "str": {Type: cty.String, Required: true}, + }, + }, + }, + cty.NullVal(cty.Set( + cty.Object(map[string]cty.Type{ + "str": cty.String, + }), + )), + }, + } + + for _, test := range tests { + t.Run(fmt.Sprintf("%#v", test.Schema), func(t *testing.T) { + got := test.Schema.EmptyValue() + if !test.Want.RawEquals(got) { + t.Errorf("wrong result\nschema: %s\ngot: %s\nwant: %s", spew.Sdump(test.Schema), dump.Value(got), dump.Value(test.Want)) + } + }) + } +} diff --git a/configs/configschema/implied_type.go b/configs/configschema/implied_type.go index a81b7eab4731..729881a03164 100644 --- a/configs/configschema/implied_type.go +++ b/configs/configschema/implied_type.go @@ -40,3 +40,37 @@ func (b *Block) ContainsSensitive() bool { } return false } + +// ImpliedType returns the cty.Type that would result from decoding a NestedType +// Attribute using the receiving block schema. +// +// ImpliedType always returns a result, even if the given schema is +// inconsistent. Code that creates configschema.Object objects should be tested +// using the InternalValidate method to detect any inconsistencies that would +// cause this method to fall back on defaults and assumptions. +func (o *Object) ImpliedType() cty.Type { + if o == nil { + return cty.EmptyObject + } + + attrTys := make(map[string]cty.Type, len(o.Attributes)) + for name, attrS := range o.Attributes { + attrTys[name] = attrS.Type + } + + var optAttrs []string + optAttrs = listOptionalAttrsFromObject(o, optAttrs) + + return cty.ObjectWithOptionalAttrs(attrTys, optAttrs) +} + +// ContainsSensitive returns true if any of the attributes of the receiving +// Object are marked as sensitive. +func (o *Object) ContainsSensitive() bool { + for _, attrS := range o.Attributes { + if attrS.Sensitive { + return true + } + } + return false +} diff --git a/configs/configschema/implied_type_test.go b/configs/configschema/implied_type_test.go index 85e4a88d5529..56316eead885 100644 --- a/configs/configschema/implied_type_test.go +++ b/configs/configschema/implied_type_test.go @@ -122,3 +122,59 @@ func TestBlockImpliedType(t *testing.T) { }) } } + +func TestObjectImpliedType(t *testing.T) { + tests := map[string]struct { + Schema *Object + Want cty.Type + }{ + "nil": { + nil, + cty.EmptyObject, + }, + "empty": { + &Object{}, + cty.EmptyObject, + }, + "attributes": { + &Object{ + Attributes: map[string]*Attribute{ + "optional": { + Type: cty.String, + Optional: true, + }, + "required": { + Type: cty.Number, + Required: true, + }, + "computed": { + Type: cty.List(cty.Bool), + Computed: true, + }, + "optional_computed": { + Type: cty.Map(cty.Bool), + Optional: true, + }, + }, + }, + cty.ObjectWithOptionalAttrs( + map[string]cty.Type{ + "optional": cty.String, + "required": cty.Number, + "computed": cty.List(cty.Bool), + "optional_computed": cty.Map(cty.Bool), + }, + []string{"optional", "optional_computed"}, + ), + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + got := test.Schema.ImpliedType() + if !got.Equals(test.Want) { + t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) + } + }) + } +} diff --git a/configs/configschema/schema.go b/configs/configschema/schema.go index 4d3e7cabc899..581bead8b98e 100644 --- a/configs/configschema/schema.go +++ b/configs/configschema/schema.go @@ -38,8 +38,13 @@ type Block struct { // Attribute represents a configuration attribute, within a block. type Attribute struct { // Type is a type specification that the attribute's value must conform to. + // It conflicts with NestedType. Type cty.Type + // NestedType indicates that the attribute is a NestedBlock-style object. + // This field conflicts with Type. + NestedType *Object + // Description is an English-language description of the purpose and // usage of the attribute. A description should be concise and use only // one or two sentences, leaving full definition to longer-form @@ -72,6 +77,25 @@ type Attribute struct { Deprecated bool } +// Object represents the embedding of a structural object inside an Attribute. +type Object struct { + // Attributes describes the nested attributes which may appear inside the + // Object. + Attributes map[string]*Attribute + + // Nesting provides the nesting mode for this Object, which determines how + // many instances of the Object are allowed, how many labels it expects, and + // how the resulting data will be converted into a data structure. + Nesting NestingMode + + // MinItems and MaxItems set, for the NestingList and NestingSet nesting + // modes, lower and upper limits on the number of child blocks allowed + // of the given type. If both are left at zero, no limit is applied. + // These fields are ignored for other nesting modes and must both be left + // at zero. + MinItems, MaxItems int +} + // NestedBlock represents the embedding of one block within another. type NestedBlock struct { // Block is the description of the block that's nested. @@ -98,6 +122,8 @@ type NestedBlock struct { // blocks. type NestingMode int +// Object represents the embedding of a NestedBl + //go:generate go run golang.org/x/tools/cmd/stringer -type=NestingMode const ( From da6ac9d6cd12d61de060408380450c4666724819 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Fri, 5 Feb 2021 13:41:06 -0500 Subject: [PATCH 3/8] plans/objchange: add handling of NestedTypes inside attributes - rename ProposedNewObject to ProposedNew: Now that there is an actual configschema.Object it will be clearer if the function names match the type the act upon. - extract attribute-handling logic from assertPlanValid and extend A new function, assertPlannedAttrsValid, takes the existing functionality and extends it to validate attributes with NestedTypes. The NestedType-specific handling is in assertPlannedObjectValid, which is very similar to the block-handling logic, except that nulls are a valid plan (an attribute can be null, but not a block). --- plans/objchange/objchange.go | 291 +++++----- plans/objchange/objchange_test.go | 350 +++++++++++- plans/objchange/plan_valid.go | 190 ++++++- plans/objchange/plan_valid_test.go | 539 +++++++++++++++++++ terraform/node_resource_abstract_instance.go | 6 +- 5 files changed, 1214 insertions(+), 162 deletions(-) diff --git a/plans/objchange/objchange.go b/plans/objchange/objchange.go index ab16f68a4b7d..cf08dda64e83 100644 --- a/plans/objchange/objchange.go +++ b/plans/objchange/objchange.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform/configs/configschema" ) -// ProposedNewObject constructs a proposed new object value by combining the +// ProposedNew constructs a proposed new object value by combining the // computed attribute values from "prior" with the configured attribute values // from "config". // @@ -24,7 +24,7 @@ import ( // heuristic based on matching non-computed attribute values and so it may // produce strange results with more "extreme" cases, such as a nested set // block where _all_ attributes are computed. -func ProposedNewObject(schema *configschema.Block, prior, config cty.Value) cty.Value { +func ProposedNew(schema *configschema.Block, prior, config cty.Value) cty.Value { // If the config and prior are both null, return early here before // populating the prior block. The prevents non-null blocks from appearing // the proposed state value. @@ -39,10 +39,10 @@ func ProposedNewObject(schema *configschema.Block, prior, config cty.Value) cty. // below by giving us one non-null level of object to pull values from. prior = AllAttributesNull(schema) } - return proposedNewObject(schema, prior, config) + return proposedNew(schema, prior, config) } -// PlannedDataResourceObject is similar to ProposedNewObject but tailored for +// PlannedDataResourceObject is similar to proposedNewBlock but tailored for // planning data resources in particular. Specifically, it replaces the values // of any Computed attributes not set in the configuration with an unknown // value, which serves as a placeholder for a value to be filled in by the @@ -51,33 +51,32 @@ func ProposedNewObject(schema *configschema.Block, prior, config cty.Value) cty. // Data resources are different because the planning of them is handled // entirely within Terraform Core and not subject to customization by the // provider. This function is, in effect, producing an equivalent result to -// passing the ProposedNewObject result into a provider's PlanResourceChange +// passing the proposedNewBlock result into a provider's PlanResourceChange // function, assuming a fixed implementation of PlanResourceChange that just // fills in unknown values as needed. func PlannedDataResourceObject(schema *configschema.Block, config cty.Value) cty.Value { - // Our trick here is to run the ProposedNewObject logic with an + // Our trick here is to run the proposedNewBlock logic with an // entirely-unknown prior value. Because of cty's unknown short-circuit // behavior, any operation on prior returns another unknown, and so // unknown values propagate into all of the parts of the resulting value // that would normally be filled in by preserving the prior state. prior := cty.UnknownVal(schema.ImpliedType()) - return proposedNewObject(schema, prior, config) + return proposedNew(schema, prior, config) } -func proposedNewObject(schema *configschema.Block, prior, config cty.Value) cty.Value { +func proposedNew(schema *configschema.Block, prior, config cty.Value) cty.Value { if config.IsNull() || !config.IsKnown() { // This is a weird situation, but we'll allow it anyway to free // callers from needing to specifically check for these cases. return prior } if (!prior.Type().IsObjectType()) || (!config.Type().IsObjectType()) { - panic("ProposedNewObject only supports object-typed values") + panic("ProposedNew only supports object-typed values") } // From this point onwards, we can assume that both values are non-null // object types, and that the config value itself is known (though it // may contain nested values that are unknown.) - newAttrs := map[string]cty.Value{} for name, attr := range schema.Attributes { priorV := prior.GetAttr(name) @@ -118,165 +117,169 @@ func proposedNewObject(schema *configschema.Block, prior, config cty.Value) cty. for name, blockType := range schema.BlockTypes { priorV := prior.GetAttr(name) configV := config.GetAttr(name) - var newV cty.Value - switch blockType.Nesting { + newAttrs[name] = proposedNewNestedBlock(blockType, priorV, configV) + } - case configschema.NestingSingle, configschema.NestingGroup: - newV = ProposedNewObject(&blockType.Block, priorV, configV) + return cty.ObjectVal(newAttrs) +} + +func proposedNewNestedBlock(schema *configschema.NestedBlock, prior, config cty.Value) cty.Value { + var newV cty.Value - case configschema.NestingList: - // Nested blocks are correlated by index. + switch schema.Nesting { + + case configschema.NestingSingle, configschema.NestingGroup: + newV = ProposedNew(&schema.Block, prior, config) + + case configschema.NestingList: + // Nested blocks are correlated by index. + configVLen := 0 + if config.IsKnown() && !config.IsNull() { + configVLen = config.LengthInt() + } + if configVLen > 0 { + newVals := make([]cty.Value, 0, configVLen) + for it := config.ElementIterator(); it.Next(); { + idx, configEV := it.Element() + if prior.IsKnown() && (prior.IsNull() || !prior.HasIndex(idx).True()) { + // If there is no corresponding prior element then + // we just take the config value as-is. + newVals = append(newVals, configEV) + continue + } + priorEV := prior.Index(idx) + + newEV := ProposedNew(&schema.Block, priorEV, configEV) + newVals = append(newVals, newEV) + } + // Despite the name, a NestingList might also be a tuple, if + // its nested schema contains dynamically-typed attributes. + if config.Type().IsTupleType() { + newV = cty.TupleVal(newVals) + } else { + newV = cty.ListVal(newVals) + } + } else { + // Despite the name, a NestingList might also be a tuple, if + // its nested schema contains dynamically-typed attributes. + if config.Type().IsTupleType() { + newV = cty.EmptyTupleVal + } else { + newV = cty.ListValEmpty(schema.ImpliedType()) + } + } + + case configschema.NestingMap: + // Despite the name, a NestingMap may produce either a map or + // object value, depending on whether the nested schema contains + // dynamically-typed attributes. + if config.Type().IsObjectType() { + // Nested blocks are correlated by key. configVLen := 0 - if configV.IsKnown() && !configV.IsNull() { - configVLen = configV.LengthInt() + if config.IsKnown() && !config.IsNull() { + configVLen = config.LengthInt() } if configVLen > 0 { - newVals := make([]cty.Value, 0, configVLen) - for it := configV.ElementIterator(); it.Next(); { - idx, configEV := it.Element() - if priorV.IsKnown() && (priorV.IsNull() || !priorV.HasIndex(idx).True()) { + newVals := make(map[string]cty.Value, configVLen) + atys := config.Type().AttributeTypes() + for name := range atys { + configEV := config.GetAttr(name) + if !prior.IsKnown() || prior.IsNull() || !prior.Type().HasAttribute(name) { // If there is no corresponding prior element then // we just take the config value as-is. - newVals = append(newVals, configEV) + newVals[name] = configEV continue } - priorEV := priorV.Index(idx) + priorEV := prior.GetAttr(name) - newEV := ProposedNewObject(&blockType.Block, priorEV, configEV) - newVals = append(newVals, newEV) - } - // Despite the name, a NestingList might also be a tuple, if - // its nested schema contains dynamically-typed attributes. - if configV.Type().IsTupleType() { - newV = cty.TupleVal(newVals) - } else { - newV = cty.ListVal(newVals) + newEV := ProposedNew(&schema.Block, priorEV, configEV) + newVals[name] = newEV } + // Although we call the nesting mode "map", we actually use + // object values so that elements might have different types + // in case of dynamically-typed attributes. + newV = cty.ObjectVal(newVals) } else { - // Despite the name, a NestingList might also be a tuple, if - // its nested schema contains dynamically-typed attributes. - if configV.Type().IsTupleType() { - newV = cty.EmptyTupleVal - } else { - newV = cty.ListValEmpty(blockType.ImpliedType()) - } + newV = cty.EmptyObjectVal } - - case configschema.NestingMap: - // Despite the name, a NestingMap may produce either a map or - // object value, depending on whether the nested schema contains - // dynamically-typed attributes. - if configV.Type().IsObjectType() { - // Nested blocks are correlated by key. - configVLen := 0 - if configV.IsKnown() && !configV.IsNull() { - configVLen = configV.LengthInt() - } - if configVLen > 0 { - newVals := make(map[string]cty.Value, configVLen) - atys := configV.Type().AttributeTypes() - for name := range atys { - configEV := configV.GetAttr(name) - if !priorV.IsKnown() || priorV.IsNull() || !priorV.Type().HasAttribute(name) { - // If there is no corresponding prior element then - // we just take the config value as-is. - newVals[name] = configEV - continue - } - priorEV := priorV.GetAttr(name) - - newEV := ProposedNewObject(&blockType.Block, priorEV, configEV) - newVals[name] = newEV + } else { + configVLen := 0 + if config.IsKnown() && !config.IsNull() { + configVLen = config.LengthInt() + } + if configVLen > 0 { + newVals := make(map[string]cty.Value, configVLen) + for it := config.ElementIterator(); it.Next(); { + idx, configEV := it.Element() + k := idx.AsString() + if prior.IsKnown() && (prior.IsNull() || !prior.HasIndex(idx).True()) { + // If there is no corresponding prior element then + // we just take the config value as-is. + newVals[k] = configEV + continue } - // Although we call the nesting mode "map", we actually use - // object values so that elements might have different types - // in case of dynamically-typed attributes. - newV = cty.ObjectVal(newVals) - } else { - newV = cty.EmptyObjectVal + priorEV := prior.Index(idx) + + newEV := ProposedNew(&schema.Block, priorEV, configEV) + newVals[k] = newEV } + newV = cty.MapVal(newVals) } else { - configVLen := 0 - if configV.IsKnown() && !configV.IsNull() { - configVLen = configV.LengthInt() - } - if configVLen > 0 { - newVals := make(map[string]cty.Value, configVLen) - for it := configV.ElementIterator(); it.Next(); { - idx, configEV := it.Element() - k := idx.AsString() - if priorV.IsKnown() && (priorV.IsNull() || !priorV.HasIndex(idx).True()) { - // If there is no corresponding prior element then - // we just take the config value as-is. - newVals[k] = configEV - continue - } - priorEV := priorV.Index(idx) - - newEV := ProposedNewObject(&blockType.Block, priorEV, configEV) - newVals[k] = newEV - } - newV = cty.MapVal(newVals) - } else { - newV = cty.MapValEmpty(blockType.ImpliedType()) - } + newV = cty.MapValEmpty(schema.ImpliedType()) } + } - case configschema.NestingSet: - if !configV.Type().IsSetType() { - panic("configschema.NestingSet value is not a set as expected") - } + case configschema.NestingSet: + if !config.Type().IsSetType() { + panic("configschema.NestingSet value is not a set as expected") + } - // Nested blocks are correlated by comparing the element values - // after eliminating all of the computed attributes. In practice, - // this means that any config change produces an entirely new - // nested object, and we only propagate prior computed values - // if the non-computed attribute values are identical. - var cmpVals [][2]cty.Value - if priorV.IsKnown() && !priorV.IsNull() { - cmpVals = setElementCompareValues(&blockType.Block, priorV, false) - } - configVLen := 0 - if configV.IsKnown() && !configV.IsNull() { - configVLen = configV.LengthInt() - } - if configVLen > 0 { - used := make([]bool, len(cmpVals)) // track used elements in case multiple have the same compare value - newVals := make([]cty.Value, 0, configVLen) - for it := configV.ElementIterator(); it.Next(); { - _, configEV := it.Element() - var priorEV cty.Value - for i, cmp := range cmpVals { - if used[i] { - continue - } - if cmp[1].RawEquals(configEV) { - priorEV = cmp[0] - used[i] = true // we can't use this value on a future iteration - break - } + // Nested blocks are correlated by comparing the element values + // after eliminating all of the computed attributes. In practice, + // this means that any config change produces an entirely new + // nested object, and we only propagate prior computed values + // if the non-computed attribute values are identical. + var cmpVals [][2]cty.Value + if prior.IsKnown() && !prior.IsNull() { + cmpVals = setElementCompareValues(&schema.Block, prior, false) + } + configVLen := 0 + if config.IsKnown() && !config.IsNull() { + configVLen = config.LengthInt() + } + if configVLen > 0 { + used := make([]bool, len(cmpVals)) // track used elements in case multiple have the same compare value + newVals := make([]cty.Value, 0, configVLen) + for it := config.ElementIterator(); it.Next(); { + _, configEV := it.Element() + var priorEV cty.Value + for i, cmp := range cmpVals { + if used[i] { + continue } - if priorEV == cty.NilVal { - priorEV = cty.NullVal(blockType.ImpliedType()) + if cmp[1].RawEquals(configEV) { + priorEV = cmp[0] + used[i] = true // we can't use this value on a future iteration + break } - - newEV := ProposedNewObject(&blockType.Block, priorEV, configEV) - newVals = append(newVals, newEV) } - newV = cty.SetVal(newVals) - } else { - newV = cty.SetValEmpty(blockType.Block.ImpliedType()) - } + if priorEV == cty.NilVal { + priorEV = cty.NullVal(schema.ImpliedType()) + } - default: - // Should never happen, since the above cases are comprehensive. - panic(fmt.Sprintf("unsupported block nesting mode %s", blockType.Nesting)) + newEV := ProposedNew(&schema.Block, priorEV, configEV) + newVals = append(newVals, newEV) + } + newV = cty.SetVal(newVals) + } else { + newV = cty.SetValEmpty(schema.Block.ImpliedType()) } - newAttrs[name] = newV + default: + // Should never happen, since the above cases are comprehensive. + panic(fmt.Sprintf("unsupported block nesting mode %s", schema.Nesting)) } - - return cty.ObjectVal(newAttrs) + return newV } // setElementCompareValues takes a known, non-null value of a cty.Set type and @@ -290,7 +293,7 @@ func proposedNewObject(schema *configschema.Block, prior, config cty.Value) cty. // value and the one-indexed element is the corresponding "compare value". // // This is intended to help correlate prior elements with configured elements -// in ProposedNewObject. The result is a heuristic rather than an exact science, +// in proposedNewBlock. The result is a heuristic rather than an exact science, // since e.g. two separate elements may reduce to the same value through this // process. The caller must therefore be ready to deal with duplicates. func setElementCompareValues(schema *configschema.Block, set cty.Value, isConfig bool) [][2]cty.Value { diff --git a/plans/objchange/objchange_test.go b/plans/objchange/objchange_test.go index 065e4add88eb..9a523609d39c 100644 --- a/plans/objchange/objchange_test.go +++ b/plans/objchange/objchange_test.go @@ -33,6 +33,18 @@ func TestProposedNewObject(t *testing.T) { Type: cty.String, Computed: true, }, + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + }, + }, + Computed: true, + }, }, BlockTypes: map[string]*configschema.NestedBlock{ "baz": { @@ -57,6 +69,9 @@ func TestProposedNewObject(t *testing.T) { cty.NullVal(cty.DynamicPseudoType), cty.ObjectVal(map[string]cty.Value{ "foo": cty.StringVal("hello"), + "bloop": cty.NullVal(cty.Object(map[string]cty.Type{ + "blop": cty.String, + })), "bar": cty.NullVal(cty.String), "baz": cty.ObjectVal(map[string]cty.Value{ "boz": cty.StringVal("world"), @@ -76,6 +91,9 @@ func TestProposedNewObject(t *testing.T) { // usually changes them to "unknown" during PlanResourceChange, // to indicate that the value will be decided during apply. "bar": cty.NullVal(cty.String), + "bloop": cty.NullVal(cty.Object(map[string]cty.Type{ + "blop": cty.String, + })), "baz": cty.ObjectVal(map[string]cty.Value{ "boz": cty.StringVal("world"), @@ -90,6 +108,18 @@ func TestProposedNewObject(t *testing.T) { Type: cty.String, Optional: true, }, + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + }, + }, + Computed: true, + }, }, BlockTypes: map[string]*configschema.NestedBlock{ "baz": { @@ -109,14 +139,20 @@ func TestProposedNewObject(t *testing.T) { cty.NullVal(cty.DynamicPseudoType), cty.ObjectVal(map[string]cty.Value{ "foo": cty.StringVal("bar"), + "bloop": cty.NullVal(cty.Object(map[string]cty.Type{ + "blop": cty.String, + })), "baz": cty.NullVal(cty.Object(map[string]cty.Type{ "boz": cty.String, })), }), - // The baz block does not exist in the config, and therefore - // shouldn't be planned. + // The bloop attribue and baz block does not exist in the config, + // and therefore shouldn't be planned. cty.ObjectVal(map[string]cty.Value{ "foo": cty.StringVal("bar"), + "bloop": cty.NullVal(cty.Object(map[string]cty.Type{ + "blop": cty.String, + })), "baz": cty.NullVal(cty.Object(map[string]cty.Type{ "boz": cty.String, })), @@ -141,6 +177,21 @@ func TestProposedNewObject(t *testing.T) { }, }, }, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + }, + }, + Computed: true, + Optional: true, + }, + }, }, cty.NullVal(cty.DynamicPseudoType), cty.ObjectVal(map[string]cty.Value{ @@ -149,6 +200,11 @@ func TestProposedNewObject(t *testing.T) { "boz": cty.StringVal("world"), }), }), + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("blub"), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "baz": cty.SetVal([]cty.Value{ @@ -156,6 +212,11 @@ func TestProposedNewObject(t *testing.T) { "boz": cty.StringVal("world"), }), }), + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("blub"), + }), + }), }), }, "prior attributes": { @@ -179,6 +240,18 @@ func TestProposedNewObject(t *testing.T) { Optional: true, Computed: true, }, + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, }, }, cty.ObjectVal(map[string]cty.Value{ @@ -186,18 +259,27 @@ func TestProposedNewObject(t *testing.T) { "bar": cty.StringVal("petit dejeuner"), "baz": cty.StringVal("grande dejeuner"), "boz": cty.StringVal("a la monde"), + "bloop": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.StringVal("hello"), "bar": cty.NullVal(cty.String), "baz": cty.NullVal(cty.String), "boz": cty.StringVal("world"), + "bloop": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("bleep"), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.StringVal("hello"), "bar": cty.StringVal("petit dejeuner"), "baz": cty.StringVal("grande dejeuner"), "boz": cty.StringVal("world"), + "bloop": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("bleep"), + }), }), }, "prior nested single": { @@ -221,24 +303,54 @@ func TestProposedNewObject(t *testing.T) { }, }, }, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + "bleep": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, }, cty.ObjectVal(map[string]cty.Value{ "foo": cty.ObjectVal(map[string]cty.Value{ "bar": cty.StringVal("beep"), "baz": cty.StringVal("boop"), }), + "bloop": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + "bleep": cty.NullVal(cty.String), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.ObjectVal(map[string]cty.Value{ "bar": cty.StringVal("bap"), "baz": cty.NullVal(cty.String), }), + "bloop": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + "bleep": cty.StringVal("beep"), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.ObjectVal(map[string]cty.Value{ "bar": cty.StringVal("bap"), "baz": cty.StringVal("boop"), }), + "bloop": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + "bleep": cty.StringVal("beep"), + }), }), }, "prior nested list": { @@ -262,6 +374,20 @@ func TestProposedNewObject(t *testing.T) { }, }, }, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + }, }, cty.ObjectVal(map[string]cty.Value{ "foo": cty.ListVal([]cty.Value{ @@ -270,6 +396,14 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.StringVal("boop"), }), }), + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("bar"), + }), + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("baz"), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.ListVal([]cty.Value{ @@ -282,6 +416,14 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.String), }), }), + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("bar"), + }), + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("baz"), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.ListVal([]cty.Value{ @@ -294,6 +436,14 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.String), }), }), + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("bar"), + }), + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("baz"), + }), + }), }), }, "prior nested list with dynamic": { @@ -317,6 +467,24 @@ func TestProposedNewObject(t *testing.T) { }, }, }, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.DynamicPseudoType, + Required: true, + }, + "blub": { + Type: cty.DynamicPseudoType, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, }, cty.ObjectVal(map[string]cty.Value{ "foo": cty.TupleVal([]cty.Value{ @@ -325,6 +493,16 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.StringVal("boop"), }), }), + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("bar"), + "blub": cty.StringVal("glub"), + }), + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("baz"), + "blub": cty.NullVal(cty.String), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.TupleVal([]cty.Value{ @@ -337,6 +515,12 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.String), }), }), + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("bar"), + "blub": cty.NullVal(cty.String), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.TupleVal([]cty.Value{ @@ -349,6 +533,12 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.String), }), }), + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("bar"), + "blub": cty.NullVal(cty.String), + }), + }), }), }, "prior nested map": { @@ -372,6 +562,20 @@ func TestProposedNewObject(t *testing.T) { }, }, }, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingMap, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + }, }, cty.ObjectVal(map[string]cty.Value{ "foo": cty.MapVal(map[string]cty.Value{ @@ -384,6 +588,14 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.StringVal("boot"), }), }), + "bloop": cty.MapVal(map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + }), + "b": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("blub"), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.MapVal(map[string]cty.Value{ @@ -396,6 +608,14 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.String), }), }), + "bloop": cty.MapVal(map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + }), + "c": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("blub"), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.MapVal(map[string]cty.Value{ @@ -408,6 +628,14 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.String), }), }), + "bloop": cty.MapVal(map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + }), + "c": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("blub"), + }), + }), }), }, "prior nested map with dynamic": { @@ -431,6 +659,20 @@ func TestProposedNewObject(t *testing.T) { }, }, }, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingMap, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.DynamicPseudoType, + Required: true, + }, + }, + }, + Optional: true, + }, + }, }, cty.ObjectVal(map[string]cty.Value{ "foo": cty.ObjectVal(map[string]cty.Value{ @@ -443,6 +685,14 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.ListVal([]cty.Value{cty.StringVal("boot")}), }), }), + "bloop": cty.ObjectVal(map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + }), + "b": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.NumberIntVal(13), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.ObjectVal(map[string]cty.Value{ @@ -455,6 +705,14 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.List(cty.String)), }), }), + "bloop": cty.ObjectVal(map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("blep"), + }), + "c": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.NumberIntVal(13), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.ObjectVal(map[string]cty.Value{ @@ -467,6 +725,14 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.List(cty.String)), }), }), + "bloop": cty.ObjectVal(map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("blep"), + }), + "c": cty.ObjectVal(map[string]cty.Value{ + "blop": cty.NumberIntVal(13), + }), + }), }), }, "prior nested set": { @@ -492,6 +758,24 @@ func TestProposedNewObject(t *testing.T) { }, }, }, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + "bleep": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, }, cty.ObjectVal(map[string]cty.Value{ "foo": cty.SetVal([]cty.Value{ @@ -504,6 +788,16 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.StringVal("boot"), }), }), + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glubglub"), + "bleep": cty.NullVal(cty.String), + }), + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glubglub"), + "bleep": cty.StringVal("beep"), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.SetVal([]cty.Value{ @@ -516,6 +810,16 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.String), }), }), + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glubglub"), + "bleep": cty.NullVal(cty.String), + }), + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + "bleep": cty.NullVal(cty.String), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "foo": cty.SetVal([]cty.Value{ @@ -528,6 +832,16 @@ func TestProposedNewObject(t *testing.T) { "baz": cty.NullVal(cty.String), }), }), + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glubglub"), + "bleep": cty.NullVal(cty.String), + }), + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("glub"), + "bleep": cty.NullVal(cty.String), + }), + }), }), }, "sets differing only by unknown": { @@ -546,6 +860,20 @@ func TestProposedNewObject(t *testing.T) { }, }, }, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + }, }, cty.NullVal(cty.DynamicPseudoType), cty.ObjectVal(map[string]cty.Value{ @@ -557,6 +885,14 @@ func TestProposedNewObject(t *testing.T) { "optional": cty.UnknownVal(cty.String), }), }), + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.UnknownVal(cty.String), + }), + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.UnknownVal(cty.String), + }), + }), }), cty.ObjectVal(map[string]cty.Value{ "multi": cty.SetVal([]cty.Value{ @@ -570,6 +906,14 @@ func TestProposedNewObject(t *testing.T) { "optional": cty.UnknownVal(cty.String), }), }), + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.UnknownVal(cty.String), + }), + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.UnknownVal(cty.String), + }), + }), }), }, "nested list in set": { @@ -858,7 +1202,7 @@ func TestProposedNewObject(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { - got := ProposedNewObject(test.Schema, test.Prior, test.Config) + got := ProposedNew(test.Schema, test.Prior, test.Config) if !got.RawEquals(test.Want) { t.Errorf("wrong result\ngot: %swant: %s", dump.Value(got), dump.Value(test.Want)) } diff --git a/plans/objchange/plan_valid.go b/plans/objchange/plan_valid.go index 69acb8979a84..6a91428f834a 100644 --- a/plans/objchange/plan_valid.go +++ b/plans/objchange/plan_valid.go @@ -53,18 +53,10 @@ func assertPlanValid(schema *configschema.Block, priorState, config, plannedStat impTy := schema.ImpliedType() - for name, attrS := range schema.Attributes { - plannedV := plannedState.GetAttr(name) - configV := config.GetAttr(name) - priorV := cty.NullVal(attrS.Type) - if !priorState.IsNull() { - priorV = priorState.GetAttr(name) - } + // verify attributes + moreErrs := assertPlannedAttrsValid(schema.Attributes, priorState, config, plannedState, path) + errs = append(errs, moreErrs...) - path := append(path, cty.GetAttrStep{Name: name}) - moreErrs := assertPlannedValueValid(attrS, priorV, configV, plannedV, path) - errs = append(errs, moreErrs...) - } for name, blockS := range schema.BlockTypes { path := append(path, cty.GetAttrStep{Name: name}) plannedV := plannedState.GetAttr(name) @@ -229,13 +221,34 @@ func assertPlanValid(schema *configschema.Block, priorState, config, plannedStat return errs } +func assertPlannedAttrsValid(schema map[string]*configschema.Attribute, priorState, config, plannedState cty.Value, path cty.Path) []error { + var errs []error + for name, attrS := range schema { + moreErrs := assertPlannedAttrValid(name, attrS, priorState, config, plannedState, path) + errs = append(errs, moreErrs...) + } + return errs +} + +func assertPlannedAttrValid(name string, attrS *configschema.Attribute, priorState, config, plannedState cty.Value, path cty.Path) []error { + plannedV := plannedState.GetAttr(name) + configV := config.GetAttr(name) + priorV := cty.NullVal(attrS.Type) + if !priorState.IsNull() { + priorV = priorState.GetAttr(name) + } + path = append(path, cty.GetAttrStep{Name: name}) + + return assertPlannedValueValid(attrS, priorV, configV, plannedV, path) +} + func assertPlannedValueValid(attrS *configschema.Attribute, priorV, configV, plannedV cty.Value, path cty.Path) []error { var errs []error if plannedV.RawEquals(configV) { // This is the easy path: provider didn't change anything at all. return errs } - if plannedV.RawEquals(priorV) && !priorV.IsNull() { + if plannedV.RawEquals(priorV) && !priorV.IsNull() && !configV.IsNull() { // Also pretty easy: there is a prior value and the provider has // returned it unchanged. This indicates that configV and plannedV // are functionally equivalent and so the provider wishes to disregard @@ -248,6 +261,11 @@ func assertPlannedValueValid(attrS *configschema.Attribute, priorV, configV, pla return errs } + // If this attribute has a NestedType, validate the nested object + if attrS.NestedType != nil { + return assertPlannedObjectValid(attrS.NestedType, priorV, configV, plannedV, path) + } + // If none of the above conditions match, the provider has made an invalid // change to this attribute. if priorV.IsNull() { @@ -265,3 +283,151 @@ func assertPlannedValueValid(attrS *configschema.Attribute, priorV, configV, pla } return errs } + +func assertPlannedObjectValid(schema *configschema.Object, prior, config, planned cty.Value, path cty.Path) []error { + var errs []error + + if planned.IsNull() && !config.IsNull() { + errs = append(errs, path.NewErrorf("planned for absense but config wants existence")) + return errs + } + if config.IsNull() && !planned.IsNull() { + errs = append(errs, path.NewErrorf("planned for existence but config wants absense")) + return errs + } + if planned.IsNull() { + // No further checks possible if the planned value is null + return errs + } + + switch schema.Nesting { + case configschema.NestingSingle, configschema.NestingGroup: + moreErrs := assertPlannedAttrsValid(schema.Attributes, prior, config, planned, path) + errs = append(errs, moreErrs...) + + case configschema.NestingList: + // A NestingList might either be a list or a tuple, depending on + // whether there are dynamically-typed attributes inside. However, + // both support a similar-enough API that we can treat them the + // same for our purposes here. + + plannedL := planned.LengthInt() + configL := config.LengthInt() + if plannedL != configL { + errs = append(errs, path.NewErrorf("count in plan (%d) disagrees with count in config (%d)", plannedL, configL)) + return errs + } + for it := planned.ElementIterator(); it.Next(); { + idx, plannedEV := it.Element() + path := append(path, cty.IndexStep{Key: idx}) + if !plannedEV.IsKnown() { + errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead")) + continue + } + if !config.HasIndex(idx).True() { + continue // should never happen since we checked the lengths above + } + configEV := config.Index(idx) + priorEV := cty.NullVal(schema.ImpliedType()) + if !prior.IsNull() && prior.HasIndex(idx).True() { + priorEV = prior.Index(idx) + } + + moreErrs := assertPlannedAttrsValid(schema.Attributes, priorEV, configEV, plannedEV, path) + errs = append(errs, moreErrs...) + } + + case configschema.NestingMap: + // A NestingMap might either be a map or an object, depending on + // whether there are dynamically-typed attributes inside, but + // that's decided statically and so all values will have the same + // kind. + if planned.Type().IsObjectType() { + plannedAtys := planned.Type().AttributeTypes() + configAtys := config.Type().AttributeTypes() + for k := range plannedAtys { + if _, ok := configAtys[k]; !ok { + errs = append(errs, path.NewErrorf("block key %q from plan is not present in config", k)) + continue + } + path := append(path, cty.GetAttrStep{Name: k}) + + plannedEV := planned.GetAttr(k) + if !plannedEV.IsKnown() { + errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead")) + continue + } + configEV := config.GetAttr(k) + priorEV := cty.NullVal(schema.ImpliedType()) + if !prior.IsNull() && prior.Type().HasAttribute(k) { + priorEV = prior.GetAttr(k) + } + moreErrs := assertPlannedAttrsValid(schema.Attributes, priorEV, configEV, plannedEV, path) + errs = append(errs, moreErrs...) + } + for k := range configAtys { + if _, ok := plannedAtys[k]; !ok { + errs = append(errs, path.NewErrorf("block key %q from config is not present in plan", k)) + continue + } + } + } else { + plannedL := planned.LengthInt() + configL := config.LengthInt() + if plannedL != configL { + errs = append(errs, path.NewErrorf("block count in plan (%d) disagrees with count in config (%d)", plannedL, configL)) + return errs + } + for it := planned.ElementIterator(); it.Next(); { + idx, plannedEV := it.Element() + path := append(path, cty.IndexStep{Key: idx}) + if !plannedEV.IsKnown() { + errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead")) + continue + } + k := idx.AsString() + if !config.HasIndex(idx).True() { + errs = append(errs, path.NewErrorf("block key %q from plan is not present in config", k)) + continue + } + configEV := config.Index(idx) + priorEV := cty.NullVal(schema.ImpliedType()) + if !prior.IsNull() && prior.HasIndex(idx).True() { + priorEV = prior.Index(idx) + } + moreErrs := assertPlannedObjectValid(schema, priorEV, configEV, plannedEV, path) + errs = append(errs, moreErrs...) + } + for it := config.ElementIterator(); it.Next(); { + idx, _ := it.Element() + if !planned.HasIndex(idx).True() { + errs = append(errs, path.NewErrorf("block key %q from config is not present in plan", idx.AsString())) + continue + } + } + } + + case configschema.NestingSet: + // Because set elements have no identifier with which to correlate + // them, we can't robustly validate the plan for a nested block + // backed by a set, and so unfortunately we need to just trust the + // provider to do the right thing. :( + // + // (In principle we could correlate elements by matching the + // subset of attributes explicitly set in config, except for the + // special diff suppression rule which allows for there to be a + // planned value that is constructed by mixing part of a prior + // value with part of a config value, creating an entirely new + // element that is not present in either prior nor config.) + for it := planned.ElementIterator(); it.Next(); { + idx, plannedEV := it.Element() + path := append(path, cty.IndexStep{Key: idx}) + if !plannedEV.IsKnown() { + errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead")) + continue + } + } + } + + return errs +} diff --git a/plans/objchange/plan_valid_test.go b/plans/objchange/plan_valid_test.go index cc41d694a396..1abc156773d9 100644 --- a/plans/objchange/plan_valid_test.go +++ b/plans/objchange/plan_valid_test.go @@ -579,6 +579,545 @@ func TestAssertPlanValid(t *testing.T) { }), nil, }, + + // Attributes with NestedTypes + "NestedType attr, no computed, all match": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "a": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "b": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("b value"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("b value"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("b value"), + }), + }), + }), + nil, + }, + "NestedType attr, no computed, plan matches, no prior": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "a": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "b": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.NullVal(cty.Object(map[string]cty.Type{ + "a": cty.List(cty.Object(map[string]cty.Type{ + "b": cty.String, + })), + })), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("c value"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("c value"), + }), + }), + }), + nil, + }, + "NestedType, no computed, invalid change in plan": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "a": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "b": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.NullVal(cty.Object(map[string]cty.Type{ + "a": cty.List(cty.Object(map[string]cty.Type{ + "b": cty.String, + })), + })), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("c value"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("new c value"), + }), + }), + }), + []string{ + `.a[0].b: planned value cty.StringVal("new c value") does not match config value cty.StringVal("c value")`, + }, + }, + "NestedType attr, no computed, invalid change in plan sensitive": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "a": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "b": { + Type: cty.String, + Optional: true, + Sensitive: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.NullVal(cty.Object(map[string]cty.Type{ + "a": cty.List(cty.Object(map[string]cty.Type{ + "b": cty.String, + })), + })), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("b value"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("new b value"), + }), + }), + }), + []string{ + `.a[0].b: sensitive planned value does not match config value`, + }, + }, + "NestedType attr, no computed, diff suppression in plan": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "a": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "b": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("b value"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("new b value"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "b": cty.StringVal("b value"), // plan uses value from prior object + }), + }), + }), + nil, + }, + "NestedType attr, no computed, all null": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "a": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "b": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "a": cty.NullVal(cty.DynamicPseudoType), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.NullVal(cty.DynamicPseudoType), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.NullVal(cty.DynamicPseudoType), + }), + nil, + }, + "NestedType attr, no computed, all zero value": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "a": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "b": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "a": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ + "b": cty.String, + }))), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ + "b": cty.String, + }))), + }), + cty.ObjectVal(map[string]cty.Value{ + "a": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ + "b": cty.String, + }))), + }), + nil, + }, + "NestedType NestingSet attribute to null": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("ok"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{ + "blop": cty.String, + }))), + }), + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{ + "blop": cty.String, + }))), + }), + nil, + }, + "NestedType deep nested optional set attribute to null": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "bleep": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "blome": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "bleep": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blome": cty.StringVal("ok"), + }), + }), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "bleep": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.NullVal(cty.Set( + cty.Object(map[string]cty.Type{ + "blome": cty.String, + }), + )), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "bleep": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.NullVal(cty.List( + cty.Object(map[string]cty.Type{ + "blome": cty.String, + }), + )), + }), + }), + }), + nil, + }, + "NestedType deep nested set": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "bleep": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "blome": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "bleep": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blome": cty.StringVal("ok"), + }), + }), + }), + }), + }), + // Note: bloop is null in the config + cty.ObjectVal(map[string]cty.Value{ + "bleep": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.NullVal(cty.Set( + cty.Object(map[string]cty.Type{ + "blome": cty.String, + }), + )), + }), + }), + }), + // provider sends back the prior value, not matching the config + cty.ObjectVal(map[string]cty.Value{ + "bleep": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blome": cty.StringVal("ok"), + }), + }), + }), + }), + }), + nil, // we cannot validate individual set elements, and trust the provider's response + }, + "NestedType nested computed list attribute": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Optional: true, + }, + }, + }, + Computed: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("ok"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ + "blop": cty.String, + }))), + }), + + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("ok"), + }), + }), + }), + nil, + }, + "NestedType nested list attribute to null": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("ok"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{ + "blop": cty.String, + }))), + }), + + // provider returned the old value + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("ok"), + }), + }), + }), + []string{".bloop: planned for existence but config wants absense"}, + }, + "NestedType nested set attribute to null": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "bloop": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "blop": { + Type: cty.String, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("ok"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{ + "blop": cty.String, + }))), + }), + // provider returned the old value + cty.ObjectVal(map[string]cty.Value{ + "bloop": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "blop": cty.StringVal("ok"), + }), + }), + }), + []string{".bloop: planned for existence but config wants absense"}, + }, } for name, test := range tests { diff --git a/terraform/node_resource_abstract_instance.go b/terraform/node_resource_abstract_instance.go index c73f600500c4..5bc1a4468173 100644 --- a/terraform/node_resource_abstract_instance.go +++ b/terraform/node_resource_abstract_instance.go @@ -649,7 +649,7 @@ func (n *NodeAbstractResourceInstance) plan( return plan, state, diags } - proposedNewVal := objchange.ProposedNewObject(schema, unmarkedPriorVal, configValIgnored) + proposedNewVal := objchange.ProposedNew(schema, unmarkedPriorVal, configValIgnored) // Call pre-diff hook diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { @@ -861,7 +861,7 @@ func (n *NodeAbstractResourceInstance) plan( } // create a new proposed value from the null state and the config - proposedNewVal = objchange.ProposedNewObject(schema, nullPriorVal, unmarkedConfigVal) + proposedNewVal = objchange.ProposedNew(schema, nullPriorVal, unmarkedConfigVal) resp = provider.PlanResourceChange(providers.PlanResourceChangeRequest{ TypeName: n.Addr.Resource.Resource.Type, @@ -1423,7 +1423,7 @@ func (n *NodeAbstractResourceInstance) planDataSource(ctx EvalContext, currentSt // While we don't propose planned changes for data sources, we can // generate a proposed value for comparison to ensure the data source // is returning a result following the rules of the provider contract. - proposedVal := objchange.ProposedNewObject(schema, unmarkedPriorVal, unmarkedConfigVal) + proposedVal := objchange.ProposedNew(schema, unmarkedPriorVal, unmarkedConfigVal) if errs := objchange.AssertObjectCompatible(schema, proposedVal, newVal); len(errs) > 0 { // Resources have the LegacyTypeSystem field to signal when they are // using an SDK which may not produce precise values. While data From 1a8d873c22cec564b5df31a1c1c74762a7177b68 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Fri, 5 Feb 2021 15:40:58 -0500 Subject: [PATCH 4/8] plugin6: new plugin package to support plugin protocol v6 plugin6 includes a `convert` package to handle conversion between the plugin protocol and configschema, and the GRPCProviderPlugin interface implementation for protocol v6. --- plugin6/convert/diagnostics.go | 132 ++++++ plugin6/convert/diagnostics_test.go | 367 +++++++++++++++++ plugin6/convert/schema.go | 301 ++++++++++++++ plugin6/convert/schema_test.go | 568 +++++++++++++++++++++++++ plugin6/doc.go | 9 + plugin6/grpc_error.go | 74 ++++ plugin6/grpc_provider.go | 617 ++++++++++++++++++++++++++++ plugin6/serve.go | 68 +++ 8 files changed, 2136 insertions(+) create mode 100644 plugin6/convert/diagnostics.go create mode 100644 plugin6/convert/diagnostics_test.go create mode 100644 plugin6/convert/schema.go create mode 100644 plugin6/convert/schema_test.go create mode 100644 plugin6/doc.go create mode 100644 plugin6/grpc_error.go create mode 100644 plugin6/grpc_provider.go create mode 100644 plugin6/serve.go diff --git a/plugin6/convert/diagnostics.go b/plugin6/convert/diagnostics.go new file mode 100644 index 000000000000..6d1db136e6eb --- /dev/null +++ b/plugin6/convert/diagnostics.go @@ -0,0 +1,132 @@ +package convert + +import ( + proto "github.com/hashicorp/terraform/internal/tfplugin6" + "github.com/hashicorp/terraform/tfdiags" + "github.com/zclconf/go-cty/cty" +) + +// WarnsAndErrorsToProto converts the warnings and errors return by the legacy +// provider to protobuf diagnostics. +func WarnsAndErrsToProto(warns []string, errs []error) (diags []*proto.Diagnostic) { + for _, w := range warns { + diags = AppendProtoDiag(diags, w) + } + + for _, e := range errs { + diags = AppendProtoDiag(diags, e) + } + + return diags +} + +// AppendProtoDiag appends a new diagnostic from a warning string or an error. +// This panics if d is not a string or error. +func AppendProtoDiag(diags []*proto.Diagnostic, d interface{}) []*proto.Diagnostic { + switch d := d.(type) { + case cty.PathError: + ap := PathToAttributePath(d.Path) + diags = append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: d.Error(), + Attribute: ap, + }) + case error: + diags = append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: d.Error(), + }) + case string: + diags = append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_WARNING, + Summary: d, + }) + case *proto.Diagnostic: + diags = append(diags, d) + case []*proto.Diagnostic: + diags = append(diags, d...) + } + return diags +} + +// ProtoToDiagnostics converts a list of proto.Diagnostics to a tf.Diagnostics. +func ProtoToDiagnostics(ds []*proto.Diagnostic) tfdiags.Diagnostics { + var diags tfdiags.Diagnostics + for _, d := range ds { + var severity tfdiags.Severity + + switch d.Severity { + case proto.Diagnostic_ERROR: + severity = tfdiags.Error + case proto.Diagnostic_WARNING: + severity = tfdiags.Warning + } + + var newDiag tfdiags.Diagnostic + + // if there's an attribute path, we need to create a AttributeValue diagnostic + if d.Attribute != nil { + path := AttributePathToPath(d.Attribute) + newDiag = tfdiags.AttributeValue(severity, d.Summary, d.Detail, path) + } else { + newDiag = tfdiags.WholeContainingBody(severity, d.Summary, d.Detail) + } + + diags = diags.Append(newDiag) + } + + return diags +} + +// AttributePathToPath takes the proto encoded path and converts it to a cty.Path +func AttributePathToPath(ap *proto.AttributePath) cty.Path { + var p cty.Path + for _, step := range ap.Steps { + switch selector := step.Selector.(type) { + case *proto.AttributePath_Step_AttributeName: + p = p.GetAttr(selector.AttributeName) + case *proto.AttributePath_Step_ElementKeyString: + p = p.Index(cty.StringVal(selector.ElementKeyString)) + case *proto.AttributePath_Step_ElementKeyInt: + p = p.Index(cty.NumberIntVal(selector.ElementKeyInt)) + } + } + return p +} + +// AttributePathToPath takes a cty.Path and converts it to a proto-encoded path. +func PathToAttributePath(p cty.Path) *proto.AttributePath { + ap := &proto.AttributePath{} + for _, step := range p { + switch selector := step.(type) { + case cty.GetAttrStep: + ap.Steps = append(ap.Steps, &proto.AttributePath_Step{ + Selector: &proto.AttributePath_Step_AttributeName{ + AttributeName: selector.Name, + }, + }) + case cty.IndexStep: + key := selector.Key + switch key.Type() { + case cty.String: + ap.Steps = append(ap.Steps, &proto.AttributePath_Step{ + Selector: &proto.AttributePath_Step_ElementKeyString{ + ElementKeyString: key.AsString(), + }, + }) + case cty.Number: + v, _ := key.AsBigFloat().Int64() + ap.Steps = append(ap.Steps, &proto.AttributePath_Step{ + Selector: &proto.AttributePath_Step_ElementKeyInt{ + ElementKeyInt: v, + }, + }) + default: + // We'll bail early if we encounter anything else, and just + // return the valid prefix. + return ap + } + } + } + return ap +} diff --git a/plugin6/convert/diagnostics_test.go b/plugin6/convert/diagnostics_test.go new file mode 100644 index 000000000000..24f269d05919 --- /dev/null +++ b/plugin6/convert/diagnostics_test.go @@ -0,0 +1,367 @@ +package convert + +import ( + "errors" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + proto "github.com/hashicorp/terraform/internal/tfplugin6" + "github.com/hashicorp/terraform/tfdiags" + "github.com/zclconf/go-cty/cty" +) + +var ignoreUnexported = cmpopts.IgnoreUnexported( + proto.Diagnostic{}, + proto.Schema_Block{}, + proto.Schema_NestedBlock{}, + proto.Schema_Attribute{}, +) + +func TestProtoDiagnostics(t *testing.T) { + diags := WarnsAndErrsToProto( + []string{ + "warning 1", + "warning 2", + }, + []error{ + errors.New("error 1"), + errors.New("error 2"), + }, + ) + + expected := []*proto.Diagnostic{ + { + Severity: proto.Diagnostic_WARNING, + Summary: "warning 1", + }, + { + Severity: proto.Diagnostic_WARNING, + Summary: "warning 2", + }, + { + Severity: proto.Diagnostic_ERROR, + Summary: "error 1", + }, + { + Severity: proto.Diagnostic_ERROR, + Summary: "error 2", + }, + } + + if !cmp.Equal(expected, diags, ignoreUnexported) { + t.Fatal(cmp.Diff(expected, diags, ignoreUnexported)) + } +} + +func TestDiagnostics(t *testing.T) { + type diagFlat struct { + Severity tfdiags.Severity + Attr []interface{} + Summary string + Detail string + } + + tests := map[string]struct { + Cons func([]*proto.Diagnostic) []*proto.Diagnostic + Want []diagFlat + }{ + "nil": { + func(diags []*proto.Diagnostic) []*proto.Diagnostic { + return diags + }, + nil, + }, + "error": { + func(diags []*proto.Diagnostic) []*proto.Diagnostic { + return append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: "simple error", + }) + }, + []diagFlat{ + { + Severity: tfdiags.Error, + Summary: "simple error", + }, + }, + }, + "detailed error": { + func(diags []*proto.Diagnostic) []*proto.Diagnostic { + return append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: "simple error", + Detail: "detailed error", + }) + }, + []diagFlat{ + { + Severity: tfdiags.Error, + Summary: "simple error", + Detail: "detailed error", + }, + }, + }, + "warning": { + func(diags []*proto.Diagnostic) []*proto.Diagnostic { + return append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_WARNING, + Summary: "simple warning", + }) + }, + []diagFlat{ + { + Severity: tfdiags.Warning, + Summary: "simple warning", + }, + }, + }, + "detailed warning": { + func(diags []*proto.Diagnostic) []*proto.Diagnostic { + return append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_WARNING, + Summary: "simple warning", + Detail: "detailed warning", + }) + }, + []diagFlat{ + { + Severity: tfdiags.Warning, + Summary: "simple warning", + Detail: "detailed warning", + }, + }, + }, + "multi error": { + func(diags []*proto.Diagnostic) []*proto.Diagnostic { + diags = append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: "first error", + }, &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: "second error", + }) + return diags + }, + []diagFlat{ + { + Severity: tfdiags.Error, + Summary: "first error", + }, + { + Severity: tfdiags.Error, + Summary: "second error", + }, + }, + }, + "warning and error": { + func(diags []*proto.Diagnostic) []*proto.Diagnostic { + diags = append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_WARNING, + Summary: "warning", + }, &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: "error", + }) + return diags + }, + []diagFlat{ + { + Severity: tfdiags.Warning, + Summary: "warning", + }, + { + Severity: tfdiags.Error, + Summary: "error", + }, + }, + }, + "attr error": { + func(diags []*proto.Diagnostic) []*proto.Diagnostic { + diags = append(diags, &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: "error", + Detail: "error detail", + Attribute: &proto.AttributePath{ + Steps: []*proto.AttributePath_Step{ + { + Selector: &proto.AttributePath_Step_AttributeName{ + AttributeName: "attribute_name", + }, + }, + }, + }, + }) + return diags + }, + []diagFlat{ + { + Severity: tfdiags.Error, + Summary: "error", + Detail: "error detail", + Attr: []interface{}{"attribute_name"}, + }, + }, + }, + "multi attr": { + func(diags []*proto.Diagnostic) []*proto.Diagnostic { + diags = append(diags, + &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: "error 1", + Detail: "error 1 detail", + Attribute: &proto.AttributePath{ + Steps: []*proto.AttributePath_Step{ + { + Selector: &proto.AttributePath_Step_AttributeName{ + AttributeName: "attr", + }, + }, + }, + }, + }, + &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: "error 2", + Detail: "error 2 detail", + Attribute: &proto.AttributePath{ + Steps: []*proto.AttributePath_Step{ + { + Selector: &proto.AttributePath_Step_AttributeName{ + AttributeName: "attr", + }, + }, + { + Selector: &proto.AttributePath_Step_AttributeName{ + AttributeName: "sub", + }, + }, + }, + }, + }, + &proto.Diagnostic{ + Severity: proto.Diagnostic_WARNING, + Summary: "warning", + Detail: "warning detail", + Attribute: &proto.AttributePath{ + Steps: []*proto.AttributePath_Step{ + { + Selector: &proto.AttributePath_Step_AttributeName{ + AttributeName: "attr", + }, + }, + { + Selector: &proto.AttributePath_Step_ElementKeyInt{ + ElementKeyInt: 1, + }, + }, + { + Selector: &proto.AttributePath_Step_AttributeName{ + AttributeName: "sub", + }, + }, + }, + }, + }, + &proto.Diagnostic{ + Severity: proto.Diagnostic_ERROR, + Summary: "error 3", + Detail: "error 3 detail", + Attribute: &proto.AttributePath{ + Steps: []*proto.AttributePath_Step{ + { + Selector: &proto.AttributePath_Step_AttributeName{ + AttributeName: "attr", + }, + }, + { + Selector: &proto.AttributePath_Step_ElementKeyString{ + ElementKeyString: "idx", + }, + }, + { + Selector: &proto.AttributePath_Step_AttributeName{ + AttributeName: "sub", + }, + }, + }, + }, + }, + ) + + return diags + }, + []diagFlat{ + { + Severity: tfdiags.Error, + Summary: "error 1", + Detail: "error 1 detail", + Attr: []interface{}{"attr"}, + }, + { + Severity: tfdiags.Error, + Summary: "error 2", + Detail: "error 2 detail", + Attr: []interface{}{"attr", "sub"}, + }, + { + Severity: tfdiags.Warning, + Summary: "warning", + Detail: "warning detail", + Attr: []interface{}{"attr", 1, "sub"}, + }, + { + Severity: tfdiags.Error, + Summary: "error 3", + Detail: "error 3 detail", + Attr: []interface{}{"attr", "idx", "sub"}, + }, + }, + }, + } + + flattenTFDiags := func(ds tfdiags.Diagnostics) []diagFlat { + var flat []diagFlat + for _, item := range ds { + desc := item.Description() + + var attr []interface{} + + for _, a := range tfdiags.GetAttribute(item) { + switch step := a.(type) { + case cty.GetAttrStep: + attr = append(attr, step.Name) + case cty.IndexStep: + switch step.Key.Type() { + case cty.Number: + i, _ := step.Key.AsBigFloat().Int64() + attr = append(attr, int(i)) + case cty.String: + attr = append(attr, step.Key.AsString()) + } + } + } + + flat = append(flat, diagFlat{ + Severity: item.Severity(), + Attr: attr, + Summary: desc.Summary, + Detail: desc.Detail, + }) + } + return flat + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + // we take the + tfDiags := ProtoToDiagnostics(tc.Cons(nil)) + + flat := flattenTFDiags(tfDiags) + + if !cmp.Equal(flat, tc.Want, typeComparer, valueComparer, equateEmpty) { + t.Fatal(cmp.Diff(flat, tc.Want, typeComparer, valueComparer, equateEmpty)) + } + }) + } +} diff --git a/plugin6/convert/schema.go b/plugin6/convert/schema.go new file mode 100644 index 000000000000..eaaace378e0f --- /dev/null +++ b/plugin6/convert/schema.go @@ -0,0 +1,301 @@ +package convert + +import ( + "encoding/json" + "reflect" + "sort" + + "github.com/hashicorp/terraform/configs/configschema" + proto "github.com/hashicorp/terraform/internal/tfplugin6" + "github.com/hashicorp/terraform/providers" + "github.com/zclconf/go-cty/cty" +) + +// ConfigSchemaToProto takes a *configschema.Block and converts it to a +// proto.Schema_Block for a grpc response. +func ConfigSchemaToProto(b *configschema.Block) *proto.Schema_Block { + block := &proto.Schema_Block{ + Description: b.Description, + DescriptionKind: protoStringKind(b.DescriptionKind), + Deprecated: b.Deprecated, + } + + for _, name := range sortedKeys(b.Attributes) { + a := b.Attributes[name] + + attr := &proto.Schema_Attribute{ + Name: name, + Description: a.Description, + DescriptionKind: protoStringKind(a.DescriptionKind), + Optional: a.Optional, + Computed: a.Computed, + Required: a.Required, + Sensitive: a.Sensitive, + Deprecated: a.Deprecated, + } + + if a.Type != cty.NilType { + ty, err := json.Marshal(a.Type) + if err != nil { + panic(err) + } + attr.Type = ty + } + + if a.NestedType != nil { + attr.NestedType = configschemaObjectToProto(a.NestedType) + } + + block.Attributes = append(block.Attributes, attr) + } + + for _, name := range sortedKeys(b.BlockTypes) { + b := b.BlockTypes[name] + block.BlockTypes = append(block.BlockTypes, protoSchemaNestedBlock(name, b)) + } + + return block +} + +func protoStringKind(k configschema.StringKind) proto.StringKind { + switch k { + default: + return proto.StringKind_PLAIN + case configschema.StringMarkdown: + return proto.StringKind_MARKDOWN + } +} + +func protoSchemaNestedBlock(name string, b *configschema.NestedBlock) *proto.Schema_NestedBlock { + var nesting proto.Schema_NestedBlock_NestingMode + switch b.Nesting { + case configschema.NestingSingle: + nesting = proto.Schema_NestedBlock_SINGLE + case configschema.NestingGroup: + nesting = proto.Schema_NestedBlock_GROUP + case configschema.NestingList: + nesting = proto.Schema_NestedBlock_LIST + case configschema.NestingSet: + nesting = proto.Schema_NestedBlock_SET + case configschema.NestingMap: + nesting = proto.Schema_NestedBlock_MAP + default: + nesting = proto.Schema_NestedBlock_INVALID + } + return &proto.Schema_NestedBlock{ + TypeName: name, + Block: ConfigSchemaToProto(&b.Block), + Nesting: nesting, + MinItems: int64(b.MinItems), + MaxItems: int64(b.MaxItems), + } +} + +// ProtoToProviderSchema takes a proto.Schema and converts it to a providers.Schema. +func ProtoToProviderSchema(s *proto.Schema) providers.Schema { + return providers.Schema{ + Version: s.Version, + Block: ProtoToConfigSchema(s.Block), + } +} + +// ProtoToConfigSchema takes the GetSchcema_Block from a grpc response and converts it +// to a terraform *configschema.Block. +func ProtoToConfigSchema(b *proto.Schema_Block) *configschema.Block { + block := &configschema.Block{ + Attributes: make(map[string]*configschema.Attribute), + BlockTypes: make(map[string]*configschema.NestedBlock), + + Description: b.Description, + DescriptionKind: schemaStringKind(b.DescriptionKind), + Deprecated: b.Deprecated, + } + + for _, a := range b.Attributes { + attr := &configschema.Attribute{ + Description: a.Description, + DescriptionKind: schemaStringKind(a.DescriptionKind), + Required: a.Required, + Optional: a.Optional, + Computed: a.Computed, + Sensitive: a.Sensitive, + Deprecated: a.Deprecated, + } + + if a.Type != nil { + if err := json.Unmarshal(a.Type, &attr.Type); err != nil { + panic(err) + } + } + + if a.NestedType != nil { + attr.NestedType = protoObjectToConfigSchema(a.NestedType) + } + + block.Attributes[a.Name] = attr + } + + for _, b := range b.BlockTypes { + block.BlockTypes[b.TypeName] = schemaNestedBlock(b) + } + + return block +} + +func schemaStringKind(k proto.StringKind) configschema.StringKind { + switch k { + default: + return configschema.StringPlain + case proto.StringKind_MARKDOWN: + return configschema.StringMarkdown + } +} + +func schemaNestedBlock(b *proto.Schema_NestedBlock) *configschema.NestedBlock { + var nesting configschema.NestingMode + switch b.Nesting { + case proto.Schema_NestedBlock_SINGLE: + nesting = configschema.NestingSingle + case proto.Schema_NestedBlock_GROUP: + nesting = configschema.NestingGroup + case proto.Schema_NestedBlock_LIST: + nesting = configschema.NestingList + case proto.Schema_NestedBlock_MAP: + nesting = configschema.NestingMap + case proto.Schema_NestedBlock_SET: + nesting = configschema.NestingSet + default: + // In all other cases we'll leave it as the zero value (invalid) and + // let the caller validate it and deal with this. + } + + nb := &configschema.NestedBlock{ + Nesting: nesting, + MinItems: int(b.MinItems), + MaxItems: int(b.MaxItems), + } + + nested := ProtoToConfigSchema(b.Block) + nb.Block = *nested + return nb +} + +func protoObjectToConfigSchema(b *proto.Schema_Object) *configschema.Object { + var nesting configschema.NestingMode + switch b.Nesting { + case proto.Schema_Object_SINGLE: + nesting = configschema.NestingSingle + case proto.Schema_Object_LIST: + nesting = configschema.NestingList + case proto.Schema_Object_MAP: + nesting = configschema.NestingMap + case proto.Schema_Object_SET: + nesting = configschema.NestingSet + default: + // In all other cases we'll leave it as the zero value (invalid) and + // let the caller validate it and deal with this. + } + + object := &configschema.Object{ + Attributes: make(map[string]*configschema.Attribute), + Nesting: nesting, + MinItems: int(b.MinItems), + MaxItems: int(b.MaxItems), + } + + for _, a := range b.Attributes { + attr := &configschema.Attribute{ + Description: a.Description, + DescriptionKind: schemaStringKind(a.DescriptionKind), + Required: a.Required, + Optional: a.Optional, + Computed: a.Computed, + Sensitive: a.Sensitive, + Deprecated: a.Deprecated, + } + + if a.Type != nil { + if err := json.Unmarshal(a.Type, &attr.Type); err != nil { + panic(err) + } + } + + if a.NestedType != nil { + attr.NestedType = protoObjectToConfigSchema(a.NestedType) + } + + object.Attributes[a.Name] = attr + } + + return object +} + +// sortedKeys returns the lexically sorted keys from the given map. This is +// used to make schema conversions are deterministic. This panics if map keys +// are not a string. +func sortedKeys(m interface{}) []string { + v := reflect.ValueOf(m) + keys := make([]string, v.Len()) + + mapKeys := v.MapKeys() + for i, k := range mapKeys { + keys[i] = k.Interface().(string) + } + + sort.Strings(keys) + return keys +} + +func configschemaObjectToProto(b *configschema.Object) *proto.Schema_Object { + var nesting proto.Schema_Object_NestingMode + switch b.Nesting { + case configschema.NestingSingle: + nesting = proto.Schema_Object_SINGLE + case configschema.NestingList: + nesting = proto.Schema_Object_LIST + case configschema.NestingSet: + nesting = proto.Schema_Object_SET + case configschema.NestingMap: + nesting = proto.Schema_Object_MAP + default: + nesting = proto.Schema_Object_INVALID + } + + attributes := make([]*proto.Schema_Attribute, len(b.Attributes)) + + for _, name := range sortedKeys(b.Attributes) { + a := b.Attributes[name] + + attr := &proto.Schema_Attribute{ + Name: name, + Description: a.Description, + DescriptionKind: protoStringKind(a.DescriptionKind), + Optional: a.Optional, + Computed: a.Computed, + Required: a.Required, + Sensitive: a.Sensitive, + Deprecated: a.Deprecated, + } + + if a.Type != cty.NilType { + ty, err := json.Marshal(a.Type) + if err != nil { + panic(err) + } + attr.Type = ty + } + + if a.NestedType != nil { + attr.NestedType = configschemaObjectToProto(a.NestedType) + } + + attributes = append(attributes, attr) + } + + return &proto.Schema_Object{ + Attributes: attributes, + Nesting: nesting, + MinItems: int64(b.MinItems), + MaxItems: int64(b.MaxItems), + } +} diff --git a/plugin6/convert/schema_test.go b/plugin6/convert/schema_test.go new file mode 100644 index 000000000000..1cb97273dd9b --- /dev/null +++ b/plugin6/convert/schema_test.go @@ -0,0 +1,568 @@ +package convert + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/hashicorp/terraform/configs/configschema" + proto "github.com/hashicorp/terraform/internal/tfplugin6" + "github.com/zclconf/go-cty/cty" +) + +var ( + equateEmpty = cmpopts.EquateEmpty() + typeComparer = cmp.Comparer(cty.Type.Equals) + valueComparer = cmp.Comparer(cty.Value.RawEquals) +) + +// Test that we can convert configschema to protobuf types and back again. +func TestConvertSchemaBlocks(t *testing.T) { + tests := map[string]struct { + Block *proto.Schema_Block + Want *configschema.Block + }{ + "attributes": { + &proto.Schema_Block{ + Attributes: []*proto.Schema_Attribute{ + { + Name: "computed", + Type: []byte(`["list","bool"]`), + Computed: true, + }, + { + Name: "optional", + Type: []byte(`"string"`), + Optional: true, + }, + { + Name: "optional_computed", + Type: []byte(`["map","bool"]`), + Optional: true, + Computed: true, + }, + { + Name: "required", + Type: []byte(`"number"`), + Required: true, + }, + { + Name: "nested_type", + NestedType: &proto.Schema_Object{ + Nesting: proto.Schema_Object_SINGLE, + Attributes: []*proto.Schema_Attribute{ + { + Name: "computed", + Type: []byte(`["list","bool"]`), + Computed: true, + }, + { + Name: "optional", + Type: []byte(`"string"`), + Optional: true, + }, + { + Name: "optional_computed", + Type: []byte(`["map","bool"]`), + Optional: true, + Computed: true, + }, + { + Name: "required", + Type: []byte(`"number"`), + Required: true, + }, + }, + }, + Required: true, + }, + { + Name: "deeply_nested_type", + NestedType: &proto.Schema_Object{ + Nesting: proto.Schema_Object_SINGLE, + Attributes: []*proto.Schema_Attribute{ + { + Name: "first_level", + NestedType: &proto.Schema_Object{ + Nesting: proto.Schema_Object_SINGLE, + Attributes: []*proto.Schema_Attribute{ + { + Name: "computed", + Type: []byte(`["list","bool"]`), + Computed: true, + }, + { + Name: "optional", + Type: []byte(`"string"`), + Optional: true, + }, + { + Name: "optional_computed", + Type: []byte(`["map","bool"]`), + Optional: true, + Computed: true, + }, + { + Name: "required", + Type: []byte(`"number"`), + Required: true, + }, + }, + }, + Computed: true, + }, + }, + }, + Required: true, + }, + { + Name: "nested_list", + NestedType: &proto.Schema_Object{ + Nesting: proto.Schema_Object_LIST, + Attributes: []*proto.Schema_Attribute{ + { + Name: "required", + Type: []byte(`"string"`), + Computed: true, + }, + }, + MinItems: 3, + }, + Required: true, + }, + { + Name: "nested_set", + NestedType: &proto.Schema_Object{ + Nesting: proto.Schema_Object_SET, + Attributes: []*proto.Schema_Attribute{ + { + Name: "required", + Type: []byte(`"string"`), + Computed: true, + }, + }, + }, + Required: true, + }, + { + Name: "nested_map", + NestedType: &proto.Schema_Object{ + Nesting: proto.Schema_Object_MAP, + Attributes: []*proto.Schema_Attribute{ + { + Name: "required", + Type: []byte(`"string"`), + Computed: true, + }, + }, + }, + Required: true, + }, + }, + }, + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "computed": { + Type: cty.List(cty.Bool), + Computed: true, + }, + "optional": { + Type: cty.String, + Optional: true, + }, + "optional_computed": { + Type: cty.Map(cty.Bool), + Optional: true, + Computed: true, + }, + "required": { + Type: cty.Number, + Required: true, + }, + "nested_type": { + NestedType: &configschema.Object{ + Attributes: map[string]*configschema.Attribute{ + "computed": { + Type: cty.List(cty.Bool), + Computed: true, + }, + "optional": { + Type: cty.String, + Optional: true, + }, + "optional_computed": { + Type: cty.Map(cty.Bool), + Optional: true, + Computed: true, + }, + "required": { + Type: cty.Number, + Required: true, + }, + }, + Nesting: configschema.NestingSingle, + }, + Required: true, + }, + "deeply_nested_type": { + NestedType: &configschema.Object{ + Attributes: map[string]*configschema.Attribute{ + "first_level": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: map[string]*configschema.Attribute{ + "computed": { + Type: cty.List(cty.Bool), + Computed: true, + }, + "optional": { + Type: cty.String, + Optional: true, + }, + "optional_computed": { + Type: cty.Map(cty.Bool), + Optional: true, + Computed: true, + }, + "required": { + Type: cty.Number, + Required: true, + }, + }, + }, + Computed: true, + }, + }, + Nesting: configschema.NestingSingle, + }, + Required: true, + }, + "nested_list": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "required": { + Type: cty.String, + Computed: true, + }, + }, + MinItems: 3, + }, + Required: true, + }, + "nested_map": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingMap, + Attributes: map[string]*configschema.Attribute{ + "required": { + Type: cty.String, + Computed: true, + }, + }, + }, + Required: true, + }, + "nested_set": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "required": { + Type: cty.String, + Computed: true, + }, + }, + }, + Required: true, + }, + }, + }, + }, + "blocks": { + &proto.Schema_Block{ + BlockTypes: []*proto.Schema_NestedBlock{ + { + TypeName: "list", + Nesting: proto.Schema_NestedBlock_LIST, + Block: &proto.Schema_Block{}, + }, + { + TypeName: "map", + Nesting: proto.Schema_NestedBlock_MAP, + Block: &proto.Schema_Block{}, + }, + { + TypeName: "set", + Nesting: proto.Schema_NestedBlock_SET, + Block: &proto.Schema_Block{}, + }, + { + TypeName: "single", + Nesting: proto.Schema_NestedBlock_SINGLE, + Block: &proto.Schema_Block{ + Attributes: []*proto.Schema_Attribute{ + { + Name: "foo", + Type: []byte(`"dynamic"`), + Required: true, + }, + }, + }, + }, + }, + }, + &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "list": &configschema.NestedBlock{ + Nesting: configschema.NestingList, + }, + "map": &configschema.NestedBlock{ + Nesting: configschema.NestingMap, + }, + "set": &configschema.NestedBlock{ + Nesting: configschema.NestingSet, + }, + "single": &configschema.NestedBlock{ + Nesting: configschema.NestingSingle, + Block: configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "foo": { + Type: cty.DynamicPseudoType, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "deep block nesting": { + &proto.Schema_Block{ + BlockTypes: []*proto.Schema_NestedBlock{ + { + TypeName: "single", + Nesting: proto.Schema_NestedBlock_SINGLE, + Block: &proto.Schema_Block{ + BlockTypes: []*proto.Schema_NestedBlock{ + { + TypeName: "list", + Nesting: proto.Schema_NestedBlock_LIST, + Block: &proto.Schema_Block{ + BlockTypes: []*proto.Schema_NestedBlock{ + { + TypeName: "set", + Nesting: proto.Schema_NestedBlock_SET, + Block: &proto.Schema_Block{}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "single": &configschema.NestedBlock{ + Nesting: configschema.NestingSingle, + Block: configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "list": &configschema.NestedBlock{ + Nesting: configschema.NestingList, + Block: configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "set": &configschema.NestedBlock{ + Nesting: configschema.NestingSet, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + converted := ProtoToConfigSchema(tc.Block) + if !cmp.Equal(converted, tc.Want, typeComparer, valueComparer, equateEmpty) { + t.Fatal(cmp.Diff(converted, tc.Want, typeComparer, valueComparer, equateEmpty)) + } + }) + } +} + +// Test that we can convert configschema to protobuf types and back again. +func TestConvertProtoSchemaBlocks(t *testing.T) { + tests := map[string]struct { + Want *proto.Schema_Block + Block *configschema.Block + }{ + "attributes": { + &proto.Schema_Block{ + Attributes: []*proto.Schema_Attribute{ + { + Name: "computed", + Type: []byte(`["list","bool"]`), + Computed: true, + }, + { + Name: "optional", + Type: []byte(`"string"`), + Optional: true, + }, + { + Name: "optional_computed", + Type: []byte(`["map","bool"]`), + Optional: true, + Computed: true, + }, + { + Name: "required", + Type: []byte(`"number"`), + Required: true, + }, + }, + }, + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "computed": { + Type: cty.List(cty.Bool), + Computed: true, + }, + "optional": { + Type: cty.String, + Optional: true, + }, + "optional_computed": { + Type: cty.Map(cty.Bool), + Optional: true, + Computed: true, + }, + "required": { + Type: cty.Number, + Required: true, + }, + }, + }, + }, + "blocks": { + &proto.Schema_Block{ + BlockTypes: []*proto.Schema_NestedBlock{ + { + TypeName: "list", + Nesting: proto.Schema_NestedBlock_LIST, + Block: &proto.Schema_Block{}, + }, + { + TypeName: "map", + Nesting: proto.Schema_NestedBlock_MAP, + Block: &proto.Schema_Block{}, + }, + { + TypeName: "set", + Nesting: proto.Schema_NestedBlock_SET, + Block: &proto.Schema_Block{}, + }, + { + TypeName: "single", + Nesting: proto.Schema_NestedBlock_SINGLE, + Block: &proto.Schema_Block{ + Attributes: []*proto.Schema_Attribute{ + { + Name: "foo", + Type: []byte(`"dynamic"`), + Required: true, + }, + }, + }, + }, + }, + }, + &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "list": &configschema.NestedBlock{ + Nesting: configschema.NestingList, + }, + "map": &configschema.NestedBlock{ + Nesting: configschema.NestingMap, + }, + "set": &configschema.NestedBlock{ + Nesting: configschema.NestingSet, + }, + "single": &configschema.NestedBlock{ + Nesting: configschema.NestingSingle, + Block: configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "foo": { + Type: cty.DynamicPseudoType, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "deep block nesting": { + &proto.Schema_Block{ + BlockTypes: []*proto.Schema_NestedBlock{ + { + TypeName: "single", + Nesting: proto.Schema_NestedBlock_SINGLE, + Block: &proto.Schema_Block{ + BlockTypes: []*proto.Schema_NestedBlock{ + { + TypeName: "list", + Nesting: proto.Schema_NestedBlock_LIST, + Block: &proto.Schema_Block{ + BlockTypes: []*proto.Schema_NestedBlock{ + { + TypeName: "set", + Nesting: proto.Schema_NestedBlock_SET, + Block: &proto.Schema_Block{}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "single": &configschema.NestedBlock{ + Nesting: configschema.NestingSingle, + Block: configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "list": &configschema.NestedBlock{ + Nesting: configschema.NestingList, + Block: configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "set": &configschema.NestedBlock{ + Nesting: configschema.NestingSet, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + converted := ConfigSchemaToProto(tc.Block) + if !cmp.Equal(converted, tc.Want, typeComparer, equateEmpty, ignoreUnexported) { + t.Fatal(cmp.Diff(converted, tc.Want, typeComparer, equateEmpty, ignoreUnexported)) + } + }) + } +} diff --git a/plugin6/doc.go b/plugin6/doc.go new file mode 100644 index 000000000000..5671893cc1a4 --- /dev/null +++ b/plugin6/doc.go @@ -0,0 +1,9 @@ +package plugin6 + +// plugin6 builds on types in package plugin to include support for plugin +// protocol v6. The main gRPC functions use by terraform (and initialized in +// init.go), such as Serve, are in the plugin package. The version of those +// functions in this package are used by various mocks and in tests. + +// When provider protocol v5 is deprecated, some functions may need to be moved +// here, or the existing functions updated, before removing the plugin pacakge. diff --git a/plugin6/grpc_error.go b/plugin6/grpc_error.go new file mode 100644 index 000000000000..4781d8216d04 --- /dev/null +++ b/plugin6/grpc_error.go @@ -0,0 +1,74 @@ +package plugin6 + +import ( + "fmt" + "path" + "runtime" + + "github.com/hashicorp/terraform/tfdiags" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// grpcErr extracts some known error types and formats them into better +// representations for core. This must only be called from plugin methods. +// Since we don't use RPC status errors for the plugin protocol, these do not +// contain any useful details, and we can return some text that at least +// indicates the plugin call and possible error condition. +func grpcErr(err error) (diags tfdiags.Diagnostics) { + if err == nil { + return + } + + // extract the method name from the caller. + pc, _, _, ok := runtime.Caller(1) + if !ok { + logger.Error("unknown grpc call", "error", err) + return diags.Append(err) + } + + f := runtime.FuncForPC(pc) + + // Function names will contain the full import path. Take the last + // segment, which will let users know which method was being called. + _, requestName := path.Split(f.Name()) + + // Here we can at least correlate the error in the logs to a particular binary. + logger.Error(requestName, "error", err) + + // TODO: while this expands the error codes into somewhat better messages, + // this still does not easily link the error to an actual user-recognizable + // plugin. The grpc plugin does not know its configured name, and the + // errors are in a list of diagnostics, making it hard for the caller to + // annotate the returned errors. + switch status.Code(err) { + case codes.Unavailable: + // This case is when the plugin has stopped running for some reason, + // and is usually the result of a crash. + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Plugin did not respond", + fmt.Sprintf("The plugin encountered an error, and failed to respond to the %s call. "+ + "The plugin logs may contain more details.", requestName), + )) + case codes.Canceled: + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Request cancelled", + fmt.Sprintf("The %s request was cancelled.", requestName), + )) + case codes.Unimplemented: + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Unsupported plugin method", + fmt.Sprintf("The %s method is not supported by this plugin.", requestName), + )) + default: + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Plugin error", + fmt.Sprintf("The plugin returned an unexpected error from %s: %v", requestName, err), + )) + } + return +} diff --git a/plugin6/grpc_provider.go b/plugin6/grpc_provider.go new file mode 100644 index 000000000000..8a359877ae9d --- /dev/null +++ b/plugin6/grpc_provider.go @@ -0,0 +1,617 @@ +package plugin6 + +import ( + "context" + "errors" + "sync" + + "github.com/zclconf/go-cty/cty" + + plugin "github.com/hashicorp/go-plugin" + "github.com/hashicorp/terraform/internal/logging" + proto6 "github.com/hashicorp/terraform/internal/tfplugin6" + "github.com/hashicorp/terraform/plugin6/convert" + "github.com/hashicorp/terraform/providers" + ctyjson "github.com/zclconf/go-cty/cty/json" + "github.com/zclconf/go-cty/cty/msgpack" + "google.golang.org/grpc" +) + +var logger = logging.HCLogger() + +// GRPCProviderPlugin implements plugin.GRPCPlugin for the go-plugin package. +type GRPCProviderPlugin struct { + plugin.Plugin + GRPCProvider func() proto6.ProviderServer +} + +func (p *GRPCProviderPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) { + return &GRPCProvider{ + client: proto6.NewProviderClient(c), + ctx: ctx, + }, nil +} + +func (p *GRPCProviderPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error { + proto6.RegisterProviderServer(s, p.GRPCProvider()) + return nil +} + +// GRPCProvider handles the client, or core side of the plugin rpc connection. +// The GRPCProvider methods are mostly a translation layer between the +// terraform provioders types and the grpc proto types, directly converting +// between the two. +type GRPCProvider struct { + // PluginClient provides a reference to the plugin.Client which controls the plugin process. + // This allows the GRPCProvider a way to shutdown the plugin process. + PluginClient *plugin.Client + + // TestServer contains a grpc.Server to close when the GRPCProvider is being + // used in an end to end test of a provider. + TestServer *grpc.Server + + // Proto client use to make the grpc service calls. + client proto6.ProviderClient + + // this context is created by the plugin package, and is canceled when the + // plugin process ends. + ctx context.Context + + // schema stores the schema for this provider. This is used to properly + // serialize the state for requests. + mu sync.Mutex + schemas providers.GetSchemaResponse +} + +func New(client proto6.ProviderClient, ctx context.Context) GRPCProvider { + return GRPCProvider{ + client: client, + ctx: ctx, + } +} + +// getSchema is used internally to get the saved provider schema. The schema +// should have already been fetched from the provider, but we have to +// synchronize access to avoid being called concurrently with GetSchema. +func (p *GRPCProvider) getSchema() providers.GetSchemaResponse { + p.mu.Lock() + // unlock inline in case GetSchema needs to be called + if p.schemas.Provider.Block != nil { + p.mu.Unlock() + return p.schemas + } + p.mu.Unlock() + + // the schema should have been fetched already, but give it another shot + // just in case things are being called out of order. This may happen for + // tests. + schemas := p.GetSchema() + if schemas.Diagnostics.HasErrors() { + panic(schemas.Diagnostics.Err()) + } + + return schemas +} + +// getResourceSchema is a helper to extract the schema for a resource, and +// panics if the schema is not available. +func (p *GRPCProvider) getResourceSchema(name string) providers.Schema { + schema := p.getSchema() + resSchema, ok := schema.ResourceTypes[name] + if !ok { + panic("unknown resource type " + name) + } + return resSchema +} + +// gettDatasourceSchema is a helper to extract the schema for a datasource, and +// panics if that schema is not available. +func (p *GRPCProvider) getDatasourceSchema(name string) providers.Schema { + schema := p.getSchema() + dataSchema, ok := schema.DataSources[name] + if !ok { + panic("unknown data source " + name) + } + return dataSchema +} + +// getProviderMetaSchema is a helper to extract the schema for the meta info +// defined for a provider, +func (p *GRPCProvider) getProviderMetaSchema() providers.Schema { + schema := p.getSchema() + return schema.ProviderMeta +} + +func (p *GRPCProvider) GetSchema() (resp providers.GetSchemaResponse) { + logger.Trace("GRPCProvider.v6: GetSchema") + p.mu.Lock() + defer p.mu.Unlock() + + if p.schemas.Provider.Block != nil { + return p.schemas + } + + resp.ResourceTypes = make(map[string]providers.Schema) + resp.DataSources = make(map[string]providers.Schema) + + // Some providers may generate quite large schemas, and the internal default + // grpc response size limit is 4MB. 64MB should cover most any use case, and + // if we get providers nearing that we may want to consider a finer-grained + // API to fetch individual resource schemas. + // Note: this option is marked as EXPERIMENTAL in the grpc API. + const maxRecvSize = 64 << 20 + protoResp, err := p.client.GetProviderSchema(p.ctx, new(proto6.GetProviderSchema_Request), grpc.MaxRecvMsgSizeCallOption{MaxRecvMsgSize: maxRecvSize}) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + + if protoResp.Provider == nil { + resp.Diagnostics = resp.Diagnostics.Append(errors.New("missing provider schema")) + return resp + } + + resp.Provider = convert.ProtoToProviderSchema(protoResp.Provider) + if protoResp.ProviderMeta == nil { + logger.Debug("No provider meta schema returned") + } else { + resp.ProviderMeta = convert.ProtoToProviderSchema(protoResp.ProviderMeta) + } + + for name, res := range protoResp.ResourceSchemas { + resp.ResourceTypes[name] = convert.ProtoToProviderSchema(res) + } + + for name, data := range protoResp.DataSourceSchemas { + resp.DataSources[name] = convert.ProtoToProviderSchema(data) + } + + p.schemas = resp + + return resp +} + +func (p *GRPCProvider) ValidateProviderConfig(r providers.PrepareProviderConfigRequest) (resp providers.PrepareProviderConfigResponse) { + logger.Trace("GRPCProvider.v6: ValidateProviderConfig") + + schema := p.getSchema() + ty := schema.Provider.Block.ImpliedType() + + mp, err := msgpack.Marshal(r.Config, ty) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + protoReq := &proto6.ValidateProviderConfig_Request{ + Config: &proto6.DynamicValue{Msgpack: mp}, + } + + protoResp, err := p.client.ValidateProviderConfig(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + return resp +} + +func (p *GRPCProvider) ValidateResourceTypeConfig(r providers.ValidateResourceTypeConfigRequest) (resp providers.ValidateResourceTypeConfigResponse) { + logger.Trace("GRPCProvider.v6: ValidateResourceTypeConfig") + resourceSchema := p.getResourceSchema(r.TypeName) + + mp, err := msgpack.Marshal(r.Config, resourceSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + protoReq := &proto6.ValidateResourceConfig_Request{ + TypeName: r.TypeName, + Config: &proto6.DynamicValue{Msgpack: mp}, + } + + protoResp, err := p.client.ValidateResourceConfig(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + return resp +} + +func (p *GRPCProvider) ValidateDataSourceConfig(r providers.ValidateDataSourceConfigRequest) (resp providers.ValidateDataSourceConfigResponse) { + logger.Trace("GRPCProvider.v6: ValidateDataSourceConfig") + + dataSchema := p.getDatasourceSchema(r.TypeName) + + mp, err := msgpack.Marshal(r.Config, dataSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + protoReq := &proto6.ValidateDataSourceConfig_Request{ + TypeName: r.TypeName, + Config: &proto6.DynamicValue{Msgpack: mp}, + } + + protoResp, err := p.client.ValidateDataSourceConfig(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + return resp +} + +func (p *GRPCProvider) UpgradeResourceState(r providers.UpgradeResourceStateRequest) (resp providers.UpgradeResourceStateResponse) { + logger.Trace("GRPCProvider.v6: UpgradeResourceState") + + resSchema := p.getResourceSchema(r.TypeName) + + protoReq := &proto6.UpgradeResourceState_Request{ + TypeName: r.TypeName, + Version: int64(r.Version), + RawState: &proto6.RawState{ + Json: r.RawStateJSON, + Flatmap: r.RawStateFlatmap, + }, + } + + protoResp, err := p.client.UpgradeResourceState(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + + ty := resSchema.Block.ImpliedType() + resp.UpgradedState = cty.NullVal(ty) + if protoResp.UpgradedState == nil { + return resp + } + + state, err := decodeDynamicValue(protoResp.UpgradedState, ty) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + resp.UpgradedState = state + + return resp +} + +func (p *GRPCProvider) Configure(r providers.ConfigureRequest) (resp providers.ConfigureResponse) { + logger.Trace("GRPCProvider.v6: Configure") + + schema := p.getSchema() + + var mp []byte + + // we don't have anything to marshal if there's no config + mp, err := msgpack.Marshal(r.Config, schema.Provider.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + protoReq := &proto6.ConfigureProvider_Request{ + TerraformVersion: r.TerraformVersion, + Config: &proto6.DynamicValue{ + Msgpack: mp, + }, + } + + protoResp, err := p.client.ConfigureProvider(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + return resp +} + +func (p *GRPCProvider) Stop() error { + logger.Trace("GRPCProvider.v6: Stop") + + resp, err := p.client.StopProvider(p.ctx, new(proto6.StopProvider_Request)) + if err != nil { + return err + } + + if resp.Error != "" { + return errors.New(resp.Error) + } + return nil +} + +func (p *GRPCProvider) ReadResource(r providers.ReadResourceRequest) (resp providers.ReadResourceResponse) { + logger.Trace("GRPCProvider.v6: ReadResource") + + resSchema := p.getResourceSchema(r.TypeName) + metaSchema := p.getProviderMetaSchema() + + mp, err := msgpack.Marshal(r.PriorState, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + protoReq := &proto6.ReadResource_Request{ + TypeName: r.TypeName, + CurrentState: &proto6.DynamicValue{Msgpack: mp}, + Private: r.Private, + } + + if metaSchema.Block != nil { + metaMP, err := msgpack.Marshal(r.ProviderMeta, metaSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + protoReq.ProviderMeta = &proto6.DynamicValue{Msgpack: metaMP} + } + + protoResp, err := p.client.ReadResource(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + + state, err := decodeDynamicValue(protoResp.NewState, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + resp.NewState = state + resp.Private = protoResp.Private + + return resp +} + +func (p *GRPCProvider) PlanResourceChange(r providers.PlanResourceChangeRequest) (resp providers.PlanResourceChangeResponse) { + logger.Trace("GRPCProvider.v6: PlanResourceChange") + + resSchema := p.getResourceSchema(r.TypeName) + metaSchema := p.getProviderMetaSchema() + + priorMP, err := msgpack.Marshal(r.PriorState, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + configMP, err := msgpack.Marshal(r.Config, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + propMP, err := msgpack.Marshal(r.ProposedNewState, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + protoReq := &proto6.PlanResourceChange_Request{ + TypeName: r.TypeName, + PriorState: &proto6.DynamicValue{Msgpack: priorMP}, + Config: &proto6.DynamicValue{Msgpack: configMP}, + ProposedNewState: &proto6.DynamicValue{Msgpack: propMP}, + PriorPrivate: r.PriorPrivate, + } + + if metaSchema.Block != nil { + metaMP, err := msgpack.Marshal(r.ProviderMeta, metaSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + protoReq.ProviderMeta = &proto6.DynamicValue{Msgpack: metaMP} + } + + protoResp, err := p.client.PlanResourceChange(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + + state, err := decodeDynamicValue(protoResp.PlannedState, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + resp.PlannedState = state + + for _, p := range protoResp.RequiresReplace { + resp.RequiresReplace = append(resp.RequiresReplace, convert.AttributePathToPath(p)) + } + + resp.PlannedPrivate = protoResp.PlannedPrivate + + return resp +} + +func (p *GRPCProvider) ApplyResourceChange(r providers.ApplyResourceChangeRequest) (resp providers.ApplyResourceChangeResponse) { + logger.Trace("GRPCProvider.v6: ApplyResourceChange") + + resSchema := p.getResourceSchema(r.TypeName) + metaSchema := p.getProviderMetaSchema() + + priorMP, err := msgpack.Marshal(r.PriorState, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + plannedMP, err := msgpack.Marshal(r.PlannedState, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + configMP, err := msgpack.Marshal(r.Config, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + protoReq := &proto6.ApplyResourceChange_Request{ + TypeName: r.TypeName, + PriorState: &proto6.DynamicValue{Msgpack: priorMP}, + PlannedState: &proto6.DynamicValue{Msgpack: plannedMP}, + Config: &proto6.DynamicValue{Msgpack: configMP}, + PlannedPrivate: r.PlannedPrivate, + } + + if metaSchema.Block != nil { + metaMP, err := msgpack.Marshal(r.ProviderMeta, metaSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + protoReq.ProviderMeta = &proto6.DynamicValue{Msgpack: metaMP} + } + + protoResp, err := p.client.ApplyResourceChange(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + + resp.Private = protoResp.Private + + state, err := decodeDynamicValue(protoResp.NewState, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + resp.NewState = state + + return resp +} + +func (p *GRPCProvider) ImportResourceState(r providers.ImportResourceStateRequest) (resp providers.ImportResourceStateResponse) { + logger.Trace("GRPCProvider.v6: ImportResourceState") + + protoReq := &proto6.ImportResourceState_Request{ + TypeName: r.TypeName, + Id: r.ID, + } + + protoResp, err := p.client.ImportResourceState(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + + for _, imported := range protoResp.ImportedResources { + resource := providers.ImportedResource{ + TypeName: imported.TypeName, + Private: imported.Private, + } + + resSchema := p.getResourceSchema(resource.TypeName) + state, err := decodeDynamicValue(imported.State, resSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + resource.State = state + resp.ImportedResources = append(resp.ImportedResources, resource) + } + + return resp +} + +func (p *GRPCProvider) ReadDataSource(r providers.ReadDataSourceRequest) (resp providers.ReadDataSourceResponse) { + logger.Trace("GRPCProvider.v6: ReadDataSource") + + dataSchema := p.getDatasourceSchema(r.TypeName) + metaSchema := p.getProviderMetaSchema() + + config, err := msgpack.Marshal(r.Config, dataSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + + protoReq := &proto6.ReadDataSource_Request{ + TypeName: r.TypeName, + Config: &proto6.DynamicValue{ + Msgpack: config, + }, + } + + if metaSchema.Block != nil { + metaMP, err := msgpack.Marshal(r.ProviderMeta, metaSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + protoReq.ProviderMeta = &proto6.DynamicValue{Msgpack: metaMP} + } + + protoResp, err := p.client.ReadDataSource(p.ctx, protoReq) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err)) + return resp + } + resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics)) + + state, err := decodeDynamicValue(protoResp.State, dataSchema.Block.ImpliedType()) + if err != nil { + resp.Diagnostics = resp.Diagnostics.Append(err) + return resp + } + resp.State = state + + return resp +} + +// closing the grpc connection is final, and terraform will call it at the end of every phase. +func (p *GRPCProvider) Close() error { + logger.Trace("GRPCProvider.v6: Close") + + // Make sure to stop the server if we're not running within go-plugin. + if p.TestServer != nil { + p.TestServer.Stop() + } + + // Check this since it's not automatically inserted during plugin creation. + // It's currently only inserted by the command package, because that is + // where the factory is built and is the only point with access to the + // plugin.Client. + if p.PluginClient == nil { + logger.Debug("provider has no plugin.Client") + return nil + } + + p.PluginClient.Kill() + return nil +} + +// Decode a DynamicValue from either the JSON or MsgPack encoding. +func decodeDynamicValue(v *proto6.DynamicValue, ty cty.Type) (cty.Value, error) { + // always return a valid value + var err error + res := cty.NullVal(ty) + if v == nil { + return res, nil + } + + switch { + case len(v.Msgpack) > 0: + res, err = msgpack.Unmarshal(v.Msgpack, ty) + case len(v.Json) > 0: + res, err = ctyjson.Unmarshal(v.Json, ty) + } + return res, err +} diff --git a/plugin6/serve.go b/plugin6/serve.go new file mode 100644 index 000000000000..7c201a7fa10b --- /dev/null +++ b/plugin6/serve.go @@ -0,0 +1,68 @@ +package plugin6 + +import ( + "github.com/hashicorp/go-plugin" + proto "github.com/hashicorp/terraform/internal/tfplugin6" +) + +const ( + // The constants below are the names of the plugins that can be dispensed + // from the plugin server. + ProviderPluginName = "provider" + ProvisionerPluginName = "provisioner" + + // DefaultProtocolVersion is the protocol version assumed for legacy clients that don't specify + // a particular version during their handshake. This is the version used when Terraform 0.10 + // and 0.11 launch plugins that were built with support for both versions 4 and 5, and must + // stay unchanged at 4 until we intentionally build plugins that are not compatible with 0.10 and + // 0.11. + DefaultProtocolVersion = 4 +) + +// Handshake is the HandshakeConfig used to configure clients and servers. +var Handshake = plugin.HandshakeConfig{ + // The ProtocolVersion is the version that must match between TF core + // and TF plugins. This should be bumped whenever a change happens in + // one or the other that makes it so that they can't safely communicate. + // This could be adding a new interface value, it could be how + // helper/schema computes diffs, etc. + ProtocolVersion: DefaultProtocolVersion, + + // The magic cookie values should NEVER be changed. + MagicCookieKey: "TF_PLUGIN_MAGIC_COOKIE", + MagicCookieValue: "d602bf8f470bc67ca7faa0386276bbdd4330efaf76d1a219cb4d6991ca9872b2", +} + +type GRPCProviderFunc func() proto.ProviderServer + +// ServeOpts are the configurations to serve a plugin. +type ServeOpts struct { + // Wrapped versions of the above plugins will automatically shimmed and + // added to the GRPC functions when possible. + GRPCProviderFunc GRPCProviderFunc +} + +// Serve serves a plugin. This function never returns and should be the final +// function called in the main function of the plugin. +func Serve(opts *ServeOpts) { + plugin.Serve(&plugin.ServeConfig{ + HandshakeConfig: Handshake, + VersionedPlugins: pluginSet(opts), + GRPCServer: plugin.DefaultGRPCServer, + }) +} + +func pluginSet(opts *ServeOpts) map[int]plugin.PluginSet { + plugins := map[int]plugin.PluginSet{} + + // add the new protocol versions if they're configured + if opts.GRPCProviderFunc != nil { + plugins[5] = plugin.PluginSet{} + if opts.GRPCProviderFunc != nil { + plugins[6]["provider"] = &GRPCProviderPlugin{ + GRPCProvider: opts.GRPCProviderFunc, + } + } + } + return plugins +} From 77af60154347ac3c5b7e3b5d9cc1ac0466993c8e Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Wed, 10 Feb 2021 08:31:21 -0500 Subject: [PATCH 5/8] plans/objchange: extended ProposedNewObject to descend into attributes with NestedType objects. There are a handful of mostly cosmetic changes in this PR which likely make the diff awkward to read; I renamed several functions to (hopefully) clarifiy which funcs worked with Blocks vs other types. I also extracted some small code snippets into their own functions for reusability. The code that descends into attributes with NestedTypes is similar to the block-handling code, and differs in all the ways blocks and attributes differ: null is valid for attributes, unlike blocks which can only be present or empty. --- plans/objchange/all_null.go | 19 +- plans/objchange/objchange.go | 283 ++++++++++++++++++++++++++---- plans/objchange/objchange_test.go | 183 ++++++++++++++++++- 3 files changed, 449 insertions(+), 36 deletions(-) diff --git a/plans/objchange/all_null.go b/plans/objchange/all_null.go index 18a7e99a37f8..93bbfdf5dd02 100644 --- a/plans/objchange/all_null.go +++ b/plans/objchange/all_null.go @@ -5,14 +5,29 @@ import ( "github.com/zclconf/go-cty/cty" ) -// AllAttributesNull constructs a non-null cty.Value of the object type implied +// AllBlockAttributesNull constructs a non-null cty.Value of the object type implied // by the given schema that has all of its leaf attributes set to null and all // of its nested block collections set to zero-length. // // This simulates what would result from decoding an empty configuration block // with the given schema, except that it does not produce errors -func AllAttributesNull(schema *configschema.Block) cty.Value { +func AllBlockAttributesNull(schema *configschema.Block) cty.Value { // "All attributes null" happens to be the definition of EmptyValue for // a Block, so we can just delegate to that. return schema.EmptyValue() } + +// AllAttributesNull returns a cty.Value of the object type implied by the given +// attriubutes that has all of its leaf attributes set to null. +func AllAttributesNull(attrs map[string]*configschema.Attribute) cty.Value { + newAttrs := make(map[string]cty.Value, len(attrs)) + + for name, attr := range attrs { + if attr.NestedType != nil { + newAttrs[name] = AllAttributesNull(attr.NestedType.Attributes) + } else { + newAttrs[name] = cty.NullVal(attr.Type) + } + } + return cty.ObjectVal(newAttrs) +} diff --git a/plans/objchange/objchange.go b/plans/objchange/objchange.go index cf08dda64e83..2873adbb709c 100644 --- a/plans/objchange/objchange.go +++ b/plans/objchange/objchange.go @@ -37,7 +37,7 @@ func ProposedNew(schema *configschema.Block, prior, config cty.Value) cty.Value // similar to the result of decoding an empty configuration block, // which simplifies our handling of the top-level attributes/blocks // below by giving us one non-null level of object to pull values from. - prior = AllAttributesNull(schema) + prior = AllBlockAttributesNull(schema) } return proposedNew(schema, prior, config) } @@ -77,38 +77,7 @@ func proposedNew(schema *configschema.Block, prior, config cty.Value) cty.Value // From this point onwards, we can assume that both values are non-null // object types, and that the config value itself is known (though it // may contain nested values that are unknown.) - newAttrs := map[string]cty.Value{} - for name, attr := range schema.Attributes { - priorV := prior.GetAttr(name) - configV := config.GetAttr(name) - var newV cty.Value - switch { - case attr.Computed && attr.Optional: - // This is the trickiest scenario: we want to keep the prior value - // if the config isn't overriding it. Note that due to some - // ambiguity here, setting an optional+computed attribute from - // config and then later switching the config to null in a - // subsequent change causes the initial config value to be "sticky" - // unless the provider specifically overrides it during its own - // plan customization step. - if configV.IsNull() { - newV = priorV - } else { - newV = configV - } - case attr.Computed: - // configV will always be null in this case, by definition. - // priorV may also be null, but that's okay. - newV = priorV - default: - // For non-computed attributes, we always take the config value, - // even if it is null. If it's _required_ then null values - // should've been caught during an earlier validation step, and - // so we don't really care about that here. - newV = configV - } - newAttrs[name] = newV - } + newAttrs := proposedNewAttributes(schema.Attributes, prior, config) // Merging nested blocks is a little more complex, since we need to // correlate blocks between both objects and then recursively propose @@ -282,6 +251,206 @@ func proposedNewNestedBlock(schema *configschema.NestedBlock, prior, config cty. return newV } +func proposedNewAttributes(attrs map[string]*configschema.Attribute, prior, config cty.Value) map[string]cty.Value { + if prior.IsNull() { + prior = AllAttributesNull(attrs) + } + newAttrs := make(map[string]cty.Value, len(attrs)) + for name, attr := range attrs { + priorV := prior.GetAttr(name) + configV := config.GetAttr(name) + var newV cty.Value + switch { + case attr.Computed && attr.Optional: + // This is the trickiest scenario: we want to keep the prior value + // if the config isn't overriding it. Note that due to some + // ambiguity here, setting an optional+computed attribute from + // config and then later switching the config to null in a + // subsequent change causes the initial config value to be "sticky" + // unless the provider specifically overrides it during its own + // plan customization step. + if configV.IsNull() { + newV = priorV + } else { + newV = configV + } + case attr.Computed: + // configV will always be null in this case, by definition. + // priorV may also be null, but that's okay. + newV = priorV + default: + if attr.NestedType != nil { + // For non-computed NestedType attributes, we need to descend + // into the individual nested attributes to build the final + // value, unless the entire nested attribute is unknown. + if !configV.IsKnown() { + newV = configV + } else { + newV = proposedNewNestedType(attr.NestedType, priorV, configV) + } + } else { + // For non-computed attributes, we always take the config value, + // even if it is null. If it's _required_ then null values + // should've been caught during an earlier validation step, and + // so we don't really care about that here. + newV = configV + } + } + newAttrs[name] = newV + } + return newAttrs +} + +func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) cty.Value { + var newV cty.Value + switch schema.Nesting { + case configschema.NestingSingle: + newAttrs := proposedNewAttributes(schema.Attributes, prior, config) + newV = cty.ObjectVal(newAttrs) + + case configschema.NestingList: + // Nested blocks are correlated by index. + configVLen := 0 + if config.IsKnown() && !config.IsNull() { + configVLen = config.LengthInt() + } + if configVLen > 0 { + newVals := make([]cty.Value, 0, configVLen) + for it := config.ElementIterator(); it.Next(); { + idx, configEV := it.Element() + if prior.IsKnown() && (prior.IsNull() || !prior.HasIndex(idx).True()) { + // If there is no corresponding prior element then + // we just take the config value as-is. + newVals = append(newVals, configEV) + continue + } + priorEV := prior.Index(idx) + + newEV := proposedNewAttributes(schema.Attributes, priorEV, configEV) + newVals = append(newVals, cty.ObjectVal(newEV)) + } + // Despite the name, a NestingList might also be a tuple, if + // its nested schema contains dynamically-typed attributes. + if config.Type().IsTupleType() { + newV = cty.TupleVal(newVals) + } else { + newV = cty.ListVal(newVals) + } + } else { + // Despite the name, a NestingList might also be a tuple, if + // its nested schema contains dynamically-typed attributes. + if config.Type().IsTupleType() { + newV = cty.EmptyTupleVal + } else { + newV = cty.ListValEmpty(schema.ImpliedType()) + } + } + + case configschema.NestingMap: + // Despite the name, a NestingMap may produce either a map or + // object value, depending on whether the nested schema contains + // dynamically-typed attributes. + if config.Type().IsObjectType() { + // Nested blocks are correlated by key. + configVLen := 0 + if config.IsKnown() && !config.IsNull() { + configVLen = config.LengthInt() + } + if configVLen > 0 { + newVals := make(map[string]cty.Value, configVLen) + atys := config.Type().AttributeTypes() + for name := range atys { + configEV := config.GetAttr(name) + if !prior.IsKnown() || prior.IsNull() || !prior.Type().HasAttribute(name) { + // If there is no corresponding prior element then + // we just take the config value as-is. + newVals[name] = configEV + continue + } + priorEV := prior.GetAttr(name) + newEV := proposedNewAttributes(schema.Attributes, priorEV, configEV) + newVals[name] = cty.ObjectVal(newEV) + } + // Although we call the nesting mode "map", we actually use + // object values so that elements might have different types + // in case of dynamically-typed attributes. + newV = cty.ObjectVal(newVals) + } else { + newV = cty.EmptyObjectVal + } + } else { + configVLen := 0 + if config.IsKnown() && !config.IsNull() { + configVLen = config.LengthInt() + } + if configVLen > 0 { + newVals := make(map[string]cty.Value, configVLen) + for it := config.ElementIterator(); it.Next(); { + idx, configEV := it.Element() + k := idx.AsString() + if prior.IsKnown() && (prior.IsNull() || !prior.HasIndex(idx).True()) { + // If there is no corresponding prior element then + // we just take the config value as-is. + newVals[k] = configEV + continue + } + priorEV := prior.Index(idx) + + newEV := proposedNewAttributes(schema.Attributes, priorEV, configEV) + newVals[k] = cty.ObjectVal(newEV) + } + newV = cty.MapVal(newVals) + } else { + newV = cty.MapValEmpty(schema.ImpliedType()) + } + } + + case configschema.NestingSet: + // Nested blocks are correlated by comparing the element values + // after eliminating all of the computed attributes. In practice, + // this means that any config change produces an entirely new + // nested object, and we only propagate prior computed values + // if the non-computed attribute values are identical. + var cmpVals [][2]cty.Value + if prior.IsKnown() && !prior.IsNull() { + cmpVals = setElementCompareValuesFromObject(schema, prior) + } + configVLen := 0 + if config.IsKnown() && !config.IsNull() { + configVLen = config.LengthInt() + } + if configVLen > 0 { + used := make([]bool, len(cmpVals)) // track used elements in case multiple have the same compare value + newVals := make([]cty.Value, 0, configVLen) + for it := config.ElementIterator(); it.Next(); { + _, configEV := it.Element() + var priorEV cty.Value + for i, cmp := range cmpVals { + if used[i] { + continue + } + if cmp[1].RawEquals(configEV) { + priorEV = cmp[0] + used[i] = true // we can't use this value on a future iteration + break + } + } + if priorEV == cty.NilVal { + newVals = append(newVals, configEV) + } else { + newEV := proposedNewAttributes(schema.Attributes, priorEV, configEV) + newVals = append(newVals, cty.ObjectVal(newEV)) + } + } + newV = cty.SetVal(newVals) + } else { + newV = cty.SetValEmpty(schema.ImpliedType()) + } + } + + return newV +} + // setElementCompareValues takes a known, non-null value of a cty.Set type and // returns a table -- constructed of two-element arrays -- that maps original // set element values to corresponding values that have all of the computed @@ -410,3 +579,51 @@ func setElementCompareValue(schema *configschema.Block, v cty.Value, isConfig bo return cty.ObjectVal(attrs) } + +// setElementCompareValues takes a known, non-null value of a cty.Set type and +// returns a table -- constructed of two-element arrays -- that maps original +// set element values to corresponding values that have all of the computed +// values removed, making them suitable for comparison with values obtained +// from configuration. The element type of the set must conform to the implied +// type of the given schema, or this function will panic. +// +// In the resulting slice, the zeroth element of each array is the original +// value and the one-indexed element is the corresponding "compare value". +// +// This is intended to help correlate prior elements with configured elements +// in proposedNewBlock. The result is a heuristic rather than an exact science, +// since e.g. two separate elements may reduce to the same value through this +// process. The caller must therefore be ready to deal with duplicates. +func setElementCompareValuesFromObject(schema *configschema.Object, set cty.Value) [][2]cty.Value { + ret := make([][2]cty.Value, 0, set.LengthInt()) + for it := set.ElementIterator(); it.Next(); { + _, ev := it.Element() + ret = append(ret, [2]cty.Value{ev, setElementCompareValueFromObject(schema, ev)}) + } + return ret +} + +// setElementCompareValue creates a new value that has all of the same +// non-computed attribute values as the one given but has all computed +// attribute values forced to null. +// +// The input value must conform to the schema's implied type, and the return +// value is guaranteed to conform to it. +func setElementCompareValueFromObject(schema *configschema.Object, v cty.Value) cty.Value { + if v.IsNull() || !v.IsKnown() { + return v + } + attrs := map[string]cty.Value{} + + for name, attr := range schema.Attributes { + attrV := v.GetAttr(name) + switch { + case attr.Computed: + attrs[name] = cty.NullVal(attr.Type) + default: + attrs[name] = attrV + } + } + + return cty.ObjectVal(attrs) +} diff --git a/plans/objchange/objchange_test.go b/plans/objchange/objchange_test.go index 9a523609d39c..181a42ea9a15 100644 --- a/plans/objchange/objchange_test.go +++ b/plans/objchange/objchange_test.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform/configs/configschema" ) -func TestProposedNewObject(t *testing.T) { +func TestProposedNew(t *testing.T) { tests := map[string]struct { Schema *configschema.Block Prior cty.Value @@ -1198,6 +1198,167 @@ func TestProposedNewObject(t *testing.T) { }), }), }, + // This example has a mixture of optional, computed and required in a deeply-nested NestedType attribute + "deeply NestedType": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "foo": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: map[string]*configschema.Attribute{ + "bar": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: testAttributes, + }, + Required: true, + }, + "baz": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: testAttributes, + }, + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + // prior + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.ObjectVal(map[string]cty.Value{ + "bar": cty.NullVal(cty.DynamicPseudoType), + "baz": cty.ObjectVal(map[string]cty.Value{ + "optional": cty.NullVal(cty.String), + "computed": cty.StringVal("hello"), + "optional_computed": cty.StringVal("prior"), + "required": cty.StringVal("present"), + }), + }), + }), + // config + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.ObjectVal(map[string]cty.Value{ + "bar": cty.UnknownVal(cty.Object(map[string]cty.Type{ // explicit unknown from the config + "optional": cty.String, + "computed": cty.String, + "optional_computed": cty.String, + "required": cty.String, + })), + "baz": cty.ObjectVal(map[string]cty.Value{ + "optional": cty.NullVal(cty.String), + "computed": cty.NullVal(cty.String), + "optional_computed": cty.StringVal("hello"), + "required": cty.StringVal("present"), + }), + }), + }), + // want + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.ObjectVal(map[string]cty.Value{ + "bar": cty.UnknownVal(cty.Object(map[string]cty.Type{ // explicit unknown preserved from the config + "optional": cty.String, + "computed": cty.String, + "optional_computed": cty.String, + "required": cty.String, + })), + "baz": cty.ObjectVal(map[string]cty.Value{ + "optional": cty.NullVal(cty.String), // config is null + "computed": cty.StringVal("hello"), // computed values come from prior + "optional_computed": cty.StringVal("hello"), // config takes precedent over prior in opt+computed + "required": cty.StringVal("present"), // value from config + }), + }), + }), + }, + "deeply nested set": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "foo": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "bar": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: testAttributes, + }, + Required: true, + }, + }, + }, + Optional: true, + }, + }, + }, + // prior values + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bar": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "optional": cty.StringVal("prior"), + "computed": cty.StringVal("prior"), + "optional_computed": cty.StringVal("prior"), + "required": cty.StringVal("prior"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "bar": cty.SetVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{ + "optional": cty.StringVal("other_prior"), + "computed": cty.StringVal("other_prior"), + "optional_computed": cty.StringVal("other_prior"), + "required": cty.StringVal("other_prior"), + })}), + }), + }), + }), + // config differs from prior + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bar": cty.SetVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{ + "optional": cty.StringVal("configured"), + "computed": cty.NullVal(cty.String), // computed attrs are null in config + "optional_computed": cty.StringVal("configured"), + "required": cty.StringVal("configured"), + })}), + }), + cty.ObjectVal(map[string]cty.Value{ + "bar": cty.SetVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{ + "optional": cty.NullVal(cty.String), // explicit null in config + "computed": cty.NullVal(cty.String), // computed attrs are null in config + "optional_computed": cty.StringVal("other_configured"), + "required": cty.StringVal("other_configured"), + })}), + }), + }), + }), + // want: + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bar": cty.SetVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{ + "optional": cty.StringVal("configured"), + "computed": cty.NullVal(cty.String), + "optional_computed": cty.StringVal("configured"), + "required": cty.StringVal("configured"), + })}), + }), + cty.ObjectVal(map[string]cty.Value{ + "bar": cty.SetVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{ + "optional": cty.NullVal(cty.String), // explicit null in config is preserved + "computed": cty.NullVal(cty.String), + "optional_computed": cty.StringVal("other_configured"), + "required": cty.StringVal("other_configured"), + })}), + }), + }), + }), + }, } for name, test := range tests { @@ -1209,3 +1370,23 @@ func TestProposedNewObject(t *testing.T) { }) } } + +var testAttributes = map[string]*configschema.Attribute{ + "optional": { + Type: cty.String, + Optional: true, + }, + "computed": { + Type: cty.String, + Computed: true, + }, + "optional_computed": { + Type: cty.String, + Computed: true, + Optional: true, + }, + "required": { + Type: cty.String, + Required: true, + }, +} From 6aa90a51d00d107c2aa6115ef48420c2160d1159 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Thu, 11 Feb 2021 10:32:31 -0500 Subject: [PATCH 6/8] ContainsSensitive must descend into nested objects --- configs/configschema/implied_type.go | 3 ++ configs/configschema/implied_type_test.go | 62 +++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/configs/configschema/implied_type.go b/configs/configschema/implied_type.go index 729881a03164..a9efa9658404 100644 --- a/configs/configschema/implied_type.go +++ b/configs/configschema/implied_type.go @@ -71,6 +71,9 @@ func (o *Object) ContainsSensitive() bool { if attrS.Sensitive { return true } + if attrS.NestedType != nil { + return attrS.NestedType.ContainsSensitive() + } } return false } diff --git a/configs/configschema/implied_type_test.go b/configs/configschema/implied_type_test.go index 56316eead885..595d9dd32020 100644 --- a/configs/configschema/implied_type_test.go +++ b/configs/configschema/implied_type_test.go @@ -178,3 +178,65 @@ func TestObjectImpliedType(t *testing.T) { }) } } + +func TestObjectContainsSensitive(t *testing.T) { + tests := map[string]struct { + Schema *Object + Want bool + }{ + "object contains sensitive": { + &Object{ + Attributes: map[string]*Attribute{ + "sensitive": {Sensitive: true}, + }, + }, + true, + }, + "no sensitive attrs": { + &Object{ + Attributes: map[string]*Attribute{ + "insensitive": {}, + }, + }, + false, + }, + "nested object contains sensitive": { + &Object{ + Attributes: map[string]*Attribute{ + "nested": { + NestedType: &Object{ + Attributes: map[string]*Attribute{ + "sensitive": {Sensitive: true}, + }, + }, + }, + }, + }, + true, + }, + "nested obj, no sensitive attrs": { + &Object{ + Attributes: map[string]*Attribute{ + "nested": { + NestedType: &Object{ + Attributes: map[string]*Attribute{ + "public": {}, + }, + }, + }, + }, + }, + false, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + got := test.Schema.ContainsSensitive() + if got != test.Want { + t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) + } + }) + } + +} From 1cf4909b280d9df6333fb6d324103dd3225b4832 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Fri, 12 Feb 2021 13:34:25 -0500 Subject: [PATCH 7/8] configschema: fix various issues with NestedTypes A handful of bugs popped up while extending the testing in plans/objchange. The main themes were failing to recurse through deeply nested NestedType attributes and improperly building up the ImpliedType. This commit fixes those issues and extends the test coverage to match. --- configs/configschema/decoder_spec.go | 28 ++---- configs/configschema/decoder_spec_test.go | 107 ++++++++++++++++++++-- configs/configschema/empty_value.go | 11 +-- configs/configschema/empty_value_test.go | 26 ------ configs/configschema/implied_type.go | 26 +++++- configs/configschema/implied_type_test.go | 84 ++++++++++++++++- 6 files changed, 212 insertions(+), 70 deletions(-) diff --git a/configs/configschema/decoder_spec.go b/configs/configschema/decoder_spec.go index 8325eaf60255..f758d27d2382 100644 --- a/configs/configschema/decoder_spec.go +++ b/configs/configschema/decoder_spec.go @@ -197,21 +197,9 @@ func (a *Attribute) decoderSpec(name string) hcldec.Spec { panic("Invalid attribute schema: NestedType and Type cannot both be set. This is a bug in the provider.") } - var optAttrs []string - optAttrs = listOptionalAttrsFromObject(a.NestedType, optAttrs) ty := a.NestedType.ImpliedType() - - switch a.NestedType.Nesting { - case NestingList: - ret.Type = cty.List(ty) - case NestingSet: - ret.Type = cty.Set(ty) - case NestingMap: - ret.Type = cty.Map(ty) - default: // NestingSingle, NestingGroup, or no NestingMode - ret.Type = ty - } - ret.Required = a.NestedType.MinItems > 0 + ret.Type = ty + ret.Required = a.Required || a.NestedType.MinItems > 0 return ret } @@ -220,12 +208,16 @@ func (a *Attribute) decoderSpec(name string) hcldec.Spec { return ret } -func listOptionalAttrsFromObject(o *Object, optAttrs []string) []string { +// listOptionalAttrsFromObject is a helper function which does *not* recurse +// into NestedType Attributes, because the optional types for each of those will +// belong to their own cty.Object definitions. It is used in other functions +// which themselves handle that recursion. +func listOptionalAttrsFromObject(o *Object) []string { + var ret []string for name, attr := range o.Attributes { if attr.Optional == true { - optAttrs = append(optAttrs, name) + ret = append(ret, name) } } - - return optAttrs + return ret } diff --git a/configs/configschema/decoder_spec_test.go b/configs/configschema/decoder_spec_test.go index 1f3691ed2237..1eefc4d8b6e3 100644 --- a/configs/configschema/decoder_spec_test.go +++ b/configs/configschema/decoder_spec_test.go @@ -451,7 +451,7 @@ func TestAttributeDecoderSpec(t *testing.T) { Type: cty.String, Optional: true, }, - hcl.EmptyBody(), + hcltest.MockBody(&hcl.BodyContent{}), cty.NullVal(cty.String), 0, }, @@ -474,6 +474,7 @@ func TestAttributeDecoderSpec(t *testing.T) { "NestedType with required string": { &Attribute{ NestedType: &Object{ + Nesting: NestingSingle, Attributes: map[string]*Attribute{ "foo": { Type: cty.String, @@ -501,6 +502,7 @@ func TestAttributeDecoderSpec(t *testing.T) { "NestedType with optional attributes": { &Attribute{ NestedType: &Object{ + Nesting: NestingSingle, Attributes: map[string]*Attribute{ "foo": { Type: cty.String, @@ -533,6 +535,7 @@ func TestAttributeDecoderSpec(t *testing.T) { "NestedType with missing required string": { &Attribute{ NestedType: &Object{ + Nesting: NestingSingle, Attributes: map[string]*Attribute{ "foo": { Type: cty.String, @@ -575,11 +578,9 @@ func TestAttributeDecoderSpec(t *testing.T) { Name: "attr", Expr: hcltest.MockExprLiteral(cty.ListVal([]cty.Value{ cty.ObjectVal(map[string]cty.Value{ - // "foo" should be a string, not a list "foo": cty.StringVal("bar"), }), cty.ObjectVal(map[string]cty.Value{ - // "foo" should be a string, not a list "foo": cty.StringVal("baz"), }), })), @@ -638,11 +639,9 @@ func TestAttributeDecoderSpec(t *testing.T) { Name: "attr", Expr: hcltest.MockExprLiteral(cty.SetVal([]cty.Value{ cty.ObjectVal(map[string]cty.Value{ - // "foo" should be a string, not a list "foo": cty.StringVal("bar"), }), cty.ObjectVal(map[string]cty.Value{ - // "foo" should be a string, not a list "foo": cty.StringVal("baz"), }), })), @@ -701,11 +700,9 @@ func TestAttributeDecoderSpec(t *testing.T) { Name: "attr", Expr: hcltest.MockExprLiteral(cty.MapVal(map[string]cty.Value{ "one": cty.ObjectVal(map[string]cty.Value{ - // "foo" should be a string, not a list "foo": cty.StringVal("bar"), }), "two": cty.ObjectVal(map[string]cty.Value{ - // "foo" should be a string, not a list "foo": cty.StringVal("baz"), }), })), @@ -747,6 +744,102 @@ func TestAttributeDecoderSpec(t *testing.T) { cty.UnknownVal(cty.Map(cty.Object(map[string]cty.Type{"foo": cty.String}))), 1, }, + "deeply NestedType NestingModeList valid": { + &Attribute{ + NestedType: &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "foo": { + NestedType: &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "bar": { + Type: cty.String, + Required: true, + }, + }, + }, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")}), + cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("boz")}), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("biz")}), + cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("buz")}), + }), + }), + })), + }, + }, + }), + cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{"foo": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")}), + cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("boz")}), + })}), + cty.ObjectVal(map[string]cty.Value{"foo": cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("biz")}), + cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("buz")}), + })}), + }), + 0, + }, + "deeply NestedType NestingList invalid": { + &Attribute{ + NestedType: &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "foo": { + NestedType: &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "bar": { + Type: cty.Number, + Required: true, + }, + }, + }, + Required: true, + }, + }, + }, + Optional: true, + }, + hcltest.MockBody(&hcl.BodyContent{ + Attributes: hcl.Attributes{ + "attr": { + Name: "attr", + Expr: hcltest.MockExprLiteral(cty.ListVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.ListVal([]cty.Value{ + // bar should be a Number + cty.ObjectVal(map[string]cty.Value{"bar": cty.True}), + cty.ObjectVal(map[string]cty.Value{"bar": cty.False}), + }), + }), + })), + }, + }, + }), + cty.UnknownVal(cty.List(cty.Object(map[string]cty.Type{ + "foo": cty.List(cty.Object(map[string]cty.Type{"bar": cty.Number})), + }))), + 1, + }, } for name, test := range tests { diff --git a/configs/configschema/empty_value.go b/configs/configschema/empty_value.go index a5146849476f..ea8cdbbcc482 100644 --- a/configs/configschema/empty_value.go +++ b/configs/configschema/empty_value.go @@ -27,16 +27,7 @@ func (b *Block) EmptyValue() cty.Value { // at all, ignoring any required constraint. func (a *Attribute) EmptyValue() cty.Value { if a.NestedType != nil { - switch a.NestedType.Nesting { - case NestingList: - return cty.NullVal(cty.List(a.NestedType.ImpliedType())) - case NestingSet: - return cty.NullVal(cty.Set(a.NestedType.ImpliedType())) - case NestingMap: - return cty.NullVal(cty.Map(a.NestedType.ImpliedType())) - default: // NestingSingle, NestingGroup, or no NestingMode - return cty.NullVal(a.NestedType.ImpliedType()) - } + return cty.NullVal(a.NestedType.ImpliedType()) } return cty.NullVal(a.Type) } diff --git a/configs/configschema/empty_value_test.go b/configs/configschema/empty_value_test.go index a11ab4cdbf5c..a9d8e307495b 100644 --- a/configs/configschema/empty_value_test.go +++ b/configs/configschema/empty_value_test.go @@ -186,19 +186,6 @@ func TestAttributeEmptyValue(t *testing.T) { }, cty.NullVal(cty.String), }, - { - &Attribute{ - NestedType: &Object{ - // no Nesting set should behave the same as NestingSingle - Attributes: map[string]*Attribute{ - "str": {Type: cty.String, Required: true}, - }, - }, - }, - cty.NullVal(cty.Object(map[string]cty.Type{ - "str": cty.String, - })), - }, { &Attribute{ NestedType: &Object{ @@ -212,19 +199,6 @@ func TestAttributeEmptyValue(t *testing.T) { "str": cty.String, })), }, - { - &Attribute{ - NestedType: &Object{ - Nesting: NestingGroup, // functionally equivalent to NestingSingle in a NestedType - Attributes: map[string]*Attribute{ - "str": {Type: cty.String, Required: true}, - }, - }, - }, - cty.NullVal(cty.Object(map[string]cty.Type{ - "str": cty.String, - })), - }, { &Attribute{ NestedType: &Object{ diff --git a/configs/configschema/implied_type.go b/configs/configschema/implied_type.go index a9efa9658404..1c8cbcd873f0 100644 --- a/configs/configschema/implied_type.go +++ b/configs/configschema/implied_type.go @@ -55,13 +55,29 @@ func (o *Object) ImpliedType() cty.Type { attrTys := make(map[string]cty.Type, len(o.Attributes)) for name, attrS := range o.Attributes { - attrTys[name] = attrS.Type + if attrS.NestedType != nil { + attrTys[name] = attrS.NestedType.ImpliedType() + } else { + attrTys[name] = attrS.Type + } + } + optAttrs := listOptionalAttrsFromObject(o) + if len(optAttrs) > 0 { + return cty.ObjectWithOptionalAttrs(attrTys, optAttrs) } - var optAttrs []string - optAttrs = listOptionalAttrsFromObject(o, optAttrs) - - return cty.ObjectWithOptionalAttrs(attrTys, optAttrs) + switch o.Nesting { + case NestingSingle: + return cty.Object(attrTys) + case NestingList: + return cty.List(cty.Object(attrTys)) + case NestingMap: + return cty.Map(cty.Object(attrTys)) + case NestingSet: + return cty.Set(cty.Object(attrTys)) + default: // Should never happen + panic("invalid Nesting") + } } // ContainsSensitive returns true if any of the attributes of the receiving diff --git a/configs/configschema/implied_type_test.go b/configs/configschema/implied_type_test.go index 595d9dd32020..70ad9fa56ea1 100644 --- a/configs/configschema/implied_type_test.go +++ b/configs/configschema/implied_type_test.go @@ -132,10 +132,6 @@ func TestObjectImpliedType(t *testing.T) { nil, cty.EmptyObject, }, - "empty": { - &Object{}, - cty.EmptyObject, - }, "attributes": { &Object{ Attributes: map[string]*Attribute{ @@ -167,6 +163,86 @@ func TestObjectImpliedType(t *testing.T) { []string{"optional", "optional_computed"}, ), }, + "nested attributes": { + &Object{ + Attributes: map[string]*Attribute{ + "nested_type": { + NestedType: &Object{ + Attributes: map[string]*Attribute{ + "optional": { + Type: cty.String, + Optional: true, + }, + "required": { + Type: cty.Number, + Required: true, + }, + "computed": { + Type: cty.List(cty.Bool), + Computed: true, + }, + "optional_computed": { + Type: cty.Map(cty.Bool), + Optional: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectWithOptionalAttrs(map[string]cty.Type{ + "nested_type": cty.ObjectWithOptionalAttrs(map[string]cty.Type{ + "optional": cty.String, + "required": cty.Number, + "computed": cty.List(cty.Bool), + "optional_computed": cty.Map(cty.Bool), + }, []string{"optional", "optional_computed"}), + }, []string{"nested_type"}), + }, + "NestingList": { + &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "foo": {Type: cty.String}, + }, + }, + cty.List(cty.Object(map[string]cty.Type{"foo": cty.String})), + }, + "NestingMap": { + &Object{ + Nesting: NestingMap, + Attributes: map[string]*Attribute{ + "foo": {Type: cty.String}, + }, + }, + cty.Map(cty.Object(map[string]cty.Type{"foo": cty.String})), + }, + "NestingSet": { + &Object{ + Nesting: NestingSet, + Attributes: map[string]*Attribute{ + "foo": {Type: cty.String}, + }, + }, + cty.Set(cty.Object(map[string]cty.Type{"foo": cty.String})), + }, + "deeply nested NestingList": { + &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "foo": { + NestedType: &Object{ + Nesting: NestingList, + Attributes: map[string]*Attribute{ + "bar": {Type: cty.String}, + }, + }, + }, + }, + }, + cty.List(cty.Object(map[string]cty.Type{"foo": cty.List(cty.Object(map[string]cty.Type{"bar": cty.String}))})), + }, } for name, test := range tests { From 8c2abbc0f0c3217cf2d6ec209eeb8032823b9af7 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Fri, 12 Feb 2021 13:37:45 -0500 Subject: [PATCH 8/8] return the properly-typed nulls, instead of empty containers, in proposedNewNestedType --- plans/objchange/objchange.go | 14 ++-- plans/objchange/objchange_test.go | 102 ++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 10 deletions(-) diff --git a/plans/objchange/objchange.go b/plans/objchange/objchange.go index 2873adbb709c..fade668c289a 100644 --- a/plans/objchange/objchange.go +++ b/plans/objchange/objchange.go @@ -337,13 +337,7 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) newV = cty.ListVal(newVals) } } else { - // Despite the name, a NestingList might also be a tuple, if - // its nested schema contains dynamically-typed attributes. - if config.Type().IsTupleType() { - newV = cty.EmptyTupleVal - } else { - newV = cty.ListValEmpty(schema.ImpliedType()) - } + newV = cty.NullVal(schema.ImpliedType()) } case configschema.NestingMap: @@ -376,7 +370,7 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) // in case of dynamically-typed attributes. newV = cty.ObjectVal(newVals) } else { - newV = cty.EmptyObjectVal + newV = cty.NullVal(schema.ImpliedType()) } } else { configVLen := 0 @@ -401,7 +395,7 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) } newV = cty.MapVal(newVals) } else { - newV = cty.MapValEmpty(schema.ImpliedType()) + newV = cty.NullVal(schema.ImpliedType()) } } @@ -444,7 +438,7 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) } newV = cty.SetVal(newVals) } else { - newV = cty.SetValEmpty(schema.ImpliedType()) + newV = cty.NullVal(schema.ImpliedType()) } } diff --git a/plans/objchange/objchange_test.go b/plans/objchange/objchange_test.go index 181a42ea9a15..759f37e1dc3f 100644 --- a/plans/objchange/objchange_test.go +++ b/plans/objchange/objchange_test.go @@ -1359,6 +1359,108 @@ func TestProposedNew(t *testing.T) { }), }), }, + "expected null NestedTypes": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "single": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + "list": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + "set": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + "map": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingMap, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + "nested_map": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingMap, + Attributes: map[string]*configschema.Attribute{ + "inner": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSingle, + Attributes: testAttributes, + }, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "single": cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")}), + "list": cty.ListVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")})}), + "map": cty.MapVal(map[string]cty.Value{ + "map_entry": cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")}), + }), + "set": cty.SetVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{"bar": cty.StringVal("baz")})}), + "nested_map": cty.MapVal(map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "inner": cty.ObjectVal(map[string]cty.Value{ + "optional": cty.StringVal("foo"), + "computed": cty.StringVal("foo"), + "optional_computed": cty.StringVal("foo"), + "required": cty.StringVal("foo"), + }), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "single": cty.ObjectVal(map[string]cty.Value{"bar": cty.NullVal(cty.String)}), + "list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "map": cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "set": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "nested_map": cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{ + "inner": cty.Object(map[string]cty.Type{ + "optional": cty.String, + "computed": cty.String, + "optional_computed": cty.String, + "required": cty.String, + }), + }))), + }), + cty.ObjectVal(map[string]cty.Value{ + "single": cty.ObjectVal(map[string]cty.Value{"bar": cty.NullVal(cty.String)}), + "list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "map": cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "set": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{"bar": cty.String}))), + "nested_map": cty.NullVal(cty.Map(cty.Object(map[string]cty.Type{ + "inner": cty.ObjectWithOptionalAttrs(map[string]cty.Type{ + "optional": cty.String, + "computed": cty.String, + "optional_computed": cty.String, + "required": cty.String, + }, []string{"optional", "optional_computed"}), + }))), + }), + }, } for name, test := range tests {