Repository navigation
cloud-waste: add idle EC2 instance detection (v1.1, ADR-0022) - #74
Merged
Merged
Conversation
Second Adapter in the package, IdleInstanceAdapter, alongside the existing CloudWasteAdapter - one Adapter per action type, not one Adapter branching on shape (ADR-0006). Idle detection uses AWS's own idle-instance convention as a starting threshold (avg CPU and network bytes, re-verify against AWS's current guidance before any real client replaces the fake one). Completion is a state fact this time, not a ledger: StopInstances is inherently idempotent, so get_stopped just checks the instance's current state - a fourth distinct idempotency mechanism proven in this codebase, and the first that needs no dedup ledger at all. Extended test_chaos.py's crash-injection harness to drive both resource types through one adapter-agnostic driver rather than duplicating it, per the issue's own scope. Holds exactly-once at the 200-trial CI default and a 5,000-trial local stress run for both release_address and stop_instance, zero violations either way. demo.py now runs both flows end to end: unassociated-address release, then idle-instance stop, sharing one outbox/approval/audit trail. 54 tests passing, ruff/mypy clean. Closes #73
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #73.
What
A second Adapter in
cloud-waste,IdleInstanceAdapter, alongside the existingCloudWasteAdapter- one Adapter per action type per ADR-0006, not one Adapter branching on action shape.client.py:Instance,InstanceNotFoundError,list_instances()/stop_instance()/get_stopped()onCloudClient/FakeCloudClient, and the idle thresholds (IDLE_CPU_PERCENT_THRESHOLD,IDLE_NETWORK_BYTES_THRESHOLD) taken from AWS Trusted Advisor's own "Low Utilization EC2 Instances" convention - flagged in comments as needing re-verification before any real client replaces the fake one.adapter.py:IdleInstanceAdapter-revalidate()re-checks CPU/network against the thresholds and confirms the instance is still running;execute()callsstop_instance.detector.py:scan_for_idle_instances(), mirroring the existing address scan, with the same optional Critic attachment (ADR-0021).demo.py: now runs both flows end to end - address release, then instance stop - sharing one outbox/approval/audit trail.Completion here is a state fact, not a ledger:
StopInstancesis inherently idempotent, soget_stoppedjust checks the instance's current state rather than any per-key record. A fourth distinct idempotency mechanism proven in this codebase (after Stripe's re-issued call, wallet-guard's nonce ledger, and cloud-waste's own "resource ceases to exist" for address release) - and the first that needs no dedup ledger at all.Chaos coverage
test_chaos.py's crash-injection driver was already adapter-agnostic (it only calls the threeAdaptermethods), so it's now parametrised over both resource kinds rather than duplicated. Holds exactly-once at the 200-trial CI default and a 5,000-trial local stress run for bothrelease_addressandstop_instance- zero violations either way.Verification
ruff check ./ruff format --check ./mypy .- all clean.pytest -v- 54 passed.uv run python -m cloud_waste.demo- both flows print correctly; only the genuinely unassociated address and genuinely idle instance are acted on.cloud-waste/- no other package touched.