workflow

package
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
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

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

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

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

type TokenSessionCleanupArgs

type TokenSessionCleanupArgs struct{}

func (TokenSessionCleanupArgs) Kind

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL