From 5eb1c6192e1fbdeff1b5edfd0de609561319584e Mon Sep 17 00:00:00 2001 From: Alberto Donato Date: Fri, 23 Oct 2026 16:51:05 +0200 Subject: [PATCH] refactor: separate platform and IaC resource/datasource base types [ENG-9440] [ENG-9440](https://stacklet.atlassian.net/browse/ENG-9440) ### what Define separate base types for resources and datasources related to platform and sinistral, each one carrying an `api` attribute pointing to the corresponding API class ### why Each resource/datasource interacts with only one API ### testing updated tests ### docs n/a --- dev-docs/architecture.md | 7 +-- internal/datasources/account.go | 2 +- internal/datasources/account_group.go | 2 +- internal/datasources/anthropic_integration.go | 2 +- internal/datasources/binding.go | 2 +- .../configuration_profile_account_owners.go | 2 +- .../configuration_profile_email.go | 2 +- .../datasources/configuration_profile_jira.go | 2 +- .../configuration_profile_msteams.go | 2 +- .../configuration_profile_resource_owner.go | 2 +- .../configuration_profile_servicenow.go | 2 +- .../configuration_profile_slack.go | 2 +- .../configuration_profile_symphony.go | 2 +- internal/datasources/datadog_integration.go | 2 +- internal/datasources/datasource.go | 22 ++++--- internal/datasources/gcp_integration.go | 2 +- .../datasources/gcp_integration_surface.go | 2 +- .../msteams_integration_surface.go | 2 +- internal/datasources/notification_template.go | 2 +- internal/datasources/platform.go | 2 +- internal/datasources/policy.go | 2 +- internal/datasources/policy_collection.go | 2 +- internal/datasources/report_group.go | 2 +- internal/datasources/repository.go | 2 +- internal/datasources/role.go | 2 +- internal/datasources/role_assignments.go | 2 +- internal/datasources/saml_provider.go | 2 +- internal/datasources/sso_group.go | 2 +- internal/datasources/user.go | 2 +- internal/datasources/user_group.go | 2 +- internal/providerdata/providerdata.go | 59 +++++++++---------- internal/resources/account.go | 2 +- internal/resources/account_discovery_aws.go | 2 +- internal/resources/account_discovery_azure.go | 2 +- internal/resources/account_discovery_gcp.go | 2 +- internal/resources/account_group.go | 2 +- internal/resources/account_group_mapping.go | 2 +- internal/resources/anthropic_integration.go | 2 +- internal/resources/binding.go | 2 +- .../configuration_profile_account_owners.go | 2 +- .../resources/configuration_profile_email.go | 2 +- .../resources/configuration_profile_jira.go | 2 +- .../configuration_profile_msteams.go | 2 +- .../configuration_profile_resource_owner.go | 2 +- .../configuration_profile_servicenow.go | 2 +- .../resources/configuration_profile_slack.go | 2 +- .../configuration_profile_symphony.go | 2 +- internal/resources/datadog_integration.go | 2 +- internal/resources/gcp_integration.go | 2 +- internal/resources/notification_template.go | 2 +- internal/resources/policy_collection.go | 2 +- .../resources/policy_collection_mapping.go | 2 +- internal/resources/report_group.go | 2 +- internal/resources/repository.go | 2 +- internal/resources/resource.go | 22 ++++--- internal/resources/role_assignment.go | 2 +- internal/resources/saml_provider.go | 2 +- internal/resources/sso_group.go | 2 +- internal/resources/user.go | 2 +- internal/resources/user_group.go | 2 +- 60 files changed, 114 insertions(+), 108 deletions(-) diff --git a/dev-docs/architecture.md b/dev-docs/architecture.md index 5794e73..f013dc1 100644 --- a/dev-docs/architecture.md +++ b/dev-docs/architecture.md @@ -122,10 +122,9 @@ Models in `internal/models/` define Terraform schema structure with `tfsdk` stru - New code should use `diag.Diagnostics` directly and the `typehelpers` package functions which all return diagnostics **Provider Data** (`internal/providerdata/`): -- `providerData` struct holds API clients for resources/data sources, built by `New()`: `API` for the platform API and `IaCAPI` for the IaC API -- Exposed as `api` and `iacAPI` fields in the `apiResource` and `apiDataSource` base types -- `GetForResource()` - Retrieves provider data in resources -- `GetForDataSource()` - Retrieves provider data in data sources +- `providerData` struct holds API clients for resources/data sources, built by `New()`: `PlatformAPI` for the platform API and `IaCAPI` for the IaC API +- `GetAPI[T]()` - Retrieves the API client of type `T` (`*platform.API` or `*iac.API`) from the provider data in a configure request +- Exposed as the `api` field by the generic `apiResource[T]`/`apiDataSource[T]` base types, through the `platformAPIResource`/`platformAPIDataSource` (platform API) and `iacAPIResource`/`iacAPIDataSource` (IaC API) aliases; resources and data sources embed the alias matching the API they use ## Architectural Patterns diff --git a/internal/datasources/account.go b/internal/datasources/account.go index b5f6b14..b9e0b7c 100644 --- a/internal/datasources/account.go +++ b/internal/datasources/account.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &accountDataSource{} type accountDataSource struct { - apiDataSource + platformAPIDataSource } func (d *accountDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/account_group.go b/internal/datasources/account_group.go index b93fd38..14ace58 100644 --- a/internal/datasources/account_group.go +++ b/internal/datasources/account_group.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &accountGroupDataSource{} type accountGroupDataSource struct { - apiDataSource + platformAPIDataSource } func (d *accountGroupDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/anthropic_integration.go b/internal/datasources/anthropic_integration.go index cc20ec2..7028b97 100644 --- a/internal/datasources/anthropic_integration.go +++ b/internal/datasources/anthropic_integration.go @@ -18,7 +18,7 @@ var ( ) type anthropicIntegrationDataSource struct { - apiDataSource + platformAPIDataSource } func (d *anthropicIntegrationDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/binding.go b/internal/datasources/binding.go index 1173767..83e6bd2 100644 --- a/internal/datasources/binding.go +++ b/internal/datasources/binding.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &bindingDataSource{} type bindingDataSource struct { - apiDataSource + platformAPIDataSource } func (d *bindingDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/configuration_profile_account_owners.go b/internal/datasources/configuration_profile_account_owners.go index b9051e3..8c36d48 100644 --- a/internal/datasources/configuration_profile_account_owners.go +++ b/internal/datasources/configuration_profile_account_owners.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &configurationProfileAccountOwnersDataSource{} type configurationProfileAccountOwnersDataSource struct { - apiDataSource + platformAPIDataSource } func (d *configurationProfileAccountOwnersDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/configuration_profile_email.go b/internal/datasources/configuration_profile_email.go index 826e15e..e965dd6 100644 --- a/internal/datasources/configuration_profile_email.go +++ b/internal/datasources/configuration_profile_email.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &configurationProfileEmailDataSource{} type configurationProfileEmailDataSource struct { - apiDataSource + platformAPIDataSource } func (d *configurationProfileEmailDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/configuration_profile_jira.go b/internal/datasources/configuration_profile_jira.go index 6bc6478..480eb8a 100644 --- a/internal/datasources/configuration_profile_jira.go +++ b/internal/datasources/configuration_profile_jira.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &configurationProfileJiraDataSource{} type configurationProfileJiraDataSource struct { - apiDataSource + platformAPIDataSource } func (d *configurationProfileJiraDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/configuration_profile_msteams.go b/internal/datasources/configuration_profile_msteams.go index 993016c..a7fca14 100644 --- a/internal/datasources/configuration_profile_msteams.go +++ b/internal/datasources/configuration_profile_msteams.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &configurationProfileMSTeamsDataSource{} type configurationProfileMSTeamsDataSource struct { - apiDataSource + platformAPIDataSource } func (d *configurationProfileMSTeamsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/configuration_profile_resource_owner.go b/internal/datasources/configuration_profile_resource_owner.go index 9845d72..596eb3b 100644 --- a/internal/datasources/configuration_profile_resource_owner.go +++ b/internal/datasources/configuration_profile_resource_owner.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &configurationProfileResourceOwnerDataSource{} type configurationProfileResourceOwnerDataSource struct { - apiDataSource + platformAPIDataSource } func (d *configurationProfileResourceOwnerDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/configuration_profile_servicenow.go b/internal/datasources/configuration_profile_servicenow.go index 3df0626..4ac1fdf 100644 --- a/internal/datasources/configuration_profile_servicenow.go +++ b/internal/datasources/configuration_profile_servicenow.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &configurationProfileServiceNowDataSource{} type configurationProfileServiceNowDataSource struct { - apiDataSource + platformAPIDataSource } func (d *configurationProfileServiceNowDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/configuration_profile_slack.go b/internal/datasources/configuration_profile_slack.go index 9ef164b..3e1c2fb 100644 --- a/internal/datasources/configuration_profile_slack.go +++ b/internal/datasources/configuration_profile_slack.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &configurationProfileSlackDataSource{} type configurationProfileSlackDataSource struct { - apiDataSource + platformAPIDataSource } func (d *configurationProfileSlackDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/configuration_profile_symphony.go b/internal/datasources/configuration_profile_symphony.go index 1c4dd9f..2972fa5 100644 --- a/internal/datasources/configuration_profile_symphony.go +++ b/internal/datasources/configuration_profile_symphony.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &configurationProfileSymphonyDataSource{} type configurationProfileSymphonyDataSource struct { - apiDataSource + platformAPIDataSource } func (d *configurationProfileSymphonyDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/datadog_integration.go b/internal/datasources/datadog_integration.go index fd9459f..1f19bb4 100644 --- a/internal/datasources/datadog_integration.go +++ b/internal/datasources/datadog_integration.go @@ -18,7 +18,7 @@ var ( ) type datadogIntegrationDataSource struct { - apiDataSource + platformAPIDataSource } func (d *datadogIntegrationDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/datasource.go b/internal/datasources/datasource.go index e9867df..dac3233 100644 --- a/internal/datasources/datasource.go +++ b/internal/datasources/datasource.go @@ -13,18 +13,22 @@ import ( "github.com/stacklet/terraform-provider-stacklet/internal/providerdata" ) -// apiDataSource is a datasource based on the API. -type apiDataSource struct { - api *platform.API - iacAPI *iac.API +// apiDataSource is a datasource based on an API client. +type apiDataSource[T providerdata.APIClient] struct { + api T } // Configure sets up API access for the datasource. -func (d *apiDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { - if pd, err := providerdata.GetForDataSource(req); err != nil { +func (d *apiDataSource[T]) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if api, err := providerdata.GetAPI[T]("datasource", req.ProviderData); err != nil { errors.AddDiagError(&resp.Diagnostics, err) - } else if pd != nil { - d.api = pd.API - d.iacAPI = pd.IaCAPI + } else { + d.api = api } } + +// platformAPIDataSource is a datasource based on the platform API. +type platformAPIDataSource = apiDataSource[*platform.API] + +// iacAPIDataSource is a datasource based on the IaC API. +type iacAPIDataSource = apiDataSource[*iac.API] //nolint:unused diff --git a/internal/datasources/gcp_integration.go b/internal/datasources/gcp_integration.go index 3591079..82fb74e 100644 --- a/internal/datasources/gcp_integration.go +++ b/internal/datasources/gcp_integration.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &gcpIntegrationDataSource{} type gcpIntegrationDataSource struct { - apiDataSource + platformAPIDataSource } func (d *gcpIntegrationDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/gcp_integration_surface.go b/internal/datasources/gcp_integration_surface.go index a44ea65..cb9de5b 100644 --- a/internal/datasources/gcp_integration_surface.go +++ b/internal/datasources/gcp_integration_surface.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &gcpIntegrationSurfaceDataSource{} type gcpIntegrationSurfaceDataSource struct { - apiDataSource + platformAPIDataSource } func (d *gcpIntegrationSurfaceDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/msteams_integration_surface.go b/internal/datasources/msteams_integration_surface.go index 4eb8d34..86436cc 100644 --- a/internal/datasources/msteams_integration_surface.go +++ b/internal/datasources/msteams_integration_surface.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &msteamsIntegrationSurfaceDataSource{} type msteamsIntegrationSurfaceDataSource struct { - apiDataSource + platformAPIDataSource } func (d *msteamsIntegrationSurfaceDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/notification_template.go b/internal/datasources/notification_template.go index 1d03a9a..14187db 100644 --- a/internal/datasources/notification_template.go +++ b/internal/datasources/notification_template.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = ¬ificationTemplateDataSource{} type notificationTemplateDataSource struct { - apiDataSource + platformAPIDataSource } func (d *notificationTemplateDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/platform.go b/internal/datasources/platform.go index 1b26ffc..e1349b2 100644 --- a/internal/datasources/platform.go +++ b/internal/datasources/platform.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &platformDataSource{} type platformDataSource struct { - apiDataSource + platformAPIDataSource } func (d *platformDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/policy.go b/internal/datasources/policy.go index 5d11575..7863737 100644 --- a/internal/datasources/policy.go +++ b/internal/datasources/policy.go @@ -18,7 +18,7 @@ import ( var _ datasource.DataSource = &policyDataSource{} type policyDataSource struct { - apiDataSource + platformAPIDataSource } func (d *policyDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/policy_collection.go b/internal/datasources/policy_collection.go index 5352d2f..9005498 100644 --- a/internal/datasources/policy_collection.go +++ b/internal/datasources/policy_collection.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &policyCollectionDataSource{} type policyCollectionDataSource struct { - apiDataSource + platformAPIDataSource } func (d *policyCollectionDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/report_group.go b/internal/datasources/report_group.go index d9da2ad..accd29a 100644 --- a/internal/datasources/report_group.go +++ b/internal/datasources/report_group.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &reportGroupDataSource{} type reportGroupDataSource struct { - apiDataSource + platformAPIDataSource } func (d *reportGroupDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/repository.go b/internal/datasources/repository.go index e1c496b..aca462c 100644 --- a/internal/datasources/repository.go +++ b/internal/datasources/repository.go @@ -17,7 +17,7 @@ var _ datasource.DataSource = &repositoryDataSource{} // repositoryDataSource defines the data source implementation. type repositoryDataSource struct { - apiDataSource + platformAPIDataSource } func (d *repositoryDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/role.go b/internal/datasources/role.go index d2a4c97..61c749e 100644 --- a/internal/datasources/role.go +++ b/internal/datasources/role.go @@ -16,7 +16,7 @@ import ( var _ datasource.DataSource = &roleDataSource{} type roleDataSource struct { - apiDataSource + platformAPIDataSource } func (d *roleDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/role_assignments.go b/internal/datasources/role_assignments.go index 87207b4..26adf8a 100644 --- a/internal/datasources/role_assignments.go +++ b/internal/datasources/role_assignments.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &roleAssignmentsDataSource{} type roleAssignmentsDataSource struct { - apiDataSource + platformAPIDataSource } func (d *roleAssignmentsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/saml_provider.go b/internal/datasources/saml_provider.go index 8bfc7e0..efcae6c 100644 --- a/internal/datasources/saml_provider.go +++ b/internal/datasources/saml_provider.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &samlProviderDataSource{} type samlProviderDataSource struct { - apiDataSource + platformAPIDataSource } func (d *samlProviderDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/sso_group.go b/internal/datasources/sso_group.go index cea1c2e..74b366e 100644 --- a/internal/datasources/sso_group.go +++ b/internal/datasources/sso_group.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &ssoGroupDataSource{} type ssoGroupDataSource struct { - apiDataSource + platformAPIDataSource } func (d *ssoGroupDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/user.go b/internal/datasources/user.go index 200d039..8f229ae 100644 --- a/internal/datasources/user.go +++ b/internal/datasources/user.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &userDataSource{} type userDataSource struct { - apiDataSource + platformAPIDataSource } func (d *userDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/datasources/user_group.go b/internal/datasources/user_group.go index 50c7c11..392a4d7 100644 --- a/internal/datasources/user_group.go +++ b/internal/datasources/user_group.go @@ -15,7 +15,7 @@ import ( var _ datasource.DataSource = &userGroupDataSource{} type userGroupDataSource struct { - apiDataSource + platformAPIDataSource } func (d *userGroupDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { diff --git a/internal/providerdata/providerdata.go b/internal/providerdata/providerdata.go index ef4b459..40936ac 100644 --- a/internal/providerdata/providerdata.go +++ b/internal/providerdata/providerdata.go @@ -5,27 +5,29 @@ package providerdata import ( "fmt" - "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/stacklet/terraform-provider-stacklet/internal/api/iac" "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" ) // providerData holds shared data for available in requests. type providerData struct { - API *platform.API - IaCAPI *iac.API + PlatformAPI *platform.API + IaCAPI *iac.API } // New returns configured provider data. func New(config platform.ClientConfig, iacConfig iac.ClientConfig) *providerData { return &providerData{ - API: platform.New(config), - IaCAPI: iac.New(iacConfig), + PlatformAPI: platform.New(config), + IaCAPI: iac.New(iacConfig), } } +// APIClient is the set of API clients available from provider data. +type APIClient interface { + *platform.API | *iac.API +} + type providerDataError struct { Kind string ProviderData any @@ -39,30 +41,27 @@ func (e providerDataError) Error() string { return fmt.Sprintf("Expected *ProviderData, got: %T. Please report this issue to the provider developers.", e.ProviderData) } -// GetForResource returns provider data for a resource request, or nil if not set. -func GetForResource(req resource.ConfigureRequest) (*providerData, error) { - if req.ProviderData == nil { - return nil, nil - } - if providerData, ok := req.ProviderData.(*providerData); ok { - return providerData, nil - } - return nil, providerDataError{ - Kind: "resource", - ProviderData: req.ProviderData, - } -} - -// GetForDataSource returns provider data for a data source request, or nil if not set. -func GetForDataSource(req datasource.ConfigureRequest) (*providerData, error) { - if req.ProviderData == nil { - return nil, nil +// GetAPI returns the API client of the requested type from the provider data +// of a configure request, or nil if provider data is not set. +// +// kind describes the type of object being configured, for error reporting. +func GetAPI[T APIClient](kind string, data any) (T, error) { + var api T + if data == nil { + return api, nil } - if providerData, ok := req.ProviderData.(*providerData); ok { - return providerData, nil + pd, ok := data.(*providerData) + if !ok { + return api, providerDataError{ + Kind: kind, + ProviderData: data, + } } - return nil, providerDataError{ - Kind: "datasource", - ProviderData: req.ProviderData, + switch p := any(&api).(type) { + case **platform.API: + *p = pd.PlatformAPI + case **iac.API: + *p = pd.IaCAPI } + return api, nil } diff --git a/internal/resources/account.go b/internal/resources/account.go index 8b82152..728fdb4 100644 --- a/internal/resources/account.go +++ b/internal/resources/account.go @@ -24,7 +24,7 @@ var ( ) type accountResource struct { - apiResource + platformAPIResource } func (r *accountResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/account_discovery_aws.go b/internal/resources/account_discovery_aws.go index 8e2b530..b78f0fe 100644 --- a/internal/resources/account_discovery_aws.go +++ b/internal/resources/account_discovery_aws.go @@ -24,7 +24,7 @@ var ( ) type accountDiscoveryAWSResource struct { - apiResource + platformAPIResource } func (r *accountDiscoveryAWSResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/account_discovery_azure.go b/internal/resources/account_discovery_azure.go index 54308d9..35818d5 100644 --- a/internal/resources/account_discovery_azure.go +++ b/internal/resources/account_discovery_azure.go @@ -24,7 +24,7 @@ var ( ) type accountDiscoveryAzureResource struct { - apiResource + platformAPIResource } func (r *accountDiscoveryAzureResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/account_discovery_gcp.go b/internal/resources/account_discovery_gcp.go index f7b3d04..e4652d5 100644 --- a/internal/resources/account_discovery_gcp.go +++ b/internal/resources/account_discovery_gcp.go @@ -25,7 +25,7 @@ var ( ) type accountDiscoveryGCPResource struct { - apiResource + platformAPIResource } func (r *accountDiscoveryGCPResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/account_group.go b/internal/resources/account_group.go index 6202bab..cc42050 100644 --- a/internal/resources/account_group.go +++ b/internal/resources/account_group.go @@ -27,7 +27,7 @@ var ( ) type accountGroupResource struct { - apiResource + platformAPIResource } func (r *accountGroupResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/account_group_mapping.go b/internal/resources/account_group_mapping.go index b190c9c..95caa2e 100644 --- a/internal/resources/account_group_mapping.go +++ b/internal/resources/account_group_mapping.go @@ -21,7 +21,7 @@ var ( ) type accountGroupMappingResource struct { - apiResource + platformAPIResource } func (r *accountGroupMappingResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/anthropic_integration.go b/internal/resources/anthropic_integration.go index 49a894a..8ecf7c8 100644 --- a/internal/resources/anthropic_integration.go +++ b/internal/resources/anthropic_integration.go @@ -23,7 +23,7 @@ var ( ) type anthropicIntegrationResource struct { - apiResource + platformAPIResource } func (r *anthropicIntegrationResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/binding.go b/internal/resources/binding.go index c9d5926..d7a02f5 100644 --- a/internal/resources/binding.go +++ b/internal/resources/binding.go @@ -28,7 +28,7 @@ var ( ) type bindingResource struct { - apiResource + platformAPIResource } func (r *bindingResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/configuration_profile_account_owners.go b/internal/resources/configuration_profile_account_owners.go index 731b59a..826cf0e 100644 --- a/internal/resources/configuration_profile_account_owners.go +++ b/internal/resources/configuration_profile_account_owners.go @@ -29,7 +29,7 @@ var ( ) type configurationProfileAccountOwnersResource struct { - apiResource + platformAPIResource } func (r *configurationProfileAccountOwnersResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/configuration_profile_email.go b/internal/resources/configuration_profile_email.go index 2d4d9d5..afbffae 100644 --- a/internal/resources/configuration_profile_email.go +++ b/internal/resources/configuration_profile_email.go @@ -24,7 +24,7 @@ var ( ) type configurationProfileEmailResource struct { - apiResource + platformAPIResource } func (r *configurationProfileEmailResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/configuration_profile_jira.go b/internal/resources/configuration_profile_jira.go index c023a48..10d3d13 100644 --- a/internal/resources/configuration_profile_jira.go +++ b/internal/resources/configuration_profile_jira.go @@ -27,7 +27,7 @@ var ( ) type configurationProfileJiraResource struct { - apiResource + platformAPIResource } func (r *configurationProfileJiraResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/configuration_profile_msteams.go b/internal/resources/configuration_profile_msteams.go index 5a72d7c..f43a8ab 100644 --- a/internal/resources/configuration_profile_msteams.go +++ b/internal/resources/configuration_profile_msteams.go @@ -31,7 +31,7 @@ var ( ) type configurationProfileMSTeamsResource struct { - apiResource + platformAPIResource } func (r *configurationProfileMSTeamsResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/configuration_profile_resource_owner.go b/internal/resources/configuration_profile_resource_owner.go index c3ac88d..06f0f31 100644 --- a/internal/resources/configuration_profile_resource_owner.go +++ b/internal/resources/configuration_profile_resource_owner.go @@ -25,7 +25,7 @@ var ( ) type configurationProfileResourceOwnerResource struct { - apiResource + platformAPIResource } func (r *configurationProfileResourceOwnerResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/configuration_profile_servicenow.go b/internal/resources/configuration_profile_servicenow.go index 3e8bc4b..13bb840 100644 --- a/internal/resources/configuration_profile_servicenow.go +++ b/internal/resources/configuration_profile_servicenow.go @@ -23,7 +23,7 @@ var ( ) type configurationProfileServiceNowResource struct { - apiResource + platformAPIResource } func (r *configurationProfileServiceNowResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/configuration_profile_slack.go b/internal/resources/configuration_profile_slack.go index f47ce49..9612d95 100644 --- a/internal/resources/configuration_profile_slack.go +++ b/internal/resources/configuration_profile_slack.go @@ -34,7 +34,7 @@ type slackWebhookSecret struct { } type configurationProfileSlackResource struct { - apiResource + platformAPIResource } func (r *configurationProfileSlackResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/configuration_profile_symphony.go b/internal/resources/configuration_profile_symphony.go index 0733122..cd8b9e4 100644 --- a/internal/resources/configuration_profile_symphony.go +++ b/internal/resources/configuration_profile_symphony.go @@ -23,7 +23,7 @@ var ( ) type configurationProfileSymphonyResource struct { - apiResource + platformAPIResource } func (r *configurationProfileSymphonyResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/datadog_integration.go b/internal/resources/datadog_integration.go index a206ef1..c71e7cf 100644 --- a/internal/resources/datadog_integration.go +++ b/internal/resources/datadog_integration.go @@ -28,7 +28,7 @@ var ( ) type datadogIntegrationResource struct { - apiResource + platformAPIResource } func (r *datadogIntegrationResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/gcp_integration.go b/internal/resources/gcp_integration.go index 1266453..2493e96 100644 --- a/internal/resources/gcp_integration.go +++ b/internal/resources/gcp_integration.go @@ -24,7 +24,7 @@ var ( ) type gcpIntegrationResource struct { - apiResource + platformAPIResource } func (r *gcpIntegrationResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/notification_template.go b/internal/resources/notification_template.go index 8174bbe..8262d33 100644 --- a/internal/resources/notification_template.go +++ b/internal/resources/notification_template.go @@ -23,7 +23,7 @@ var ( ) type notificationTemplateResource struct { - apiResource + platformAPIResource } func (r *notificationTemplateResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/policy_collection.go b/internal/resources/policy_collection.go index bea5653..72a28da 100644 --- a/internal/resources/policy_collection.go +++ b/internal/resources/policy_collection.go @@ -30,7 +30,7 @@ var ( ) type policyCollectionResource struct { - apiResource + platformAPIResource } func (r *policyCollectionResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/policy_collection_mapping.go b/internal/resources/policy_collection_mapping.go index a90ebf9..8a11a38 100644 --- a/internal/resources/policy_collection_mapping.go +++ b/internal/resources/policy_collection_mapping.go @@ -22,7 +22,7 @@ var ( ) type policyCollectionMappingResource struct { - apiResource + platformAPIResource } func (r *policyCollectionMappingResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/report_group.go b/internal/resources/report_group.go index 85c24a5..b5a9223 100644 --- a/internal/resources/report_group.go +++ b/internal/resources/report_group.go @@ -32,7 +32,7 @@ var ( ) type reportGroupResource struct { - apiResource + platformAPIResource } func (r *reportGroupResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/repository.go b/internal/resources/repository.go index dde2db4..bb90ef2 100644 --- a/internal/resources/repository.go +++ b/internal/resources/repository.go @@ -26,7 +26,7 @@ var ( // repositoryResource defines the resource implementation. type repositoryResource struct { - apiResource + platformAPIResource } func (r *repositoryResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/resource.go b/internal/resources/resource.go index d4d2a72..a0a9cb4 100644 --- a/internal/resources/resource.go +++ b/internal/resources/resource.go @@ -13,18 +13,22 @@ import ( "github.com/stacklet/terraform-provider-stacklet/internal/providerdata" ) -// apiResource is a resource based on the API. -type apiResource struct { - api *platform.API - iacAPI *iac.API +// apiResource is a resource based on an API client. +type apiResource[T providerdata.APIClient] struct { + api T } // Configure sets up API access for the resource. -func (r *apiResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - if pd, err := providerdata.GetForResource(req); err != nil { +func (r *apiResource[T]) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if api, err := providerdata.GetAPI[T]("resource", req.ProviderData); err != nil { errors.AddDiagError(&resp.Diagnostics, err) - } else if pd != nil { - r.api = pd.API - r.iacAPI = pd.IaCAPI + } else { + r.api = api } } + +// platformAPIResource is a resource based on the platform API. +type platformAPIResource = apiResource[*platform.API] + +// iacAPIResource is a resource based on the IaC API. +type iacAPIResource = apiResource[*iac.API] //nolint:unused diff --git a/internal/resources/role_assignment.go b/internal/resources/role_assignment.go index 738edeb..a21243f 100644 --- a/internal/resources/role_assignment.go +++ b/internal/resources/role_assignment.go @@ -22,7 +22,7 @@ var ( ) type roleAssignmentResource struct { - apiResource + platformAPIResource } func (r *roleAssignmentResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/saml_provider.go b/internal/resources/saml_provider.go index d332337..8cee5f7 100644 --- a/internal/resources/saml_provider.go +++ b/internal/resources/saml_provider.go @@ -26,7 +26,7 @@ var ( ) type samlProviderResource struct { - apiResource + platformAPIResource } func (r *samlProviderResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/sso_group.go b/internal/resources/sso_group.go index 89c31bf..33b9a1d 100644 --- a/internal/resources/sso_group.go +++ b/internal/resources/sso_group.go @@ -22,7 +22,7 @@ var ( ) type ssoGroupResource struct { - apiResource + platformAPIResource } func (r *ssoGroupResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/user.go b/internal/resources/user.go index 6110176..913e97d 100644 --- a/internal/resources/user.go +++ b/internal/resources/user.go @@ -24,7 +24,7 @@ var ( ) type userResource struct { - apiResource + platformAPIResource } func (r *userResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { diff --git a/internal/resources/user_group.go b/internal/resources/user_group.go index c55f66d..096a99e 100644 --- a/internal/resources/user_group.go +++ b/internal/resources/user_group.go @@ -22,7 +22,7 @@ var ( ) type userGroupResource struct { - apiResource + platformAPIResource } func (r *userGroupResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {