nvoi 0.1.7 → 0.2.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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -5
  3. data/Gemfile.lock +17 -8
  4. data/Rakefile +1 -1
  5. data/lib/nvoi/cli/config/command.rb +46 -41
  6. data/lib/nvoi/cli/credentials/edit/command.rb +20 -20
  7. data/lib/nvoi/cli/credentials/show/command.rb +1 -1
  8. data/lib/nvoi/cli/db/command.rb +10 -10
  9. data/lib/nvoi/cli/delete/command.rb +2 -2
  10. data/lib/nvoi/cli/deploy/command.rb +29 -13
  11. data/lib/nvoi/cli/deploy/steps/build_image.rb +48 -6
  12. data/lib/nvoi/cli/deploy/steps/configure_tunnel.rb +2 -2
  13. data/lib/nvoi/cli/deploy/steps/deploy_service.rb +3 -13
  14. data/lib/nvoi/cli/deploy/steps/provision_server.rb +1 -1
  15. data/lib/nvoi/cli/deploy/steps/provision_volume.rb +1 -1
  16. data/lib/nvoi/cli/exec/command.rb +3 -3
  17. data/lib/nvoi/cli/logs/command.rb +2 -2
  18. data/lib/nvoi/cli/onboard/command.rb +176 -622
  19. data/lib/nvoi/cli/onboard/steps/app.rb +108 -0
  20. data/lib/nvoi/cli/onboard/steps/app_name.rb +26 -0
  21. data/lib/nvoi/cli/onboard/steps/compute.rb +139 -0
  22. data/lib/nvoi/cli/onboard/steps/database.rb +97 -0
  23. data/lib/nvoi/cli/onboard/steps/domain.rb +48 -0
  24. data/lib/nvoi/cli/onboard/steps/env.rb +67 -0
  25. data/lib/nvoi/cli/onboard/ui.rb +84 -0
  26. data/lib/nvoi/cli/unlock/command.rb +2 -2
  27. data/lib/nvoi/cli.rb +0 -32
  28. data/lib/nvoi/configuration/app_service.rb +54 -0
  29. data/lib/nvoi/configuration/application.rb +44 -0
  30. data/lib/nvoi/configuration/builder.rb +417 -0
  31. data/lib/nvoi/configuration/database.rb +56 -0
  32. data/lib/nvoi/configuration/deploy.rb +15 -0
  33. data/lib/nvoi/{objects/service_spec.rb → configuration/deployment.rb} +4 -3
  34. data/lib/nvoi/{objects/config_override.rb → configuration/override.rb} +4 -4
  35. data/lib/nvoi/configuration/providers.rb +78 -0
  36. data/lib/nvoi/configuration/result.rb +43 -0
  37. data/lib/nvoi/configuration/root.rb +234 -0
  38. data/lib/nvoi/configuration/server.rb +39 -0
  39. data/lib/nvoi/configuration/service.rb +62 -0
  40. data/lib/nvoi/external/cloud/aws.rb +12 -12
  41. data/lib/nvoi/external/cloud/hetzner.rb +7 -7
  42. data/lib/nvoi/external/cloud/scaleway.rb +7 -7
  43. data/lib/nvoi/external/cloud/types.rb +42 -0
  44. data/lib/nvoi/external/containerd.rb +1 -48
  45. data/lib/nvoi/external/database/mysql.rb +1 -1
  46. data/lib/nvoi/external/database/postgres.rb +1 -1
  47. data/lib/nvoi/external/database/provider.rb +1 -1
  48. data/lib/nvoi/external/database/sqlite.rb +1 -1
  49. data/lib/nvoi/external/database/types.rb +55 -0
  50. data/lib/nvoi/external/dns/cloudflare.rb +6 -6
  51. data/lib/nvoi/external/dns/types.rb +24 -0
  52. data/lib/nvoi/external/ssh.rb +0 -12
  53. data/lib/nvoi/external/ssh_tunnel.rb +100 -0
  54. data/lib/nvoi/utils/config_loader.rb +12 -12
  55. data/lib/nvoi/utils/credential_store.rb +4 -4
  56. data/lib/nvoi/utils/env_resolver.rb +3 -3
  57. data/lib/nvoi/utils/namer.rb +2 -2
  58. data/lib/nvoi/utils/presence.rb +23 -0
  59. data/lib/nvoi/version.rb +1 -1
  60. data/lib/nvoi.rb +2 -17
  61. metadata +96 -57
  62. data/.claude/todo/refactor/00-overview.md +0 -171
  63. data/.claude/todo/refactor/01-objects.md +0 -96
  64. data/.claude/todo/refactor/02-utils.md +0 -143
  65. data/.claude/todo/refactor/03-external-cloud.md +0 -164
  66. data/.claude/todo/refactor/04-external-dns.md +0 -104
  67. data/.claude/todo/refactor/05-external.md +0 -133
  68. data/.claude/todo/refactor/06-cli.md +0 -123
  69. data/.claude/todo/refactor/07-cli-deploy-command.md +0 -177
  70. data/.claude/todo/refactor/08-cli-deploy-steps.md +0 -201
  71. data/.claude/todo/refactor/09-cli-delete-command.md +0 -169
  72. data/.claude/todo/refactor/10-cli-exec-command.md +0 -157
  73. data/.claude/todo/refactor/11-cli-credentials-command.md +0 -190
  74. data/.claude/todo/refactor/12-cli-db-command.md +0 -128
  75. data/.claude/todo/refactor/_target.md +0 -79
  76. data/.claude/todo/refactor-execution/00-entrypoint.md +0 -49
  77. data/.claude/todo/refactor-execution/01-objects.md +0 -42
  78. data/.claude/todo/refactor-execution/02-utils.md +0 -41
  79. data/.claude/todo/refactor-execution/03-external-cloud.md +0 -38
  80. data/.claude/todo/refactor-execution/04-external-dns.md +0 -35
  81. data/.claude/todo/refactor-execution/05-external-other.md +0 -46
  82. data/.claude/todo/refactor-execution/06-cli-deploy.md +0 -45
  83. data/.claude/todo/refactor-execution/07-cli-delete.md +0 -43
  84. data/.claude/todo/refactor-execution/08-cli-exec.md +0 -30
  85. data/.claude/todo/refactor-execution/09-cli-credentials.md +0 -34
  86. data/.claude/todo/refactor-execution/10-cli-db.md +0 -31
  87. data/.claude/todo/refactor-execution/11-cli-router.md +0 -44
  88. data/.claude/todo/refactor-execution/12-cleanup.md +0 -120
  89. data/.claude/todo/refactor-execution/_monitoring-strategy.md +0 -126
  90. data/.claude/todo/scaleway.impl.md +0 -644
  91. data/.claude/todo/scaleway.reference.md +0 -520
  92. data/.claude/todos.md +0 -550
  93. data/ingest +0 -0
  94. data/lib/nvoi/config_api/actions/app.rb +0 -53
  95. data/lib/nvoi/config_api/actions/compute_provider.rb +0 -55
  96. data/lib/nvoi/config_api/actions/database.rb +0 -70
  97. data/lib/nvoi/config_api/actions/domain_provider.rb +0 -40
  98. data/lib/nvoi/config_api/actions/env.rb +0 -32
  99. data/lib/nvoi/config_api/actions/init.rb +0 -67
  100. data/lib/nvoi/config_api/actions/secret.rb +0 -32
  101. data/lib/nvoi/config_api/actions/server.rb +0 -66
  102. data/lib/nvoi/config_api/actions/service.rb +0 -52
  103. data/lib/nvoi/config_api/actions/volume.rb +0 -40
  104. data/lib/nvoi/config_api/base.rb +0 -38
  105. data/lib/nvoi/config_api/result.rb +0 -26
  106. data/lib/nvoi/config_api.rb +0 -93
  107. data/lib/nvoi/objects/configuration.rb +0 -483
  108. data/lib/nvoi/objects/database.rb +0 -56
  109. data/lib/nvoi/objects/dns.rb +0 -14
  110. data/lib/nvoi/objects/firewall.rb +0 -11
  111. data/lib/nvoi/objects/network.rb +0 -11
  112. data/lib/nvoi/objects/server.rb +0 -14
  113. data/lib/nvoi/objects/tunnel.rb +0 -14
  114. data/lib/nvoi/objects/volume.rb +0 -17
