mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-21 03:36:35 +00:00
63 lines
4.8 KiB
Markdown
63 lines
4.8 KiB
Markdown
# EC2 instance-command contract, version 1
|
|
|
|
This package owns the cross-process contract used to direct a command to the
|
|
node that owns a running EC2 instance. It is not an in-process service
|
|
interface or the owner of instance state.
|
|
|
|
## Route and purpose
|
|
|
|
The subject is `ec2.cmd.<instance-id>`. It is request/reply, and the daemon
|
|
that hosts that instance's QEMU process is the only subscriber. This route
|
|
exists because lifecycle operations such as start, stop, terminate, volume
|
|
attach/detach and ENI attach/detach must reach that one process; sending them
|
|
through the normal daemon queue group could select a different node.
|
|
|
|
`InstanceCommandSubject` constructs a targeted subject. The corresponding
|
|
subscription and permission pattern is `ec2.cmd.*`: the `*` deliberately
|
|
matches exactly one final instance-ID token, not an arbitrary descendant.
|
|
|
|
## Compatibility boundary
|
|
|
|
`EC2InstanceCommand`, its nested data objects, their JSON field names and the
|
|
subject shape are wire compatibility. Callers and receivers must use this
|
|
package rather than rebuild those details. `commands_test.go` preserves the
|
|
version-1 JSON shape and subject form.
|
|
|
|
This package owns shared command payloads and the drain-volume response. It
|
|
does not define every action's reply body, authorize the request, store EC2
|
|
state or implement NATS transport. Those remain responsibilities of the EC2
|
|
domain and its runtime composition.
|
|
|
|
Any incompatible subject or payload change requires an explicit versioned
|
|
contract or an approved compatibility plan; it is not a package refactor.
|
|
|
|
## Default VPC request
|
|
|
|
`EnsureDefaultVpcSubject` (`ec2.EnsureDefaultVpc`) is the request/reply route on which the gateway's account creation asks a daemon in the `spinifex-workers` queue group to build the account's default VPC.
|
|
Only the subject is owned here today.
|
|
The request (`account_id`) and reply (`vpc_id`, `error`) bodies are still declared as anonymous structs on each side; moving them into this package is a contract change that needs its own characterization first.
|
|
|
|
## Platform inventory
|
|
|
|
`PlatformInventorySubject` (`ec2.v1.PlatformInventory`) is a request/reply route on which a daemon in the `spinifex-workers` queue group reports one account's key pairs, placement groups, launch templates and their `ec2-tags` entries from the EC2 owner stores.
|
|
EC2 owns it: `domains/ec2/accountinventory` produces the reply and the daemon serves it; the only consumer today is `accountteardown`, which calls it only on an explicit operator dry run (`spx admin account delete --dry-run` or the admin API `DryRun`) and only logs a comparison with its legacy listings; no teardown calls it.
|
|
|
|
The request names the account in its body (`account_id`, a 12-digit ID) and may carry an opaque `correlation_ref` that is echoed for logs.
|
|
The daemon ignores `X-Account-ID` for this subject.
|
|
Neither field grants anything: the subject is read-only, writes to no store, and its reply is never authority to delete.
|
|
|
|
The reply has one `kinds` entry per kind (`key-pair`, `placement-group`, `launch-template`, `tag-index`) with a status and scan start and end times.
|
|
The times are zero when no owner scan ran: a consumer-synthesised `scan-incomplete` report for no responder, a timeout or a transport failure carries zero timestamps and must not be read as a scan.
|
|
`observed-clean-at-scan-time` means every store for that kind was read completely and held nothing at scan time; writers are not fenced, so it is a snapshot and never evidence of absence.
|
|
`items` carry only a resource ID, kind and disposition (`live`, `dependency-held`, or tag-index `residue`), which are the identities the per-kind Describe subjects already return.
|
|
A `dependency-held` placement group does not name its member instances, which may be stale and are not exposed by the existing subjects.
|
|
Records no existing subject exposes (public-key objects without metadata, launch-template version bodies and name-index entries without a header, and every unreadable record) appear only as aggregate `counts` per kind, disposition and class.
|
|
The reply never carries an object key, raw KV key, key or template name, tag key or value, public-key bytes, launch-template data, user data, record body or store error text; `incomplete_reasons` are fixed categories.
|
|
|
|
### Compatibility boundary
|
|
|
|
The subject name carries the contract major; `platform_inventory_test.go` preserves the version-1 JSON shape and wire vocabulary.
|
|
Producer and consumer are in the coordinated Spinifex release, so the window is N and N-1.
|
|
A daemon that predates the subject has no subscription, so the request gets no responder; the consumer treats no responder, a timeout, an error reply, an undecodable reply, a reply for another account, and a missing, repeated or unknown-status kind as `scan-incomplete`, never clean.
|
|
An incompatible change to the subject, fields or vocabulary needs a new major.
|