A Terraform provider for Dokploy
Plugin-framework provider covering projects, environments, applications, Compose stacks, managed databases, domains, mounts, ports, redirects, basic auth, registries, SSH keys, certificates and backup destinations, over Dokploy's tRPC-over-REST API. The shim package exposes the provider to other Go modules, which is how pulumi-dokploy bridges it.
This commit is contained in:
87
internal/provider/resource_project.go
Normal file
87
internal/provider/resource_project.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
)
|
||||
|
||||
type projectModel struct {
|
||||
ID types.String `tfsdk:"id" dokploy:"projectId,id"`
|
||||
Name types.String `tfsdk:"name" dokploy:"name"`
|
||||
Description types.String `tfsdk:"description" dokploy:"description,nullable"`
|
||||
Env types.String `tfsdk:"env" dokploy:"env"`
|
||||
CreatedAt types.String `tfsdk:"created_at" dokploy:"createdAt,ro"`
|
||||
OrgID types.String `tfsdk:"organization_id" dokploy:"organizationId,ro"`
|
||||
|
||||
// Derived in PostRead from the nested `environments` array.
|
||||
DefaultEnvironmentID types.String `tfsdk:"default_environment_id"`
|
||||
}
|
||||
|
||||
func projectResource() ResourceSpec {
|
||||
return ResourceSpec{
|
||||
Name: "project",
|
||||
CreateProc: "project.create",
|
||||
ReadProc: "project.one",
|
||||
UpdateProc: "project.update",
|
||||
DeleteProc: "project.remove",
|
||||
CreateResponseKey: "project",
|
||||
NewModel: func() any { return &projectModel{} },
|
||||
PostRead: projectPostRead,
|
||||
Schema: schema.Schema{
|
||||
MarkdownDescription: "A Dokploy project: the top-level container for environments and services.\n\n" +
|
||||
"Creating a project automatically creates a default `production` environment. Its ID is exposed as " +
|
||||
"`default_environment_id`, so services can be attached without declaring a separate " +
|
||||
"`dokploy_environment` resource.",
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"id": computedID("Unique project identifier."),
|
||||
"name": requiredString("Display name of the project."),
|
||||
"description": optionalString("Free-form description."),
|
||||
"env": optionalComputedString("Project-wide environment variables in `KEY=value` format, one per " +
|
||||
"line. These are shared with every service in the project."),
|
||||
"created_at": computedString("RFC 3339 timestamp of when the project was created."),
|
||||
"organization_id": computedString("Organization that owns the project."),
|
||||
"default_environment_id": computedString("ID of the `production` environment that Dokploy creates " +
|
||||
"automatically with the project."),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// projectPostRead extracts the default environment from a `project.one`
|
||||
// response so it can be referenced directly.
|
||||
func projectPostRead(raw json.RawMessage, model any) error {
|
||||
project, ok := model.(*projectModel)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected *projectModel, got %T", model)
|
||||
}
|
||||
|
||||
var payload struct {
|
||||
Environments []struct {
|
||||
EnvironmentID string `json:"environmentId"`
|
||||
Name string `json:"name"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
} `json:"environments"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &payload); err != nil {
|
||||
return fmt.Errorf("decoding project environments: %w", err)
|
||||
}
|
||||
|
||||
project.DefaultEnvironmentID = types.StringNull()
|
||||
for _, env := range payload.Environments {
|
||||
if env.IsDefault {
|
||||
project.DefaultEnvironmentID = types.StringValue(env.EnvironmentID)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// Fall back to a conventionally named environment if none is flagged.
|
||||
for _, env := range payload.Environments {
|
||||
if env.Name == "production" {
|
||||
project.DefaultEnvironmentID = types.StringValue(env.EnvironmentID)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user