data/lib/nvoi/cli.rb CHANGED
@@ -23,7 +23,6 @@ module Nvoi
23
23
 
24
24
  desc "onboard", "Interactive setup wizard"
25
25
  def onboard
26
- require_relative "cli/onboard/command"
27
26
  Cli::Onboard::Command.new.run
28
27
  end
29
28
 
@@ -31,20 +30,17 @@ module Nvoi
31
30
  option :dockerfile_path, desc: "Path to Dockerfile (optional, defaults to ./Dockerfile)"
32
31
  option :config_dir, desc: "Directory containing SSH keys (optional, defaults to ~/.ssh)"
33
32
  def deploy
34
- require_relative "cli/deploy/command"
35
33
  Cli::Deploy::Command.new(options).run
36
34
  end
37
35
 
38
36
  desc "delete", "Delete server, firewall, and network"
39
37
  option :config_dir, desc: "Directory containing SSH keys (optional, defaults to ~/.ssh)"
40
38
  def delete
41
- require_relative "cli/delete/command"
42
39
  Cli::Delete::Command.new(options).run
43
40
  end
44
41
 
45
42
  desc "unlock", "Remove deployment lock (use when deploy hangs)"
46
43
  def unlock
47
- require_relative "cli/unlock/command"
48
44
  Cli::Unlock::Command.new(options).run
