drivers

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: May 17, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package drivers contains ResourceDriver implementations for each DigitalOcean resource type.

Package drivers implements per-resource DigitalOcean drivers used by the plugin. shared.go holds helpers that are used by more than one driver.

Package drivers — SpacesKeyDriver provisions DigitalOcean Spaces access keys (resource type `infra.spaces_key`) via godo's SpacesKeysService.

Engine-routing pattern (workflow v0.27.0+):

  • Create returns ResourceOutput.Outputs containing every field including access_key and secret_key, and flags both as Sensitive via ResourceOutput.Sensitive[k]==true. The workflow engine's iac/sensitive package routes those flagged values through the configured secrets.Provider (keyed `<resource>_<output>`) and replaces them with `secret_ref://...` placeholders before persisting state. The driver itself NEVER touches secrets.Provider — it stays platform-agnostic.

  • Read and Update return Outputs WITHOUT secret_key (the DO API only exposes secret_key on Create; Get/List/Update never re-emit it). The secret value lives in the secrets.Provider after Create routed it. Audit/refresh paths reconcile against access_key, name, created_at, grants — the only fields the API can re-read.

  • Delete is idempotent on 404: when the underlying DELETE responds 404 (key already gone), the driver returns nil so reapply / cleanup pipelines don't error on prior partial success. Sister provider RevokeProviderCredential takes the same stance.

  • Diff compares mutable fields (name, grants). godo's SpacesKeysService.Update accepts both Name and Grants, so name divergence is a NeedsUpdate (in-place rename), NOT NeedsReplace. A FieldChange entry is appended for each differing field.

  • SensitiveKeys() returns access_key + secret_key for plan/diff display masking; this is independent from the per-call routing trigger above.

ProviderID == access_key — matches the sister bucket driver (internal/drivers/spaces.go) and the EnumerateAll path in internal/provider.go::enumerateAllSpacesKeys. Per ADR 0015/0020.

Index

Constants

View Source
const NoTargetsErrFmt = `` /* 152-byte string literal not displayed */

NoTargetsErrFmt is the format string for the error returned by validateFirewallTargets when a firewall spec has neither droplet_ids nor tags. The string is exported and stable so tests can assert exact-match equality without redefining the literal, and so plan-output greps and runbooks can rely on a fixed phrase. The em dash (U+2014) and the App Platform clause are part of the contract — DO firewalls do not protect App Platform apps, and the surfaced error must say so.

Variables

View Source
var ErrAppNotFound = fmt.Errorf("trusted_sources app: %w", ErrResourceNotFound)

ErrAppNotFound is returned by resolveAppNamesMap when a requested app name is absent from the DO Apps.List result. It wraps ErrResourceNotFound so callers using errors.Is(err, ErrResourceNotFound) continue to work; the more specific sentinel is used internally to distinguish "app not yet created" from API-level failures (rate-limit, transient, auth) that must NOT trigger the deferred-update path.

View Source
var ErrResourceNotFound = interfaces.ErrResourceNotFound

ErrResourceNotFound is returned when a resource cannot be located by name or ID. It is an alias for interfaces.ErrResourceNotFound so that cross-package errors.Is checks work for the DetectDrift ghost-classification path.

Functions

func ParseImageRef added in v0.5.1

func ParseImageRef(imageStr string) (*godo.ImageSourceSpec, error)

ParseImageRef parses a flat image reference string into a DO App Platform ImageSourceSpec. Supports:

  • registry.digitalocean.com/<registry>/<repo>:<tag> → DOCR (Registry left empty per DO API requirement)
  • ghcr.io/<org>/<repo>:<tag> → GHCR
  • docker.io/<org>/<repo>:<tag> → DOCKER_HUB
  • <org>/<repo>:<tag> → DOCKER_HUB (bare form)

A missing tag defaults to "latest".

func WrapGodoError added in v0.6.1

func WrapGodoError(err error) error

WrapGodoError inspects err for a *godo.ErrorResponse and maps its HTTP status code to the matching interfaces.Err* sentinel. The returned error wraps the sentinel so callers can use errors.Is for classification while still having access to the original DO API message via err.Error().

Two passthrough branches return err unchanged:

  • err is nil → return nil (no-op; safe to call unconditionally)
  • err is not a *godo.ErrorResponse, or its Response field is nil → return err (e.g. network errors, context cancellation, or SDK bugs; not DO API errors)

HTTP codes with no sentinel mapping (e.g. 301, 400 handled elsewhere) also pass through unchanged via sentinelForStatus returning nil.

Types

type APIGatewayAppClient added in v0.1.1

type APIGatewayAppClient interface {
	Create(ctx context.Context, req *godo.AppCreateRequest) (*godo.App, *godo.Response, error)
	Get(ctx context.Context, appID string) (*godo.App, *godo.Response, error)
	List(ctx context.Context, opts *godo.ListOptions) ([]*godo.App, *godo.Response, error)
	Update(ctx context.Context, appID string, req *godo.AppUpdateRequest) (*godo.App, *godo.Response, error)
	Delete(ctx context.Context, appID string) (*godo.Response, error)
}

APIGatewayAppClient is the godo App interface used for API gateway management (for mocking).

type APIGatewayDriver added in v0.1.1

type APIGatewayDriver struct {
	// contains filtered or unexported fields
}

APIGatewayDriver manages API routing via DigitalOcean App Platform (infra.api_gateway). It creates an App Platform application with HTTP route rules mapping paths to backend services.

Config keys:

region  string            — DO region slug (default: driver region)
routes  []map[string]any  — each: {path, component, preserve_path_prefix}
                            component maps to an App Platform service component name

func NewAPIGatewayDriver added in v0.1.1

func NewAPIGatewayDriver(c *godo.Client, region string) *APIGatewayDriver

NewAPIGatewayDriver creates an APIGatewayDriver backed by a real godo client.

func NewAPIGatewayDriverWithClient added in v0.1.1

func NewAPIGatewayDriverWithClient(c APIGatewayAppClient, region string) *APIGatewayDriver

NewAPIGatewayDriverWithClient creates a driver with an injected client (for tests).

func (*APIGatewayDriver) Create added in v0.1.1

func (*APIGatewayDriver) Delete added in v0.1.1

func (*APIGatewayDriver) Diff added in v0.1.1

func (*APIGatewayDriver) HealthCheck added in v0.1.1

