kitsune-kit 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +117 -2
- data/CONTRIBUTING.md +83 -0
- data/README.md +108 -136
- data/SECURITY.md +25 -0
- data/bin/kit +4 -1
- data/docs/architecture/decisions/0001-product-boundary.md +23 -0
- data/docs/architecture/decisions/0002-core-and-interfaces.md +23 -0
- data/docs/architecture/decisions/0003-configuration-state-and-secrets.md +23 -0
- data/docs/architecture/decisions/0004-supported-platforms.md +19 -0
- data/docs/architecture/decisions/0005-operation-semantics.md +19 -0
- data/docs/architecture/decisions/0006-tui-backend.md +21 -0
- data/docs/architecture/provider-adapters.md +49 -0
- data/docs/architecture.md +89 -0
- data/docs/commands.md +210 -0
- data/docs/configuration.md +210 -0
- data/docs/getting-started.md +133 -0
- data/docs/providers/digitalocean.md +52 -0
- data/docs/releasing.md +43 -0
- data/docs/roadmap.md +46 -0
- data/docs/security-audit.md +130 -0
- data/docs/security.md +116 -0
- data/docs/services/postgres.md +78 -0
- data/docs/services/redis.md +53 -0
- data/docs/testing.md +200 -0
- data/docs/troubleshooting.md +123 -0
- data/docs/tui.md +57 -0
- data/lib/kitsune/kit/adapters/confirming_host_key_verifier.rb +42 -0
- data/lib/kitsune/kit/adapters/digitalocean_provider.rb +217 -0
- data/lib/kitsune/kit/adapters/fake_clock.rb +34 -0
- data/lib/kitsune/kit/adapters/fake_provider.rb +107 -0
- data/lib/kitsune/kit/adapters/fake_reporter.rb +34 -0
- data/lib/kitsune/kit/adapters/fake_secret_store.rb +35 -0
- data/lib/kitsune/kit/adapters/fake_state_store.rb +91 -0
- data/lib/kitsune/kit/adapters/fake_transport.rb +56 -0
- data/lib/kitsune/kit/adapters/net_ssh_transport.rb +155 -0
- data/lib/kitsune/kit/adapters/provider.rb +34 -0
- data/lib/kitsune/kit/adapters/transport.rb +22 -0
- data/lib/kitsune/kit/adapters/transport_factory.rb +116 -0
- data/lib/kitsune/kit/application.rb +170 -0
- data/lib/kitsune/kit/cancellation.rb +21 -0
- data/lib/kitsune/kit/cli.rb +802 -64
- data/lib/kitsune/kit/clock.rb +11 -0
- data/lib/kitsune/kit/configuration.rb +493 -0
- data/lib/kitsune/kit/errors.rb +98 -0
- data/lib/kitsune/kit/events.rb +55 -0
- data/lib/kitsune/kit/operations/ensure_dns_records.rb +165 -0
- data/lib/kitsune/kit/operations/ensure_server.rb +135 -0
- data/lib/kitsune/kit/operations/ensure_service.rb +285 -0
- data/lib/kitsune/kit/operations/remote_script.rb +214 -0
- data/lib/kitsune/kit/operations/service_backup.rb +71 -0
- data/lib/kitsune/kit/operations/service_files.rb +127 -0
- data/lib/kitsune/kit/operations/service_firewall.rb +190 -0
- data/lib/kitsune/kit/operations/service_state.rb +59 -0
- data/lib/kitsune/kit/plan.rb +72 -0
- data/lib/kitsune/kit/reporters/human.rb +89 -0
- data/lib/kitsune/kit/reporters/json.rb +65 -0
- data/lib/kitsune/kit/reporters/reporter.rb +11 -0
- data/lib/kitsune/kit/result.rb +28 -0
- data/lib/kitsune/kit/run_journal.rb +102 -0
- data/lib/kitsune/kit/run_logger.rb +37 -0
- data/lib/kitsune/kit/scripts/docker.sh +137 -0
- data/lib/kitsune/kit/scripts/firewall.sh +205 -0
- data/lib/kitsune/kit/scripts/metrics.sh +54 -0
- data/lib/kitsune/kit/scripts/ssh.sh +95 -0
- data/lib/kitsune/kit/scripts/swap.sh +86 -0
- data/lib/kitsune/kit/scripts/unattended.sh +81 -0
- data/lib/kitsune/kit/scripts/user.sh +114 -0
- data/lib/kitsune/kit/secret_filter.rb +54 -0
- data/lib/kitsune/kit/secret_store.rb +32 -0
- data/lib/kitsune/kit/secret_stores/store.rb +12 -0
- data/lib/kitsune/kit/service_compose.rb +72 -0
- data/lib/kitsune/kit/state_store.rb +158 -0
- data/lib/kitsune/kit/state_stores/store.rb +15 -0
- data/lib/kitsune/kit/tui/actions.rb +72 -0
- data/lib/kitsune/kit/tui/application.rb +35 -0
- data/lib/kitsune/kit/tui/controller.rb +162 -0
- data/lib/kitsune/kit/tui/renderer.rb +134 -0
- data/lib/kitsune/kit/tui/state.rb +18 -0
- data/lib/kitsune/kit/tui/store.rb +88 -0
- data/lib/kitsune/kit/tui/terminal.rb +95 -0
- data/lib/kitsune/kit/version.rb +1 -1
- data/lib/kitsune/kit/workflows/apply_plan.rb +145 -0
- data/lib/kitsune/kit/workflows/base.rb +31 -0
- data/lib/kitsune/kit/workflows/build_plan.rb +33 -0
- data/lib/kitsune/kit/workflows/destroy_server.rb +84 -0
- data/lib/kitsune/kit/workflows/doctor.rb +225 -0
- data/lib/kitsune/kit/workflows/environment_selection.rb +70 -0
- data/lib/kitsune/kit/workflows/import_server.rb +100 -0
- data/lib/kitsune/kit/workflows/initialize_project.rb +121 -0
- data/lib/kitsune/kit/workflows/inspect_environment.rb +44 -0
- data/lib/kitsune/kit/workflows/rollback.rb +54 -0
- data/lib/kitsune/kit/workflows/support_bundle.rb +82 -0
- data/lib/kitsune/kit.rb +41 -2
- metadata +122 -79
- data/.rspec +0 -3
- data/Rakefile +0 -8
- data/kitsune-kit-logo.jpg +0 -0
- data/lib/kitsune/blueprints/.env.template +0 -31
- data/lib/kitsune/blueprints/docker/postgres.yml +0 -27
- data/lib/kitsune/blueprints/docker/redis.yml +0 -23
- data/lib/kitsune/blueprints/kit.env.template +0 -1
- data/lib/kitsune/kit/ansi_color.rb +0 -78
- data/lib/kitsune/kit/commands/bootstrap.rb +0 -134
- data/lib/kitsune/kit/commands/bootstrap_docker.rb +0 -66
- data/lib/kitsune/kit/commands/dns.rb +0 -112
- data/lib/kitsune/kit/commands/init.rb +0 -148
- data/lib/kitsune/kit/commands/install_docker_engine.rb +0 -146
- data/lib/kitsune/kit/commands/postinstall_docker.rb +0 -142
- data/lib/kitsune/kit/commands/provision.rb +0 -43
- data/lib/kitsune/kit/commands/setup_do_metrics.rb +0 -123
- data/lib/kitsune/kit/commands/setup_docker_prereqs.rb +0 -151
- data/lib/kitsune/kit/commands/setup_firewall.rb +0 -132
- data/lib/kitsune/kit/commands/setup_postgres_docker.rb +0 -246
- data/lib/kitsune/kit/commands/setup_redis_docker.rb +0 -241
- data/lib/kitsune/kit/commands/setup_swap.rb +0 -151
- data/lib/kitsune/kit/commands/setup_unattended.rb +0 -132
- data/lib/kitsune/kit/commands/setup_user.rb +0 -189
- data/lib/kitsune/kit/commands/ssh.rb +0 -46
- data/lib/kitsune/kit/commands/switch_env.rb +0 -42
- data/lib/kitsune/kit/defaults.rb +0 -91
- data/lib/kitsune/kit/env_loader.rb +0 -41
- data/lib/kitsune/kit/options_builder.rb +0 -26
- data/lib/kitsune/kit/provisioner.rb +0 -107
- data/sig/kitsune/kit.rbs +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 02a64110c8bffb9342d3cd0550360d95d871a4c1179f33899e34787abe59a080
|
|
4
|
+
data.tar.gz: 2bf327e34d000c12ba3883573a088493f353f5265ca2b7aa4693b645ba9f3ee9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 23e94dae8106856bd149f8e66d47ee61c47d1ddb5ccbb3311ec8f214d0874b4cdf64b40777d7f6dd04b393be684044785e6135f23f78618237ba5e6927e317cb
|
|
7
|
+
data.tar.gz: 59f168aa081fc7047a0e49a1107c288cdd4f2c04e0da45be46e514c89e181ee023e1f860ceb2511017e1f9885e9c2a773a6008959a9c3c78ff15e49bf75f8750
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,121 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
All notable changes are documented here. The project follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
4
|
+
and [Semantic Versioning](https://semver.org/); minor releases may change public interfaces before 1.0.
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
## [0.5.0] - 2026-08-14
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Comprehensive security hardening and release process.
|
|
13
|
+
- Architecture decisions for the direct rewrite, presentation parity, configuration, state and operation semantics.
|
|
14
|
+
- Contribution and security policies.
|
|
15
|
+
- Typed configuration, domain errors/results/events, versioned state, run journals and safe resume.
|
|
16
|
+
- Provider and SSH contracts with deterministic fakes and hardened DigitalOcean/Net::SSH adapters.
|
|
17
|
+
- Deterministic fake state/reporter adapters and shared real/fake state contracts.
|
|
18
|
+
- Read-only `doctor` and `plan`, non-interactive/JSON output, stable exit codes and support bundles.
|
|
19
|
+
- Ownership-aware server, DNS, Docker, PostgreSQL and Redis lifecycle operations.
|
|
20
|
+
- Optional pure-Ruby full-screen TUI over the same workflows as the conventional CLI.
|
|
21
|
+
- Unit, contract, hostile-input, CLI, headless TUI, Docker SSH integration and guarded DigitalOcean E2E suites.
|
|
22
|
+
- Matrix CI, dependency audit, shell lint, artifact installation smoke test, Dependabot and TTL resource cleanup.
|
|
23
|
+
- Complete user, security, provider, service, architecture, testing, troubleshooting and TUI documentation.
|
|
24
|
+
- Exact-ID server state import, schema compatibility guidance and a documented manual security audit.
|
|
25
|
+
- External PostgreSQL/Redis endpoint mode that never assumes or mutates a local Docker service.
|
|
26
|
+
- Pseudo-terminal TUI lifecycle and restoration coverage.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Version 0.5.0 directly replaces the earlier preview CLI; legacy compatibility is not a goal.
|
|
31
|
+
- Declare Ruby 3.2–3.4 support explicitly; Ruby 4 remains blocked by the current DigitalOcean SDK dependency chain.
|
|
32
|
+
- The command tree is now `init -> doctor -> plan -> apply`, with explicit resource subcommands.
|
|
33
|
+
- PostgreSQL and Redis are private and disabled by default; data destruction is separate from service removal.
|
|
34
|
+
- SSH, firewall, Docker and metrics setup use versioned verified scripts and captured rollback state.
|
|
35
|
+
- Safety-critical SSH/firewall transitions reuse a preserved session and transactionally recover failed changes.
|
|
36
|
+
- Service data destruction offers an optional backup and requires exact interactive or automation confirmation.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- Declared `base64`, `bigdecimal` and transitive `ostruct` requirements explicitly for supported Ruby releases.
|
|
41
|
+
- Made the ShellCheck availability probe portable across macOS and Ubuntu CI runners.
|
|
42
|
+
- Prevented framework commands added by newer Thor releases from silently changing Kitsune Kit's public CLI.
|
|
43
|
+
- Wait for SSH readiness after a new Droplet becomes active and reject mismatched E2E key pairs before billing.
|
|
44
|
+
- Validate DigitalOcean account access before E2E provisioning and avoid false server drift warnings.
|
|
45
|
+
- Use DropletKit's real `account.info` endpoint instead of a fake-only `account.get` method.
|
|
46
|
+
- Correct TUI plan/doctor shortcut routing and prevent full-width terminal frames from scrolling during redraws.
|
|
47
|
+
- Wait for authenticated SSH, rather than an open Docker proxy port, before running container integration cases.
|
|
48
|
+
|
|
49
|
+
### Removed
|
|
50
|
+
|
|
51
|
+
- Legacy bootstrap/setup command classes and interpolated Compose/env templates.
|
|
52
|
+
- The unused RBS placeholder; types will only return with a maintained, CI-checked contract.
|
|
53
|
+
|
|
54
|
+
### Security
|
|
55
|
+
|
|
56
|
+
- Added strict SSH host-key verification, input allow-lists, safe argument transport and secret redaction.
|
|
57
|
+
- Added exact provider/resource identity checks, atomic restricted state, protected Docker firewall rules and explicit destructive confirmations.
|
|
58
|
+
- Prevented Redis passwords from resolving into container command arguments and made installer/config temporaries failure-safe.
|
|
59
|
+
|
|
60
|
+
## [0.4.1] - 2025-06-01
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- Corrected Redis defaults and removed an accidental debugger dependency from runtime code.
|
|
65
|
+
|
|
66
|
+
## [0.4.0] - 2025-05-04
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
|
|
70
|
+
- DigitalOcean DNS record management.
|
|
71
|
+
|
|
72
|
+
### Changed
|
|
73
|
+
|
|
74
|
+
- Replaced the external color dependency with the internal ANSI helper.
|
|
75
|
+
- Corrected generated development environment defaults.
|
|
76
|
+
|
|
77
|
+
## [0.3.0] - 2025-05-03
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- Redis service setup with Docker Compose.
|
|
82
|
+
- Version command and initial CLI integration tests.
|
|
83
|
+
|
|
84
|
+
### Fixed
|
|
85
|
+
|
|
86
|
+
- Corrected SSH invocation and PostgreSQL setup behavior.
|
|
87
|
+
|
|
88
|
+
## [0.2.1] - 2025-05-01
|
|
89
|
+
|
|
90
|
+
### Changed
|
|
91
|
+
|
|
92
|
+
- Expanded documentation for swap and DigitalOcean metrics support.
|
|
93
|
+
|
|
94
|
+
## [0.2.0] - 2025-05-01
|
|
95
|
+
|
|
96
|
+
### Added
|
|
97
|
+
|
|
98
|
+
- Managed swap setup and rollback.
|
|
99
|
+
- DigitalOcean metrics-agent setup.
|
|
100
|
+
|
|
101
|
+
## [0.1.1] - 2025-05-01
|
|
102
|
+
|
|
103
|
+
### Added
|
|
104
|
+
|
|
105
|
+
- PostgreSQL firewall integration and improved CLI feedback.
|
|
106
|
+
|
|
3
107
|
## [0.1.0] - 2025-04-29
|
|
108
|
+
|
|
4
109
|
### Added
|
|
5
|
-
|
|
6
|
-
-
|
|
110
|
+
|
|
111
|
+
- First public preview.
|
|
112
|
+
- Bootstrap commands for DigitalOcean, Docker and PostgreSQL.
|
|
113
|
+
|
|
114
|
+
[Unreleased]: https://github.com/omarhrra/kitsune-kit/compare/v0.5.0...HEAD
|
|
115
|
+
[0.5.0]: https://github.com/omarhrra/kitsune-kit/compare/v0.4.1...v0.5.0
|
|
116
|
+
[0.4.1]: https://github.com/omarhrra/kitsune-kit/compare/v0.4.0...v0.4.1
|
|
117
|
+
[0.4.0]: https://github.com/omarhrra/kitsune-kit/compare/v0.3.0...v0.4.0
|
|
118
|
+
[0.3.0]: https://github.com/omarhrra/kitsune-kit/compare/v0.2.1...v0.3.0
|
|
119
|
+
[0.2.1]: https://github.com/omarhrra/kitsune-kit/compare/v0.2.0...v0.2.1
|
|
120
|
+
[0.2.0]: https://github.com/omarhrra/kitsune-kit/compare/v0.1.0...v0.2.0
|
|
121
|
+
[0.1.0]: https://github.com/omarhrra/kitsune-kit/releases/tag/v0.1.0
|
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Contributing to Kitsune Kit
|
|
2
|
+
|
|
3
|
+
Kitsune Kit is being rebuilt as a secure, inspectable infrastructure CLI. Read the architecture decisions in `docs/architecture/decisions` before changing public commands, configuration, state, events or destructive behavior.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
Requirements:
|
|
8
|
+
|
|
9
|
+
- Ruby 3.2 or newer
|
|
10
|
+
- Bundler 4.0.18
|
|
11
|
+
- ShellCheck for remote script linting
|
|
12
|
+
- Docker for integration tests
|
|
13
|
+
|
|
14
|
+
Run:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bin/setup
|
|
18
|
+
bundle exec rake ci
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Development commands
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bundle exec rake spec # Ruby tests
|
|
25
|
+
bundle exec rake lint # Ruby and shell lint
|
|
26
|
+
bundle exec rake security # dependency audit
|
|
27
|
+
bundle exec rake build # build the gem
|
|
28
|
+
bundle exec rake artifact_smoke # install the gem with fresh dependencies and verify its CLI
|
|
29
|
+
bundle exec rake ci # local pull-request gate
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Integration and real-provider tests are kept separate because they require Docker or credentials:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bundle exec rake integration
|
|
36
|
+
KITSUNE_E2E=1 bundle exec rake e2e
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Adding an operation
|
|
40
|
+
|
|
41
|
+
An operation must validate input, calculate a non-mutating plan, be idempotent, verify its result, declare destructive effects, redact secrets, use timeouts and have success/no-change/failure tests. Provider and SSH code belongs in adapters, not workflows or presentation classes.
|
|
42
|
+
|
|
43
|
+
Every action exposed in the TUI must have a CLI equivalent. Domain behavior is tested below either presentation layer.
|
|
44
|
+
|
|
45
|
+
## Adding or changing a provider
|
|
46
|
+
|
|
47
|
+
Implement the provider port without leaking SDK values or exceptions into the core. The adapter must:
|
|
48
|
+
|
|
49
|
+
- use exact provider IDs for destructive calls;
|
|
50
|
+
- preserve configured ownership tags;
|
|
51
|
+
- map authentication, retryable provider and timeout failures to domain errors;
|
|
52
|
+
- persist an ID before waiting on a newly created resource;
|
|
53
|
+
- satisfy the shared provider contract and adapter-specific HTTP/SDK tests;
|
|
54
|
+
- document credentials, permissions, identity and cleanup behavior.
|
|
55
|
+
|
|
56
|
+
Do not add a second provider until its full create/wait/resume/delete lifecycle can run through existing workflows without provider conditionals in presentation code.
|
|
57
|
+
|
|
58
|
+
## Tests
|
|
59
|
+
|
|
60
|
+
Every behavior change needs the smallest appropriate unit/contract tests plus integration coverage when it crosses a real process, SSH or shell boundary. Destructive paths, failure-after-mutation, retry/resume, timeout and hostile inputs require explicit examples.
|
|
61
|
+
|
|
62
|
+
Run the complete local gate before opening a pull request:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bundle exec rake ci
|
|
66
|
+
bundle exec rake integration # when Docker/SSH/scripts changed
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The DigitalOcean E2E suite is billable and credential-gated. Never run it against a production account; follow `docs/testing.md`.
|
|
70
|
+
|
|
71
|
+
## Pull requests
|
|
72
|
+
|
|
73
|
+
- Keep changes focused on one coherent capability.
|
|
74
|
+
- Include tests and documentation with behavior changes.
|
|
75
|
+
- Never commit tokens, private keys, `.kitsune/state`, logs or generated support bundles.
|
|
76
|
+
- Explain destructive behavior and rollback semantics explicitly.
|
|
77
|
+
- Update `CHANGELOG.md` under `Unreleased` for user-visible changes.
|
|
78
|
+
|
|
79
|
+
Commit messages should be imperative and describe one coherent change. Pull requests should explain user-visible behavior, security/destruction implications, test evidence and any migration. A maintainer may squash on merge.
|
|
80
|
+
|
|
81
|
+
## Releases
|
|
82
|
+
|
|
83
|
+
Releases follow `docs/releasing.md`. Do not publish manually with a long-lived RubyGems API key. The protected `release` environment and RubyGems trusted publisher must approve the tag-triggered workflow.
|
data/README.md
CHANGED
|
@@ -1,198 +1,170 @@
|
|
|
1
|
-
# Kitsune Kit
|
|
1
|
+
# Kitsune Kit
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
<img src="kitsune-kit-logo.jpg" alt="Kitsune Logo" width="180"/>
|
|
5
|
-
</p>
|
|
3
|
+
Kitsune Kit prepares Ubuntu servers for Docker and Kamal deployments through a predictable, inspectable CLI.
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
> Status: `0.5.0` (pre-1.0). DigitalOcean and Ubuntu 22.04/24.04 LTS are supported. The command, configuration and state schemas may still change before 1.0.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
## What it does
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
- Provisions an explicitly tagged DigitalOcean Droplet.
|
|
10
|
+
- Configures a deploy user, verified SSH policy, UFW, swap and unattended security updates.
|
|
11
|
+
- Installs Docker Engine and Docker Compose from Docker's official Ubuntu repository.
|
|
12
|
+
- Optionally installs private PostgreSQL/Redis services or represents provider-managed external endpoints.
|
|
13
|
+
- Creates exact DNS records without adopting unrelated resources.
|
|
14
|
+
- Shows a plan before changing infrastructure and records managed state for resume and rollback.
|
|
15
|
+
- Offers both a conventional CLI and an optional full-screen TUI over the same workflows.
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
Kitsune Kit is not a general-purpose configuration manager and does not manage arbitrary existing servers. It only removes resources recorded in its local state.
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
- 👤 Configures a secure, passwordless `deploy` user
|
|
17
|
-
- 🔐 Applies firewall rules (UFW) for SSH, HTTP, HTTPS
|
|
18
|
-
- ♻️ Enables automatic security updates (unattended-upgrades)
|
|
19
|
-
- 💾 Configures swap space for better performance
|
|
20
|
-
- 📊 Installs [DigitalOcean monitoring agent](https://docs.digitalocean.com/products/monitoring/how-to/install-agent/)
|
|
21
|
-
- 🌐 **Automatically links** domains or subdomains (A records) to your server using DigitalOcean DNS
|
|
22
|
-
- 🐳 Installs and configures Docker Engine and private networking
|
|
23
|
-
- 🐘 Deploys PostgreSQL via Docker Compose with healthcheck
|
|
24
|
-
- 🗄️ Deploys Redis via Docker Compose with healthcheck
|
|
25
|
-
- 🔄 All steps can be rolled back (`--rollback`)
|
|
26
|
-
- ⚡ Fast, reproducible and without relying on YAML or complex external tools
|
|
19
|
+
## Requirements
|
|
27
20
|
|
|
28
|
-
|
|
21
|
+
- Ruby 3.2, 3.3 or 3.4 (`>= 3.2`, `< 4.0`). Ruby 4 support is currently blocked by the DigitalOcean SDK dependency chain.
|
|
22
|
+
- A DigitalOcean account, API token and uploaded SSH public key.
|
|
23
|
+
- A local private SSH key with restricted permissions.
|
|
24
|
+
- A project directory whose `.kitsune/` state can be backed up securely.
|
|
29
25
|
|
|
30
|
-
##
|
|
31
|
-
|
|
32
|
-
Add this line to your `Gemfile`:
|
|
33
|
-
|
|
34
|
-
```ruby
|
|
35
|
-
gem "kitsune-kit"
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Or install it manually:
|
|
26
|
+
## Installation
|
|
39
27
|
|
|
40
28
|
```bash
|
|
41
29
|
gem install kitsune-kit
|
|
42
30
|
```
|
|
43
31
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
## ⚙️ Prerequisites
|
|
47
|
-
|
|
48
|
-
1. Configure a DigitalOcean API token:
|
|
49
|
-
```bash
|
|
50
|
-
export DO_API_TOKEN="your_token"
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
2. Have the SSH key ID uploaded to DigitalOcean:
|
|
54
|
-
```bash
|
|
55
|
-
export SSH_KEY_ID="123456"
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
3. Have the private key installed on your local machine:
|
|
59
|
-
```bash
|
|
60
|
-
export SSH_KEY_PATH="~/.ssh/id_rsa"
|
|
61
|
-
```
|
|
32
|
+
Or add it to a project:
|
|
62
33
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
34
|
+
```ruby
|
|
35
|
+
gem "kitsune-kit", "~> 0.5.0"
|
|
36
|
+
```
|
|
66
37
|
|
|
67
|
-
|
|
38
|
+
## Safe quick start
|
|
68
39
|
|
|
69
40
|
```bash
|
|
70
41
|
kit init
|
|
71
|
-
```
|
|
72
42
|
|
|
73
|
-
|
|
43
|
+
# Edit .kitsune/config.yml first.
|
|
44
|
+
export DO_API_TOKEN="..."
|
|
74
45
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
### 🏗️ Server Provisioning
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
kit bootstrap execute
|
|
46
|
+
kit doctor
|
|
47
|
+
kit plan
|
|
48
|
+
kit apply
|
|
83
49
|
```
|
|
84
50
|
|
|
85
|
-
|
|
51
|
+
`kit apply` asks for confirmation. In automation, review the plan and use `kit apply --no-input --yes`. The first SSH connection also requires verifying the displayed host-key fingerprint; non-interactive runs must pass the exact value with `--trust-host-key`.
|
|
86
52
|
|
|
87
|
-
|
|
88
|
-
2. `setup_firewall create`
|
|
89
|
-
3. `setup_unattended create`
|
|
90
|
-
4. `setup_swap`
|
|
91
|
-
5. `setup_do_metrics`
|
|
53
|
+
The recommended workflow is always:
|
|
92
54
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
kit bootstrap_docker execute --server-ip 123.123.123.123
|
|
55
|
+
```text
|
|
56
|
+
init -> edit configuration -> doctor -> plan -> apply -> doctor
|
|
97
57
|
```
|
|
98
58
|
|
|
99
|
-
|
|
59
|
+
See [Getting started](docs/getting-started.md) for the complete first-run procedure.
|
|
100
60
|
|
|
101
|
-
|
|
102
|
-
2. `install_docker_engine create`
|
|
103
|
-
3. `postinstall_docker create`
|
|
61
|
+
## Commands
|
|
104
62
|
|
|
105
|
-
|
|
63
|
+
| Command | Purpose | Changes resources |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `kit init` | Create project configuration | Local |
|
|
66
|
+
| `kit doctor` | Check configuration, credentials, connectivity and drift | No |
|
|
67
|
+
| `kit plan` | Show the desired changes | No |
|
|
68
|
+
| `kit apply` | Apply the reviewed plan | Yes |
|
|
69
|
+
| `kit resume [RUN_ID]` | Continue an incomplete run | Yes |
|
|
70
|
+
| `kit status` | Show tracked state and the server | No |
|
|
71
|
+
| `kit server import` | Recover a verified server ID after state loss | Exact name |
|
|
72
|
+
| `kit rollback` | Restore managed configuration; preserve server and service data | Yes |
|
|
73
|
+
| `kit server ACTION` | Show, create, configure, connect to or destroy the server | Depends |
|
|
74
|
+
| `kit service TYPE ACTION` | Manage PostgreSQL or Redis | Depends |
|
|
75
|
+
| `kit dns ACTION` | List, plan, apply or remove configured records | Depends |
|
|
76
|
+
| `kit docker ACTION` | Inspect, install or uninstall Docker | Depends |
|
|
77
|
+
| `kit env ACTION [NAME]` | List, read or select environments | Local |
|
|
78
|
+
| `kit support bundle` | Create a local redacted diagnostic file | Local |
|
|
79
|
+
| `kit ui` | Open the optional interactive terminal interface | Depends |
|
|
106
80
|
|
|
107
|
-
|
|
108
|
-
kit setup_postgres_docker create --server-ip 123.123.123.123
|
|
109
|
-
```
|
|
81
|
+
Run `kit help` or `kit help COMMAND` for built-in help. The complete action and option reference is in [Commands](docs/commands.md).
|
|
110
82
|
|
|
111
|
-
|
|
83
|
+
## Configuration and environments
|
|
112
84
|
|
|
113
|
-
|
|
85
|
+
The base configuration is `.kitsune/config.yml`. Environment overlays live at `.kitsune/environments/NAME.yml`. Selection precedence is:
|
|
114
86
|
|
|
115
|
-
|
|
87
|
+
1. `--env NAME`
|
|
88
|
+
2. `KITSUNE_ENV`
|
|
89
|
+
3. `.kitsune/environment`
|
|
90
|
+
4. `development`
|
|
116
91
|
|
|
117
|
-
|
|
92
|
+
Within a selected environment, value precedence is defaults, base file, environment overlay, supported environment-variable overrides, then explicit internal API overrides. Tokens and service passwords are read from environment variables and are never stored in configuration or state.
|
|
118
93
|
|
|
119
|
-
|
|
120
|
-
kit bootstrap execute --rollback --keep-server
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
This:
|
|
124
|
-
- Reverts the server configuration (`unattended`, `firewall`, `user`)
|
|
125
|
-
- Optionally **deletes the Droplet** (if you don't use `--keep-server`)
|
|
94
|
+
See [Configuration](docs/configuration.md).
|
|
126
95
|
|
|
127
|
-
|
|
96
|
+
## Security model
|
|
128
97
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
98
|
+
- PostgreSQL and Redis have no published host port by default.
|
|
99
|
+
- Publishing a data port requires explicit allowed CIDRs; Kitsune Kit also manages matching `DOCKER-USER` firewall rules.
|
|
100
|
+
- SSH host keys use trust-on-explicit-confirmation and are subsequently checked strictly.
|
|
101
|
+
- Shell arguments are validated and passed separately; uploaded scripts and configuration use restricted modes.
|
|
102
|
+
- State writes are locked and atomic, with a recoverable backup.
|
|
103
|
+
- Logs and support bundles are redacted and never uploaded automatically.
|
|
104
|
+
- Destructive commands require exact or explicit confirmation.
|
|
133
105
|
|
|
134
|
-
|
|
106
|
+
Read [Security](docs/security.md) before managing production infrastructure.
|
|
135
107
|
|
|
136
|
-
##
|
|
108
|
+
## PostgreSQL and Redis
|
|
137
109
|
|
|
138
|
-
|
|
110
|
+
Services are optional and disabled initially. Enable a service in configuration and export its configured secret:
|
|
139
111
|
|
|
140
112
|
```bash
|
|
141
|
-
|
|
113
|
+
export POSTGRES_PASSWORD="$(ruby -rsecurerandom -e 'print SecureRandom.base64(36)')"
|
|
114
|
+
kit service postgres install
|
|
142
115
|
```
|
|
143
116
|
|
|
144
|
-
|
|
117
|
+
`remove` stops/removes containers but preserves the Docker volume. `destroy-data` permanently removes it and requires `--confirm-destroy TYPE@ENV`. Create a backup first.
|
|
145
118
|
|
|
146
|
-
|
|
119
|
+
See [PostgreSQL](docs/services/postgres.md) and [Redis](docs/services/redis.md).
|
|
147
120
|
|
|
148
|
-
##
|
|
121
|
+
## CLI and optional TUI
|
|
149
122
|
|
|
150
|
-
|
|
123
|
+
Kitsune Kit is fully usable without the TUI. Every infrastructure action available in the full-screen interface invokes the same domain workflow and has a conventional command equivalent. Scripts and CI should use subcommands, `--no-input`, and optionally `--format json`.
|
|
151
124
|
|
|
152
|
-
|
|
153
|
-
2. Run `kamal setup` to initialize the deployment
|
|
154
|
-
3. Use `kamal deploy` as usual
|
|
125
|
+
With no arguments, `kit` opens the TUI only when both standard input and output are terminals; otherwise it prints help. Use `kit ui` to request it explicitly. See [TUI](docs/tui.md).
|
|
155
126
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
## 💡 Tips
|
|
159
|
-
|
|
160
|
-
- Use `kit init` in every new project.
|
|
161
|
-
- Customize `.kitsune/docker/postgres.yml` if you need additional services.
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## 📘 Quick Example
|
|
127
|
+
## Automation and JSON
|
|
166
128
|
|
|
167
129
|
```bash
|
|
168
|
-
|
|
169
|
-
kit
|
|
130
|
+
kit plan --format json --no-input --no-color
|
|
131
|
+
kit apply --format json --no-input --yes
|
|
132
|
+
```
|
|
170
133
|
|
|
171
|
-
|
|
172
|
-
kit bootstrap execute
|
|
134
|
+
JSON documents include `schema_version`, command/run metadata, status, result, warnings and domain events. Errors are emitted as a versioned JSON object on standard error and have documented exit codes. Do not parse human output.
|
|
173
135
|
|
|
174
|
-
|
|
175
|
-
kit bootstrap_docker execute --server-ip 123.123.123.123
|
|
136
|
+
## Development
|
|
176
137
|
|
|
177
|
-
|
|
178
|
-
|
|
138
|
+
```bash
|
|
139
|
+
bin/setup
|
|
140
|
+
bundle exec rake test
|
|
141
|
+
bundle exec rake lint
|
|
142
|
+
bundle exec rake security
|
|
143
|
+
bundle exec rake integration
|
|
144
|
+
bundle exec rake ci
|
|
179
145
|
```
|
|
180
146
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
## 🧪 In Development
|
|
147
|
+
Docker-backed integration tests and credential-gated DigitalOcean E2E tests are intentionally separate. See [Testing](docs/testing.md) and [Contributing](CONTRIBUTING.md).
|
|
184
148
|
|
|
185
|
-
|
|
186
|
-
- [ ] Create databases on another server
|
|
149
|
+
## Documentation
|
|
187
150
|
|
|
188
|
-
|
|
151
|
+
- [Getting started](docs/getting-started.md)
|
|
152
|
+
- [Configuration](docs/configuration.md)
|
|
153
|
+
- [Command reference](docs/commands.md)
|
|
154
|
+
- [Security](docs/security.md)
|
|
155
|
+
- [Manual security audit](docs/security-audit.md)
|
|
156
|
+
- [Troubleshooting](docs/troubleshooting.md)
|
|
157
|
+
- [Architecture](docs/architecture.md)
|
|
158
|
+
- [Testing](docs/testing.md)
|
|
159
|
+
- [Releasing](docs/releasing.md)
|
|
160
|
+
- [Roadmap and extension decisions](docs/roadmap.md)
|
|
189
161
|
|
|
190
|
-
##
|
|
162
|
+
## Roadmap and stability
|
|
191
163
|
|
|
192
|
-
|
|
164
|
+
The current focus is stabilizing the DigitalOcean lifecycle, schema migrations and real-infrastructure E2E coverage before 1.0. Additional providers and extension hooks will be considered only after those contracts are stable.
|
|
193
165
|
|
|
194
|
-
|
|
166
|
+
Security reports follow [SECURITY.md](SECURITY.md). Changes are recorded in [CHANGELOG.md](CHANGELOG.md).
|
|
195
167
|
|
|
196
|
-
##
|
|
168
|
+
## License
|
|
197
169
|
|
|
198
|
-
|
|
170
|
+
Kitsune Kit is available under the [MIT License](LICENSE.txt).
|
data/SECURITY.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Kitsune Kit is pre-1.0 software. Security fixes are provided for the latest release. Minor releases may change commands, configuration and state schemas until 1.0, so infrastructure state must be backed up before upgrading.
|
|
6
|
+
|
|
7
|
+
## Reporting a vulnerability
|
|
8
|
+
|
|
9
|
+
Do not open a public issue for vulnerabilities that could expose credentials, execute injected commands, destroy infrastructure or lock users out of servers. Report them privately to `contact@omarherrera.me` with:
|
|
10
|
+
|
|
11
|
+
- affected version or commit;
|
|
12
|
+
- reproduction steps;
|
|
13
|
+
- impact;
|
|
14
|
+
- suggested remediation, if known.
|
|
15
|
+
|
|
16
|
+
Do not include real tokens, keys, domains or server addresses. An acknowledgement should be expected within seven days.
|
|
17
|
+
|
|
18
|
+
## Security guarantees under development
|
|
19
|
+
|
|
20
|
+
- Databases are private by default.
|
|
21
|
+
- Secrets are never written to state or normal logs.
|
|
22
|
+
- SSH host keys are verified.
|
|
23
|
+
- Destructive operations require explicit confirmation.
|
|
24
|
+
- Rollback only changes resources recorded as managed by Kitsune Kit.
|
|
25
|
+
- User input is validated before reaching shell commands.
|
data/bin/kit
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
3
5
|
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
4
6
|
require "kitsune/kit"
|
|
5
7
|
require "kitsune/kit/cli"
|
|
6
8
|
|
|
9
|
+
ARGV << ($stdin.tty? && $stdout.tty? ? "ui" : "help") if ARGV.empty?
|
|
7
10
|
Kitsune::Kit::CLI.start(ARGV)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# ADR 0001: Product boundary and rewrite policy
|
|
2
|
+
|
|
3
|
+
- Status: accepted
|
|
4
|
+
- Date: 2026-08-14
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
The published preview has no known users or dependent projects. Its commands mix presentation, provider calls, SSH, shell scripts and state mutation. Preserving those interfaces would make unsafe behavior part of the new design.
|
|
9
|
+
|
|
10
|
+
## Decision
|
|
11
|
+
|
|
12
|
+
Kitsune Kit will manage the complete lifecycle of a small Ubuntu application server on DigitalOcean: provisioning, SSH policy, firewall, updates, swap, Docker, optional private PostgreSQL and Redis services, and DNS.
|
|
13
|
+
|
|
14
|
+
The existing CLI and configuration are not compatibility constraints. The new implementation replaces them directly. Git history is the archive for old behavior; production code will not contain legacy adapters or deprecated command aliases.
|
|
15
|
+
|
|
16
|
+
The rewrite may be released as 0.5.0 after its real-provider end-to-end suite passes reliably.
|
|
17
|
+
|
|
18
|
+
## Consequences
|
|
19
|
+
|
|
20
|
+
- Breaking changes are expected before 1.0.
|
|
21
|
+
- Documentation describes only the new interface.
|
|
22
|
+
- Each old implementation is deleted when its replacement is verified.
|
|
23
|
+
- Scope remains DigitalOcean and Ubuntu 22.04/24.04 until the first provider is stable.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# ADR 0002: One core with CLI, JSON and TUI presentations
|
|
2
|
+
|
|
3
|
+
- Status: accepted
|
|
4
|
+
- Date: 2026-08-14
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Kitsune Kit must be pleasant interactively and fully usable in scripts and CI. A full-screen TUI is valuable for inspecting resources and following long operations, but cannot become a second infrastructure implementation.
|
|
9
|
+
|
|
10
|
+
## Decision
|
|
11
|
+
|
|
12
|
+
Application workflows depend only on ports for provider, transport, state, secrets, clock and event publishing. They never call Thor, `puts`, terminal widgets or concrete adapters.
|
|
13
|
+
|
|
14
|
+
Workflows publish typed events. Human CLI output, JSON output, logs and the TUI consume the same event stream. Every TUI action has a documented CLI equivalent. The complete lifecycle works without installing or opening the TUI.
|
|
15
|
+
|
|
16
|
+
The first TUI renderer will be isolated behind a presentation interface. A native rendering dependency may be adopted later without changing workflows.
|
|
17
|
+
|
|
18
|
+
## Consequences
|
|
19
|
+
|
|
20
|
+
- CLI and TUI parity is testable at the workflow-result level.
|
|
21
|
+
- CI can use `--format json` and `--no-input`.
|
|
22
|
+
- TUI failures cannot change domain semantics.
|
|
23
|
+
- Presentation differences are limited to navigation, prompts and progress rendering.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# ADR 0003: Configuration, state and secrets
|
|
2
|
+
|
|
3
|
+
- Status: accepted
|
|
4
|
+
- Date: 2026-08-14
|
|
5
|
+
|
|
6
|
+
## Decision
|
|
7
|
+
|
|
8
|
+
- `.kitsune/config.yml` contains versioned, non-secret project configuration.
|
|
9
|
+
- `.kitsune/environments/<name>.yml` contains versioned environment overrides.
|
|
10
|
+
- `.kitsune/state/<name>.json` contains versioned, non-secret managed-resource state.
|
|
11
|
+
- Secrets come from environment variables initially. Secret-store adapters may be added later.
|
|
12
|
+
- Configuration precedence is CLI, environment variables, the selected environment file, project file, safe defaults.
|
|
13
|
+
- The active environment is selected by `--env`, then `KITSUNE_ENV`, then `.kitsune/environment`, then `development`.
|
|
14
|
+
- State writes are locked and atomic.
|
|
15
|
+
- State stores provider IDs and previous managed values; deletion never relies only on a resource name.
|
|
16
|
+
- Reporters pass all values through one secret filter.
|
|
17
|
+
- Version 1 is the new product baseline; legacy preview formats are not migrated or interpreted.
|
|
18
|
+
- Any future schema transition must be an explicit, tested adjacent-version migration that preserves a backup.
|
|
19
|
+
- Unknown/future configuration and state versions fail with compatible-version or migration guidance.
|
|
20
|
+
|
|
21
|
+
## Consequences
|
|
22
|
+
|
|
23
|
+
Existing `.env` infrastructure files are not read by the new product. Sensitive data is never persisted in state or diagnostic bundles.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# ADR 0004: Supported platforms
|
|
2
|
+
|
|
3
|
+
- Status: accepted
|
|
4
|
+
- Date: 2026-08-14
|
|
5
|
+
|
|
6
|
+
## Decision
|
|
7
|
+
|
|
8
|
+
- Ruby 3.2, 3.3 and 3.4 are supported (`>= 3.2`, `< 4.0`).
|
|
9
|
+
- CI tests every supported Ruby minor version.
|
|
10
|
+
- Local clients support macOS and Linux.
|
|
11
|
+
- Managed servers support Ubuntu 22.04 and 24.04 LTS.
|
|
12
|
+
- Docker Compose v2 is required.
|
|
13
|
+
- DigitalOcean is the only supported provider before 1.0.
|
|
14
|
+
|
|
15
|
+
Ruby 3.2 is selected because the new core uses immutable `Data` value objects. Dependencies that require a newer patch or minor version must not be mandatory until the support declaration is updated and verified.
|
|
16
|
+
|
|
17
|
+
Ruby 4 is excluded from the 0.5.0 contract because DropletKit 3.22 constrains `faraday-retry` to the 2.2 series,
|
|
18
|
+
whose gem metadata requires Ruby `< 4`. Support can be enabled once that provider dependency accepts a
|
|
19
|
+
Ruby-4-compatible `faraday-retry` release, or when the provider adapter no longer depends on that SDK.
|