9.4 KiB
PostgreSQL Service Analysis & Implementation Plan
Date: 2026-01-27
Artifacts Analyzed: pg.har (Traffic), pg.html (Form Schema)
1. Service Overview
PostgreSQL "Database as a Service" in Nubes.
- Service Type: Stateful Application
- Lifecycle Constraint: Strict Quarantine (14 days).
- Like the VM resource, this service cannot be immediately deleted.
- Attempting to
deletean active instance returns:Услуга ПРОМ. Не в состоянии ПРИОСТАНОВЛЕНА более 14 дней. - Implication for Terraform: The
Deleteoperation in the provider must likely perform aSuspendinstead, or Terraform will require the user to manually suspend and wait 14 days before a successful destroy (which is bad UX). - Strategy Reference: Similar to
nubes_vm,destroyshould triggersuspend.
2. Resource Parameter Mapping
Extracted from pg.html (labels) and pg.har (values/IDs).
| Terraform Argument | Label (UI) | API Key (instanceOperationCfsParams) |
Type | ID | Notes |
|---|---|---|---|---|---|
nodes_count |
Количество узлов | resourceInstances |
Int | 80 | |
cpu |
Квота ядра пода (mili) | resourceCPU |
Int | 81 | 500 = 0.5 CPU |
ram |
Квота памяти пода (MB) | resourceMemory |
Int | 82 | |
disk_size |
Размер диска для базы данных (GB) | resourceDisk |
Int | 83 | |
version |
Версия PostgreSQL | appVersion |
String | 310 | "17", "16", etc. |
enable_external_master |
Выделение белого ip для master ноды | needExternalAddressMaster |
Bool | 145 | |
ip_space_master |
Имя ipSpace для публикации VIP master | ipSpaceNameMaster |
String | 102 | Req if external master=true |
enable_external_slave |
Выделение белого ip для slave ноды | needExternalAddressSlave |
Bool | 146 | |
ip_space_slave |
Имя ipSpace для публикации VIP slave | ipSpaceNameSlave |
String | --- | Req if external slave=true (ID mismatch in artifacts, verify) |
backup_schedule |
ext_BACKUP_SCHEDULE | ext_BACKUP_SCHEDULE |
String | 265 | Cron format |
backup_retention |
ext_BACKUP_NUM_TO_RETAIN | ext_BACKUP_NUM_TO_RETAIN |
Int | 266 | |
config_json |
jsonParameters | jsonParameters |
JSON | 311 | Postgres runtime config |
enable_pooler_master |
enablePgPoolerMaster | enablePgPoolerMaster |
Bool | --- | ID needs verification |
enable_pooler_slave |
enablePgPoolerSlave | enablePgPoolerSlave |
Bool | --- | ID needs verification |
allow_no_ssl |
allowNoSSL | allowNoSSL |
Bool | --- | ID needs verification |
dns_name |
(Inferred from HAR) | dnsRecord (Likely) |
String | 102 | In HAR k8s-3... was sent as ID 102, which matches ipSpaceNameMaster or DNS? Needs check. |
Note: Some IDs (Pooler, SSL, IP Space Slave) were visible in HTML but their submission IDs need confirmation from a full submission log or deduction.
Mismatches/Detailed Logic
- ID 102: In HAR,
svcOperationCfsParamId: 102sent valuek8s-3.ext.nubes.ru. This looks like a DNS name or IP Space name. HTML label is "Имя ipSpace...". - ID 23:
instanceOperationUid? No, HAR shows paramId 23 with UUID value. Check if this isaccount_idor similar.
3. Implementation Plan
Resource Schema (nubes_postgres)
resource "nubes_postgres" "db" {
organization_uuid = "..."
vdc_uuid = "..." # If applicable, or just organization context
name = "my-pg"
version = "17"
cpu = 500
ram = 512
disk_gb = 10
nodes = 1
# Network
external_master = false
# ...
# Backup
backup_schedule = "0 0 * * *"
backup_retention = 7
# Advanced
config = jsonencode({
"max_connections" = 100
})
}
Lifecycle Logic
- Create: POST
/instanceOperationCfsParamswith mapped IDs. - Read: GET
/instances/{id}-> ParsecfsParamsfrominstanceConfig. - Delete:
- Check
explainedStatus. - If
active: Callsuspend. State remains in Terraform (or marked as tainted? No, usually we just update state to show suspended or remove if we consider suspend=deleted). - Given the "quarantine", Terraform
destroycannot fully remove the resource. - Decision:
destroywill executesuspend. The resource will arguably still exist in the cloud. Terraform state should probably be removed to simulate "deletion" from the Infrastructure as Code perspective, alerting the user via logs that actual deletion requires 14 days wait.
- Check
4. Next Steps
- Create
internal/provider/postgres_resource.go(skeleton exists?). - Implement
Createmethod with correct param IDs. - specific testing of the
Suspendworkflow.
5. Technical Implementation Details (For AI Agent)
A. API Request Pattern
Analysis of pg.har reveals that parameters are NOT sent in a single JSON body.
The client sends multiple sequential POST requests to /api/v1/index.cfm/instanceOperationCfsParams.
Payload Schema per Parameter:
{
"paramValue": "1", // The value (stringified)
"instanceOperationUid": "...", // The operation ID (from the create instance response)
"svcOperationCfsParamId": 80 // The specific ID mapped above
}
Implementation Strategy:
The provider must loop through the defined parameters and make individual API calls for each one using the client.CreateInstanceParam (or similar existing method).
B. Code References
- Lifecycle Logic: See
internal/provider/vm_resource.go. This resource implements the "Suspend instead of Delete" logic required for quarantine-constrained resources. - API Client: Check
internal/provider/client_impl.goforSendCfsParamor similar helpers.
C. Implementation Order (User Request)
PRIORITY 1: Documentation First The user wants to visualize parameters on the documentation site before code implementation.
- Create Documentation File:
- Path:
docs/registry/resources/postgres.md - Content: Description of the resource, schema table (Inputs determined in Section 2), and an example usage block.
- Path:
- Update Navigation:
- File:
mkdocs.yml - Action: Add
- Postgres: resources/postgres.mdunderResources.
- File:
- Review: Ask user to check the visual representation.
- Codegen: Only then proceed to Go implementation.
6. Live Instance Analysis (2026-01-27)
User provided a full text dump of a running PostgreSQL instance (test-org-pg-1769262059).
Key Findings:
-
Quarantine Confirmation:
- Operation Log:
deletefailed with "Услуга ПРОМ. Не в состоянии ПРИОСТАНОВЛЕНА более 14 дней". - This confirms
terraform destroyMUST callsuspendand remove state, warning the user.
- Operation Log:
-
Sensitive Outputs (Credentials):
adminUser:postgresadminPass: (Provided in plain text in UI/API response)standbyUser/standbyPass: For HA configurations.
-
Connection Info:
internalConnect.master: internal K8s DNS (e.g.,postgresqlk8s-master...svc.).externalConnect: JSON object withmasterandslavekeys, each containingip,fqdn,uuid,isExternal.
-
Dependencies:
- Explicit dependency on an S3 Bucket (
s3Uid:6d6061cb-...). - UI shows: "Экземпляр зависит от: S3 Object Storage".
- Implication: The Terraform resource likely needs an
s3_bucket_idinput argument.
- Explicit dependency on an S3 Bucket (
-
Constraints:
- Disk Shrink Forbidden: Operation log shows error "ERROR | Ресурсы под Disk меньше чем в текущем экземпляре".
- Terraform validation must prevent reducing
disk_size.
-
New Parameters Identified:
resourceRealm:k8s-3.ext.nubes.ru(Likely corresponds to ID 102 inferred earlier).monitoring: Contains Grafana URL.
7. API Diff Check (2026-02-18)
Based on service metadata for Postgres (svcId 90) across prod/test/dev.
Operations
- prod:
create,delete,modify,recovery,restart,resume,suspend - test/dev: all prod ops plus
create_user,delete_user,create_database,delete_database
Input Params (operation-level)
- create: identical param set across prod/test/dev (21 params)
- modify/delete/restart/resume/suspend: identical across prod/test/dev
- recovery: prod missing
resourceCPU,resourceDisk,resourceInstances,resourceMemory,resourceRealmcompared to test/dev
Outputs
- Output fields are not declared in service metadata. Only visible on instance state (
state_out,state_params).
8. YAML Generator Check (service_params_gen)
Generator reads service metadata via:
/index.cfm?endpoint=/services/{svcId}/index.cfm?endpoint=/serviceOperation/{svcOperationId}
Limitations found:
- Only collects params for create and modify operations.
- Does not include
create_user,delete_user,create_database,delete_databaseeven when present in API (test/dev). - Outputs are hardcoded defaults, not pulled from API.