ConfigLMM 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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