func (*APIGatewayDriver) ProviderIDFormat added in v0.7.9

func (d *APIGatewayDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*APIGatewayDriver) Read added in v0.1.1

func (*APIGatewayDriver) Scale added in v0.1.1

func (*APIGatewayDriver) SensitiveKeys added in v0.2.1

func (d *APIGatewayDriver) SensitiveKeys() []string

func (*APIGatewayDriver) Update added in v0.1.1

type ActionsClient added in v0.11.0

type ActionsClient interface {
	Get(ctx context.Context, actionID int) (*godo.Action, *godo.Response, error)
}

ActionsClient is the godo ActionsService subset DropletDriver uses for waiting on async actions (volume detach is the canonical case). Subset means: only Get(ctx, actionID) — the pollable status read.

type AppBlueGreenDriver added in v0.2.0

type AppBlueGreenDriver struct {
	// contains filtered or unexported fields
}

AppBlueGreenDriver implements module.BlueGreenDriver for DigitalOcean App Platform.

Blue environment: the existing app identified by blueID. Green environment: a new app created with the "-green" name suffix.

SwitchTraffic is implemented by updating the blue app's spec with the green image (making blue the new stable), then DestroyBlue removes the green clone. The green app's live URL is returned from GreenEndpoint.

func NewAppBlueGreenDriver added in v0.2.0

func NewAppBlueGreenDriver(c AppPlatformClient, region, blueID, blueName string) *AppBlueGreenDriver

NewAppBlueGreenDriver creates a BlueGreenDriver for DO App Platform.

func (*AppBlueGreenDriver) CreateGreen added in v0.2.0

func (d *AppBlueGreenDriver) CreateGreen(ctx context.Context, image string) error

CreateGreen creates a new App Platform app with the "-green" name suffix and the given image, recording the green app ID and live URL for later use.

func (*AppBlueGreenDriver) CurrentImage added in v0.2.0

func (d *AppBlueGreenDriver) CurrentImage(ctx context.Context) (string, error)

func (*AppBlueGreenDriver) DestroyBlue added in v0.2.0

func (d *AppBlueGreenDriver) DestroyBlue(ctx context.Context) error

DestroyBlue deletes the green clone (the temporary environment).

func (*AppBlueGreenDriver) GreenEndpoint added in v0.2.0

func (d *AppBlueGreenDriver) GreenEndpoint(_ context.Context) (string, error)

GreenEndpoint returns the live URL of the green App Platform app.

func (*AppBlueGreenDriver) HealthCheck added in v0.2.0

func (d *AppBlueGreenDriver) HealthCheck(ctx context.Context, path string) error

func (*AppBlueGreenDriver) ReplicaCount added in v0.2.0

func (d *AppBlueGreenDriver) ReplicaCount(ctx context.Context) (int, error)

func (*AppBlueGreenDriver) SwitchTraffic added in v0.2.0

func (d *AppBlueGreenDriver) SwitchTraffic(ctx context.Context) error

SwitchTraffic updates the blue app spec to use the green image, effectively promoting the green version as the stable app. DO App Platform does not support weighted traffic splitting natively; this performs a full cutover.

func (*AppBlueGreenDriver) Update added in v0.2.0

func (d *AppBlueGreenDriver) Update(ctx context.Context, image string) error

type AppCanaryDriver added in v0.2.0

type AppCanaryDriver struct {
	// contains filtered or unexported fields
}

AppCanaryDriver implements module.CanaryDriver for DigitalOcean App Platform.

DigitalOcean App Platform does not support native traffic splitting between app instances. RoutePercent returns a clear unsupported error directing users to DigitalOcean Load Balancer + Droplets for canary deployments.

CreateCanary, PromoteCanary, and DestroyCanary follow the standard create/promote/delete pattern using two separate apps.

func NewAppCanaryDriver added in v0.2.0

func NewAppCanaryDriver(c AppPlatformClient, region, stableID, stableName string) *AppCanaryDriver

NewAppCanaryDriver creates a CanaryDriver for DO App Platform.

func (*AppCanaryDriver) CheckMetricGate added in v0.2.0

func (d *AppCanaryDriver) CheckMetricGate(_ context.Context, _ string) error

CheckMetricGate always passes (no native metric integration).

func (*AppCanaryDriver) CreateCanary added in v0.2.0

func (d *AppCanaryDriver) CreateCanary(ctx context.Context, image string) error

CreateCanary creates a new App Platform app with the "-canary" name suffix and the given image.

func (*AppCanaryDriver) CurrentImage added in v0.2.0

func (d *AppCanaryDriver) CurrentImage(ctx context.Context) (string, error)

func (*AppCanaryDriver) DestroyCanary added in v0.2.0

func (d *AppCanaryDriver) DestroyCanary(ctx context.Context) error

DestroyCanary deletes the canary App Platform app.

func (*AppCanaryDriver) HealthCheck added in v0.2.0

func (d *AppCanaryDriver) HealthCheck(ctx context.Context, path string) error

func (*AppCanaryDriver) PromoteCanary added in v0.2.0

func (d *AppCanaryDriver) PromoteCanary(ctx context.Context) error

PromoteCanary updates the stable app with the canary image and deletes the canary.

func (*AppCanaryDriver) ReplicaCount added in v0.2.0

func (d *AppCanaryDriver) ReplicaCount(ctx context.Context) (int, error)

func (*AppCanaryDriver) RoutePercent added in v0.2.0

func (d *AppCanaryDriver) RoutePercent(_ context.Context, percent int) error

RoutePercent is not supported by DigitalOcean App Platform. Use DigitalOcean Load Balancer with Droplets for canary traffic splitting.

func (*AppCanaryDriver) Update added in v0.2.0

func (d *AppCanaryDriver) Update(ctx context.Context, image string) error

type AppDeployDriver added in v0.2.0

type AppDeployDriver struct {
	// contains filtered or unexported fields
}

AppDeployDriver implements module.DeployDriver for DigitalOcean App Platform. It manages a single App Platform application identified by its app ID.

func NewAppDeployDriver added in v0.2.0

func NewAppDeployDriver(c AppPlatformClient, region, appID, appName string) *AppDeployDriver

NewAppDeployDriver creates a DeployDriver backed by a DO App Platform app.

func (*AppDeployDriver) CurrentImage added in v0.2.0

func (d *AppDeployDriver) CurrentImage(ctx context.Context) (string, error)

