Documentation
¶
Overview ¶
Package digitalocean reads DigitalOcean's billing and infrastructure APIs. DO is our PRIMARY venue (a large promotional credit); this client turns the customer balance + billing history into money.Cents the finance aggregator folds into gross margin and runway, and exposes the account's physical inventory — droplets, block-storage volumes, DOKS clusters, load balancers — that the /v1/admin/infra board reads.
This is the ONE DigitalOcean client the admin plane uses. A new DO read is a method here calling the shared get/send primitive, never a second client.
Auth is a single personal-access token, DO_API_TOKEN, sourced from a KMSSecret on the cloud env — NEVER hard-coded. When the token is unset the client is not Ready and every read reports the honest not-configured state.
SIGN CONVENTION (from DO's public OpenAPI spec): GET /v2/customers/my/balance returns decimal-dollar strings; account_balance carries the accounts-receivable sign — POSITIVE = we OWE DO, NEGATIVE = we hold CREDIT. Our promo credit shows as a negative account balance, so credit-remaining = -Account. Dollars are converted to cents once at this edge; everything downstream is money.Cents.
Index ¶
- type Action
- type Balance
- type Client
- func (c *Client) Balance(ctx context.Context) (Balance, error)
- func (c *Client) Clusters(ctx context.Context) ([]Cluster, error)
- func (c *Client) DeleteDroplet(ctx context.Context, dropletID int) error
- func (c *Client) DeleteLoadBalancer(ctx context.Context, lbID string) error
- func (c *Client) DeleteVolume(ctx context.Context, volumeID string) error
- func (c *Client) Droplets(ctx context.Context) ([]Droplet, error)
- func (c *Client) History(ctx context.Context, perPage int) ([]Entry, error)
- func (c *Client) Kubeconfig(ctx context.Context, clusterID string) ([]byte, error)
- func (c *Client) LoadBalancers(ctx context.Context) ([]LoadBalancer, error)
- func (c *Client) Ready() bool
- func (c *Client) ResizeDroplet(ctx context.Context, dropletID int, size string, disk bool) (Action, error)
- func (c *Client) ResizeVolume(ctx context.Context, volumeID, region string, gib int) (Action, error)
- func (c *Client) ScaleNodePool(ctx context.Context, clusterID, poolID, name string, count int) error
- func (c *Client) SnapshotVolume(ctx context.Context, volumeID, name string) (Snapshot, error)
- func (c *Client) Volumes(ctx context.Context) ([]Volume, error)
- type Cluster
- type Droplet
- type Entry
- type LoadBalancer
- type NodePool
- type Snapshot
- type Volume
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Action ¶ added in v1.801.256
Action is a queued DO droplet action. DO performs a resize ASYNCHRONOUSLY, so a successful call means "accepted", not "done" — the id is what an operator polls.
type Balance ¶
Balance is the decoded /v2/customers/my/balance, in cents. Account carries DO's accounts-receivable sign (positive = owed to DO, negative = credit we hold).
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client reads DigitalOcean billing with a personal-access token.
func NewWithBase ¶
NewWithBase builds a DO client against base (a test may point it at a stub).
func (*Client) Balance ¶
Balance fetches the customer balance, converting every dollar string to cents.
func (*Client) Clusters ¶ added in v1.801.245
Clusters lists ALL DOKS clusters. This is the authoritative denominator for the orphan analysis: a volume may only be called unreferenced once EVERY cluster here has been searched for a PV that claims it.
func (*Client) DeleteDroplet ¶ added in v1.801.256
DeleteDroplet destroys a droplet. Irreversible, and there is no snapshot-first undo for a droplet the way there is for a volume: callers MUST have proven the droplet is not a DOKS node first (see clients/admin/infra).
func (*Client) DeleteLoadBalancer ¶ added in v1.801.256
DeleteLoadBalancer destroys a load balancer. Irreversible, and it takes the public IP with it: callers MUST have proven no Kubernetes Service still targets it.
func (*Client) DeleteVolume ¶ added in v1.801.245
DeleteVolume destroys a block-storage volume. Irreversible: callers MUST have proven the volume is referenced by no PV in any cluster first.
func (*Client) History ¶
History fetches recent billing history. Used only for the burn-down series; a failure is non-fatal to the caller (it renders the balance tiles with no series).
func (*Client) Kubeconfig ¶ added in v1.801.245
Kubeconfig fetches a cluster's admin kubeconfig. DO returns a token-based config against the cluster's public https endpoint (never an exec plugin), which the caller must still funnel through fleet.SafeRESTConfig before dialing.
func (*Client) LoadBalancers ¶ added in v1.801.245
func (c *Client) LoadBalancers(ctx context.Context) ([]LoadBalancer, error)
LoadBalancers lists ALL load balancers across the account.
func (*Client) ResizeDroplet ¶ added in v1.801.256
func (c *Client) ResizeDroplet(ctx context.Context, dropletID int, size string, disk bool) (Action, error)
ResizeDroplet changes a droplet's plan.
disk=true makes the change PERMANENT AND IRREVERSIBLE: the disk grows and the droplet can never be resized down again. disk=false resizes CPU/RAM only and is reversible.
DO requires the droplet to be powered off; if it is not, DO refuses and its message is surfaced verbatim rather than being retried or worked around.
func (*Client) ResizeVolume ¶ added in v1.801.293
func (c *Client) ResizeVolume(ctx context.Context, volumeID, region string, gib int) (Action, error)
ResizeVolume grows a block-storage volume.
GROW ONLY, and not by choice: DigitalOcean has no shrink. It resizes the DEVICE and does nothing to the filesystem on it, so a volume Kubernetes manages must be grown through its PersistentVolumeClaim instead — that path does both, and leaves nothing declaring a stale capacity. See infra.ExpandPVC. This call is for the volumes Kubernetes does not manage, where the DigitalOcean API is the only thing that holds the size.
func (*Client) ScaleNodePool ¶ added in v1.801.256
func (c *Client) ScaleNodePool(ctx context.Context, clusterID, poolID, name string, count int) error
ScaleNodePool sets a node pool's node count. DO's update endpoint requires the pool's name alongside the count — omitting it clears the name, so it is always sent back.
func (*Client) SnapshotVolume ¶ added in v1.801.245
SnapshotVolume takes a point-in-time snapshot of a volume. This is the "undo" that makes a delete recoverable, so the delete path takes one FIRST by default.
type Cluster ¶ added in v1.801.245
type Cluster struct {
ID string
Name string
Region string
Version string
Status string
Pools []NodePool
CreatedAt string
}
Cluster is one DOKS cluster.
type Droplet ¶ added in v1.801.245
type Droplet struct {
ID int
Name string
Region string
Status string
SizeSlug string
VCPUs int
MemoryMiB int
LocalDiskGiB int
MonthlyCents money.Cents
CreatedAt string
PrivateIP string
PublicIP string
Tags []string
VolumeIDs []string
}
Droplet is one DO droplet. LocalDiskGiB is the droplet's own disk, which is INCLUDED in MonthlyCents — it is NOT separately billed, and conflating it with block storage is how a fleet appears to hold terabytes it never pays for.
type Entry ¶
type Entry struct {
Description string
Amount money.Cents
Date string
Kind string
InvoiceID string
}
Entry is one billing-history row (used to build the credit burn-down series).
type LoadBalancer ¶ added in v1.801.245
type LoadBalancer struct {
ID string
Name string
Region string
Status string
IP string
SizeUnit int
MonthlyCents money.Cents
DropletIDs []int
}
LoadBalancer is one DO load balancer. DO does not price LBs in the API, so cost is derived from the billed unit count (see lbUnitCents).
type NodePool ¶ added in v1.801.256
NodePool is one DOKS node pool — the ONLY correct way to change a cluster's node count. DOKS owns the droplets in a pool: deleting or resizing one directly is undone by the pool controller, which recreates it.
type Volume ¶ added in v1.801.186
type Volume struct {
ID string
Name string
Region string
SizeGiB int
DropletIDs []int
// Tags carries DO's resource tags. DOKS stamps `k8s:<cluster-uuid>` on the volumes
// it provisions, but that tag is ADVISORY ONLY — it survives cluster deletion and
// is wrong often enough that it must never decide whether a volume is garbage. The
// only sound liveness test is a PV cross-reference (see clients/admin/infra).
Tags []string
CreatedAt string
}
Volume is one DO block-storage volume: capacity + attachment + region. DO's API gives capacity and which droplets a volume is attached to, but NOT fill % — the caller enriches fill only where a filesystem source (the datastore's own system.disks) reports it, and renders an honest "—" everywhere else.