loadBalancers
Load balancers on a provider account (DigitalOcean regional and global first). Every call records what the tenant wants and returns at once; the `vps.provider-resources` reconciler converges the provider through `ProviderImpl.loadBalancers`. Reading takes `compute:load-balancers:read`, everything else `compute:load-balancers:manage`, on `provider-load-balancer/{id}`. A load balancer books one `loadBalancers` quota on the pool (no quota row grants none) and bills `vps.load-balancer.hours` from `ready` until deleted.
Load balancers on a provider account (DigitalOcean regional and global first). Every call records what the tenant wants and returns at once; the vps.provider-resources reconciler converges the provider through ProviderImpl.loadBalancers. Reading takes compute:load-balancers:read, everything else compute:load-balancers:manage, on provider-load-balancer/{id}. A load balancer books one loadBalancers quota on the pool (no quota row grants none) and bills vps.load-balancer.hours from ready until deleted.
What a load balancer reaches is computed from the tenant's own rows and sent to the provider as explicit machine ids, never a tag, so it never reaches another tenant's machine. A regional one targets the tenant's instances in its pool and region (targets: { pool: true }) or named instances of the tenant (targets: { instanceIds }); a global one targets the tenant's regional load balancers (targets: { loadBalancerIds }). A regional load balancer is in one VPC and the provider balances only to machines in it: it lives on one subnet of a tenant network (subnetId, or the subnet its named instances share) and reaches only instances on that subnet, or, without one, on the account's default network and reaches only instances on no tenant network. An instance counts once it has a machine and until it is being deleted. Deleting an instance updates its load balancers at once; one that gains a machine is added by the periodic pass, within five minutes.
All 5 methods are served by @better-compute/server 0.3.0.
| Method | Kind | Authorization | Phase | Status |
|---|---|---|---|---|
create | mutation | compute:load-balancers:manage @ compute-provider-load-balancer | v1.0 | registered |
list | read | compute:load-balancers:read @ compute-tenant + items | v1.0 | registered |
get | read | compute:load-balancers:read @ compute-provider-load-balancer | v1.0 | registered |
update | mutation | compute:load-balancers:manage @ compute-provider-load-balancer | v1.0 | registered |
delete | mutation | compute:load-balancers:manage @ compute-provider-load-balancer | v1.0 | registered |
create
POST /api/compute/loadBalancers/create
Makes a load balancer with its forwarding rules (1 to 15; an https or http2 entry names a certificateId of the tenant on the same account, or an https one passes TLS through with tlsPassthrough), an optional healthCheck, stickySessions, sourceRanges and redirectHttpToHttps, and (global only) the domains it serves. It returns pending, booking one loadBalancers; no room, or no quota row, is QUOTA_EXCEEDED. Another tenant's instance is ACCESS_DENIED, another region or account INVALID_INPUT, named instances on two subnets (or not on subnetId) INVALID_INPUT, another tenant's subnet NOT_FOUND, another tenant's certificate or load balancer NOT_FOUND. Named instances are also decided as compute:instances:update on each, with the caller's own credential. The provider is asked once the certificates it names are ready. Publishes providerLoadBalancer.created, then providerLoadBalancer.ready with its address, or providerLoadBalancer.error.
- Kind: mutation
- Authorization:
compute:load-balancers:manage@compute-provider-load-balancer - Module:
vps - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | at most 128 characters; matches ^[A-Za-z0-9._:-]{1,128}$ |
projectId | string | at most 56 characters; matches ^prj_[0-9a-hjkmnp-tv-z]{26,52}$ | |
poolId | string | yes | at most 57 characters; matches ^pool_[0-9a-hjkmnp-tv-z]{26,52}$ |
name | string | yes | at most 42 characters; matches ^[a-z]([-a-z0-9]{0,40}[a-z0-9])?$ |
description | string | at most 256 characters | |
scope | one of regional, global | default "regional" | |
region | string | at most 40 characters; matches ^[a-z][a-z0-9-]{0,38}[a-z0-9]$ | |
subnetId | string | at most 57 characters; matches ^snet_[0-9a-hjkmnp-tv-z]{26,52}$ | |
targets | object | yes | |
targets.pool | any | ||
targets.instanceIds | list of string | 1-100 items | |
targets.loadBalancerIds | list of string | 1-100 items | |
forwarding | list of object | yes | 1-15 items |
forwarding[].entryProtocol | one of http, https, http2, tcp, udp | yes | |
forwarding[].entryPort | integer | yes | 1-65535 |
forwarding[].targetProtocol | one of http, https, http2, tcp, udp | yes | |
forwarding[].targetPort | integer | yes | 1-65535 |
forwarding[].certificateId | string | at most 58 characters; matches ^pcert_[0-9a-hjkmnp-tv-z]{26,52}$ | |
forwarding[].tlsPassthrough | boolean | ||
healthCheck | object | ||
healthCheck.protocol | one of http, https, tcp | yes | |
healthCheck.port | integer | yes | 1-65535 |
healthCheck.path | string | at most 255 characters | |
healthCheck.intervalSeconds | integer | 3-300 | |
healthCheck.timeoutSeconds | integer | 3-300 | |
healthCheck.healthyThreshold | integer | 2-10 | |
healthCheck.unhealthyThreshold | integer | 2-10 | |
stickySessions | object | ||
stickySessions.cookieName | string | yes | at most 40 characters; matches ^[A-Za-z0-9_-]{1,40}$ |
stickySessions.ttlSeconds | integer | yes | 1-604800 |
sourceRanges | object | ||
sourceRanges.allow | list of string | 0-50 items | |
sourceRanges.deny | list of string | 0-50 items | |
redirectHttpToHttps | boolean | ||
domains | list of object | 0-20 items | |
domains[].name | string | yes | at most 253 characters |
domains[].certificateId | string | at most 58 characters; matches ^pcert_[0-9a-hjkmnp-tv-z]{26,52}$ | |
idempotencyKey | string | yes | at most 128 characters; matches ^[A-Za-z0-9._:-]{1,128}$ |
list
POST /api/compute/loadBalancers/list
Returns the tenant's load balancers in the order they were made (at most 1000), optionally of one pool or project. Deleted ones only with includeDeleted.
- Kind: read
- Authorization:
compute:load-balancers:read@compute-tenant+ items - Module:
vps - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | at most 128 characters; matches ^[A-Za-z0-9._:-]{1,128}$ |
poolId | string | at most 57 characters; matches ^pool_[0-9a-hjkmnp-tv-z]{26,52}$ | |
projectId | string | at most 56 characters; matches ^prj_[0-9a-hjkmnp-tv-z]{26,52}$ | |
includeDeleted | boolean | default false |
get
POST /api/compute/loadBalancers/get
Returns one load balancer: its settings, targets, address (and addressV6) once assigned, and its state.
- Kind: read
- Authorization:
compute:load-balancers:read@compute-provider-load-balancer - Module:
vps - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | at most 128 characters; matches ^[A-Za-z0-9._:-]{1,128}$ |
loadBalancerId | string | yes | at most 56 characters; matches ^plb_[0-9a-hjkmnp-tv-z]{26,52}$ |
update
POST /api/compute/loadBalancers/update
Replaces each part given (forwarding, healthCheck, targets, stickySessions, sourceRanges, redirectHttpToHttps, domains) in place and returns it updating until the provider has applied it; publishes providerLoadBalancer.updated with what changed. The scope, region, pool and subnet never change: make another load balancer. Named instances must be on its subnet (or, without one, on no tenant network), else INVALID_INPUT.
- Kind: mutation
- Authorization:
compute:load-balancers:manage@compute-provider-load-balancer - Module:
vps - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | at most 128 characters; matches ^[A-Za-z0-9._:-]{1,128}$ |
loadBalancerId | string | yes | at most 56 characters; matches ^plb_[0-9a-hjkmnp-tv-z]{26,52}$ |
targets | object | ||
targets.pool | any | ||
targets.instanceIds | list of string | 1-100 items | |
targets.loadBalancerIds | list of string | 1-100 items | |
forwarding | list of object | 1-15 items | |
forwarding[].entryProtocol | one of http, https, http2, tcp, udp | yes | |
forwarding[].entryPort | integer | yes | 1-65535 |
forwarding[].targetProtocol | one of http, https, http2, tcp, udp | yes | |
forwarding[].targetPort | integer | yes | 1-65535 |
forwarding[].certificateId | string | at most 58 characters; matches ^pcert_[0-9a-hjkmnp-tv-z]{26,52}$ | |
forwarding[].tlsPassthrough | boolean | ||
healthCheck | object | ||
healthCheck.protocol | one of http, https, tcp | yes | |
healthCheck.port | integer | yes | 1-65535 |
healthCheck.path | string | at most 255 characters | |
healthCheck.intervalSeconds | integer | 3-300 | |
healthCheck.timeoutSeconds | integer | 3-300 | |
healthCheck.healthyThreshold | integer | 2-10 | |
healthCheck.unhealthyThreshold | integer | 2-10 | |
stickySessions | object | ||
stickySessions.cookieName | string | yes | at most 40 characters; matches ^[A-Za-z0-9_-]{1,40}$ |
stickySessions.ttlSeconds | integer | yes | 1-604800 |
sourceRanges | object | ||
sourceRanges.allow | list of string | 0-50 items | |
sourceRanges.deny | list of string | 0-50 items | |
redirectHttpToHttps | boolean | ||
domains | list of object | 0-20 items | |
domains[].name | string | yes | at most 253 characters |
domains[].certificateId | string | at most 58 characters; matches ^pcert_[0-9a-hjkmnp-tv-z]{26,52}$ |
delete
POST /api/compute/loadBalancers/delete
Marks the load balancer for deletion and returns it deleting; the reconciler deletes it at the provider, refunds its quota and publishes providerLoadBalancer.deleted. A regional load balancer a global one of the tenant targets is INVALID_STATE (reason inUse).
- Kind: mutation
- Authorization:
compute:load-balancers:manage@compute-provider-load-balancer - Module:
vps - Phase: v1.0 (registered)
Input
| Field | Type | Required | Constraints |
|---|---|---|---|
tenantId | string | yes | at most 128 characters; matches ^[A-Za-z0-9._:-]{1,128}$ |
loadBalancerId | string | yes | at most 56 characters; matches ^plb_[0-9a-hjkmnp-tv-z]{26,52}$ |
Better Compute is created by Sean Filimon
Last updated
kubernetesSubstrates
A pool substrate is the managed Kubernetes cluster behind a pool whose policy has a `substrate` (`kind: 'kubernetes'`, an `account`, and `cluster: { create }` or `cluster: { adopt }`). The `kubernetes.substrates` reconciler records it here: it creates the cluster with one node pool per flavor (or adopts an existing cluster and adds the flavors' node pools to it, named `bc-<pool>-<flavor>` so they never collide with the tenant's own pools), server-side applies bcd's DaemonSet with a hosted join token, and the cluster's Nodes join the pool. Every object it applies carries the label `better-compute.dev/substrate-pool=<pool id>`; on an adopted cluster an object of the same name it did not create is never taken over or deleted. There is nothing to call to create or delete a substrate: change the pool's policy, or archive the pool to tear it down.
metal
The metal group enrolls machines by their BMCs and moves them through the provision state machine: inspect, commission, deploy, rescue, release and retire. Each verb checks the move against the provision state table, records it in one transaction and queues the metal reconciler, which runs the workflow of the new state; no verb touches the machine itself. Every method returns the node's metal view, which reports whether BMC credentials are set but never returns them. See [Bare metal](/docs/guides/bare-metal) and [BMC drivers and credentials](/docs/guides/bare-metal/bmc).