func (*AppDeployDriver) HealthCheck added in v0.2.0

func (d *AppDeployDriver) HealthCheck(ctx context.Context, _ string) error

func (*AppDeployDriver) ReplicaCount added in v0.2.0

func (d *AppDeployDriver) ReplicaCount(ctx context.Context) (int, error)

func (*AppDeployDriver) Update added in v0.2.0

func (d *AppDeployDriver) Update(ctx context.Context, image string) error

type AppPlatformClient

type AppPlatformClient interface {
	Create(ctx context.Context, req *godo.AppCreateRequest) (*godo.App, *godo.Response, error)
	Get(ctx context.Context, appID string) (*godo.App, *godo.Response, error)
	List(ctx context.Context, opts *godo.ListOptions) ([]*godo.App, *godo.Response, error)
	Update(ctx context.Context, appID string, req *godo.AppUpdateRequest) (*godo.App, *godo.Response, error)
	CreateDeployment(ctx context.Context, appID string, req ...*godo.DeploymentCreateRequest) (*godo.Deployment, *godo.Response, error)
	ListDeployments(ctx context.Context, appID string, opts *godo.ListOptions) ([]*godo.Deployment, *godo.Response, error)
	Delete(ctx context.Context, appID string) (*godo.Response, error)
	GetLogs(ctx context.Context, appID, deploymentID, component string, logType godo.AppLogType, follow bool, tailLines int) (*godo.AppLogs, *godo.Response, error)
}

AppPlatformClient is the godo App interface used by AppPlatformDriver (for mocking).

type AppPlatformDriver

type AppPlatformDriver struct {
	// contains filtered or unexported fields
}

AppPlatformDriver manages DigitalOcean App Platform (infra.container_service).

func NewAppPlatformDriver

func NewAppPlatformDriver(c *godo.Client, region string) *AppPlatformDriver

NewAppPlatformDriver creates an AppPlatformDriver backed by a real godo client.

func NewAppPlatformDriverWithClient

func NewAppPlatformDriverWithClient(c AppPlatformClient, region string) *AppPlatformDriver

NewAppPlatformDriverWithClient creates a driver with an injected apps client (for tests). regClient is nil; image-presence check is skipped.

func NewAppPlatformDriverWithClients added in v0.12.0

func NewAppPlatformDriverWithClients(c AppPlatformClient, r RegistryClient, region string) *AppPlatformDriver

NewAppPlatformDriverWithClients creates a driver with both clients injected (for tests).

func (*AppPlatformDriver) Create

func (*AppPlatformDriver) Delete

func (*AppPlatformDriver) Diff

func (*AppPlatformDriver) HealthCheck

func (*AppPlatformDriver) ProviderIDFormat added in v0.7.9

func (d *AppPlatformDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*AppPlatformDriver) Read

func (*AppPlatformDriver) RepairDirtyMigration added in v0.7.13

func (*AppPlatformDriver) Scale

func (*AppPlatformDriver) SensitiveKeys added in v0.2.1

func (d *AppPlatformDriver) SensitiveKeys() []string

func (*AppPlatformDriver) SupportsUpsert added in v0.7.2

func (d *AppPlatformDriver) SupportsUpsert() bool

SupportsUpsert reports that AppPlatformDriver can locate a resource by name alone (empty ProviderID), enabling the ErrResourceAlreadyExists → upsert path in DOProvider.Apply. Other drivers that require ProviderID in Read do not implement this method and are excluded from the upsert path.

func (*AppPlatformDriver) Troubleshoot added in v0.7.8

Troubleshoot implements interfaces.Troubleshooter for AppPlatformDriver. It fetches the app (to inspect its three deployment slots: InProgress, Pending, Active) plus recent historical deployments, prioritises them, and returns per-deployment Diagnostics so wfctl can render a structured failure block on health-check timeout without requiring a DO console visit.

For each candidate deployment in a terminal error phase (Error, Canceled, Superseded), Troubleshoot fetches deploy logs via GetLogs and appends the last troubleshootLogTailLines of output per component to the Diagnostic.Detail. Log fetch failures are best-effort: the Diagnostic is still produced without the log block when GetLogs or the HTTP fetch fails.

func (*AppPlatformDriver) Update

type CacheClient added in v0.1.1

type CacheClient interface {
	Create(ctx context.Context, req *godo.DatabaseCreateRequest) (*godo.Database, *godo.Response, error)
	Get(ctx context.Context, databaseID string) (*godo.Database, *godo.Response, error)
	List(ctx context.Context, opts *godo.ListOptions) ([]godo.Database, *godo.Response, error)
	Resize(ctx context.Context, databaseID string, req *godo.DatabaseResizeRequest) (*godo.Response, error)
	Delete(ctx context.Context, databaseID string) (*godo.Response, error)
}

CacheClient is the godo Databases interface used for Redis cache clusters (for mocking).

type CacheDriver added in v0.1.1

type CacheDriver struct {
	// contains filtered or unexported fields
}

CacheDriver manages DigitalOcean Managed Redis clusters (infra.cache). It uses the same Databases API as DatabaseDriver with engine=redis.

func NewCacheDriver added in v0.1.1

func NewCacheDriver(c *godo.Client, region string) *CacheDriver

NewCacheDriver creates a CacheDriver backed by a real godo client.

func NewCacheDriverWithClient added in v0.1.1

func NewCacheDriverWithClient(c CacheClient, region string) *CacheDriver

NewCacheDriverWithClient creates a driver with an injected client (for tests).

func (*CacheDriver) Create added in v0.1.1

func (*CacheDriver) Delete added in v0.1.1

func (d *CacheDriver) Delete(ctx context.Context, ref interfaces.ResourceRef) error

func (*CacheDriver) Diff added in v0.1.1

func (*CacheDriver) HealthCheck added in v0.1.1

func (*CacheDriver) ProviderIDFormat added in v0.7.9

func (d *CacheDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*CacheDriver) Read added in v0.1.1

func (*CacheDriver) Scale added in v0.1.1

func (*CacheDriver) SensitiveKeys added in v0.2.1

func (d *CacheDriver) SensitiveKeys() []string

func (*CacheDriver) Update added in v0.1.1

type CertificateClient

type CertificateClient interface {
	Create(ctx context.Context, req *godo.CertificateRequest) (*godo.Certificate, *godo.Response, error)
	Get(ctx context.Context, certID string) (*godo.Certificate, *godo.Response, error)
	Delete(ctx context.Context, certID string) (*godo.Response, error)
	List(ctx context.Context, opts *godo.ListOptions) ([]godo.Certificate, *godo.Response, error)
}

