Class: Nvoi::Configuration::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/nvoi/configuration/builder.rb

Overview

Builder for constructing and modifying config data hashes Replaces ConfigApi with a cleaner, chainable interface

Constant Summary collapse

COMPUTE_PROVIDERS =
%w[hetzner aws scaleway].freeze
DOMAIN_PROVIDERS =
%w[cloudflare].freeze
DATABASE_ADAPTERS =
%w[postgres postgresql mysql sqlite sqlite3].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = nil) ⇒ Builder

Returns a new instance of Builder.



15
16
17
# File 'lib/nvoi/configuration/builder.rb', line 15

def initialize(data = nil)
  @data = data || { "application" => {} }
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



13
14
15
# File 'lib/nvoi/configuration/builder.rb', line 13

def data
  @data
end

Class Method Details

.from_hash(data) ⇒ Object

─── Class Methods ───



21
22
23
# File 'lib/nvoi/configuration/builder.rb', line 21

def self.from_hash(data)
  new(data)
end

.init(name:, environment: "production") ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/nvoi/configuration/builder.rb', line 25

def self.init(name:, environment: "production")
  raise ArgumentError, "name is required" if name.blank?

  master_key = Utils::Crypto.generate_key
  private_key, public_key = Utils::ConfigLoader.generate_keypair

  builder = new
  builder.name(name)
  builder.environment(environment)
  builder.ssh_keys(private_key, public_key)

  yaml = YAML.dump(builder.to_h)
  encrypted_config = Utils::Crypto.encrypt(yaml, master_key)

  Result::Init.new(
    config: encrypted_config,
    master_key:,
    ssh_public_key: public_key
  )
rescue ArgumentError => e
  Result::Init.new(error_type: :invalid_args, error_message: e.message)
rescue Errors::ConfigError => e
  Result::Init.new(error_type: :config_error, error_message: e.message)
end

Instance Method Details

#app_entry(name, servers:, domain: nil, subdomain: nil, port: nil, command: nil, pre_run_command: nil, env: nil, mounts: nil) ⇒ Object

─── App ───



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/nvoi/configuration/builder.rb', line 151

def app_entry(name, servers:, domain: nil, subdomain: nil, port: nil, command: nil, pre_run_command: nil, env: nil, mounts: nil)
  validate_presence!(name, "name")
  validate_servers_array!(servers)
  validate_server_refs!(servers)

  apps[name.to_s] = {
    "servers" => servers.map(&:to_s),
    "domain" => domain,
    "subdomain" => subdomain,
    "port" => port,
    "command" => command,
    "pre_run_command" => pre_run_command,
    "env" => env,
    "mounts" => mounts
  }.compact
  wrap_success
end

#compute_provider(provider, **opts) ⇒ Object

─── Compute Provider ───



72
73
74
75
76
77
78
# File 'lib/nvoi/configuration/builder.rb', line 72

def compute_provider(provider, **opts)
  validate_presence!(provider, "provider")
  validate_inclusion!(provider.to_s, COMPUTE_PROVIDERS, "provider")

  app["compute_provider"] = { provider.to_s => build_compute_config(provider.to_s, opts) }
  wrap_success
end

#database(servers:, adapter:, image: nil, url: nil, user: nil, password: nil, database_name: nil, mount: nil, path: nil) ⇒ Object

─── Database ───



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/nvoi/configuration/builder.rb', line 179

def database(servers:, adapter:, image: nil, url: nil, user: nil, password: nil, database_name: nil, mount: nil, path: nil)
  validate_servers_array!(servers)
  validate_presence!(adapter, "adapter")
  validate_inclusion!(adapter.to_s.downcase, DATABASE_ADAPTERS, "adapter")
  validate_server_refs!(servers)

  secrets = build_database_secrets(adapter, user, password, database_name)

  app["database"] = {
    "servers" => servers.map(&:to_s),
    "adapter" => adapter.to_s,
    "image" => image,
    "url" => url,
    "secrets" => secrets.empty? ? nil : secrets,
    "mount" => mount,
    "path" => path
  }.compact
  wrap_success
end

#domain_provider(provider, **opts) ⇒ Object

─── Domain Provider ───



87
88
89
90
91
92
93
# File 'lib/nvoi/configuration/builder.rb', line 87

def domain_provider(provider, **opts)
  validate_presence!(provider, "provider")
  validate_inclusion!(provider.to_s, DOMAIN_PROVIDERS, "provider")

  app["domain_provider"] = { provider.to_s => build_domain_config(provider.to_s, opts) }
  wrap_success
end

#env(key, value) ⇒ Object

─── Env ───

Raises:

  • (ArgumentError)


251
252
253
254
255
256
257
# File 'lib/nvoi/configuration/builder.rb', line 251

def env(key, value)
  validate_presence!(key, "key")
  raise ArgumentError, "value is required" if value.nil?

  env_vars[key.to_s] = value.to_s
  wrap_success
end

#environment(e) ⇒ Object



57
58
59
60
# File 'lib/nvoi/configuration/builder.rb', line 57

def environment(e)
  app["environment"] = e.to_s
  self
end

#name(n) ⇒ Object

─── Basic Setters ───



52
53
54
55
# File 'lib/nvoi/configuration/builder.rb', line 52

