nvoi 0.1.5 → 0.1.6
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/_target.md +79 -0
- data/.claude/todo/scaleway.impl.md +644 -0
- data/.claude/todo/scaleway.reference.md +520 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +12 -2
- 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/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 +49 -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 +100 -0
- data/lib/nvoi/cli/deploy/steps/deploy_service.rb +396 -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 +481 -0
- data/lib/nvoi/cli/exec/command.rb +173 -0
- data/lib/nvoi/cli.rb +83 -142
- 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/env.rb +32 -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/volume.rb +40 -0
- data/lib/nvoi/config_api/base.rb +44 -0
- data/lib/nvoi/config_api/result.rb +26 -0
- data/lib/nvoi/config_api.rb +70 -0
- data/lib/nvoi/errors.rb +68 -50
- data/lib/nvoi/external/cloud/aws.rb +425 -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 +376 -0
- data/lib/nvoi/external/cloud/scaleway.rb +533 -0
- data/lib/nvoi/external/cloud.rb +15 -0
- data/lib/nvoi/external/containerd.rb +82 -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 +292 -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 +463 -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} +28 -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 +10 -54
- data/templates/error-backend.yaml.erb +134 -0
- metadata +97 -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
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nvoi
|
|
4
|
+
module ConfigApi
|
|
5
|
+
module Actions
|
|
6
|
+
class SetServer < Base
|
|
7
|
+
protected
|
|
8
|
+
|
|
9
|
+
def mutate(data, name:, master: false, type: nil, location: nil, count: 1)
|
|
10
|
+
raise ArgumentError, "name is required" if name.nil? || name.to_s.empty?
|
|
11
|
+
raise ArgumentError, "count must be positive" if count && count < 1
|
|
12
|
+
|
|
13
|
+
app(data)["servers"] ||= {}
|
|
14
|
+
app(data)["servers"][name.to_s] = {
|
|
15
|
+
"master" => master,
|
|
16
|
+
"type" => type,
|
|
17
|
+
"location" => location,
|
|
18
|
+
"count" => count
|
|
19
|
+
}.compact
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class DeleteServer < Base
|
|
24
|
+
protected
|
|
25
|
+
|
|
26
|
+
def mutate(data, name:)
|
|
27
|
+
raise ArgumentError, "name is required" if name.nil? || name.to_s.empty?
|
|
28
|
+
|
|
29
|
+
servers = app(data)["servers"] || {}
|
|
30
|
+
raise Errors::ConfigValidationError, "server '#{name}' not found" unless servers.key?(name.to_s)
|
|
31
|
+
|
|
32
|
+
servers.delete(name.to_s)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def validate(data)
|
|
36
|
+
check_orphaned_references(data)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def check_orphaned_references(data)
|
|
42
|
+
servers = (app(data)["servers"] || {}).keys
|
|
43
|
+
|
|
44
|
+
(app(data)["app"] || {}).each do |svc_name, svc|
|
|
45
|
+
(svc["servers"] || []).each do |ref|
|
|
46
|
+
raise Errors::ConfigValidationError, "app.#{svc_name} references non-existent server '#{ref}'" unless servers.include?(ref)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
db = app(data)["database"]
|
|
51
|
+
if db
|
|
52
|
+
(db["servers"] || []).each do |ref|
|
|
53
|
+
raise Errors::ConfigValidationError, "database references non-existent server '#{ref}'" unless servers.include?(ref)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
(app(data)["services"] || {}).each do |svc_name, svc|
|
|
58
|
+
(svc["servers"] || []).each do |ref|
|
|
59
|
+
raise Errors::ConfigValidationError, "services.#{svc_name} references non-existent server '#{ref}'" unless servers.include?(ref)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nvoi
|
|
4
|
+
module ConfigApi
|
|
5
|
+
module Actions
|
|
6
|
+
class SetVolume < Base
|
|
7
|
+
protected
|
|
8
|
+
|
|
9
|
+
def mutate(data, server:, name:, size: 10)
|
|
10
|
+
raise ArgumentError, "server is required" if server.nil? || server.to_s.empty?
|
|
11
|
+
raise ArgumentError, "name is required" if name.nil? || name.to_s.empty?
|
|
12
|
+
raise ArgumentError, "size must be positive" if size && size < 1
|
|
13
|
+
|
|
14
|
+
servers = app(data)["servers"] ||= {}
|
|
15
|
+
raise Errors::ConfigValidationError, "server '#{server}' not found" unless servers.key?(server.to_s)
|
|
16
|
+
|
|
17
|
+
servers[server.to_s]["volumes"] ||= {}
|
|
18
|
+
servers[server.to_s]["volumes"][name.to_s] = { "size" => size }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class DeleteVolume < Base
|
|
23
|
+
protected
|
|
24
|
+
|
|
25
|
+
def mutate(data, server:, name:)
|
|
26
|
+
raise ArgumentError, "server is required" if server.nil? || server.to_s.empty?
|
|
27
|
+
raise ArgumentError, "name is required" if name.nil? || name.to_s.empty?
|
|
28
|
+
|
|
29
|
+
servers = app(data)["servers"] || {}
|
|
30
|
+
raise Errors::ConfigValidationError, "server '#{server}' not found" unless servers.key?(server.to_s)
|
|
31
|
+
|
|
32
|
+
volumes = servers[server.to_s]["volumes"] || {}
|
|
33
|
+
raise Errors::ConfigValidationError, "volume '#{name}' not found on server '#{server}'" unless volumes.key?(name.to_s)
|
|
34
|
+
|
|
35
|
+
volumes.delete(name.to_s)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nvoi
|
|
4
|
+
module ConfigApi
|
|
5
|
+
class Base
|
|
6
|
+
def initialize(encrypted_config, master_key)
|
|
7
|
+
@encrypted_config = encrypted_config
|
|
8
|
+
@master_key = master_key
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call(**args)
|
|
12
|
+
yaml = Utils::Crypto.decrypt(@encrypted_config, @master_key)
|
|
13
|
+
@data = YAML.safe_load(yaml, permitted_classes: [Symbol])
|
|
14
|
+
|
|
15
|
+
mutate(@data, **args)
|
|
16
|
+
validate(@data)
|
|
17
|
+
|
|
18
|
+
new_yaml = YAML.dump(@data)
|
|
19
|
+
Result.success(Utils::Crypto.encrypt(new_yaml, @master_key))
|
|
20
|
+
rescue Errors::DecryptionError, Errors::InvalidKeyError => e
|
|
21
|
+
Result.failure(:decryption_error, e.message)
|
|
22
|
+
rescue Errors::ConfigValidationError => e
|
|
23
|
+
Result.failure(:validation_error, e.message)
|
|
24
|
+
rescue ArgumentError => e
|
|
25
|
+
Result.failure(:invalid_args, e.message)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
protected
|
|
29
|
+
|
|
30
|
+
def mutate(_data, **_args)
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def validate(_data)
|
|
35
|
+
# Subclasses can override to add validation
|
|
36
|
+
# Default: no validation (lightweight actions like set_env don't need full config validation)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def app(data)
|
|
40
|
+
data["application"] ||= {}
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nvoi
|
|
4
|
+
module ConfigApi
|
|
5
|
+
class Result
|
|
6
|
+
attr_reader :config, :error_type, :error_message
|
|
7
|
+
|
|
8
|
+
def self.success(config)
|
|
9
|
+
new(config: config)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.failure(type, message)
|
|
13
|
+
new(error_type: type, error_message: message)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def initialize(config: nil, error_type: nil, error_message: nil)
|
|
17
|
+
@config = config
|
|
18
|
+
@error_type = error_type
|
|
19
|
+
@error_message = error_message
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def success? = @error_type.nil?
|
|
23
|
+
def failure? = !success?
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nvoi
|
|
4
|
+
module ConfigApi
|
|
5
|
+
class << self
|
|
6
|
+
# Compute Provider
|
|
7
|
+
def set_compute_provider(config, key, **args)
|
|
8
|
+
Actions::SetComputeProvider.new(config, key).call(**args)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def delete_compute_provider(config, key)
|
|
12
|
+
Actions::DeleteComputeProvider.new(config, key).call
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Server
|
|
16
|
+
def set_server(config, key, **args)
|
|
17
|
+
Actions::SetServer.new(config, key).call(**args)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def delete_server(config, key, **args)
|
|
21
|
+
Actions::DeleteServer.new(config, key).call(**args)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Volume
|
|
25
|
+
def set_volume(config, key, **args)
|
|
26
|
+
Actions::SetVolume.new(config, key).call(**args)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def delete_volume(config, key, **args)
|
|
30
|
+
Actions::DeleteVolume.new(config, key).call(**args)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# App
|
|
34
|
+
def set_app(config, key, **args)
|
|
35
|
+
Actions::SetApp.new(config, key).call(**args)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def delete_app(config, key, **args)
|
|
39
|
+
Actions::DeleteApp.new(config, key).call(**args)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Database
|
|
43
|
+
def set_database(config, key, **args)
|
|
44
|
+
Actions::SetDatabase.new(config, key).call(**args)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def delete_database(config, key)
|
|
48
|
+
Actions::DeleteDatabase.new(config, key).call
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Secret
|
|
52
|
+
def set_secret(config, key, **args)
|
|
53
|
+
Actions::SetSecret.new(config, key).call(**args)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def delete_secret(config, key, **args)
|
|
57
|
+
Actions::DeleteSecret.new(config, key).call(**args)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Env
|
|
61
|
+
def set_env(config, key, **args)
|
|
62
|
+
Actions::SetEnv.new(config, key).call(**args)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def delete_env(config, key, **args)
|
|
66
|
+
Actions::DeleteEnv.new(config, key).call(**args)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/nvoi/errors.rb
CHANGED
|
@@ -1,67 +1,85 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Nvoi
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
# Errors module
|
|
5
|
+
module Errors
|
|
6
|
+
# Base error class for all Nvoi errors
|
|
7
|
+
class Error < StandardError
|
|
8
|
+
attr_reader :details
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
def initialize(message, details: nil)
|
|
11
|
+
@details = details
|
|
12
|
+
super(message)
|
|
13
|
+
end
|
|
11
14
|
end
|
|
12
|
-
end
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
# Configuration errors
|
|
17
|
+
class ConfigError < Error; end
|
|
18
|
+
class ConfigNotFoundError < ConfigError; end
|
|
19
|
+
class ConfigValidationError < ConfigError; end
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
# Credential errors
|
|
22
|
+
class CredentialError < Error; end
|
|
23
|
+
class DecryptionError < CredentialError; end
|
|
24
|
+
class EncryptionError < CredentialError; end
|
|
25
|
+
class InvalidKeyError < CredentialError; end
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
# Provider errors
|
|
28
|
+
class ProviderError < Error; end
|
|
29
|
+
class ServerCreationError < ProviderError; end
|
|
30
|
+
class NetworkError < ProviderError; end
|
|
31
|
+
class FirewallError < ProviderError; end
|
|
32
|
+
class VolumeError < ProviderError; end
|
|
33
|
+
class ValidationError < ProviderError; end
|
|
34
|
+
class ApiError < ProviderError; end
|
|
35
|
+
class AuthenticationError < ProviderError; end
|
|
36
|
+
class NotFoundError < ProviderError; end
|
|
37
|
+
class ConflictError < ProviderError; end
|
|
38
|
+
class RateLimitError < ProviderError; end
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
# Cloudflare errors
|
|
41
|
+
class CloudflareError < Error; end
|
|
42
|
+
class TunnelError < CloudflareError; end
|
|
43
|
+
class DnsError < CloudflareError; end
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
# Ssh errors
|
|
46
|
+
class SshError < Error; end
|
|
47
|
+
class SshConnectionError < SshError; end
|
|
48
|
+
class SshCommandError < SshError; end
|
|
45
49
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
attr_reader :step, :retryable
|
|
50
|
+
# Timeout errors
|
|
51
|
+
class TimeoutError < Error; end
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
super("#{step}: #{message}", details:)
|
|
54
|
-
end
|
|
53
|
+
# Deployment errors
|
|
54
|
+
class DeploymentError < Error
|
|
55
|
+
attr_reader :step, :retryable
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
def initialize(step, message, retryable: false, details: nil)
|
|
58
|
+
@step = step
|
|
59
|
+
@retryable = retryable
|
|
60
|
+
super("#{step}: #{message}", details:)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def retryable?
|
|
64
|
+
@retryable
|
|
65
|
+
end
|
|
58
66
|
end
|
|
59
|
-
end
|
|
60
67
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
# K8s errors
|
|
69
|
+
class K8sError < Error; end
|
|
70
|
+
class TemplateError < K8sError; end
|
|
64
71
|
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
# Service errors
|
|
73
|
+
class ServiceError < Error; end
|
|
74
|
+
|
|
75
|
+
# Database errors
|
|
76
|
+
class DatabaseError < Error
|
|
77
|
+
attr_reader :operation
|
|
78
|
+
|
|
79
|
+
def initialize(operation, message, details: nil)
|
|
80
|
+
@operation = operation
|
|
81
|
+
super("database #{operation}: #{message}", details:)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
67
85
|
end
|