New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
provider: Deprecate DataSourceType
, ResourceType
, Provider
type GetDataSources
, and Provider
type GetResources
#472
Merged
Commits on Sep 8, 2022
-
provider: Deprecate
DataSourceType
,ResourceType
,Provider
type…… `GetDataSources`, and `Provider` type `GetResources` Reference: #441 Reference: #442 The goal of this change is twofold: - Deprecate the separate `DataSourceType` and `ResourceType` types. - Enable `DataSource` and `Resource` to be self-documenting with respects to their type name. Removing `DataSourceType` and `ResourceType` simplifies provider implementations and gives developers the choice of whether or not to configure extra data in their `DataSource` and `Resource` implementations by adding the optional `Configure` method. This data is no longer required to be the `provider.Provider` itself, but rather can be any type such as a provider-defined structure or vendor-supplied client type. Enabling `DataSource` and `Resource` type name handling within the implementation allows provider developers to further split out their data source and resource code across package boundaries without repeated map addition logic. Given this framework version 0.11.1 code (which generally is split across Go files/packages, but shown altogether here for brevity): ```go var _ provider.Provider = &ExampleProvider{} type ExampleProvider struct{ configured bool // ... additional remote client fields, etc. } func (p ExampleProvider) GetDataSources(ctx context.Context) (map[string]provider.DataSourceType, diag.Diagnostics) { return map[string]provider.DataSourceType{ "example_thing": ThingDataSourceType{}, }, nil } func (p ExampleProvider) GetResources(ctx context.Context) (map[string]provider.ResourceType, diag.Diagnostics) { return map[string]provider.ResourceType{ "example_thing": ThingResourceType{}, }, nil } func (p ExampleProvider) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { /* ... */ } func (p *ExampleProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { // ... remote client setup, etc. p.configured = true } var _ provider.DataSourceType = ThingDataSourceType{} var _ datasource.DataSource = ThingDataSource{} type ThingDataSourceType struct{} type ThingDataSource struct{ provider ExampleProvider } func (t ThingDataSourceType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { /* ... */ } func (t ThingDataSourceType) NewDataSource(ctx context.Context, p provider.Provider) (datasource.DataSource, diag.Diagnostics) { return ThingDataSource{ provider: p.(ExampleProvider), // unchecked type assertion shown for brevity } } func (d ThingDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // e.g. d.provider.Client.ReadThing() } var _ provider.ResourceType = ThingResourceType{} var _ resource.Resource = ThingResource{} type ThingResourceType struct{} type ThingResource struct{ provider ExampleProvider } func (t ThingResourceType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { /* ... */ } func (t ThingResourceType) NewResource(ctx context.Context, p provider.Provider) (resource.Resource, diag.Diagnostics) { return ThingResource{ provider: p.(ExampleProvider), // unchecked type assertion shown for brevity } } func (r ThingResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { // e.g. r.provider.Client.CreateThing() } func (r ThingResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { // e.g. r.provider.Client.DeleteThing() } func (r ThingResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { // e.g. r.provider.Client.ReadThing() } func (r ThingResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { // e.g. r.provider.Client.UpdateThing() } ``` Could be migrated as: ```go type ExampleClient struct { // client/data fields OR just use the vendor client type directly instead of this new type } var _ provider.Provider = &ExampleProvider{} type ExampleProvider struct{ // setting client, etc. fields here is now completely optional, // if you want to configure data sources and resource with _this_ type } func (p ExampleProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) { // make available in DataSource and Resource type TypeName methods resp.TypeName = "example" } func (p ExampleProvider) DataSources(ctx context.Context) []func() datasource.DataSource { return []func() datasource.DataSource{ NewThingDataSource, } } func (p ExampleProvider) Resources(ctx context.Context) []func() resource.Resource { return []func() resource.Resource{ NewThingResource, } } func (p ExampleProvider) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { /* ... */ } func (p *ExampleProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { client := &ExampleClient{} // OR existing vendor type OR p itself resp.DataSourceData = client resp.ResourceData = client } var _ datasource.DataSource = ThingDataSource{} func NewThingDataSource() datasource.DataSource { return ThingDataSource{} } type ThingDataSource struct{ client *ExampleClient } func (d ThingDataSource) TypeName(ctx context.Context, req datasource.TypeNameRequest, resp *datasource.TypeNameResponse) { resp.TypeName = req.ProviderTypeName + "_thing" } func (d ThingDataSource) GetSchema(ctx context.Context) (fwschema.Schema, diag.Diagnostics) { /* ... */ } func (d ThingDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { d.client = req.ProviderData.(*ExampleClient) // unchecked type assertion shown for brevity } func (d ThingDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // e.g. d.client.ReadThing() } var _ resource.Resource = ThingResource{} func NewThingResource() resource.Resource { return ThingResource{} } type ThingResource struct{ client *ExampleClient } func (d ThingResource) TypeName(ctx context.Context, req resource.TypeNameRequest, resp *resource.TypeNameResponse) { resp.TypeName = req.ProviderTypeName + "_thing" } func (r ThingResource) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { /* ... */ } func (r ThingResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { r.client = req.ProviderConfigureData.(*ExampleClient) // unchecked type assertion shown for brevity } func (r ThingResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { // e.g. r.client.CreateThing() } func (r ThingResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { // e.g. r.client.DeleteThing() } func (r ThingResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { // e.g. r.client.ReadThing() } func (r ThingResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { // e.g. r.client.UpdateThing() } ``` Some additional implementation notes: - The new `Provider` type `Metadata` method is called at the beginning of the `GetProviderSchema` RPC and populates the provider type name for data source and resource type name requests. - The framework server will automatically validate against duplicate type names, missing type names, and missing schemas when using the new `Provider` type `DataSources` and `Resources` methods. - The new `DataSource` and `Resource` type `Configure` methods are automatically called where the framework server previously called the `DataSourceType` type `NewDataSource` method and `ResourceType` type `NewDataSource` method. - The new `DataSource` and `Resource` type `TypeName` methods could potentially be renamed `Metadata` to match the `Provider` implementation and potentially help futureproof it, however it could be unclear to provider developers where to set the type name at first and there are no apparent use cases which would extend that type of metadata yet.
-
-
internal/fwserver: Check deprecated ResourceType's when searching for…
… Resource implementations
Commits on Sep 9, 2022
-
-
-
provider: Ensure DataSourceType and ResourceType includes Go document…
…ation Deprecated comment
Commits on Sep 12, 2022
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.