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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +117 -2
  3. data/CONTRIBUTING.md +83 -0
  4. data/README.md +108 -136
  5. data/SECURITY.md +25 -0
  6. data/bin/kit +4 -1
  7. data/docs/architecture/decisions/0001-product-boundary.md +23 -0
  8. data/docs/architecture/decisions/0002-core-and-interfaces.md +23 -0
  9. data/docs/architecture/decisions/0003-configuration-state-and-secrets.md +23 -0
  10. data/docs/architecture/decisions/0004-supported-platforms.md +19 -0
  11. data/docs/architecture/decisions/0005-operation-semantics.md +19 -0
  12. data/docs/architecture/decisions/0006-tui-backend.md +21 -0
  13. data/docs/architecture/provider-adapters.md +49 -0
  14. data/docs/architecture.md +89 -0
  15. data/docs/commands.md +210 -0
  16. data/docs/configuration.md +210 -0
  17. data/docs/getting-started.md +133 -0
  18. data/docs/providers/digitalocean.md +52 -0
  19. data/docs/releasing.md +43 -0
  20. data/docs/roadmap.md +46 -0
  21. data/docs/security-audit.md +130 -0
  22. data/docs/security.md +116 -0
  23. data/docs/services/postgres.md +78 -0
  24. data/docs/services/redis.md +53 -0
  25. data/docs/testing.md +200 -0
  26. data/docs/troubleshooting.md +123 -0
  27. data/docs/tui.md +57 -0
  28. data/lib/kitsune/kit/adapters/confirming_host_key_verifier.rb +42 -0
  29. data/lib/kitsune/kit/adapters/digitalocean_provider.rb +217 -0
  30. data/lib/kitsune/kit/adapters/fake_clock.rb +34 -0
  31. data/lib/kitsune/kit/adapters/fake_provider.rb +107 -0
  32. data/lib/kitsune/kit/adapters/fake_reporter.rb +34 -0
  33. data/lib/kitsune/kit/adapters/fake_secret_store.rb +35 -0
  34. data/lib/kitsune/kit/adapters/fake_state_store.rb +91 -0
  35. data/lib/kitsune/kit/adapters/fake_transport.rb +56 -0
  36. data/lib/kitsune/kit/adapters/net_ssh_transport.rb +155 -0
  37. data/lib/kitsune/kit/adapters/provider.rb +34 -0
  38. data/lib/kitsune/kit/adapters/transport.rb +22 -0
  39. data/lib/kitsune/kit/adapters/transport_factory.rb +116 -0
  40. data/lib/kitsune/kit/application.rb +170 -0
  41. data/lib/kitsune/kit/cancellation.rb +21 -0
  42. data/lib/kitsune/kit/cli.rb +802 -64
  43. data/lib/kitsune/kit/clock.rb +11 -0
  44. data/lib/kitsune/kit/configuration.rb +493 -0
  45. data/lib/kitsune/kit/errors.rb +98 -0
  46. data/lib/kitsune/kit/events.rb +55 -0
  47. data/lib/kitsune/kit/operations/ensure_dns_records.rb +165 -0
  48. data/lib/kitsune/kit/operations/ensure_server.rb +135 -0
  49. data/lib/kitsune/kit/operations/ensure_service.rb +285 -0
  50. data/lib/kitsune/kit/operations/remote_script.rb +214 -0
  51. data/lib/kitsune/kit/operations/service_backup.rb +71 -0
  52. data/lib/kitsune/kit/operations/service_files.rb +127 -0
  53. data/lib/kitsune/kit/operations/service_firewall.rb +190 -0
  54. data/lib/kitsune/kit/operations/service_state.rb +59 -0
  55. data/lib/kitsune/kit/plan.rb +72 -0
  56. data/lib/kitsune/kit/reporters/human.rb +89 -0
  57. data/lib/kitsune/kit/reporters/json.rb +65 -0
  58. data/lib/kitsune/kit/reporters/reporter.rb +11 -0
  59. data/lib/kitsune/kit/result.rb +28 -0
  60. data/lib/kitsune/kit/run_journal.rb +102 -0
  61. data/lib/kitsune/kit/run_logger.rb +37 -0
  62. data/lib/kitsune/kit/scripts/docker.sh +137 -0
  63. data/lib/kitsune/kit/scripts/firewall.sh +205 -0
  64. data/lib/kitsune/kit/scripts/metrics.sh +54 -0
  65. data/lib/kitsune/kit/scripts/ssh.sh +95 -0
  66. data/lib/kitsune/kit/scripts/swap.sh +86 -0
  67. data/lib/kitsune/kit/scripts/unattended.sh +81 -0
  68. data/lib/kitsune/kit/scripts/user.sh +114 -0
  69. data/lib/kitsune/kit/secret_filter.rb +54 -0
  70. data/lib/kitsune/kit/secret_store.rb +32 -0
  71. data/lib/kitsune/kit/secret_stores/store.rb +12 -0
  72. data/lib/kitsune/kit/service_compose.rb +72 -0
  73. data/lib/kitsune/kit/state_store.rb +158 -0
  74. data/lib/kitsune/kit/state_stores/store.rb +15 -0
  75. data/lib/kitsune/kit/tui/actions.rb +72 -0
  76. data/lib/kitsune/kit/tui/application.rb +35 -0
  77. data/lib/kitsune/kit/tui/controller.rb +162 -0
  78. data/lib/kitsune/kit/tui/renderer.rb +134 -0
  79. data/lib/kitsune/kit/tui/state.rb +18 -0
  80. data/lib/kitsune/kit/tui/store.rb +88 -0
  81. data/lib/kitsune/kit/tui/terminal.rb +95 -0
  82. data/lib/kitsune/kit/version.rb +1 -1
  83. data/lib/kitsune/kit/workflows/apply_plan.rb +145 -0
  84. data/lib/kitsune/kit/workflows/base.rb +31 -0
  85. data/lib/kitsune/kit/workflows/build_plan.rb +33 -0
  86. data/lib/kitsune/kit/workflows/destroy_server.rb +84 -0
  87. data/lib/kitsune/kit/workflows/doctor.rb +225 -0
  88. data/lib/kitsune/kit/workflows/environment_selection.rb +70 -0
  89. data/lib/kitsune/kit/workflows/import_server.rb +100 -0
  90. data/lib/kitsune/kit/workflows/initialize_project.rb +121 -0
  91. data/lib/kitsune/kit/workflows/inspect_environment.rb +44 -0
  92. data/lib/kitsune/kit/workflows/rollback.rb +54 -0
  93. data/lib/kitsune/kit/workflows/support_bundle.rb +82 -0
  94. data/lib/kitsune/kit.rb +41 -2
  95. metadata +122 -79
  96. data/.rspec +0 -3
  97. data/Rakefile +0 -8
  98. data/kitsune-kit-logo.jpg +0 -0
  99. data/lib/kitsune/blueprints/.env.template +0 -31
  100. data/lib/kitsune/blueprints/docker/postgres.yml +0 -27
  101. data/lib/kitsune/blueprints/docker/redis.yml +0 -23
  102. data/lib/kitsune/blueprints/kit.env.template +0 -1
  103. data/lib/kitsune/kit/ansi_color.rb +0 -78
  104. data/lib/kitsune/kit/commands/bootstrap.rb +0 -134
  105. data/lib/kitsune/kit/commands/bootstrap_docker.rb +0 -66
  106. data/lib/kitsune/kit/commands/dns.rb +0 -112
  107. data/lib/kitsune/kit/commands/init.rb +0 -148
  108. data/lib/kitsune/kit/commands/install_docker_engine.rb +0 -146
  109. data/lib/kitsune/kit/commands/postinstall_docker.rb +0 -142
  110. data/lib/kitsune/kit/commands/provision.rb +0 -43
  111. data/lib/kitsune/kit/commands/setup_do_metrics.rb +0 -123
  112. data/lib/kitsune/kit/commands/setup_docker_prereqs.rb +0 -151
  113. data/lib/kitsune/kit/commands/setup_firewall.rb +0 -132
  114. data/lib/kitsune/kit/commands/setup_postgres_docker.rb +0 -246
  115. data/lib/kitsune/kit/commands/setup_redis_docker.rb +0 -241
  116. data/lib/kitsune/kit/commands/setup_swap.rb +0 -151
  117. data/lib/kitsune/kit/commands/setup_unattended.rb +0 -132
  118. data/lib/kitsune/kit/commands/setup_user.rb +0 -189
  119. data/lib/kitsune/kit/commands/ssh.rb +0 -46
  120. data/lib/kitsune/kit/commands/switch_env.rb +0 -42
  121. data/lib/kitsune/kit/defaults.rb +0 -91
  122. data/lib/kitsune/kit/env_loader.rb +0 -41
  123. data/lib/kitsune/kit/options_builder.rb +0 -26
  124. data/lib/kitsune/kit/provisioner.rb +0 -107
  125. data/sig/kitsune/kit.rbs +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc00c2d601950e0e2ab250c0b19bf8d46eb31fc37490494ab937114b00ebbbf4
