Documentation
¶
Index ¶
- Variables
- func OpenEmailBody(key []byte, args *SendEmailArgs) (string, error)
- type ArriveHypervisorArgs
- type BootstrapHiveArgs
- type DepartHypervisorArgs
- type DestroyTenantArgs
- type DomainCohortAuditArgs
- type Enqueuer
- type MockEnqueuer
- func (m *MockEnqueuer) EnqueueArriveHypervisor(context.Context, *ArriveHypervisorArgs) error
- func (m *MockEnqueuer) EnqueueBootstrapHive(context.Context, *BootstrapHiveArgs) error
- func (m *MockEnqueuer) EnqueueDepartHypervisor(context.Context, *DepartHypervisorArgs) error
- func (m *MockEnqueuer) EnqueueDestroyTenant(ctx context.Context, args *DestroyTenantArgs) error
- func (m *MockEnqueuer) EnqueueProvisionTenant(ctx context.Context, args *ProvisionTenantArgs) error
- func (m *MockEnqueuer) EnqueueSendEmail(context.Context, *SendEmailArgs) error
- func (m *MockEnqueuer) EnqueueSyncHiveCapacity(context.Context, *SyncHiveCapacityArgs) error
- type OrgProvingArgs
- type ProvisionTenantArgs
- type SendEmailArgs
- type SyncHiveCapacityArgs
- type TokenSessionCleanupArgs
Constants ¶
This section is empty.
Variables ¶
var QueuePayloadKeyID = uuid.MustParse("00000000-0000-0000-0000-0000000000e1")
queuePayloadKeyID names the key a sealed payload was written under. utils.Seal refuses uuid.Nil, because a key id is what lets a rotation tell re-wrapped rows from un-rewrapped ones. Queue payloads are short-lived and never rotated in place — a job outlives its key by minutes, not months — so a single stable id is honest here, and it still distinguishes payloads from any future scheme.
Functions ¶
func OpenEmailBody ¶
func OpenEmailBody(key []byte, args *SendEmailArgs) (string, error)
OpenEmailBody is the worker's half.
Types ¶
type ArriveHypervisorArgs ¶
type ArriveHypervisorArgs struct {
OrganizationID string `json:"organization_id"`
HypervisorID string `json:"hypervisor_id"`
TargetHiveID string `json:"target_hive_id"`
// Links are the joining node's corosync rings. Carried on the job rather than
// looked up, because they are an operator's decision about network topology
// and nothing in the database knows them.
//
// Plural: a single ring makes the cluster network a single point of failure
// for quorum. Proxmox supports link0-link7.
Links []tenant.CorosyncLink `json:"links"`
}
ArriveHypervisorArgs adds one standalone host to a hive.
Keyed on the HYPERVISOR, symmetrically with departure. The old asymmetry — keyed on the bee — was forced by a Hypervisor row meaning "something a capacity sync observed in a cluster", which a host outside one did not have. That row is the durable machine record now and exists before any cluster membership does.
func (ArriveHypervisorArgs) Kind ¶
func (ArriveHypervisorArgs) Kind() string
type BootstrapHiveArgs ¶
type BootstrapHiveArgs struct {
OrganizationID string `json:"organization_id"`
HypervisorID string `json:"hypervisor_id"`
TargetHiveID string `json:"target_hive_id"`
// Links are the first node's corosync rings. They matter more here than on
// an arrival: `pvecm create` writes the ring configuration every later node
// inherits, so a single-ring cluster created today is a single point of
// failure for quorum for as long as the cluster lives.
Links []tenant.CorosyncLink `json:"links"`
}
BootstrapHiveArgs creates a Proxmox cluster on a standalone host and records it as the hive's first node.
The other half of ArriveHypervisorArgs, and the reason a hive can acquire a first node at all: arrival refuses with target_hive_empty when the hive has none, which is every hive on the day it is created.
func (BootstrapHiveArgs) Kind ¶
func (BootstrapHiveArgs) Kind() string
type DepartHypervisorArgs ¶
type DepartHypervisorArgs struct {
OrganizationID string `json:"organization_id"`
HypervisorID string `json:"hypervisor_id"`
// Mirrors jobs.DepartHypervisorArgs.
CredentialDisposition string `json:"credential_disposition"`
}
DepartHypervisorArgs removes one host from its hive, leaving it standalone and fleetless. Mirrors jobs.DepartHypervisorArgs and is matched to it by Kind — the same split every job kind here uses, so a handler never imports the worker package.
func (DepartHypervisorArgs) Kind ¶
func (DepartHypervisorArgs) Kind() string
type DestroyTenantArgs ¶
type DestroyTenantArgs struct {
OrganizationID string `json:"organization_id"`
}
func (DestroyTenantArgs) Kind ¶
func (DestroyTenantArgs) Kind() string
type DomainCohortAuditArgs ¶
type DomainCohortAuditArgs struct{}
func (DomainCohortAuditArgs) Kind ¶
func (DomainCohortAuditArgs) Kind() string
type Enqueuer ¶
type Enqueuer interface {
EnqueueProvisionTenant(ctx context.Context, args *ProvisionTenantArgs) error
EnqueueDestroyTenant(ctx context.Context, args *DestroyTenantArgs) error
EnqueueSendEmail(ctx context.Context, args *SendEmailArgs) error
// Fleet lifecycle. A migration is a departure and then an arrival, enqueued
// separately by an operator, because the fleetless state between them is real
// and a failed arrival must leave a standalone host rather than a
// half-migrated one.
EnqueueDepartHypervisor(ctx context.Context, args *DepartHypervisorArgs) error
EnqueueArriveHypervisor(ctx context.Context, args *ArriveHypervisorArgs) error
EnqueueBootstrapHive(ctx context.Context, args *BootstrapHiveArgs) error
EnqueueSyncHiveCapacity(ctx context.Context, args *SyncHiveCapacityArgs) error
}
type MockEnqueuer ¶
type MockEnqueuer struct{}
func (*MockEnqueuer) EnqueueArriveHypervisor ¶
func (m *MockEnqueuer) EnqueueArriveHypervisor(context.Context, *ArriveHypervisorArgs) error
func (*MockEnqueuer) EnqueueBootstrapHive ¶
func (m *MockEnqueuer) EnqueueBootstrapHive(context.Context, *BootstrapHiveArgs) error
func (*MockEnqueuer) EnqueueDepartHypervisor ¶
func (m *MockEnqueuer) EnqueueDepartHypervisor(context.Context, *DepartHypervisorArgs) error
func (*MockEnqueuer) EnqueueDestroyTenant ¶
func (m *MockEnqueuer) EnqueueDestroyTenant(ctx context.Context, args *DestroyTenantArgs) error
func (*MockEnqueuer) EnqueueProvisionTenant ¶
func (m *MockEnqueuer) EnqueueProvisionTenant(ctx context.Context, args *ProvisionTenantArgs) error
func (*MockEnqueuer) EnqueueSendEmail ¶
func (m *MockEnqueuer) EnqueueSendEmail(context.Context, *SendEmailArgs) error
EnqueueSendEmail records nothing and succeeds: the mock exists so that a command which never runs a worker can still build a Deps.
func (*MockEnqueuer) EnqueueSyncHiveCapacity ¶
func (m *MockEnqueuer) EnqueueSyncHiveCapacity(context.Context, *SyncHiveCapacityArgs) error
type OrgProvingArgs ¶
type OrgProvingArgs struct{}
func (OrgProvingArgs) Kind ¶
func (OrgProvingArgs) Kind() string
type ProvisionTenantArgs ¶
type ProvisionTenantArgs struct {
OrganizationID string `json:"organization_id"`
}
func (ProvisionTenantArgs) Kind ¶
func (ProvisionTenantArgs) Kind() string
type SendEmailArgs ¶
type SendEmailArgs struct {
To string `json:"to"`
Subject string `json:"subject"`
// The sealed body, as base64 produced by utils.Seal.
Ciphertext string `json:"ciphertext"`
IV string `json:"iv"`
Tag string `json:"tag"`
KeyID string `json:"key_id"`
}
SendEmailArgs is a queued outbound email.
Mail used to be sent from a bare goroutine that logged on failure and dropped it. A transient SMTP fault therefore lost the message outright: for a registration confirmation that means an account which exists, cannot log in (the confirmation gate), and whose organization is never provisioned — with a single log line as the only trace. Going through River buys retries with backoff, and a failure that is visible in the job table rather than in scrollback.
The BODY IS SEALED, and that is the point of this shape. It contains a live token — a confirmation link, a password reset, an invitation — and River persists args as JSONB in the control DB and retains them after completion. Storing the rendered body in clear would put a working credential next to the table that deliberately keeps only its SHA-256, which is the whole reason that table hashes. Sealed, the queue holds ciphertext the worker can open and a database reader cannot.
Subject and To stay in clear: the worker needs no key to route or log a job, and neither is a credential.
func SealEmailBody ¶
func SealEmailBody(key []byte, to, subject, htmlBody string) (*SendEmailArgs, error)
SealEmailBody renders a SendEmailArgs with its body sealed under the queue payload key.
func (SendEmailArgs) Kind ¶
func (SendEmailArgs) Kind() string
type SyncHiveCapacityArgs ¶
type SyncHiveCapacityArgs struct {
OrganizationID string `json:"organization_id"`
HiveID string `json:"hive_id"`
}
SyncHiveCapacityArgs refreshes one hive's capacity observations on demand.
The scheduled fan-out does this on a timer; this is the same job enqueued by an operator who does not want to wait for the next tick — most often because a departure just refused with drain_unknown.
func (SyncHiveCapacityArgs) Kind ¶
func (SyncHiveCapacityArgs) Kind() string
type TokenSessionCleanupArgs ¶
type TokenSessionCleanupArgs struct{}
func (TokenSessionCleanupArgs) Kind ¶
func (TokenSessionCleanupArgs) Kind() string