@@ -57,6 +57,34 @@ type Server struct {
57
57
// providerSchemaMutex is a mutex to protect concurrent providerSchema
58
58
// access from race conditions.
59
59
providerSchemaMutex sync.Mutex
60
+
61
+ // resourceSchemas is the cached Resource Schemas for RPCs that need to
62
+ // convert configuration data from the protocol. If not found, it will be
63
+ // fetched from the ResourceType.GetSchema() method.
64
+ resourceSchemas map [string ]* tfsdk.Schema
65
+
66
+ // resourceSchemasDiags is the cached Diagnostics obtained while populating
67
+ // resourceSchemas. This is to ensure any warnings or errors are also
68
+ // returned appropriately when fetching resourceSchemas.
69
+ resourceSchemasDiags diag.Diagnostics
70
+
71
+ // resourceSchemasMutex is a mutex to protect concurrent resourceSchemas
72
+ // access from race conditions.
73
+ resourceSchemasMutex sync.Mutex
74
+
75
+ // resourceTypes is the cached ResourceTypes for RPCs that need to
76
+ // access resources. If not found, it will be fetched from the
77
+ // Provider.GetResources() method.
78
+ resourceTypes map [string ]tfsdk.ResourceType
79
+
80
+ // resourceTypesDiags is the cached Diagnostics obtained while populating
81
+ // resourceTypes. This is to ensure any warnings or errors are also
82
+ // returned appropriately when fetching resourceTypes.
83
+ resourceTypesDiags diag.Diagnostics
84
+
85
+ // resourceTypesMutex is a mutex to protect concurrent resourceTypes
86
+ // access from race conditions.
87
+ resourceTypesMutex sync.Mutex
60
88
}
61
89
62
90
// DataSourceSchema returns the Schema associated with the DataSourceType for
@@ -174,3 +202,98 @@ func (s *Server) ProviderSchema(ctx context.Context) (*tfsdk.Schema, diag.Diagno
174
202
175
203
return s .providerSchema , s .providerSchemaDiags
176
204
}
205
+
206
+ // ResourceSchema returns the Schema associated with the ResourceType for
207
+ // the given type name.
208
+ func (s * Server ) ResourceSchema (ctx context.Context , typeName string ) (* tfsdk.Schema , diag.Diagnostics ) {
209
+ resourceSchemas , diags := s .ResourceSchemas (ctx )
210
+
211
+ resourceSchema , ok := resourceSchemas [typeName ]
212
+
213
+ if ! ok {
214
+ diags .AddError (
215
+ "Resource Schema Not Found" ,
216
+ fmt .Sprintf ("No resource type named %q was found in the provider to fetch the schema. " , typeName )+
217
+ "This is always an issue in the Terraform Provider SDK used to implement the provider and should be reported to the provider developers." ,
218
+ )
219
+
220
+ return nil , diags
221
+ }
222
+
223
+ return resourceSchema , diags
224
+ }
225
+
226
+ // ResourceSchemas returns the map of ResourceType Schemas. The results are
227
+ // cached on first use.
228
+ func (s * Server ) ResourceSchemas (ctx context.Context ) (map [string ]* tfsdk.Schema , diag.Diagnostics ) {
229
+ logging .FrameworkTrace (ctx , "Checking ResourceSchemas lock" )
230
+ s .resourceSchemasMutex .Lock ()
231
+ defer s .resourceSchemasMutex .Unlock ()
232
+
233
+ if s .resourceSchemas != nil {
234
+ return s .resourceSchemas , s .resourceSchemasDiags
235
+ }
236
+
237
+ resourceTypes , diags := s .ResourceTypes (ctx )
238
+
239
+ s .resourceSchemas = map [string ]* tfsdk.Schema {}
240
+ s .resourceSchemasDiags = diags
241
+
242
+ if s .resourceSchemasDiags .HasError () {
243
+ return s .resourceSchemas , s .resourceSchemasDiags
244
+ }
245
+
246
+ for resourceTypeName , resourceType := range resourceTypes {
247
+ logging .FrameworkTrace (ctx , "Found resource type" , map [string ]interface {}{logging .KeyResourceType : resourceTypeName })
248
+
249
+ logging .FrameworkDebug (ctx , "Calling provider defined ResourceType GetSchema" , map [string ]interface {}{logging .KeyResourceType : resourceTypeName })
250
+ schema , diags := resourceType .GetSchema (ctx )
251
+ logging .FrameworkDebug (ctx , "Called provider defined ResourceType GetSchema" , map [string ]interface {}{logging .KeyResourceType : resourceTypeName })
252
+
253
+ s .resourceSchemasDiags .Append (diags ... )
254
+
255
+ if s .resourceSchemasDiags .HasError () {
256
+ return s .resourceSchemas , s .resourceSchemasDiags
257
+ }
258
+
259
+ s .resourceSchemas [resourceTypeName ] = & schema
260
+ }
261
+
262
+ return s .resourceSchemas , s .resourceSchemasDiags
263
+ }
264
+
265
+ // ResourceType returns the ResourceType for a given type name.
266
+ func (s * Server ) ResourceType (ctx context.Context , typeName string ) (tfsdk.ResourceType , diag.Diagnostics ) {
267
+ resourceTypes , diags := s .ResourceTypes (ctx )
268
+
269
+ resourceType , ok := resourceTypes [typeName ]
270
+
271
+ if ! ok {
272
+ diags .AddError (
273
+ "Resource Type Not Found" ,
274
+ fmt .Sprintf ("No resource type named %q was found in the provider." , typeName ),
275
+ )
276
+
277
+ return nil , diags
278
+ }
279
+
280
+ return resourceType , diags
281
+ }
282
+
283
+ // ResourceTypes returns the map of ResourceTypes. The results are cached
284
+ // on first use.
285
+ func (s * Server ) ResourceTypes (ctx context.Context ) (map [string ]tfsdk.ResourceType , diag.Diagnostics ) {
286
+ logging .FrameworkTrace (ctx , "Checking ResourceTypes lock" )
287
+ s .resourceTypesMutex .Lock ()
288
+ defer s .resourceTypesMutex .Unlock ()
289
+
290
+ if s .resourceTypes != nil {
291
+ return s .resourceTypes , s .resourceTypesDiags
292
+ }
293
+
294
+ logging .FrameworkDebug (ctx , "Calling provider defined Provider GetResources" )
295
+ s .resourceTypes , s .resourceTypesDiags = s .Provider .GetResources (ctx )
296
+ logging .FrameworkDebug (ctx , "Called provider defined Provider GetResources" )
297
+
298
+ return s .resourceTypes , s .resourceTypesDiags
299
+ }
0 commit comments