ConfigLMM 0.1.0 → 0.3.0

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +63 -1
  3. data/Examples/Implemented.mm.yaml +120 -0
  4. data/Examples/Keys.ini +2 -0
  5. data/Examples/Linux.mm.yaml +14 -3
  6. data/Images/configINconfig.png +0 -0
  7. data/Images/singleConfig.png +0 -0
  8. data/Plugins/Apps/Authentik/Authentik-Server.container +18 -0
  9. data/Plugins/Apps/Authentik/Authentik-Worker.container +17 -0
  10. data/Plugins/Apps/Authentik/Authentik.conf.erb +35 -0
  11. data/Plugins/Apps/Authentik/Authentik.lmm.rb +73 -0
  12. data/Plugins/Apps/Cassandra/Cassandra.lmm.rb +41 -0
  13. data/Plugins/Apps/Dovecot/Dovecot.lmm.rb +165 -0
  14. data/Plugins/Apps/GitLab/GitLab.conf.erb +26 -0
  15. data/Plugins/Apps/GitLab/GitLab.container +17 -0
  16. data/Plugins/Apps/GitLab/GitLab.lmm.rb +75 -0
  17. data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +48 -10
  18. data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +59 -2
  19. data/Plugins/Apps/Nextcloud/config.php +18 -0
  20. data/Plugins/Apps/Nginx/conf.d/configlmm.conf +62 -0
  21. data/Plugins/Apps/Nginx/config-lmm/errors.conf +2 -2
  22. data/Plugins/Apps/Nginx/config-lmm/security.conf +4 -0
  23. data/Plugins/Apps/Nginx/main.conf.erb +31 -0
  24. data/Plugins/Apps/Nginx/nginx.conf +3 -68
  25. data/Plugins/Apps/Nginx/nginx.lmm.rb +71 -14
  26. data/Plugins/Apps/Odoo/Odoo.conf.erb +30 -13
  27. data/Plugins/Apps/Odoo/Odoo.container +17 -0
  28. data/Plugins/Apps/Odoo/Odoo.lmm.rb +62 -2
  29. data/Plugins/Apps/Odoo/odoo.conf +37 -0
  30. data/Plugins/Apps/PHP-FPM/PHP-FPM.lmm.rb +95 -0
  31. data/Plugins/Apps/Peppermint/Peppermint.conf.erb +64 -0
  32. data/Plugins/Apps/Peppermint/Peppermint.container +14 -0
  33. data/Plugins/Apps/Peppermint/Peppermint.lmm.rb +58 -0
  34. data/Plugins/Apps/Postfix/Postfix.lmm.rb +184 -0
  35. data/Plugins/Apps/Postfix/smtpd.conf +3 -0
  36. data/Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb +225 -0
  37. data/Plugins/Apps/SSH/SSH.lmm.rb +51 -0
  38. data/Plugins/Apps/UVdesk/UVdesk.conf.erb +52 -0
  39. data/Plugins/Apps/UVdesk/UVdesk.lmm.rb +85 -0
  40. data/Plugins/Apps/Valkey/Valkey.lmm.rb +56 -0
  41. data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +35 -18
  42. data/Plugins/Apps/Vaultwarden/Vaultwarden.container +16 -0
  43. data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +42 -3
  44. data/Plugins/Apps/gollum/gollum.conf.erb +45 -18
  45. data/Plugins/Apps/gollum/gollum.container +12 -0
  46. data/Plugins/Apps/gollum/gollum.lmm.rb +39 -10
  47. data/Plugins/OS/Linux/Distributions.yaml +16 -0
  48. data/Plugins/OS/Linux/Linux.lmm.rb +389 -0
  49. data/Plugins/OS/Linux/Packages.yaml +51 -0
  50. data/Plugins/OS/Linux/WireGuard/WireGuard.lmm.rb +108 -0
  51. data/Plugins/OS/Linux/WireGuard/wg0.conf.erb +15 -0
  52. data/Plugins/OS/Linux/openSUSE/autoinst.xml.erb +87 -0
  53. data/Plugins/OS/Linux/systemd/systemd.lmm.rb +28 -0
  54. data/Plugins/OS/Linux/systemd/user-0.slice +9 -0
  55. data/Plugins/OS/Linux/systemd/user@.service.d/delegate.conf +3 -0
  56. data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +6 -1
  57. data/Plugins/Platforms/libvirt/libvirt.lmm.rb +103 -0
  58. data/Plugins/Services/DNS/PowerDNS.lmm.rb +69 -6
  59. data/README.md +10 -0
  60. data/bootstrap.sh +54 -0
  61. data/lib/ConfigLMM/Framework/plugins/dns.rb +1 -2
  62. data/lib/ConfigLMM/Framework/plugins/linuxApp.rb +237 -0
  63. data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +24 -6
  64. data/lib/ConfigLMM/Framework/plugins/plugin.rb +150 -0
  65. data/lib/ConfigLMM/Framework/plugins.rb +1 -0
  66. data/lib/ConfigLMM/commands/configsCommand.rb +3 -0
  67. data/lib/ConfigLMM/version.rb +1 -1
  68. metadata +87 -5
  69. data/Plugins/Apps/Nginx/main.conf +0 -30
  70. data/Plugins/OS/Linux.lmm.rb +0 -64
