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" ) // DNS providers and vault providers both arrived in Dokploy v0.30.0. They // share a shape: a name plus a free-form `config` object whose keys depend on // a `providerType` discriminator nested inside it. // // Dokploy masks the credentials in `config` on every read, so the value is // tagged `noread`: the configured value stays authoritative in state instead // of being overwritten with asterisks on the next refresh. // ---------------------------------------------------------- DNS provider type dnsProviderModel struct { ID types.String `tfsdk:"id" dokploy:"dnsProviderId,id"` Name types.String `tfsdk:"name" dokploy:"name"` Config jsontypes.Normalized `tfsdk:"config" dokploy:"config,noread"` ProviderType types.String `tfsdk:"provider_type" dokploy:"providerType,ro"` OrganizationID types.String `tfsdk:"organization_id" dokploy:"organizationId,ro"` CreatedAt types.String `tfsdk:"created_at" dokploy:"createdAt,ro"` } func dnsProviderResource() ResourceSpec { return ResourceSpec{ Name: "dns_provider", CreateProc: "dnsProvider.create", ReadProc: "dnsProvider.one", UpdateProc: "dnsProvider.update", DeleteProc: "dnsProvider.remove", NewModel: func() any { return &dnsProviderModel{} }, Schema: schema.Schema{ MarkdownDescription: "A DNS provider connection Dokploy uses to create records for domains " + "automatically.\n\n" + "`config` is a JSON object whose shape depends on `providerType`:\n\n" + "```hcl\n" + "# Cloudflare\n" + "config = jsonencode({ providerType = \"cloudflare\", apiToken = var.cloudflare_token })\n\n" + "# AWS Route53\n" + "config = jsonencode({\n" + " providerType = \"route53\"\n" + " accessKeyId = var.aws_access_key_id\n" + " secretAccessKey = var.aws_secret_access_key\n" + "})\n" + "```\n\n" + "~> Dokploy masks the credentials when reading a provider back, so Terraform keeps the value " + "you configured. Drift in `config` is not detected.", Attributes: map[string]schema.Attribute{ "id": computedID("Unique DNS provider identifier."), "name": requiredString("Name of the connection. Must be unique within the organization and may " + "contain only letters, digits, `-` and `_`."), "config": schema.StringAttribute{ Required: true, Sensitive: true, CustomType: jsontypes.NormalizedType{}, MarkdownDescription: "Provider credentials as a JSON object, including the `providerType` discriminator.", }, "provider_type": computedString("Provider kind derived from `config`: `cloudflare` or `route53`."), "organization_id": computedString("Organization that owns the connection."), "created_at": computedString("RFC 3339 timestamp of when the connection was created."), }, }, } } // -------------------------------------------------------- Vault provider type vaultProviderModel struct { ID types.String `tfsdk:"id" dokploy:"vaultProviderId,id"` Name types.String `tfsdk:"name" dokploy:"name"` Config jsontypes.Normalized `tfsdk:"config" dokploy:"config,noread"` Assignments jsontypes.Normalized `tfsdk:"assignments" dokploy:"assignments"` ProviderType types.String `tfsdk:"provider_type" dokploy:"providerType,ro"` OrganizationID types.String `tfsdk:"organization_id" dokploy:"organizationId,ro"` CreatedAt types.String `tfsdk:"created_at" dokploy:"createdAt,ro"` } func vaultProviderResource() ResourceSpec { return ResourceSpec{ Name: "vault_provider", CreateProc: "vaultProvider.create", ReadProc: "vaultProvider.one", UpdateProc: "vaultProvider.update", DeleteProc: "vaultProvider.remove", NewModel: func() any { return &vaultProviderModel{} }, Schema: schema.Schema{ MarkdownDescription: "An external secret manager Dokploy resolves environment variables from at " + "deploy time.\n\n" + "Reference a secret from any `env` value with `${{vault..}}`. The value is fetched " + "when the deployment runs and is never stored in Dokploy — so rotating it in the vault takes " + "effect on the next deploy with no Terraform change.\n\n" + "Supported `providerType` values: `hashicorp` (Vault/OpenBao), `infisical`, `aws` " + "(Secrets Manager), `doppler`, `azure` (Key Vault) and `scaleway`.\n\n" + "```hcl\n" + "config = jsonencode({\n" + " providerType = \"hashicorp\"\n" + " url = \"https://vault.example.com\"\n" + " token = var.vault_token\n" + " mount = \"secret\"\n" + "})\n" + "```\n\n" + "~> Dokploy masks the credentials when reading a provider back, so Terraform keeps the value " + "you configured. Drift in `config` is not detected.", Attributes: map[string]schema.Attribute{ "id": computedID("Unique vault provider identifier."), "name": requiredString("Name of the connection, unique within the organization."), "config": schema.StringAttribute{ Required: true, Sensitive: true, CustomType: jsontypes.NormalizedType{}, MarkdownDescription: "Provider credentials as a JSON object, including the `providerType` discriminator.", }, "assignments": schema.StringAttribute{ Required: true, CustomType: jsontypes.NormalizedType{}, MarkdownDescription: "JSON array scoping which projects or environments may resolve secrets " + "from this provider. Pass `jsonencode([])` to leave it unscoped.", }, "provider_type": computedString("Provider kind derived from `config`."), "organization_id": computedString("Organization that owns the connection."), "created_at": computedString("RFC 3339 timestamp of when the connection was created."), }, }, } }