49
45
  end
50
46
 
@@ -52,7 +48,6 @@ module Nvoi
52
48
  option :follow, aliases: "-f", type: :boolean, default: false, desc: "Follow log output"
53
49
  option :tail, aliases: "-n", type: :numeric, default: 100, desc: "Number of lines to show"
54
50
  def logs(app_name)
55
- require_relative "cli/logs/command"
56
51
  Cli::Logs::Command.new(options).run(app_name)
57
52
  end
58
53
 
@@ -62,7 +57,6 @@ module Nvoi
62
57
  option :interactive, aliases: "-i", type: :boolean, default: false,
63
58
  desc: "Open interactive SSH shell instead of executing command"
64
59
  def exec(*args)
65
- require_relative "cli/exec/command"
66
60
  Cli::Exec::Command.new(options).run(args)
67
61
  end
68
62
 
@@ -78,19 +72,16 @@ module Nvoi
78
72
 
79
73
  desc "edit", "Edit encrypted credentials"
80
74
  def edit
81
- require_relative "cli/credentials/edit/command"
82
75
  Nvoi::Cli::Credentials::Edit::Command.new(options).run
83
76
  end
84
77
 
85
78
  desc "show", "Show decrypted credentials"
86
79
  def show
87
- require_relative "cli/credentials/show/command"
88
80
  Nvoi::Cli::Credentials::Show::Command.new(options).run
89
81
  end
90
82
 
91
83
  desc "set PATH VALUE", "Set a value at a dot-notation path"
92
84
  def set(path, value)
93
- require_relative "cli/credentials/edit/command"
94
85
  Nvoi::Cli::Credentials::Edit::Command.new(options).set(path, value)
95
86
  end
96
87
  }
@@ -109,7 +100,6 @@ module Nvoi
109
100
  option :name, required: true, desc: "Application name"
110
101
  option :environment, default: "production", desc: "Environment"
111
102
  def init
112
- require_relative "cli/config/command"
113
103
  Nvoi::Cli::Config::Command.new(options).init(options[:name], options[:environment])
114
104
  end
115
105
 
@@ -132,7 +122,6 @@ module Nvoi
132
122
  option :project_id, desc: "Scaleway project ID"
133
123
  option :zone, desc: "Scaleway zone"
134
124
  def set(provider)
135
- require_relative "cli/config/command"
136
125
  Nvoi::Cli::Config::Command.new(options).provider_set(provider, **options.slice(
137
126
  :api_token, :server_type, :server_location,
138
127
  :access_key_id, :secret_access_key, :region, :instance_type,
@@ -142,7 +131,6 @@ module Nvoi
142
131
 
143
132
  desc "rm", "Remove compute provider"
144
133
  def rm
145
- require_relative "cli/config/command"
146
134
  Nvoi::Cli::Config::Command.new(options).provider_rm
147
135
  end
148
136
  }
@@ -158,13 +146,11 @@ module Nvoi
158
146
  option :api_token, required: true, desc: "API token"
159
147
  option :account_id, required: true, desc: "Account ID"
160
148
  def set(provider)
161
- require_relative "cli/config/command"
162
149
  Nvoi::Cli::Config::Command.new(options).domain_set(provider, api_token: options[:api_token], account_id: options[:account_id])
163
150
  end
164
151
 
165
152
  desc "rm", "Remove domain provider"
166
153
  def rm
167
- require_relative "cli/config/command"
168
154
  Nvoi::Cli::Config::Command.new(options).domain_rm
169
155
  end
170
156
  }
@@ -182,13 +168,11 @@ module Nvoi
182
168
  option :location, desc: "Location override"
183
169
  option :count, type: :numeric, default: 1, desc: "Number of servers"
184
170
  def set(name)
