From 5e1d2303fb23c12c7c623c3535c93d00396dc9c2 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Wed, 2 Oct 2024 15:41:12 +0100 Subject: [PATCH] jsonprovider: Expose ephemeral resource schemas (#35800) * jsonprovider: Expose ephemeral resource schemas * add ephemeral resource to the test --- internal/command/jsonprovider/provider.go | 18 ++-- .../command/jsonprovider/provider_test.go | 101 +++++++++++++++++- internal/schemarepo/loadschemas/plugins.go | 6 ++ 3 files changed, 112 insertions(+), 13 deletions(-) diff --git a/internal/command/jsonprovider/provider.go b/internal/command/jsonprovider/provider.go index 8d4036103d..6ec6f65a0b 100644 --- a/internal/command/jsonprovider/provider.go +++ b/internal/command/jsonprovider/provider.go @@ -23,10 +23,11 @@ type Providers struct { } type Provider struct { - Provider *Schema `json:"provider,omitempty"` - ResourceSchemas map[string]*Schema `json:"resource_schemas,omitempty"` - DataSourceSchemas map[string]*Schema `json:"data_source_schemas,omitempty"` - Functions map[string]*jsonfunction.FunctionSignature `json:"functions,omitempty"` + Provider *Schema `json:"provider,omitempty"` + ResourceSchemas map[string]*Schema `json:"resource_schemas,omitempty"` + DataSourceSchemas map[string]*Schema `json:"data_source_schemas,omitempty"` + EphemeralResourceSchemas map[string]*Schema `json:"ephemeral_resource_schemas,omitempty"` + Functions map[string]*jsonfunction.FunctionSignature `json:"functions,omitempty"` } func newProviders() *Providers { @@ -58,9 +59,10 @@ func Marshal(s *terraform.Schemas) ([]byte, error) { func marshalProvider(tps providers.ProviderSchema) *Provider { return &Provider{ - Provider: marshalSchema(tps.Provider), - ResourceSchemas: marshalSchemas(tps.ResourceTypes), - DataSourceSchemas: marshalSchemas(tps.DataSources), - Functions: jsonfunction.MarshalProviderFunctions(tps.Functions), + Provider: marshalSchema(tps.Provider), + ResourceSchemas: marshalSchemas(tps.ResourceTypes), + DataSourceSchemas: marshalSchemas(tps.DataSources), + EphemeralResourceSchemas: marshalSchemas(tps.EphemeralResourceTypes), + Functions: jsonfunction.MarshalProviderFunctions(tps.Functions), } } diff --git a/internal/command/jsonprovider/provider_test.go b/internal/command/jsonprovider/provider_test.go index 6d4818455b..08c46babfb 100644 --- a/internal/command/jsonprovider/provider_test.go +++ b/internal/command/jsonprovider/provider_test.go @@ -26,9 +26,10 @@ func TestMarshalProvider(t *testing.T) { { providers.ProviderSchema{}, &Provider{ - Provider: &Schema{}, - ResourceSchemas: map[string]*Schema{}, - DataSourceSchemas: map[string]*Schema{}, + Provider: &Schema{}, + ResourceSchemas: map[string]*Schema{}, + DataSourceSchemas: map[string]*Schema{}, + EphemeralResourceSchemas: map[string]*Schema{}, }, }, { @@ -147,6 +148,65 @@ func TestMarshalProvider(t *testing.T) { }, }, }, + EphemeralResourceSchemas: map[string]*Schema{ + "test_eph_instance": { + Block: &Block{ + Attributes: map[string]*Attribute{ + "id": { + AttributeType: json.RawMessage(`"string"`), + Optional: true, + Computed: true, + DescriptionKind: "plain", + }, + "ami": { + AttributeType: json.RawMessage(`"string"`), + Optional: true, + DescriptionKind: "plain", + }, + "volumes": { + AttributeNestedType: &NestedType{ + NestingMode: "list", + Attributes: map[string]*Attribute{ + "size": { + AttributeType: json.RawMessage(`"string"`), + Required: true, + DescriptionKind: "plain", + }, + "mount_point": { + AttributeType: json.RawMessage(`"string"`), + Required: true, + DescriptionKind: "plain", + }, + }, + }, + Optional: true, + DescriptionKind: "plain", + }, + }, + BlockTypes: map[string]*BlockType{ + "network_interface": { + Block: &Block{ + Attributes: map[string]*Attribute{ + "device_index": { + AttributeType: json.RawMessage(`"string"`), + Optional: true, + DescriptionKind: "plain", + }, + "description": { + AttributeType: json.RawMessage(`"string"`), + Optional: true, + DescriptionKind: "plain", + }, + }, + DescriptionKind: "plain", + }, + NestingMode: "list", + }, + }, + DescriptionKind: "plain", + }, + }, + }, }, }, } @@ -154,8 +214,8 @@ func TestMarshalProvider(t *testing.T) { for i, test := range tests { t.Run(fmt.Sprint(i), func(t *testing.T) { got := marshalProvider(test.Input) - if !cmp.Equal(got, test.Want, cmpOpts) { - t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, test.Want, cmpOpts)) + if diff := cmp.Diff(test.Want, got, cmpOpts); diff != "" { + t.Fatalf("wrong result:\n %s\n", diff) } }) } @@ -224,5 +284,36 @@ func testProvider() providers.ProviderSchema { }, }, }, + EphemeralResourceTypes: map[string]providers.Schema{ + "test_eph_instance": { + Block: &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "id": {Type: cty.String, Optional: true, Computed: true}, + "ami": {Type: cty.String, Optional: true}, + "volumes": { + Optional: true, + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "size": {Type: cty.String, Required: true}, + "mount_point": {Type: cty.String, Required: true}, + }, + }, + }, + }, + BlockTypes: map[string]*configschema.NestedBlock{ + "network_interface": { + Nesting: configschema.NestingList, + Block: configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "device_index": {Type: cty.String, Optional: true}, + "description": {Type: cty.String, Optional: true}, + }, + }, + }, + }, + }, + }, + }, } } diff --git a/internal/schemarepo/loadschemas/plugins.go b/internal/schemarepo/loadschemas/plugins.go index 1bff1dbf4b..dfd21c55f4 100644 --- a/internal/schemarepo/loadschemas/plugins.go +++ b/internal/schemarepo/loadschemas/plugins.go @@ -154,6 +154,12 @@ func (cp *Plugins) ProviderSchema(addr addrs.Provider) (providers.ProviderSchema } } + for t, r := range resp.EphemeralResourceTypes { + if err := r.Block.InternalValidate(); err != nil { + return resp, fmt.Errorf("provider %s has invalid schema for ephemeral resource type %q, which is a bug in the provider: %q", addr, t, err) + } + } + for n, f := range resp.Functions { if !hclsyntax.ValidIdentifier(n) { return resp, fmt.Errorf("provider %s declares function with invalid name %q", addr, n)