Skip to content

Commit

Permalink
terraform provider: terraform_random_number ephemeral resource type
Browse files Browse the repository at this point in the history
Similar to terraform_data, this is really just here to use as a
placeholder when one needs an ephemeral resource for some reason but
doesn't need any specific one.

This might get removed before the ephemeral_values experiment gets
stabilized. For now it's here to use as an initial testing vehicle since
we don't have any mechanism for offering experimental features in the
provider plugin protocol, whereas this provider is not a plugin.
  • Loading branch information
apparentlymart committed Apr 29, 2024
1 parent e1bf50a commit 1d7f970
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 10 deletions.
45 changes: 45 additions & 0 deletions internal/builtin/providers/terraform/ephemeral_random.go
@@ -0,0 +1,45 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package terraform

import (
"math/rand"

"github.com/zclconf/go-cty/cty"

"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/providers"
)

func ephemeralRandomNumberSchema() providers.Schema {
return providers.Schema{
Block: &configschema.Block{
Attributes: map[string]*configschema.Attribute{
"value": {Type: cty.String, Computed: true},
},
},
}
}

func openEphemeralRandomNumber(req providers.OpenEphemeralRequest) providers.OpenEphemeralResponse {
result := rand.NormFloat64()
return providers.OpenEphemeralResponse{
Result: cty.ObjectVal(map[string]cty.Value{
"value": cty.NumberFloatVal(result),
}),
}
}

func renewEphemeralRandomNumber(req providers.RenewEphemeralRequest) providers.RenewEphemeralResponse {
// This resource type does not need renewing, but if we get asked to do
// it for some reason then we'll just say it succeeded.
return providers.RenewEphemeralResponse{}
}

func closeEphemeralRandomNumber(req providers.CloseEphemeralRequest) providers.CloseEphemeralResponse {
// This resource type does not need closing because it isn't really
// backed by any long-lived object, so we'll just say that closing it
// succeeded even though we aren't really doing anything.
return providers.CloseEphemeralResponse{}
}
39 changes: 30 additions & 9 deletions internal/builtin/providers/terraform/provider.go
Expand Up @@ -29,6 +29,9 @@ func (p *Provider) GetProviderSchema() providers.GetProviderSchemaResponse {
ResourceTypes: map[string]providers.Schema{
"terraform_data": dataStoreResourceSchema(),
},
EphemeralResourceTypes: map[string]providers.Schema{
"terraform_random_number": ephemeralRandomNumberSchema(),
},
Functions: map[string]providers.FunctionDecl{
"encode_tfvars": {
Summary: "Produce a string representation of an object using the same syntax as for `.tfvars` files",
Expand Down Expand Up @@ -180,19 +183,37 @@ func (p *Provider) ValidateResourceConfig(req providers.ValidateResourceConfigRe
return validateDataStoreResourceConfig(req)
}

// CloseEphemeral implements providers.Interface.
func (p *Provider) CloseEphemeral(providers.CloseEphemeralRequest) providers.CloseEphemeralResponse {
panic("unimplemented - terraform.io/builtin/terraform has no ephemeral resource types")
}

// OpenEphemeral implements providers.Interface.
func (p *Provider) OpenEphemeral(providers.OpenEphemeralRequest) providers.OpenEphemeralResponse {
panic("unimplemented - terraform.io/builtin/terraform has no ephemeral resource types")
func (p *Provider) OpenEphemeral(req providers.OpenEphemeralRequest) providers.OpenEphemeralResponse {
if req.TypeName != "terraform_random_number" {
// This should not happen
var resp providers.OpenEphemeralResponse
resp.Diagnostics.Append(fmt.Errorf("unsupported ephemeral resource type %q", req.TypeName))
return resp
}
return openEphemeralRandomNumber(req)
}

// RenewEphemeral implements providers.Interface.
func (p *Provider) RenewEphemeral(providers.RenewEphemeralRequest) providers.RenewEphemeralResponse {
panic("unimplemented - terraform.io/builtin/terraform has no ephemeral resource types")
func (p *Provider) RenewEphemeral(req providers.RenewEphemeralRequest) providers.RenewEphemeralResponse {
if req.TypeName != "terraform_random_number" {
// This should not happen
var resp providers.RenewEphemeralResponse
resp.Diagnostics.Append(fmt.Errorf("unsupported ephemeral resource type %q", req.TypeName))
return resp
}
return renewEphemeralRandomNumber(req)
}

// CloseEphemeral implements providers.Interface.
func (p *Provider) CloseEphemeral(req providers.CloseEphemeralRequest) providers.CloseEphemeralResponse {
if req.TypeName != "terraform_random_number" {
// This should not happen
var resp providers.CloseEphemeralResponse
resp.Diagnostics.Append(fmt.Errorf("unsupported ephemeral resource type %q", req.TypeName))
return resp
}
return closeEphemeralRandomNumber(req)
}

// CallFunction would call a function contributed by this provider, but this
Expand Down
2 changes: 1 addition & 1 deletion internal/configs/resource.go
Expand Up @@ -537,7 +537,7 @@ func decodeDataBlock(block *hcl.Block, override, nested bool) (*Resource, hcl.Di
func decodeEphemeralBlock(block *hcl.Block, override bool) (*Resource, hcl.Diagnostics) {
var diags hcl.Diagnostics
r := &Resource{
Mode: addrs.DataResourceMode,
Mode: addrs.EphemeralResourceMode,
Type: block.Labels[0],
Name: block.Labels[1],
DeclRange: block.DefRange,
Expand Down

0 comments on commit 1d7f970

Please sign in to comment.