Add ConfigValidators and CreateDefaults hooks to the generic resource

Two things ResourceSpec could not express: plan-time checks that span
several attributes, and create bodies that need a key Dokploy insists on
receiving but the model cannot produce. Both are used by the commits that
follow.
This commit is contained in:
max-voitcov
2026-08-26 00:39:51 +03:00
parent 209079cf68
commit 0890384552
+26 -3
View File
@@ -67,6 +67,16 @@ type ResourceSpec struct {
// discover the new ID.
ListIDs func(ctx context.Context, api *client.Client, model any) (map[string]struct{}, error)
// CreateDefaults supplies values for API fields that Dokploy's create
// schema insists on receiving but that the model cannot produce -- most
// often a name the server declines to generate. Only keys missing from
// the assembled body are added, so an explicit configuration always wins.
CreateDefaults func(model any) map[string]any
// ConfigValidators are plan-time checks that span several attributes, for
// invariants Terraform's schema cannot express on its own.
ConfigValidators []resource.ConfigValidator
// PostRead derives extra model fields from the raw read response, for
// values that are not plain top-level columns (for example a project's
// default environment, which arrives nested under `environments`).
@@ -80,9 +90,10 @@ type genericResource struct {
}
var (
_ resource.Resource = &genericResource{}
_ resource.ResourceWithConfigure = &genericResource{}
_ resource.ResourceWithImportState = &genericResource{}
_ resource.Resource = &genericResource{}
_ resource.ResourceWithConfigure = &genericResource{}
_ resource.ResourceWithImportState = &genericResource{}
_ resource.ResourceWithConfigValidators = &genericResource{}
)
func newGenericResource(spec ResourceSpec) func() resource.Resource {
@@ -97,6 +108,10 @@ func (r *genericResource) Schema(_ context.Context, _ resource.SchemaRequest, re
resp.Schema = r.spec.Schema
}
func (r *genericResource) ConfigValidators(_ context.Context) []resource.ConfigValidator {
return r.spec.ConfigValidators
}
func (r *genericResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
@@ -125,6 +140,14 @@ func (r *genericResource) Create(ctx context.Context, req resource.CreateRequest
return
}
if r.spec.CreateDefaults != nil {
for key, value := range r.spec.CreateDefaults(model) {
if _, present := body[key]; !present {
body[key] = value
}
}
}
if r.spec.NeedsOrganizationID {
orgID, err := r.api.OrganizationID(ctx)
if err != nil {