185
- require_relative "cli/config/command"
186
171
  Nvoi::Cli::Config::Command.new(options).server_set(name, master: options[:master], type: options[:type], location: options[:location], count: options[:count])
187
172
  end
188
173
 
189
174
  desc "rm NAME", "Remove server"
190
175
  def rm(name)
191
- require_relative "cli/config/command"
192
176
  Nvoi::Cli::Config::Command.new(options).server_rm(name)
193
177
  end
194
178
  }
@@ -203,13 +187,11 @@ module Nvoi
203
187
  desc "set SERVER NAME", "Add or update volume"
204
188
  option :size, type: :numeric, default: 10, desc: "Volume size in GB"
205
189
  def set(server, name)
206
- require_relative "cli/config/command"
207
190
  Nvoi::Cli::Config::Command.new(options).volume_set(server, name, size: options[:size])
208
191
  end
209
192
 
210
193
  desc "rm SERVER NAME", "Remove volume"
211
194
  def rm(server, name)
212
- require_relative "cli/config/command"
213
195
  Nvoi::Cli::Config::Command.new(options).volume_rm(server, name)
214
196
  end
215
197
  }
@@ -229,13 +211,11 @@ module Nvoi
229
211
  option :command, desc: "Run command"
230
212
  option :pre_run_command, desc: "Pre-run command (migrations, etc)"
231
213
  def set(name)
232
- require_relative "cli/config/command"
233
214
  Nvoi::Cli::Config::Command.new(options).app_set(name, **options.slice(:servers, :domain, :subdomain, :port, :command, :pre_run_command).transform_keys(&:to_sym).compact)
234
215
  end
235
216
 
236
217
  desc "rm NAME", "Remove app"
237
218
  def rm(name)
238
- require_relative "cli/config/command"
239
219
  Nvoi::Cli::Config::Command.new(options).app_rm(name)
240
220
  end
241
221
  }
@@ -256,13 +236,11 @@ module Nvoi
256
236
  option :url, desc: "Database URL (alternative to user/pass/db)"
257
237
  option :image, desc: "Custom Docker image"
258
238
  def set
259
- require_relative "cli/config/command"
260
239
  Nvoi::Cli::Config::Command.new(options).database_set(**options.slice(:servers, :adapter, :user, :password, :database, :url, :image).transform_keys(&:to_sym).compact)
261
240
  end
262
241
 
263
242
  desc "rm", "Remove database"
264
243
  def rm
265
- require_relative "cli/config/command"
266
244
  Nvoi::Cli::Config::Command.new(options).database_rm
267
245
  end
268
246
  }
@@ -280,13 +258,11 @@ module Nvoi
280
258
  option :port, type: :numeric, desc: "Port"
281
259
  option :command, desc: "Command"
282
260
  def set(name)
283
- require_relative "cli/config/command"
284
261
  Nvoi::Cli::Config::Command.new(options).service_set(name, **options.slice(:servers, :image, :port, :command).transform_keys(&:to_sym).compact)
285
262
  end
286
263
 
287
264
  desc "rm NAME", "Remove service"
288
265
  def rm(name)
289
- require_relative "cli/config/command"
290
266
  Nvoi::Cli::Config::Command.new(options).service_rm(name)
291
267
  end
292
268
  }
@@ -300,13 +276,11 @@ module Nvoi
300
276
 
301
277
  desc "set KEY VALUE", "Set secret"
302
278
  def set(key, value)
303
- require_relative "cli/config/command"
304
279
  Nvoi::Cli::Config::Command.new(options).secret_set(key, value)
305
280
  end
306
281
 
307
282
  desc "rm KEY", "Remove secret"
308
283
  def rm(key)
309
- require_relative "cli/config/command"
310
284
  Nvoi::Cli::Config::Command.new(options).secret_rm(key)
311
285
  end
312
286
  }
@@ -320,13 +294,11 @@ module Nvoi
320
294
 
321
295
  desc "set KEY VALUE", "Set environment variable"
322
296
  def set(key, value)
323
- require_relative "cli/config/command"
324
297
  Nvoi::Cli::Config::Command.new(options).env_set(key, value)
325
298
  end
326
299
 
327
300
  desc "rm KEY", "Remove environment variable"
328
301
  def rm(key)
329
- require_relative "cli/config/command"
330
302
  Nvoi::Cli::Config::Command.new(options).env_rm(key)
331
303
  end
332
304
  }
@@ -360,26 +332,22 @@ module Nvoi
360
332
 
361
333
  desc "create [NAME]", "Create a new database branch (snapshot)"
