nvoi 0.1.5 → 0.1.7

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 (156) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/todo/refactor/00-overview.md +171 -0
  3. data/.claude/todo/refactor/01-objects.md +96 -0
  4. data/.claude/todo/refactor/02-utils.md +143 -0
  5. data/.claude/todo/refactor/03-external-cloud.md +164 -0
  6. data/.claude/todo/refactor/04-external-dns.md +104 -0
  7. data/.claude/todo/refactor/05-external.md +133 -0
  8. data/.claude/todo/refactor/06-cli.md +123 -0
  9. data/.claude/todo/refactor/07-cli-deploy-command.md +177 -0
  10. data/.claude/todo/refactor/08-cli-deploy-steps.md +201 -0
  11. data/.claude/todo/refactor/09-cli-delete-command.md +169 -0
  12. data/.claude/todo/refactor/10-cli-exec-command.md +157 -0
  13. data/.claude/todo/refactor/11-cli-credentials-command.md +190 -0
  14. data/.claude/todo/refactor/12-cli-db-command.md +128 -0
  15. data/.claude/todo/refactor/_target.md +79 -0
  16. data/.claude/todo/refactor-execution/00-entrypoint.md +49 -0
  17. data/.claude/todo/refactor-execution/01-objects.md +42 -0
  18. data/.claude/todo/refactor-execution/02-utils.md +41 -0
  19. data/.claude/todo/refactor-execution/03-external-cloud.md +38 -0
  20. data/.claude/todo/refactor-execution/04-external-dns.md +35 -0
  21. data/.claude/todo/refactor-execution/05-external-other.md +46 -0
  22. data/.claude/todo/refactor-execution/06-cli-deploy.md +45 -0
  23. data/.claude/todo/refactor-execution/07-cli-delete.md +43 -0
  24. data/.claude/todo/refactor-execution/08-cli-exec.md +30 -0
  25. data/.claude/todo/refactor-execution/09-cli-credentials.md +34 -0
  26. data/.claude/todo/refactor-execution/10-cli-db.md +31 -0
  27. data/.claude/todo/refactor-execution/11-cli-router.md +44 -0
  28. data/.claude/todo/refactor-execution/12-cleanup.md +120 -0
  29. data/.claude/todo/refactor-execution/_monitoring-strategy.md +126 -0
  30. data/.claude/todo/scaleway.impl.md +644 -0
  31. data/.claude/todo/scaleway.reference.md +520 -0
  32. data/.claude/todos.md +550 -0
  33. data/Gemfile +6 -0
  34. data/Gemfile.lock +46 -5
  35. data/Rakefile +1 -1
  36. data/doc/config-schema.yaml +44 -11
  37. data/examples/golang/deploy.enc +0 -0
  38. data/examples/golang/main.go +18 -0
  39. data/exe/nvoi +3 -1
  40. data/ingest +0 -0
  41. data/lib/nvoi/cli/config/command.rb +219 -0
  42. data/lib/nvoi/cli/credentials/edit/command.rb +384 -0
  43. data/lib/nvoi/cli/credentials/show/command.rb +35 -0
  44. data/lib/nvoi/cli/db/command.rb +308 -0
  45. data/lib/nvoi/cli/delete/command.rb +75 -0
  46. data/lib/nvoi/cli/delete/steps/detach_volumes.rb +98 -0
  47. data/lib/nvoi/cli/delete/steps/teardown_dns.rb +50 -0
  48. data/lib/nvoi/cli/delete/steps/teardown_firewall.rb +46 -0
  49. data/lib/nvoi/cli/delete/steps/teardown_network.rb +30 -0
  50. data/lib/nvoi/cli/delete/steps/teardown_server.rb +50 -0
  51. data/lib/nvoi/cli/delete/steps/teardown_tunnel.rb +44 -0
  52. data/lib/nvoi/cli/delete/steps/teardown_volume.rb +61 -0
  53. data/lib/nvoi/cli/deploy/command.rb +184 -0
  54. data/lib/nvoi/cli/deploy/steps/build_image.rb +27 -0
  55. data/lib/nvoi/cli/deploy/steps/cleanup_images.rb +42 -0
  56. data/lib/nvoi/cli/deploy/steps/configure_tunnel.rb +102 -0
  57. data/lib/nvoi/cli/deploy/steps/deploy_service.rb +399 -0
  58. data/lib/nvoi/cli/deploy/steps/provision_network.rb +44 -0
  59. data/lib/nvoi/cli/deploy/steps/provision_server.rb +143 -0
  60. data/lib/nvoi/cli/deploy/steps/provision_volume.rb +171 -0
  61. data/lib/nvoi/cli/deploy/steps/setup_k3s.rb +490 -0
  62. data/lib/nvoi/cli/exec/command.rb +173 -0
  63. data/lib/nvoi/cli/logs/command.rb +66 -0
  64. data/lib/nvoi/cli/onboard/command.rb +761 -0
  65. data/lib/nvoi/cli/unlock/command.rb +72 -0
  66. data/lib/nvoi/cli.rb +339 -141
  67. data/lib/nvoi/config_api/actions/app.rb +53 -0
  68. data/lib/nvoi/config_api/actions/compute_provider.rb +55 -0
  69. data/lib/nvoi/config_api/actions/database.rb +70 -0
  70. data/lib/nvoi/config_api/actions/domain_provider.rb +40 -0
  71. data/lib/nvoi/config_api/actions/env.rb +32 -0
  72. data/lib/nvoi/config_api/actions/init.rb +67 -0
  73. data/lib/nvoi/config_api/actions/secret.rb +32 -0
  74. data/lib/nvoi/config_api/actions/server.rb +66 -0
  75. data/lib/nvoi/config_api/actions/service.rb +52 -0
  76. data/lib/nvoi/config_api/actions/volume.rb +40 -0
  77. data/lib/nvoi/config_api/base.rb +38 -0
  78. data/lib/nvoi/config_api/result.rb +26 -0
  79. data/lib/nvoi/config_api.rb +93 -0
  80. data/lib/nvoi/errors.rb +68 -50
  81. data/lib/nvoi/external/cloud/aws.rb +450 -0
  82. data/lib/nvoi/external/cloud/base.rb +99 -0
  83. data/lib/nvoi/external/cloud/factory.rb +48 -0
  84. data/lib/nvoi/external/cloud/hetzner.rb +402 -0
  85. data/lib/nvoi/external/cloud/scaleway.rb +559 -0
  86. data/lib/nvoi/external/cloud.rb +15 -0
  87. data/lib/nvoi/external/containerd.rb +86 -0
  88. data/lib/nvoi/external/database/mysql.rb +84 -0
  89. data/lib/nvoi/external/database/postgres.rb +82 -0
  90. data/lib/nvoi/external/database/provider.rb +65 -0
  91. data/lib/nvoi/external/database/sqlite.rb +72 -0
  92. data/lib/nvoi/external/database.rb +22 -0
  93. data/lib/nvoi/external/dns/cloudflare.rb +310 -0
  94. data/lib/nvoi/external/kubectl.rb +65 -0
  95. data/lib/nvoi/external/ssh.rb +106 -0
  96. data/lib/nvoi/objects/config_override.rb +60 -0
  97. data/lib/nvoi/objects/configuration.rb +483 -0
  98. data/lib/nvoi/objects/database.rb +56 -0
  99. data/lib/nvoi/objects/dns.rb +14 -0
  100. data/lib/nvoi/objects/firewall.rb +11 -0
  101. data/lib/nvoi/objects/network.rb +11 -0
  102. data/lib/nvoi/objects/server.rb +14 -0
  103. data/lib/nvoi/objects/service_spec.rb +26 -0
  104. data/lib/nvoi/objects/tunnel.rb +14 -0
  105. data/lib/nvoi/objects/volume.rb +17 -0
  106. data/lib/nvoi/utils/config_loader.rb +172 -0
  107. data/lib/nvoi/utils/constants.rb +61 -0
  108. data/lib/nvoi/{credentials/manager.rb → utils/credential_store.rb} +16 -16
  109. data/lib/nvoi/{credentials → utils}/crypto.rb +8 -5
  110. data/lib/nvoi/{config → utils}/env_resolver.rb +10 -2
  111. data/lib/nvoi/utils/logger.rb +84 -0
  112. data/lib/nvoi/{config/naming.rb → utils/namer.rb} +37 -25
  113. data/lib/nvoi/{deployer → utils}/retry.rb +23 -3
  114. data/lib/nvoi/utils/templates.rb +62 -0
  115. data/lib/nvoi/version.rb +1 -1
  116. data/lib/nvoi.rb +27 -55
  117. data/templates/app-ingress.yaml.erb +3 -1
  118. data/templates/error-backend.yaml.erb +134 -0
  119. metadata +121 -44
  120. data/examples/golang/deploy.yml +0 -54
  121. data/lib/nvoi/cloudflare/client.rb +0 -287
  122. data/lib/nvoi/config/config.rb +0 -248
  123. data/lib/nvoi/config/loader.rb +0 -102
  124. data/lib/nvoi/config/ssh_keys.rb +0 -82
  125. data/lib/nvoi/config/types.rb +0 -274
  126. data/lib/nvoi/constants.rb +0 -59
  127. data/lib/nvoi/credentials/editor.rb +0 -272
  128. data/lib/nvoi/deployer/cleaner.rb +0 -36
  129. data/lib/nvoi/deployer/image_builder.rb +0 -23
  130. data/lib/nvoi/deployer/infrastructure.rb +0 -126
  131. data/lib/nvoi/deployer/orchestrator.rb +0 -146
  132. data/lib/nvoi/deployer/service_deployer.rb +0 -311
  133. data/lib/nvoi/deployer/tunnel_manager.rb +0 -57
  134. data/lib/nvoi/deployer/types.rb +0 -8
  135. data/lib/nvoi/k8s/renderer.rb +0 -44
  136. data/lib/nvoi/k8s/templates.rb +0 -29
  137. data/lib/nvoi/logger.rb +0 -72
  138. data/lib/nvoi/providers/aws.rb +0 -403
  139. data/lib/nvoi/providers/base.rb +0 -111
  140. data/lib/nvoi/providers/hetzner.rb +0 -288
  141. data/lib/nvoi/providers/hetzner_client.rb +0 -170
  142. data/lib/nvoi/remote/docker_manager.rb +0 -203
  143. data/lib/nvoi/remote/ssh_executor.rb +0 -72
  144. data/lib/nvoi/remote/volume_manager.rb +0 -103
  145. data/lib/nvoi/service/delete.rb +0 -234
  146. data/lib/nvoi/service/deploy.rb +0 -80
  147. data/lib/nvoi/service/exec.rb +0 -144
  148. data/lib/nvoi/service/provider.rb +0 -36
  149. data/lib/nvoi/steps/application_deployer.rb +0 -26
  150. data/lib/nvoi/steps/database_provisioner.rb +0 -60
  151. data/lib/nvoi/steps/k3s_cluster_setup.rb +0 -105
  152. data/lib/nvoi/steps/k3s_provisioner.rb +0 -351
  153. data/lib/nvoi/steps/server_provisioner.rb +0 -43
  154. data/lib/nvoi/steps/services_provisioner.rb +0 -29
  155. data/lib/nvoi/steps/tunnel_configurator.rb +0 -66
  156. data/lib/nvoi/steps/volume_provisioner.rb +0 -154
