package provider import ( "context" "fmt" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/provider" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" ) // Ensure provider defined types fully satisfy framework interfaces var _ provider.Provider = &scaffoldingProvider{} // provider satisfies the tfsdk.Provider interface and usually is included // with all Resource and DataSource implementations. type scaffoldingProvider struct { // client can contain the upstream provider SDK or HTTP client used to // communicate with the upstream service. Resource and DataSource // implementations can then make calls using this client. // // TODO: If appropriate, implement upstream provider SDK or HTTP client. // client vendorsdk.ExampleClient // configured is set to true at the end of the Configure method. // This can be used in Resource and DataSource implementations to verify // that the provider was previously configured. configured bool // version is set to the provider version on release, "dev" when the // provider is built and ran locally, and "test" when running acceptance // testing. version string } // providerData can be used to store data from the Terraform configuration. type providerData struct { Example types.String `tfsdk:"example"` } func (p *scaffoldingProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { var data providerData diags := req.Config.Get(ctx, &data) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return } // Configuration values are now available. // if data.Example.Null { /* ... */ } // If the upstream provider SDK or HTTP client requires configuration, such // as authentication or logging, this is a great opportunity to do so. p.configured = true } func (p *scaffoldingProvider) GetResources(ctx context.Context) (map[string]provider.ResourceType, diag.Diagnostics) { return map[string]provider.ResourceType{ "scaffolding_example": exampleResourceType{}, }, nil } func (p *scaffoldingProvider) GetDataSources(ctx context.Context) (map[string]provider.DataSourceType, diag.Diagnostics) { return map[string]provider.DataSourceType{ "scaffolding_example": exampleDataSourceType{}, }, nil } func (p *scaffoldingProvider) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { return tfsdk.Schema{ Attributes: map[string]tfsdk.Attribute{ "example": { MarkdownDescription: "Example provider attribute", Optional: true, Type: types.StringType, }, }, }, nil } func New(version string) func() provider.Provider { return func() provider.Provider { return &scaffoldingProvider{ version: version, } } } // convertProviderType is a helper function for NewResource and NewDataSource // implementations to associate the concrete provider type. Alternatively, // this helper can be skipped and the provider type can be directly type // asserted (e.g. provider: in.(*scaffoldingProvider)), however using this can prevent // potential panics. func convertProviderType(in provider.Provider) (scaffoldingProvider, diag.Diagnostics) { var diags diag.Diagnostics p, ok := in.(*scaffoldingProvider) if !ok { diags.AddError( "Unexpected Provider Instance Type", fmt.Sprintf("While creating the data source or resource, an unexpected provider type (%T) was received. This is always a bug in the provider code and should be reported to the provider developers.", p), ) return scaffoldingProvider{}, diags } if p == nil { diags.AddError( "Unexpected Provider Instance Type", "While creating the data source or resource, an unexpected empty provider instance was received. This is always a bug in the provider code and should be reported to the provider developers.", ) return scaffoldingProvider{}, diags } return *p, diags }