nvoi 0.1.5

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 (178) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +19 -0
  3. data/Gemfile +9 -0
  4. data/Gemfile.lock +151 -0
  5. data/Makefile +26 -0
  6. data/Rakefile +16 -0
  7. data/doc/config-schema.yaml +357 -0
  8. data/examples/apex-wildcard/deploy.yml +68 -0
  9. data/examples/golang/.gitignore +19 -0
  10. data/examples/golang/Dockerfile +43 -0
  11. data/examples/golang/README.md +59 -0
  12. data/examples/golang/deploy.enc +0 -0
  13. data/examples/golang/deploy.yml +54 -0
  14. data/examples/golang/go.mod +39 -0
  15. data/examples/golang/go.sum +96 -0
  16. data/examples/golang/main.go +177 -0
  17. data/examples/golang/models/user.go +17 -0
  18. data/examples/golang-postgres-multi/.gitignore +18 -0
  19. data/examples/golang-postgres-multi/Dockerfile +39 -0
  20. data/examples/golang-postgres-multi/README.md +211 -0
  21. data/examples/golang-postgres-multi/deploy.yml +67 -0
  22. data/examples/golang-postgres-multi/go.mod +45 -0
  23. data/examples/golang-postgres-multi/go.sum +108 -0
  24. data/examples/golang-postgres-multi/main.go +197 -0
  25. data/examples/golang-postgres-multi/models/user.go +17 -0
  26. data/examples/postgres-multi/.env.production.example +11 -0
  27. data/examples/postgres-multi/README.md +112 -0
  28. data/examples/postgres-multi/deploy.yml +74 -0
  29. data/examples/postgres-single/.env.production.example +11 -0
  30. data/examples/postgres-single/.gitignore +15 -0
  31. data/examples/postgres-single/Dockerfile +35 -0
  32. data/examples/postgres-single/README.md +76 -0
  33. data/examples/postgres-single/deploy.yml +56 -0
  34. data/examples/postgres-single/go.mod +45 -0
  35. data/examples/postgres-single/go.sum +108 -0
  36. data/examples/postgres-single/main.go +184 -0
  37. data/examples/rails-single/.dockerignore +51 -0
  38. data/examples/rails-single/.env.production.example +11 -0
  39. data/examples/rails-single/.github/dependabot.yml +12 -0
  40. data/examples/rails-single/.github/workflows/ci.yml +39 -0
  41. data/examples/rails-single/.gitignore +20 -0
  42. data/examples/rails-single/.node-version +1 -0
  43. data/examples/rails-single/.rubocop.yml +8 -0
  44. data/examples/rails-single/.ruby-version +1 -0
  45. data/examples/rails-single/Dockerfile +86 -0
  46. data/examples/rails-single/Gemfile +56 -0
  47. data/examples/rails-single/Gemfile.lock +350 -0
  48. data/examples/rails-single/Procfile.dev +3 -0
  49. data/examples/rails-single/README.md +17 -0
  50. data/examples/rails-single/Rakefile +6 -0
  51. data/examples/rails-single/app/assets/builds/.keep +0 -0
  52. data/examples/rails-single/app/assets/images/.keep +0 -0
  53. data/examples/rails-single/app/assets/stylesheets/application.tailwind.css +1 -0
  54. data/examples/rails-single/app/controllers/application_controller.rb +4 -0
  55. data/examples/rails-single/app/controllers/concerns/.keep +0 -0
  56. data/examples/rails-single/app/controllers/users_controller.rb +19 -0
  57. data/examples/rails-single/app/helpers/application_helper.rb +2 -0
  58. data/examples/rails-single/app/javascript/application.js +3 -0
  59. data/examples/rails-single/app/javascript/controllers/application.js +9 -0
  60. data/examples/rails-single/app/javascript/controllers/hello_controller.js +7 -0
  61. data/examples/rails-single/app/javascript/controllers/index.js +8 -0
  62. data/examples/rails-single/app/jobs/application_job.rb +7 -0
  63. data/examples/rails-single/app/mailers/application_mailer.rb +4 -0
  64. data/examples/rails-single/app/models/application_record.rb +3 -0
  65. data/examples/rails-single/app/models/concerns/.keep +0 -0
  66. data/examples/rails-single/app/models/user.rb +2 -0
  67. data/examples/rails-single/app/views/layouts/application.html.erb +28 -0
  68. data/examples/rails-single/app/views/layouts/mailer.html.erb +13 -0
  69. data/examples/rails-single/app/views/layouts/mailer.text.erb +1 -0
  70. data/examples/rails-single/app/views/pwa/manifest.json.erb +22 -0
  71. data/examples/rails-single/app/views/pwa/service-worker.js +26 -0
  72. data/examples/rails-single/app/views/users/index.html.erb +38 -0
  73. data/examples/rails-single/bin/brakeman +7 -0
  74. data/examples/rails-single/bin/bundle +109 -0
  75. data/examples/rails-single/bin/dev +11 -0
  76. data/examples/rails-single/bin/docker-entrypoint +14 -0
  77. data/examples/rails-single/bin/jobs +6 -0
  78. data/examples/rails-single/bin/kamal +27 -0
  79. data/examples/rails-single/bin/rails +4 -0
  80. data/examples/rails-single/bin/rake +4 -0
  81. data/examples/rails-single/bin/rubocop +8 -0
  82. data/examples/rails-single/bin/setup +37 -0
  83. data/examples/rails-single/bin/thrust +5 -0
  84. data/examples/rails-single/bun.lock +224 -0
  85. data/examples/rails-single/config/application.rb +42 -0
  86. data/examples/rails-single/config/boot.rb +4 -0
  87. data/examples/rails-single/config/cable.yml +17 -0
  88. data/examples/rails-single/config/cache.yml +16 -0
  89. data/examples/rails-single/config/credentials.yml.enc +1 -0
  90. data/examples/rails-single/config/database.yml +100 -0
  91. data/examples/rails-single/config/environment.rb +5 -0
  92. data/examples/rails-single/config/environments/development.rb +69 -0
  93. data/examples/rails-single/config/environments/production.rb +87 -0
  94. data/examples/rails-single/config/environments/test.rb +50 -0
  95. data/examples/rails-single/config/initializers/assets.rb +7 -0
  96. data/examples/rails-single/config/initializers/content_security_policy.rb +25 -0
  97. data/examples/rails-single/config/initializers/filter_parameter_logging.rb +8 -0
  98. data/examples/rails-single/config/initializers/inflections.rb +16 -0
  99. data/examples/rails-single/config/locales/en.yml +31 -0
  100. data/examples/rails-single/config/puma.rb +41 -0
  101. data/examples/rails-single/config/queue.yml +18 -0
  102. data/examples/rails-single/config/recurring.yml +15 -0
  103. data/examples/rails-single/config/routes.rb +4 -0
  104. data/examples/rails-single/config.ru +6 -0
  105. data/examples/rails-single/db/cable_schema.rb +11 -0
  106. data/examples/rails-single/db/cache_schema.rb +12 -0
  107. data/examples/rails-single/db/migrate/20251123095526_create_users.rb +10 -0
  108. data/examples/rails-single/db/queue_schema.rb +129 -0
  109. data/examples/rails-single/db/seeds.rb +9 -0
  110. data/examples/rails-single/deploy.yml +57 -0
  111. data/examples/rails-single/lib/tasks/.keep +0 -0
  112. data/examples/rails-single/log/.keep +0 -0
  113. data/examples/rails-single/package.json +17 -0
  114. data/examples/rails-single/public/400.html +114 -0
  115. data/examples/rails-single/public/404.html +114 -0
  116. data/examples/rails-single/public/406-unsupported-browser.html +114 -0
  117. data/examples/rails-single/public/422.html +114 -0
  118. data/examples/rails-single/public/500.html +114 -0
  119. data/examples/rails-single/public/icon.png +0 -0
  120. data/examples/rails-single/public/icon.svg +3 -0
  121. data/examples/rails-single/public/robots.txt +1 -0
  122. data/examples/rails-single/script/.keep +0 -0
  123. data/examples/rails-single/vendor/.keep +0 -0
  124. data/examples/rails-single/yarn.lock +188 -0
  125. data/exe/nvoi +6 -0
  126. data/lib/nvoi/cli.rb +190 -0
  127. data/lib/nvoi/cloudflare/client.rb +287 -0
  128. data/lib/nvoi/config/config.rb +248 -0
  129. data/lib/nvoi/config/env_resolver.rb +63 -0
  130. data/lib/nvoi/config/loader.rb +102 -0
  131. data/lib/nvoi/config/naming.rb +196 -0
  132. data/lib/nvoi/config/ssh_keys.rb +82 -0
  133. data/lib/nvoi/config/types.rb +274 -0
  134. data/lib/nvoi/constants.rb +59 -0
  135. data/lib/nvoi/credentials/crypto.rb +88 -0
  136. data/lib/nvoi/credentials/editor.rb +272 -0
  137. data/lib/nvoi/credentials/manager.rb +173 -0
  138. data/lib/nvoi/deployer/cleaner.rb +36 -0
  139. data/lib/nvoi/deployer/image_builder.rb +23 -0
  140. data/lib/nvoi/deployer/infrastructure.rb +126 -0
  141. data/lib/nvoi/deployer/orchestrator.rb +146 -0
  142. data/lib/nvoi/deployer/retry.rb +67 -0
  143. data/lib/nvoi/deployer/service_deployer.rb +311 -0
  144. data/lib/nvoi/deployer/tunnel_manager.rb +57 -0
  145. data/lib/nvoi/deployer/types.rb +8 -0
  146. data/lib/nvoi/errors.rb +67 -0
  147. data/lib/nvoi/k8s/renderer.rb +44 -0
  148. data/lib/nvoi/k8s/templates.rb +29 -0
  149. data/lib/nvoi/logger.rb +72 -0
  150. data/lib/nvoi/providers/aws.rb +403 -0
  151. data/lib/nvoi/providers/base.rb +111 -0
  152. data/lib/nvoi/providers/hetzner.rb +288 -0
  153. data/lib/nvoi/providers/hetzner_client.rb +170 -0
  154. data/lib/nvoi/remote/docker_manager.rb +203 -0
  155. data/lib/nvoi/remote/ssh_executor.rb +72 -0
  156. data/lib/nvoi/remote/volume_manager.rb +103 -0
  157. data/lib/nvoi/service/delete.rb +234 -0
  158. data/lib/nvoi/service/deploy.rb +80 -0
  159. data/lib/nvoi/service/exec.rb +144 -0
  160. data/lib/nvoi/service/provider.rb +36 -0
  161. data/lib/nvoi/steps/application_deployer.rb +26 -0
  162. data/lib/nvoi/steps/database_provisioner.rb +60 -0
  163. data/lib/nvoi/steps/k3s_cluster_setup.rb +105 -0
  164. data/lib/nvoi/steps/k3s_provisioner.rb +351 -0
  165. data/lib/nvoi/steps/server_provisioner.rb +43 -0
  166. data/lib/nvoi/steps/services_provisioner.rb +29 -0
  167. data/lib/nvoi/steps/tunnel_configurator.rb +66 -0
  168. data/lib/nvoi/steps/volume_provisioner.rb +154 -0
  169. data/lib/nvoi/version.rb +5 -0
  170. data/lib/nvoi.rb +79 -0
  171. data/templates/app-deployment.yaml.erb +102 -0
  172. data/templates/app-ingress.yaml.erb +20 -0
  173. data/templates/app-secret.yaml.erb +10 -0
  174. data/templates/app-service.yaml.erb +12 -0
  175. data/templates/db-statefulset.yaml.erb +76 -0
  176. data/templates/service-deployment.yaml.erb +91 -0
  177. data/templates/worker-deployment.yaml.erb +50 -0
  178. metadata +361 -0
@@ -0,0 +1,154 @@
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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nvoi
4
+ VERSION = "0.1.5"
5
+ end
data/lib/nvoi.rb ADDED
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "json"
5
+ require "openssl"
6
+ require "securerandom"
7
+ require "fileutils"
8
+ require "tempfile"
9
+ require "open3"
10
+
11
+ require_relative "nvoi/version"
12
+ require_relative "nvoi/constants"
13
+ require_relative "nvoi/errors"
14
+ require_relative "nvoi/logger"
15
+
16
+ require_relative "nvoi/config/types"
17
+ require_relative "nvoi/config/naming"
18
+ require_relative "nvoi/config/ssh_keys"
19
+ require_relative "nvoi/config/env_resolver"
20
+ require_relative "nvoi/config/loader"
21
+ require_relative "nvoi/config/config"
22
+
23
+ require_relative "nvoi/credentials/crypto"
24
+ require_relative "nvoi/credentials/manager"
25
+ require_relative "nvoi/credentials/editor"
26
+
27
+ require_relative "nvoi/providers/base"
28
+ require_relative "nvoi/providers/hetzner"
29
+ require_relative "nvoi/providers/aws"
30
+
31
+ require_relative "nvoi/cloudflare/client"
32
+
33
+ require_relative "nvoi/remote/ssh_executor"
34
+ require_relative "nvoi/remote/docker_manager"
35
+ require_relative "nvoi/remote/volume_manager"
36
+
37
+ require_relative "nvoi/k8s/templates"
38
+ require_relative "nvoi/k8s/renderer"
39
+
40
+ require_relative "nvoi/deployer/types"
41
+ require_relative "nvoi/deployer/retry"
42
+ require_relative "nvoi/deployer/tunnel_manager"
43
+ require_relative "nvoi/deployer/infrastructure"
44
+ require_relative "nvoi/deployer/image_builder"
45
+ require_relative "nvoi/deployer/service_deployer"
46
+ require_relative "nvoi/deployer/cleaner"
47
+ require_relative "nvoi/deployer/orchestrator"
48
+
49
+ require_relative "nvoi/steps/server_provisioner"
50
+ require_relative "nvoi/steps/volume_provisioner"
51
+ require_relative "nvoi/steps/k3s_provisioner"
52
+ require_relative "nvoi/steps/k3s_cluster_setup"
53
+ require_relative "nvoi/steps/tunnel_configurator"
54
+ require_relative "nvoi/steps/database_provisioner"
55
+ require_relative "nvoi/steps/services_provisioner"
56
+ require_relative "nvoi/steps/application_deployer"
57
+
58
+ require_relative "nvoi/service/provider"
59
+ require_relative "nvoi/service/deploy"
60
+ require_relative "nvoi/service/delete"
61
+ require_relative "nvoi/service/exec"
62
+
63
+ require_relative "nvoi/cli"
64
+
65
+ module Nvoi
66
+ class << self
67
+ attr_accessor :logger
68
+
69
+ def root
70
+ File.expand_path("..", __dir__)
71
+ end
72
+
73
+ def templates_path
74
+ File.join(root, "templates")
75
+ end
76
+ end
77
+
78
+ self.logger = Logger.new
79
+ end
@@ -0,0 +1,102 @@
1
+ apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: <%= name %>
5
+ namespace: default
6
+ spec:
7
+ replicas: <%= replicas %>
8
+ strategy:
9
+ type: RollingUpdate
10
+ rollingUpdate:
11
+ maxUnavailable: 0
12
+ maxSurge: 1
13
+ selector:
14
+ matchLabels:
15
+ app: <%= name %>
16
+ template:
17
+ metadata:
18
+ labels:
19
+ app: <%= name %>
20
+ spec:
21
+ <% if affinity_server_names && !affinity_server_names.empty? %>
22
+ affinity:
23
+ nodeAffinity:
24
+ requiredDuringSchedulingIgnoredDuringExecution:
25
+ nodeSelectorTerms:
26
+ - matchExpressions:
27
+ - key: nvoi.io/server-name
28
+ operator: In
29
+ values:
30
+ <% affinity_server_names.each do |server| %>
31
+ - <%= server %>
32
+ <% end %>
33
+ <% end %>
34
+ containers:
35
+ - name: app
36
+ image: <%= image %>
37
+ <% if command && !command.empty? %>
38
+ command:
39
+ <% command.each do |cmd| %>
40
+ - <%= cmd.inspect %>
41
+ <% end %>
42
+ <% end %>
43
+ <% if port && port > 0 %>
44
+ ports:
45
+ - containerPort: <%= port %>
46
+ <% end %>
47
+ env:
48
+ <% env_keys.each do |key| %>
49
+ - name: <%= key %>
50
+ valueFrom:
51
+ secretKeyRef:
52
+ name: <%= secret_name %>
53
+ key: <%= key %>
54
+ <% end %>
55
+ <% if readiness_probe %>
56
+ readinessProbe:
57
+ httpGet:
58
+ path: <%= readiness_probe[:path] %>
59
+ port: <%= readiness_probe[:port] %>
60
+ initialDelaySeconds: <%= readiness_probe[:initial_delay] %>
61
+ periodSeconds: <%= readiness_probe[:period] %>
62
+ timeoutSeconds: <%= readiness_probe[:timeout] %>
63
+ failureThreshold: <%= readiness_probe[:failure_threshold] %>
64
+ <% end %>
65
+ <% if liveness_probe %>
66
+ livenessProbe:
67
+ httpGet:
68
+ path: <%= liveness_probe[:path] %>
69
+ port: <%= liveness_probe[:port] %>
70
+ initialDelaySeconds: <%= liveness_probe[:initial_delay] %>
71
+ periodSeconds: <%= liveness_probe[:period] %>
72
+ timeoutSeconds: <%= liveness_probe[:timeout] %>
73
+ failureThreshold: <%= liveness_probe[:failure_threshold] %>
74
+ <% end %>
75
+ resources:
76
+ requests:
77
+ memory: <%= resources[:request_memory] %>
78
+ cpu: <%= resources[:request_cpu] %>
79
+ limits:
80
+ memory: <%= resources[:limit_memory] %>
81
+ cpu: <%= resources[:limit_cpu] %>
82
+ <% if volume_mounts && !volume_mounts.empty? %>
83
+ volumeMounts:
84
+ <% volume_mounts.each do |vol| %>
85
+ - name: <%= vol[:name] %>
86
+ mountPath: <%= vol[:mount_path] %>
87
+ <% end %>
88
+ <% end %>
89
+ <% if (host_path_volumes && !host_path_volumes.empty?) || (volumes && !volumes.empty?) %>
90
+ volumes:
91
+ <% (host_path_volumes || []).each do |vol| %>
92
+ - name: <%= vol[:name] %>
93
+ hostPath:
94
+ path: <%= vol[:host_path] %>
95
+ type: DirectoryOrCreate
96
+ <% end %>
97
+ <% (volumes || []).each do |vol| %>
98
+ - name: <%= vol[:name] %>
99
+ persistentVolumeClaim:
100
+ claimName: <%= vol[:claim_name] %>
101
+ <% end %>
102
+ <% end %>
@@ -0,0 +1,20 @@
1
+ apiVersion: networking.k8s.io/v1
2
+ kind: Ingress
3
+ metadata:
4
+ name: <%= name %>
5
+ namespace: default
6
+ annotations:
7
+ nginx.ingress.kubernetes.io/ssl-redirect: "true"
8
+ spec:
9
+ ingressClassName: nginx
10
+ rules:
11
+ - host: <%= domain %>
12
+ http:
13
+ paths:
14
+ - path: /
15
+ pathType: Prefix
16
+ backend:
17
+ service:
18
+ name: <%= name %>
19
+ port:
20
+ number: <%= port %>
@@ -0,0 +1,10 @@
1
+ apiVersion: v1
2
+ kind: Secret
3
+ metadata:
4
+ name: <%= name %>
5
+ namespace: default
6
+ type: Opaque
7
+ stringData:
8
+ <% env_vars.each do |key, value| %>
9
+ <%= key %>: <%= value.inspect %>
10
+ <% end %>
@@ -0,0 +1,12 @@
1
+ apiVersion: v1
2
+ kind: Service
3
+ metadata:
4
+ name: <%= name %>
5
+ namespace: default
6
+ spec:
7
+ selector:
8
+ app: <%= name %>
9
+ ports:
10
+ - port: <%= port %>
11
+ targetPort: <%= port %>
12
+ type: ClusterIP
@@ -0,0 +1,76 @@
1
+ apiVersion: apps/v1
2
+ kind: StatefulSet
3
+ metadata:
4
+ name: <%= service_name %>
5
+ namespace: default
6
+ spec:
7
+ serviceName: <%= service_name %>
8
+ replicas: 1
9
+ selector:
10
+ matchLabels:
11
+ app: <%= service_name %>
12
+ template:
13
+ metadata:
14
+ labels:
15
+ app: <%= service_name %>
16
+ spec:
17
+ <% if affinity_server_names && !affinity_server_names.empty? %>
18
+ affinity:
19
+ nodeAffinity:
20
+ requiredDuringSchedulingIgnoredDuringExecution:
21
+ nodeSelectorTerms:
22
+ - matchExpressions:
23
+ - key: nvoi.io/server-name
24
+ operator: In
25
+ values:
26
+ <% affinity_server_names.each do |server| %>
27
+ - <%= server %>
28
+ <% end %>
29
+ <% end %>
30
+ containers:
31
+ - name: <%= adapter %>
32
+ image: <%= image %>
33
+ env:
34
+ - name: PGDATA
35
+ value: /var/lib/postgresql/data/pgdata
36
+ <% secret_keys.each do |key| %>
37
+ - name: <%= key %>
38
+ valueFrom:
39
+ secretKeyRef:
40
+ name: <%= secret_name %>
41
+ key: <%= key %>
42
+ <% end %>
43
+ ports:
44
+ - containerPort: <%= port %>
45
+ volumeMounts:
46
+ - name: data
47
+ mountPath: <%= data_path %>
48
+ <% if host_path %>
49
+ volumes:
50
+ - name: data
51
+ hostPath:
52
+ path: <%= host_path %>
53
+ type: DirectoryOrCreate
54
+ <% else %>
55
+ volumeClaimTemplates:
56
+ - metadata:
57
+ name: data
58
+ spec:
59
+ accessModes: ["ReadWriteOnce"]
60
+ resources:
61
+ requests:
62
+ storage: <%= storage_size %>
63
+ <% end %>
64
+ ---
65
+ apiVersion: v1
66
+ kind: Service
67
+ metadata:
68
+ name: <%= service_name %>
69
+ namespace: default
70
+ spec:
71
+ clusterIP: None
72
+ selector:
73
+ app: <%= service_name %>
74
+ ports:
75
+ - port: <%= port %>
76
+ targetPort: <%= port %>
@@ -0,0 +1,91 @@
1
+ apiVersion: v1
2
+ kind: Secret
3
+ metadata:
4
+ name: <%= name %>-secret
5
+ namespace: default
6
+ type: Opaque
7
+ stringData:
8
+ <% env_vars.each do |key, value| %>
9
+ <%= key %>: <%= value.inspect %>
10
+ <% end %>
11
+ ---
12
+ apiVersion: apps/v1
13
+ kind: Deployment
14
+ metadata:
15
+ name: <%= name %>
16
+ namespace: default
17
+ spec:
18
+ replicas: 1
19
+ selector:
20
+ matchLabels:
21
+ app: <%= name %>
22
+ template:
23
+ metadata:
24
+ labels:
25
+ app: <%= name %>
26
+ spec:
27
+ <% if affinity_server_names && !affinity_server_names.empty? %>
28
+ affinity:
29
+ nodeAffinity:
30
+ requiredDuringSchedulingIgnoredDuringExecution:
31
+ nodeSelectorTerms:
32
+ - matchExpressions:
33
+ - key: nvoi.io/server-name
34
+ operator: In
35
+ values:
36
+ <% affinity_server_names.each do |server| %>
37
+ - <%= server %>
38
+ <% end %>
39
+ <% end %>
40
+ containers:
41
+ - name: service
42
+ image: <%= image %>
43
+ <% if command && !command.empty? %>
44
+ command:
45
+ <% command.each do |cmd| %>
46
+ - <%= cmd.inspect %>
47
+ <% end %>
48
+ <% end %>
49
+ <% if port && port > 0 %>
50
+ ports:
51
+ - containerPort: <%= port %>
52
+ <% end %>
53
+ env:
54
+ <% env_keys.each do |key| %>
55
+ - name: <%= key %>
56
+ valueFrom:
57
+ secretKeyRef:
58
+ name: <%= name %>-secret
59
+ key: <%= key %>
60
+ <% end %>
61
+ <% if volume_path %>
62
+ volumeMounts:
63
+ - name: data
64
+ mountPath: <%= volume_path %>
65
+ <% end %>
66
+ <% if host_path %>
67
+ volumes:
68
+ - name: data
69
+ hostPath:
70
+ path: <%= host_path %>
71
+ type: DirectoryOrCreate
72
+ <% elsif volume_path %>
73
+ volumes:
74
+ - name: data
75
+ emptyDir: {}
76
+ <% end %>
77
+ ---
78
+ <% if port && port > 0 %>
79
+ apiVersion: v1
80
+ kind: Service
81
+ metadata:
82
+ name: <%= name %>
83
+ namespace: default
84
+ spec:
85
+ selector:
86
+ app: <%= name %>
87
+ ports:
88
+ - port: <%= port %>
89
+ targetPort: <%= port %>
90
+ type: ClusterIP
91
+ <% end %>
@@ -0,0 +1,50 @@
1
+ apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: <%= name %>
5
+ namespace: default
6
+ spec:
7
+ replicas: <%= replicas %>
8
+ selector:
9
+ matchLabels:
10
+ app: <%= name %>
11
+ template:
12
+ metadata:
13
+ labels:
14
+ app: <%= name %>
15
+ spec:
16
+ <% if affinity_server_names && !affinity_server_names.empty? %>
17
+ affinity:
18
+ nodeAffinity:
19
+ requiredDuringSchedulingIgnoredDuringExecution:
20
+ nodeSelectorTerms:
21
+ - matchExpressions:
22
+ - key: nvoi.io/server-name
23
+ operator: In
24
+ values:
25
+ <% affinity_server_names.each do |server| %>
26
+ - <%= server %>
27
+ <% end %>
28
+ <% end %>
29
+ containers:
30
+ - name: worker
31
+ image: <%= image %>
32
+ command:
33
+ <% command.each do |cmd| %>
34
+ - <%= cmd.inspect %>
35
+ <% end %>
36
+ env:
37
+ <% env_keys.each do |key| %>
38
+ - name: <%= key %>
39
+ valueFrom:
40
+ secretKeyRef:
41
+ name: <%= secret_name %>
42
+ key: <%= key %>
43
+ <% end %>
44
+ resources:
45
+ requests:
46
+ memory: <%= resources[:request_memory] %>
47
+ cpu: <%= resources[:request_cpu] %>
48
+ limits:
49
+ memory: <%= resources[:limit_memory] %>
50
+ cpu: <%= resources[:limit_cpu] %>