@@ -0,0 +1,237 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConfigLMM
4
+ module Framework
5
+
6
+ class LinuxApp < Framework::Plugin
7
+
8
+ LINUX_FOLDER = __dir__ + '/../../../../Plugins/OS/Linux/'
9
+ SUSE_NAME = 'openSUSE Leap'
10
+ SUSE_ID = 'opensuse-leap'
11
+ PODMAN_PACKAGE = 'Podman'
12
+ SYSTEMD_CONTAINERS_PATH = '~/.config/containers/systemd/'
13
+
14
+ def ensurePackage(name, location)
15
+ self.class.ensurePackages([name], location)
16
+ end
17
+
18
+ def ensurePackages(names, location)
19
+ self.class.ensurePackages(names, location)
20
+ end
21
+
22
+ def self.ensurePackages(names, locationOrSSH)
23
+ distroInfo = nil
24
+ closure = Proc.new do |ssh|
25
+ distroInfo = self.currentDistroInfo(ssh)
26
+ reposPackages = self.mapPackages(names, distroInfo['Name'])
27
+
28
+ repos = []
29
+ pkgs = []
30
+ reposPackages.each do |pkg|
31
+ if pkg.include?('|')
32
+ repoName, pkg = pkg.split('|')
33
+ repos << repoName
34
+ pkgs << pkg
35
+ else
36
+ pkgs << pkg
37
+ end
38
+ end
39
+ repos.each do |repoName|
40
+ self.addRepo(repoName, distroInfo, ssh)
41
+ end
42
+ command = distroInfo['InstallPackage'] + ' ' + pkgs.map { |pkg| pkg.shellescape }.join(' ')
43
+ if ssh
44
+ self.sshExec!(ssh, command)
45
+ else
46
+ if `echo $EUID`.strip == '0'
47
+ `#{command} >/dev/null`
48
+ else
49
+ `sudo #{command} >/dev/null`
50
+ end
51
+ end
52
+ distroInfo
53
+ end
54
+
55
+ if locationOrSSH.nil? || locationOrSSH == '@me'
56
+ distroInfo = closure.call(nil)
57
+ elsif locationOrSSH.is_a?(String) || locationOrSSH.is_a?(Addressable::URI)
58
+ uri = Addressable::URI.parse(locationOrSSH)
59
+ raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
60
+
61
+ self.sshStart(locationOrSSH) do |ssh|
62
+ distroInfo = closure.call(ssh)
63
+ end
64
+ else
65
+ distroInfo = closure.call(locationOrSSH)
66
+ end
67
+ distroInfo
68
+ end
69
+
70
+ def ensureServiceAutoStart(name, location)
71
+ if location && location != '@me'
72
+ uri = Addressable::URI.parse(location)
73
+ raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
74
+ self.class.ensureServiceAutoStartOverSSH(name, uri)
75
+ else
76
+ # TODO
77
+ end
78
+ end
79
+
80
+ def self.ensureServiceAutoStartOverSSH(name, locationOrSSH)
81
+ closure = Proc.new do |ssh|
82
+ distroInfo = self.currentDistroInfo(ssh)
83
+
84
+ command = distroInfo['AutoStartService'] + ' ' + name.shellescape
85
+ self.sshExec!(ssh, command)
86
+ end
87
+
88
+ if locationOrSSH.is_a?(String) || locationOrSSH.is_a?(Addressable::URI)
89
+ self.sshStart(locationOrSSH) do |ssh|
90
+ closure.call(ssh)
91
+ end
92
+ else
93
+ closure.call(locationOrSSH)
94
+ end
95
+ end
96
+
97
+ def startService(name, location)
98
+ if location && location != '@me'
99
+ uri = Addressable::URI.parse(location)
100
+ raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
101
+ self.class.startServiceOverSSH(name, location)
102
+ else
103
+ # TODO
104
+ end
105
+ end
106
+
107
+ def self.startServiceOverSSH(name, locationOrSSH)
108
+ closure = Proc.new do |ssh|
109
+ distroInfo = self.currentDistroInfo(ssh)
110
+
111
+ command = distroInfo['StartService'] + ' ' + name.shellescape
112
+ self.sshExec!(ssh, command)
113
+ end
114
+
115
+ if locationOrSSH.is_a?(String) || locationOrSSH.is_a?(Addressable::URI)
116
+ self.sshStart(locationOrSSH) do |ssh|
117
+ closure.call(ssh)
118
+ end
119
+ else
120
+ closure.call(locationOrSSH)
121
+ end
122
+ end
123
+
124
+
125
+ def self.firewallAddServiceOverSSH(serviceName, locationOrSSH)
126
+ closure = Proc.new do |ssh|
127
+ command = 'firewall-cmd --permanent --add-service ' + serviceName.shellescape
128
+ self.sshExec!(ssh, command, true)
129
+ command = 'firewall-cmd --add-service ' + serviceName.shellescape
130
+ self.sshExec!(ssh, command, true)
131
+ end
132
+
133
+ if locationOrSSH.is_a?(String) || locationOrSSH.is_a?(Addressable::URI)
134
+ self.sshStart(locationOrSSH) do |ssh|
135
+ closure.call(ssh)
136
+ end
137
+ else
138
+ closure.call(locationOrSSH)
139
+ end
140
+ end
141
+
142
+ def self.firewallAddPortOverSSH(portName, locationOrSSH)
143
+ closure = Proc.new do |ssh|
144
+ command = 'firewall-cmd --permanent --add-port ' + portName.shellescape
145
+ self.sshExec!(ssh, command, true)
146
+ command = 'firewall-cmd --add-port ' + portName.shellescape
147
+ self.sshExec!(ssh, command, true)
148
+ end
149
+
150
+ if locationOrSSH.is_a?(String) || locationOrSSH.is_a?(Addressable::URI)
151
+ self.sshStart(locationOrSSH) do |ssh|
152
+ closure.call(ssh)
153
+ end
154
+ else
155
+ closure.call(locationOrSSH)
156
+ end
157
+ end
158
+
159
+ def self.mapPackages(packages, distroName)
160
+ distroPackages = YAML.load_file(LINUX_FOLDER + 'Packages.yaml')
161
+ names = []
162
+ packages.to_a.each do |pkg|
163
+ packageName = distroPackages[distroName][pkg]
164
+ if packageName
165
+ if packageName.is_a?(Array)
166
+ names += packageName
167
+ else
168
+ names << packageName
169
+ end
170
+ else
171
+ names << pkg.downcase
172
+ end
173
+ end
174
+ names
175
+ end
176
+
177
+ def self.createCertificateOverSSH(ssh)
178
+ dir = "/etc/letsencrypt/live/Wildcard/"
179
+ self.sshExec!(ssh, "mkdir -p #{dir}")
180
+ # Need this temporarily before real certs are created
181
+ if !self.remoteFilePresent?(dir + 'fullchain.pem', ssh)
182
+ self.sshExec!(ssh, "openssl req -x509 -noenc -days 90 -newkey rsa:2048 -keyout #{dir}privkey.pem -out #{dir}fullchain.pem -subj '/C=US/O=ConfigLMM/CN=Wildcard'")
183
+ self.sshExec!(ssh, "cp #{dir}fullchain.pem #{dir}chain.pem")
184
+ end
185
+ dir
186
+ end
187
+
188
+ def self.configurePodmanServiceOverSSH(user, homedir, userComment, distroInfo, ssh)
189
+ Framework::LinuxApp.ensurePackages([PODMAN_PACKAGE], ssh)
190
+ addUserCmd = "#{distroInfo['CreateServiceUser']} --home-dir '#{homedir}' --create-home --comment '#{userComment}' #{user}"
191
+ self.sshExec!(ssh, addUserCmd, true)
192
+ self.createSubuidsOverSSH(user, distroInfo, ssh)
193
+ self.sshExec!(ssh, "loginctl enable-linger #{user}")
194
+ self.sshExec!(ssh, "su --login #{user} --shell /bin/sh --command 'mkdir -p #{SYSTEMD_CONTAINERS_PATH}'")
195
+ end
196
+
197
+ def self.addRepo(name, distroInfo, ssh = nil)
198
+ if distroInfo['Name'] == 'openSUSE Leap'
199
+ if ssh
200
+ versionId = ssh.exec!('cat /etc/os-release | grep "^VERSION_ID=" | cut -d "=" -f 2').strip.gsub('"', '')
201
+ self.sshExec!(ssh, "zypper addrepo https://download.opensuse.org/repositories/#{name}/#{versionId}/#{name}.repo", true)
202
+ self.sshExec!(ssh, "zypper --gpg-auto-import-keys refresh")
203
+ else
204
+ versionId = `cat /etc/os-release | grep "^VERSION_ID=" | cut -d "=" -f 2`.strip.gsub('"', '')
205
+ `zypper addrepo https://download.opensuse.org/repositories/#{name}/#{versionId}/#{name}.repo`
206
+ `zypper --gpg-auto-import-keys refresh`
207
+ end
208
+ else
209
+ # TODO
210
+ end
211
+ end
212
+
213
+ def self.createSubuidsOverSSH(user, distroInfo, ssh)
214
+ self.sshExec!(ssh, "#{distroInfo['ModifyUser']} --add-subuids 100000-165535 --add-subgids 100000-165535 #{user}")
215
+ end
216
+
217
+ def self.distroID(ssh = nil)
218
+ if ssh
219
+ ssh.exec!('cat /etc/os-release | grep "^ID=" | cut -d "=" -f 2').strip.gsub('"', '')
220
+ else
221
+ `cat /etc/os-release | grep "^ID=" | cut -d "=" -f 2`.strip.gsub('"', '')
222
+ end
223
+ end
224
+
225
+ def self.currentDistroInfo(ssh)
226
+ self.distroInfo(self.distroID(ssh))
227
+ end
228
+
229
+ def self.distroInfo(distroID)
230
+ distributions = YAML.load_file(LINUX_FOLDER + 'Distributions.yaml')
231
+ raise Framework::PluginProcessError.new("Unknown Linux Distro: #{distroID}!") unless distributions.key?(distroID)
232
+ distributions[distroID]
233
+ end
234
+
235
+ end
236
+ end
237
+ end
@@ -13,30 +13,48 @@ module ConfigLMM
13
13
 