CertificateClient is the godo Certificates interface (for mocking).

type CertificateDriver

type CertificateDriver struct {
	// contains filtered or unexported fields
}

CertificateDriver manages DigitalOcean SSL/TLS certificates (infra.certificate).

func NewCertificateDriver

func NewCertificateDriver(c *godo.Client) *CertificateDriver

NewCertificateDriver creates a CertificateDriver backed by a real godo client.

func NewCertificateDriverWithClient

func NewCertificateDriverWithClient(c CertificateClient) *CertificateDriver

NewCertificateDriverWithClient creates a driver with an injected client (for tests).

func (*CertificateDriver) Create

func (*CertificateDriver) Delete

func (*CertificateDriver) Diff

func (*CertificateDriver) HealthCheck

func (*CertificateDriver) ProviderIDFormat added in v0.7.9

func (d *CertificateDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*CertificateDriver) Read

func (*CertificateDriver) Scale

func (*CertificateDriver) SensitiveKeys added in v0.2.1

func (d *CertificateDriver) SensitiveKeys() []string

func (*CertificateDriver) Update

type DNSDriver

type DNSDriver struct {
	// contains filtered or unexported fields
}

DNSDriver manages DigitalOcean Domains and DNS records (infra.dns). Idempotent: creates domain if missing, creates or updates records.

func NewDNSDriver

func NewDNSDriver(c *godo.Client) *DNSDriver

NewDNSDriver creates a DNSDriver backed by a real godo client.

func NewDNSDriverWithClient

func NewDNSDriverWithClient(c DomainsClient) *DNSDriver

NewDNSDriverWithClient creates a driver with an injected client (for tests).

func (*DNSDriver) Create

Create creates a domain and any declared DNS records idempotently. Config keys:

domain   string            — the zone name (e.g. "example.com")
records  []any|[]map[string]any — each: {type, name, data, ttl}

func (*DNSDriver) Delete

func (d *DNSDriver) Delete(ctx context.Context, ref interfaces.ResourceRef) error

func (*DNSDriver) Diff

func (*DNSDriver) HealthCheck

func (*DNSDriver) ProviderIDFormat added in v0.7.9

func (d *DNSDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*DNSDriver) Read

func (*DNSDriver) Scale

func (*DNSDriver) SensitiveKeys added in v0.2.1

func (d *DNSDriver) SensitiveKeys() []string

type DatabaseClient

type DatabaseClient interface {
	Create(ctx context.Context, req *godo.DatabaseCreateRequest) (*godo.Database, *godo.Response, error)
	Get(ctx context.Context, databaseID string) (*godo.Database, *godo.Response, error)
	List(ctx context.Context, opts *godo.ListOptions) ([]godo.Database, *godo.Response, error)
	Resize(ctx context.Context, databaseID string, req *godo.DatabaseResizeRequest) (*godo.Response, error)
	Delete(ctx context.Context, databaseID string) (*godo.Response, error)
	UpdateFirewallRules(ctx context.Context, databaseID string, req *godo.DatabaseUpdateFirewallRulesRequest) (*godo.Response, error)
}

DatabaseClient is the godo Databases interface (for mocking).

type DatabaseDriver

type DatabaseDriver struct {
	// contains filtered or unexported fields
}

DatabaseDriver manages DigitalOcean Managed Databases (infra.database). Supports pg, mysql, redis, mongodb, kafka.

func NewDatabaseDriver

func NewDatabaseDriver(c *godo.Client, region string) *DatabaseDriver

NewDatabaseDriver creates a DatabaseDriver backed by a real godo client. The godo Apps client is wired automatically to support type=app trusted_source name → UUID resolution at apply time.

func NewDatabaseDriverWithClient

func NewDatabaseDriverWithClient(c DatabaseClient, region string) *DatabaseDriver

NewDatabaseDriverWithClient creates a driver with an injected database client (for tests). appsClient may be nil when tests do not exercise type=app trusted_source rules.

func NewDatabaseDriverWithClients added in v0.7.10

func NewDatabaseDriverWithClients(c DatabaseClient, apps appNameLister, region string) *DatabaseDriver

NewDatabaseDriverWithClients creates a driver with injected database and apps clients (for tests that exercise type=app trusted_source name → UUID resolution). apps must implement appNameLister (i.e. have a List method); any *fakeAppsClient or real godo.AppsService satisfies this.

func (*DatabaseDriver) AdoptionRef added in v0.14.4

func (*DatabaseDriver) Create

func (*DatabaseDriver) Delete

func (*DatabaseDriver) Diff

func (*DatabaseDriver) FlushDeferredUpdates added in v0.8.2

func (d *DatabaseDriver) FlushDeferredUpdates(ctx context.Context) error

FlushDeferredUpdates applies all pending firewall updates that were deferred during Create/Update because referenced app(s) did not exist yet. Each entry re-resolves its type=app trusted_sources entries (app must now exist) and calls UpdateFirewallRules with the full rule set. Returns an error if any update fails — the caller (DOProvider.Apply) appends these to result.Errors so the failure is visible to the operator.

Only successfully-flushed entries are removed from the queue. Entries that failed (rule-resolution error or UpdateFirewallRules API error) are retained so that a subsequent Apply automatically re-attempts the flush without requiring operator intervention. This matters because DatabaseDriver.Diff does not compare trusted_sources, meaning a retry Apply would otherwise produce no update action and the second-pass flush would never fire.

func (*DatabaseDriver) HasDeferredUpdates added in v0.8.2

func (d *DatabaseDriver) HasDeferredUpdates() bool

HasDeferredUpdates reports whether the driver has pending firewall updates queued from Create or Update calls where type=app trusted_sources entries referenced apps that did not exist yet. DOProvider.Apply checks this after the main action loop and calls FlushDeferredUpdates when true.

func (*DatabaseDriver) HealthCheck

func (*DatabaseDriver) ProviderIDFormat added in v0.7.9

func (d *DatabaseDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*DatabaseDriver) Read

func (*DatabaseDriver) Scale

func (*DatabaseDriver) SensitiveKeys added in v0.2.1

func (d *DatabaseDriver) SensitiveKeys() []string

func (*DatabaseDriver) SupportsUpsert added in v0.7.3

