ARCHITECTURE: PRIMARY source of truth — action rules (redeploy inline, others excluded), 401 retry, API endpoint auto-detect

This commit is contained in:
“Naeel”
2026-07-05 08:17:56 +04:00
parent e9901c6309
commit a5df6dca62
+49 -13
View File
@@ -1,8 +1,10 @@
# Provider Architecture (Source of Truth)
# Provider Architecture (PRIMARY SOURCE OF TRUTH)
**⛔ THIS FILE IS THE FOUNDATION. ALL CODE AND SCRIPTS ARE DERIVED FROM IT.**
This document defines the project-wide architecture and rules for generation,
provider behavior, and documentation. It is the single source of truth for
implementation and DevOps workflow.
provider behavior, and documentation. Any change to provider logic MUST be
reflected here FIRST, then implemented in `gen_v2` and other tools.
## Core Principles
@@ -12,6 +14,7 @@ implementation and DevOps workflow.
4) Documentation is generated from the same YAML.
5) Build artifacts for 3 OS targets are published to the registry, and docs are
published to the website.
6) `devops/ARCHITECTURE.md` (this file) is the primary spec. Code follows.
## Service Selection
@@ -19,6 +22,12 @@ implementation and DevOps workflow.
- Each line starts with service_id, followed by service name/alias.
- Operation timeouts source is defined by: `devops/config/operation_timeouts.json`.
## API Endpoint
The provider supports two API styles, auto-detected by `NUBES_API_ENDPOINT`:
- **Legacy proxy**: contains `index.cfm``?endpoint=/path`
- **REST Gateway**: no `index.cfm` → direct path concatenation
## Unified YAML (Per Service)
One YAML file per service. This is the only input for:
@@ -39,16 +48,33 @@ Required top-level fields:
### Operations: Kinds and Rules
Each operation has a kind:
- kind: instance (CRUD for the service instance, plus suspend/resume)
- kind: subresource (CRUD for objects inside the service, e.g. users/databases)
- kind: action (one-shot operations, e.g. restart/recovery/redeploy)
**instance** — CRUD for the service instance, plus suspend/resume:
| API action | Terraform behavior |
|---|---|
| create | `terraform apply` (new resource) |
| delete | `terraform destroy` |
| modify | `terraform apply` (params changed) |
| suspend | `terraform destroy` when `suspend_on_destroy=true` |
| resume | `terraform apply` when `adopt_existing_on_create=true` |
**subresource** — CRUD for objects inside the service (users, databases, topics):
- Exposed as separate resources: `nubes_{service}_{subresource}`
- Identity = `{parent_instance_uid, subresource_key}` (e.g. `{postgres_id, username}`)
- Supports `adopt_existing_on_create` — if subresource already exists, adopt it instead of failing
**action** — one-shot operations. **Only `redeploy` is included**:
- `redeploy`**inline**: field `git_revision` in the main resource. When it changes, call redeploy instead of (or after) modify
- `restart`, `recovery`, `reconcile`**excluded**. These are manual operational tasks, performed via UI only. Reason:
- `restart` — modify handles pod restart when needed
- `recovery` — creates a new instance from backup, not a modification of existing
- `reconcile` — sync after manual changes; Terraform owns its own state
### Idempotency Rules
- instance CRUD is idempotent via standard Terraform behavior.
- subresource CRUD is idempotent by resource identity.
- action operations are idempotent via a trigger field (e.g. run_id/nonce).
If the trigger does not change, the action is not re-run.
- `redeploy`: idempotent via `git_revision` field — if unchanged, no redeploy
### Lifecycle Behavior
@@ -83,6 +109,13 @@ Each operation has a kind:
- Core is universal: no service-specific logic inside the core.
- Generated service resources contain only schema/params and references.
### API Resilience
- Core MUST retry transient 401 errors from Gateway (3 attempts, exponential backoff).
Gateway may temporarily reject valid JWT tokens.
- GET operations (GetInstanceState, GetInstanceStateRaw) retry 401 with 2s/4s/8s backoff.
- `doRequest` treats 401 as retryable for GET requests (alongside 429, 502, 503, 504).
### Subresource Resources
Subresource operations are exposed as standard resources.
@@ -98,14 +131,17 @@ resource "nubes_postgres_user" "user1" {
role = "app_user"
}
### Action Resources
### Redeploy (inline action)
Services with `redeploy` operation get a `git_revision` field in the main resource.
Changing `git_revision` triggers `redeploy` instead of `modify`.
Action operations are exposed as action resources with a trigger field.
Example HCL:
resource "nubes_postgres_restart" "restart1" {
postgres_id = nubes_postgres.db.id
run_id = "2026-02-20-001"
resource "nubes_flask" "app" {
resource_name = "my-flask"
git_revision = "abc123" # ← change this to trigger redeploy
app_configuration = jsonencode({...})
}
## Concurrency and State Locking