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:
2026-08-09 12:17:26 +03:00
commit a6d8aa8b52
160 changed files with 24260 additions and 0 deletions

View File

@@ -0,0 +1,406 @@
package provider
import (
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
// The five managed databases share almost their entire surface. The Terraform
// Plugin Framework cannot reflect into embedded structs, so each model is
// written out flat, but the schema attributes are assembled from one place.
// databaseCommonSchema returns the attributes every database resource exposes.
// engine is used to word the descriptions.
func databaseCommonSchema(engine string) map[string]schema.Attribute {
return map[string]schema.Attribute{
"id": computedID("Unique " + engine + " identifier."),
"name": requiredString("Display name of the database."),
"app_name": optionalComputedReplaceString("Unique Docker service name. Generated by Dokploy when omitted. " +
"Changing it forces a new database."),
"description": optionalString("Free-form description."),
"environment_id": requiredReplaceString("Environment this database belongs to."),
"server_id": optionalReplaceString("Remote server to deploy on. Omit to use the Dokploy host itself."),
"command": optionalString("Override the container entrypoint command."),
"args": optionalComputedStringList("Arguments appended to the container command."),
"env": optionalString("Environment variables in `KEY=value` format, one per line."),
"memory_reservation": optionalString("Soft memory reservation, for example `256m`."),
"memory_limit": optionalString("Hard memory limit, for example `512m`."),
"cpu_reservation": optionalString("Soft CPU reservation, for example `0.5`."),
"cpu_limit": optionalString("Hard CPU limit, for example `1`."),
"external_port": schema.Int64Attribute{
Optional: true,
MarkdownDescription: "Host port to expose the database on. Leave unset to keep the database reachable " +
"only from inside the Docker network.",
},
"replicas": optionalComputedInt("Number of replicas to run."),
"network_ids": optionalComputedStringList("IDs of additional Docker networks to attach."),
"detach_dokploy_network": optionalComputedBool("Detach the service from the shared `dokploy-network`."),
"health_check_swarm": optionalJSON("Docker Swarm health check configuration, as a JSON object."),
"restart_policy_swarm": optionalJSON("Docker Swarm restart policy, as a JSON object."),
"placement_swarm": optionalJSON("Docker Swarm placement constraints, as a JSON object."),
"update_config_swarm": optionalJSON("Docker Swarm rolling update configuration, as a JSON object."),
"rollback_config_swarm": optionalJSON("Docker Swarm rollback configuration, as a JSON object."),
"mode_swarm": optionalJSON("Docker Swarm service mode, as a JSON object."),
"labels_swarm": optionalJSON("Docker Swarm service labels, as a JSON object."),
"network_swarm": optionalJSON("Docker Swarm network attachments, as a JSON array."),
"endpoint_spec_swarm": optionalJSON("Docker Swarm endpoint specification, as a JSON object."),
"ulimits_swarm": optionalJSON("Docker Swarm ulimits, as a JSON object."),
"stop_grace_period_swarm": schema.Int64Attribute{Optional: true, MarkdownDescription: "Grace period in nanoseconds before a container is killed."},
"application_status": computedString("Current status reported by Dokploy: `idle`, `running`, `done` or `error`."),
"created_at": computedString("RFC 3339 timestamp of when the database was created."),
}
}
func withAttributes(base map[string]schema.Attribute, extra map[string]schema.Attribute) map[string]schema.Attribute {
for name, attribute := range extra {
base[name] = attribute
}
return base
}
func databaseNote(engine string) string {
return "A managed " + engine + " instance running on Dokploy.\n\n" +
"~> Creating this resource provisions the service definition but does **not** start a deployment. " +
"Deploy it from the Dokploy UI or CLI.\n\n" +
"~> Credentials are stored in Terraform state. Use a state backend with encryption at rest."
}
// ---------------------------------------------------------------- PostgreSQL
type postgresModel struct {
ID types.String `tfsdk:"id" dokploy:"postgresId,id"`
Name types.String `tfsdk:"name" dokploy:"name"`
AppName types.String `tfsdk:"app_name" dokploy:"appName"`
Description types.String `tfsdk:"description" dokploy:"description,nullable"`
EnvironmentID types.String `tfsdk:"environment_id" dokploy:"environmentId"`
ServerID types.String `tfsdk:"server_id" dokploy:"serverId,create"`
DatabaseName types.String `tfsdk:"database_name" dokploy:"databaseName"`
DatabaseUser types.String `tfsdk:"database_user" dokploy:"databaseUser"`
DatabasePassword types.String `tfsdk:"database_password" dokploy:"databasePassword"`
DockerImage types.String `tfsdk:"docker_image" dokploy:"dockerImage"`
Command types.String `tfsdk:"command" dokploy:"command,nullable"`
Args types.List `tfsdk:"args" dokploy:"args,nullable"`
Env types.String `tfsdk:"env" dokploy:"env,nullable"`
MemoryReserve types.String `tfsdk:"memory_reservation" dokploy:"memoryReservation,nullable"`
MemoryLimit types.String `tfsdk:"memory_limit" dokploy:"memoryLimit,nullable"`
CPUReserve types.String `tfsdk:"cpu_reservation" dokploy:"cpuReservation,nullable"`
CPULimit types.String `tfsdk:"cpu_limit" dokploy:"cpuLimit,nullable"`
ExternalPort types.Int64 `tfsdk:"external_port" dokploy:"externalPort,nullable"`
Replicas types.Int64 `tfsdk:"replicas" dokploy:"replicas"`
NetworkIDs types.List `tfsdk:"network_ids" dokploy:"networkIds"`
DetachDokployNetwork types.Bool `tfsdk:"detach_dokploy_network" dokploy:"detachDokployNetwork"`
HealthCheckSwarm jsontypes.Normalized `tfsdk:"health_check_swarm" dokploy:"healthCheckSwarm,nullable"`
RestartPolicySwarm jsontypes.Normalized `tfsdk:"restart_policy_swarm" dokploy:"restartPolicySwarm,nullable"`
PlacementSwarm jsontypes.Normalized `tfsdk:"placement_swarm" dokploy:"placementSwarm,nullable"`
UpdateConfigSwarm jsontypes.Normalized `tfsdk:"update_config_swarm" dokploy:"updateConfigSwarm,nullable"`
RollbackConfigSwarm jsontypes.Normalized `tfsdk:"rollback_config_swarm" dokploy:"rollbackConfigSwarm,nullable"`
ModeSwarm jsontypes.Normalized `tfsdk:"mode_swarm" dokploy:"modeSwarm,nullable"`
LabelsSwarm jsontypes.Normalized `tfsdk:"labels_swarm" dokploy:"labelsSwarm,nullable"`
NetworkSwarm jsontypes.Normalized `tfsdk:"network_swarm" dokploy:"networkSwarm,nullable"`
EndpointSpecSwarm jsontypes.Normalized `tfsdk:"endpoint_spec_swarm" dokploy:"endpointSpecSwarm,nullable"`
UlimitsSwarm jsontypes.Normalized `tfsdk:"ulimits_swarm" dokploy:"ulimitsSwarm,nullable"`
StopGracePeriodSwarm types.Int64 `tfsdk:"stop_grace_period_swarm" dokploy:"stopGracePeriodSwarm,nullable"`
ApplicationStatus types.String `tfsdk:"application_status" dokploy:"applicationStatus,ro"`
CreatedAt types.String `tfsdk:"created_at" dokploy:"createdAt,ro"`
}
func postgresResource() ResourceSpec {
return ResourceSpec{
Name: "postgres",
// The create endpoint accepts only the core fields; everything else
// (limits, env, swarm settings) has to be written through update.
UpdateAfterCreate: true,
CreateProc: "postgres.create",
ReadProc: "postgres.one",
UpdateProc: "postgres.update",
DeleteProc: "postgres.remove",
NewModel: func() any { return &postgresModel{} },
Schema: schema.Schema{
MarkdownDescription: databaseNote("PostgreSQL"),
Attributes: withAttributes(databaseCommonSchema("postgres"), map[string]schema.Attribute{
"database_name": requiredString("Name of the database to create."),
"database_user": requiredString("Database user to create."),
"database_password": sensitiveString("Password for the database user.", true),
"docker_image": requiredString("PostgreSQL image to run, for example `postgres:16`."),
}),
},
}
}
// --------------------------------------------------------------------- MySQL
type mysqlModel struct {
ID types.String `tfsdk:"id" dokploy:"mysqlId,id"`
Name types.String `tfsdk:"name" dokploy:"name"`
AppName types.String `tfsdk:"app_name" dokploy:"appName"`
Description types.String `tfsdk:"description" dokploy:"description,nullable"`
EnvironmentID types.String `tfsdk:"environment_id" dokploy:"environmentId"`
ServerID types.String `tfsdk:"server_id" dokploy:"serverId,create"`
DatabaseName types.String `tfsdk:"database_name" dokploy:"databaseName"`
DatabaseUser types.String `tfsdk:"database_user" dokploy:"databaseUser"`
DatabasePassword types.String `tfsdk:"database_password" dokploy:"databasePassword"`
DatabaseRootPass types.String `tfsdk:"database_root_password" dokploy:"databaseRootPassword"`
DockerImage types.String `tfsdk:"docker_image" dokploy:"dockerImage"`
Command types.String `tfsdk:"command" dokploy:"command,nullable"`
Args types.List `tfsdk:"args" dokploy:"args,nullable"`
Env types.String `tfsdk:"env" dokploy:"env,nullable"`
MemoryReserve types.String `tfsdk:"memory_reservation" dokploy:"memoryReservation,nullable"`
MemoryLimit types.String `tfsdk:"memory_limit" dokploy:"memoryLimit,nullable"`
CPUReserve types.String `tfsdk:"cpu_reservation" dokploy:"cpuReservation,nullable"`
CPULimit types.String `tfsdk:"cpu_limit" dokploy:"cpuLimit,nullable"`
ExternalPort types.Int64 `tfsdk:"external_port" dokploy:"externalPort,nullable"`
Replicas types.Int64 `tfsdk:"replicas" dokploy:"replicas"`
NetworkIDs types.List `tfsdk:"network_ids" dokploy:"networkIds"`
DetachDokployNetwork types.Bool `tfsdk:"detach_dokploy_network" dokploy:"detachDokployNetwork"`
HealthCheckSwarm jsontypes.Normalized `tfsdk:"health_check_swarm" dokploy:"healthCheckSwarm,nullable"`
RestartPolicySwarm jsontypes.Normalized `tfsdk:"restart_policy_swarm" dokploy:"restartPolicySwarm,nullable"`
PlacementSwarm jsontypes.Normalized `tfsdk:"placement_swarm" dokploy:"placementSwarm,nullable"`
UpdateConfigSwarm jsontypes.Normalized `tfsdk:"update_config_swarm" dokploy:"updateConfigSwarm,nullable"`
RollbackConfigSwarm jsontypes.Normalized `tfsdk:"rollback_config_swarm" dokploy:"rollbackConfigSwarm,nullable"`
ModeSwarm jsontypes.Normalized `tfsdk:"mode_swarm" dokploy:"modeSwarm,nullable"`
LabelsSwarm jsontypes.Normalized `tfsdk:"labels_swarm" dokploy:"labelsSwarm,nullable"`
NetworkSwarm jsontypes.Normalized `tfsdk:"network_swarm" dokploy:"networkSwarm,nullable"`
EndpointSpecSwarm jsontypes.Normalized `tfsdk:"endpoint_spec_swarm" dokploy:"endpointSpecSwarm,nullable"`
UlimitsSwarm jsontypes.Normalized `tfsdk:"ulimits_swarm" dokploy:"ulimitsSwarm,nullable"`
StopGracePeriodSwarm types.Int64 `tfsdk:"stop_grace_period_swarm" dokploy:"stopGracePeriodSwarm,nullable"`
ApplicationStatus types.String `tfsdk:"application_status" dokploy:"applicationStatus,ro"`
CreatedAt types.String `tfsdk:"created_at" dokploy:"createdAt,ro"`
}
func mysqlResource() ResourceSpec {
return ResourceSpec{
Name: "mysql",
// The create endpoint accepts only the core fields; everything else
// (limits, env, swarm settings) has to be written through update.
UpdateAfterCreate: true,
CreateProc: "mysql.create",
ReadProc: "mysql.one",
UpdateProc: "mysql.update",
DeleteProc: "mysql.remove",
NewModel: func() any { return &mysqlModel{} },
Schema: schema.Schema{
MarkdownDescription: databaseNote("MySQL"),
Attributes: withAttributes(databaseCommonSchema("mysql"), map[string]schema.Attribute{
"database_name": requiredString("Name of the database to create."),
"database_user": requiredString("Database user to create."),
"database_password": sensitiveString("Password for the database user.", true),
"database_root_password": sensitiveString("Password for the MySQL `root` user.", true),
"docker_image": requiredString("MySQL image to run, for example `mysql:8`."),
}),
},
}
}
// ------------------------------------------------------------------- MariaDB
type mariadbModel struct {
ID types.String `tfsdk:"id" dokploy:"mariadbId,id"`
Name types.String `tfsdk:"name" dokploy:"name"`
AppName types.String `tfsdk:"app_name" dokploy:"appName"`
Description types.String `tfsdk:"description" dokploy:"description,nullable"`
EnvironmentID types.String `tfsdk:"environment_id" dokploy:"environmentId"`
ServerID types.String `tfsdk:"server_id" dokploy:"serverId,create"`
DatabaseName types.String `tfsdk:"database_name" dokploy:"databaseName"`
DatabaseUser types.String `tfsdk:"database_user" dokploy:"databaseUser"`
DatabasePassword types.String `tfsdk:"database_password" dokploy:"databasePassword"`
DatabaseRootPass types.String `tfsdk:"database_root_password" dokploy:"databaseRootPassword"`
DockerImage types.String `tfsdk:"docker_image" dokploy:"dockerImage"`
Command types.String `tfsdk:"command" dokploy:"command,nullable"`
Args types.List `tfsdk:"args" dokploy:"args,nullable"`
Env types.String `tfsdk:"env" dokploy:"env,nullable"`
MemoryReserve types.String `tfsdk:"memory_reservation" dokploy:"memoryReservation,nullable"`
MemoryLimit types.String `tfsdk:"memory_limit" dokploy:"memoryLimit,nullable"`
CPUReserve types.String `tfsdk:"cpu_reservation" dokploy:"cpuReservation,nullable"`
CPULimit types.String `tfsdk:"cpu_limit" dokploy:"cpuLimit,nullable"`
ExternalPort types.Int64 `tfsdk:"external_port" dokploy:"externalPort,nullable"`
Replicas types.Int64 `tfsdk:"replicas" dokploy:"replicas"`
NetworkIDs types.List `tfsdk:"network_ids" dokploy:"networkIds"`
DetachDokployNetwork types.Bool `tfsdk:"detach_dokploy_network" dokploy:"detachDokployNetwork"`
HealthCheckSwarm jsontypes.Normalized `tfsdk:"health_check_swarm" dokploy:"healthCheckSwarm,nullable"`
RestartPolicySwarm jsontypes.Normalized `tfsdk:"restart_policy_swarm" dokploy:"restartPolicySwarm,nullable"`
PlacementSwarm jsontypes.Normalized `tfsdk:"placement_swarm" dokploy:"placementSwarm,nullable"`
UpdateConfigSwarm jsontypes.Normalized `tfsdk:"update_config_swarm" dokploy:"updateConfigSwarm,nullable"`
RollbackConfigSwarm jsontypes.Normalized `tfsdk:"rollback_config_swarm" dokploy:"rollbackConfigSwarm,nullable"`
ModeSwarm jsontypes.Normalized `tfsdk:"mode_swarm" dokploy:"modeSwarm,nullable"`
LabelsSwarm jsontypes.Normalized `tfsdk:"labels_swarm" dokploy:"labelsSwarm,nullable"`
NetworkSwarm jsontypes.Normalized `tfsdk:"network_swarm" dokploy:"networkSwarm,nullable"`
EndpointSpecSwarm jsontypes.Normalized `tfsdk:"endpoint_spec_swarm" dokploy:"endpointSpecSwarm,nullable"`
UlimitsSwarm jsontypes.Normalized `tfsdk:"ulimits_swarm" dokploy:"ulimitsSwarm,nullable"`
StopGracePeriodSwarm types.Int64 `tfsdk:"stop_grace_period_swarm" dokploy:"stopGracePeriodSwarm,nullable"`
ApplicationStatus types.String `tfsdk:"application_status" dokploy:"applicationStatus,ro"`
CreatedAt types.String `tfsdk:"created_at" dokploy:"createdAt,ro"`
}
func mariadbResource() ResourceSpec {
return ResourceSpec{
Name: "mariadb",
// The create endpoint accepts only the core fields; everything else
// (limits, env, swarm settings) has to be written through update.
UpdateAfterCreate: true,
CreateProc: "mariadb.create",
ReadProc: "mariadb.one",
UpdateProc: "mariadb.update",
DeleteProc: "mariadb.remove",
NewModel: func() any { return &mariadbModel{} },
Schema: schema.Schema{
MarkdownDescription: databaseNote("MariaDB"),
Attributes: withAttributes(databaseCommonSchema("mariadb"), map[string]schema.Attribute{
"database_name": requiredString("Name of the database to create."),
"database_user": requiredString("Database user to create."),
"database_password": sensitiveString("Password for the database user.", true),
"database_root_password": sensitiveString("Password for the MariaDB `root` user.", true),
"docker_image": requiredString("MariaDB image to run, for example `mariadb:11`."),
}),
},
}
}
// ------------------------------------------------------------------- MongoDB
type mongoModel struct {
ID types.String `tfsdk:"id" dokploy:"mongoId,id"`
Name types.String `tfsdk:"name" dokploy:"name"`
AppName types.String `tfsdk:"app_name" dokploy:"appName"`
Description types.String `tfsdk:"description" dokploy:"description,nullable"`
EnvironmentID types.String `tfsdk:"environment_id" dokploy:"environmentId"`
ServerID types.String `tfsdk:"server_id" dokploy:"serverId,create"`
DatabaseUser types.String `tfsdk:"database_user" dokploy:"databaseUser"`
DatabasePassword types.String `tfsdk:"database_password" dokploy:"databasePassword"`
DockerImage types.String `tfsdk:"docker_image" dokploy:"dockerImage"`
ReplicaSets types.Bool `tfsdk:"replica_sets" dokploy:"replicaSets,nullable"`
Command types.String `tfsdk:"command" dokploy:"command,nullable"`
Args types.List `tfsdk:"args" dokploy:"args,nullable"`
Env types.String `tfsdk:"env" dokploy:"env,nullable"`
MemoryReserve types.String `tfsdk:"memory_reservation" dokploy:"memoryReservation,nullable"`
MemoryLimit types.String `tfsdk:"memory_limit" dokploy:"memoryLimit,nullable"`
CPUReserve types.String `tfsdk:"cpu_reservation" dokploy:"cpuReservation,nullable"`
CPULimit types.String `tfsdk:"cpu_limit" dokploy:"cpuLimit,nullable"`
ExternalPort types.Int64 `tfsdk:"external_port" dokploy:"externalPort,nullable"`
Replicas types.Int64 `tfsdk:"replicas" dokploy:"replicas"`
NetworkIDs types.List `tfsdk:"network_ids" dokploy:"networkIds"`
DetachDokployNetwork types.Bool `tfsdk:"detach_dokploy_network" dokploy:"detachDokployNetwork"`
HealthCheckSwarm jsontypes.Normalized `tfsdk:"health_check_swarm" dokploy:"healthCheckSwarm,nullable"`
RestartPolicySwarm jsontypes.Normalized `tfsdk:"restart_policy_swarm" dokploy:"restartPolicySwarm,nullable"`
PlacementSwarm jsontypes.Normalized `tfsdk:"placement_swarm" dokploy:"placementSwarm,nullable"`
UpdateConfigSwarm jsontypes.Normalized `tfsdk:"update_config_swarm" dokploy:"updateConfigSwarm,nullable"`
RollbackConfigSwarm jsontypes.Normalized `tfsdk:"rollback_config_swarm" dokploy:"rollbackConfigSwarm,nullable"`
ModeSwarm jsontypes.Normalized `tfsdk:"mode_swarm" dokploy:"modeSwarm,nullable"`
LabelsSwarm jsontypes.Normalized `tfsdk:"labels_swarm" dokploy:"labelsSwarm,nullable"`
NetworkSwarm jsontypes.Normalized `tfsdk:"network_swarm" dokploy:"networkSwarm,nullable"`
EndpointSpecSwarm jsontypes.Normalized `tfsdk:"endpoint_spec_swarm" dokploy:"endpointSpecSwarm,nullable"`
UlimitsSwarm jsontypes.Normalized `tfsdk:"ulimits_swarm" dokploy:"ulimitsSwarm,nullable"`
StopGracePeriodSwarm types.Int64 `tfsdk:"stop_grace_period_swarm" dokploy:"stopGracePeriodSwarm,nullable"`
ApplicationStatus types.String `tfsdk:"application_status" dokploy:"applicationStatus,ro"`
CreatedAt types.String `tfsdk:"created_at" dokploy:"createdAt,ro"`
}
func mongoResource() ResourceSpec {
return ResourceSpec{
Name: "mongo",
// The create endpoint accepts only the core fields; everything else
// (limits, env, swarm settings) has to be written through update.
UpdateAfterCreate: true,
CreateProc: "mongo.create",
ReadProc: "mongo.one",
UpdateProc: "mongo.update",
DeleteProc: "mongo.remove",
NewModel: func() any { return &mongoModel{} },
Schema: schema.Schema{
MarkdownDescription: databaseNote("MongoDB"),
Attributes: withAttributes(databaseCommonSchema("mongo"), map[string]schema.Attribute{
"database_user": requiredString("Root username to create."),
"database_password": sensitiveString("Password for the root user.", true),
"docker_image": optionalComputedString("MongoDB image to run. Defaults to `mongo:8`."),
"replica_sets": optionalComputedBool("Start the instance as a single-node replica set."),
}),
},
}
}
// --------------------------------------------------------------------- Redis
type redisModel struct {
ID types.String `tfsdk:"id" dokploy:"redisId,id"`
Name types.String `tfsdk:"name" dokploy:"name"`
AppName types.String `tfsdk:"app_name" dokploy:"appName"`
Description types.String `tfsdk:"description" dokploy:"description,nullable"`
EnvironmentID types.String `tfsdk:"environment_id" dokploy:"environmentId"`
ServerID types.String `tfsdk:"server_id" dokploy:"serverId,create"`
DatabasePassword types.String `tfsdk:"database_password" dokploy:"databasePassword"`
DockerImage types.String `tfsdk:"docker_image" dokploy:"dockerImage"`
Command types.String `tfsdk:"command" dokploy:"command,nullable"`
Args types.List `tfsdk:"args" dokploy:"args,nullable"`
Env types.String `tfsdk:"env" dokploy:"env,nullable"`
MemoryReserve types.String `tfsdk:"memory_reservation" dokploy:"memoryReservation,nullable"`
MemoryLimit types.String `tfsdk:"memory_limit" dokploy:"memoryLimit,nullable"`
CPUReserve types.String `tfsdk:"cpu_reservation" dokploy:"cpuReservation,nullable"`
CPULimit types.String `tfsdk:"cpu_limit" dokploy:"cpuLimit,nullable"`
ExternalPort types.Int64 `tfsdk:"external_port" dokploy:"externalPort,nullable"`
Replicas types.Int64 `tfsdk:"replicas" dokploy:"replicas"`
NetworkIDs types.List `tfsdk:"network_ids" dokploy:"networkIds"`
DetachDokployNetwork types.Bool `tfsdk:"detach_dokploy_network" dokploy:"detachDokployNetwork"`
HealthCheckSwarm jsontypes.Normalized `tfsdk:"health_check_swarm" dokploy:"healthCheckSwarm,nullable"`
RestartPolicySwarm jsontypes.Normalized `tfsdk:"restart_policy_swarm" dokploy:"restartPolicySwarm,nullable"`
PlacementSwarm jsontypes.Normalized `tfsdk:"placement_swarm" dokploy:"placementSwarm,nullable"`
UpdateConfigSwarm jsontypes.Normalized `tfsdk:"update_config_swarm" dokploy:"updateConfigSwarm,nullable"`
RollbackConfigSwarm jsontypes.Normalized `tfsdk:"rollback_config_swarm" dokploy:"rollbackConfigSwarm,nullable"`
ModeSwarm jsontypes.Normalized `tfsdk:"mode_swarm" dokploy:"modeSwarm,nullable"`
LabelsSwarm jsontypes.Normalized `tfsdk:"labels_swarm" dokploy:"labelsSwarm,nullable"`
NetworkSwarm jsontypes.Normalized `tfsdk:"network_swarm" dokploy:"networkSwarm,nullable"`
EndpointSpecSwarm jsontypes.Normalized `tfsdk:"endpoint_spec_swarm" dokploy:"endpointSpecSwarm,nullable"`
UlimitsSwarm jsontypes.Normalized `tfsdk:"ulimits_swarm" dokploy:"ulimitsSwarm,nullable"`
StopGracePeriodSwarm types.Int64 `tfsdk:"stop_grace_period_swarm" dokploy:"stopGracePeriodSwarm,nullable"`
ApplicationStatus types.String `tfsdk:"application_status" dokploy:"applicationStatus,ro"`
CreatedAt types.String `tfsdk:"created_at" dokploy:"createdAt,ro"`
}
func redisResource() ResourceSpec {
return ResourceSpec{
Name: "redis",
// The create endpoint accepts only the core fields; everything else
// (limits, env, swarm settings) has to be written through update.
UpdateAfterCreate: true,
CreateProc: "redis.create",
ReadProc: "redis.one",
UpdateProc: "redis.update",
DeleteProc: "redis.remove",
NewModel: func() any { return &redisModel{} },
Schema: schema.Schema{
MarkdownDescription: databaseNote("Redis"),
Attributes: withAttributes(databaseCommonSchema("redis"), map[string]schema.Attribute{
"database_password": sensitiveString("Password used to authenticate to Redis.", true),
"docker_image": requiredString("Redis image to run, for example `redis:7`."),
}),
},
}
}