@@ -5,28 +5,142 @@ package provider
5
5
6
6
import (
7
7
"context"
8
+ "fmt"
8
9
10
+ "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
9
11
"github.com/hashicorp/terraform-plugin-framework/datasource"
12
+ "github.com/hashicorp/terraform-plugin-framework/diag"
13
+ "github.com/hashicorp/terraform-plugin-framework/path"
10
14
"github.com/hashicorp/terraform-plugin-framework/provider"
15
+ "github.com/hashicorp/terraform-plugin-framework/provider/schema"
11
16
"github.com/hashicorp/terraform-plugin-framework/resource"
17
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
18
+ "github.com/hashicorp/terraform-plugin-framework/tfsdk"
19
+ "github.com/hashicorp/terraform-plugin-framework/types"
20
+ "github.com/hashicorp/terraform-plugin-log/tflog"
12
21
)
13
22
23
+ type httpProviderConfig struct {
24
+ }
25
+
26
+ type httpProvider struct {
27
+ Hostname string
28
+ RequestHeaders map [string ]string
29
+ }
30
+
31
+ var _ provider.Provider = (* httpProvider )(nil )
32
+
14
33
func New () provider.Provider {
15
34
return & httpProvider {}
16
35
}
17
36
18
- var _ provider.Provider = (* httpProvider )(nil )
37
+ type httpProviderConfigModel struct {
38
+ Host types.List `tfsdk:"host"`
39
+ }
19
40
20
- type httpProvider struct {}
41
+ type httpProviderHostConfigModel struct {
42
+ Name types.String `tfsdk:"name"`
43
+ RequestHeaders types.Map `tfsdk:"request_headers"`
44
+ }
21
45
22
46
func (p * httpProvider ) Metadata (_ context.Context , _ provider.MetadataRequest , resp * provider.MetadataResponse ) {
23
47
resp .TypeName = "http"
24
48
}
25
49
26
- func (p * httpProvider ) Schema (context.Context , provider.SchemaRequest , * provider.SchemaResponse ) {
50
+ func (p * httpProvider ) Schema (_ context.Context , _ provider.SchemaRequest , resp * provider.SchemaResponse ) {
51
+ resp .Schema = schema.Schema {
52
+ Description : "Configures the HTTP provider" ,
53
+ Blocks : map [string ]schema.Block {
54
+ "host" : schema.ListNestedBlock {
55
+ Description : "A host provider configuration." ,
56
+ Validators : []validator.List {
57
+ listvalidator .SizeBetween (0 , 1 ),
58
+ },
59
+ NestedObject : schema.NestedBlockObject {
60
+ Attributes : map [string ]schema.Attribute {
61
+ "name" : schema.StringAttribute {
62
+ Description : "The host name for which the host configuration should take affect." ,
63
+ Required : true ,
64
+ },
65
+ "request_headers" : schema.MapAttribute {
66
+ Description : "A map of request header field names and values." ,
67
+ ElementType : types .StringType ,
68
+ Optional : true ,
69
+ Sensitive : true ,
70
+ },
71
+ },
72
+ },
73
+ },
74
+ },
75
+ }
27
76
}
28
77
29
- func (p * httpProvider ) Configure (context.Context , provider.ConfigureRequest , * provider.ConfigureResponse ) {
78
+ func (p * httpProvider ) Configure (ctx context.Context , req provider.ConfigureRequest , res * provider.ConfigureResponse ) {
79
+ tflog .Debug (ctx , "Configuring provider" )
80
+ //p.resetConfig()
81
+
82
+ // Ensure these response values are set before early returns, etc.
83
+ res .DataSourceData = p
84
+ res .ResourceData = p
85
+
86
+ // Load configuration into the model
87
+ var conf httpProviderConfigModel
88
+ res .Diagnostics .Append (req .Config .Get (ctx , & conf )... )
89
+ if res .Diagnostics .HasError () {
90
+ return
91
+ }
92
+ if conf .Host .IsNull () || conf .Host .IsUnknown () || len (conf .Host .Elements ()) == 0 {
93
+ tflog .Debug (ctx , "No host configuration detected: using provider defaults" )
94
+ return
95
+ }
96
+
97
+ // Load proxy configuration into model
98
+ hostConfSlice := make ([]httpProviderHostConfigModel , 1 )
99
+ res .Diagnostics .Append (conf .Host .ElementsAs (ctx , & hostConfSlice , true )... )
100
+ if res .Diagnostics .HasError () {
101
+ return
102
+ }
103
+ if len (hostConfSlice ) != 1 {
104
+ res .Diagnostics .AddAttributeError (
105
+ path .Root ("host" ),
106
+ "Provider Proxy Configuration Handling Error" ,
107
+ "The provider failed to fully load the expected host configuration. " +
108
+ "This is likely a bug in the Terraform Provider and should be reported to the provider developers." ,
109
+ )
110
+ return
111
+ }
112
+ hostConf := hostConfSlice [0 ]
113
+ tflog .Debug (ctx , "Loaded provider configuration" )
114
+
115
+ // Parse the host name
116
+ if ! hostConf .Name .IsNull () && ! hostConf .Name .IsUnknown () {
117
+ tflog .Debug (ctx , "Configuring host via name" , map [string ]interface {}{
118
+ "name" : hostConf .Name .ValueString (),
119
+ })
120
+
121
+ p .Hostname = hostConf .Name .ValueString ()
122
+ }
123
+
124
+ if ! hostConf .RequestHeaders .IsNull () && ! hostConf .RequestHeaders .IsUnknown () {
125
+ tflog .Debug (ctx , "Configuring request headers" )
126
+ requestHeaders := map [string ]string {}
127
+ for name , value := range hostConf .RequestHeaders .Elements () {
128
+ var header string
129
+ diags := tfsdk .ValueAs (ctx , value , & header )
130
+ res .Diagnostics .Append (diags ... )
131
+ if res .Diagnostics .HasError () {
132
+ return
133
+ }
134
+
135
+ requestHeaders [name ] = header
136
+ }
137
+
138
+ p .RequestHeaders = requestHeaders
139
+ }
140
+
141
+ tflog .Debug (ctx , "Provider configuration" , map [string ]interface {}{
142
+ "provider" : fmt .Sprintf ("%+v" , p ),
143
+ })
30
144
}
31
145
32
146
func (p * httpProvider ) Resources (context.Context ) []func () resource.Resource {
@@ -38,3 +152,27 @@ func (p *httpProvider) DataSources(context.Context) []func() datasource.DataSour
38
152
NewHttpDataSource ,
39
153
}
40
154
}
155
+
156
+ // toProvider can be used to cast a generic provider.Provider reference to this specific provider.
157
+ // This is ideally used in DataSourceType.NewDataSource and ResourceType.NewResource calls.
158
+ func toProvider (in any ) (* httpProvider , diag.Diagnostics ) {
159
+ if in == nil {
160
+ return nil , nil
161
+ }
162
+
163
+ var diags diag.Diagnostics
164
+
165
+ p , ok := in .(* httpProvider )
166
+
167
+ if ! ok {
168
+ diags .AddError (
169
+ "Unexpected Provider Instance Type" ,
170
+ fmt .Sprintf ("While creating the data source or resource, an unexpected provider type (%T) was received. " +
171
+ "This is likely a bug in the provider code and should be reported to the provider developers." , in ,
172
+ ),
173
+ )
174
+ return nil , diags
175
+ }
176
+
177
+ return p , diags
178
+ }
0 commit comments