Add support for provider metadata to modules. (#22583)
Implement a new provider_meta block in the terraform block of modules, allowing provider-keyed metadata to be communicated from HCL to provider binaries. Bundled in this change for minimal protocol version bumping is the addition of markdown support for attribute descriptions and the ability to indicate when an attribute is deprecated, so this information can be shown in the schema dump. Co-authored-by: Paul Tyng <paul@paultyng.net>
This commit is contained in:
parent
4654b45d6b
commit
e6592dc710
|
@ -16,6 +16,13 @@ func Provider() terraform.ResourceProvider {
|
||||||
Optional: true,
|
Optional: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
ProviderMetaSchema: map[string]*schema.Schema{
|
||||||
|
// Optionally allow specifying information at a module-level
|
||||||
|
"foo": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
"test_resource": testResource(),
|
"test_resource": testResource(),
|
||||||
"test_resource_gh12183": testResourceGH12183(),
|
"test_resource_gh12183": testResourceGH12183(),
|
||||||
|
@ -36,6 +43,7 @@ func Provider() terraform.ResourceProvider {
|
||||||
"test_resource_computed_set": testResourceComputedSet(),
|
"test_resource_computed_set": testResourceComputedSet(),
|
||||||
"test_resource_config_mode": testResourceConfigMode(),
|
"test_resource_config_mode": testResourceConfigMode(),
|
||||||
"test_resource_nested_id": testResourceNestedId(),
|
"test_resource_nested_id": testResourceNestedId(),
|
||||||
|
"test_resource_provider_meta": testResourceProviderMeta(),
|
||||||
"test_undeleteable": testResourceUndeleteable(),
|
"test_undeleteable": testResourceUndeleteable(),
|
||||||
"test_resource_required_min": testResourceRequiredMin(),
|
"test_resource_required_min": testResourceRequiredMin(),
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testResourceProviderMeta() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: testResourceProviderMetaCreate,
|
||||||
|
Read: testResourceProviderMetaRead,
|
||||||
|
Update: testResourceProviderMetaUpdate,
|
||||||
|
Delete: testResourceProviderMetaDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"optional": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type providerMeta struct {
|
||||||
|
Foo string `cty:"foo"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceProviderMetaCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
d.SetId("testId")
|
||||||
|
var m providerMeta
|
||||||
|
|
||||||
|
err := d.GetProviderMeta(&m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Foo != "bar" {
|
||||||
|
return fmt.Errorf("expected provider_meta.foo to be %q, was %q",
|
||||||
|
"bar", m.Foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
return testResourceProviderMetaRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceProviderMetaRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
var m providerMeta
|
||||||
|
|
||||||
|
err := d.GetProviderMeta(&m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Foo != "bar" {
|
||||||
|
return fmt.Errorf("expected provider_meta.foo to be %q, was %q",
|
||||||
|
"bar", m.Foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceProviderMetaUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
var m providerMeta
|
||||||
|
|
||||||
|
err := d.GetProviderMeta(&m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Foo != "bar" {
|
||||||
|
return fmt.Errorf("expected provider_meta.foo to be %q, was %q",
|
||||||
|
"bar", m.Foo)
|
||||||
|
}
|
||||||
|
return testResourceProviderMetaRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceProviderMetaDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
d.SetId("")
|
||||||
|
var m providerMeta
|
||||||
|
|
||||||
|
err := d.GetProviderMeta(&m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Foo != "bar" {
|
||||||
|
return fmt.Errorf("expected provider_meta.foo to be %q, was %q",
|
||||||
|
"bar", m.Foo)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResourceProviderMeta_basic(t *testing.T) {
|
||||||
|
resource.UnitTest(t, resource.TestCase{
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckResourceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: strings.TrimSpace(`
|
||||||
|
terraform {
|
||||||
|
provider_meta "test" {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_resource_provider_meta" "foo" {
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
|
@ -7,12 +7,23 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type attribute struct {
|
type attribute struct {
|
||||||
AttributeType json.RawMessage `json:"type,omitempty"`
|
AttributeType json.RawMessage `json:"type,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
Required bool `json:"required,omitempty"`
|
DescriptionKind string `json:"description_kind,omitempty"`
|
||||||
Optional bool `json:"optional,omitempty"`
|
Deprecated bool `json:"deprecated,omitempty"`
|
||||||
Computed bool `json:"computed,omitempty"`
|
Required bool `json:"required,omitempty"`
|
||||||
Sensitive bool `json:"sensitive,omitempty"`
|
Optional bool `json:"optional,omitempty"`
|
||||||
|
Computed bool `json:"computed,omitempty"`
|
||||||
|
Sensitive bool `json:"sensitive,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func marshalStringKind(sk configschema.StringKind) string {
|
||||||
|
switch sk {
|
||||||
|
default:
|
||||||
|
return "plain"
|
||||||
|
case configschema.StringMarkdown:
|
||||||
|
return "markdown"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshalAttribute(attr *configschema.Attribute) *attribute {
|
func marshalAttribute(attr *configschema.Attribute) *attribute {
|
||||||
|
@ -21,11 +32,13 @@ func marshalAttribute(attr *configschema.Attribute) *attribute {
|
||||||
attrTy, _ := attr.Type.MarshalJSON()
|
attrTy, _ := attr.Type.MarshalJSON()
|
||||||
|
|
||||||
return &attribute{
|
return &attribute{
|
||||||
AttributeType: attrTy,
|
AttributeType: attrTy,
|
||||||
Description: attr.Description,
|
Description: attr.Description,
|
||||||
Required: attr.Required,
|
DescriptionKind: marshalStringKind(attr.DescriptionKind),
|
||||||
Optional: attr.Optional,
|
Required: attr.Required,
|
||||||
Computed: attr.Computed,
|
Optional: attr.Optional,
|
||||||
Sensitive: attr.Sensitive,
|
Computed: attr.Computed,
|
||||||
|
Sensitive: attr.Sensitive,
|
||||||
|
Deprecated: attr.Deprecated,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,17 +18,19 @@ func TestMarshalAttribute(t *testing.T) {
|
||||||
{
|
{
|
||||||
&configschema.Attribute{Type: cty.String, Optional: true, Computed: true},
|
&configschema.Attribute{Type: cty.String, Optional: true, Computed: true},
|
||||||
&attribute{
|
&attribute{
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ // collection types look a little odd.
|
{ // collection types look a little odd.
|
||||||
&configschema.Attribute{Type: cty.Map(cty.String), Optional: true, Computed: true},
|
&configschema.Attribute{Type: cty.Map(cty.String), Optional: true, Computed: true},
|
||||||
&attribute{
|
&attribute{
|
||||||
AttributeType: json.RawMessage(`["map","string"]`),
|
AttributeType: json.RawMessage(`["map","string"]`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type block struct {
|
type block struct {
|
||||||
Attributes map[string]*attribute `json:"attributes,omitempty"`
|
Attributes map[string]*attribute `json:"attributes,omitempty"`
|
||||||
BlockTypes map[string]*blockType `json:"block_types,omitempty"`
|
BlockTypes map[string]*blockType `json:"block_types,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
DescriptionKind string `json:"description_kind,omitempty"`
|
||||||
|
Deprecated bool `json:"deprecated,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type blockType struct {
|
type blockType struct {
|
||||||
|
@ -48,7 +51,12 @@ func marshalBlock(configBlock *configschema.Block) *block {
|
||||||
return &block{}
|
return &block{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret block
|
ret := block{
|
||||||
|
Deprecated: configBlock.Deprecated,
|
||||||
|
Description: configBlock.Description,
|
||||||
|
DescriptionKind: marshalStringKind(configBlock.DescriptionKind),
|
||||||
|
}
|
||||||
|
|
||||||
if len(configBlock.Attributes) > 0 {
|
if len(configBlock.Attributes) > 0 {
|
||||||
attrs := make(map[string]*attribute, len(configBlock.Attributes))
|
attrs := make(map[string]*attribute, len(configBlock.Attributes))
|
||||||
for k, attr := range configBlock.Attributes {
|
for k, attr := range configBlock.Attributes {
|
||||||
|
|
|
@ -39,20 +39,22 @@ func TestMarshalBlock(t *testing.T) {
|
||||||
},
|
},
|
||||||
Want: &block{
|
Want: &block{
|
||||||
Attributes: map[string]*attribute{
|
Attributes: map[string]*attribute{
|
||||||
"ami": {AttributeType: json.RawMessage(`"string"`), Optional: true},
|
"ami": {AttributeType: json.RawMessage(`"string"`), Optional: true, DescriptionKind: "plain"},
|
||||||
"id": {AttributeType: json.RawMessage(`"string"`), Optional: true, Computed: true},
|
"id": {AttributeType: json.RawMessage(`"string"`), Optional: true, Computed: true, DescriptionKind: "plain"},
|
||||||
},
|
},
|
||||||
BlockTypes: map[string]*blockType{
|
BlockTypes: map[string]*blockType{
|
||||||
"network_interface": {
|
"network_interface": {
|
||||||
NestingMode: "list",
|
NestingMode: "list",
|
||||||
Block: &block{
|
Block: &block{
|
||||||
Attributes: map[string]*attribute{
|
Attributes: map[string]*attribute{
|
||||||
"description": {AttributeType: json.RawMessage(`"string"`), Optional: true},
|
"description": {AttributeType: json.RawMessage(`"string"`), Optional: true, DescriptionKind: "plain"},
|
||||||
"device_index": {AttributeType: json.RawMessage(`"string"`), Optional: true},
|
"device_index": {AttributeType: json.RawMessage(`"string"`), Optional: true, DescriptionKind: "plain"},
|
||||||
},
|
},
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,12 @@ func TestMarshalProvider(t *testing.T) {
|
||||||
Block: &block{
|
Block: &block{
|
||||||
Attributes: map[string]*attribute{
|
Attributes: map[string]*attribute{
|
||||||
"region": {
|
"region": {
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Required: true,
|
Required: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ResourceSchemas: map[string]*schema{
|
ResourceSchemas: map[string]*schema{
|
||||||
|
@ -40,13 +42,15 @@ func TestMarshalProvider(t *testing.T) {
|
||||||
Block: &block{
|
Block: &block{
|
||||||
Attributes: map[string]*attribute{
|
Attributes: map[string]*attribute{
|
||||||
"id": {
|
"id": {
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
"ami": {
|
"ami": {
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
BlockTypes: map[string]*blockType{
|
BlockTypes: map[string]*blockType{
|
||||||
|
@ -54,18 +58,22 @@ func TestMarshalProvider(t *testing.T) {
|
||||||
Block: &block{
|
Block: &block{
|
||||||
Attributes: map[string]*attribute{
|
Attributes: map[string]*attribute{
|
||||||
"device_index": {
|
"device_index": {
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
NestingMode: "list",
|
NestingMode: "list",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -75,13 +83,15 @@ func TestMarshalProvider(t *testing.T) {
|
||||||
Block: &block{
|
Block: &block{
|
||||||
Attributes: map[string]*attribute{
|
Attributes: map[string]*attribute{
|
||||||
"id": {
|
"id": {
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
"ami": {
|
"ami": {
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
BlockTypes: map[string]*blockType{
|
BlockTypes: map[string]*blockType{
|
||||||
|
@ -89,18 +99,22 @@ func TestMarshalProvider(t *testing.T) {
|
||||||
Block: &block{
|
Block: &block{
|
||||||
Attributes: map[string]*attribute{
|
Attributes: map[string]*attribute{
|
||||||
"device_index": {
|
"device_index": {
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
AttributeType: json.RawMessage(`"string"`),
|
AttributeType: json.RawMessage(`"string"`),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
NestingMode: "list",
|
NestingMode: "list",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
DescriptionKind: "plain",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,17 +9,20 @@
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"ami": {
|
"ami": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"optional": true
|
"optional": true,
|
||||||
|
"description_kind": "plain"
|
||||||
},
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"computed": true
|
"computed": true,
|
||||||
|
"description_kind": "plain"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"description_kind": "plain"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,13 @@ import (
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type StringKind int
|
||||||
|
|
||||||
|
const (
|
||||||
|
StringPlain StringKind = iota
|
||||||
|
StringMarkdown
|
||||||
|
)
|
||||||
|
|
||||||
// Block represents a configuration block.
|
// Block represents a configuration block.
|
||||||
//
|
//
|
||||||
// "Block" here is a logical grouping construct, though it happens to map
|
// "Block" here is a logical grouping construct, though it happens to map
|
||||||
|
@ -21,6 +28,11 @@ type Block struct {
|
||||||
// BlockTypes describes any nested block types that may appear directly
|
// BlockTypes describes any nested block types that may appear directly
|
||||||
// inside the block.
|
// inside the block.
|
||||||
BlockTypes map[string]*NestedBlock
|
BlockTypes map[string]*NestedBlock
|
||||||
|
|
||||||
|
Description string
|
||||||
|
DescriptionKind StringKind
|
||||||
|
|
||||||
|
Deprecated bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attribute represents a configuration attribute, within a block.
|
// Attribute represents a configuration attribute, within a block.
|
||||||
|
@ -32,7 +44,8 @@ type Attribute struct {
|
||||||
// usage of the attribute. A description should be concise and use only
|
// usage of the attribute. A description should be concise and use only
|
||||||
// one or two sentences, leaving full definition to longer-form
|
// one or two sentences, leaving full definition to longer-form
|
||||||
// documentation defined elsewhere.
|
// documentation defined elsewhere.
|
||||||
Description string
|
Description string
|
||||||
|
DescriptionKind StringKind
|
||||||
|
|
||||||
// Required, if set to true, specifies that an omitted or null value is
|
// Required, if set to true, specifies that an omitted or null value is
|
||||||
// not permitted.
|
// not permitted.
|
||||||
|
@ -55,6 +68,8 @@ type Attribute struct {
|
||||||
// future to help Terraform mask sensitive information. (Terraform
|
// future to help Terraform mask sensitive information. (Terraform
|
||||||
// currently achieves this in a limited sense via other mechanisms.)
|
// currently achieves this in a limited sense via other mechanisms.)
|
||||||
Sensitive bool
|
Sensitive bool
|
||||||
|
|
||||||
|
Deprecated bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NestedBlock represents the embedding of one block within another.
|
// NestedBlock represents the embedding of one block within another.
|
||||||
|
|
|
@ -32,6 +32,7 @@ type Module struct {
|
||||||
ProviderConfigs map[string]*Provider
|
ProviderConfigs map[string]*Provider
|
||||||
ProviderRequirements map[string]ProviderRequirements
|
ProviderRequirements map[string]ProviderRequirements
|
||||||
ProviderLocalNames map[addrs.Provider]string
|
ProviderLocalNames map[addrs.Provider]string
|
||||||
|
ProviderMetas map[addrs.Provider]*ProviderMeta
|
||||||
|
|
||||||
Variables map[string]*Variable
|
Variables map[string]*Variable
|
||||||
Locals map[string]*Local
|
Locals map[string]*Local
|
||||||
|
@ -61,6 +62,7 @@ type File struct {
|
||||||
|
|
||||||
Backends []*Backend
|
Backends []*Backend
|
||||||
ProviderConfigs []*Provider
|
ProviderConfigs []*Provider
|
||||||
|
ProviderMetas []*ProviderMeta
|
||||||
RequiredProviders []*RequiredProvider
|
RequiredProviders []*RequiredProvider
|
||||||
|
|
||||||
Variables []*Variable
|
Variables []*Variable
|
||||||
|
@ -93,6 +95,7 @@ func NewModule(primaryFiles, overrideFiles []*File) (*Module, hcl.Diagnostics) {
|
||||||
ModuleCalls: map[string]*ModuleCall{},
|
ModuleCalls: map[string]*ModuleCall{},
|
||||||
ManagedResources: map[string]*Resource{},
|
ManagedResources: map[string]*Resource{},
|
||||||
DataResources: map[string]*Resource{},
|
DataResources: map[string]*Resource{},
|
||||||
|
ProviderMetas: map[addrs.Provider]*ProviderMeta{},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range primaryFiles {
|
for _, file := range primaryFiles {
|
||||||
|
@ -195,6 +198,19 @@ func (m *Module) appendFile(file *File) hcl.Diagnostics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, pm := range file.ProviderMetas {
|
||||||
|
// TODO(paddy): pm.Provider is a string, but we need to build an addrs.Provider out of it somehow
|
||||||
|
if existing, exists := m.ProviderMetas[addrs.NewLegacyProvider(pm.Provider)]; exists {
|
||||||
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: "Duplicate provider_meta block",
|
||||||
|
Detail: fmt.Sprintf("A provider_meta block for provider %q was already declared at %s. Providers may only have one provider_meta block per module.", existing.Provider, existing.DeclRange),
|
||||||
|
Subject: &pm.DeclRange,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
m.ProviderMetas[addrs.NewLegacyProvider(pm.Provider)] = pm
|
||||||
|
}
|
||||||
|
|
||||||
for _, v := range file.Variables {
|
for _, v := range file.Variables {
|
||||||
if existing, exists := m.Variables[v.Name]; exists {
|
if existing, exists := m.Variables[v.Name]; exists {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
|
|
|
@ -77,6 +77,13 @@ func (p *Parser) loadConfigFile(path string, override bool) (*File, hcl.Diagnost
|
||||||
diags = append(diags, reqsDiags...)
|
diags = append(diags, reqsDiags...)
|
||||||
file.RequiredProviders = append(file.RequiredProviders, reqs...)
|
file.RequiredProviders = append(file.RequiredProviders, reqs...)
|
||||||
|
|
||||||
|
case "provider_meta":
|
||||||
|
providerCfg, cfgDiags := decodeProviderMetaBlock(innerBlock)
|
||||||
|
diags = append(diags, cfgDiags...)
|
||||||
|
if providerCfg != nil {
|
||||||
|
file.ProviderMetas = append(file.ProviderMetas, providerCfg)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Should never happen because the above cases should be exhaustive
|
// Should never happen because the above cases should be exhaustive
|
||||||
// for all block type names in our schema.
|
// for all block type names in our schema.
|
||||||
|
@ -231,6 +238,10 @@ var terraformBlockSchema = &hcl.BodySchema{
|
||||||
{
|
{
|
||||||
Type: "required_providers",
|
Type: "required_providers",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Type: "provider_meta",
|
||||||
|
LabelNames: []string{"provider"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package configs
|
||||||
|
|
||||||
|
import "github.com/hashicorp/hcl/v2"
|
||||||
|
|
||||||
|
// ProviderMeta represents a "provider_meta" block inside a "terraform" block
|
||||||
|
// in a module or file.
|
||||||
|
type ProviderMeta struct {
|
||||||
|
Provider string
|
||||||
|
Config hcl.Body
|
||||||
|
|
||||||
|
ProviderRange hcl.Range
|
||||||
|
DeclRange hcl.Range
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeProviderMetaBlock(block *hcl.Block) (*ProviderMeta, hcl.Diagnostics) {
|
||||||
|
return &ProviderMeta{
|
||||||
|
Provider: block.Labels[0],
|
||||||
|
ProviderRange: block.LabelRanges[0],
|
||||||
|
Config: block.Body,
|
||||||
|
DeclRange: block.DefRange,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -0,0 +1,368 @@
|
||||||
|
// Terraform Plugin RPC protocol version 5.2
|
||||||
|
//
|
||||||
|
// This file defines version 5.2 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 5 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";
|
||||||
|
|
||||||
|
package tfplugin5;
|
||||||
|
|
||||||
|
// 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 Stop {
|
||||||
|
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<string, string> flatmap = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum StringKind {
|
||||||
|
PLAIN = 0;
|
||||||
|
MARKDOWN = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schema is the configuration schema for a Resource, Provider, or Provisioner.
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 GetSchema(GetProviderSchema.Request) returns (GetProviderSchema.Response);
|
||||||
|
rpc PrepareProviderConfig(PrepareProviderConfig.Request) returns (PrepareProviderConfig.Response);
|
||||||
|
rpc ValidateResourceTypeConfig(ValidateResourceTypeConfig.Request) returns (ValidateResourceTypeConfig.Response);
|
||||||
|
rpc ValidateDataSourceConfig(ValidateDataSourceConfig.Request) returns (ValidateDataSourceConfig.Response);
|
||||||
|
rpc UpgradeResourceState(UpgradeResourceState.Request) returns (UpgradeResourceState.Response);
|
||||||
|
|
||||||
|
//////// One-time initialization, called before other functions below
|
||||||
|
rpc Configure(Configure.Request) returns (Configure.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 Stop(Stop.Request) returns (Stop.Response);
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetProviderSchema {
|
||||||
|
message Request {
|
||||||
|
}
|
||||||
|
message Response {
|
||||||
|
Schema provider = 1;
|
||||||
|
map<string, Schema> resource_schemas = 2;
|
||||||
|
map<string, Schema> data_source_schemas = 3;
|
||||||
|
repeated Diagnostic diagnostics = 4;
|
||||||
|
Schema provider_meta = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message PrepareProviderConfig {
|
||||||
|
message Request {
|
||||||
|
DynamicValue config = 1;
|
||||||
|
}
|
||||||
|
message Response {
|
||||||
|
DynamicValue prepared_config = 1;
|
||||||
|
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 ValidateResourceTypeConfig {
|
||||||
|
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 Configure {
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
// This may be set only by the helper/schema "SDK" in the main Terraform
|
||||||
|
// repository, to request that Terraform Core >=0.12 permit additional
|
||||||
|
// inconsistencies that can result from the legacy SDK type system
|
||||||
|
// and its imprecise mapping to the >=0.12 type system.
|
||||||
|
// The change in behavior implied by this flag makes sense only for the
|
||||||
|
// specific details of the legacy SDK type system, and are not a general
|
||||||
|
// mechanism to avoid proper type handling in providers.
|
||||||
|
//
|
||||||
|
// ==== DO NOT USE THIS ====
|
||||||
|
// ==== THIS MUST BE LEFT UNSET IN ALL OTHER SDKS ====
|
||||||
|
// ==== DO NOT USE THIS ====
|
||||||
|
bool legacy_type_system = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// This may be set only by the helper/schema "SDK" in the main Terraform
|
||||||
|
// repository, to request that Terraform Core >=0.12 permit additional
|
||||||
|
// inconsistencies that can result from the legacy SDK type system
|
||||||
|
// and its imprecise mapping to the >=0.12 type system.
|
||||||
|
// The change in behavior implied by this flag makes sense only for the
|
||||||
|
// specific details of the legacy SDK type system, and are not a general
|
||||||
|
// mechanism to avoid proper type handling in providers.
|
||||||
|
//
|
||||||
|
// ==== DO NOT USE THIS ====
|
||||||
|
// ==== THIS MUST BE LEFT UNSET IN ALL OTHER SDKS ====
|
||||||
|
// ==== DO NOT USE THIS ====
|
||||||
|
bool legacy_type_system = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
service Provisioner {
|
||||||
|
rpc GetSchema(GetProvisionerSchema.Request) returns (GetProvisionerSchema.Response);
|
||||||
|
rpc ValidateProvisionerConfig(ValidateProvisionerConfig.Request) returns (ValidateProvisionerConfig.Response);
|
||||||
|
rpc ProvisionResource(ProvisionResource.Request) returns (stream ProvisionResource.Response);
|
||||||
|
rpc Stop(Stop.Request) returns (Stop.Response);
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetProvisionerSchema {
|
||||||
|
message Request {
|
||||||
|
}
|
||||||
|
message Response {
|
||||||
|
Schema provisioner = 1;
|
||||||
|
repeated Diagnostic diagnostics = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message ValidateProvisionerConfig {
|
||||||
|
message Request {
|
||||||
|
DynamicValue config = 1;
|
||||||
|
}
|
||||||
|
message Response {
|
||||||
|
repeated Diagnostic diagnostics = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message ProvisionResource {
|
||||||
|
message Request {
|
||||||
|
DynamicValue config = 1;
|
||||||
|
DynamicValue connection = 2;
|
||||||
|
}
|
||||||
|
message Response {
|
||||||
|
string output = 1;
|
||||||
|
repeated Diagnostic diagnostics = 2;
|
||||||
|
}
|
||||||
|
}
|
9
go.sum
9
go.sum
|
@ -106,7 +106,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/coreos/bbolt v1.3.0 h1:HIgH5xUWXT914HCI671AxuTTqjj64UOFr7pHn48LUTI=
|
github.com/coreos/bbolt v1.3.0 h1:HIgH5xUWXT914HCI671AxuTTqjj64UOFr7pHn48LUTI=
|
||||||
github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
|
github.com/coreos/etcd v3.3.10+incompatible h1:KjVWqrZ5U0wa3CxY2AxlH6/UcB+PK2td1DcsYhA+HRs=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
|
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
@ -372,6 +372,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
|
||||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
|
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
|
||||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
|
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
|
||||||
|
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
|
||||||
|
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
|
||||||
|
@ -479,6 +481,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||||
golang.org/x/net v0.0.0-20191009170851-d66e71096ffb h1:TR699M2v0qoKTOHxeLgp6zPqaQNs74f01a/ob9W0qko=
|
golang.org/x/net v0.0.0-20191009170851-d66e71096ffb h1:TR699M2v0qoKTOHxeLgp6zPqaQNs74f01a/ob9W0qko=
|
||||||
golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
@ -529,11 +532,15 @@ google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn
|
||||||
google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8=
|
google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8=
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk=
|
||||||
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
|
|
@ -55,6 +55,10 @@ func (s *GRPCProviderServer) GetSchema(_ context.Context, req *proto.GetProvider
|
||||||
Block: convert.ConfigSchemaToProto(s.getProviderSchemaBlock()),
|
Block: convert.ConfigSchemaToProto(s.getProviderSchemaBlock()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resp.ProviderMeta = &proto.Schema{
|
||||||
|
Block: convert.ConfigSchemaToProto(s.getProviderMetaSchemaBlock()),
|
||||||
|
}
|
||||||
|
|
||||||
for typ, res := range s.provider.ResourcesMap {
|
for typ, res := range s.provider.ResourcesMap {
|
||||||
resp.ResourceSchemas[typ] = &proto.Schema{
|
resp.ResourceSchemas[typ] = &proto.Schema{
|
||||||
Version: int64(res.SchemaVersion),
|
Version: int64(res.SchemaVersion),
|
||||||
|
@ -76,6 +80,10 @@ func (s *GRPCProviderServer) getProviderSchemaBlock() *configschema.Block {
|
||||||
return schema.InternalMap(s.provider.Schema).CoreConfigSchema()
|
return schema.InternalMap(s.provider.Schema).CoreConfigSchema()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GRPCProviderServer) getProviderMetaSchemaBlock() *configschema.Block {
|
||||||
|
return schema.InternalMap(s.provider.ProviderMetaSchema).CoreConfigSchema()
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GRPCProviderServer) getResourceSchemaBlock(name string) *configschema.Block {
|
func (s *GRPCProviderServer) getResourceSchemaBlock(name string) *configschema.Block {
|
||||||
res := s.provider.ResourcesMap[name]
|
res := s.provider.ResourcesMap[name]
|
||||||
return res.CoreConfigSchema()
|
return res.CoreConfigSchema()
|
||||||
|
@ -522,6 +530,16 @@ func (s *GRPCProviderServer) ReadResource(_ context.Context, req *proto.ReadReso
|
||||||
}
|
}
|
||||||
instanceState.Meta = private
|
instanceState.Meta = private
|
||||||
|
|
||||||
|
pmSchemaBlock := s.getProviderMetaSchemaBlock()
|
||||||
|
if pmSchemaBlock != nil && req.ProviderMeta != nil {
|
||||||
|
providerSchemaVal, err := msgpack.Unmarshal(req.ProviderMeta.Msgpack, pmSchemaBlock.ImpliedType())
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
instanceState.ProviderMeta = providerSchemaVal
|
||||||
|
}
|
||||||
|
|
||||||
newInstanceState, err := res.RefreshWithoutUpgrade(instanceState, s.provider.Meta())
|
newInstanceState, err := res.RefreshWithoutUpgrade(instanceState, s.provider.Meta())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
|
@ -621,6 +639,16 @@ func (s *GRPCProviderServer) PlanResourceChange(_ context.Context, req *proto.Pl
|
||||||
|
|
||||||
priorState.Meta = priorPrivate
|
priorState.Meta = priorPrivate
|
||||||
|
|
||||||
|
pmSchemaBlock := s.getProviderMetaSchemaBlock()
|
||||||
|
if pmSchemaBlock != nil && req.ProviderMeta != nil {
|
||||||
|
providerSchemaVal, err := msgpack.Unmarshal(req.ProviderMeta.Msgpack, pmSchemaBlock.ImpliedType())
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
priorState.ProviderMeta = providerSchemaVal
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure there are no nulls that will cause helper/schema to panic.
|
// Ensure there are no nulls that will cause helper/schema to panic.
|
||||||
if err := validateConfigNulls(proposedNewStateVal, nil); err != nil {
|
if err := validateConfigNulls(proposedNewStateVal, nil); err != nil {
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
|
@ -882,6 +910,16 @@ func (s *GRPCProviderServer) ApplyResourceChange(_ context.Context, req *proto.A
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pmSchemaBlock := s.getProviderMetaSchemaBlock()
|
||||||
|
if pmSchemaBlock != nil && req.ProviderMeta != nil {
|
||||||
|
providerSchemaVal, err := msgpack.Unmarshal(req.ProviderMeta.Msgpack, pmSchemaBlock.ImpliedType())
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
priorState.ProviderMeta = providerSchemaVal
|
||||||
|
}
|
||||||
|
|
||||||
newInstanceState, err := s.provider.Apply(info, priorState, diff)
|
newInstanceState, err := s.provider.Apply(info, priorState, diff)
|
||||||
// we record the error here, but continue processing any returned state.
|
// we record the error here, but continue processing any returned state.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
multierror "github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/terraform/configs/configschema"
|
"github.com/hashicorp/terraform/configs/configschema"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
)
|
)
|
||||||
|
@ -50,6 +50,14 @@ type Provider struct {
|
||||||
// and must *not* implement Create, Update or Delete.
|
// and must *not* implement Create, Update or Delete.
|
||||||
DataSourcesMap map[string]*Resource
|
DataSourcesMap map[string]*Resource
|
||||||
|
|
||||||
|
// ProviderMetaSchema is the schema for the configuration of the meta
|
||||||
|
// information for this provider. If this provider has no meta info,
|
||||||
|
// this can be omitted. This functionality is currently experimental
|
||||||
|
// and subject to change or break without warning; it should only be
|
||||||
|
// used by providers that are collaborating on its use with the
|
||||||
|
// Terraform team.
|
||||||
|
ProviderMetaSchema map[string]*Schema
|
||||||
|
|
||||||
// ConfigureFunc is a function for configuring the provider. If the
|
// ConfigureFunc is a function for configuring the provider. If the
|
||||||
// provider doesn't need to be configured, this can be omitted.
|
// provider doesn't need to be configured, this can be omitted.
|
||||||
//
|
//
|
||||||
|
|
|
@ -247,6 +247,9 @@ func (r *Resource) Apply(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
if s != nil && data != nil {
|
||||||
|
data.providerMeta = s.ProviderMeta
|
||||||
|
}
|
||||||
|
|
||||||
// Instance Diff shoould have the timeout info, need to copy it over to the
|
// Instance Diff shoould have the timeout info, need to copy it over to the
|
||||||
// ResourceData meta
|
// ResourceData meta
|
||||||
|
@ -437,6 +440,10 @@ func (r *Resource) RefreshWithoutUpgrade(
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s != nil {
|
||||||
|
data.providerMeta = s.ProviderMeta
|
||||||
|
}
|
||||||
|
|
||||||
exists, err := r.Exists(data, meta)
|
exists, err := r.Exists(data, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s, err
|
return s, err
|
||||||
|
@ -452,6 +459,10 @@ func (r *Resource) RefreshWithoutUpgrade(
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s != nil {
|
||||||
|
data.providerMeta = s.ProviderMeta
|
||||||
|
}
|
||||||
|
|
||||||
err = r.Read(data, meta)
|
err = r.Read(data, meta)
|
||||||
state := data.State()
|
state := data.State()
|
||||||
if state != nil && state.ID == "" {
|
if state != nil && state.ID == "" {
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/gocty"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResourceData is used to query and set the attributes of a resource.
|
// ResourceData is used to query and set the attributes of a resource.
|
||||||
|
@ -20,12 +22,13 @@ import (
|
||||||
// The most relevant methods to take a look at are Get, Set, and Partial.
|
// The most relevant methods to take a look at are Get, Set, and Partial.
|
||||||
type ResourceData struct {
|
type ResourceData struct {
|
||||||
// Settable (internally)
|
// Settable (internally)
|
||||||
schema map[string]*Schema
|
schema map[string]*Schema
|
||||||
config *terraform.ResourceConfig
|
config *terraform.ResourceConfig
|
||||||
state *terraform.InstanceState
|
state *terraform.InstanceState
|
||||||
diff *terraform.InstanceDiff
|
diff *terraform.InstanceDiff
|
||||||
meta map[string]interface{}
|
meta map[string]interface{}
|
||||||
timeouts *ResourceTimeout
|
timeouts *ResourceTimeout
|
||||||
|
providerMeta cty.Value
|
||||||
|
|
||||||
// Don't set
|
// Don't set
|
||||||
multiReader *MultiLevelFieldReader
|
multiReader *MultiLevelFieldReader
|
||||||
|
@ -549,3 +552,10 @@ func (d *ResourceData) get(addr []string, source getSource) getResult {
|
||||||
Schema: schema,
|
Schema: schema,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *ResourceData) GetProviderMeta(dst interface{}) error {
|
||||||
|
if d.providerMeta.IsNull() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return gocty.FromCtyValue(d.providerMeta, &dst)
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,31 @@ var _ = math.Inf
|
||||||
// proto package needs to be updated.
|
// proto package needs to be updated.
|
||||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||||
|
|
||||||
|
type StringKind int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
StringKind_PLAIN StringKind = 0
|
||||||
|
StringKind_MARKDOWN StringKind = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
var StringKind_name = map[int32]string{
|
||||||
|
0: "PLAIN",
|
||||||
|
1: "MARKDOWN",
|
||||||
|
}
|
||||||
|
|
||||||
|
var StringKind_value = map[string]int32{
|
||||||
|
"PLAIN": 0,
|
||||||
|
"MARKDOWN": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x StringKind) String() string {
|
||||||
|
return proto.EnumName(StringKind_name, int32(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (StringKind) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_17ae6090ff270234, []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
type Diagnostic_Severity int32
|
type Diagnostic_Severity int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -542,6 +567,9 @@ type Schema_Block struct {
|
||||||
Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
|
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"`
|
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"`
|
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=tfplugin5.StringKind" json:"description_kind,omitempty"`
|
||||||
|
Deprecated bool `protobuf:"varint,6,opt,name=deprecated,proto3" json:"deprecated,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -593,17 +621,40 @@ func (m *Schema_Block) GetBlockTypes() []*Schema_NestedBlock {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Schema_Block) GetDescription() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Description
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Schema_Block) GetDescriptionKind() StringKind {
|
||||||
|
if m != nil {
|
||||||
|
return m.DescriptionKind
|
||||||
|
}
|
||||||
|
return StringKind_PLAIN
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Schema_Block) GetDeprecated() bool {
|
||||||
|
if m != nil {
|
||||||
|
return m.Deprecated
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type Schema_Attribute struct {
|
type Schema_Attribute struct {
|
||||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
Type []byte `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
|
Type []byte `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
|
||||||
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,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"`
|
Required bool `protobuf:"varint,4,opt,name=required,proto3" json:"required,omitempty"`
|
||||||
Optional bool `protobuf:"varint,5,opt,name=optional,proto3" json:"optional,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"`
|
Computed bool `protobuf:"varint,6,opt,name=computed,proto3" json:"computed,omitempty"`
|
||||||
Sensitive bool `protobuf:"varint,7,opt,name=sensitive,proto3" json:"sensitive,omitempty"`
|
Sensitive bool `protobuf:"varint,7,opt,name=sensitive,proto3" json:"sensitive,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
DescriptionKind StringKind `protobuf:"varint,8,opt,name=description_kind,json=descriptionKind,proto3,enum=tfplugin5.StringKind" json:"description_kind,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
Deprecated bool `protobuf:"varint,9,opt,name=deprecated,proto3" json:"deprecated,omitempty"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Schema_Attribute) Reset() { *m = Schema_Attribute{} }
|
func (m *Schema_Attribute) Reset() { *m = Schema_Attribute{} }
|
||||||
|
@ -680,6 +731,20 @@ func (m *Schema_Attribute) GetSensitive() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Schema_Attribute) GetDescriptionKind() StringKind {
|
||||||
|
if m != nil {
|
||||||
|
return m.DescriptionKind
|
||||||
|
}
|
||||||
|
return StringKind_PLAIN
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Schema_Attribute) GetDeprecated() bool {
|
||||||
|
if m != nil {
|
||||||
|
return m.Deprecated
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type Schema_NestedBlock struct {
|
type Schema_NestedBlock struct {
|
||||||
TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"`
|
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"`
|
Block *Schema_Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"`
|
||||||
|
@ -818,6 +883,7 @@ type GetProviderSchema_Response struct {
|
||||||
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"`
|
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"`
|
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"`
|
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"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -876,6 +942,13 @@ func (m *GetProviderSchema_Response) GetDiagnostics() []*Diagnostic {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *GetProviderSchema_Response) GetProviderMeta() *Schema {
|
||||||
|
if m != nil {
|
||||||
|
return m.ProviderMeta
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type PrepareProviderConfig struct {
|
type PrepareProviderConfig struct {
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
@ -1524,6 +1597,7 @@ type ReadResource_Request struct {
|
||||||
TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"`
|
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"`
|
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"`
|
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"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -1575,6 +1649,13 @@ func (m *ReadResource_Request) GetPrivate() []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ReadResource_Request) GetProviderMeta() *DynamicValue {
|
||||||
|
if m != nil {
|
||||||
|
return m.ProviderMeta
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type ReadResource_Response struct {
|
type ReadResource_Response struct {
|
||||||
NewState *DynamicValue `protobuf:"bytes,1,opt,name=new_state,json=newState,proto3" json:"new_state,omitempty"`
|
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"`
|
Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"`
|
||||||
|
@ -1667,6 +1748,7 @@ type PlanResourceChange_Request struct {
|
||||||
ProposedNewState *DynamicValue `protobuf:"bytes,3,opt,name=proposed_new_state,json=proposedNewState,proto3" json:"proposed_new_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"`
|
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"`
|
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"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -1732,6 +1814,13 @@ func (m *PlanResourceChange_Request) GetPriorPrivate() []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *PlanResourceChange_Request) GetProviderMeta() *DynamicValue {
|
||||||
|
if m != nil {
|
||||||
|
return m.ProviderMeta
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type PlanResourceChange_Response struct {
|
type PlanResourceChange_Response struct {
|
||||||
PlannedState *DynamicValue `protobuf:"bytes,1,opt,name=planned_state,json=plannedState,proto3" json:"planned_state,omitempty"`
|
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"`
|
RequiresReplace []*AttributePath `protobuf:"bytes,2,rep,name=requires_replace,json=requiresReplace,proto3" json:"requires_replace,omitempty"`
|
||||||
|
@ -1851,6 +1940,7 @@ type ApplyResourceChange_Request struct {
|
||||||
PlannedState *DynamicValue `protobuf:"bytes,3,opt,name=planned_state,json=plannedState,proto3" json:"planned_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"`
|
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"`
|
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"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -1916,6 +2006,13 @@ func (m *ApplyResourceChange_Request) GetPlannedPrivate() []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ApplyResourceChange_Request) GetProviderMeta() *DynamicValue {
|
||||||
|
if m != nil {
|
||||||
|
return m.ProviderMeta
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type ApplyResourceChange_Response struct {
|
type ApplyResourceChange_Response struct {
|
||||||
NewState *DynamicValue `protobuf:"bytes,1,opt,name=new_state,json=newState,proto3" json:"new_state,omitempty"`
|
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"`
|
Private []byte `protobuf:"bytes,2,opt,name=private,proto3" json:"private,omitempty"`
|
||||||
|
@ -2204,6 +2301,7 @@ var xxx_messageInfo_ReadDataSource proto.InternalMessageInfo
|
||||||
type ReadDataSource_Request struct {
|
type ReadDataSource_Request struct {
|
||||||
TypeName string `protobuf:"bytes,1,opt,name=type_name,json=typeName,proto3" json:"type_name,omitempty"`
|
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"`
|
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"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -2248,6 +2346,13 @@ func (m *ReadDataSource_Request) GetConfig() *DynamicValue {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ReadDataSource_Request) GetProviderMeta() *DynamicValue {
|
||||||
|
if m != nil {
|
||||||
|
return m.ProviderMeta
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type ReadDataSource_Response struct {
|
type ReadDataSource_Response struct {
|
||||||
State *DynamicValue `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"`
|
State *DynamicValue `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"`
|
||||||
Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"`
|
Diagnostics []*Diagnostic `protobuf:"bytes,2,rep,name=diagnostics,proto3" json:"diagnostics,omitempty"`
|
||||||
|
@ -2639,6 +2744,7 @@ func (m *ProvisionResource_Response) GetDiagnostics() []*Diagnostic {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
proto.RegisterEnum("tfplugin5.StringKind", StringKind_name, StringKind_value)
|
||||||
proto.RegisterEnum("tfplugin5.Diagnostic_Severity", Diagnostic_Severity_name, Diagnostic_Severity_value)
|
proto.RegisterEnum("tfplugin5.Diagnostic_Severity", Diagnostic_Severity_name, Diagnostic_Severity_value)
|
||||||
proto.RegisterEnum("tfplugin5.Schema_NestedBlock_NestingMode", Schema_NestedBlock_NestingMode_name, Schema_NestedBlock_NestingMode_value)
|
proto.RegisterEnum("tfplugin5.Schema_NestedBlock_NestingMode", Schema_NestedBlock_NestingMode_name, Schema_NestedBlock_NestingMode_value)
|
||||||
proto.RegisterType((*DynamicValue)(nil), "tfplugin5.DynamicValue")
|
proto.RegisterType((*DynamicValue)(nil), "tfplugin5.DynamicValue")
|
||||||
|
@ -2704,125 +2810,133 @@ func init() {
|
||||||
func init() { proto.RegisterFile("tfplugin5.proto", fileDescriptor_17ae6090ff270234) }
|
func init() { proto.RegisterFile("tfplugin5.proto", fileDescriptor_17ae6090ff270234) }
|
||||||
|
|
||||||
var fileDescriptor_17ae6090ff270234 = []byte{
|
var fileDescriptor_17ae6090ff270234 = []byte{
|
||||||
// 1880 bytes of a gzipped FileDescriptorProto
|
// 2010 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xcb, 0x6f, 0x23, 0x49,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xcd, 0x6f, 0x23, 0x49,
|
||||||
0x19, 0x9f, 0xf6, 0x23, 0xb1, 0x3f, 0xe7, 0xe1, 0xd4, 0xcc, 0x0e, 0xa6, 0x77, 0x17, 0x82, 0x79,
|
0x15, 0x9f, 0x6e, 0xdb, 0x89, 0xfd, 0xec, 0x49, 0x3a, 0x35, 0x1f, 0x98, 0xde, 0x0f, 0x82, 0x61,
|
||||||
0x24, 0xab, 0xdd, 0xf1, 0xac, 0x32, 0xb0, 0xbb, 0x84, 0xd1, 0x8a, 0x6c, 0x26, 0x64, 0x22, 0x66,
|
0x49, 0x96, 0xdd, 0xf1, 0xac, 0x32, 0x30, 0xbb, 0x84, 0xd1, 0x6a, 0xb3, 0x49, 0xc8, 0x44, 0x33,
|
||||||
0xb2, 0xa1, 0x3c, 0x0f, 0x24, 0xa4, 0xb5, 0x6a, 0xdc, 0x15, 0x4f, 0x33, 0x76, 0x77, 0x6f, 0x75,
|
0xf1, 0x84, 0xf2, 0xcc, 0x04, 0x09, 0x69, 0xad, 0x1a, 0x77, 0xc5, 0xd3, 0xc4, 0xee, 0xee, 0xad,
|
||||||
0x39, 0x89, 0x85, 0xc4, 0x05, 0xc1, 0x19, 0x09, 0xf1, 0x90, 0x78, 0x5c, 0x40, 0xe2, 0x1f, 0xe0,
|
0x2e, 0x67, 0x62, 0x71, 0x44, 0x70, 0x46, 0xa0, 0x85, 0x03, 0x70, 0x81, 0x03, 0xe2, 0xc4, 0x0d,
|
||||||
0x00, 0xdc, 0x38, 0xf1, 0x0f, 0x70, 0x03, 0x4e, 0x08, 0x6e, 0x9c, 0xe1, 0x82, 0x84, 0xea, 0xd5,
|
0xf1, 0x75, 0xe1, 0xce, 0x81, 0x3b, 0xdc, 0x56, 0x1c, 0xb9, 0xf0, 0x17, 0xa0, 0xaa, 0xae, 0xee,
|
||||||
0x5d, 0xb6, 0xdb, 0x4e, 0x4f, 0xb2, 0x23, 0xc4, 0xad, 0xab, 0xbe, 0x5f, 0x7d, 0xdf, 0x57, 0xdf,
|
0x2e, 0xdb, 0xed, 0xa4, 0x93, 0xec, 0x0a, 0xed, 0xad, 0xeb, 0xbd, 0x5f, 0xbd, 0xf7, 0xea, 0xbd,
|
||||||
0xab, 0xbe, 0xcf, 0x86, 0x55, 0x7e, 0x1c, 0xf5, 0x87, 0x3d, 0x3f, 0xf8, 0x42, 0x2b, 0x62, 0x21,
|
0x5f, 0xbd, 0xaa, 0xb2, 0x61, 0x91, 0x1f, 0x06, 0xfd, 0x61, 0xcf, 0xf5, 0xbe, 0xde, 0x0c, 0x98,
|
||||||
0x0f, 0x51, 0x35, 0xd9, 0x68, 0xde, 0x86, 0xa5, 0x3b, 0xa3, 0x80, 0x0c, 0xfc, 0xee, 0x23, 0xd2,
|
0xcf, 0x7d, 0x54, 0x49, 0x04, 0x8d, 0x7b, 0x50, 0xdb, 0x1a, 0x79, 0x64, 0xe0, 0x76, 0x9f, 0x92,
|
||||||
0x1f, 0x52, 0xd4, 0x80, 0xc5, 0x41, 0xdc, 0x8b, 0x48, 0xf7, 0x59, 0xc3, 0x59, 0x77, 0x36, 0x97,
|
0xfe, 0x90, 0xa2, 0x3a, 0xcc, 0x0f, 0xc2, 0x5e, 0x40, 0xba, 0x47, 0x75, 0x63, 0xd9, 0x58, 0xad,
|
||||||
0xb0, 0x59, 0x22, 0x04, 0xa5, 0x6f, 0xc6, 0x61, 0xd0, 0x28, 0xc8, 0x6d, 0xf9, 0xdd, 0xfc, 0x9b,
|
0xe1, 0x78, 0x88, 0x10, 0x14, 0xbf, 0x17, 0xfa, 0x5e, 0xdd, 0x94, 0x62, 0xf9, 0xdd, 0xf8, 0xd8,
|
||||||
0x03, 0x70, 0xc7, 0x27, 0xbd, 0x20, 0x8c, 0xb9, 0xdf, 0x45, 0xdb, 0x50, 0x89, 0xe9, 0x09, 0x65,
|
0x00, 0xd8, 0x72, 0x49, 0xcf, 0xf3, 0x43, 0xee, 0x76, 0xd1, 0x3a, 0x94, 0x43, 0x7a, 0x4c, 0x99,
|
||||||
0x3e, 0x1f, 0xc9, 0xd3, 0x2b, 0x5b, 0x9f, 0x68, 0xa5, 0xb2, 0x53, 0x60, 0xab, 0xad, 0x51, 0x38,
|
0xcb, 0x47, 0x72, 0xf6, 0xc2, 0xda, 0xab, 0xcd, 0xd4, 0x77, 0x0a, 0x6c, 0xb6, 0x15, 0x0a, 0x27,
|
||||||
0xc1, 0x0b, 0xc1, 0xf1, 0x70, 0x30, 0x20, 0x6c, 0x24, 0x25, 0x54, 0xb1, 0x59, 0xa2, 0xeb, 0xb0,
|
0x78, 0xe1, 0x38, 0x1c, 0x0e, 0x06, 0x84, 0x8d, 0xa4, 0x87, 0x0a, 0x8e, 0x87, 0xe8, 0x26, 0xcc,
|
||||||
0xe0, 0x51, 0x4e, 0xfc, 0x7e, 0xa3, 0x28, 0x09, 0x7a, 0x85, 0xde, 0x82, 0x2a, 0xe1, 0x9c, 0xf9,
|
0x39, 0x94, 0x13, 0xb7, 0x5f, 0x2f, 0x48, 0x85, 0x1a, 0xa1, 0xbb, 0x50, 0x21, 0x9c, 0x33, 0xf7,
|
||||||
0x4f, 0x86, 0x9c, 0x36, 0x4a, 0xeb, 0xce, 0x66, 0x6d, 0xab, 0x61, 0x89, 0xdb, 0x31, 0xb4, 0x23,
|
0xd9, 0x90, 0xd3, 0x7a, 0x71, 0xd9, 0x58, 0xad, 0xae, 0xd5, 0x35, 0x77, 0x1b, 0xb1, 0x6e, 0x9f,
|
||||||
0xc2, 0x9f, 0xe2, 0x14, 0xda, 0xbc, 0x09, 0x15, 0x23, 0x1f, 0xd5, 0x60, 0xf1, 0xe0, 0xf0, 0xd1,
|
0xf0, 0xe7, 0x38, 0x85, 0x36, 0x6e, 0x43, 0x39, 0xf6, 0x8f, 0xaa, 0x30, 0xbf, 0xdb, 0x7a, 0xba,
|
||||||
0xce, 0xbd, 0x83, 0x3b, 0xf5, 0x2b, 0xa8, 0x0a, 0xe5, 0x3d, 0x8c, 0xdf, 0xc7, 0x75, 0x47, 0xec,
|
0xf1, 0x70, 0x77, 0xcb, 0xba, 0x82, 0x2a, 0x50, 0xda, 0xc6, 0xf8, 0x11, 0xb6, 0x0c, 0x21, 0x3f,
|
||||||
0x3f, 0xde, 0xc1, 0x87, 0x07, 0x87, 0xfb, 0xf5, 0x42, 0xf3, 0x2f, 0x0e, 0x2c, 0x8f, 0x71, 0x43,
|
0xd8, 0xc0, 0xad, 0xdd, 0xd6, 0x8e, 0x65, 0x36, 0xfe, 0x65, 0xc0, 0xd5, 0x31, 0x6b, 0xe8, 0x0e,
|
||||||
0xb7, 0xa0, 0x1c, 0x73, 0x1a, 0xc5, 0x0d, 0x67, 0xbd, 0xb8, 0x59, 0xdb, 0x7a, 0x75, 0x96, 0xd8,
|
0x94, 0x42, 0x4e, 0x83, 0xb0, 0x6e, 0x2c, 0x17, 0x56, 0xab, 0x6b, 0xaf, 0xcc, 0x72, 0xdb, 0x6c,
|
||||||
0x56, 0x9b, 0xd3, 0x08, 0x2b, 0xac, 0xfb, 0x43, 0x07, 0x4a, 0x62, 0x8d, 0x36, 0x60, 0x25, 0xd1,
|
0x73, 0x1a, 0xe0, 0x08, 0x6b, 0x7f, 0x64, 0x40, 0x51, 0x8c, 0xd1, 0x0a, 0x2c, 0x24, 0xd1, 0x74,
|
||||||
0xa6, 0x13, 0x90, 0x01, 0x95, 0xc6, 0xaa, 0xde, 0xbd, 0x82, 0x97, 0x93, 0xfd, 0x43, 0x32, 0xa0,
|
0x3c, 0x32, 0xa0, 0x32, 0x59, 0x95, 0xfb, 0x57, 0xf0, 0xd5, 0x44, 0xde, 0x22, 0x03, 0x8a, 0x9a,
|
||||||
0xa8, 0x05, 0x88, 0xf6, 0xe9, 0x80, 0x06, 0xbc, 0xf3, 0x8c, 0x8e, 0x3a, 0x31, 0x67, 0x7e, 0xd0,
|
0x80, 0x68, 0x9f, 0x0e, 0xa8, 0xc7, 0x3b, 0x47, 0x74, 0xd4, 0x09, 0x39, 0x73, 0xbd, 0x5e, 0x94,
|
||||||
0x53, 0xe6, 0xb9, 0x7b, 0x05, 0xd7, 0x35, 0xed, 0xab, 0x74, 0xd4, 0x96, 0x14, 0xb4, 0x09, 0xab,
|
0x9e, 0xfb, 0x57, 0xb0, 0xa5, 0x74, 0x0f, 0xe8, 0xa8, 0x2d, 0x35, 0x68, 0x15, 0x16, 0x75, 0xbc,
|
||||||
0x36, 0xde, 0x0f, 0xb8, 0x34, 0x59, 0x51, 0x70, 0x4e, 0xc1, 0x07, 0x01, 0x7f, 0x0f, 0x84, 0xa7,
|
0xeb, 0x71, 0x99, 0xb2, 0x82, 0xb0, 0x9c, 0x82, 0x77, 0x3d, 0xfe, 0x3e, 0x88, 0x4a, 0xf5, 0x69,
|
||||||
0xfa, 0xb4, 0xcb, 0x43, 0xd6, 0xbc, 0x25, 0xd4, 0x0a, 0x23, 0xb7, 0x0a, 0x8b, 0x98, 0x7e, 0x38,
|
0x97, 0xfb, 0xac, 0x71, 0x47, 0x84, 0xe5, 0x07, 0x76, 0x05, 0xe6, 0x31, 0xfd, 0x70, 0x48, 0x43,
|
||||||
0xa4, 0x31, 0x77, 0xd7, 0xa1, 0x82, 0x69, 0x1c, 0x85, 0x41, 0x4c, 0xd1, 0x35, 0x28, 0xef, 0x31,
|
0x6e, 0x2f, 0x43, 0x19, 0xd3, 0x30, 0xf0, 0xbd, 0x90, 0xa2, 0xeb, 0x50, 0xda, 0x66, 0xcc, 0x67,
|
||||||
0x16, 0x32, 0xa5, 0x24, 0x56, 0x8b, 0xe6, 0x8f, 0x1c, 0xa8, 0x60, 0x72, 0xda, 0xe6, 0x84, 0xd3,
|
0x51, 0x90, 0x38, 0x1a, 0x34, 0x7e, 0x66, 0x40, 0x19, 0x93, 0x17, 0x6d, 0x4e, 0x38, 0x4d, 0xa8,
|
||||||
0x24, 0x34, 0x9c, 0x34, 0x34, 0xd0, 0x36, 0x2c, 0x1e, 0xf7, 0x09, 0x1f, 0x90, 0xa8, 0x51, 0x90,
|
0x61, 0xa4, 0xd4, 0x40, 0xeb, 0x30, 0x7f, 0xd8, 0x27, 0x7c, 0x40, 0x82, 0xba, 0x29, 0x93, 0xb4,
|
||||||
0x46, 0x5a, 0xb7, 0x8c, 0x64, 0x4e, 0xb6, 0xbe, 0xa2, 0x20, 0x7b, 0x01, 0x67, 0x23, 0x6c, 0x0e,
|
0xac, 0x25, 0x29, 0x9e, 0xd9, 0xfc, 0x56, 0x04, 0xd9, 0xf6, 0x38, 0x1b, 0xe1, 0x78, 0x82, 0xbd,
|
||||||
0xb8, 0xdb, 0xb0, 0x64, 0x13, 0x50, 0x1d, 0x8a, 0xcf, 0xe8, 0x48, 0x2b, 0x20, 0x3e, 0x85, 0x52,
|
0x0e, 0x35, 0x5d, 0x81, 0x2c, 0x28, 0x1c, 0xd1, 0x91, 0x0a, 0x40, 0x7c, 0x8a, 0xa0, 0x8e, 0x05,
|
||||||
0x27, 0x22, 0x5e, 0x75, 0xac, 0xa8, 0xc5, 0x76, 0xe1, 0x1d, 0xa7, 0xf9, 0x8f, 0x32, 0x2c, 0xb4,
|
0x5f, 0x15, 0x57, 0xa2, 0xc1, 0xba, 0xf9, 0x8e, 0xd1, 0xf8, 0xfb, 0x3c, 0xcc, 0xb5, 0xbb, 0xcf,
|
||||||
0xbb, 0x4f, 0xe9, 0x80, 0x88, 0x90, 0x3a, 0xa1, 0x2c, 0xf6, 0xb5, 0x66, 0x45, 0x6c, 0x96, 0xe8,
|
0xe9, 0x80, 0x08, 0x4a, 0x1d, 0x53, 0x16, 0xba, 0x2a, 0xb2, 0x02, 0x8e, 0x87, 0xe8, 0x16, 0x94,
|
||||||
0x06, 0x94, 0x9f, 0xf4, 0xc3, 0xee, 0x33, 0x79, 0xbc, 0xb6, 0xf5, 0x31, 0x4b, 0x35, 0x75, 0xb6,
|
0x9e, 0xf5, 0xfd, 0xee, 0x91, 0x9c, 0x5e, 0x5d, 0xfb, 0x9c, 0x16, 0x5a, 0x34, 0xb7, 0xf9, 0xbe,
|
||||||
0xf5, 0x9e, 0x20, 0x63, 0x85, 0x72, 0x7f, 0xe1, 0x40, 0x59, 0x6e, 0xcc, 0x61, 0xf9, 0x25, 0x80,
|
0x50, 0xe3, 0x08, 0x65, 0xff, 0xda, 0x84, 0x92, 0x14, 0x9c, 0x62, 0xf2, 0x9b, 0x00, 0x49, 0xf1,
|
||||||
0xc4, 0x79, 0xb1, 0xbe, 0xf2, 0xcb, 0xd3, 0x7c, 0x93, 0xf0, 0xc0, 0x16, 0x1c, 0xbd, 0x0b, 0x35,
|
0x42, 0xb5, 0xe4, 0x97, 0xa6, 0xed, 0x26, 0xf4, 0xc0, 0x1a, 0x1c, 0xbd, 0x0b, 0x55, 0xe9, 0xa9,
|
||||||
0x29, 0xa9, 0xc3, 0x47, 0x11, 0x8d, 0x1b, 0xc5, 0xa9, 0xa8, 0xd2, 0xa7, 0x0f, 0x69, 0xcc, 0xa9,
|
0xc3, 0x47, 0x01, 0x0d, 0xeb, 0x85, 0x29, 0x56, 0xa9, 0xd9, 0x2d, 0x1a, 0x72, 0xea, 0x44, 0xb1,
|
||||||
0xa7, 0x74, 0x03, 0x79, 0xe2, 0x81, 0x38, 0xe0, 0xfe, 0xd1, 0x81, 0x6a, 0xc2, 0x59, 0xb8, 0x23,
|
0x81, 0x9c, 0xf1, 0x58, 0x4c, 0x40, 0xcb, 0x50, 0x75, 0x68, 0xd8, 0x65, 0x6e, 0xc0, 0x45, 0x68,
|
||||||
0x8d, 0x2a, 0x2c, 0xbf, 0xc5, 0x9e, 0xe0, 0x6d, 0xb2, 0x57, 0x7c, 0xa3, 0x75, 0xa8, 0x79, 0x34,
|
0x45, 0x99, 0x14, 0x5d, 0x84, 0xde, 0x03, 0x4b, 0x1b, 0x76, 0x8e, 0x5c, 0xcf, 0xa9, 0x97, 0xe4,
|
||||||
0xee, 0x32, 0x3f, 0xe2, 0xe2, 0x42, 0x2a, 0xbb, 0xec, 0x2d, 0xe4, 0x42, 0x85, 0xd1, 0x0f, 0x87,
|
0x16, 0xbd, 0xa1, 0xbb, 0x91, 0x3c, 0x7a, 0xe0, 0x7a, 0x0e, 0x5e, 0xd4, 0xe0, 0x42, 0x80, 0x5e,
|
||||||
0x3e, 0xa3, 0x9e, 0xcc, 0xb0, 0x0a, 0x4e, 0xd6, 0x82, 0x16, 0x4a, 0x14, 0xe9, 0x37, 0xca, 0x8a,
|
0x05, 0x70, 0x68, 0xc0, 0x68, 0x97, 0x70, 0xea, 0xd4, 0xe7, 0x96, 0x8d, 0xd5, 0x32, 0xd6, 0x24,
|
||||||
0x66, 0xd6, 0x82, 0xd6, 0x0d, 0x07, 0xd1, 0x90, 0x53, 0xaf, 0xb1, 0xa0, 0x68, 0x66, 0x8d, 0x5e,
|
0xf6, 0xef, 0x4c, 0xa8, 0x24, 0xab, 0x13, 0x94, 0x48, 0x99, 0x8d, 0xe5, 0xb7, 0x90, 0x89, 0xf5,
|
||||||
0x81, 0x6a, 0x4c, 0x83, 0xd8, 0xe7, 0xfe, 0x09, 0x6d, 0x2c, 0x4a, 0x62, 0xba, 0xe1, 0xfe, 0xba,
|
0xc5, 0x1d, 0x44, 0x7c, 0x4f, 0x46, 0x5e, 0x98, 0x8e, 0xdc, 0x86, 0x32, 0xa3, 0x1f, 0x0e, 0x5d,
|
||||||
0x00, 0x35, 0xeb, 0x96, 0xe8, 0x65, 0xa8, 0x0a, 0x5d, 0xad, 0x34, 0xc1, 0x15, 0xb1, 0x21, 0xf3,
|
0x46, 0x1d, 0xb9, 0xb0, 0x32, 0x4e, 0xc6, 0x42, 0xe7, 0x4b, 0x14, 0xe9, 0xcb, 0xd5, 0x94, 0x71,
|
||||||
0xe3, 0xf9, 0xdc, 0x88, 0x76, 0x61, 0x31, 0xa0, 0x31, 0x17, 0x39, 0x54, 0x94, 0xd5, 0xe9, 0xb5,
|
0x32, 0x16, 0xba, 0xae, 0x3f, 0x08, 0x86, 0x69, 0xb4, 0xc9, 0x18, 0xbd, 0x0c, 0x95, 0x90, 0x7a,
|
||||||
0xb9, 0x16, 0x96, 0xdf, 0x7e, 0xd0, 0xbb, 0x1f, 0x7a, 0x14, 0x9b, 0x93, 0x42, 0xa1, 0x81, 0x1f,
|
0xa1, 0xcb, 0xdd, 0x63, 0x5a, 0x9f, 0x97, 0xca, 0x54, 0x90, 0x99, 0xab, 0xf2, 0x25, 0x72, 0x55,
|
||||||
0x74, 0x7c, 0x4e, 0x07, 0xb1, 0xb4, 0x49, 0x11, 0x57, 0x06, 0x7e, 0x70, 0x20, 0xd6, 0x92, 0x48,
|
0x99, 0xca, 0xd5, 0x6f, 0x4d, 0xa8, 0x6a, 0xb5, 0x44, 0x2f, 0x41, 0x45, 0x64, 0x43, 0x6b, 0x06,
|
||||||
0xce, 0x34, 0xb1, 0xac, 0x89, 0xe4, 0x4c, 0x12, 0x9b, 0xf7, 0xd5, 0xcd, 0x34, 0xc7, 0xf1, 0xd2,
|
0xb8, 0x2c, 0x04, 0xb2, 0x0b, 0x9c, 0x8f, 0xac, 0x68, 0x13, 0xe6, 0x3d, 0x1a, 0x72, 0xd1, 0x29,
|
||||||
0x03, 0xb0, 0xd0, 0x3e, 0x38, 0xdc, 0xbf, 0xb7, 0x57, 0x77, 0x50, 0x05, 0x4a, 0xf7, 0x0e, 0xda,
|
0x0a, 0x32, 0xe8, 0xd7, 0x4f, 0xe5, 0x91, 0xfc, 0x76, 0xbd, 0xde, 0x9e, 0xef, 0x50, 0x1c, 0xcf,
|
||||||
0x0f, 0xea, 0x05, 0xb4, 0x08, 0xc5, 0xf6, 0xde, 0x83, 0x7a, 0x51, 0x7c, 0xdc, 0xdf, 0x39, 0xaa,
|
0x14, 0x01, 0x0d, 0x5c, 0xaf, 0xe3, 0x72, 0x3a, 0x08, 0x65, 0xd6, 0x0b, 0xb8, 0x3c, 0x70, 0xbd,
|
||||||
0x97, 0x44, 0x89, 0xda, 0xc7, 0xef, 0x3f, 0x3c, 0xaa, 0x97, 0x9b, 0x3f, 0x29, 0xc1, 0xda, 0x3e,
|
0x5d, 0x31, 0x96, 0x4a, 0x72, 0xa2, 0x94, 0x25, 0xa5, 0x24, 0x27, 0x52, 0xd9, 0xd8, 0x8b, 0x56,
|
||||||
0xe5, 0x47, 0x2c, 0x3c, 0xf1, 0x3d, 0xca, 0x94, 0xfe, 0x76, 0x12, 0xff, 0xab, 0x68, 0x65, 0xf1,
|
0xa6, 0x2c, 0x8e, 0x37, 0x58, 0x80, 0xb9, 0xf6, 0x6e, 0x6b, 0xe7, 0xe1, 0xb6, 0x65, 0xa0, 0x32,
|
||||||
0x0d, 0xa8, 0x44, 0x1a, 0x29, 0xcd, 0x58, 0xdb, 0x5a, 0x9b, 0xba, 0x3c, 0x4e, 0x20, 0x88, 0x42,
|
0x14, 0x1f, 0xee, 0xb6, 0x1f, 0x5b, 0x26, 0x9a, 0x87, 0x42, 0x7b, 0xfb, 0xb1, 0x55, 0x10, 0x1f,
|
||||||
0x9d, 0xd1, 0x38, 0x1c, 0xb2, 0x2e, 0xed, 0xc4, 0x92, 0x68, 0x62, 0x7a, 0xdb, 0x3a, 0x36, 0x25,
|
0x7b, 0x1b, 0xfb, 0x56, 0x51, 0x34, 0xe2, 0x1d, 0xfc, 0xe8, 0xc9, 0xbe, 0x55, 0x6a, 0xfc, 0xa3,
|
||||||
0xbe, 0x65, 0xe4, 0x89, 0x0f, 0x79, 0x5a, 0xed, 0xc7, 0x2a, 0xc1, 0x57, 0xd9, 0xf8, 0x2e, 0xea,
|
0x08, 0x4b, 0x3b, 0x94, 0xef, 0x33, 0xff, 0xd8, 0x75, 0x28, 0x8b, 0xe2, 0xd7, 0x5b, 0xd5, 0xef,
|
||||||
0xc3, 0x55, 0x8f, 0x70, 0xd2, 0x99, 0x90, 0xa4, 0xe2, 0xff, 0x76, 0x3e, 0x49, 0x77, 0x08, 0x27,
|
0x8b, 0x5a, 0xaf, 0xba, 0x05, 0xe5, 0x40, 0x21, 0x65, 0x1a, 0xab, 0x6b, 0x4b, 0x53, 0x8b, 0xc7,
|
||||||
0xed, 0x69, 0x59, 0x6b, 0xde, 0xe4, 0x3e, 0x7a, 0x1b, 0x6a, 0x5e, 0xf2, 0x06, 0x09, 0xe7, 0x09,
|
0x09, 0x04, 0x51, 0xb0, 0x18, 0x0d, 0xfd, 0x21, 0xeb, 0xd2, 0x4e, 0x28, 0x95, 0xf1, 0xce, 0x5d,
|
||||||
0x29, 0x2f, 0x65, 0xbe, 0x50, 0xd8, 0x46, 0xba, 0x0f, 0xe1, 0x5a, 0xd6, 0x7d, 0x32, 0xea, 0xd2,
|
0xd7, 0xa6, 0x4d, 0xb9, 0x6f, 0xc6, 0xfe, 0xc4, 0x87, 0x9c, 0x1d, 0xc9, 0xc3, 0xa8, 0x8d, 0x2d,
|
||||||
0x86, 0x5d, 0x97, 0x32, 0x6d, 0x9c, 0x96, 0x2a, 0xf7, 0x31, 0x5c, 0xcf, 0x56, 0xfe, 0x92, 0x8c,
|
0xb2, 0x71, 0x29, 0xea, 0xc3, 0x35, 0x87, 0x70, 0xd2, 0x99, 0xf0, 0x14, 0xed, 0xf2, 0x7b, 0xf9,
|
||||||
0x9b, 0x7f, 0x76, 0xe0, 0xa5, 0x23, 0x46, 0x23, 0xc2, 0xa8, 0xb1, 0xda, 0x6e, 0x18, 0x1c, 0xfb,
|
0x3c, 0x6d, 0x11, 0x4e, 0xda, 0xd3, 0xbe, 0x96, 0x9c, 0x49, 0x39, 0x7a, 0x1b, 0xaa, 0x4e, 0x72,
|
||||||
0x3d, 0x77, 0x3b, 0x09, 0x0f, 0x74, 0x13, 0x16, 0xba, 0x72, 0x53, 0xc7, 0x83, 0x9d, 0x3d, 0x76,
|
0xd2, 0x8a, 0xe2, 0x09, 0x2f, 0x37, 0x32, 0xcf, 0x61, 0xac, 0x23, 0xd1, 0x5d, 0xb8, 0x1a, 0x67,
|
||||||
0x4b, 0x80, 0x35, 0xcc, 0xfd, 0xae, 0x63, 0xc5, 0xd3, 0x97, 0x61, 0x35, 0x52, 0x12, 0xbc, 0x4e,
|
0xa6, 0x33, 0xa0, 0x9c, 0xc8, 0xd2, 0x66, 0x66, 0xb0, 0x16, 0xe3, 0xf6, 0x28, 0x27, 0xf6, 0x13,
|
||||||
0x3e, 0x36, 0x2b, 0x06, 0xaf, 0x54, 0x99, 0xf4, 0x46, 0x21, 0xaf, 0x37, 0x9a, 0xdf, 0x2f, 0xc0,
|
0xb8, 0x9e, 0x95, 0x87, 0x8c, 0xae, 0xbd, 0xa2, 0x77, 0xed, 0x4c, 0xcb, 0x69, 0x23, 0xb7, 0x0f,
|
||||||
0xb5, 0x87, 0x51, 0x8f, 0x11, 0x8f, 0x26, 0x5e, 0x11, 0x8f, 0x89, 0xcb, 0xd2, 0xcb, 0xcd, 0x2d,
|
0xe0, 0x66, 0xf6, 0xa2, 0x2f, 0x69, 0xb8, 0xf1, 0x4f, 0x03, 0x6e, 0xec, 0x33, 0x1a, 0x10, 0x46,
|
||||||
0x1b, 0x56, 0x11, 0x2f, 0x8c, 0x17, 0xf1, 0x37, 0xa1, 0xca, 0xc8, 0x69, 0x27, 0x16, 0xec, 0x64,
|
0xe3, 0x6c, 0x6f, 0xfa, 0xde, 0xa1, 0xdb, 0xb3, 0xd7, 0x13, 0x5a, 0xa1, 0xdb, 0x30, 0xd7, 0x95,
|
||||||
0x8d, 0xa8, 0x6d, 0x5d, 0xcd, 0x78, 0xb6, 0x70, 0x85, 0xe9, 0x2f, 0xf7, 0x3b, 0xb6, 0x51, 0xde,
|
0x42, 0xc5, 0x23, 0x7d, 0xd7, 0xe9, 0x17, 0x26, 0xac, 0x60, 0xf6, 0x0f, 0x0d, 0x8d, 0x87, 0xef,
|
||||||
0x85, 0x95, 0xa1, 0x52, 0xcc, 0xd3, 0x3c, 0xce, 0xb1, 0xc9, 0xb2, 0x81, 0xab, 0x77, 0xf4, 0xc2,
|
0xc1, 0x62, 0x10, 0x79, 0x70, 0x3a, 0xf9, 0xcc, 0x2c, 0xc4, 0xf8, 0x28, 0x94, 0xc9, 0x2a, 0x9a,
|
||||||
0x26, 0xf9, 0xbd, 0x03, 0xee, 0x23, 0xd2, 0xf7, 0x3d, 0xa1, 0x9c, 0xb6, 0x89, 0x78, 0x19, 0xb4,
|
0x79, 0xab, 0xd8, 0xf8, 0xb1, 0x09, 0xd7, 0x9f, 0x04, 0x3d, 0x46, 0x1c, 0x9a, 0x54, 0x45, 0x1c,
|
||||||
0xd7, 0x1f, 0xe7, 0x34, 0x4c, 0x1a, 0x12, 0x85, 0x7c, 0x21, 0xb1, 0x6b, 0x5d, 0x7e, 0x42, 0x79,
|
0xb5, 0x36, 0x4b, 0x17, 0x77, 0x6a, 0xbb, 0xd1, 0x8e, 0x38, 0x73, 0xfc, 0x88, 0x7b, 0x0b, 0x2a,
|
||||||
0x27, 0xb7, 0xf2, 0xbf, 0x75, 0xa0, 0x61, 0x94, 0x4f, 0xf3, 0xe1, 0xff, 0x42, 0xf5, 0xdf, 0x39,
|
0x8c, 0xbc, 0xe8, 0x84, 0xc2, 0x9c, 0xec, 0x2d, 0xd5, 0xb5, 0x6b, 0x19, 0x87, 0x3a, 0x2e, 0x33,
|
||||||
0x50, 0x55, 0x8a, 0x0e, 0x19, 0x75, 0x7b, 0xa9, 0xae, 0xaf, 0xc3, 0x1a, 0xa7, 0x8c, 0x91, 0xe3,
|
0xf5, 0x65, 0xff, 0x40, 0x4f, 0xca, 0xbb, 0xb0, 0x30, 0x8c, 0x02, 0x73, 0x94, 0x8d, 0x33, 0x72,
|
||||||
0x90, 0x0d, 0x3a, 0x76, 0xc7, 0x50, 0xc5, 0xf5, 0x84, 0xf0, 0x48, 0x47, 0xdd, 0xff, 0x46, 0xf7,
|
0x72, 0x35, 0x86, 0x47, 0xb7, 0x8c, 0x0b, 0xa7, 0xe4, 0xcf, 0x06, 0xd8, 0x4f, 0x49, 0xdf, 0x75,
|
||||||
0x5f, 0x15, 0x60, 0x09, 0x53, 0xe2, 0x99, 0x78, 0x71, 0xbf, 0x9d, 0xd3, 0xd4, 0xb7, 0x61, 0xb9,
|
0x44, 0x70, 0x2a, 0x27, 0xe2, 0xdc, 0x54, 0x55, 0x3f, 0xc8, 0x99, 0x98, 0x94, 0x12, 0x66, 0x3e,
|
||||||
0x3b, 0x64, 0x4c, 0x74, 0x99, 0x2a, 0xc8, 0xcf, 0xd1, 0x7a, 0x49, 0xa3, 0x55, 0x8c, 0x37, 0x60,
|
0x4a, 0x6c, 0x6a, 0x8b, 0x9f, 0x08, 0xde, 0xc8, 0x1d, 0xfc, 0x1f, 0x0d, 0xa8, 0xc7, 0xc1, 0xa7,
|
||||||
0x31, 0x62, 0xfe, 0x89, 0x49, 0xb0, 0x25, 0x6c, 0x96, 0xee, 0x0f, 0xec, 0x54, 0xfa, 0x3c, 0x54,
|
0xfb, 0xe1, 0x33, 0x11, 0xfa, 0x9f, 0x0c, 0xa8, 0x44, 0x81, 0x0e, 0x19, 0xb5, 0x7b, 0x69, 0xac,
|
||||||
0x03, 0x7a, 0x9a, 0x2f, 0x8b, 0x2a, 0x01, 0x3d, 0xbd, 0x5c, 0x02, 0xcd, 0xd6, 0xaa, 0xf9, 0x9b,
|
0x6f, 0xc0, 0x12, 0xa7, 0x8c, 0x91, 0x43, 0x9f, 0x0d, 0x3a, 0xfa, 0x7d, 0xaa, 0x82, 0xad, 0x44,
|
||||||
0x12, 0xa0, 0xa3, 0x3e, 0x09, 0x8c, 0x99, 0x76, 0x9f, 0x92, 0xa0, 0x47, 0xdd, 0xff, 0x38, 0x39,
|
0xf1, 0x54, 0xb1, 0xee, 0xff, 0x13, 0xfb, 0xc7, 0x26, 0xd4, 0x30, 0x25, 0x4e, 0xcc, 0x17, 0xfb,
|
||||||
0xad, 0xf5, 0x0e, 0xd4, 0x22, 0xe6, 0x87, 0x2c, 0x9f, 0xad, 0x40, 0x62, 0xd5, 0x65, 0xf6, 0x00,
|
0xaf, 0x46, 0xce, 0x5c, 0xdf, 0x83, 0xab, 0xdd, 0x21, 0x63, 0xe2, 0x12, 0x1e, 0xb1, 0xfc, 0x8c,
|
||||||
0x45, 0x2c, 0x8c, 0xc2, 0x98, 0x7a, 0x9d, 0xd4, 0x16, 0xc5, 0xf9, 0x0c, 0xea, 0xe6, 0xc8, 0xa1,
|
0xb0, 0x6b, 0x0a, 0x1d, 0x91, 0xbc, 0x0e, 0xf3, 0x01, 0x73, 0x8f, 0xe3, 0x1d, 0x56, 0xc3, 0xf1,
|
||||||
0xb1, 0x49, 0x1a, 0x5d, 0xa5, 0x5c, 0xd1, 0x85, 0x3e, 0x0d, 0xcb, 0x4a, 0x63, 0x63, 0x91, 0xb2,
|
0x50, 0xd8, 0x1d, 0x6f, 0xcf, 0xc5, 0x33, 0xec, 0x8e, 0x35, 0xe9, 0x9f, 0xea, 0x3b, 0xf1, 0x6b,
|
||||||
0xb4, 0xc8, 0x92, 0xdc, 0x3c, 0xd2, 0xce, 0xfa, 0x79, 0xc1, 0x72, 0xd6, 0x6d, 0x58, 0x8e, 0xfa,
|
0x50, 0xf1, 0xe8, 0x8b, 0x7c, 0x9b, 0xb0, 0xec, 0xd1, 0x17, 0x97, 0xdb, 0x7f, 0xb3, 0xd7, 0xd4,
|
||||||
0x24, 0x08, 0xf2, 0x96, 0xbd, 0x25, 0x8d, 0x56, 0x0a, 0xee, 0x8a, 0x5e, 0x43, 0x36, 0x95, 0x71,
|
0xf8, 0x6f, 0x11, 0xd0, 0x7e, 0x9f, 0x78, 0x71, 0x96, 0x37, 0x9f, 0x13, 0xaf, 0x47, 0xed, 0xbf,
|
||||||
0x87, 0xd1, 0xa8, 0x4f, 0xba, 0x54, 0x7b, 0x6e, 0xf6, 0x38, 0xb7, 0x6a, 0x4e, 0x60, 0x75, 0x00,
|
0x98, 0x39, 0x73, 0xfd, 0x0e, 0x54, 0x03, 0xe6, 0xfa, 0x2c, 0x5f, 0xa6, 0x41, 0x62, 0xa3, 0xc5,
|
||||||
0x6d, 0xc0, 0xaa, 0x51, 0x61, 0xdc, 0x91, 0x2b, 0x7a, 0x5b, 0x2b, 0x7e, 0xe1, 0x26, 0x00, 0xbd,
|
0x6c, 0x03, 0x0a, 0x98, 0x1f, 0xf8, 0x21, 0x75, 0x3a, 0x69, 0x2e, 0x0a, 0xa7, 0x1b, 0xb0, 0xe2,
|
||||||
0x01, 0xa8, 0x4f, 0x7b, 0xa4, 0x3b, 0x92, 0x4d, 0x7a, 0x27, 0x1e, 0xc5, 0x9c, 0x0e, 0x74, 0xe7,
|
0x29, 0xad, 0x38, 0x27, 0x29, 0x39, 0x8b, 0xb9, 0xc8, 0x89, 0xbe, 0x24, 0xaa, 0x28, 0x22, 0x8e,
|
||||||
0x5b, 0x57, 0x14, 0x51, 0x72, 0xdb, 0x72, 0xbf, 0xf9, 0xa7, 0x22, 0x5c, 0xdd, 0x89, 0xa2, 0xfe,
|
0x33, 0x52, 0x92, 0x19, 0xa9, 0x49, 0xe1, 0xfe, 0xac, 0x52, 0xcf, 0x9d, 0xa7, 0xd4, 0xbf, 0x32,
|
||||||
0x68, 0x22, 0x6e, 0xfe, 0xfd, 0xe2, 0xe3, 0x66, 0xca, 0x1b, 0xc5, 0xe7, 0xf1, 0xc6, 0x73, 0x87,
|
0xb5, 0x52, 0x0b, 0x53, 0x7d, 0xe2, 0x79, 0x79, 0x7b, 0x6e, 0x4d, 0xa1, 0xa3, 0xe5, 0x6d, 0x8a,
|
||||||
0x4b, 0x86, 0xe5, 0xcb, 0x59, 0x96, 0x77, 0xff, 0x70, 0xf9, 0xfc, 0xb6, 0xd2, 0xb4, 0x30, 0x96,
|
0x0b, 0x92, 0xbc, 0x6b, 0x87, 0x1d, 0x46, 0x83, 0x3e, 0xe9, 0x52, 0x55, 0xf7, 0xd9, 0x2f, 0xed,
|
||||||
0xa6, 0x93, 0x6e, 0x2d, 0x5e, 0xd2, 0xad, 0xa5, 0x19, 0x6e, 0xfd, 0x67, 0x01, 0xae, 0x1e, 0x0c,
|
0xc5, 0x78, 0x06, 0x8e, 0x26, 0xa0, 0x15, 0x58, 0x8c, 0x43, 0x18, 0xa7, 0xc1, 0x82, 0x12, 0xc7,
|
||||||
0xa2, 0x90, 0xf1, 0xf1, 0xd6, 0xe3, 0xad, 0x9c, 0x5e, 0x5d, 0x81, 0x82, 0xef, 0xe9, 0xa1, 0xb5,
|
0xcb, 0xbe, 0xf0, 0xcd, 0xe5, 0x4d, 0x40, 0x7d, 0xda, 0x23, 0xdd, 0x91, 0x7c, 0x3f, 0x75, 0xc2,
|
||||||
0xe0, 0x7b, 0xee, 0x19, 0xd4, 0x15, 0x3b, 0x9a, 0xd4, 0xe1, 0x73, 0x47, 0x9e, 0x5c, 0x01, 0xa1,
|
0x51, 0xc8, 0xe9, 0x40, 0x3d, 0x08, 0xac, 0x48, 0x23, 0xfa, 0x7d, 0x5b, 0xca, 0x1b, 0x3f, 0x29,
|
||||||
0x50, 0x73, 0xaa, 0xed, 0x2f, 0x6d, 0x6f, 0x7c, 0x00, 0xc8, 0xd7, 0x6a, 0x74, 0x4c, 0x8f, 0x6e,
|
0xc2, 0xb5, 0x8d, 0x20, 0xe8, 0x8f, 0x26, 0x58, 0xf7, 0x87, 0x4f, 0x9f, 0x75, 0x53, 0xd5, 0x28,
|
||||||
0xde, 0x92, 0x9b, 0x96, 0x88, 0x8c, 0xab, 0xb7, 0x26, 0xf5, 0xc7, 0x6b, 0xfe, 0xc4, 0x4e, 0x7c,
|
0x9c, 0xa7, 0x1a, 0xe7, 0x26, 0x5b, 0x46, 0xe6, 0x4b, 0x99, 0x99, 0xbf, 0x1c, 0xe1, 0xfe, 0x76,
|
||||||
0xf1, 0xc6, 0xe6, 0xaf, 0x0e, 0xac, 0x88, 0x47, 0x2a, 0xed, 0x0b, 0x5e, 0x5c, 0x47, 0xc0, 0xc6,
|
0xf9, 0xde, 0xa2, 0xb5, 0x08, 0x73, 0xbc, 0xed, 0x4d, 0x90, 0xa2, 0x70, 0x49, 0x52, 0x14, 0x67,
|
||||||
0xc6, 0xa5, 0x72, 0xae, 0xd0, 0xd4, 0x66, 0xbe, 0xf0, 0xfd, 0x7e, 0xea, 0xc0, 0x35, 0x33, 0xdb,
|
0x90, 0xe2, 0x3f, 0x26, 0x5c, 0xdb, 0x1d, 0x04, 0x3e, 0xe3, 0xe3, 0xb7, 0xa6, 0xbb, 0x39, 0x39,
|
||||||
0x88, 0x5e, 0x20, 0x6b, 0x8e, 0x3b, 0xb3, 0xf4, 0xba, 0x25, 0xaa, 0x42, 0x82, 0x9d, 0x3d, 0xc9,
|
0xb1, 0x00, 0xa6, 0xeb, 0xa8, 0x5f, 0x23, 0x4c, 0xd7, 0xb1, 0x4f, 0xc0, 0x8a, 0xcc, 0xd1, 0xe4,
|
||||||
0xd9, 0xa8, 0x8b, 0x6b, 0xf7, 0x33, 0x07, 0x3e, 0x6e, 0x3a, 0x33, 0x4b, 0xc5, 0x8f, 0x60, 0x96,
|
0x08, 0x39, 0xf3, 0x95, 0x97, 0x8b, 0x4e, 0x11, 0x6a, 0x76, 0x4f, 0xb5, 0x7f, 0xa3, 0x57, 0xe3,
|
||||||
0xf8, 0x48, 0x3a, 0x98, 0xbf, 0x3b, 0xb0, 0x96, 0xa8, 0x95, 0xb4, 0x31, 0xf1, 0xc5, 0xd5, 0x42,
|
0x03, 0x40, 0xae, 0x0a, 0xa3, 0x13, 0x3f, 0x4b, 0xe2, 0x63, 0xf0, 0xb6, 0xe6, 0x22, 0x63, 0xe9,
|
||||||
0x6f, 0x03, 0x74, 0xc3, 0x20, 0xa0, 0x5d, 0x6e, 0x86, 0x83, 0x79, 0x35, 0x37, 0x85, 0xba, 0xdf,
|
0xcd, 0xc9, 0xf8, 0xf1, 0x92, 0x3b, 0x21, 0x09, 0x2f, 0x7e, 0x27, 0xfb, 0xa5, 0x09, 0x0b, 0xe2,
|
||||||
0xb0, 0xee, 0x73, 0x1d, 0x16, 0xc2, 0x21, 0x8f, 0x86, 0x5c, 0x87, 0xa4, 0x5e, 0x5d, 0xd8, 0x0d,
|
0x7c, 0x4d, 0xaf, 0x34, 0xf6, 0x47, 0xc6, 0xa7, 0x74, 0x9b, 0x99, 0xa6, 0x77, 0xe1, 0x3c, 0xf4,
|
||||||
0x5b, 0x3f, 0xae, 0x42, 0xc5, 0xcc, 0x71, 0xe8, 0xeb, 0x50, 0xdd, 0xa7, 0x5c, 0xff, 0xc2, 0xf5,
|
0x66, 0x63, 0x0f, 0xcc, 0x52, 0x2e, 0x66, 0xab, 0x2a, 0x5d, 0x38, 0x3d, 0xbf, 0x30, 0xe0, 0x7a,
|
||||||
0x99, 0x73, 0x46, 0x64, 0x15, 0x40, 0x9f, 0xcd, 0x35, 0x48, 0xa3, 0xfe, 0x8c, 0xa1, 0x11, 0x6d,
|
0xfc, 0x1a, 0x14, 0xb7, 0xa0, 0xac, 0x97, 0xef, 0x89, 0x16, 0xd7, 0x1d, 0xd1, 0x92, 0x12, 0xec,
|
||||||
0x5a, 0xe7, 0x33, 0x11, 0x89, 0xa4, 0xd7, 0x72, 0x20, 0xb5, 0xb4, 0x6f, 0xcd, 0x9b, 0x58, 0xd0,
|
0xec, 0xb7, 0xaf, 0x8e, 0xba, 0x44, 0xf1, 0x0c, 0xf8, 0x7c, 0x7c, 0x27, 0xd5, 0x42, 0xfc, 0x04,
|
||||||
0x0d, 0x8b, 0xd1, 0x6c, 0x58, 0x22, 0xb7, 0x95, 0x17, 0xae, 0x85, 0x0f, 0x67, 0x4f, 0x1c, 0xe8,
|
0x5e, 0x51, 0x9f, 0xc8, 0xdd, 0xed, 0xdf, 0x06, 0x2c, 0x25, 0x61, 0x25, 0x17, 0xb8, 0xf0, 0xe2,
|
||||||
0xf5, 0x0c, 0x5e, 0x93, 0xa0, 0x44, 0xf0, 0x1b, 0xf9, 0xc0, 0x5a, 0xac, 0x9f, 0x3d, 0xb8, 0xa2,
|
0x61, 0xa1, 0xb7, 0x01, 0xba, 0xbe, 0xe7, 0xd1, 0x2e, 0x8f, 0x9f, 0x45, 0xa7, 0x35, 0xfc, 0x14,
|
||||||
0x0d, 0x8b, 0x4b, 0x16, 0x20, 0x11, 0xb7, 0x79, 0x3e, 0x50, 0x8b, 0xba, 0x6b, 0x0d, 0x26, 0xe8,
|
0x6a, 0x7f, 0x57, 0x5b, 0xcf, 0x4d, 0x98, 0xf3, 0x87, 0x3c, 0x18, 0x72, 0x45, 0x68, 0x35, 0xba,
|
||||||
0x15, 0xeb, 0x58, 0xb2, 0x9b, 0x30, 0x7d, 0x75, 0x06, 0x55, 0x73, 0xfa, 0xda, 0xf8, 0x98, 0x80,
|
0x70, 0x19, 0xbe, 0xfa, 0x1a, 0x40, 0xfa, 0x23, 0x14, 0xaa, 0x40, 0x69, 0xff, 0xe1, 0xc6, 0x6e,
|
||||||
0x3e, 0x69, 0x0f, 0xc4, 0x16, 0x21, 0xe1, 0xb7, 0x3e, 0x1b, 0xa0, 0x59, 0x76, 0xb3, 0x5a, 0x6a,
|
0xcb, 0xba, 0x82, 0x6a, 0x50, 0xde, 0xdb, 0xc0, 0x0f, 0xb6, 0x1e, 0x1d, 0xb4, 0x2c, 0x63, 0xed,
|
||||||
0x64, 0x87, 0xe9, 0x34, 0x39, 0x61, 0xff, 0xb9, 0xf3, 0x60, 0x5a, 0xc8, 0x71, 0x66, 0x03, 0x86,
|
0xe7, 0x15, 0x28, 0xc7, 0x0f, 0x5d, 0xf4, 0x1d, 0xa8, 0xec, 0x50, 0xae, 0x7e, 0x20, 0xfd, 0xf2,
|
||||||
0xec, 0xe3, 0x19, 0xf4, 0x44, 0xcc, 0xc6, 0xb9, 0xb8, 0x54, 0x4e, 0xc6, 0xb3, 0x38, 0x26, 0x27,
|
0x19, 0xbf, 0x3d, 0x44, 0x3c, 0x7b, 0x2d, 0xd7, 0x2f, 0x14, 0xa8, 0x3f, 0xe3, 0x55, 0x8d, 0x56,
|
||||||
0xeb, 0xd9, 0xcc, 0x92, 0x93, 0x8d, 0xd3, 0x72, 0x1e, 0x4f, 0xbe, 0x84, 0xe8, 0x53, 0x13, 0x86,
|
0xb5, 0xf9, 0x99, 0x88, 0xc4, 0xd3, 0xeb, 0x39, 0x90, 0xca, 0xdb, 0xf7, 0x4f, 0x7b, 0xd2, 0xa1,
|
||||||
0x4e, 0x49, 0x09, 0xf7, 0xe6, 0x3c, 0x88, 0x66, 0xfc, 0x45, 0xf5, 0xfb, 0x3f, 0x1a, 0xfb, 0xf9,
|
0x5b, 0x9a, 0xa1, 0xd9, 0xb0, 0xc4, 0x6f, 0x33, 0x2f, 0x5c, 0x39, 0x1f, 0xce, 0x7e, 0x92, 0xa1,
|
||||||
0x94, 0x87, 0x51, 0xc2, 0xa4, 0x31, 0x4d, 0x50, 0x47, 0xb7, 0xbe, 0x57, 0x84, 0x9a, 0xf5, 0x30,
|
0x37, 0x32, 0x6c, 0x4d, 0x82, 0x12, 0xc7, 0x6f, 0xe6, 0x03, 0x2b, 0xb7, 0x6e, 0xf6, 0xcb, 0x1e,
|
||||||
0xa0, 0x0f, 0xec, 0xe2, 0xb4, 0x91, 0x51, 0x76, 0xec, 0x37, 0x2e, 0x33, 0xaa, 0x67, 0x00, 0xb5,
|
0xad, 0x68, 0x56, 0xb2, 0x00, 0x89, 0xbb, 0xd5, 0xb3, 0x81, 0xca, 0xd5, 0x7d, 0xed, 0xe5, 0x86,
|
||||||
0xaa, 0x67, 0x73, 0xde, 0x23, 0x94, 0x95, 0x8b, 0x53, 0xa8, 0x44, 0xe8, 0x8d, 0x9c, 0x68, 0x2d,
|
0x5e, 0xd6, 0xa6, 0x25, 0xd2, 0xc4, 0xe8, 0x2b, 0x33, 0xb4, 0xca, 0xd2, 0xb7, 0xc7, 0xdf, 0x51,
|
||||||
0xf9, 0x49, 0xc6, 0x53, 0x33, 0x56, 0x7e, 0xa7, 0xa8, 0x99, 0xe5, 0x37, 0x0b, 0xa5, 0x24, 0xbc,
|
0xe8, 0x0b, 0xfa, 0x2f, 0x06, 0x9a, 0x22, 0xb1, 0xb7, 0x3c, 0x1b, 0xa0, 0x4c, 0x76, 0xb3, 0x1e,
|
||||||
0xe9, 0x5c, 0xc2, 0x11, 0x4f, 0x16, 0xe4, 0x1f, 0x7b, 0xb7, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff,
|
0x0d, 0x48, 0xa7, 0xe9, 0xb4, 0x3a, 0x31, 0xff, 0x95, 0xb3, 0x60, 0xca, 0xc9, 0x61, 0xe6, 0x25,
|
||||||
0x8a, 0x61, 0xfa, 0xcc, 0xeb, 0x1b, 0x00, 0x00,
|
0x11, 0xe9, 0xd3, 0x33, 0xf4, 0x89, 0x9b, 0x95, 0x33, 0x71, 0xa9, 0x9f, 0x8c, 0xc3, 0x77, 0xcc,
|
||||||
|
0x4f, 0xd6, 0xe1, 0x9c, 0xe5, 0x27, 0x1b, 0xa7, 0xfc, 0x1c, 0x4c, 0x9e, 0xb7, 0xe8, 0x8b, 0x13,
|
||||||
|
0x89, 0x4e, 0x55, 0x89, 0xf5, 0xc6, 0x69, 0x10, 0x65, 0xf8, 0x1b, 0xd1, 0xdf, 0x47, 0x68, 0xec,
|
||||||
|
0x77, 0x69, 0xee, 0x07, 0x89, 0x91, 0xfa, 0xb4, 0x22, 0x9a, 0xba, 0xf6, 0xa3, 0x02, 0x54, 0xb5,
|
||||||
|
0xf3, 0x03, 0x7d, 0xa0, 0x37, 0xa7, 0x95, 0x8c, 0xb6, 0xa3, 0x1f, 0x85, 0x99, 0xac, 0x9e, 0x01,
|
||||||
|
0x54, 0xa1, 0x9e, 0x9c, 0x72, 0x6c, 0xa1, 0xac, 0xbd, 0x38, 0x85, 0x4a, 0x9c, 0xde, 0xca, 0x89,
|
||||||
|
0x56, 0x9e, 0x9f, 0x65, 0x9c, 0x48, 0x63, 0xed, 0x77, 0x4a, 0x9b, 0xd9, 0x7e, 0xb3, 0x50, 0x91,
|
||||||
|
0x87, 0xb7, 0x8c, 0x4b, 0x14, 0xe2, 0xd9, 0x9c, 0xfc, 0x5f, 0xf8, 0xce, 0xff, 0x02, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xe3, 0x8e, 0xe1, 0x22, 0x2a, 0x1e, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference imports to suppress errors if they are not otherwise used.
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
../../docs/plugin-protocol/tfplugin5.1.proto
|
../../docs/plugin-protocol/tfplugin5.2.proto
|
|
@ -13,17 +13,24 @@ import (
|
||||||
// ConfigSchemaToProto takes a *configschema.Block and converts it to a
|
// ConfigSchemaToProto takes a *configschema.Block and converts it to a
|
||||||
// proto.Schema_Block for a grpc response.
|
// proto.Schema_Block for a grpc response.
|
||||||
func ConfigSchemaToProto(b *configschema.Block) *proto.Schema_Block {
|
func ConfigSchemaToProto(b *configschema.Block) *proto.Schema_Block {
|
||||||
block := &proto.Schema_Block{}
|
block := &proto.Schema_Block{
|
||||||
|
Description: b.Description,
|
||||||
|
DescriptionKind: protoStringKind(b.DescriptionKind),
|
||||||
|
Deprecated: b.Deprecated,
|
||||||
|
}
|
||||||
|
|
||||||
for _, name := range sortedKeys(b.Attributes) {
|
for _, name := range sortedKeys(b.Attributes) {
|
||||||
a := b.Attributes[name]
|
a := b.Attributes[name]
|
||||||
|
|
||||||
attr := &proto.Schema_Attribute{
|
attr := &proto.Schema_Attribute{
|
||||||
Name: name,
|
Name: name,
|
||||||
Description: a.Description,
|
Description: a.Description,
|
||||||
Optional: a.Optional,
|
DescriptionKind: protoStringKind(a.DescriptionKind),
|
||||||
Computed: a.Computed,
|
Optional: a.Optional,
|
||||||
Required: a.Required,
|
Computed: a.Computed,
|
||||||
Sensitive: a.Sensitive,
|
Required: a.Required,
|
||||||
|
Sensitive: a.Sensitive,
|
||||||
|
Deprecated: a.Deprecated,
|
||||||
}
|
}
|
||||||
|
|
||||||
ty, err := json.Marshal(a.Type)
|
ty, err := json.Marshal(a.Type)
|
||||||
|
@ -44,6 +51,15 @@ func ConfigSchemaToProto(b *configschema.Block) *proto.Schema_Block {
|
||||||
return block
|
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 {
|
func protoSchemaNestedBlock(name string, b *configschema.NestedBlock) *proto.Schema_NestedBlock {
|
||||||
var nesting proto.Schema_NestedBlock_NestingMode
|
var nesting proto.Schema_NestedBlock_NestingMode
|
||||||
switch b.Nesting {
|
switch b.Nesting {
|
||||||
|
@ -83,15 +99,21 @@ func ProtoToConfigSchema(b *proto.Schema_Block) *configschema.Block {
|
||||||
block := &configschema.Block{
|
block := &configschema.Block{
|
||||||
Attributes: make(map[string]*configschema.Attribute),
|
Attributes: make(map[string]*configschema.Attribute),
|
||||||
BlockTypes: make(map[string]*configschema.NestedBlock),
|
BlockTypes: make(map[string]*configschema.NestedBlock),
|
||||||
|
|
||||||
|
Description: b.Description,
|
||||||
|
DescriptionKind: schemaStringKind(b.DescriptionKind),
|
||||||
|
Deprecated: b.Deprecated,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, a := range b.Attributes {
|
for _, a := range b.Attributes {
|
||||||
attr := &configschema.Attribute{
|
attr := &configschema.Attribute{
|
||||||
Description: a.Description,
|
Description: a.Description,
|
||||||
Required: a.Required,
|
DescriptionKind: schemaStringKind(a.DescriptionKind),
|
||||||
Optional: a.Optional,
|
Required: a.Required,
|
||||||
Computed: a.Computed,
|
Optional: a.Optional,
|
||||||
Sensitive: a.Sensitive,
|
Computed: a.Computed,
|
||||||
|
Sensitive: a.Sensitive,
|
||||||
|
Deprecated: a.Deprecated,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(a.Type, &attr.Type); err != nil {
|
if err := json.Unmarshal(a.Type, &attr.Type); err != nil {
|
||||||
|
@ -108,6 +130,15 @@ func ProtoToConfigSchema(b *proto.Schema_Block) *configschema.Block {
|
||||||
return block
|
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 {
|
func schemaNestedBlock(b *proto.Schema_NestedBlock) *configschema.NestedBlock {
|
||||||
var nesting configschema.NestingMode
|
var nesting configschema.NestingMode
|
||||||
switch b.Nesting {
|
switch b.Nesting {
|
||||||
|
|
|
@ -105,6 +105,13 @@ func (p *GRPCProvider) getDatasourceSchema(name string) providers.Schema {
|
||||||
return dataSchema
|
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) {
|
func (p *GRPCProvider) GetSchema() (resp providers.GetSchemaResponse) {
|
||||||
log.Printf("[TRACE] GRPCProvider: GetSchema")
|
log.Printf("[TRACE] GRPCProvider: GetSchema")
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
|
@ -137,6 +144,11 @@ func (p *GRPCProvider) GetSchema() (resp providers.GetSchemaResponse) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.Provider = convert.ProtoToProviderSchema(protoResp.Provider)
|
resp.Provider = convert.ProtoToProviderSchema(protoResp.Provider)
|
||||||
|
if protoResp.ProviderMeta == nil {
|
||||||
|
log.Printf("[TRACE] No provider meta schema returned")
|
||||||
|
} else {
|
||||||
|
resp.ProviderMeta = convert.ProtoToProviderSchema(protoResp.ProviderMeta)
|
||||||
|
}
|
||||||
|
|
||||||
for name, res := range protoResp.ResourceSchemas {
|
for name, res := range protoResp.ResourceSchemas {
|
||||||
resp.ResourceTypes[name] = convert.ProtoToProviderSchema(res)
|
resp.ResourceTypes[name] = convert.ProtoToProviderSchema(res)
|
||||||
|
@ -319,6 +331,7 @@ func (p *GRPCProvider) ReadResource(r providers.ReadResourceRequest) (resp provi
|
||||||
log.Printf("[TRACE] GRPCProvider: ReadResource")
|
log.Printf("[TRACE] GRPCProvider: ReadResource")
|
||||||
|
|
||||||
resSchema := p.getResourceSchema(r.TypeName)
|
resSchema := p.getResourceSchema(r.TypeName)
|
||||||
|
metaSchema := p.getProviderMetaSchema()
|
||||||
|
|
||||||
mp, err := msgpack.Marshal(r.PriorState, resSchema.Block.ImpliedType())
|
mp, err := msgpack.Marshal(r.PriorState, resSchema.Block.ImpliedType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -332,6 +345,15 @@ func (p *GRPCProvider) ReadResource(r providers.ReadResourceRequest) (resp provi
|
||||||
Private: r.Private,
|
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 = &proto.DynamicValue{Msgpack: metaMP}
|
||||||
|
}
|
||||||
|
|
||||||
protoResp, err := p.client.ReadResource(p.ctx, protoReq)
|
protoResp, err := p.client.ReadResource(p.ctx, protoReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = resp.Diagnostics.Append(err)
|
resp.Diagnostics = resp.Diagnostics.Append(err)
|
||||||
|
@ -357,6 +379,7 @@ func (p *GRPCProvider) PlanResourceChange(r providers.PlanResourceChangeRequest)
|
||||||
log.Printf("[TRACE] GRPCProvider: PlanResourceChange")
|
log.Printf("[TRACE] GRPCProvider: PlanResourceChange")
|
||||||
|
|
||||||
resSchema := p.getResourceSchema(r.TypeName)
|
resSchema := p.getResourceSchema(r.TypeName)
|
||||||
|
metaSchema := p.getProviderMetaSchema()
|
||||||
|
|
||||||
priorMP, err := msgpack.Marshal(r.PriorState, resSchema.Block.ImpliedType())
|
priorMP, err := msgpack.Marshal(r.PriorState, resSchema.Block.ImpliedType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -384,6 +407,15 @@ func (p *GRPCProvider) PlanResourceChange(r providers.PlanResourceChangeRequest)
|
||||||
PriorPrivate: r.PriorPrivate,
|
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 = &proto.DynamicValue{Msgpack: metaMP}
|
||||||
|
}
|
||||||
|
|
||||||
protoResp, err := p.client.PlanResourceChange(p.ctx, protoReq)
|
protoResp, err := p.client.PlanResourceChange(p.ctx, protoReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = resp.Diagnostics.Append(err)
|
resp.Diagnostics = resp.Diagnostics.Append(err)
|
||||||
|
@ -416,6 +448,7 @@ func (p *GRPCProvider) ApplyResourceChange(r providers.ApplyResourceChangeReques
|
||||||
log.Printf("[TRACE] GRPCProvider: ApplyResourceChange")
|
log.Printf("[TRACE] GRPCProvider: ApplyResourceChange")
|
||||||
|
|
||||||
resSchema := p.getResourceSchema(r.TypeName)
|
resSchema := p.getResourceSchema(r.TypeName)
|
||||||
|
metaSchema := p.getProviderMetaSchema()
|
||||||
|
|
||||||
priorMP, err := msgpack.Marshal(r.PriorState, resSchema.Block.ImpliedType())
|
priorMP, err := msgpack.Marshal(r.PriorState, resSchema.Block.ImpliedType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -441,6 +474,15 @@ func (p *GRPCProvider) ApplyResourceChange(r providers.ApplyResourceChangeReques
|
||||||
PlannedPrivate: r.PlannedPrivate,
|
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 = &proto.DynamicValue{Msgpack: metaMP}
|
||||||
|
}
|
||||||
|
|
||||||
protoResp, err := p.client.ApplyResourceChange(p.ctx, protoReq)
|
protoResp, err := p.client.ApplyResourceChange(p.ctx, protoReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = resp.Diagnostics.Append(err)
|
resp.Diagnostics = resp.Diagnostics.Append(err)
|
||||||
|
@ -506,6 +548,7 @@ func (p *GRPCProvider) ReadDataSource(r providers.ReadDataSourceRequest) (resp p
|
||||||
log.Printf("[TRACE] GRPCProvider: ReadDataSource")
|
log.Printf("[TRACE] GRPCProvider: ReadDataSource")
|
||||||
|
|
||||||
dataSchema := p.getDatasourceSchema(r.TypeName)
|
dataSchema := p.getDatasourceSchema(r.TypeName)
|
||||||
|
metaSchema := p.getProviderMetaSchema()
|
||||||
|
|
||||||
config, err := msgpack.Marshal(r.Config, dataSchema.Block.ImpliedType())
|
config, err := msgpack.Marshal(r.Config, dataSchema.Block.ImpliedType())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -520,6 +563,15 @@ func (p *GRPCProvider) ReadDataSource(r providers.ReadDataSourceRequest) (resp p
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = &proto.DynamicValue{Msgpack: metaMP}
|
||||||
|
}
|
||||||
|
|
||||||
protoResp, err := p.client.ReadDataSource(p.ctx, protoReq)
|
protoResp, err := p.client.ReadDataSource(p.ctx, protoReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = resp.Diagnostics.Append(err)
|
resp.Diagnostics = resp.Diagnostics.Append(err)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package plugin
|
||||||
import (
|
import (
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
|
|
||||||
"github.com/hashicorp/go-plugin"
|
plugin "github.com/hashicorp/go-plugin"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,9 @@ type GetSchemaResponse struct {
|
||||||
// Provider is the schema for the provider itself.
|
// Provider is the schema for the provider itself.
|
||||||
Provider Schema
|
Provider Schema
|
||||||
|
|
||||||
|
// ProviderMeta is the schema for the provider's meta info in a module
|
||||||
|
ProviderMeta Schema
|
||||||
|
|
||||||
// ResourceTypes map the resource type name to that type's schema.
|
// ResourceTypes map the resource type name to that type's schema.
|
||||||
ResourceTypes map[string]Schema
|
ResourceTypes map[string]Schema
|
||||||
|
|
||||||
|
@ -180,6 +183,12 @@ type ReadResourceRequest struct {
|
||||||
// Private is an opaque blob that will be stored in state along with the
|
// Private is an opaque blob that will be stored in state along with the
|
||||||
// resource. It is intended only for interpretation by the provider itself.
|
// resource. It is intended only for interpretation by the provider itself.
|
||||||
Private []byte
|
Private []byte
|
||||||
|
|
||||||
|
// ProviderMeta is the configuration for the provider_meta block for the
|
||||||
|
// module and provider this resource belongs to. Its use is defined by
|
||||||
|
// each provider, and it should not be used without coordination with
|
||||||
|
// HashiCorp. It is considered experimental and subject to change.
|
||||||
|
ProviderMeta cty.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReadResourceResponse struct {
|
type ReadResourceResponse struct {
|
||||||
|
@ -216,6 +225,12 @@ type PlanResourceChangeRequest struct {
|
||||||
// PriorPrivate is the previously saved private data returned from the
|
// PriorPrivate is the previously saved private data returned from the
|
||||||
// provider during the last apply.
|
// provider during the last apply.
|
||||||
PriorPrivate []byte
|
PriorPrivate []byte
|
||||||
|
|
||||||
|
// ProviderMeta is the configuration for the provider_meta block for the
|
||||||
|
// module and provider this resource belongs to. Its use is defined by
|
||||||
|
// each provider, and it should not be used without coordination with
|
||||||
|
// HashiCorp. It is considered experimental and subject to change.
|
||||||
|
ProviderMeta cty.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
type PlanResourceChangeResponse struct {
|
type PlanResourceChangeResponse struct {
|
||||||
|
@ -262,6 +277,12 @@ type ApplyResourceChangeRequest struct {
|
||||||
|
|
||||||
// PlannedPrivate is the same value as returned by PlanResourceChange.
|
// PlannedPrivate is the same value as returned by PlanResourceChange.
|
||||||
PlannedPrivate []byte
|
PlannedPrivate []byte
|
||||||
|
|
||||||
|
// ProviderMeta is the configuration for the provider_meta block for the
|
||||||
|
// module and provider this resource belongs to. Its use is defined by
|
||||||
|
// each provider, and it should not be used without coordination with
|
||||||
|
// HashiCorp. It is considered experimental and subject to change.
|
||||||
|
ProviderMeta cty.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApplyResourceChangeResponse struct {
|
type ApplyResourceChangeResponse struct {
|
||||||
|
@ -348,6 +369,12 @@ type ReadDataSourceRequest struct {
|
||||||
|
|
||||||
// Config is the complete configuration for the requested data source.
|
// Config is the complete configuration for the requested data source.
|
||||||
Config cty.Value
|
Config cty.Value
|
||||||
|
|
||||||
|
// ProviderMeta is the configuration for the provider_meta block for the
|
||||||
|
// module and provider this resource belongs to. Its use is defined by
|
||||||
|
// each provider, and it should not be used without coordination with
|
||||||
|
// HashiCorp. It is considered experimental and subject to change.
|
||||||
|
ProviderMeta cty.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReadDataSourceResponse struct {
|
type ReadDataSourceResponse struct {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/hashicorp/terraform/states/statefile"
|
"github.com/hashicorp/terraform/states/statefile"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/gocty"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestContext2Apply_basic(t *testing.T) {
|
func TestContext2Apply_basic(t *testing.T) {
|
||||||
|
@ -10174,7 +10175,6 @@ func TestContext2Apply_invalidIndexRef(t *testing.T) {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
|
||||||
diags := c.Validate()
|
diags := c.Validate()
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
t.Fatalf("unexpected validation failure: %s", diags.Err())
|
t.Fatalf("unexpected validation failure: %s", diags.Err())
|
||||||
|
@ -10741,3 +10741,915 @@ func TestContext2Apply_cbdCycle(t *testing.T) {
|
||||||
t.Fatalf("diags: %s", diags.Err())
|
t.Fatalf("diags: %s", diags.Err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_apply_set(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
arcPMs := map[string]cty.Value{}
|
||||||
|
p.ApplyResourceChangeFn = func(req providers.ApplyResourceChangeRequest) providers.ApplyResourceChangeResponse {
|
||||||
|
arcPMs[req.TypeName] = req.ProviderMeta
|
||||||
|
s := req.PlannedState.AsValueMap()
|
||||||
|
s["id"] = cty.StringVal("ID")
|
||||||
|
return providers.ApplyResourceChangeResponse{
|
||||||
|
NewState: cty.ObjectVal(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Apply()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
if !p.ApplyResourceChangeCalled {
|
||||||
|
t.Fatalf("ApplyResourceChange not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
expectations := map[string]cty.Value{}
|
||||||
|
|
||||||
|
if pm, ok := arcPMs["test_resource"]; !ok {
|
||||||
|
t.Fatalf("sub-module ApplyResourceChange not called")
|
||||||
|
} else if pm.IsNull() {
|
||||||
|
t.Fatalf("null ProviderMeta in sub-module ApplyResourceChange")
|
||||||
|
} else {
|
||||||
|
expectations["quux-submodule"] = pm
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := arcPMs["test_instance"]; !ok {
|
||||||
|
t.Fatalf("root module ApplyResourceChange not called")
|
||||||
|
} else if pm.IsNull() {
|
||||||
|
t.Fatalf("null ProviderMeta in root module ApplyResourceChange")
|
||||||
|
} else {
|
||||||
|
expectations["quux"] = pm
|
||||||
|
}
|
||||||
|
|
||||||
|
type metaStruct struct {
|
||||||
|
Baz string `cty:"baz"`
|
||||||
|
}
|
||||||
|
|
||||||
|
for expected, v := range expectations {
|
||||||
|
var meta metaStruct
|
||||||
|
err := gocty.FromCtyValue(v, &meta)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error parsing cty value: %s", err)
|
||||||
|
}
|
||||||
|
if meta.Baz != expected {
|
||||||
|
t.Fatalf("Expected meta.Baz to be %q, got %q", expected, meta.Baz)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_apply_unset(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-unset")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
arcPMs := map[string]cty.Value{}
|
||||||
|
p.ApplyResourceChangeFn = func(req providers.ApplyResourceChangeRequest) providers.ApplyResourceChangeResponse {
|
||||||
|
arcPMs[req.TypeName] = req.ProviderMeta
|
||||||
|
s := req.PlannedState.AsValueMap()
|
||||||
|
s["id"] = cty.StringVal("ID")
|
||||||
|
return providers.ApplyResourceChangeResponse{
|
||||||
|
NewState: cty.ObjectVal(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Apply()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
if !p.ApplyResourceChangeCalled {
|
||||||
|
t.Fatalf("ApplyResourceChange not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := arcPMs["test_resource"]; !ok {
|
||||||
|
t.Fatalf("sub-module ApplyResourceChange not called")
|
||||||
|
} else if !pm.IsNull() {
|
||||||
|
t.Fatalf("non-null ProviderMeta in sub-module ApplyResourceChange: %+v", pm)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := arcPMs["test_instance"]; !ok {
|
||||||
|
t.Fatalf("root module ApplyResourceChange not called")
|
||||||
|
} else if !pm.IsNull() {
|
||||||
|
t.Fatalf("non-null ProviderMeta in root module ApplyResourceChange: %+v", pm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_plan_set(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
prcPMs := map[string]cty.Value{}
|
||||||
|
p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) providers.PlanResourceChangeResponse {
|
||||||
|
prcPMs[req.TypeName] = req.ProviderMeta
|
||||||
|
return providers.PlanResourceChangeResponse{
|
||||||
|
PlannedState: req.ProposedNewState,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
if !p.PlanResourceChangeCalled {
|
||||||
|
t.Fatalf("PlanResourceChange not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
expectations := map[string]cty.Value{}
|
||||||
|
|
||||||
|
if pm, ok := prcPMs["test_resource"]; !ok {
|
||||||
|
t.Fatalf("sub-module PlanResourceChange not called")
|
||||||
|
} else if pm.IsNull() {
|
||||||
|
t.Fatalf("null ProviderMeta in sub-module PlanResourceChange")
|
||||||
|
} else {
|
||||||
|
expectations["quux-submodule"] = pm
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := prcPMs["test_instance"]; !ok {
|
||||||
|
t.Fatalf("root module PlanResourceChange not called")
|
||||||
|
} else if pm.IsNull() {
|
||||||
|
t.Fatalf("null ProviderMeta in root module PlanResourceChange")
|
||||||
|
} else {
|
||||||
|
expectations["quux"] = pm
|
||||||
|
}
|
||||||
|
|
||||||
|
type metaStruct struct {
|
||||||
|
Baz string `cty:"baz"`
|
||||||
|
}
|
||||||
|
|
||||||
|
for expected, v := range expectations {
|
||||||
|
var meta metaStruct
|
||||||
|
err := gocty.FromCtyValue(v, &meta)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error parsing cty value: %s", err)
|
||||||
|
}
|
||||||
|
if meta.Baz != expected {
|
||||||
|
t.Fatalf("Expected meta.Baz to be %q, got %q", expected, meta.Baz)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_plan_unset(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-unset")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
prcPMs := map[string]cty.Value{}
|
||||||
|
p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) providers.PlanResourceChangeResponse {
|
||||||
|
prcPMs[req.TypeName] = req.ProviderMeta
|
||||||
|
return providers.PlanResourceChangeResponse{
|
||||||
|
PlannedState: req.ProposedNewState,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
if !p.PlanResourceChangeCalled {
|
||||||
|
t.Fatalf("PlanResourceChange not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := prcPMs["test_resource"]; !ok {
|
||||||
|
t.Fatalf("sub-module PlanResourceChange not called")
|
||||||
|
} else if !pm.IsNull() {
|
||||||
|
t.Fatalf("non-null ProviderMeta in sub-module PlanResourceChange: %+v", pm)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := prcPMs["test_instance"]; !ok {
|
||||||
|
t.Fatalf("root module PlanResourceChange not called")
|
||||||
|
} else if !pm.IsNull() {
|
||||||
|
t.Fatalf("non-null ProviderMeta in root module PlanResourceChange: %+v", pm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_plan_setNoSchema(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
if !diags.HasErrors() {
|
||||||
|
t.Fatalf("plan supposed to error, has no errors")
|
||||||
|
}
|
||||||
|
|
||||||
|
var rootErr, subErr bool
|
||||||
|
errorSummary := "The resource test_%s.bar belongs to a provider that doesn't support provider_meta blocks"
|
||||||
|
for _, diag := range diags {
|
||||||
|
if diag.Description().Summary != "Provider registry.terraform.io/-/test doesn't support provider_meta" {
|
||||||
|
t.Errorf("Unexpected error: %+v", diag.Description())
|
||||||
|
}
|
||||||
|
switch diag.Description().Detail {
|
||||||
|
case fmt.Sprintf(errorSummary, "instance"):
|
||||||
|
rootErr = true
|
||||||
|
case fmt.Sprintf(errorSummary, "resource"):
|
||||||
|
subErr = true
|
||||||
|
default:
|
||||||
|
t.Errorf("Unexpected error: %s", diag.Description())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !rootErr {
|
||||||
|
t.Errorf("Expected unsupported provider_meta block error for root module, none received")
|
||||||
|
}
|
||||||
|
if !subErr {
|
||||||
|
t.Errorf("Expected unsupported provider_meta block error for sub-module, none received")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_plan_setInvalid(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"quux": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
if !diags.HasErrors() {
|
||||||
|
t.Fatalf("plan supposed to error, has no errors")
|
||||||
|
}
|
||||||
|
|
||||||
|
var reqErr, invalidErr bool
|
||||||
|
for _, diag := range diags {
|
||||||
|
switch diag.Description().Summary {
|
||||||
|
case "Missing required argument":
|
||||||
|
if diag.Description().Detail == `The argument "quux" is required, but no definition was found.` {
|
||||||
|
reqErr = true
|
||||||
|
} else {
|
||||||
|
t.Errorf("Unexpected error %+v", diag.Description())
|
||||||
|
}
|
||||||
|
case "Unsupported argument":
|
||||||
|
if diag.Description().Detail == `An argument named "baz" is not expected here.` {
|
||||||
|
invalidErr = true
|
||||||
|
} else {
|
||||||
|
t.Errorf("Unexpected error %+v", diag.Description())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.Errorf("Unexpected error %+v", diag.Description())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !reqErr {
|
||||||
|
t.Errorf("Expected missing required argument error, none received")
|
||||||
|
}
|
||||||
|
if !invalidErr {
|
||||||
|
t.Errorf("Expected unsupported argument error, none received")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_refresh_set(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
rrcPMs := map[string]cty.Value{}
|
||||||
|
p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
|
||||||
|
rrcPMs[req.TypeName] = req.ProviderMeta
|
||||||
|
newState, err := p.GetSchemaReturn.ResourceTypes[req.TypeName].CoerceValue(p.ReadResourceResponse.NewState)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
resp := p.ReadResourceResponse
|
||||||
|
resp.NewState = newState
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Apply()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Refresh()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
if !p.ReadResourceCalled {
|
||||||
|
t.Fatalf("ReadResource not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
expectations := map[string]cty.Value{}
|
||||||
|
|
||||||
|
if pm, ok := rrcPMs["test_resource"]; !ok {
|
||||||
|
t.Fatalf("sub-module ReadResource not called")
|
||||||
|
} else if pm.IsNull() {
|
||||||
|
t.Fatalf("null ProviderMeta in sub-module ReadResource")
|
||||||
|
} else {
|
||||||
|
expectations["quux-submodule"] = pm
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := rrcPMs["test_instance"]; !ok {
|
||||||
|
t.Fatalf("root module ReadResource not called")
|
||||||
|
} else if pm.IsNull() {
|
||||||
|
t.Fatalf("null ProviderMeta in root module ReadResource")
|
||||||
|
} else {
|
||||||
|
expectations["quux"] = pm
|
||||||
|
}
|
||||||
|
|
||||||
|
type metaStruct struct {
|
||||||
|
Baz string `cty:"baz"`
|
||||||
|
}
|
||||||
|
|
||||||
|
for expected, v := range expectations {
|
||||||
|
var meta metaStruct
|
||||||
|
err := gocty.FromCtyValue(v, &meta)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error parsing cty value: %s", err)
|
||||||
|
}
|
||||||
|
if meta.Baz != expected {
|
||||||
|
t.Fatalf("Expected meta.Baz to be %q, got %q", expected, meta.Baz)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_refresh_unset(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-unset")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Apply()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Refresh()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
if !p.ReadResourceCalled {
|
||||||
|
t.Fatalf("ReadResource not called")
|
||||||
|
}
|
||||||
|
if !p.ReadResourceRequest.ProviderMeta.IsNull() {
|
||||||
|
t.Fatalf("Expected null ProviderMeta in ReadResource, got %v", p.ReadResourceRequest.ProviderMeta)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_refresh_setNoSchema(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
|
||||||
|
// we need a schema for plan/apply so they don't error
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Apply()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
// drop the schema before refresh, to test that it errors
|
||||||
|
schema.ProviderMeta = nil
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx = testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
State: ctx.State(),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags = ctx.Refresh()
|
||||||
|
if !diags.HasErrors() {
|
||||||
|
t.Fatalf("refresh supposed to error, has no errors")
|
||||||
|
}
|
||||||
|
|
||||||
|
var rootErr, subErr bool
|
||||||
|
errorSummary := "The resource test_%s.bar belongs to a provider that doesn't support provider_meta blocks"
|
||||||
|
for _, diag := range diags {
|
||||||
|
if diag.Description().Summary != "Provider registry.terraform.io/-/test doesn't support provider_meta" {
|
||||||
|
t.Errorf("Unexpected error: %+v", diag.Description())
|
||||||
|
}
|
||||||
|
switch diag.Description().Detail {
|
||||||
|
case fmt.Sprintf(errorSummary, "instance"):
|
||||||
|
rootErr = true
|
||||||
|
case fmt.Sprintf(errorSummary, "resource"):
|
||||||
|
subErr = true
|
||||||
|
default:
|
||||||
|
t.Errorf("Unexpected error: %s", diag.Description())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !rootErr {
|
||||||
|
t.Errorf("Expected unsupported provider_meta block error for root module, none received")
|
||||||
|
}
|
||||||
|
if !subErr {
|
||||||
|
t.Errorf("Expected unsupported provider_meta block error for sub-module, none received")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_refresh_setInvalid(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
|
||||||
|
// we need a matching schema for plan/apply so they don't error
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Apply()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
// change the schema before refresh, to test that it errors
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"quux": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx = testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
State: ctx.State(),
|
||||||
|
})
|
||||||
|
|
||||||
|
_, diags = ctx.Refresh()
|
||||||
|
if !diags.HasErrors() {
|
||||||
|
t.Fatalf("refresh supposed to error, has no errors")
|
||||||
|
}
|
||||||
|
|
||||||
|
var reqErr, invalidErr bool
|
||||||
|
for _, diag := range diags {
|
||||||
|
switch diag.Description().Summary {
|
||||||
|
case "Missing required argument":
|
||||||
|
if diag.Description().Detail == `The argument "quux" is required, but no definition was found.` {
|
||||||
|
reqErr = true
|
||||||
|
} else {
|
||||||
|
t.Errorf("Unexpected error %+v", diag.Description())
|
||||||
|
}
|
||||||
|
case "Unsupported argument":
|
||||||
|
if diag.Description().Detail == `An argument named "baz" is not expected here.` {
|
||||||
|
invalidErr = true
|
||||||
|
} else {
|
||||||
|
t.Errorf("Unexpected error %+v", diag.Description())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.Errorf("Unexpected error %+v", diag.Description())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !reqErr {
|
||||||
|
t.Errorf("Expected missing required argument error, none received")
|
||||||
|
}
|
||||||
|
if !invalidErr {
|
||||||
|
t.Errorf("Expected unsupported argument error, none received")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_refreshdata_set(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-data-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
rdsPMs := map[string]cty.Value{}
|
||||||
|
p.ReadDataSourceFn = func(req providers.ReadDataSourceRequest) providers.ReadDataSourceResponse {
|
||||||
|
rdsPMs[req.TypeName] = req.ProviderMeta
|
||||||
|
switch req.TypeName {
|
||||||
|
case "test_data_source":
|
||||||
|
log.Printf("[TRACE] test_data_source RDSR returning")
|
||||||
|
return providers.ReadDataSourceResponse{
|
||||||
|
State: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("yo"),
|
||||||
|
"foo": cty.StringVal("bar"),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
case "test_file":
|
||||||
|
log.Printf("[TRACE] test_file RDSR returning")
|
||||||
|
return providers.ReadDataSourceResponse{
|
||||||
|
State: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("bar"),
|
||||||
|
"rendered": cty.StringVal("baz"),
|
||||||
|
"template": cty.StringVal(""),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// config drift, oops
|
||||||
|
log.Printf("[TRACE] unknown request TypeName: %q", req.TypeName)
|
||||||
|
return providers.ReadDataSourceResponse{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, diags := ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Apply()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Refresh()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
if !p.ReadDataSourceCalled {
|
||||||
|
t.Fatalf("ReadDataSource not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
expectations := map[string]cty.Value{}
|
||||||
|
|
||||||
|
if pm, ok := rdsPMs["test_file"]; !ok {
|
||||||
|
t.Fatalf("sub-module ReadDataSource not called")
|
||||||
|
} else if pm.IsNull() {
|
||||||
|
t.Fatalf("null ProviderMeta in sub-module ReadDataSource")
|
||||||
|
} else {
|
||||||
|
expectations["quux-submodule"] = pm
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := rdsPMs["test_data_source"]; !ok {
|
||||||
|
t.Fatalf("root module ReadDataSource not called")
|
||||||
|
} else if pm.IsNull() {
|
||||||
|
t.Fatalf("null ProviderMeta in root module ReadDataSource")
|
||||||
|
} else {
|
||||||
|
expectations["quux"] = pm
|
||||||
|
}
|
||||||
|
|
||||||
|
type metaStruct struct {
|
||||||
|
Baz string `cty:"baz"`
|
||||||
|
}
|
||||||
|
|
||||||
|
for expected, v := range expectations {
|
||||||
|
var meta metaStruct
|
||||||
|
err := gocty.FromCtyValue(v, &meta)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error parsing cty value: %s", err)
|
||||||
|
}
|
||||||
|
if meta.Baz != expected {
|
||||||
|
t.Fatalf("Expected meta.Baz to be %q, got %q", expected, meta.Baz)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_refreshdata_unset(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-data-unset")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"baz": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
rdsPMs := map[string]cty.Value{}
|
||||||
|
p.ReadDataSourceFn = func(req providers.ReadDataSourceRequest) providers.ReadDataSourceResponse {
|
||||||
|
rdsPMs[req.TypeName] = req.ProviderMeta
|
||||||
|
switch req.TypeName {
|
||||||
|
case "test_data_source":
|
||||||
|
return providers.ReadDataSourceResponse{
|
||||||
|
State: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("yo"),
|
||||||
|
"foo": cty.StringVal("bar"),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
case "test_file":
|
||||||
|
return providers.ReadDataSourceResponse{
|
||||||
|
State: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("bar"),
|
||||||
|
"rendered": cty.StringVal("baz"),
|
||||||
|
"template": cty.StringVal(""),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// config drift, oops
|
||||||
|
return providers.ReadDataSourceResponse{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, diags := ctx.Refresh()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Plan()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
_, diags = ctx.Apply()
|
||||||
|
assertNoErrors(t, diags)
|
||||||
|
|
||||||
|
if !p.ReadDataSourceCalled {
|
||||||
|
t.Fatalf("ReadDataSource not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := rdsPMs["test_file"]; !ok {
|
||||||
|
t.Fatalf("sub-module ReadDataSource not called")
|
||||||
|
} else if !pm.IsNull() {
|
||||||
|
t.Fatalf("non-null ProviderMeta in sub-module ReadDataSource")
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm, ok := rdsPMs["test_data_source"]; !ok {
|
||||||
|
t.Fatalf("root module ReadDataSource not called")
|
||||||
|
} else if !pm.IsNull() {
|
||||||
|
t.Fatalf("non-null ProviderMeta in root module ReadDataSource")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_refreshdata_setNoSchema(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-data-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
p.ReadDataSourceResponse = providers.ReadDataSourceResponse{
|
||||||
|
State: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("yo"),
|
||||||
|
"foo": cty.StringVal("bar"),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, diags := ctx.Refresh()
|
||||||
|
if !diags.HasErrors() {
|
||||||
|
t.Fatalf("refresh supposed to error, has no errors")
|
||||||
|
}
|
||||||
|
|
||||||
|
var rootErr, subErr bool
|
||||||
|
errorSummary := "The resource data.test_%s.foo belongs to a provider that doesn't support provider_meta blocks"
|
||||||
|
for _, diag := range diags {
|
||||||
|
if diag.Description().Summary != "Provider registry.terraform.io/-/test doesn't support provider_meta" {
|
||||||
|
t.Errorf("Unexpected error: %+v", diag.Description())
|
||||||
|
}
|
||||||
|
switch diag.Description().Detail {
|
||||||
|
case fmt.Sprintf(errorSummary, "data_source"):
|
||||||
|
rootErr = true
|
||||||
|
case fmt.Sprintf(errorSummary, "file"):
|
||||||
|
subErr = true
|
||||||
|
default:
|
||||||
|
t.Errorf("Unexpected error: %s", diag.Description())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !rootErr {
|
||||||
|
t.Errorf("Expected unsupported provider_meta block error for root module, none received")
|
||||||
|
}
|
||||||
|
if !subErr {
|
||||||
|
t.Errorf("Expected unsupported provider_meta block error for sub-module, none received")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext2Apply_ProviderMeta_refreshdata_setInvalid(t *testing.T) {
|
||||||
|
m := testModule(t, "provider-meta-data-set")
|
||||||
|
p := testProvider("test")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
schema := p.GetSchemaReturn
|
||||||
|
schema.ProviderMeta = &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"quux": {
|
||||||
|
Type: cty.String,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p.GetSchemaReturn = schema
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Config: m,
|
||||||
|
ProviderResolver: providers.ResolverFixed(
|
||||||
|
map[addrs.Provider]providers.Factory{
|
||||||
|
addrs.NewLegacyProvider("test"): testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
p.ReadDataSourceResponse = providers.ReadDataSourceResponse{
|
||||||
|
State: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("yo"),
|
||||||
|
"foo": cty.StringVal("bar"),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, diags := ctx.Refresh()
|
||||||
|
if !diags.HasErrors() {
|
||||||
|
t.Fatalf("refresh supposed to error, has no errors")
|
||||||
|
}
|
||||||
|
|
||||||
|
var reqErr, invalidErr bool
|
||||||
|
for _, diag := range diags {
|
||||||
|
switch diag.Description().Summary {
|
||||||
|
case "Missing required argument":
|
||||||
|
if diag.Description().Detail == `The argument "quux" is required, but no definition was found.` {
|
||||||
|
reqErr = true
|
||||||
|
} else {
|
||||||
|
t.Errorf("Unexpected error %+v", diag.Description())
|
||||||
|
}
|
||||||
|
case "Unsupported argument":
|
||||||
|
if diag.Description().Detail == `An argument named "baz" is not expected here.` {
|
||||||
|
invalidErr = true
|
||||||
|
} else {
|
||||||
|
t.Errorf("Unexpected error %+v", diag.Description())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.Errorf("Unexpected error %+v", diag.Description())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !reqErr {
|
||||||
|
t.Errorf("Expected missing required argument error, none received")
|
||||||
|
}
|
||||||
|
if !invalidErr {
|
||||||
|
t.Errorf("Expected unsupported argument error, none received")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
multierror "github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ type EvalApply struct {
|
||||||
Change **plans.ResourceInstanceChange
|
Change **plans.ResourceInstanceChange
|
||||||
ProviderAddr addrs.AbsProviderConfig
|
ProviderAddr addrs.AbsProviderConfig
|
||||||
Provider *providers.Interface
|
Provider *providers.Interface
|
||||||
|
ProviderMetas map[addrs.Provider]*configs.ProviderMeta
|
||||||
ProviderSchema **ProviderSchema
|
ProviderSchema **ProviderSchema
|
||||||
Output **states.ResourceInstanceObject
|
Output **states.ResourceInstanceObject
|
||||||
CreateNew *bool
|
CreateNew *bool
|
||||||
|
@ -76,6 +77,31 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metaConfigVal := cty.NullVal(cty.DynamicPseudoType)
|
||||||
|
if n.ProviderMetas != nil {
|
||||||
|
log.Printf("[DEBUG] EvalApply: ProviderMeta config value set")
|
||||||
|
if m, ok := n.ProviderMetas[n.ProviderAddr.Provider]; ok && m != nil {
|
||||||
|
// if the provider doesn't support this feature, throw an error
|
||||||
|
if (*n.ProviderSchema).ProviderMeta == nil {
|
||||||
|
log.Printf("[DEBUG] EvalApply: no ProviderMeta schema")
|
||||||
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", n.ProviderAddr.Provider.String()),
|
||||||
|
Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr),
|
||||||
|
Subject: &m.ProviderRange,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log.Printf("[DEBUG] EvalApply: ProviderMeta schema found")
|
||||||
|
var configDiags tfdiags.Diagnostics
|
||||||
|
metaConfigVal, _, configDiags = ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey)
|
||||||
|
diags = diags.Append(configDiags)
|
||||||
|
if configDiags.HasErrors() {
|
||||||
|
return nil, diags.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] %s: applying the planned %s change", n.Addr.Absolute(ctx.Path()), change.Action)
|
log.Printf("[DEBUG] %s: applying the planned %s change", n.Addr.Absolute(ctx.Path()), change.Action)
|
||||||
resp := provider.ApplyResourceChange(providers.ApplyResourceChangeRequest{
|
resp := provider.ApplyResourceChange(providers.ApplyResourceChangeRequest{
|
||||||
TypeName: n.Addr.Resource.Type,
|
TypeName: n.Addr.Resource.Type,
|
||||||
|
@ -83,6 +109,7 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
Config: configVal,
|
Config: configVal,
|
||||||
PlannedState: change.After,
|
PlannedState: change.After,
|
||||||
PlannedPrivate: change.Private,
|
PlannedPrivate: change.Private,
|
||||||
|
ProviderMeta: metaConfigVal,
|
||||||
})
|
})
|
||||||
applyDiags := resp.Diagnostics
|
applyDiags := resp.Diagnostics
|
||||||
if n.Config != nil {
|
if n.Config != nil {
|
||||||
|
|
|
@ -93,6 +93,7 @@ type EvalDiff struct {
|
||||||
Config *configs.Resource
|
Config *configs.Resource
|
||||||
Provider *providers.Interface
|
Provider *providers.Interface
|
||||||
ProviderAddr addrs.AbsProviderConfig
|
ProviderAddr addrs.AbsProviderConfig
|
||||||
|
ProviderMetas map[addrs.Provider]*configs.ProviderMeta
|
||||||
ProviderSchema **ProviderSchema
|
ProviderSchema **ProviderSchema
|
||||||
State **states.ResourceInstanceObject
|
State **states.ResourceInstanceObject
|
||||||
PreviousDiff **plans.ResourceInstanceChange
|
PreviousDiff **plans.ResourceInstanceChange
|
||||||
|
@ -140,6 +141,28 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, diags.Err()
|
return nil, diags.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metaConfigVal := cty.NullVal(cty.DynamicPseudoType)
|
||||||
|
if n.ProviderMetas != nil {
|
||||||
|
if m, ok := n.ProviderMetas[n.ProviderAddr.Provider]; ok && m != nil {
|
||||||
|
// if the provider doesn't support this feature, throw an error
|
||||||
|
if (*n.ProviderSchema).ProviderMeta == nil {
|
||||||
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", n.ProviderAddr.Provider.String()),
|
||||||
|
Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr),
|
||||||
|
Subject: &m.ProviderRange,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
var configDiags tfdiags.Diagnostics
|
||||||
|
metaConfigVal, _, configDiags = ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey)
|
||||||
|
diags = diags.Append(configDiags)
|
||||||
|
if configDiags.HasErrors() {
|
||||||
|
return nil, diags.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
absAddr := n.Addr.Absolute(ctx.Path())
|
absAddr := n.Addr.Absolute(ctx.Path())
|
||||||
var priorVal cty.Value
|
var priorVal cty.Value
|
||||||
var priorValTainted cty.Value
|
var priorValTainted cty.Value
|
||||||
|
@ -204,6 +227,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
PriorState: priorVal,
|
PriorState: priorVal,
|
||||||
ProposedNewState: proposedNewVal,
|
ProposedNewState: proposedNewVal,
|
||||||
PriorPrivate: priorPrivate,
|
PriorPrivate: priorPrivate,
|
||||||
|
ProviderMeta: metaConfigVal,
|
||||||
})
|
})
|
||||||
diags = diags.Append(resp.Diagnostics.InConfigBody(config.Config))
|
diags = diags.Append(resp.Diagnostics.InConfigBody(config.Config))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
|
@ -382,6 +406,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
PriorState: nullPriorVal,
|
PriorState: nullPriorVal,
|
||||||
ProposedNewState: proposedNewVal,
|
ProposedNewState: proposedNewVal,
|
||||||
PriorPrivate: plannedPrivate,
|
PriorPrivate: plannedPrivate,
|
||||||
|
ProviderMeta: metaConfigVal,
|
||||||
})
|
})
|
||||||
// We need to tread carefully here, since if there are any warnings
|
// We need to tread carefully here, since if there are any warnings
|
||||||
// in here they probably also came out of our previous call to
|
// in here they probably also came out of our previous call to
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/configs"
|
"github.com/hashicorp/terraform/configs"
|
||||||
"github.com/hashicorp/terraform/plans"
|
"github.com/hashicorp/terraform/plans"
|
||||||
|
@ -23,6 +24,7 @@ type EvalReadData struct {
|
||||||
Config *configs.Resource
|
Config *configs.Resource
|
||||||
Provider *providers.Interface
|
Provider *providers.Interface
|
||||||
ProviderAddr addrs.AbsProviderConfig
|
ProviderAddr addrs.AbsProviderConfig
|
||||||
|
ProviderMetas map[addrs.Provider]*configs.ProviderMeta
|
||||||
ProviderSchema **ProviderSchema
|
ProviderSchema **ProviderSchema
|
||||||
|
|
||||||
// Planned is set when dealing with data resources that were deferred to
|
// Planned is set when dealing with data resources that were deferred to
|
||||||
|
@ -104,6 +106,28 @@ func (n *EvalReadData) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, diags.Err()
|
return nil, diags.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metaConfigVal := cty.NullVal(cty.DynamicPseudoType)
|
||||||
|
if n.ProviderMetas != nil {
|
||||||
|
if m, ok := n.ProviderMetas[n.ProviderAddr.Provider]; ok && m != nil {
|
||||||
|
// if the provider doesn't support this feature, throw an error
|
||||||
|
if (*n.ProviderSchema).ProviderMeta == nil {
|
||||||
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", n.ProviderAddr.Provider.String()),
|
||||||
|
Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr),
|
||||||
|
Subject: &m.ProviderRange,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
var configDiags tfdiags.Diagnostics
|
||||||
|
metaConfigVal, _, configDiags = ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey)
|
||||||
|
diags = diags.Append(configDiags)
|
||||||
|
if configDiags.HasErrors() {
|
||||||
|
return nil, diags.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
proposedNewVal := objchange.PlannedDataResourceObject(schema, configVal)
|
proposedNewVal := objchange.PlannedDataResourceObject(schema, configVal)
|
||||||
|
|
||||||
// If our configuration contains any unknown values then we must defer the
|
// If our configuration contains any unknown values then we must defer the
|
||||||
|
@ -203,8 +227,9 @@ func (n *EvalReadData) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := provider.ReadDataSource(providers.ReadDataSourceRequest{
|
resp := provider.ReadDataSource(providers.ReadDataSourceRequest{
|
||||||
TypeName: n.Addr.Resource.Type,
|
TypeName: n.Addr.Resource.Type,
|
||||||
Config: configVal,
|
Config: configVal,
|
||||||
|
ProviderMeta: metaConfigVal,
|
||||||
})
|
})
|
||||||
diags = diags.Append(resp.Diagnostics.InConfigBody(n.Config.Config))
|
diags = diags.Append(resp.Diagnostics.InConfigBody(n.Config.Config))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
|
@ -306,6 +331,7 @@ type EvalReadDataApply struct {
|
||||||
Addr addrs.ResourceInstance
|
Addr addrs.ResourceInstance
|
||||||
Provider *providers.Interface
|
Provider *providers.Interface
|
||||||
ProviderAddr addrs.AbsProviderConfig
|
ProviderAddr addrs.AbsProviderConfig
|
||||||
|
ProviderMeta *configs.ProviderMeta
|
||||||
ProviderSchema **ProviderSchema
|
ProviderSchema **ProviderSchema
|
||||||
Output **states.ResourceInstanceObject
|
Output **states.ResourceInstanceObject
|
||||||
Config *configs.Resource
|
Config *configs.Resource
|
||||||
|
@ -330,6 +356,26 @@ func (n *EvalReadDataApply) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metaConfigVal := cty.NullVal(cty.DynamicPseudoType)
|
||||||
|
if n.ProviderMeta != nil {
|
||||||
|
// if the provider doesn't support this feature, throw an error
|
||||||
|
if (*n.ProviderSchema).ProviderMeta == nil {
|
||||||
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", n.ProviderAddr.Provider.String()),
|
||||||
|
Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr),
|
||||||
|
Subject: &n.ProviderMeta.ProviderRange,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
var configDiags tfdiags.Diagnostics
|
||||||
|
metaConfigVal, _, configDiags = ctx.EvaluateBlock(n.ProviderMeta.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey)
|
||||||
|
diags = diags.Append(configDiags)
|
||||||
|
if configDiags.HasErrors() {
|
||||||
|
return nil, diags.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For the purpose of external hooks we present a data apply as a
|
// For the purpose of external hooks we present a data apply as a
|
||||||
// "Refresh" rather than an "Apply" because creating a data source
|
// "Refresh" rather than an "Apply" because creating a data source
|
||||||
// is presented to users/callers as a "read" operation.
|
// is presented to users/callers as a "read" operation.
|
||||||
|
@ -343,8 +389,9 @@ func (n *EvalReadDataApply) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := provider.ReadDataSource(providers.ReadDataSourceRequest{
|
resp := provider.ReadDataSource(providers.ReadDataSourceRequest{
|
||||||
TypeName: n.Addr.Resource.Type,
|
TypeName: n.Addr.Resource.Type,
|
||||||
Config: change.After,
|
Config: change.After,
|
||||||
|
ProviderMeta: metaConfigVal,
|
||||||
})
|
})
|
||||||
diags = diags.Append(resp.Diagnostics.InConfigBody(n.Config.Config))
|
diags = diags.Append(resp.Diagnostics.InConfigBody(n.Config.Config))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
|
|
|
@ -6,7 +6,9 @@ import (
|
||||||
|
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/hashicorp/terraform/configs"
|
||||||
"github.com/hashicorp/terraform/providers"
|
"github.com/hashicorp/terraform/providers"
|
||||||
"github.com/hashicorp/terraform/states"
|
"github.com/hashicorp/terraform/states"
|
||||||
"github.com/hashicorp/terraform/tfdiags"
|
"github.com/hashicorp/terraform/tfdiags"
|
||||||
|
@ -18,6 +20,7 @@ type EvalRefresh struct {
|
||||||
Addr addrs.ResourceInstance
|
Addr addrs.ResourceInstance
|
||||||
ProviderAddr addrs.AbsProviderConfig
|
ProviderAddr addrs.AbsProviderConfig
|
||||||
Provider *providers.Interface
|
Provider *providers.Interface
|
||||||
|
ProviderMetas map[addrs.Provider]*configs.ProviderMeta
|
||||||
ProviderSchema **ProviderSchema
|
ProviderSchema **ProviderSchema
|
||||||
State **states.ResourceInstanceObject
|
State **states.ResourceInstanceObject
|
||||||
Output **states.ResourceInstanceObject
|
Output **states.ResourceInstanceObject
|
||||||
|
@ -42,6 +45,31 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
return nil, fmt.Errorf("provider does not support resource type %q", n.Addr.Resource.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metaConfigVal := cty.NullVal(cty.DynamicPseudoType)
|
||||||
|
if n.ProviderMetas != nil {
|
||||||
|
if m, ok := n.ProviderMetas[n.ProviderAddr.Provider]; ok && m != nil {
|
||||||
|
log.Printf("[DEBUG] EvalRefresh: ProviderMeta config value set")
|
||||||
|
// if the provider doesn't support this feature, throw an error
|
||||||
|
if (*n.ProviderSchema).ProviderMeta == nil {
|
||||||
|
log.Printf("[DEBUG] EvalRefresh: no ProviderMeta schema")
|
||||||
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", n.ProviderAddr.Provider.String()),
|
||||||
|
Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr),
|
||||||
|
Subject: &m.ProviderRange,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log.Printf("[DEBUG] EvalRefresh: ProviderMeta schema found: %+v", (*n.ProviderSchema).ProviderMeta)
|
||||||
|
var configDiags tfdiags.Diagnostics
|
||||||
|
metaConfigVal, _, configDiags = ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey)
|
||||||
|
diags = diags.Append(configDiags)
|
||||||
|
if configDiags.HasErrors() {
|
||||||
|
return nil, diags.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Call pre-refresh hook
|
// Call pre-refresh hook
|
||||||
err := ctx.Hook(func(h Hook) (HookAction, error) {
|
err := ctx.Hook(func(h Hook) (HookAction, error) {
|
||||||
return h.PreRefresh(absAddr, states.CurrentGen, state.Value)
|
return h.PreRefresh(absAddr, states.CurrentGen, state.Value)
|
||||||
|
@ -53,9 +81,10 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
// Refresh!
|
// Refresh!
|
||||||
priorVal := state.Value
|
priorVal := state.Value
|
||||||
req := providers.ReadResourceRequest{
|
req := providers.ReadResourceRequest{
|
||||||
TypeName: n.Addr.Resource.Type,
|
TypeName: n.Addr.Resource.Type,
|
||||||
PriorState: priorVal,
|
PriorState: priorVal,
|
||||||
Private: state.Private,
|
Private: state.Private,
|
||||||
|
ProviderMeta: metaConfigVal,
|
||||||
}
|
}
|
||||||
|
|
||||||
provider := *n.Provider
|
provider := *n.Provider
|
||||||
|
|
|
@ -349,6 +349,7 @@ type EvalValidateResource struct {
|
||||||
Provider *providers.Interface
|
Provider *providers.Interface
|
||||||
ProviderSchema **ProviderSchema
|
ProviderSchema **ProviderSchema
|
||||||
Config *configs.Resource
|
Config *configs.Resource
|
||||||
|
ProviderMetas map[addrs.Provider]*configs.ProviderMeta
|
||||||
|
|
||||||
// IgnoreWarnings means that warnings will not be passed through. This allows
|
// IgnoreWarnings means that warnings will not be passed through. This allows
|
||||||
// "just-in-time" passes of validation to continue execution through warnings.
|
// "just-in-time" passes of validation to continue execution through warnings.
|
||||||
|
@ -423,6 +424,40 @@ func (n *EvalValidateResource) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate the provider_meta block for the provider this resource
|
||||||
|
// belongs to, if there is one.
|
||||||
|
//
|
||||||
|
// Note: this will return an error for every resource a provider
|
||||||
|
// uses in a module, if the provider_meta for that module is
|
||||||
|
// incorrect. The only way to solve this that we've foudn is to
|
||||||
|
// insert a new ProviderMeta graph node in the graph, and make all
|
||||||
|
// that provider's resources in the module depend on the node. That's
|
||||||
|
// an awful heavy hammer to swing for this feature, which should be
|
||||||
|
// used only in limited cases with heavy coordination with the
|
||||||
|
// Terraform team, so we're going to defer that solution for a future
|
||||||
|
// enhancement to this functionality.
|
||||||
|
/*
|
||||||
|
if n.ProviderMetas != nil {
|
||||||
|
if m, ok := n.ProviderMetas[n.ProviderAddr.ProviderConfig.Type]; ok && m != nil {
|
||||||
|
// if the provider doesn't support this feature, throw an error
|
||||||
|
if (*n.ProviderSchema).ProviderMeta == nil {
|
||||||
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: fmt.Sprintf("Provider %s doesn't support provider_meta", cfg.ProviderConfigAddr()),
|
||||||
|
Detail: fmt.Sprintf("The resource %s belongs to a provider that doesn't support provider_meta blocks", n.Addr),
|
||||||
|
Subject: &m.ProviderRange,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
_, _, metaDiags := ctx.EvaluateBlock(m.Config, (*n.ProviderSchema).ProviderMeta, nil, EvalDataForNoInstanceKey)
|
||||||
|
diags = diags.Append(metaDiags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// BUG(paddy): we're not validating provider_meta blocks on EvalValidate right now
|
||||||
|
// because the ProviderAddr for the resource isn't available on the EvalValidate
|
||||||
|
// struct.
|
||||||
|
|
||||||
// Provider entry point varies depending on resource mode, because
|
// Provider entry point varies depending on resource mode, because
|
||||||
// managed resources and data resources are two distinct concepts
|
// managed resources and data resources are two distinct concepts
|
||||||
// in the provider abstraction.
|
// in the provider abstraction.
|
||||||
|
|
|
@ -15,12 +15,13 @@ type NodeRefreshableDataResource struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ GraphNodeSubPath = (*NodeRefreshableDataResource)(nil)
|
_ GraphNodeSubPath = (*NodeRefreshableDataResource)(nil)
|
||||||
_ GraphNodeDynamicExpandable = (*NodeRefreshableDataResource)(nil)
|
_ GraphNodeDynamicExpandable = (*NodeRefreshableDataResource)(nil)
|
||||||
_ GraphNodeReferenceable = (*NodeRefreshableDataResource)(nil)
|
_ GraphNodeReferenceable = (*NodeRefreshableDataResource)(nil)
|
||||||
_ GraphNodeReferencer = (*NodeRefreshableDataResource)(nil)
|
_ GraphNodeReferencer = (*NodeRefreshableDataResource)(nil)
|
||||||
_ GraphNodeResource = (*NodeRefreshableDataResource)(nil)
|
_ GraphNodeResource = (*NodeRefreshableDataResource)(nil)
|
||||||
_ GraphNodeAttachResourceConfig = (*NodeRefreshableDataResource)(nil)
|
_ GraphNodeAttachResourceConfig = (*NodeRefreshableDataResource)(nil)
|
||||||
|
_ GraphNodeAttachProviderMetaConfigs = (*NodeAbstractResource)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// GraphNodeDynamicExpandable
|
// GraphNodeDynamicExpandable
|
||||||
|
@ -76,6 +77,7 @@ func (n *NodeRefreshableDataResource) DynamicExpand(ctx EvalContext) (*Graph, er
|
||||||
// Add the config and state since we don't do that via transforms
|
// Add the config and state since we don't do that via transforms
|
||||||
a.Config = n.Config
|
a.Config = n.Config
|
||||||
a.ResolvedProvider = n.ResolvedProvider
|
a.ResolvedProvider = n.ResolvedProvider
|
||||||
|
a.ProviderMetas = n.ProviderMetas
|
||||||
|
|
||||||
return &NodeRefreshableDataResourceInstance{
|
return &NodeRefreshableDataResourceInstance{
|
||||||
NodeAbstractResourceInstance: a,
|
NodeAbstractResourceInstance: a,
|
||||||
|
@ -182,6 +184,7 @@ func (n *NodeRefreshableDataResourceInstance) EvalTree() EvalNode {
|
||||||
Config: n.Config,
|
Config: n.Config,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
OutputChange: &change,
|
OutputChange: &change,
|
||||||
OutputConfigValue: &configVal,
|
OutputConfigValue: &configVal,
|
||||||
|
|
|
@ -57,6 +57,9 @@ type NodeAbstractResource struct {
|
||||||
SchemaVersion uint64 // Schema version of "Schema", as decided by the provider
|
SchemaVersion uint64 // Schema version of "Schema", as decided by the provider
|
||||||
Config *configs.Resource // Config is the resource in the config
|
Config *configs.Resource // Config is the resource in the config
|
||||||
|
|
||||||
|
// ProviderMetas is the provider_meta configs for the module this resource belongs to
|
||||||
|
ProviderMetas map[addrs.Provider]*configs.ProviderMeta
|
||||||
|
|
||||||
ProvisionerSchemas map[string]*configschema.Block
|
ProvisionerSchemas map[string]*configschema.Block
|
||||||
|
|
||||||
Targets []addrs.Targetable // Set from GraphNodeTargetable
|
Targets []addrs.Targetable // Set from GraphNodeTargetable
|
||||||
|
@ -66,17 +69,18 @@ type NodeAbstractResource struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ GraphNodeSubPath = (*NodeAbstractResource)(nil)
|
_ GraphNodeSubPath = (*NodeAbstractResource)(nil)
|
||||||
_ GraphNodeReferenceable = (*NodeAbstractResource)(nil)
|
_ GraphNodeReferenceable = (*NodeAbstractResource)(nil)
|
||||||
_ GraphNodeReferencer = (*NodeAbstractResource)(nil)
|
_ GraphNodeReferencer = (*NodeAbstractResource)(nil)
|
||||||
_ GraphNodeProviderConsumer = (*NodeAbstractResource)(nil)
|
_ GraphNodeProviderConsumer = (*NodeAbstractResource)(nil)
|
||||||
_ GraphNodeProvisionerConsumer = (*NodeAbstractResource)(nil)
|
_ GraphNodeProvisionerConsumer = (*NodeAbstractResource)(nil)
|
||||||
_ GraphNodeResource = (*NodeAbstractResource)(nil)
|
_ GraphNodeResource = (*NodeAbstractResource)(nil)
|
||||||
_ GraphNodeAttachResourceConfig = (*NodeAbstractResource)(nil)
|
_ GraphNodeAttachResourceConfig = (*NodeAbstractResource)(nil)
|
||||||
_ GraphNodeAttachResourceSchema = (*NodeAbstractResource)(nil)
|
_ GraphNodeAttachResourceSchema = (*NodeAbstractResource)(nil)
|
||||||
_ GraphNodeAttachProvisionerSchema = (*NodeAbstractResource)(nil)
|
_ GraphNodeAttachProvisionerSchema = (*NodeAbstractResource)(nil)
|
||||||
_ GraphNodeTargetable = (*NodeAbstractResource)(nil)
|
_ GraphNodeAttachProviderMetaConfigs = (*NodeAbstractResource)(nil)
|
||||||
_ dag.GraphNodeDotter = (*NodeAbstractResource)(nil)
|
_ GraphNodeTargetable = (*NodeAbstractResource)(nil)
|
||||||
|
_ dag.GraphNodeDotter = (*NodeAbstractResource)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewNodeAbstractResource creates an abstract resource graph node for
|
// NewNodeAbstractResource creates an abstract resource graph node for
|
||||||
|
@ -104,19 +108,20 @@ type NodeAbstractResourceInstance struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ GraphNodeSubPath = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeSubPath = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeReferenceable = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeReferenceable = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeReferencer = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeReferencer = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeProviderConsumer = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeProviderConsumer = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeProvisionerConsumer = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeProvisionerConsumer = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeResource = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeResource = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeResourceInstance = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeResourceInstance = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeAttachResourceState = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeAttachResourceState = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeAttachResourceConfig = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeAttachResourceConfig = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeAttachResourceSchema = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeAttachResourceSchema = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeAttachProvisionerSchema = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeAttachProvisionerSchema = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ GraphNodeTargetable = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeAttachProviderMetaConfigs = (*NodeAbstractResourceInstance)(nil)
|
||||||
_ dag.GraphNodeDotter = (*NodeAbstractResourceInstance)(nil)
|
_ GraphNodeTargetable = (*NodeAbstractResourceInstance)(nil)
|
||||||
|
_ dag.GraphNodeDotter = (*NodeAbstractResourceInstance)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewNodeAbstractResourceInstance creates an abstract resource instance graph
|
// NewNodeAbstractResourceInstance creates an abstract resource instance graph
|
||||||
|
@ -404,6 +409,11 @@ func (n *NodeAbstractResource) AttachResourceSchema(schema *configschema.Block,
|
||||||
n.SchemaVersion = version
|
n.SchemaVersion = version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GraphNodeAttachProviderMetaConfigs impl
|
||||||
|
func (n *NodeAbstractResource) AttachProviderMetaConfigs(c map[addrs.Provider]*configs.ProviderMeta) {
|
||||||
|
n.ProviderMetas = c
|
||||||
|
}
|
||||||
|
|
||||||
// GraphNodeDotter impl.
|
// GraphNodeDotter impl.
|
||||||
func (n *NodeAbstractResource) DotNode(name string, opts *dag.DotOpts) *dag.DotNode {
|
func (n *NodeAbstractResource) DotNode(name string, opts *dag.DotOpts) *dag.DotNode {
|
||||||
return &dag.DotNode{
|
return &dag.DotNode{
|
||||||
|
|
|
@ -180,6 +180,7 @@ func (n *NodeApplyableResourceInstance) evalTreeDataResource(addr addrs.AbsResou
|
||||||
Planned: &change, // setting this indicates that the result must be complete
|
Planned: &change, // setting this indicates that the result must be complete
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
OutputState: &state,
|
OutputState: &state,
|
||||||
},
|
},
|
||||||
|
@ -287,6 +288,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||||
Config: n.Config,
|
Config: n.Config,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
State: &state,
|
State: &state,
|
||||||
PreviousDiff: &diff,
|
PreviousDiff: &diff,
|
||||||
|
@ -350,6 +352,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||||
Change: &diffApply,
|
Change: &diffApply,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
Output: &state,
|
Output: &state,
|
||||||
Error: &err,
|
Error: &err,
|
||||||
|
|
|
@ -246,6 +246,7 @@ func (n *NodeDestroyResourceInstance) EvalTree() EvalNode {
|
||||||
Change: &changeApply,
|
Change: &changeApply,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
Output: &state,
|
Output: &state,
|
||||||
Error: &err,
|
Error: &err,
|
||||||
|
|
|
@ -97,6 +97,7 @@ func (n *NodePlanDeposedResourceInstanceObject) EvalTree() EvalNode {
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
State: &state,
|
State: &state,
|
||||||
Output: &state,
|
Output: &state,
|
||||||
|
|
|
@ -104,6 +104,7 @@ func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
||||||
a.ResolvedProvider = n.ResolvedProvider
|
a.ResolvedProvider = n.ResolvedProvider
|
||||||
a.Schema = n.Schema
|
a.Schema = n.Schema
|
||||||
a.ProvisionerSchemas = n.ProvisionerSchemas
|
a.ProvisionerSchemas = n.ProvisionerSchemas
|
||||||
|
a.ProviderMetas = n.ProviderMetas
|
||||||
|
|
||||||
return &NodePlannableResourceInstance{
|
return &NodePlannableResourceInstance{
|
||||||
NodeAbstractResourceInstance: a,
|
NodeAbstractResourceInstance: a,
|
||||||
|
@ -122,6 +123,7 @@ func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
||||||
a.ResolvedProvider = n.ResolvedProvider
|
a.ResolvedProvider = n.ResolvedProvider
|
||||||
a.Schema = n.Schema
|
a.Schema = n.Schema
|
||||||
a.ProvisionerSchemas = n.ProvisionerSchemas
|
a.ProvisionerSchemas = n.ProvisionerSchemas
|
||||||
|
a.ProviderMetas = n.ProviderMetas
|
||||||
|
|
||||||
return &NodePlannableResourceInstanceOrphan{
|
return &NodePlannableResourceInstanceOrphan{
|
||||||
NodeAbstractResourceInstance: a,
|
NodeAbstractResourceInstance: a,
|
||||||
|
|
|
@ -116,6 +116,7 @@ func (n *NodePlannableResourceInstance) evalTreeDataResource(addr addrs.AbsResou
|
||||||
Config: n.Config,
|
Config: n.Config,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
ForcePlanRead: true, // _always_ produce a Read change, even if the config seems ready
|
ForcePlanRead: true, // _always_ produce a Read change, even if the config seems ready
|
||||||
OutputChange: &change,
|
OutputChange: &change,
|
||||||
|
@ -174,6 +175,7 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||||
CreateBeforeDestroy: n.ForceCreateBeforeDestroy,
|
CreateBeforeDestroy: n.ForceCreateBeforeDestroy,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
State: &state,
|
State: &state,
|
||||||
OutputChange: &change,
|
OutputChange: &change,
|
||||||
|
|
|
@ -85,6 +85,7 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph,
|
||||||
a.Config = n.Config
|
a.Config = n.Config
|
||||||
a.ResolvedProvider = n.ResolvedProvider
|
a.ResolvedProvider = n.ResolvedProvider
|
||||||
a.Dependencies = n.Dependencies
|
a.Dependencies = n.Dependencies
|
||||||
|
a.ProviderMetas = n.ProviderMetas
|
||||||
|
|
||||||
return &NodeRefreshableManagedResourceInstance{
|
return &NodeRefreshableManagedResourceInstance{
|
||||||
NodeAbstractResourceInstance: a,
|
NodeAbstractResourceInstance: a,
|
||||||
|
@ -237,6 +238,7 @@ func (n *NodeRefreshableManagedResourceInstance) evalTreeManagedResource() EvalN
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
ProviderAddr: n.ResolvedProvider,
|
ProviderAddr: n.ResolvedProvider,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
State: &state,
|
State: &state,
|
||||||
Output: &state,
|
Output: &state,
|
||||||
|
|
|
@ -15,12 +15,13 @@ type NodeValidatableResource struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ GraphNodeSubPath = (*NodeValidatableResource)(nil)
|
_ GraphNodeSubPath = (*NodeValidatableResource)(nil)
|
||||||
_ GraphNodeEvalable = (*NodeValidatableResource)(nil)
|
_ GraphNodeEvalable = (*NodeValidatableResource)(nil)
|
||||||
_ GraphNodeReferenceable = (*NodeValidatableResource)(nil)
|
_ GraphNodeReferenceable = (*NodeValidatableResource)(nil)
|
||||||
_ GraphNodeReferencer = (*NodeValidatableResource)(nil)
|
_ GraphNodeReferencer = (*NodeValidatableResource)(nil)
|
||||||
_ GraphNodeResource = (*NodeValidatableResource)(nil)
|
_ GraphNodeResource = (*NodeValidatableResource)(nil)
|
||||||
_ GraphNodeAttachResourceConfig = (*NodeValidatableResource)(nil)
|
_ GraphNodeAttachResourceConfig = (*NodeValidatableResource)(nil)
|
||||||
|
_ GraphNodeAttachProviderMetaConfigs = (*NodeValidatableResource)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// GraphNodeEvalable
|
// GraphNodeEvalable
|
||||||
|
@ -45,6 +46,7 @@ func (n *NodeValidatableResource) EvalTree() EvalNode {
|
||||||
&EvalValidateResource{
|
&EvalValidateResource{
|
||||||
Addr: addr.Resource,
|
Addr: addr.Resource,
|
||||||
Provider: &provider,
|
Provider: &provider,
|
||||||
|
ProviderMetas: n.ProviderMetas,
|
||||||
ProviderSchema: &providerSchema,
|
ProviderSchema: &providerSchema,
|
||||||
Config: config,
|
Config: config,
|
||||||
ConfigVal: &configVal,
|
ConfigVal: &configVal,
|
||||||
|
|
|
@ -118,6 +118,7 @@ func (p *MockProvider) getSchema() providers.GetSchemaResponse {
|
||||||
}
|
}
|
||||||
if p.GetSchemaReturn != nil {
|
if p.GetSchemaReturn != nil {
|
||||||
ret.Provider.Block = p.GetSchemaReturn.Provider
|
ret.Provider.Block = p.GetSchemaReturn.Provider
|
||||||
|
ret.ProviderMeta.Block = p.GetSchemaReturn.ProviderMeta
|
||||||
for n, s := range p.GetSchemaReturn.DataSources {
|
for n, s := range p.GetSchemaReturn.DataSources {
|
||||||
ret.DataSources[n] = providers.Schema{
|
ret.DataSources[n] = providers.Schema{
|
||||||
Block: s,
|
Block: s,
|
||||||
|
|
|
@ -164,6 +164,10 @@ func loadProviderSchemas(schemas map[addrs.Provider]*ProviderSchema, config *con
|
||||||
}
|
}
|
||||||
|
|
||||||
schemas[fqn] = s
|
schemas[fqn] = s
|
||||||
|
|
||||||
|
if resp.ProviderMeta.Block != nil {
|
||||||
|
s.ProviderMeta = resp.ProviderMeta.Block
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config != nil {
|
if config != nil {
|
||||||
|
@ -246,6 +250,7 @@ func loadProvisionerSchemas(schemas map[string]*configschema.Block, config *conf
|
||||||
// resource types and data sources used by that configuration.
|
// resource types and data sources used by that configuration.
|
||||||
type ProviderSchema struct {
|
type ProviderSchema struct {
|
||||||
Provider *configschema.Block
|
Provider *configschema.Block
|
||||||
|
ProviderMeta *configschema.Block
|
||||||
ResourceTypes map[string]*configschema.Block
|
ResourceTypes map[string]*configschema.Block
|
||||||
DataSources map[string]*configschema.Block
|
DataSources map[string]*configschema.Block
|
||||||
|
|
||||||
|
|
|
@ -1634,6 +1634,8 @@ type InstanceState struct {
|
||||||
// and collections.
|
// and collections.
|
||||||
Meta map[string]interface{} `json:"meta"`
|
Meta map[string]interface{} `json:"meta"`
|
||||||
|
|
||||||
|
ProviderMeta cty.Value
|
||||||
|
|
||||||
// Tainted is used to mark a resource for recreation.
|
// Tainted is used to mark a resource for recreation.
|
||||||
Tainted bool `json:"tainted"`
|
Tainted bool `json:"tainted"`
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
data "test_data_source" "foo" {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
provider_meta "test" {
|
||||||
|
baz = "quux"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module "my_module" {
|
||||||
|
source = "./my-module"
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
data "test_file" "foo" {
|
||||||
|
id = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
provider_meta "test" {
|
||||||
|
baz = "quux-submodule"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
data "test_data_source" "foo" {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
module "my_module" {
|
||||||
|
source = "./my-module"
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
data "test_file" "foo" {
|
||||||
|
id = "bar"
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
resource "test_instance" "bar" {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
provider_meta "test" {
|
||||||
|
baz = "quux"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module "my_module" {
|
||||||
|
source = "./my-module"
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
resource "test_resource" "bar" {
|
||||||
|
value = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
provider_meta "test" {
|
||||||
|
baz = "quux-submodule"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
resource "test_instance" "bar" {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
module "my_module" {
|
||||||
|
source = "./my-module"
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
resource "test_resource" "bar" {
|
||||||
|
value = "bar"
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/addrs"
|
||||||
|
"github.com/hashicorp/terraform/configs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GraphNodeAttachProviderMetaConfigs is an interface that must be implemented
|
||||||
|
// by nodes that want provider meta configurations attached.
|
||||||
|
type GraphNodeAttachProviderMetaConfigs interface {
|
||||||
|
GraphNodeResource
|
||||||
|
|
||||||
|
// Sets the configuration
|
||||||
|
AttachProviderMetaConfigs(map[addrs.Provider]*configs.ProviderMeta)
|
||||||
|
}
|
|
@ -56,6 +56,24 @@ func (t *AttachResourceConfigTransformer) Transform(g *Graph) error {
|
||||||
|
|
||||||
log.Printf("[TRACE] AttachResourceConfigTransformer: attaching to %q (%T) config from %s", dag.VertexName(v), v, r.DeclRange)
|
log.Printf("[TRACE] AttachResourceConfigTransformer: attaching to %q (%T) config from %s", dag.VertexName(v), v, r.DeclRange)
|
||||||
arn.AttachResourceConfig(r)
|
arn.AttachResourceConfig(r)
|
||||||
|
|
||||||
|
// attach the provider_meta info
|
||||||
|
if gnapmc, ok := v.(GraphNodeAttachProviderMetaConfigs); ok {
|
||||||
|
log.Printf("[TRACE] AttachResourceConfigTransformer: attaching provider meta configs to %s", dag.VertexName(v))
|
||||||
|
if config == nil {
|
||||||
|
log.Printf("[TRACE] AttachResourceConfigTransformer: no config set on the transformer for %s", dag.VertexName(v))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if config.Module == nil {
|
||||||
|
log.Printf("[TRACE] AttachResourceConfigTransformer: no module in config for %s", dag.VertexName(v))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if config.Module.ProviderMetas == nil {
|
||||||
|
log.Printf("[TRACE] AttachResourceConfigTransformer: no provider metas defined for %s", dag.VertexName(v))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gnapmc.AttachProviderMetaConfigs(config.Module.ProviderMetas)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, r := range config.Module.DataResources {
|
for _, r := range config.Module.DataResources {
|
||||||
rAddr := r.Addr()
|
rAddr := r.Addr()
|
||||||
|
@ -67,6 +85,24 @@ func (t *AttachResourceConfigTransformer) Transform(g *Graph) error {
|
||||||
|
|
||||||
log.Printf("[TRACE] AttachResourceConfigTransformer: attaching to %q (%T) config from %#v", dag.VertexName(v), v, r.DeclRange)
|
log.Printf("[TRACE] AttachResourceConfigTransformer: attaching to %q (%T) config from %#v", dag.VertexName(v), v, r.DeclRange)
|
||||||
arn.AttachResourceConfig(r)
|
arn.AttachResourceConfig(r)
|
||||||
|
|
||||||
|
// attach the provider_meta info
|
||||||
|
if gnapmc, ok := v.(GraphNodeAttachProviderMetaConfigs); ok {
|
||||||
|
log.Printf("[TRACE] AttachResourceConfigTransformer: attaching provider meta configs to %s", dag.VertexName(v))
|
||||||
|
if config == nil {
|
||||||
|
log.Printf("[TRACE] AttachResourceConfigTransformer: no config set on the transformer for %s", dag.VertexName(v))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if config.Module == nil {
|
||||||
|
log.Printf("[TRACE] AttachResourceConfigTransformer: no module in config for %s", dag.VertexName(v))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if config.Module.ProviderMetas == nil {
|
||||||
|
log.Printf("[TRACE] AttachResourceConfigTransformer: no provider metas defined for %s", dag.VertexName(v))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gnapmc.AttachProviderMetaConfigs(config.Module.ProviderMetas)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,3 +179,11 @@ The introduction and completion of experiments is reported in
|
||||||
[Terraform's changelog](https://github.com/hashicorp/terraform/blob/master/CHANGELOG.md),
|
[Terraform's changelog](https://github.com/hashicorp/terraform/blob/master/CHANGELOG.md),
|
||||||
so you can watch the release notes there to discover which experiment keywords,
|
so you can watch the release notes there to discover which experiment keywords,
|
||||||
if any, are available in a particular Terraform release.
|
if any, are available in a particular Terraform release.
|
||||||
|
|
||||||
|
## Passing Metadata to Providers
|
||||||
|
|
||||||
|
The `terraform` block can have a nested `provider_meta` block for each
|
||||||
|
provider a module is using, if the provider defines a schema for it. This
|
||||||
|
allows the provider to receive module-specific information. No interpolations
|
||||||
|
are performed on this block. For more information, see the
|
||||||
|
[`provider_meta` page](/docs/internals/provider-meta.html).
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
---
|
||||||
|
layout: "docs"
|
||||||
|
page_title: "Provider Metadata"
|
||||||
|
sidebar_current: "docs-internals-provider-meta"
|
||||||
|
description: |-
|
||||||
|
For advanced use cases, modules can provide some pre-defined metadata for providers.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Provider Metadata
|
||||||
|
|
||||||
|
In some situations it's beneficial for a provider to offer an interface
|
||||||
|
through which modules can pass it information unrelated to the resources
|
||||||
|
in the module, but scoped on a per-module basis. The provider metadata
|
||||||
|
functionality allows a provider to do this in a straightforward way.
|
||||||
|
|
||||||
|
~> **Advanced Topic!** This page covers technical details
|
||||||
|
of Terraform. You don't need to understand these details to
|
||||||
|
effectively use Terraform. The details are documented here for
|
||||||
|
module authors and provider developers working on advanced
|
||||||
|
functionality.
|
||||||
|
|
||||||
|
~> **Experimental Feature!** This functionality is still considered
|
||||||
|
experimental, and anyone taking advantage of it should [coordinate
|
||||||
|
with the Terraform team](https://github.com/hashicorp/terraform/issues/new)
|
||||||
|
to help the team understand how the feature is being used and to make
|
||||||
|
sure their use case is taken into account as the feature develops.
|
||||||
|
|
||||||
|
## Defining the Schema
|
||||||
|
|
||||||
|
Before a provider can receive information from a module, the provider
|
||||||
|
must strictly define the data it can accept. You can do this by setting
|
||||||
|
the `ProviderMeta` property on your `schema.Provider` struct. Its value
|
||||||
|
functions similarly to the provider config: a map of strings to the
|
||||||
|
`schema.Schema` describing the values those strings accept.
|
||||||
|
|
||||||
|
## Using the Data
|
||||||
|
|
||||||
|
When Terraform calls your provider, you can use the `schema.ResourceData`
|
||||||
|
that your `Create`, `Read`, and `Update` functions already use to get
|
||||||
|
access to the provider metadata being passed. First define a struct
|
||||||
|
that matches your schema, then call the `GetProviderSchema` method on
|
||||||
|
your `schema.ResourceData`, passing a pointer to a variable of that type.
|
||||||
|
The variable will be populated with the provider metadata, and will return
|
||||||
|
an error if there was an issue with parsing the data into the struct.
|
||||||
|
|
||||||
|
## Specifying Data in Modules
|
||||||
|
|
||||||
|
To include data in your modules, create a `provider_meta` nested block under
|
||||||
|
your module's `terraform` block, with the name of the provider it's trying
|
||||||
|
to pass information to:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
terraform {
|
||||||
|
provider_meta "my-provider" {
|
||||||
|
hello = "world"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `provider_meta` block must match the schema the provider has defined.
|
||||||
|
|
||||||
|
## Versioning Your Modules
|
||||||
|
|
||||||
|
Any module taking advantage of this functionality must make sure that the
|
||||||
|
provider metadata supplied matches the schema defined in the provider, and
|
||||||
|
that the version of Terraform that is being run has support for the provider
|
||||||
|
metadata functionality. It's therefore recommended that any module taking
|
||||||
|
advantage of this functionality should specify a minimum Terraform version of
|
||||||
|
0.13.0 or higher, and a minimum version of each of the providers it specifies
|
||||||
|
metadata as the first version the schema being used was supported by the
|
||||||
|
provider.
|
|
@ -472,6 +472,10 @@
|
||||||
<li<%= sidebar_current("docs-internals-plugins") %>>
|
<li<%= sidebar_current("docs-internals-plugins") %>>
|
||||||
<a href="/docs/internals/internal-plugins.html">Internal Plugins</a>
|
<a href="/docs/internals/internal-plugins.html">Internal Plugins</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-internals-provider-meta") %>>
|
||||||
|
<a href="/docs/internals/provider-meta.html">Provider Metadata</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue