11 Commits

Author SHA1 Message Date
Riccardo Schirone 111a6cd995 Validate rendered cloud-init templates against official schema (#63)
* Validate rendered cloud-init templates against official schema

Add jsonschema dev dependency and two new tests that render the Jinja2
cloud-init template (with and without Tailscale) then validate the
output against canonical/cloud-init's JSON schema. Tests skip gracefully
when the network is unavailable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Pin cloud-init schema to 22.4.2 and load from local test data

Replace the network-fetched schema (from cloud-init main) with a local
copy pinned to version 22.4.2 — the oldest cloud-init shipped by any
currently supported DigitalOcean image (Debian 12 bookworm). This
addresses review feedback to avoid validating against a schema newer
than what target distros actually support, and removes the network
dependency so tests work offline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 17:03:16 +02:00
dm 2bf36e2304 Fix Docker APT source to work with both Ubuntu and Debian images (#59)
The cloud-init template hardcoded the Docker APT repo URL for Ubuntu,
which breaks on Debian images (e.g. Debian 13 "trixie"). Replace the
static apt.sources block with a runcmd script that detects the distro
via /etc/os-release and configures the correct Docker repo dynamically.
Also uses dpkg --print-architecture instead of hardcoding amd64.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 14:33:11 +02:00
Riccardo Schirone f6bb0e9aca Add E2E lifecycle test and CI workflow (#43)
* Add E2E lifecycle test for create/destroy workflow

  Bash script that exercises the full droplet lifecycle: create (no
  Tailscale), verify SSH config, run commands over SSH, destroy, and
  verify cleanup

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: dm <alexis.challande@trailofbits.com>
2026-03-24 14:57:58 +01:00
Riccardo Schirone 212306c568 Update default Ubuntu image to 25.10 and extract slug constants (#48)
* Update default Ubuntu image from 25.04 to 25.10

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Extract default region/size/image slugs into constants

Replace duplicated hardcoded strings across config.py, main.py, and
tests with DEFAULT_REGION, DEFAULT_SIZE, and DEFAULT_IMAGE constants
defined in config.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 10:01:13 +01:00
Riccardo Schirone 0efeea52bb Add Jinja2 template validation test and pre-commit hook (#45)
* Remove escaped chars in comments

* Add Jinja2 template validation test and pre-commit hook

Catch template syntax errors early with a unit test that parses and
renders the default cloud-init template, and a pre-commit hook that
validates all templates in dropkit/templates/ on change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:23:39 +01:00
William Tan 77069f5516 Allow resizing hibernated droplets by modifying the size tag (#34)
* allow resizing hibernated droplets by modifying the size tag

* Prevent removal of protected tags (owner, firewall) in untag_resource

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:49:24 -05:00
William Tan b5c099840b Fix macOS Tailscale CLI discovery for App Store installs (#35)
* Fix macOS Tailscale CLI discovery for App Store installs

On macOS, Tailscale installed via the App Store places its CLI at
/Applications/Tailscale.app/Contents/MacOS/Tailscale, which is not in
PATH. Add find_tailscale_cli() helper that checks PATH first, then
falls back to the macOS App Store location on darwin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Address PR feedback: better error message, remove excessive test

Distinguish "Tailscale not found" from "not running" when the local
check fails, so users know whether to install or start Tailscale.
Remove the overly comprehensive binary_vanishes race condition test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:48:17 -05:00
Riccardo Schirone eae5bc1cf4 Generalize email domain handling in documentation and tests (#27)
* Generalize email domain handling in documentation and tests

- Add .worktrees/ to .gitignore for git worktree support
- Update _sanitize_email_for_username docstring to be domain-agnostic
- Change CLAUDE.md example from trailofbits.com to example.com
- Add tests for google.com, gmail.com, corporate, and plus addressing

The code already supported any email domain; this updates docs and
tests to reflect that capability.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Address PR review comments

- Remove redundant trailofbits.com regex, simplify to split("@")[0]
- Rename test to clarify backwards compatibility intent

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Dan Guido <dan@trailofbits.com>
2026-02-09 19:26:59 +01:00
Riccardo Schirone 9895dd9d5e Fix known_hosts removal for hashed entries (#28)
Replace manual file parsing with ssh-keygen -R which properly handles
both hashed (|1|...) and unhashed entries. macOS and many Linux systems
use HashKnownHosts by default, making the previous implementation unable
to remove entries.

Changes:
- Use ssh-keygen -R for each hostname instead of parsing the file
- Detect successful removal via "updated" in stdout
- Backup files are now .old (ssh-keygen default) instead of .bak
- Bracketed entries ([host]:port) now require exact format

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 15:58:05 -05:00
dm a875f3d430 Rename tobcloud references to dropkit in tests (#29)
* Rename tobcloud references to dropkit in tests

Update test data and test method names to use the new project name.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Format test_ssh_config.py

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 15:57:55 -05:00
Dan Guido bc36073036 Initial commit 2026-01-29 21:53:58 -05:00