func (d *DatabaseDriver) SupportsUpsert() bool

SupportsUpsert reports that DatabaseDriver can locate a resource by name alone (empty ProviderID), enabling the ErrResourceAlreadyExists → upsert path.

func (*DatabaseDriver) Update

type DomainsClient

type DomainsClient interface {
	Create(ctx context.Context, req *godo.DomainCreateRequest) (*godo.Domain, *godo.Response, error)
	Get(ctx context.Context, name string) (*godo.Domain, *godo.Response, error)
	Delete(ctx context.Context, name string) (*godo.Response, error)
	CreateRecord(ctx context.Context, domain string, req *godo.DomainRecordEditRequest) (*godo.DomainRecord, *godo.Response, error)
	EditRecord(ctx context.Context, domain string, id int, req *godo.DomainRecordEditRequest) (*godo.DomainRecord, *godo.Response, error)
	DeleteRecord(ctx context.Context, domain string, id int) (*godo.Response, error)
	Records(ctx context.Context, domain string, opts *godo.ListOptions) ([]godo.DomainRecord, *godo.Response, error)
}

DomainsClient is the godo Domains interface (for mocking).

type DropletDriver

type DropletDriver struct {
	// contains filtered or unexported fields
}

DropletDriver manages DigitalOcean Droplets (infra.droplet).

func NewDropletDriver

func NewDropletDriver(c *godo.Client, region string) *DropletDriver

NewDropletDriver creates a DropletDriver backed by a real godo client. The Storage, StorageActions, and Actions clients are wired so volumes-by-name resolution and Replace's detach-wait work without additional configuration.

func NewDropletDriverWithClient

func NewDropletDriverWithClient(c DropletsClient, region string, optional ...interface{}) *DropletDriver

NewDropletDriverWithClient creates a driver with injected clients (for tests). Optional clients are provided via a variadic interface{} parameter; each value is type-switched to the appropriate field. Typed-nil interface values are rejected (treated as "not provided") to prevent nil-method-set panics at call time.

Existing tests that pass (DropletsClient, region) continue to compile unchanged. Tests that exercise Replace must additionally pass StorageActionsClient and ActionsClient.

func (*DropletDriver) Create

func (*DropletDriver) Delete

func (*DropletDriver) Diff

Diff compares the desired spec against the current droplet output and returns a DiffResult. Update is disallowed by godo (Droplet PUT only resizes), so every detected change is flagged as ForceNew — the caller must replace the droplet, not patch it.