14
14
  class NginxApp < Framework::Plugin
15
15
 
16
+ NGINX_PACKAGE = 'nginx'
17
+ CONFIG_DIR = '/etc/nginx/'
18
+ WWW_DIR = '/srv/www/'
19
+
16
20
  def writeNginxConfig(dir, name, id, target, activeState, context, options)
17
21
  outputFolder = options['output']
18
22
 
19
23
  updateTargetConfig(target)
20
24
 
25
+ target = target.dup
26
+ target['NginxVersion'] = 0 unless target['NginxVersion']
21
27
  template = ERB.new(File.read(dir + '/' + name + '.conf.erb'))
22
28
  renderTemplate(template, target, outputFolder + '/nginx/servers-lmm/' + name + '.conf', options)
23
- plugins[:Nginx].actionNginxBuild(id, target, activeState, context, options)
24
29
  end
25
30
 
26
31
  def deployNginxConfig(id, target, activeState, context, options)
27
- outputFolder = options['output']
32
+ outputFolder = options['output'] + '/nginx/servers-lmm'
28
33
 
29
- if !target['Location'] || target['Location'] == '@me'
30
- copy(outputFolder + '/nginx/servers-lmm', '/etc/nginx/', options['dry'])
34
+ if target['Location'] && target['Location'] != '@me'
35
+ uri = Addressable::URI.parse(target['Location'])
36
+ raise Framework::PluginProcessError.new("Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
37
+ self.class.sshStart(uri) do |ssh|
38
+ self.class.uploadFolder(outputFolder, CONFIG_DIR, ssh)
39
+ Framework::LinuxApp.firewallAddServiceOverSSH('https', ssh)
40
+ end
41
+ else
42
+ copy(outputFolder, CONFIG_DIR, options['dry'])
31
43
  end
32
-
33
- plugins[:Nginx].actionNginxDeploy(id, target, activeState, context, options)
34
44
  end
35
45
 
36
46
  def cleanupNginxConfig(name, id, state, context, options)
37
47
  rm('/etc/nginx/servers-lmm/' + name + '.conf', options['dry'])
38
48
  end
39
49
 
50
+ def self.prepareNginxConfig(target, ssh = nil)
51
+ if ssh
52
+ target['NginxVersion'] = self.sshExec!(ssh, 'nginx -v').strip.split('/')[1].to_f
53
+ else
54
+ target['NginxVersion'] = `nginx -v`.strip.split('/')[1].to_f
55
+ end
56
+ end
57
+
40
58
  private
41
59
 
42
60
  def updateTargetConfig(target)
@@ -2,8 +2,12 @@
2
2
 
3
3
  require_relative 'errors'
4
4
  require_relative 'store'
5
+ require 'addressable/uri'
5
6
  require 'http'
6
7
  require 'fileutils'
8
+ require 'net/ssh'
9
+ require 'net/scp'
10
+ require 'open3'
7
11
 
8
12
  module ConfigLMM
9
13
  module Framework
@@ -42,6 +46,8 @@ module ConfigLMM
42
46
 
43
47
  addMeta :name, :description
44
48
 
49
+ attr_accessor :state
50
+
45
51
  def initialize(logger, prompt, plugins)
46
52
  @Logger = logger
47
53
  @Prompt = prompt
@@ -141,6 +147,150 @@ module ConfigLMM
141
147
  end
142
148
  end
143
149
 
150
+ def self.loadVariable(value, target)
151
+ variableStart = value.index('${')
152
+ return value unless variableStart
153
+ variableEnd = value.index('}', variableStart + 2)
154
+ variableName = value[variableStart + 2...variableEnd]
155
+ if variableName.start_with?('ENV:')
156
+ value = value[0...variableStart].to_s + ENV[variableName[4..variableEnd]] + value[(variableEnd + 1)..-1].to_s
157
+ else
158
+ raise 'Not implemented!'
159
+ end
160
+ value
161
+ end
162
+
163
+ CONFIGLMM_SECTION_BEGIN = "# -----BEGIN CONFIGLMM-----\n"
164
+ CONFIGLMM_SECTION_END = "# -----END CONFIGLMM-----\n"
165
+
166
+ def updateLocalFile(file, options, atTop = false, comment = '#')
167
+ File.write(file, '') unless File.exist?(file)
168
+ sectionBegin = CONFIGLMM_SECTION_BEGIN.gsub('#', comment)
169
+ sectionEnd = CONFIGLMM_SECTION_END.gsub('#', comment)
170
+ fileLines = File.read(file).lines
171
+ sectionBeginIndex = fileLines.index(sectionBegin)
172
+ sectionEndIndex = fileLines.index(sectionEnd)
173
+ if sectionBeginIndex.nil?
174
+ linesBefore = []
175
+ linesBefore = fileLines unless atTop
176
+ linesBefore << "\n"
177
+ linesBefore << sectionBegin
178
+ linesAfter = [sectionEnd]
179
+ linesAfter << "\n"
180
+ linesAfter += fileLines if atTop
181
+ else
182
+ linesBefore = fileLines[0..sectionBeginIndex]
183
+ if sectionEndIndex.nil?
184
+ linesAfter = [sectionEnd]
185
+ linesAfter << "\n"
186
+ else
187
+ linesAfter = fileLines[sectionEndIndex..fileLines.length]
188
+ end
189
+ end
190
+
191
+ fileLines = linesBefore
192
+ fileLines = yield(fileLines)
193
+ fileLines += linesAfter
194
+
195
+ fileWrite(file, fileLines.join(), options[:dry])
196
+ end
197
+
198
+ def updateRemoteFile(locationOrSSH, file, options, atTop = false, comment = '#', &block)
199
+
200
+ closure = Proc.new do |ssh|
201
+ localFile = options['output'] + '/' + SecureRandom.alphanumeric(10)
202
+ File.write(localFile, '')
203
+ self.class.sshExec!(ssh, "touch #{file}")
204
+ ssh.scp.download!(file, localFile)
205
+ updateLocalFile(localFile, options, atTop, comment, &block)
206
+ ssh.scp.upload!(localFile, file)
207
+ end
208
+
209
+ if locationOrSSH.is_a?(String) || locationOrSSH.is_a?(Addressable::URI)
210
+ uri = Addressable::URI.parse(locationOrSSH)
211
+ raise Framework::PluginProcessError.new("Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
212
+
213
+ self.class.sshStart(uri) do |ssh|
214
+ closure.call(ssh)
215
+ end
216
+ else
217
+ closure.call(locationOrSSH)
218
+ end
219
+ end
220
+
221
+ def self.filePresent?(file, ssh = nil)
222
+ result = self.exec("stat #{file}", ssh, true)
223
+ !result.start_with?('stat: cannot')
224
+ end
225
+
226
+ # DEPRECATED - use filePresent()
227
+ def self.remoteFilePresent?(file, ssh)
228
+ self.filePresent?(file, ssh)
229
+ end
230
+
231
+ def self.remoteFileContains?(file, content, ssh)
232
+ !self.sshExec!(ssh, "grep '#{content}' #{file}", true).strip.empty?
233
+ end
234
+
235
+ def self.uploadNotPresent(file, target, ssh)
236
+ target += '/' + File.basename(file)
237
+ if !self.remoteFilePresent?(target, ssh)
238
+ ssh.scp.upload!(file, target)
239
+ end
240
+ end
241
+
242
+ def self.uploadFolder(folder, target, ssh)
243
+ target += '/' + File.basename(folder) + '/'
244
+ self.sshExec!(ssh, "mkdir -p #{target}")
245
+ Dir[folder + '/*'].each do |file|
246
+ ssh.scp.upload!(file, target + File.basename(file), recursive: true)
247
+ end
248
+ end
249
+
250
+ def self.exec(command, ssh = nil, allowFailure = false)
251
+ if ssh.nil?
252
+ stdout, stdeerr, status = Open3.capture3(command)
253
+ if !allowFailure && !status.success?
254
+ $stderr.puts(stdout)
255
+ $stderr.puts(stdeerr)
256
+ raise Framework::PluginProcessError.new("Failed '#{command}'")
257
+ end
258
+ stdout + stdeerr
259
+ else
260
+ self.sshExec!(ssh, command, allowFailure)
261
+ end
262
+ end
263
+
264
+ def self.toSSHparams(locationUri)
265
+ server = locationUri.hostname
266
+ params = {}
267
+ params[:port] = locationUri.port if locationUri.port
268
+ params[:user] = locationUri.user if locationUri.user
269
+ [server, params]
270
+ end
271
+
272
+ def self.sshStart(uri)
273
+ uri = Addressable::URI.parse(uri) if uri.is_a?(String)
274
+ server, sshParams = self.toSSHparams(uri)
275
+ Net::SSH.start(server, nil, sshParams) do |ssh|
276
+ yield(ssh)
277
+ end
278
+ end
279
+
280
+ def self.sshExec!(ssh, command, allowFailure = false)
281
+ status = {}
282
+ output = ''
283
+ channel = ssh.exec(command, status: status) do |channel, stream, data|
284
+ output += data
285
+ end
286
+ channel.wait
287
+ if !allowFailure && !status[:exit_code].zero?
288
+ $stderr.puts(output)
289
+ raise Framework::PluginProcessError.new("Failed '#{command}'")
290
+ end
291
+ output
292
+ end
293
+
144
294
  def renderTemplate(template, target, outputPath, options)
145
295
  variables = {
146
296
  config: target,
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'plugins/dns'
4
+ require_relative 'plugins/linuxApp'
4
5
  require_relative 'plugins/nginxApp'
5
6
  require_relative 'plugins/ssh'
@@ -32,6 +32,9 @@ module ConfigLMM
32
32
 
33
33
  # Create Plugin instances
34
34
  Framework::Store.boot(logger, prompt, @Plugins)
35
+ @Plugins.each do |id, plugin|
36
+ plugin.state = @State
37
+ end
35
38
  end
36
39
 
37
40
  def execute
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ConfigLMM
4
- VERSION = '0.1.0'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ConfigLMM
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dāvis Mosāns
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-11 00:00:00.000000000 Z
11
+ date: 2024-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: filesize
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: fog-libvirt
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: fog-powerdns
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +136,20 @@ dependencies:
108
136
  - - "~>"
109
137
  - !ruby/object:Gem::Version
110
138
  version: 5.1.1
139
+ - !ruby/object:Gem::Dependency
140
+ name: net-scp
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
111
153
  - !ruby/object:Gem::Dependency
112
154
  name: net-ssh
113
155
  requirement: !ruby/object:Gem::Requirement
@@ -366,8 +408,19 @@ files:
366
408
  - Examples/Linux.mm.yaml
367
409
  - Examples/Windows.mm.yaml
368
410
  - Examples/configlmmAuth.sh
411
+ - Images/configINconfig.png
412
+ - Images/singleConfig.png
369
413
  - Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.conf.erb
370
414
  - Plugins/Apps/ArchiSteamFarm/ArchiSteamFarm.lmm.rb
415
+ - Plugins/Apps/Authentik/Authentik-Server.container
416
+ - Plugins/Apps/Authentik/Authentik-Worker.container
417
+ - Plugins/Apps/Authentik/Authentik.conf.erb
418
+ - Plugins/Apps/Authentik/Authentik.lmm.rb
419
+ - Plugins/Apps/Cassandra/Cassandra.lmm.rb
420
+ - Plugins/Apps/Dovecot/Dovecot.lmm.rb
421
+ - Plugins/Apps/GitLab/GitLab.conf.erb
422
+ - Plugins/Apps/GitLab/GitLab.container
423
+ - Plugins/Apps/GitLab/GitLab.lmm.rb
371
424
  - Plugins/Apps/IPFS/IPFS.conf.erb
372
425
  - Plugins/Apps/IPFS/IPFS.lmm.rb
373
426
  - Plugins/Apps/InfluxDB/InfluxDB.conf.erb
@@ -384,34 +437,61 @@ files:
384
437
  - Plugins/Apps/Netdata/Netdata.lmm.rb
385
438
  - Plugins/Apps/Nextcloud/Nextcloud.conf.erb
386
439
  - Plugins/Apps/Nextcloud/Nextcloud.lmm.rb
440
+ - Plugins/Apps/Nextcloud/config.php
441
+ - Plugins/Apps/Nginx/conf.d/configlmm.conf
387
442
  - Plugins/Apps/Nginx/config-lmm/errors.conf
388
443
  - Plugins/Apps/Nginx/config-lmm/private.conf
389
444
  - Plugins/Apps/Nginx/config-lmm/proxy.conf
390
445
  - Plugins/Apps/Nginx/config-lmm/public.conf
446
+ - Plugins/Apps/Nginx/config-lmm/security.conf
391
447
  - Plugins/Apps/Nginx/config-lmm/ssl.conf
392
- - Plugins/Apps/Nginx/main.conf
448
+ - Plugins/Apps/Nginx/main.conf.erb
393
449
  - Plugins/Apps/Nginx/nginx.conf
394
450
  - Plugins/Apps/Nginx/nginx.lmm.rb
395
451
  - Plugins/Apps/Nginx/proxy.conf.erb
396
452
  - Plugins/Apps/Odoo/Odoo.conf.erb
453
+ - Plugins/Apps/Odoo/Odoo.container
397
454
  - Plugins/Apps/Odoo/Odoo.lmm.rb
455
+ - Plugins/Apps/Odoo/odoo.conf
456
+ - Plugins/Apps/PHP-FPM/PHP-FPM.lmm.rb
457
+ - Plugins/Apps/Peppermint/Peppermint.conf.erb
458
+ - Plugins/Apps/Peppermint/Peppermint.container
459
+ - Plugins/Apps/Peppermint/Peppermint.lmm.rb
460
+ - Plugins/Apps/Postfix/Postfix.lmm.rb
461
+ - Plugins/Apps/Postfix/smtpd.conf
462
+ - Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb
398
463
  - Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb
399
464
  - Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb
400
465
  - Plugins/Apps/Pterodactyl/Wings.conf.erb
466
+ - Plugins/Apps/SSH/SSH.lmm.rb
401
467
  - Plugins/Apps/Sunshine/Sunshine.conf.erb
402
468
  - Plugins/Apps/Sunshine/Sunshine.lmm.rb
469
+ - Plugins/Apps/UVdesk/UVdesk.conf.erb
470
+ - Plugins/Apps/UVdesk/UVdesk.lmm.rb
471
+ - Plugins/Apps/Valkey/Valkey.lmm.rb
403
472
  - Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb
473
+ - Plugins/Apps/Vaultwarden/Vaultwarden.container
404
474
  - Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb
405
475
  - Plugins/Apps/bitmagnet/bitmagnet.conf.erb
406
476
  - Plugins/Apps/bitmagnet/bitmagnet.lmm.rb
407
477
  - Plugins/Apps/gollum/config.ru
408
478
  - Plugins/Apps/gollum/gollum.conf.erb
479
+ - Plugins/Apps/gollum/gollum.container
409
480
  - Plugins/Apps/gollum/gollum.lmm.rb
410
- - Plugins/OS/Linux.lmm.rb
481
+ - Plugins/OS/Linux/Distributions.yaml
482
+ - Plugins/OS/Linux/Linux.lmm.rb
483
+ - Plugins/OS/Linux/Packages.yaml
484
+ - Plugins/OS/Linux/WireGuard/WireGuard.lmm.rb
485
+ - Plugins/OS/Linux/WireGuard/wg0.conf.erb
486
+ - Plugins/OS/Linux/openSUSE/autoinst.xml.erb
487
+ - Plugins/OS/Linux/systemd/systemd.lmm.rb
488
+ - Plugins/OS/Linux/systemd/user-0.slice
489
+ - Plugins/OS/Linux/systemd/user@.service.d/delegate.conf
411
490
  - Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb
412
491
  - Plugins/Platforms/GitHub.lmm.rb
413
492
  - Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb
414
493
  - Plugins/Platforms/GoDaddy/zone.txt.erb
494
+ - Plugins/Platforms/libvirt/libvirt.lmm.rb
415
495
  - Plugins/Platforms/porkbun.lmm.rb
416
496
  - Plugins/Platforms/porkbun_spec.rb
417
497
  - Plugins/Services/DNS/AmberBit.lmm.rb
@@ -425,11 +505,13 @@ files:
425
505
  - bin/configlmm
426
506
  - bin/console
427
507
  - bin/setup
508
+ - bootstrap.sh
428
509
  - lib/ConfigLMM.rb
429
510
  - lib/ConfigLMM/Framework.rb
430
511
  - lib/ConfigLMM/Framework/plugins.rb
431
512
  - lib/ConfigLMM/Framework/plugins/dns.rb
432
513
  - lib/ConfigLMM/Framework/plugins/errors.rb
514
+ - lib/ConfigLMM/Framework/plugins/linuxApp.rb
433
515
  - lib/ConfigLMM/Framework/plugins/nginxApp.rb
434
516
  - lib/ConfigLMM/Framework/plugins/plugin.rb
435
517
  - lib/ConfigLMM/Framework/plugins/ssh.rb
@@ -478,7 +560,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
478
560
  - !ruby/object:Gem::Version
479
561
  version: '0'
480
562
  requirements: []
481
- rubygems_version: 3.5.11
563
+ rubygems_version: 3.5.15
482
564
  signing_key:
483
565
  specification_version: 4
484
566
  summary: Manage configuration for your applications/systems/services/servers