ConfigLMM 0.1.0 → 0.2.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.
@@ -2,8 +2,11 @@
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'
7
10
 
8
11
  module ConfigLMM
9
12
  module Framework
@@ -42,6 +45,8 @@ module ConfigLMM
42
45
 
43
46
  addMeta :name, :description
44
47
 
48
+ attr_accessor :state
49
+
45
50
  def initialize(logger, prompt, plugins)
46
51
  @Logger = logger
47
52
  @Prompt = prompt
@@ -141,6 +146,111 @@ module ConfigLMM
141
146
  end
142
147
  end
143
148
 
149
+ CONFIGLMM_SECTION_BEGIN = "# -----BEGIN CONFIGLMM-----\n"
150
+ CONFIGLMM_SECTION_END = "# -----END CONFIGLMM-----\n"
151
+
152
+ def updateLocalFile(file, options, atTop = false)
153
+ fileLines = File.read(file).lines
154
+ sectionBeginIndex = fileLines.index(CONFIGLMM_SECTION_BEGIN)
155
+ sectionEndIndex = fileLines.index(CONFIGLMM_SECTION_END)
156
+ if sectionBeginIndex.nil?
157
+ linesBefore = []
158
+ linesBefore = fileLines unless atTop
159
+ linesBefore << "\n"
160
+ linesBefore << CONFIGLMM_SECTION_BEGIN
161
+ linesAfter = [CONFIGLMM_SECTION_END]
162
+ linesAfter << "\n"
163
+ linesAfter += fileLines if atTop
164
+ else
165
+ linesBefore = fileLines[0..sectionBeginIndex]
166
+ if sectionEndIndex.nil?
167
+ linesAfter = [CONFIGLMM_SECTION_END]
168
+ linesAfter << "\n"
169
+ else
170
+ linesAfter = fileLines[sectionEndIndex..fileLines.length]
171
+ end
172
+ end
173
+
174
+ fileLines = linesBefore
175
+ fileLines = yield(fileLines)
176
+ fileLines += linesAfter
177
+
178
+ fileWrite(file, fileLines.join(), options[:dry])
179
+ end
180
+
181
+ def updateRemoteFile(locationOrSSH, file, options, atTop = false, &block)
182
+
183
+ closure = Proc.new do |ssh|
184
+ localFile = options['output'] + '/' + SecureRandom.alphanumeric(10)
185
+ File.write(localFile, '')
186
+ self.class.sshExec!(ssh, "touch #{file}")
187
+ ssh.scp.download!(file, localFile)
188
+ updateLocalFile(localFile, options, atTop, &block)
189
+ ssh.scp.upload!(localFile, file)
190
+ end
191
+
192
+ if locationOrSSH.is_a?(String) || locationOrSSH.is_a?(Addressable::URI)
193
+ uri = Addressable::URI.parse(locationOrSSH)
194
+ raise Framework::PluginProcessError.new("Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
195
+
196
+ self.class.sshStart(uri) do |ssh|
197
+ closure.call(ssh)
198
+ end
199
+ else
200
+ closure.call(locationOrSSH)
201
+ end
202
+ end
203
+
204
+ def self.remoteFilePresent?(file, ssh)
205
+ result = self.sshExec!(ssh, "stat #{file}", true)
206
+ !result.start_with?('stat: cannot')
207
+ end
208
+
209
+ def self.uploadNotPresent(file, target, ssh)
210
+ target += '/' + File.basename(file)
211
+ if !self.remoteFilePresent?(target)
212
+ ssh.scp.upload!(file, target)
213
+ end
214
+ end
215
+
216
+ def self.uploadFolder(folder, target, ssh)
217
+ target += '/' + File.basename(folder) + '/'
218
+ self.sshExec!(ssh, "mkdir -p #{target}")
219
+ Dir[folder + '/*'].each do |file|
220
+ ssh.scp.upload!(file, target + File.basename(file))
221
+ end
222
+ end
223
+
224
+ def self.toSSHparams(locationUri)
225
+ server = locationUri.hostname
226
+ params = {}
227
+ params[:port] = locationUri.port if locationUri.port
228
+ params[:user] = locationUri.user if locationUri.user
229
+ [server, params]
230
+ end
231
+
232
+ def self.sshStart(uri)
233
+ uri = Addressable::URI.parse(uri) if uri.is_a?(String)
234
+ server, sshParams = self.toSSHparams(uri)
235
+ Net::SSH.start(server, nil, sshParams) do |ssh|
236
+ yield(ssh)
237
+ end
238
+ end
239
+
240
+ def self.sshExec!(ssh, command, allowFailure = false)
241
+ status = {}
242
+ output = ''
243
+ channel = ssh.exec(command, status: status) do |channel, stream, data|
244
+ output += data
245
+ end
246
+ channel.wait
247
+ if !allowFailure && !status[:exit_code].zero?
248
+ $stderr.puts(output)
249
+ raise Framework::PluginProcessError.new("Failed '#{command}'")
250
+ end
251
+ output
252
+ end
253
+
144
254
  def renderTemplate(template, target, outputPath, options)
145
255
  variables = {
146
256
  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.2.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.2.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-07-19 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,11 @@ 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/Dovecot/Dovecot.lmm.rb
371
416
  - Plugins/Apps/IPFS/IPFS.conf.erb
372
417
  - Plugins/Apps/IPFS/IPFS.lmm.rb
373
418
  - Plugins/Apps/InfluxDB/InfluxDB.conf.erb
@@ -388,6 +433,7 @@ files:
388
433
  - Plugins/Apps/Nginx/config-lmm/private.conf
389
434
  - Plugins/Apps/Nginx/config-lmm/proxy.conf
390
435
  - Plugins/Apps/Nginx/config-lmm/public.conf
436
+ - Plugins/Apps/Nginx/config-lmm/security.conf
391
437
  - Plugins/Apps/Nginx/config-lmm/ssl.conf
392
438
  - Plugins/Apps/Nginx/main.conf
393
439
  - Plugins/Apps/Nginx/nginx.conf
@@ -395,11 +441,14 @@ files:
395
441
  - Plugins/Apps/Nginx/proxy.conf.erb
396
442
  - Plugins/Apps/Odoo/Odoo.conf.erb
397
443
  - Plugins/Apps/Odoo/Odoo.lmm.rb
444
+ - Plugins/Apps/Postfix/Postfix.lmm.rb
445
+ - Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb
398
446
  - Plugins/Apps/Pterodactyl/Pterodactyl.conf.erb
399
447
  - Plugins/Apps/Pterodactyl/Pterodactyl.lmm.rb
400
448
  - Plugins/Apps/Pterodactyl/Wings.conf.erb
401
449
  - Plugins/Apps/Sunshine/Sunshine.conf.erb
402
450
  - Plugins/Apps/Sunshine/Sunshine.lmm.rb
451
+ - Plugins/Apps/Valkey/Valkey.lmm.rb
403
452
  - Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb
404
453
  - Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb
405
454
  - Plugins/Apps/bitmagnet/bitmagnet.conf.erb
@@ -407,11 +456,15 @@ files:
407
456
  - Plugins/Apps/gollum/config.ru
408
457
  - Plugins/Apps/gollum/gollum.conf.erb
409
458
  - Plugins/Apps/gollum/gollum.lmm.rb
410
- - Plugins/OS/Linux.lmm.rb
459
+ - Plugins/OS/Linux/Distributions.yaml
460
+ - Plugins/OS/Linux/Linux.lmm.rb
461
+ - Plugins/OS/Linux/Packages.yaml
462
+ - Plugins/OS/Linux/openSUSE/autoinst.xml.erb
411
463
  - Plugins/OS/Routers/Aruba/ArubaInstant.lmm.rb
412
464
  - Plugins/Platforms/GitHub.lmm.rb
413
465
  - Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb
414
466
  - Plugins/Platforms/GoDaddy/zone.txt.erb
467
+ - Plugins/Platforms/libvirt/libvirt.lmm.rb
415
468
  - Plugins/Platforms/porkbun.lmm.rb
416
469
  - Plugins/Platforms/porkbun_spec.rb
417
470
  - Plugins/Services/DNS/AmberBit.lmm.rb
@@ -430,6 +483,7 @@ files:
430
483
  - lib/ConfigLMM/Framework/plugins.rb
431
484
  - lib/ConfigLMM/Framework/plugins/dns.rb
432
485
  - lib/ConfigLMM/Framework/plugins/errors.rb
486
+ - lib/ConfigLMM/Framework/plugins/linuxApp.rb
433
487
  - lib/ConfigLMM/Framework/plugins/nginxApp.rb
434
488
  - lib/ConfigLMM/Framework/plugins/plugin.rb
435
489
  - lib/ConfigLMM/Framework/plugins/ssh.rb
@@ -478,7 +532,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
478
532
  - !ruby/object:Gem::Version
479
533
  version: '0'
480
534
  requirements: []
481
- rubygems_version: 3.5.11
535
+ rubygems_version: 3.5.15
482
536
  signing_key:
483
537
  specification_version: 4
484
538
  summary: Manage configuration for your applications/systems/services/servers
@@ -1,64 +0,0 @@
1
-
2
- module ConfigLMM
3
- module LMM
4
- class Linux < Framework::Plugin
5
-
6
- HOSTS_FILE = '/etc/hosts'
7
- HOSTS_SECTION_BEGIN = "# -----BEGIN CONFIGLMM-----\n"
8
- HOSTS_SECTION_END = "# -----END CONFIGLMM-----\n"
9
-
10
- def actionLinuxBuild(id, target, activeState, context, options)
11
- if target['Hosts']
12
- hosts = "#\n"
13
- hosts += "# /etc/hosts: static lookup table for host names\n"
14
- hosts += "#\n\n"
15
- hosts += "#<ip-address> <hostname.domain.org> <hostname>\n"
16
- hosts += "127.0.0.1 localhost\n"
17
- hosts += "::1 localhost\n\n"
18
- hosts += HOSTS_SECTION_BEGIN
19
- target['Hosts'].each do |ip, entries|
20
- hosts += ip.ljust(16) + entries.join(' ') + "\n"
21
- end
22
- hosts += HOSTS_SECTION_END
23
-
24
- mkdir(options['output'] + '/etc', options[:dry])
25
- fileWrite(options['output'] + HOSTS_FILE, hosts, options[:dry])
26
- end
27
- end
28
-
29
- def actionLinuxDeploy(id, target, activeState, context, options)
30
- if !target['Location'] || target['Location'] == '@me'
31
- if target['Hosts']
32
- hostsLines = File.read(HOSTS_FILE).lines
33
- sectionBeginIndex = hostsLines.index(HOSTS_SECTION_BEGIN)
34
- sectionEndIndex = hostsLines.index(HOSTS_SECTION_END)
35
- if sectionBeginIndex.nil?
36
- linesBefore = hostsLines
37
- linesBefore << "\n"
38
- linesBefore << HOSTS_SECTION_BEGIN
39
- linesAfter = [HOSTS_SECTION_END]
40
- linesAfter << "\n"
41
- else
42
- linesBefore = hostsLines[0..sectionBeginIndex]
43
- if sectionEndIndex.nil?
44
- linesAfter = [HOSTS_SECTION_END]
45
- linesAfter << "\n"
46
- else
47
- linesAfter = hostsLines[sectionEndIndex..hostsLines.length]
48
- end
49
- end
50
-
51
- hostsLines = linesBefore
52
- target['Hosts'].each do |ip, entries|
53
- hostsLines << ip.ljust(16) + entries.join(' ') + "\n"
54
- end
55
- hostsLines += linesAfter
56
-
57
- fileWrite(HOSTS_FILE, hostsLines.join(), options[:dry])
58
- end
59
- end
60
- end
61
-
62
- end
63
- end
64
- end