Skip to content

Commit a6a38f5

Browse files
committed
somewhat working i guess
1 parent a118a87 commit a6a38f5

File tree

7 files changed

+278
-4
lines changed

7 files changed

+278
-4
lines changed

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ require (
5353
github.com/hashicorp/terraform-plugin-go v0.26.0 // indirect
5454
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
5555
github.com/hashicorp/terraform-plugin-mux v0.18.0 // indirect
56+
github.com/hashicorp/terraform-plugin-testing v1.11.0 // indirect
5657
github.com/hashicorp/terraform-registry-address v0.2.4 // indirect
5758
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
5859
github.com/hashicorp/yamux v0.1.1 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ github.com/hashicorp/terraform-plugin-mux v0.18.0 h1:7491JFSpWyAe0v9YqBT+kel7mzH
115115
github.com/hashicorp/terraform-plugin-mux v0.18.0/go.mod h1:Ho1g4Rr8qv0qTJlcRKfjjXTIO67LNbDtM6r+zHUNHJQ=
116116
github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0 h1:7/iejAPyCRBhqAg3jOx+4UcAhY0A+Sg8B+0+d/GxSfM=
117117
github.com/hashicorp/terraform-plugin-sdk/v2 v2.36.0/go.mod h1:TiQwXAjFrgBf5tg5rvBRz8/ubPULpU0HjSaVi5UoJf8=
118+
github.com/hashicorp/terraform-plugin-testing v1.11.0 h1:MeDT5W3YHbONJt2aPQyaBsgQeAIckwPX41EUHXEn29A=
119+
github.com/hashicorp/terraform-plugin-testing v1.11.0/go.mod h1:WNAHQ3DcgV/0J+B15WTE6hDvxcUdkPPpnB1FR3M910U=
118120
github.com/hashicorp/terraform-registry-address v0.2.4 h1:JXu/zHB2Ymg/TGVCRu10XqNa4Sh2bWcqCNyKWjnCPJA=
119121
github.com/hashicorp/terraform-registry-address v0.2.4/go.mod h1:tUNYTVyCtU4OIGXXMDp7WNcJ+0W1B4nmstVDgHMjfAU=
120122
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=

main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func main() {
3737
}
3838

3939
providers := []func() tfprotov6.ProviderServer{
40-
providerserver.NewProtocol6(tpfprovider.NewFrameworkProvider()),
40+
providerserver.NewProtocol6(tpfprovider.NewFrameworkProvider()()),
4141
func() tfprotov6.ProviderServer {
4242
return upgradedSDKServer
4343
},

tpfprovider/parameter.go

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package tpfprovider
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"math/big"
7+
"os"
8+
"strings"
9+
10+
"github.com/coder/terraform-provider-coder/v2/provider"
11+
"github.com/hashicorp/terraform-plugin-framework/datasource"
12+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
13+
"github.com/hashicorp/terraform-plugin-framework/types"
14+
)
15+
16+
type parameterDataSourceModel struct {
17+
Name types.String `tfsdk:"name"`
18+
Type types.Dynamic `tfsdk:"type"`
19+
Value types.Dynamic `tfsdk:"value"`
20+
}
21+
22+
type parameterDataSource struct{}
23+
24+
func NewParameterDataSource() datasource.DataSource {
25+
return &parameterDataSource{}
26+
}
27+
28+
func (m *parameterDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
29+
resp.TypeName = "coder_parameter"
30+
}
31+
32+
func (m *parameterDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
33+
resp.Schema = schema.Schema{
34+
Attributes: map[string]schema.Attribute{
35+
"name": schema.StringAttribute{
36+
Required: true,
37+
},
38+
"type": schema.DynamicAttribute{
39+
Required: true,
40+
},
41+
"value": schema.DynamicAttribute{
42+
Computed: true,
43+
},
44+
},
45+
}
46+
}
47+
48+
func (m *parameterDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
49+
var data parameterDataSourceModel
50+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
51+
52+
if resp.Diagnostics.HasError() {
53+
return
54+
}
55+
56+
if data.Name.IsNull() {
57+
resp.Diagnostics.AddError("name is required", "name")
58+
return
59+
}
60+
61+
ds := data.Name.ValueString()
62+
parameterEnv := provider.ParameterEnvironmentVariable(ds)
63+
rawValue, ok := os.LookupEnv(parameterEnv)
64+
if !ok {
65+
resp.Diagnostics.AddError("parameter not found", "name")
66+
return
67+
}
68+
69+
switch data.Type.UnderlyingValue().(type) {
70+
case types.String:
71+
data.Value = types.DynamicValue(types.StringValue(rawValue))
72+
case types.Number:
73+
// convert the raw value to a number
74+
var floatVal float64
75+
if err := json.NewDecoder(strings.NewReader(rawValue)).Decode(&floatVal); err != nil {
76+
resp.Diagnostics.AddError("failed to parse value as number", "value")
77+
return
78+
}
79+
80+
data.Value = types.DynamicValue(types.NumberValue(big.NewFloat(floatVal)))
81+
case types.Bool:
82+
// convert the raw value to a bool
83+
var boolVal bool
84+
if err := json.NewDecoder(strings.NewReader(rawValue)).Decode(&boolVal); err != nil {
85+
resp.Diagnostics.AddError("failed to parse value as bool", "value")
86+
return
87+
}
88+
data.Value = types.DynamicValue(types.BoolValue(boolVal))
89+
case types.List:
90+
// TODO: handle list
91+
resp.Diagnostics.AddError("TODO: list type not supported", "type")
92+
return
93+
case types.Map:
94+
// TODO: handle map
95+
resp.Diagnostics.AddError("TODO: map type not supported", "type")
96+
return
97+
}
98+
99+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
100+
}

tpfprovider/parameter_test.go

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package tpfprovider
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
8+
"github.com/coder/terraform-provider-coder/v2/provider"
9+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
10+
"github.com/hashicorp/terraform-plugin-testing/terraform"
11+
)
12+
13+
func TestAccParameterDataSource(t *testing.T) {
14+
t.Run("string", func(t *testing.T) {
15+
t.Setenv(provider.ParameterEnvironmentVariable("test"), "test")
16+
resource.Test(t, resource.TestCase{
17+
IsUnitTest: true,
18+
PreCheck: func() { testAccPreCheck(t) },
19+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
20+
Steps: []resource.TestStep{{
21+
Config: `
22+
provider coder {}
23+
data "coder_parameter" "test" {
24+
name = "test"
25+
type = ""
26+
}`,
27+
Check: resource.ComposeAggregateTestCheckFunc(
28+
testParameterEnv("test", "test"),
29+
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
30+
resource.TestCheckResourceAttr("data.coder_parameter.test", "type", ""),
31+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value", "test"),
32+
),
33+
}},
34+
})
35+
})
36+
37+
t.Run("number", func(t *testing.T) {
38+
t.Setenv(provider.ParameterEnvironmentVariable("test"), "3.14")
39+
resource.Test(t, resource.TestCase{
40+
IsUnitTest: true,
41+
PreCheck: func() { testAccPreCheck(t) },
42+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
43+
Steps: []resource.TestStep{{
44+
Config: `
45+
provider coder {}
46+
data "coder_parameter" "test" {
47+
name = "test"
48+
type = 0
49+
}`,
50+
Check: resource.ComposeAggregateTestCheckFunc(
51+
testParameterEnv("test", "3.14"),
52+
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
53+
resource.TestCheckResourceAttr("data.coder_parameter.test", "type", "0"),
54+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value", "3.14"),
55+
),
56+
}},
57+
})
58+
})
59+
60+
t.Run("bool", func(t *testing.T) {
61+
t.Setenv(provider.ParameterEnvironmentVariable("test"), "true")
62+
resource.Test(t, resource.TestCase{
63+
IsUnitTest: true,
64+
PreCheck: func() { testAccPreCheck(t) },
65+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
66+
Steps: []resource.TestStep{{
67+
Config: `
68+
provider coder {}
69+
data "coder_parameter" "test" {
70+
name = "test"
71+
type = false
72+
}`,
73+
Check: resource.ComposeAggregateTestCheckFunc(
74+
testParameterEnv("test", "true"),
75+
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
76+
resource.TestCheckResourceAttr("data.coder_parameter.test", "type", "false"),
77+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value", "true"),
78+
),
79+
}},
80+
})
81+
})
82+
83+
t.Run("list of string", func(t *testing.T) {
84+
t.Skip("TODO: not implemented yet")
85+
t.Setenv(provider.ParameterEnvironmentVariable("test"), `["a","b","c"]`)
86+
resource.Test(t, resource.TestCase{
87+
IsUnitTest: true,
88+
PreCheck: func() { testAccPreCheck(t) },
89+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
90+
Steps: []resource.TestStep{{
91+
Config: `
92+
provider coder {}
93+
data "coder_parameter" "test" {
94+
name = "test"
95+
type = [""]
96+
}`,
97+
Check: resource.ComposeAggregateTestCheckFunc(
98+
testParameterEnv("test", `["a","b","c"]`),
99+
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
100+
resource.TestCheckTypeSetElemAttr("data.coder_parameter.test", "type*", "[]"),
101+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.#", "3"),
102+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.0", "a"),
103+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.1", "b"),
104+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.2", "c"),
105+
),
106+
}},
107+
})
108+
})
109+
110+
t.Run("list of number", func(t *testing.T) {
111+
t.Skip("TODO: not implemented yet")
112+
t.Setenv(provider.ParameterEnvironmentVariable("test"), `[1, 2, 3]`)
113+
resource.Test(t, resource.TestCase{
114+
IsUnitTest: true,
115+
PreCheck: func() { testAccPreCheck(t) },
116+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
117+
Steps: []resource.TestStep{{
118+
Config: `
119+
provider coder {}
120+
data "coder_parameter" "test" {
121+
name = "test"
122+
type = [0]
123+
}
124+
`,
125+
Check: resource.ComposeAggregateTestCheckFunc(
126+
testParameterEnv("test", `[1,2,3]`),
127+
resource.TestCheckResourceAttr("data.coder_parameter.test", "name", "test"),
128+
resource.TestCheckTypeSetElemAttr("data.coder_parameter.test", "type*", "[]"),
129+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.#", "3"),
130+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.0", "1"),
131+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.1", "2"),
132+
resource.TestCheckResourceAttr("data.coder_parameter.test", "value.2", "3"),
133+
),
134+
}},
135+
})
136+
})
137+
}
138+
139+
func testParameterEnv(name, value string) func(*terraform.State) error {
140+
return func(*terraform.State) error {
141+
penv := provider.ParameterEnvironmentVariable("test")
142+
val, ok := os.LookupEnv(penv)
143+
if !ok {
144+
return fmt.Errorf("parameter environment variable %q not set", penv)
145+
}
146+
if val != value {
147+
return fmt.Errorf("parameter environment variable %q has unexpected value %q", penv, val)
148+
}
149+
return nil
150+
}
151+
}

tpfprovider/tpfprovider.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,20 @@ type coderProvider struct {
1616

1717
var _ provider.Provider = (*coderProvider)(nil)
1818

19-
func NewFrameworkProvider() provider.Provider {
20-
return &coderProvider{}
19+
func NewFrameworkProvider() func() provider.Provider {
20+
return func() provider.Provider {
21+
return &coderProvider{}
22+
}
2123
}
2224

2325
func (p *coderProvider) Resources(_ context.Context) []func() resource.Resource {
2426
return []func() resource.Resource{}
2527
}
2628

2729
func (p *coderProvider) DataSources(_ context.Context) []func() datasource.DataSource {
28-
return []func() datasource.DataSource{}
30+
return []func() datasource.DataSource{
31+
NewParameterDataSource,
32+
}
2933
}
3034

3135
func (p *coderProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {

tpfprovider/tpfprovider_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package tpfprovider
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/providerserver"
7+
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
8+
)
9+
10+
var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
11+
"coder": providerserver.NewProtocol6WithError(NewFrameworkProvider()()),
12+
}
13+
14+
func testAccPreCheck(t *testing.T) {
15+
t.Helper()
16+
}

0 commit comments

Comments
 (0)