@@ -5,28 +5,142 @@ package provider
55
66import (
77 "context"
8+ "fmt"
89
10+ "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
911 "github.com/hashicorp/terraform-plugin-framework/datasource"
12+ "github.com/hashicorp/terraform-plugin-framework/diag"
13+ "github.com/hashicorp/terraform-plugin-framework/path"
1014 "github.com/hashicorp/terraform-plugin-framework/provider"
15+ "github.com/hashicorp/terraform-plugin-framework/provider/schema"
1116 "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"
1221)
1322
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+
1433func New () provider.Provider {
1534 return & httpProvider {}
1635}
1736
18- var _ provider.Provider = (* httpProvider )(nil )
37+ type httpProviderConfigModel struct {
38+ Host types.List `tfsdk:"host"`
39+ }
1940
20- type httpProvider struct {}
41+ type httpProviderHostConfigModel struct {
42+ Name types.String `tfsdk:"name"`
43+ RequestHeaders types.Map `tfsdk:"request_headers"`
44+ }
2145
2246func (p * httpProvider ) Metadata (_ context.Context , _ provider.MetadataRequest , resp * provider.MetadataResponse ) {
2347 resp .TypeName = "http"
2448}
2549
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+ }
2776}
2877
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+ })
30144}
31145
32146func (p * httpProvider ) Resources (context.Context ) []func () resource.Resource {
@@ -38,3 +152,27 @@ func (p *httpProvider) DataSources(context.Context) []func() datasource.DataSour
38152 NewHttpDataSource ,
39153 }
40154}
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