Here's a summary of what it would take to add Vultr support (issue #43):
Current State
The codebase is tightly coupled to DigitalOcean — there's no provider abstraction layer. Every subcommand directly imports and uses python-digitalocean classes (Manager, Droplet, Domain, etc.). The config loader is hardcoded to expect a digital-ocean section.
One bright spot: cloud_config.py is already provider-agnostic since cloud-init is a cross-provider standard.
What Would Need to Change
1. Provider Abstraction Layer (new)
Create a CloudProvider ABC with methods like create_vm(), destroy_vm(), list_vms(), get_ssh_key(), create_dns_record(), etc. Then implement DigitalOceanProvider and VultrProvider.
2. Config (config.py, types.py)
- Support a
vultr:section alongsidedigital-ocean: - Add provider selection logic
- Map provider-specific parameters (regions, images, sizes all differ between providers)
3. All 9 Subcommands
Every subcommand (create, destroy, list, status, ssh-keys, domains, list-domain, projects, types) currently calls DO APIs directly and would need refactoring to use the provider abstraction.
4. Utilities (util.py)
All helpers (projectFromName, sshKeyFromName, dnsRecordIdFromName) work directly with DO objects and would need provider-neutral equivalents.
5. Tagging/Session System
DO has native tags used for session tracking. Vultr may need an alternative mechanism (metadata, naming conventions).
6. Region/Image/Size Mapping
Hardcoded DO-specific lists in create.py (e.g., ["NYC1", "NYC3", ...], ["ubuntu-22-04-x64", ...]) would need per-provider equivalents.
Vultr Specifics
Vultr is a reasonable choice — it supports cloud-init, has a REST API, offers DNS management, and has similar pricing. The vultr Python library exists. Key differences to handle: - Different auth (API key vs DO access token) - Different resource naming (instances vs droplets, plans vs size slugs) - No native "projects" concept - Different region/image identifiers
Recommended Approach
- Introduce the provider abstraction first (without Vultr) — refactor all subcommands to go through a
CloudProviderinterface, withDigitalOceanProvideras the sole implementation - Then add
VultrProvideras a second implementation - Update config to support provider selection
This is a significant refactor (~900 lines of code, all subcommands affected) but the codebase is small enough that it's very manageable.