362
334
  def create(name = nil)
363
- require_relative "cli/db/command"
364
335
  Nvoi::Cli::Db::Command.new(options).branch_create(name)
365
336
  end
366
337
 
367
338
  desc "list", "List all database branches"
368
339
  def list
369
- require_relative "cli/db/command"
370
340
  Nvoi::Cli::Db::Command.new(options).branch_list
371
341
  end
372
342
 
373
343
  desc "restore ID [NEW_DB_NAME]", "Restore a database branch to a new database"
374
344
  def restore(branch_id, new_db_name = nil)
375
- require_relative "cli/db/command"
376
345
  Nvoi::Cli::Db::Command.new(options).branch_restore(branch_id, new_db_name)
377
346
  end
378
347
 
379
348
  desc "download ID", "Download a database branch dump"
380
349
  option :path, aliases: "-p", desc: "Output file path (default: {branch_id}.sql)"
381
350
  def download(branch_id)
382
- require_relative "cli/db/command"
383
351
  Nvoi::Cli::Db::Command.new(options).branch_download(branch_id)
384
352
  end
385
353
  }
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nvoi
4
+ module Configuration
5
+ # AppService defines a service in the app section
6
+ class AppService
7
+ attr_accessor :servers, :domain, :subdomain, :port, :healthcheck,
8
+ :command, :pre_run_command, :env, :mounts
9
+
10
+ def initialize(data = nil)
11
+ data ||= {}
12
+ @servers = data["servers"] || []
13
+ @domain = data["domain"]
14
+ @subdomain = data["subdomain"]
15
+ @port = data["port"]&.to_i
16
+ @healthcheck = data["healthcheck"] ? HealthCheck.new(data["healthcheck"]) : nil
17
+ @command = data["command"]
18
+ @pre_run_command = data["pre_run_command"]
19
+ @env = data["env"] || {}
20
+ @mounts = data["mounts"] || {}
21
+ end
22
+
23
+ def web?
24
+ @port && @port.positive?
25
+ end
26
+
27
+ def worker?
28
+ !web?
29
+ end
30
+
31
+ def fqdn
32
+ return nil if @domain.blank?
33
+
34
+ @subdomain.blank? ? @domain : "#{@subdomain}.#{@domain}"
35
+ end
36
+
37
+ # HealthCheck defines health check configuration
38
+ class HealthCheck
39
+ attr_accessor :type, :path, :port, :command, :interval, :timeout, :retries
40
+
41
+ def initialize(data = nil)
42
+ data ||= {}
43
+ @type = data["type"]
44
+ @path = data["path"]
45
+ @port = data["port"]&.to_i
46
+ @command = data["command"]
47
+ @interval = data["interval"]
48
+ @timeout = data["timeout"]
49
+ @retries = data["retries"]&.to_i
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nvoi
4
+ module Configuration
5
+ # Application contains application-level configuration
6
+ class Application
7
+ attr_accessor :name, :environment, :domain_provider, :compute_provider,
8
+ :keep_count, :servers, :app, :database, :services, :env,
9
+ :secrets, :ssh_keys
10
+
11
+ def initialize(data = nil)
12
+ data ||= {}
13
+ @name = data["name"]
14
+ @environment = data["environment"] || "production"
15
+ @domain_provider = Providers::DomainProvider.new(data["domain_provider"])
16
+ @compute_provider = Providers::ComputeProvider.new(data["compute_provider"])
17
+ @keep_count = data["keep_count"]&.to_i
18
+ @servers = (data["servers"] || {}).transform_values { |v| Server.new(v) }
19
+ @app = (data["app"] || {}).transform_values { |v| AppService.new(v) }
20
+ @database = data["database"] ? Database.new(data["database"]) : nil
21
+ @services = (data["services"] || {}).transform_values { |v| Service.new(v) }
22
+ @env = data["env"] || {}
23
+ @secrets = data["secrets"] || {}
24
+ @ssh_keys = data["ssh_keys"] ? SshKey.new(data["ssh_keys"]) : nil
25
+ end
26
+
27
+ def app_by_name(name)
28
+ @app[name.to_s]
29
+ end
30
+
31
+ def server_by_name(name)
32
+ @servers[name.to_s]
33
+ end
34
+
35
+ def web_apps
36
+ @app.select { |_, cfg| cfg.web? }
37
+ end
38
+
39
+ def workers
40
+ @app.reject { |_, cfg| cfg.web? }
41
+ end
42
+ end
43
+ end
44
+ end