Detected: size, vpc_uuid, enable_backups, tags, volumes (by NAME after dropletOutput's ID→name resolution), monitoring, ipv6 (via the droplet.Features string slice returned by the DO API).

NOT detected (godo Read limitation, tracked in issue #56): user_data, ssh_keys. Operators must taint the Droplet manually to roll a new value for any of these. See the inline comment near the end of this function for the full rationale.

func (*DropletDriver) HealthCheck

func (*DropletDriver) ProviderIDFormat added in v0.7.9

func (d *DropletDriver) ProviderIDFormat() interfaces.ProviderIDFormat

ProviderIDFormat returns Freeform because DO Droplet IDs are integers, not UUIDs. We declare Freeform; providerIDToInt performs strict local validation and rejects any non-integer ProviderID with an explicit error before any API call is made — no UUID-based state-heal needed for Droplet.

func (*DropletDriver) Read

func (*DropletDriver) Replace added in v0.11.0

Replace implements interfaces.ResourceReplacer for DigitalOcean Droplets. Orchestration: read old → DetachByDropletID per attached Volume → wait for each detach action → delete old Droplet → create new Droplet with the same resolved Volume IDs (bypassing the name-resolution race in Create's resolveDropletVolumes path).

On 404 from the initial Get(oldID), Replace falls through with detach-skipped + delete-skipped; Create still fires (orphan-state recovery — same as engine-default Delete-then-Create when the old Droplet is gone).

Error wrapping: every sub-step wraps with "droplet replace %q: <step>: %w" so the workflow engine's error-prefix backstop sees the recognized "<resource-type> replace " family and passes the error through unchanged.

func (*DropletDriver) Scale

func (*DropletDriver) SensitiveKeys added in v0.2.1

func (d *DropletDriver) SensitiveKeys() []string

func (*DropletDriver) SetReplaceTimeoutsForTest added in v0.11.0

func (d *DropletDriver) SetReplaceTimeoutsForTest(timeout, pollInterval time.Duration)

SetReplaceTimeoutsForTest is a test-only seam to override the production 60s/2s detach-wait bounds. Production code MUST NOT call this.

type DropletsClient

type DropletsClient interface {
	Create(ctx context.Context, req *godo.DropletCreateRequest) (*godo.Droplet, *godo.Response, error)
	Get(ctx context.Context, dropletID int) (*godo.Droplet, *godo.Response, error)
	Delete(ctx context.Context, dropletID int) (*godo.Response, error)
}

DropletsClient is the godo Droplets interface (for mocking).

type FirewallClient

type FirewallClient interface {
	Create(ctx context.Context, req *godo.FirewallRequest) (*godo.Firewall, *godo.Response, error)
	Get(ctx context.Context, fwID string) (*godo.Firewall, *godo.Response, error)
	List(ctx context.Context, opts *godo.ListOptions) ([]godo.Firewall, *godo.Response, error)
	Update(ctx context.Context, fwID string, req *godo.FirewallRequest) (*godo.Firewall, *godo.Response, error)
	Delete(ctx context.Context, fwID string) (*godo.Response, error)
}

FirewallClient is the godo Firewalls interface (for mocking).

type FirewallDriver

type FirewallDriver struct {
	// contains filtered or unexported fields
}

FirewallDriver manages DigitalOcean Firewalls (infra.firewall).

Targets are required: every firewall must declare at least one of `droplet_ids` (a list of Droplet integer IDs) or `tags` (a list of Droplet/DOKS-pool tag strings, which auto-attach future resources). Both Create and Update reject specs with neither field set.

Note: DO firewalls do NOT attach to App Platform apps. For App-Platform-only deployments, omit `infra.firewall` and instead use `expose: internal` on the service plus `trusted_sources` on managed databases.

func NewFirewallDriver

func NewFirewallDriver(c *godo.Client) *FirewallDriver

NewFirewallDriver creates a FirewallDriver backed by a real godo client.

func NewFirewallDriverWithClient

func NewFirewallDriverWithClient(c FirewallClient) *FirewallDriver

NewFirewallDriverWithClient creates a driver with an injected client (for tests).

func (*FirewallDriver) Create

func (*FirewallDriver) Delete

func (*FirewallDriver) Diff

Diff compares the desired spec against the live firewall recorded on `current` to detect in-place reconfiguration. It compares the four canonical fields (`droplet_ids`, `tags`, `inbound_rules`, `outbound_rules`) so that toggling any of them between deploys produces a Plan action rather than silently no-op'ing.

`droplet_ids` and `tags` use SET semantics: reorder is not a change, since DO normalizes membership server-side. Rules use ORDER-SENSITIVE deep-equal because rule order is preserved in the API response and may carry user intent.

Both sides of the rule comparison are normalized to the structpb- compatible canonical map shape so the comparison is symmetric whether `current.Outputs` is read in-process or after a wfctl→plugin gRPC round- trip.

Legacy state without the recorded keys (`ResourceOutput` written by older plugin versions) is treated as having empty fields, which surfaces a Plan action on first Diff post-upgrade — the safe over-detect direction.

func (*FirewallDriver) HealthCheck

func (*FirewallDriver) ProviderIDFormat added in v0.7.9

func (d *FirewallDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*FirewallDriver) Read

func (*FirewallDriver) Scale

func (*FirewallDriver) SensitiveKeys added in v0.2.1

func (d *FirewallDriver) SensitiveKeys() []string

func (*FirewallDriver) SupportsUpsert added in v0.7.3

func (d *FirewallDriver) SupportsUpsert() bool

SupportsUpsert reports that FirewallDriver can locate a resource by name alone (empty ProviderID), enabling the ErrResourceAlreadyExists → upsert path.

func (*FirewallDriver) Update

type IAMRoleDriver added in v0.1.1

type IAMRoleDriver struct{}

IAMRoleDriver provides a ResourceDriver for infra.iam_role on DigitalOcean.

Limitation

DigitalOcean does not expose fine-grained IAM role management via the godo API. Personal Access Tokens and OAuth applications must be created through the DO control panel (https://cloud.digitalocean.com/account/api/tokens).

This driver is entirely declarative: Create/Update return the declared config as outputs with a limitation notice; Read/HealthCheck return a healthy declared state; Delete and Scale are no-ops. No godo API calls are made.

func NewIAMRoleDriver added in v0.1.1

func NewIAMRoleDriver() *IAMRoleDriver

NewIAMRoleDriver creates an IAMRoleDriver.

func (*IAMRoleDriver) Create added in v0.1.1

Create records an IAM role declaration. Since DO has no native role API the driver returns the declared metadata as outputs with a clear limitation notice.

func (*IAMRoleDriver) Delete added in v0.1.1

func (*IAMRoleDriver) Diff added in v0.1.1

func (*IAMRoleDriver) HealthCheck added in v0.1.1

func (*IAMRoleDriver) ProviderIDFormat added in v0.7.9

func (d *IAMRoleDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*IAMRoleDriver) Read added in v0.1.1

func (*IAMRoleDriver) Scale added in v0.1.1

func (*IAMRoleDriver) SensitiveKeys added in v0.2.1

func (d *IAMRoleDriver) SensitiveKeys() []string

func (*IAMRoleDriver) Update added in v0.1.1

type KubernetesClient

KubernetesClient is the godo Kubernetes interface (for mocking).

type KubernetesDriver

type KubernetesDriver struct {
	// contains filtered or unexported fields
}

KubernetesDriver manages DigitalOcean Kubernetes Service (DOKS) clusters (infra.k8s_cluster).

func NewKubernetesDriver

func NewKubernetesDriver(c *godo.Client, region string) *KubernetesDriver

NewKubernetesDriver creates a KubernetesDriver backed by a real godo client.

func NewKubernetesDriverWithClient

func NewKubernetesDriverWithClient(c KubernetesClient, region string) *KubernetesDriver

NewKubernetesDriverWithClient creates a driver with an injected client (for tests).

func (*KubernetesDriver) Create

func (*KubernetesDriver) Delete

func (*KubernetesDriver) Diff

func (*KubernetesDriver) HealthCheck

func (*KubernetesDriver) ProviderIDFormat added in v0.7.9

func (d *KubernetesDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*KubernetesDriver) Read

func (*KubernetesDriver) Scale

Scale resizes the first node pool of the cluster to the given replica count using godo.Kubernetes.UpdateNodePool.

func (*KubernetesDriver) SensitiveKeys added in v0.2.1

func (d *KubernetesDriver) SensitiveKeys() []string

func (*KubernetesDriver) Update

type LoadBalancerClient

type LoadBalancerClient interface {
	Create(ctx context.Context, req *godo.LoadBalancerRequest) (*godo.LoadBalancer, *godo.Response, error)
	Get(ctx context.Context, lbID string) (*godo.LoadBalancer, *godo.Response, error)
	List(ctx context.Context, opts *godo.ListOptions) ([]godo.LoadBalancer, *godo.Response, error)
	Update(ctx context.Context, lbID string, req *godo.LoadBalancerRequest) (*godo.LoadBalancer, *godo.Response, error)
	Delete(ctx context.Context, lbID string) (*godo.Response, error)
}

LoadBalancerClient is the godo LoadBalancers interface (for mocking).

type LoadBalancerDriver

type LoadBalancerDriver struct {
	// contains filtered or unexported fields
}

LoadBalancerDriver manages DigitalOcean Load Balancers (infra.load_balancer).

func NewLoadBalancerDriver

func NewLoadBalancerDriver(c *godo.Client, region string) *LoadBalancerDriver

NewLoadBalancerDriver creates a LoadBalancerDriver backed by a real godo client.

func NewLoadBalancerDriverWithClient

func NewLoadBalancerDriverWithClient(c LoadBalancerClient, region string) *LoadBalancerDriver

NewLoadBalancerDriverWithClient creates a driver with an injected client (for tests).

func (*LoadBalancerDriver) Create

func (*LoadBalancerDriver) Delete

func (*LoadBalancerDriver) Diff

func (*LoadBalancerDriver) HealthCheck

func (*LoadBalancerDriver) ProviderIDFormat added in v0.7.9

func (d *LoadBalancerDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*LoadBalancerDriver) Read

func (*LoadBalancerDriver) Scale

func (*LoadBalancerDriver) SensitiveKeys added in v0.2.1

func (d *LoadBalancerDriver) SensitiveKeys() []string

func (*LoadBalancerDriver) Update

type RegistryClient

type RegistryClient interface {
	Create(ctx context.Context, req *godo.RegistryCreateRequest) (*godo.Registry, *godo.Response, error)
	Get(ctx context.Context) (*godo.Registry, *godo.Response, error)
	Delete(ctx context.Context) (*godo.Response, error)
	// ListRepositoryTags lists tags for a repository under the named registry.
	// Used by AppPlatformDriver image-presence pre-flight.
	ListRepositoryTags(ctx context.Context, registry, repository string, opts *godo.ListOptions) ([]*godo.RepositoryTag, *godo.Response, error)
}

RegistryClient is the godo Registry interface (for mocking).

type RegistryDriver

type RegistryDriver struct {
	// contains filtered or unexported fields
}

RegistryDriver manages the DigitalOcean Container Registry (infra.registry).

DOCR is account-level: Basic plan supports one registry per account, Professional supports up to ten. A registry can host many repositories, so multi-project consolidation under one registry is supported on every plan tier.

This driver is **account-singleton**: godo's Registry.Get(ctx) and Delete(ctx) take no name parameter, so the driver can only see and manage one registry per account regardless of plan tier. On Professional accounts with multiple registries, the others must be managed out-of-band.

Two deployment topologies are supported:

  • Owned: declare an infra.registry IaC module; this driver manages create/update/destroy. Use on single-project DO accounts.
  • Shared: omit the module declaration and reference only the path under ci.registries; bootstrap the registry once out-of-band. Use when multiple projects share a DO account.

See docs/container-registry.md for the canonical pattern, including migration guidance and the deploy-time verification snippet for Shared consumers. Picking the wrong topology produces a peer-deploy race that only surfaces when the second project tries to create the registry.

Create is idempotent against the DO API for same name + region. Update is a no-op (DOCR does not support in-place tier/region changes; drift is not reconciled).

func NewRegistryDriver

func NewRegistryDriver(c *godo.Client) *RegistryDriver

NewRegistryDriver creates a RegistryDriver backed by a real godo client.

func NewRegistryDriverWithClient

func NewRegistryDriverWithClient(c RegistryClient) *RegistryDriver

NewRegistryDriverWithClient creates a driver with an injected client (for tests).

func (*RegistryDriver) Create

func (*RegistryDriver) Delete

func (*RegistryDriver) Diff

func (*RegistryDriver) HealthCheck

func (*RegistryDriver) ProviderIDFormat added in v0.7.9

func (d *RegistryDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*RegistryDriver) Read

func (*RegistryDriver) Scale

func (*RegistryDriver) SensitiveKeys added in v0.2.1

func (d *RegistryDriver) SensitiveKeys() []string

type SpacesBucket

type SpacesBucket struct {
	Name      string
	Region    string
	CreatedAt time.Time
}

SpacesBucket is a minimal representation of a DigitalOcean Spaces bucket.

type SpacesBucketClient

type SpacesBucketClient interface {
	CreateBucket(ctx context.Context, name, region string) (*SpacesBucket, error)
	GetBucket(ctx context.Context, name, region string) (*SpacesBucket, error)
	DeleteBucket(ctx context.Context, name, region string) error
}

SpacesBucketClient is the interface for Spaces bucket management (injectable for mocking). DigitalOcean Spaces uses an S3-compatible API; this interface abstracts those calls.

type SpacesDriver

type SpacesDriver struct {
	// contains filtered or unexported fields
}

SpacesDriver manages DigitalOcean Spaces object storage buckets (infra.storage).

func NewSpacesDriver

func NewSpacesDriver(_ *godo.Client, region, accessKey, secretKey string) *SpacesDriver

NewSpacesDriver creates a SpacesDriver. If accessKey and secretKey are non-empty a real S3-compatible client is used; otherwise a no-op client is used (suitable only for tests / dry-run mode).

func NewSpacesDriverWithClient

func NewSpacesDriverWithClient(c SpacesBucketClient, region string) *SpacesDriver

NewSpacesDriverWithClient creates a driver with an injected client (for tests).

func (*SpacesDriver) Create

func (*SpacesDriver) Delete

func (*SpacesDriver) Diff

func (*SpacesDriver) HealthCheck

func (*SpacesDriver) ProviderIDFormat added in v0.7.9

func (d *SpacesDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*SpacesDriver) Read

func (*SpacesDriver) Scale

func (*SpacesDriver) SensitiveKeys added in v0.2.1

func (d *SpacesDriver) SensitiveKeys() []string

type SpacesKeyDriver added in v0.14.0

type SpacesKeyDriver struct {
	// contains filtered or unexported fields
}

SpacesKeyDriver manages DigitalOcean Spaces access keys (infra.spaces_key). Constructed with a *godo.Client only — the secrets.Provider is the engine's concern under the v0.27.0 engine-side routing contract.

func NewSpacesKeyDriver added in v0.14.0

func NewSpacesKeyDriver(client *godo.Client) *SpacesKeyDriver

NewSpacesKeyDriver returns a driver bound to the given godo client.

func (*SpacesKeyDriver) Create added in v0.14.0

Create provisions a new Spaces key and returns its full outputs flagged for engine-side sensitive routing.

func (*SpacesKeyDriver) Delete added in v0.14.0

Delete removes the Spaces key by access_key. 404 is treated as success (idempotent delete) — sister provider RevokeProviderCredential takes the same stance.

func (*SpacesKeyDriver) Diff added in v0.14.0

Diff compares desired spec against current state. Spaces keys support in-place rename + grant updates; both go via Update (NeedsUpdate=true), no replace path.

func (*SpacesKeyDriver) HealthCheck added in v0.14.0

HealthCheck has no provider-side concept for Spaces keys; report healthy if the key still exists. Errors here are non-fatal at the call site.

func (*SpacesKeyDriver) ProviderIDFormat added in v0.14.0

func (d *SpacesKeyDriver) ProviderIDFormat() interfaces.ProviderIDFormat

ProviderIDFormat declares ProviderIDs are freeform (DO access keys are not UUIDs). Disables UUID validation while still enforcing non-empty.

func (*SpacesKeyDriver) Read added in v0.14.0

Read refreshes metadata for an existing Spaces key. secret_key is NOT returned (the DO API only exposes it on Create); the cached value lives in the secrets.Provider after Create routed it.

func (*SpacesKeyDriver) ResourceType added in v0.14.0

func (d *SpacesKeyDriver) ResourceType() string

ResourceType is the canonical resource-type string this driver serves.

func (*SpacesKeyDriver) Scale added in v0.14.0

Scale is not supported (access keys have no replica concept).

func (*SpacesKeyDriver) SensitiveKeys added in v0.14.0

func (d *SpacesKeyDriver) SensitiveKeys() []string

SensitiveKeys returns the output keys whose values should be masked in plan/diff display. The engine ALSO consults ResourceOutput.Sensitive per-call to decide routing through secrets.Provider; SensitiveKeys is strictly the display-side signal.

func (*SpacesKeyDriver) SupportsUpsert added in v0.14.0

func (d *SpacesKeyDriver) SupportsUpsert() bool

SupportsUpsert advertises that Read can locate by Name when ProviderID is empty, so wfctl ApplyPlan can recover from ErrResourceAlreadyExists.

func (*SpacesKeyDriver) Update added in v0.14.0

Update mutates a Spaces key in place. The DO API only allows changing grants and name — name change is treated as in-place rename via SpacesKeyUpdateRequest.

type StorageActionsClient added in v0.9.0

type StorageActionsClient interface {
	Resize(ctx context.Context, volumeID string, sizeGigabytes int, regionSlug string) (*godo.Action, *godo.Response, error)
	// DetachByDropletID detaches the volume from the given Droplet. Used by
	// DropletDriver.Replace before deleting the old Droplet so DO does not
	// reject the new Droplet's create with "422 storage already associated".
	DetachByDropletID(ctx context.Context, volumeID string, dropletID int) (*godo.Action, *godo.Response, error)
}

StorageActionsClient is the subset of godo.StorageActionsService used by VolumeDriver (resize) and DropletDriver.Replace (volume detach before delete). Both operations are on the same godo.StorageActionsService so one interface covers both callers.

type StorageClient added in v0.9.0

type StorageClient interface {
	CreateVolume(ctx context.Context, req *godo.VolumeCreateRequest) (*godo.Volume, *godo.Response, error)
	GetVolume(ctx context.Context, volumeID string) (*godo.Volume, *godo.Response, error)
	DeleteVolume(ctx context.Context, volumeID string) (*godo.Response, error)
	ListVolumes(ctx context.Context, params *godo.ListVolumeParams) ([]godo.Volume, *godo.Response, error)
}

StorageClient is the godo Storage interface (for mocking). Subset of godo.StorageService — only the methods VolumeDriver and DropletDriver (volumes-by-name resolution) need.

type VPCClient

type VPCClient interface {
	Create(ctx context.Context, req *godo.VPCCreateRequest) (*godo.VPC, *godo.Response, error)
	Get(ctx context.Context, vpcID string) (*godo.VPC, *godo.Response, error)
	List(ctx context.Context, opts *godo.ListOptions) ([]*godo.VPC, *godo.Response, error)
	Update(ctx context.Context, vpcID string, req *godo.VPCUpdateRequest) (*godo.VPC, *godo.Response, error)
	Delete(ctx context.Context, vpcID string) (*godo.Response, error)
}

VPCClient is the godo VPCs interface (for mocking).

type VPCDriver

type VPCDriver struct {
	// contains filtered or unexported fields
}

VPCDriver manages DigitalOcean VPCs (infra.vpc).

func NewVPCDriver

func NewVPCDriver(c *godo.Client, region string) *VPCDriver

NewVPCDriver creates a VPCDriver backed by a real godo client.

func NewVPCDriverWithClient

func NewVPCDriverWithClient(c VPCClient, region string) *VPCDriver

NewVPCDriverWithClient creates a driver with an injected client (for tests).

func (*VPCDriver) Create

func (*VPCDriver) Delete

func (d *VPCDriver) Delete(ctx context.Context, ref interfaces.ResourceRef) error

func (*VPCDriver) Diff

func (*VPCDriver) HealthCheck

func (*VPCDriver) ProviderIDFormat added in v0.7.9

func (d *VPCDriver) ProviderIDFormat() interfaces.ProviderIDFormat

func (*VPCDriver) Read

func (*VPCDriver) Scale

func (*VPCDriver) SensitiveKeys added in v0.2.1

func (d *VPCDriver) SensitiveKeys() []string

func (*VPCDriver) SupportsUpsert added in v0.7.3

func (d *VPCDriver) SupportsUpsert() bool

SupportsUpsert reports that VPCDriver can locate a resource by name alone (empty ProviderID), enabling the ErrResourceAlreadyExists → upsert path.

type VolumeDriver added in v0.9.0

type VolumeDriver struct {
	// contains filtered or unexported fields
}

VolumeDriver manages DigitalOcean Block Storage volumes (infra.volume).

Update semantics: only size GROWTH is supported in-place via StorageActions.Resize. Size shrinks are unsupported by DO; any other attribute change (region, filesystem_type) forces replace via Diff.

func NewVolumeDriver added in v0.9.0

func NewVolumeDriver(c *godo.Client, region string) *VolumeDriver

NewVolumeDriver creates a VolumeDriver backed by a real godo client.

func NewVolumeDriverWithClient added in v0.9.0

func NewVolumeDriverWithClient(c StorageClient, actions StorageActionsClient, region string) *VolumeDriver

NewVolumeDriverWithClient creates a driver with injected clients (for tests). The actions client may be nil for tests that do not exercise the resize path.

func (*VolumeDriver) Create added in v0.9.0

func (*VolumeDriver) Delete added in v0.9.0

func (*VolumeDriver) Diff added in v0.9.0

func (*VolumeDriver) HealthCheck added in v0.9.0

func (*VolumeDriver) ProviderIDFormat added in v0.9.0

func (d *VolumeDriver) ProviderIDFormat() interfaces.ProviderIDFormat

ProviderIDFormat is UUID — DO Block Storage volume IDs are UUIDs.

func (*VolumeDriver) Read added in v0.9.0

func (*VolumeDriver) Scale added in v0.9.0

func (*VolumeDriver) SensitiveKeys added in v0.9.0

func (d *VolumeDriver) SensitiveKeys() []string

func (*VolumeDriver) Update added in v0.9.0

Jump to

Keyboard shortcuts

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