def name(n)
  app["name"] = n.to_s
  self
end

#remove_app(name) ⇒ Object



169
170
171
172
173
174
175
# File 'lib/nvoi/configuration/builder.rb', line 169

def remove_app(name)
  validate_presence!(name, "name")
  validate_exists!(apps, name.to_s, "app")

  apps.delete(name.to_s)
  wrap_success
end

#remove_compute_providerObject



80
81
82
83
# File 'lib/nvoi/configuration/builder.rb', line 80

def remove_compute_provider
  app["compute_provider"] = {}
  wrap_success
end

#remove_databaseObject



199
200
201
202
# File 'lib/nvoi/configuration/builder.rb', line 199

def remove_database
  app.delete("database")
  wrap_success
end

#remove_domain_providerObject



95
96
97
98
# File 'lib/nvoi/configuration/builder.rb', line 95

def remove_domain_provider
  app["domain_provider"] = {}
  wrap_success
end

#remove_env(key) ⇒ Object



259
260
261
262
263
264
265
# File 'lib/nvoi/configuration/builder.rb', line 259

def remove_env(key)
  validate_presence!(key, "key")
  validate_exists!(env_vars, key.to_s, "env")

  env_vars.delete(key.to_s)
  wrap_success
end

#remove_secret(key) ⇒ Object



241
242
243
244
245
246
247
# File 'lib/nvoi/configuration/builder.rb', line 241

def remove_secret(key)
  validate_presence!(key, "key")
  validate_exists!(secrets, key.to_s, "secret")

  secrets.delete(key.to_s)
  wrap_success
end

#remove_server(name) ⇒ Object



115
116
117
118
119
120
121
122
# File 'lib/nvoi/configuration/builder.rb', line 115

def remove_server(name)
  validate_presence!(name, "name")
  validate_exists!(servers, name.to_s, "server")
  check_server_references(name.to_s)

  servers.delete(name.to_s)
  wrap_success
end

#remove_service(name) ⇒ Object



223
224
225
226
227
228
229
# File 'lib/nvoi/configuration/builder.rb', line 223

def remove_service(name)
  validate_presence!(name, "name")
  validate_exists!(services, name.to_s, "service")

  services.delete(name.to_s)
  wrap_success
end

#remove_volume(server_name, name) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
# File 'lib/nvoi/configuration/builder.rb', line 137

def remove_volume(server_name, name)
  validate_presence!(server_name, "server")
  validate_presence!(name, "name")
  validate_exists!(servers, server_name.to_s, "server")

  volumes = servers[server_name.to_s]["volumes"] || {}
  validate_exists!(volumes, name.to_s, "volume")

  volumes.delete(name.to_s)
  wrap_success
end

#secret(key, value) ⇒ Object

─── Secret ───

Raises:

  • (ArgumentError)


233
234
235
236
237
238
239
# File 'lib/nvoi/configuration/builder.rb', line 233

def secret(key, value)
  validate_presence!(key, "key")
  raise ArgumentError, "value is required" if value.nil?

  secrets[key.to_s] = value.to_s
  wrap_success
end

#server(name, master: false, type: nil, location: nil, count: 1) ⇒ Object

─── Server ───



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/nvoi/configuration/builder.rb', line 102

def server(name, master: false, type: nil, location: nil, count: 1)
  validate_presence!(name, "name")
  validate_positive!(count, "count") if count

  servers[name.to_s] = {
    "master" => master,
    "type" => type,
    "location" => location,
    "count" => count
  }.compact
  wrap_success
end

#service(name, servers:, image:, port: nil, command: nil, env: nil, mount: nil) ⇒ Object

─── Service ───



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/nvoi/configuration/builder.rb', line 206

def service(name, servers:, image:, port: nil, command: nil, env: nil, mount: nil)
  validate_presence!(name, "name")
  validate_servers_array!(servers)
  validate_presence!(image, "image")
  validate_server_refs!(servers)

  services[name.to_s] = {
    "servers" => servers.map(&:to_s),
    "image" => image.to_s,
    "port" => port,
    "command" => command,
    "env" => env,
    "mount" => mount
  }.compact
  wrap_success
end

#ssh_keys(private_key, public_key) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/nvoi/configuration/builder.rb', line 62

def ssh_keys(private_key, public_key)
  app["ssh_keys"] = {
    "private_key" => private_key,
    "public_key" => public_key
  }
  self
end

#to_hObject

─── Output ───



269
270
271
# File 'lib/nvoi/configuration/builder.rb', line 269

def to_h
  @data
end

#to_yamlObject



273
274
275
# File 'lib/nvoi/configuration/builder.rb', line 273

def to_yaml
  YAML.dump(@data)
end

#volume(server_name, name, size: 10) ⇒ Object

─── Volume ───



126
127
128
129
130
131
132
133
134
135
# File 'lib/nvoi/configuration/builder.rb', line 126

def volume(server_name, name, size: 10)
  validate_presence!(server_name, "server")
  validate_presence!(name, "name")
  validate_positive!(size, "size") if size
  validate_exists!(servers, server_name.to_s, "server")

  servers[server_name.to_s]["volumes"] ||= {}
  servers[server_name.to_s]["volumes"][name.to_s] = { "size" => size }
  wrap_success
end