Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

DNM: hack: terraform-plugin-framework and dynamic types#354

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
johnstcn wants to merge4 commits intomain
base:main
Choose a base branch
Loading
fromcj/hack/parameter-dynamic-type
Draft
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletionsMakefile
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ build: terraform-provider-coder

# Builds the provider. Note that as coder/coder is based on
# alpine, we need to disable cgo.
terraform-provider-coder: provider/*.go main.go
terraform-provider-coder: provider/*.gotpfprovider/*.gomain.go
CGO_ENABLED=0 go build .

# Run integration tests
Expand All@@ -22,4 +22,4 @@ test-integration: terraform-provider-coder
# Run acceptance tests
.PHONY: testacc
testacc:
TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
TF_ACC=1 go test ./... -v-count=1$(TESTARGS) -timeout 120m
3 changes: 3 additions & 0 deletionsgo.mod
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,8 +49,11 @@ require (
github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.22.0 // indirect
github.com/hashicorp/terraform-json v0.24.0 // indirect
github.com/hashicorp/terraform-plugin-framework v1.14.1 // indirect
github.com/hashicorp/terraform-plugin-go v0.26.0 // indirect
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
github.com/hashicorp/terraform-plugin-mux v0.18.0 // indirect
github.com/hashicorp/terraform-plugin-testing v1.11.0 // indirect
github.com/hashicorp/terraform-registry-address v0.2.4 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
Expand Down
6 changes: 6 additions & 0 deletionsgo.sum
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,12 +105,18 @@ github.com/hashicorp/terraform-exec v0.22.0 h1:G5+4Sz6jYZfRYUCg6eQgDsqTzkNXV+fP8
github.com/hashicorp/terraform-exec v0.22.0/go.mod h1:bjVbsncaeh8jVdhttWYZuBGj21FcYw6Ia/XfHcNO7lQ=
github.com/hashicorp/terraform-json v0.24.0 h1:rUiyF+x1kYawXeRth6fKFm/MdfBS6+lW4NbeATsYz8Q=
github.com/hashicorp/terraform-json v0.24.0/go.mod h1:Nfj5ubo9xbu9uiAoZVBsNOjvNKB66Oyrvtit74kC7ow=
github.com/hashicorp/terraform-plugin-framework v1.14.1 h1:jaT1yvU/kEKEsxnbrn4ZHlgcxyIfjvZ41BLdlLk52fY=
github.com/hashicorp/terraform-plugin-framework v1.14.1/go.mod h1:xNUKmvTs6ldbwTuId5euAtg37dTxuyj3LHS3uj7BHQ4=
github.com/hashicorp/terraform-plugin-go v0.26.0 h1:cuIzCv4qwigug3OS7iKhpGAbZTiypAfFQmw8aE65O2M=
github.com/hashicorp/terraform-plugin-go v0.26.0/go.mod h1:+CXjuLDiFgqR+GcrM5a2E2Kal5t5q2jb0E3D57tTdNY=
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
github.com/hashicorp/terraform-plugin-mux v0.18.0 h1:7491JFSpWyAe0v9YqBT+kel7mzHAbO5EpxxT0cUL/Ms=
github.com/hashicorp/terraform-plugin-mux v0.18.0/go.mod h1:Ho1g4Rr8qv0qTJlcRKfjjXTIO67LNbDtM6r+zHUNHJQ=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0 h1:7/iejAPyCRBhqAg3jOx+4UcAhY0A+Sg8B+0+d/GxSfM=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0/go.mod h1:TiQwXAjFrgBf5tg5rvBRz8/ubPULpU0HjSaVi5UoJf8=
github.com/hashicorp/terraform-plugin-testing v1.11.0 h1:MeDT5W3YHbONJt2aPQyaBsgQeAIckwPX41EUHXEn29A=
github.com/hashicorp/terraform-plugin-testing v1.11.0/go.mod h1:WNAHQ3DcgV/0J+B15WTE6hDvxcUdkPPpnB1FR3M910U=
github.com/hashicorp/terraform-registry-address v0.2.4 h1:JXu/zHB2Ymg/TGVCRu10XqNa4Sh2bWcqCNyKWjnCPJA=
github.com/hashicorp/terraform-registry-address v0.2.4/go.mod h1:tUNYTVyCtU4OIGXXMDp7WNcJ+0W1B4nmstVDgHMjfAU=
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
Expand Down
55 changes: 51 additions & 4 deletionsmain.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,65 @@
package main

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
"context"
"flag"
"log"

"github.com/hashicorp/terraform-plugin-framework/providerserver"

"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server"
"github.com/hashicorp/terraform-plugin-mux/tf5to6server"
"github.com/hashicorp/terraform-plugin-mux/tf6muxserver"

"github.com/coder/terraform-provider-coder/v2/provider"
"github.com/coder/terraform-provider-coder/v2/tpfprovider"
)

// Run the docs generation tool, check its repository for more information on how it works and how docs
// can be customized.
//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs

func main() {
ctx := context.Background()
var debug bool
flag.BoolVar(&debug, "debug", false, "enable debug logging")
flag.Parse()

servePprof()
plugin.Serve(&plugin.ServeOpts{
ProviderFunc: provider.New,
})

upgradedSDKServer, err := tf5to6server.UpgradeServer(
ctx,
provider.New().GRPCProvider,
)
if err != nil {
log.Fatal(err)
}

providers := []func() tfprotov6.ProviderServer{
providerserver.NewProtocol6(tpfprovider.NewFrameworkProvider()()),
func() tfprotov6.ProviderServer {
return upgradedSDKServer
},
}

muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...)
if err != nil {
log.Fatal(err)
}

var serveOpts []tf6server.ServeOpt
if debug {
serveOpts = append(serveOpts, tf6server.WithManagedDebug())
}

err = tf6server.Serve(
"registry.terraform.io/coder/coder",
muxServer.ProviderServer,
serveOpts...,
)

if err != nil {
log.Fatal(err)
}
}
100 changes: 100 additions & 0 deletionstpfprovider/parameter.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
package tpfprovider

import (
"context"
"encoding/json"
"math/big"
"os"
"strings"

"github.com/coder/terraform-provider-coder/v2/provider"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

type parameterDataSourceModel struct {
Name types.String `tfsdk:"name"`
Type types.Dynamic `tfsdk:"type"`
Value types.Dynamic `tfsdk:"value"`
}

type parameterDataSource struct{}

func NewParameterDataSource() datasource.DataSource {
return &parameterDataSource{}
}

func (m *parameterDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = "coder_parameter"
}

func (m *parameterDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Required: true,
},
"type": schema.DynamicAttribute{
Required: true,
},
"value": schema.DynamicAttribute{
Computed: true,
},
},
}
}

func (m *parameterDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data parameterDataSourceModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}

if data.Name.IsNull() {
resp.Diagnostics.AddError("name is required", "name")
return
}

ds := data.Name.ValueString()
parameterEnv := provider.ParameterEnvironmentVariable(ds)
rawValue, ok := os.LookupEnv(parameterEnv)
if !ok {
resp.Diagnostics.AddError("parameter not found", "name")
return
}

switch data.Type.UnderlyingValue().(type) {
case types.String:
data.Value = types.DynamicValue(types.StringValue(rawValue))
case types.Number:
// convert the raw value to a number
var floatVal float64
if err := json.NewDecoder(strings.NewReader(rawValue)).Decode(&floatVal); err != nil {
resp.Diagnostics.AddError("failed to parse value as number", "value")
return
}

data.Value = types.DynamicValue(types.NumberValue(big.NewFloat(floatVal)))
case types.Bool:
// convert the raw value to a bool
var boolVal bool
if err := json.NewDecoder(strings.NewReader(rawValue)).Decode(&boolVal); err != nil {
resp.Diagnostics.AddError("failed to parse value as bool", "value")
return
}
data.Value = types.DynamicValue(types.BoolValue(boolVal))
case types.List:
// TODO: handle list
resp.Diagnostics.AddError("TODO: list type not supported", "type")
return
case types.Map:
// TODO: handle map
resp.Diagnostics.AddError("TODO: map type not supported", "type")
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
151 changes: 151 additions & 0 deletionstpfprovider/parameter_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
package tpfprovider

import (
"fmt"
"os"
"testing"

"github.com/coder/terraform-provider-coder/v2/provider"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
)

func TestAccParameterDataSource(t *testing.T) {
t.Run("string", func(t *testing.T) {
t.Setenv(provider.ParameterEnvironmentVariable("test"), "test")
resource.Test(t, resource.TestCase{
IsUnitTest: true,
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{{
Config: `
provider coder {}
data "coder_parameter" "test" {
name = "test"
type = ""
}`,
Check: resource.ComposeAggregateTestCheckFunc(
testParameterEnv("test", "test"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "type", ""),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value", "test"),
),
}},
})
})

t.Run("number", func(t *testing.T) {
t.Setenv(provider.ParameterEnvironmentVariable("test"), "3.14")
resource.Test(t, resource.TestCase{
IsUnitTest: true,
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{{
Config: `
provider coder {}
data "coder_parameter" "test" {
name = "test"
type = 0
}`,
Check: resource.ComposeAggregateTestCheckFunc(
testParameterEnv("test", "3.14"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "type", "0"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value", "3.14"),
),
}},
})
})

t.Run("bool", func(t *testing.T) {
t.Setenv(provider.ParameterEnvironmentVariable("test"), "true")
resource.Test(t, resource.TestCase{
IsUnitTest: true,
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{{
Config: `
provider coder {}
data "coder_parameter" "test" {
name = "test"
type = false
}`,
Check: resource.ComposeAggregateTestCheckFunc(
testParameterEnv("test", "true"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "type", "false"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value", "true"),
),
}},
})
})

t.Run("list of string", func(t *testing.T) {
t.Skip("TODO: not implemented yet")
t.Setenv(provider.ParameterEnvironmentVariable("test"), `["a","b","c"]`)
resource.Test(t, resource.TestCase{
IsUnitTest: true,
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{{
Config: `
provider coder {}
data "coder_parameter" "test" {
name = "test"
type = [""]
}`,
Check: resource.ComposeAggregateTestCheckFunc(
testParameterEnv("test", `["a","b","c"]`),
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
resource.TestCheckTypeSetElemAttr("data.coder_parameter.test", "type*", "[]"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.#", "3"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.0", "a"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.1", "b"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.2", "c"),
),
}},
})
})

t.Run("list of number", func(t *testing.T) {
t.Skip("TODO: not implemented yet")
t.Setenv(provider.ParameterEnvironmentVariable("test"), `[1, 2, 3]`)
resource.Test(t, resource.TestCase{
IsUnitTest: true,
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{{
Config: `
provider coder {}
data "coder_parameter" "test" {
name = "test"
type = [0]
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
testParameterEnv("test", `[1,2,3]`),
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
resource.TestCheckTypeSetElemAttr("data.coder_parameter.test", "type*", "[]"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.#", "3"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.0", "1"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.1", "2"),
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.2", "3"),
),
}},
})
})
}

func testParameterEnv(name, value string) func(*terraform.State) error {
return func(*terraform.State) error {
penv := provider.ParameterEnvironmentVariable("test")
val, ok := os.LookupEnv(penv)
if !ok {
return fmt.Errorf("parameter environment variable %q not set", penv)
}
if val != value {
return fmt.Errorf("parameter environment variable %q has unexpected value %q", penv, val)
}
return nil
}
}
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp