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.
- checksums.yaml +4 -4
- data/.claude/todo/refactor/00-overview.md +171 -0
- data/.claude/todo/refactor/01-objects.md +96 -0
- data/.claude/todo/refactor/02-utils.md +143 -0
- data/.claude/todo/refactor/03-external-cloud.md +164 -0
- data/.claude/todo/refactor/04-external-dns.md +104 -0
- data/.claude/todo/refactor/05-external.md +133 -0
- data/.claude/todo/refactor/06-cli.md +123 -0
- data/.claude/todo/refactor/07-cli-deploy-command.md +177 -0
- data/.claude/todo/refactor/08-cli-deploy-steps.md +201 -0
- data/.claude/todo/refactor/09-cli-delete-command.md +169 -0
- data/.claude/todo/refactor/10-cli-exec-command.md +157 -0
- data/.claude/todo/refactor/11-cli-credentials-command.md +190 -0
- data/.claude/todo/refactor/12-cli-db-command.md +128 -0
- data/.claude/todo/refactor/_target.md +79 -0
- data/.claude/todo/refactor-execution/00-entrypoint.md +49 -0
- data/.claude/todo/refactor-execution/01-objects.md +42 -0
- data/.claude/todo/refactor-execution/02-utils.md +41 -0
- data/.claude/todo/refactor-execution/03-external-cloud.md +38 -0
- data/.claude/todo/refactor-execution/04-external-dns.md +35 -0
- data/.claude/todo/refactor-execution/05-external-other.md +46 -0
- data/.claude/todo/refactor-execution/06-cli-deploy.md +45 -0
- data/.claude/todo/refactor-execution/07-cli-delete.md +43 -0
- data/.claude/todo/refactor-execution/08-cli-exec.md +30 -0
- data/.claude/todo/refactor-execution/09-cli-credentials.md +34 -0
- data/.claude/todo/refactor-execution/10-cli-db.md +31 -0
- data/.claude/todo/refactor-execution/11-cli-router.md +44 -0
- data/.claude/todo/refactor-execution/12-cleanup.md +120 -0
- data/.claude/todo/refactor-execution/_monitoring-strategy.md +126 -0
- data/.claude/todo/scaleway.impl.md +644 -0
- data/.claude/todo/scaleway.reference.md +520 -0
- data/.claude/todos.md +550 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +46 -5
- data/Rakefile +1 -1
- data/doc/config-schema.yaml +44 -11
- data/examples/golang/deploy.enc +0 -0
- data/examples/golang/main.go +18 -0
- data/exe/nvoi +3 -1
- data/ingest +0 -0
- data/lib/nvoi/cli/config/command.rb +219 -0
- data/lib/nvoi/cli/credentials/edit/command.rb +384 -0
- data/lib/nvoi/cli/credentials/show/command.rb +35 -0
- data/lib/nvoi/cli/db/command.rb +308 -0
- data/lib/nvoi/cli/delete/command.rb +75 -0
- data/lib/nvoi/cli/delete/steps/detach_volumes.rb +98 -0
- data/lib/nvoi/cli/delete/steps/teardown_dns.rb +50 -0
- data/lib/nvoi/cli/delete/steps/teardown_firewall.rb +46 -0
- data/lib/nvoi/cli/delete/steps/teardown_network.rb +30 -0
- data/lib/nvoi/cli/delete/steps/teardown_server.rb +50 -0
- data/lib/nvoi/cli/delete/steps/teardown_tunnel.rb +44 -0
- data/lib/nvoi/cli/delete/steps/teardown_volume.rb +61 -0
- data/lib/nvoi/cli/deploy/command.rb +184 -0
- data/lib/nvoi/cli/deploy/steps/build_image.rb +27 -0
- data/lib/nvoi/cli/deploy/steps/cleanup_images.rb +42 -0
- data/lib/nvoi/cli/deploy/steps/configure_tunnel.rb +102 -0
- data/lib/nvoi/cli/deploy/steps/deploy_service.rb +399 -0
- data/lib/nvoi/cli/deploy/steps/provision_network.rb +44 -0
- data/lib/nvoi/cli/deploy/steps/provision_server.rb +143 -0
- data/lib/nvoi/cli/deploy/steps/provision_volume.rb +171 -0
- data/lib/nvoi/cli/deploy/steps/setup_k3s.rb +490 -0
- data/lib/nvoi/cli/exec/command.rb +173 -0
- data/lib/nvoi/cli/logs/command.rb +66 -0
- data/lib/nvoi/cli/onboard/command.rb +761 -0
- data/lib/nvoi/cli/unlock/command.rb +72 -0
- data/lib/nvoi/cli.rb +339 -141
- data/lib/nvoi/config_api/actions/app.rb +53 -0
- data/lib/nvoi/config_api/actions/compute_provider.rb +55 -0
- data/lib/nvoi/config_api/actions/database.rb +70 -0
- data/lib/nvoi/config_api/actions/domain_provider.rb +40 -0
- data/lib/nvoi/config_api/actions/env.rb +32 -0
- data/lib/nvoi/config_api/actions/init.rb +67 -0
- data/lib/nvoi/config_api/actions/secret.rb +32 -0
- data/lib/nvoi/config_api/actions/server.rb +66 -0
- data/lib/nvoi/config_api/actions/service.rb +52 -0
- data/lib/nvoi/config_api/actions/volume.rb +40 -0
- data/lib/nvoi/config_api/base.rb +38 -0
- data/lib/nvoi/config_api/result.rb +26 -0
- data/lib/nvoi/config_api.rb +93 -0
- data/lib/nvoi/errors.rb +68 -50
- data/lib/nvoi/external/cloud/aws.rb +450 -0
- data/lib/nvoi/external/cloud/base.rb +99 -0
- data/lib/nvoi/external/cloud/factory.rb +48 -0
- data/lib/nvoi/external/cloud/hetzner.rb +402 -0
- data/lib/nvoi/external/cloud/scaleway.rb +559 -0
- data/lib/nvoi/external/cloud.rb +15 -0
- data/lib/nvoi/external/containerd.rb +86 -0
- data/lib/nvoi/external/database/mysql.rb +84 -0
- data/lib/nvoi/external/database/postgres.rb +82 -0
- data/lib/nvoi/external/database/provider.rb +65 -0
- data/lib/nvoi/external/database/sqlite.rb +72 -0
- data/lib/nvoi/external/database.rb +22 -0
- data/lib/nvoi/external/dns/cloudflare.rb +310 -0
- data/lib/nvoi/external/kubectl.rb +65 -0
- data/lib/nvoi/external/ssh.rb +106 -0
- data/lib/nvoi/objects/config_override.rb +60 -0
- data/lib/nvoi/objects/configuration.rb +483 -0
- data/lib/nvoi/objects/database.rb +56 -0
- data/lib/nvoi/objects/dns.rb +14 -0
- data/lib/nvoi/objects/firewall.rb +11 -0
- data/lib/nvoi/objects/network.rb +11 -0
- data/lib/nvoi/objects/server.rb +14 -0
- data/lib/nvoi/objects/service_spec.rb +26 -0
- data/lib/nvoi/objects/tunnel.rb +14 -0
- data/lib/nvoi/objects/volume.rb +17 -0
- data/lib/nvoi/utils/config_loader.rb +172 -0
- data/lib/nvoi/utils/constants.rb +61 -0
- data/lib/nvoi/{credentials/manager.rb → utils/credential_store.rb} +16 -16
- data/lib/nvoi/{credentials → utils}/crypto.rb +8 -5
- data/lib/nvoi/{config → utils}/env_resolver.rb +10 -2
- data/lib/nvoi/utils/logger.rb +84 -0
- data/lib/nvoi/{config/naming.rb → utils/namer.rb} +37 -25
- data/lib/nvoi/{deployer → utils}/retry.rb +23 -3
- data/lib/nvoi/utils/templates.rb +62 -0
- data/lib/nvoi/version.rb +1 -1
- data/lib/nvoi.rb +27 -55
- data/templates/app-ingress.yaml.erb +3 -1
- data/templates/error-backend.yaml.erb +134 -0
- metadata +121 -44
- data/examples/golang/deploy.yml +0 -54
- data/lib/nvoi/cloudflare/client.rb +0 -287
- data/lib/nvoi/config/config.rb +0 -248
- data/lib/nvoi/config/loader.rb +0 -102
- data/lib/nvoi/config/ssh_keys.rb +0 -82
- data/lib/nvoi/config/types.rb +0 -274
- data/lib/nvoi/constants.rb +0 -59
- data/lib/nvoi/credentials/editor.rb +0 -272
- data/lib/nvoi/deployer/cleaner.rb +0 -36
- data/lib/nvoi/deployer/image_builder.rb +0 -23
- data/lib/nvoi/deployer/infrastructure.rb +0 -126
- data/lib/nvoi/deployer/orchestrator.rb +0 -146
- data/lib/nvoi/deployer/service_deployer.rb +0 -311
- data/lib/nvoi/deployer/tunnel_manager.rb +0 -57
- data/lib/nvoi/deployer/types.rb +0 -8
- data/lib/nvoi/k8s/renderer.rb +0 -44
- data/lib/nvoi/k8s/templates.rb +0 -29
- data/lib/nvoi/logger.rb +0 -72
- data/lib/nvoi/providers/aws.rb +0 -403
- data/lib/nvoi/providers/base.rb +0 -111
- data/lib/nvoi/providers/hetzner.rb +0 -288
- data/lib/nvoi/providers/hetzner_client.rb +0 -170
- data/lib/nvoi/remote/docker_manager.rb +0 -203
- data/lib/nvoi/remote/ssh_executor.rb +0 -72
- data/lib/nvoi/remote/volume_manager.rb +0 -103
- data/lib/nvoi/service/delete.rb +0 -234
- data/lib/nvoi/service/deploy.rb +0 -80
- data/lib/nvoi/service/exec.rb +0 -144
- data/lib/nvoi/service/provider.rb +0 -36
- data/lib/nvoi/steps/application_deployer.rb +0 -26
- data/lib/nvoi/steps/database_provisioner.rb +0 -60
- data/lib/nvoi/steps/k3s_cluster_setup.rb +0 -105
- data/lib/nvoi/steps/k3s_provisioner.rb +0 -351
- data/lib/nvoi/steps/server_provisioner.rb +0 -43
- data/lib/nvoi/steps/services_provisioner.rb +0 -29
- data/lib/nvoi/steps/tunnel_configurator.rb +0 -66
- 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
|