4
- data.tar.gz: 1939661240dba888530d041ffb0a36c39946674df556f236015ab8bc3885fd89
3
+ metadata.gz: 02a64110c8bffb9342d3cd0550360d95d871a4c1179f33899e34787abe59a080
4
+ data.tar.gz: 2bf327e34d000c12ba3883573a088493f353f5265ca2b7aa4693b645ba9f3ee9
5
5
  SHA512:
6
- metadata.gz: e9051494678982c1c728d6c64b0a428ac6d313872d8af5c92ecfecc402fc206173deffbbd789f33f808783d9cfdc18b35ac1d5fe7d5aae581db79e289a74c993
7
- data.tar.gz: 83003db9d7c0f50b206d6375f46244f2e582b770ad6b7c1515b9af39aaa74f63c505893341f37690259ef40835eb619261722747dbd485cca018a6619a9679d9
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
- - First public release
6
- - Bootstrap commands for DigitalOcean + Docker + PostgreSQL
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
- <p align="center">
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
- **Kitsune Kit** is a Ruby gem that automates the provisioning, configuration, and setup of remote Linux servers (VPS) to host applications deployed with [Kamal](https://github.com/basecamp/kamal) or Docker Compose. It is designed to work on DigitalOcean infrastructure (for now), featuring reversible commands and a clear workflow.
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
- > 🛠️ *Ideal for Ruby developers who want to launch production without relying on other services.*
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
- ## 🔍 Main Features
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
- - 🧪 **Automatically provisions** a Droplet on DigitalOcean
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
- ## 📦 Installation
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
- ## 🚀 Getting Started
34
+ ```ruby
35
+ gem "kitsune-kit", "~> 0.5.0"
36
+ ```
66
37
 
67
- Initialize the Kitsune project structure:
38
+ ## Safe quick start
68
39
 
69
40
  ```bash
70
41
  kit init
71
- ```
72
42
 
73
- This will create the `.kitsune/` directory, multiple `.env` files, and the necessary Docker templates. Run it in your project's root directory.
43
+ # Edit .kitsune/config.yml first.
44
+ export DO_API_TOKEN="..."
74
45
 
75
- ---
76
-
77
- ## 🔧 Main Commands
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
- This creates a Droplet and executes:
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
- 1. `setup_user create`
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
- ### 🐳 Full Docker Installation
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
- This applies in order:
59
+ See [Getting started](docs/getting-started.md) for the complete first-run procedure.
100
60
 
101
- 1. `setup_docker_prereqs create`
102
- 2. `install_docker_engine create`
103
- 3. `postinstall_docker create`
61
+ ## Commands
104
62
 
105
- ### 🐘 Install PostgreSQL with Docker Compose
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
- ```bash
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
- It will provide you with a `DATABASE_URL` ready for Rails or any other app.
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
- ## ♻️ Rollback for Each Step
87
+ 1. `--env NAME`
88
+ 2. `KITSUNE_ENV`
89
+ 3. `.kitsune/environment`
90
+ 4. `development`
116
91
 
117
- Each command accepts the `--rollback` flag. For example:
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
- ```bash
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
- The same applies to any other subcommand, such as:
96
+ ## Security model
128
97
 
129
- ```bash
130
- kit bootstrap_docker execute --rollback --server-ip ...
131
- kit setup_postgres_docker rollback --server-ip ...
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
- ## 🌎 Support for Multiple Environments
108
+ ## PostgreSQL and Redis
137
109
 
138
- Use `switch_env` to change between environments:
110
+ Services are optional and disabled initially. Enable a service in configuration and export its configured secret:
139
111
 
140
112
  ```bash
141
- kit switch_env to production
113
+ export POSTGRES_PASSWORD="$(ruby -rsecurerandom -e 'print SecureRandom.base64(36)')"
114
+ kit service postgres install
142
115
  ```
143
116
 
144
- This updates `.kitsune/kit.env` and creates (if it doesn't exist) `.kitsune/infra.production.env`.
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
- ## 🔗 Integration with Kamal
121
+ ## CLI and optional TUI
149
122
 
150
- Once the server is configured:
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
- 1. Define your `kamal.yml` pointing to the created droplet
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
- # Initialize project structure
169
- kit init
130
+ kit plan --format json --no-input --no-color
131
+ kit apply --format json --no-input --yes
132
+ ```
170
133
 
171
- # Provision Droplet and configure everything
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
- # Install Docker
175
- kit bootstrap_docker execute --server-ip 123.123.123.123
136
+ ## Development
176
137
 
177
- # Set up the database
178
- kit setup_postgres_docker create --server-ip 123.123.123.123
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
- - [ ] Support for other providers (Hetzner)
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
- ## 🔐 Security
162
+ ## Roadmap and stability
191
163
 
192
- Never upload your `.env` files to public repositories. Kitsune does not encrypt them: it assumes you control your machine and your repo. Add `.kitsune/` to your project's `.gitignore`.
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
- ## 📄 License
168
+ ## License
197
169
 
198
- MIT License © [Omar Herrera / OmarHrra]
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
- require "bundler/setup"
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.