@@ -1,154 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Nvoi
4
- module Steps
5
- # VolumeProvisioner handles provisioning of block storage volumes
6
- class VolumeProvisioner
7
- def initialize(config, provider, log)
8
- @config = config
9
- @provider = provider
10
- @log = log
11
- @namer = config.namer
12
- end
13
-
14
- def run
15
- volumes_to_provision = collect_volumes
16
- return if volumes_to_provision.empty?
17
-
18
- @log.info "Provisioning %d volume(s)", volumes_to_provision.size
19
-
20
- volumes_to_provision.each do |vol_config|
21
- provision_volume(vol_config)
22
- end
23
-
24
- @log.success "All volumes provisioned"
25
- end
26
-
27
- private
28
-
29
- def collect_volumes
30
- volumes = []
31
-
32
- # Database volume
33
- db = @config.deploy.application.database
34
- if db&.volume && !db.volume.empty?
35
- server_name = resolve_server_name(db.servers)
36
- volumes << {
37
- name: @namer.database_volume_name,
38
- server_name:,
39
- mount_path: "/opt/nvoi/volumes/#{@namer.database_volume_name}",
40
- size: 10
41
- }
42
- end
43
-
44
- # Service volumes
45
- @config.deploy.application.services.each do |svc_name, svc|
46
- next unless svc&.volume && !svc.volume.empty?
47
-
48
- server_name = resolve_server_name(svc.servers)
49
- vol_name = @namer.service_volume_name(svc_name, "data")
50
- volumes << {
51
- name: vol_name,
52
- server_name:,
53
- mount_path: "/opt/nvoi/volumes/#{vol_name}",
54
- size: 10
55
- }
56
- end
57
-
58
- # App volumes
59
- @config.deploy.application.app.each do |app_name, app|
60
- next unless app&.volumes && !app.volumes.empty?
61
-
62
- server_name = resolve_server_name(app.servers)
63
- app.volumes.each_key do |vol_key|
64
- vol_name = @namer.app_volume_name(app_name, vol_key)
65
- volumes << {
66
- name: vol_name,
67
- server_name:,
68
- mount_path: "/opt/nvoi/volumes/#{vol_name}",
69
- size: 10
70
- }
71
- end
72
- end
73
-
74
- volumes
75
- end
76
-
77
- def resolve_server_name(servers)
78
- return @config.server_name if servers.nil? || servers.empty?
79
-
80
- # Use first server in the list
81
- group_name = servers.first
82
- @namer.server_name(group_name, 1)
83
- end
84
-
85
- def provision_volume(vol_config)
86
- @log.info "Provisioning volume: %s", vol_config[:name]
87
-
88
- # Check if volume already exists
89
- existing = @provider.get_volume_by_name(vol_config[:name])
90
- if existing
91
- @log.info "Volume already exists: %s", vol_config[:name]
92
- ensure_attached_and_mounted(existing, vol_config)
93
- return
94
- end
95
-
96
- # Find server to attach to
97
- server = @provider.find_server(vol_config[:server_name])
98
- raise VolumeError, "server not found: #{vol_config[:server_name]}" unless server
99
-
100
- # Create volume
101
- opts = Providers::VolumeCreateOptions.new(
102
- name: vol_config[:name],
103
- size: vol_config[:size],
104
- server_id: server.id
105
- )
106
- volume = @provider.create_volume(opts)
107
-
108
- # Attach volume
109
- @log.info "Attaching volume to server..."
110
- @provider.attach_volume(volume.id, server.id)
111
-
112
- # Mount volume on server (includes device wait)
113
- mount_volume(server.public_ipv4, volume, vol_config[:mount_path])
114
-
115
- @log.success "Volume provisioned and mounted: %s", vol_config[:name]
116
- end
117
-
118
- def ensure_attached_and_mounted(volume, vol_config)
119
- server = @provider.find_server(vol_config[:server_name])
120
- return unless server
121
-
122
- # Attach if not attached
123
- if volume.server_id.nil? || volume.server_id.empty?
124
- @log.info "Attaching existing volume..."
125
- @provider.attach_volume(volume.id, server.id)
126
- volume = @provider.get_volume(volume.id)
127
- end
128
-
129
- # Mount if not mounted
130
- mount_volume(server.public_ipv4, volume, vol_config[:mount_path])
131
- end
132
-
133
- def mount_volume(server_ip, volume, mount_path)
134
- ssh = Remote::SSHExecutor.new(server_ip, @config.ssh_key_path)
135
- volume_manager = Remote::VolumeManager.new(ssh)
136
-
137
- # Get device path (refreshed from provider)
138
- refreshed = @provider.get_volume(volume.id)
139
- device_path = refreshed&.device_path
140
-
141
- return unless device_path && !device_path.empty?
142
-
143
- @log.info "Mounting volume at %s", mount_path
144
-
145
- opts = Remote::MountOptions.new(
146
- device_path:,
147
- mount_path:,
148
- fs_type: "xfs"
149
- )
150
- volume_manager.mount(opts)
151
- end
152
- end
153
- end
154
- end